[cdo] 45/84: Upstream 1.6.3

Alastair McKinstry mckinstry at moszumanska.debian.org
Sat Jun 13 16:48:33 UTC 2015


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

mckinstry pushed a commit to branch master
in repository cdo.

commit 0b4a48c2b9d2a80bf9b076959a665cbd30ba5c8e
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Mon Feb 24 19:05:45 2014 +0000

    Upstream 1.6.3
---
 ChangeLog                                          |   71 +
 NEWS                                               |   15 +
 OPERATORS                                          |    3 +-
 cdo.spec                                           |    2 +-
 config/default                                     |   19 +-
 configure                                          |   21 +-
 configure.ac                                       |    3 +-
 contrib/cdoCompletion.bash                         |    5 +-
 contrib/cdoCompletion.tcsh                         |    5 +-
 contrib/cdoCompletion.zsh                          |    5 +-
 doc/cdo.pdf                                        |  Bin 1424406 -> 1436698 bytes
 doc/cdo_refcard.pdf                                |  Bin 96567 -> 96405 bytes
 libcdi/ChangeLog                                   |   36 +-
 libcdi/Makefile.in                                 |   15 +-
 libcdi/NEWS                                        |    9 +
 libcdi/aclocal.m4                                  |  194 +-
 libcdi/app/Makefile.in                             |    9 +-
 libcdi/cdi.settings.in                             |    2 +-
 libcdi/configure                                   |  456 +-
 libcdi/configure.ac                                |   73 +-
 libcdi/doc/cdi_cman.pdf                            |  Bin 450726 -> 453981 bytes
 libcdi/doc/cdi_fman.pdf                            |  Bin 491954 -> 494569 bytes
 libcdi/examples/Makefile.am                        |    7 -
 libcdi/examples/Makefile.in                        |   11 +-
 libcdi/examples/pio/Makefile.am                    |   13 +-
 libcdi/examples/pio/Makefile.in                    |   44 +-
 libcdi/examples/pio/collectData.c                  |   16 +-
 libcdi/examples/pio/collectData2003.F90            |   20 +-
 libcdi/examples/pio/collectDataNStreams.c          |   26 +-
 libcdi/examples/pio/compareResourcesArray.c        |   13 +-
 libcdi/interfaces/Makefile.in                      |    9 +-
 libcdi/m4/pkg.m4                                   |  159 +
 libcdi/m4/starlink_fpp.m4                          |   31 +-
 libcdi/src/Makefile.am                             |  109 +-
 libcdi/src/Makefile.in                             |  173 +-
 libcdi/src/cdi.h                                   |   80 +-
 libcdi/src/cdi.inc                                 |   80 +-
 libcdi/src/cdiFortran.c                            |   60 +-
 libcdi/src/cdiFortran.h                            |   20 -
 libcdi/src/cdi_cksum.c                             |   17 +
 libcdi/src/cdi_cksum.h                             |    8 +
 libcdi/src/cdi_int.c                               |   27 +-
 libcdi/src/cdi_int.h                               |    2 +
 libcdi/src/cdilib.c                                | 6253 +++++---------------
 libcdi/src/cdipio.h                                |   49 +
 libcdi/src/cdipio.inc                              |   71 +
 libcdi/src/cdipioFortran.c                         |   54 +
 libcdi/src/cgribex.h                               |    2 +-
 libcdi/src/cgribexlib.c                            |   20 +-
 libcdi/{tests => src}/cksum.c                      |   58 +-
 libcdi/{tests => src}/cksum.h                      |    7 +-
 libcdi/src/config.h.in                             |   22 +
 libcdi/src/dmemory.c                               |   30 +
 libcdi/src/dmemory.h                               |   11 +
 libcdi/src/error.c                                 |   16 +-
 libcdi/src/error.h                                 |    2 +
 libcdi/src/grid.c                                  |  267 +-
 libcdi/src/institution.c                           |   46 +-
 libcdi/src/mo_cdi.f90                              |   59 +-
 libcdi/src/model.c                                 |    1 -
 libcdi/src/namespace.c                             |  128 +-
 libcdi/src/namespace.h                             |    3 +
 libcdi/src/pio.c                                   |   15 +-
 libcdi/src/pio.h                                   |    3 +-
 libcdi/src/pio_cdf_int.c                           |    1 +
 libcdi/src/pio_client.c                            |  110 +-
 libcdi/src/pio_comm.c                              |   23 +-
 libcdi/src/pio_comm.h                              |    2 +-
 libcdi/src/pio_impl.h                              |    6 +-
 libcdi/src/pio_interface.c                         |  359 +-
 libcdi/src/pio_interface.h                         |   21 +-
 libcdi/src/pio_list_set.c                          |    1 +
 libcdi/src/pio_mpinonb.c                           |    6 +-
 libcdi/src/pio_posixasynch.c                       |   13 +-
 libcdi/src/pio_posixfpguardsendrecv.c              |   34 +-
 libcdi/src/pio_posixnonb.c                         |    4 +-
 libcdi/src/pio_record_send.c                       |   44 +-
 libcdi/src/pio_rpc.h                               |   48 +-
 libcdi/src/pio_serialize.c                         |   11 +-
 libcdi/src/pio_server.c                            |  454 +-
 libcdi/src/pio_server.h                            |    2 +-
 libcdi/src/pio_util.c                              |   77 +-
 libcdi/src/pio_util.h                              |   45 +-
 libcdi/src/pkgconfig/cdipio.pc.in                  |   48 +
 libcdi/src/resource_handle.c                       |   96 +-
 libcdi/src/resource_handle.h                       |    7 +
 libcdi/src/resource_unpack.c                       |    2 +-
 libcdi/src/serialize.c                             |    7 +-
 libcdi/src/serialize.h                             |    2 -
 libcdi/src/stream.c                                |   97 +-
 libcdi/src/stream_cdf.c                            |  186 +-
 libcdi/src/stream_cgribex.c                        |   38 +-
 libcdi/src/stream_grb.c                            |    4 +-
 libcdi/src/stream_gribapi.c                        |   31 +-
 libcdi/src/taxis.c                                 |   37 +-
 libcdi/src/taxis.h                                 |    2 +
 libcdi/src/varscan.c                               |  107 +-
 libcdi/src/vlist.c                                 |  187 +-
 libcdi/src/vlist.h                                 |    3 +-
 libcdi/src/vlist_att.c                             |   12 +-
 libcdi/src/vlist_var.c                             |  245 +-
 libcdi/src/vlist_var.h                             |    7 +-
 libcdi/src/zaxis.c                                 |  137 +-
 libcdi/tests/Makefile.am                           |   40 +-
 libcdi/tests/Makefile.in                           |  157 +-
 libcdi/tests/cksum_verify                          |  Bin 13808 -> 0 bytes
 libcdi/tests/deco2d_model.c                        |  496 ++
 libcdi/tests/ensure_array_size.c                   |    2 +-
 libcdi/tests/pio_cksum_asynch                      |    9 -
 libcdi/tests/pio_cksum_cdf                         |   10 -
 libcdi/tests/pio_cksum_fpguard                     |    9 -
 libcdi/tests/pio_cksum_mpinonb                     |    9 -
 libcdi/tests/pio_cksum_writer                      |    9 -
 libcdi/tests/pio_write.c                           |  417 +-
 libcdi/tests/pio_write.h                           |   18 +
 .../{pio_write_run => pio_write_deco2d_run.in}     |   10 +-
 libcdi/tests/simple_model.c                        |  333 ++
 libcdi/tests/simple_model_helper.c                 |  135 +
 libcdi/tests/simple_model_helper.h                 |   42 +
 libcdi/tests/stream_cksum.c                        |    5 +-
 libcdi/tests/test_chunk_cksum                      |   14 -
 libcdi/tests/test_cksum_extra                      |   14 -
 libcdi/tests/test_cksum_grib                       |   14 -
 libcdi/tests/test_cksum_ieg                        |   14 -
 libcdi/tests/test_cksum_nc                         |   14 -
 libcdi/tests/test_cksum_nc2                        |   14 -
 libcdi/tests/test_cksum_nc4                        |   14 -
 libcdi/tests/test_cksum_service                    |   14 -
 libcdi/tests/test_grib.sh                          |    9 -
 libcdi/tests/test_resource_copy                    |  Bin 8984 -> 0 bytes
 libcdi/tests/test_resource_copy.c                  |   67 +-
 libcdi/tests/test_resource_copy_mpi_run.in         |    5 +
 libcdi/util/xlfpreproc-wrapper                     |   39 +-
 src/Adisit.c                                       |   10 +-
 src/Arith.c                                        |   18 +-
 src/Arithc.c                                       |    6 +-
 src/Arithdays.c                                    |    4 +-
 src/Arithlat.c                                     |    6 +-
 src/CDIread.c                                      |   26 +-
 src/CDItest.c                                      |    4 +-
 src/CDIwrite.c                                     |   36 +-
 src/Cat.c                                          |    4 +-
 src/Change.c                                       |   10 +-
 src/Change_e5slm.c                                 |   10 +-
 src/Cloudlayer.c                                   |   12 +-
 src/Command.c                                      |    6 +-
 src/Comp.c                                         |   12 +-
 src/Compc.c                                        |    6 +-
 src/Complextorect.c                                |    8 +-
 src/Cond.c                                         |   16 +-
 src/Cond2.c                                        |   18 +-
 src/Condc.c                                        |    6 +-
 src/Consecstat.c                                   |    4 +-
 src/Copy.c                                         |    6 +-
 src/Deltime.c                                      |    4 +-
 src/Derivepar.c                                    |  146 +-
 src/Detrend.c                                      |   14 +-
 src/Diff.c                                         |   10 +-
 src/Duplicate.c                                    |   10 +-
 src/EOFs.c                                         |   67 +-
 src/EcaIndices.c                                   |   38 +-
 src/Echam5ini.c                                    |   56 +-
 src/Enlarge.c                                      |    6 +-
 src/Enlargegrid.c                                  |   20 +-
 src/Ensstat.c                                      |   14 +-
 src/Ensstat3.c                                     |   48 +-
 src/Ensval.c                                       |   34 +-
 src/Eof3d.c                                        |   53 +-
 src/Eofcoeff.c                                     |   25 +-
 src/Eofcoeff3d.c                                   |   33 +-
 src/Exprf.c                                        |   17 +-
 src/FC.c                                           |    8 +-
 src/Filedes.c                                      |    2 +-
 src/Fillmiss.c                                     |   14 +-
 src/Filter.c                                       |   18 +-
 src/Fldrms.c                                       |    9 +-
 src/Fldstat.c                                      |    7 +-
 src/Fldstat2.c                                     |    9 +-
 src/Fourier.c                                      |   20 +-
 src/Gather.c                                       |   50 +-
 src/Gengrid.c                                      |    8 +-
 src/Gradsdes.c                                     |  216 +-
 src/Gridboxstat.c                                  |   46 +-
 src/Gridcell.c                                     |   10 +-
 src/Harmonic.c                                     |   18 +-
 src/Hi.c                                           |    6 +-
 src/Histogram.c                                    |   18 +-
 src/Importamsr.c                                   |    8 +-
 src/Importbinary.c                                 |   25 +-
 src/Importcmsaf.c                                  |   30 +-
 src/Importobs.c                                    |    8 +-
 src/Info.c                                         |    4 +-
 src/Input.c                                        |    8 +-
 src/Intgrid.c                                      |   38 +-
 src/Intgridtraj.c                                  |   16 +-
 src/Intlevel.c                                     |   30 +-
 src/Intlevel3d.c                                   |   48 +-
 src/Intntime.c                                     |   24 +-
 src/Inttime.c                                      |   27 +-
 src/Intyear.c                                      |   10 +-
 src/Invert.c                                       |   30 +-
 src/Invertlev.c                                    |   20 +-
 src/Isosurface.c                                   |   14 +-
 src/Kvl.c                                          |    2 +-
 src/Log.c                                          |    2 +-
 src/Maggraph.c                                     |   42 +-
 src/Magplot.c                                      |    8 +-
 src/Magvector.c                                    |    8 +-
 src/Makefile.am                                    |   20 +
 src/Makefile.in                                    |  174 +-
 src/Maskbox.c                                      |   16 +-
 src/Mastrfu.c                                      |   18 +-
 src/Math.c                                         |    6 +-
 src/Merge.c                                        |   12 +-
 src/Mergegrid.c                                    |   20 +-
 src/Mergetime.c                                    |    6 +-
 src/Merstat.c                                      |    8 +-
 src/Monarith.c                                     |   14 +-
 src/Mrotuv.c                                       |   30 +-
 src/Mrotuvb.c                                      |   30 +-
 src/Ninfo.c                                        |    2 +-
 src/Nmltest.c                                      |    2 +-
 src/Output.c                                       |   10 +-
 src/Outputgmt.c                                    |   44 +-
 src/Pack.c                                         |    8 +-
 src/Pinfo.c                                        |    6 +-
 src/Pressure.c                                     |   32 +-
 src/Regres.c                                       |   10 +-
 src/Remap.c                                        |  330 +-
 src/Remapeta.c                                     |   69 +-
 src/Replace.c                                      |   20 +-
 src/Replacevalues.c                                |    4 +-
 src/Rhopot.c                                       |   10 +-
 src/Rotuv.c                                        |   18 +-
 src/Runpctl.c                                      |   10 +-
 src/Runstat.c                                      |   16 +-
 src/SSOpar.c                                       |   30 +-
 src/Scatter.c                                      |   28 +-
 src/Seascount.c                                    |    6 +-
 src/Seaspctl.c                                     |   12 +-
 src/Seasstat.c                                     |   12 +-
 src/Selbox.c                                       |   72 +-
 src/Select.c                                       |   46 +-
 src/Seloperator.c                                  |    4 +-
 src/Selrec.c                                       |    2 +-
 src/Seltime.c                                      |   14 +-
 src/Selvar.c                                       |    6 +-
 src/Set.c                                          |    6 +-
 src/Setbox.c                                       |    6 +-
 src/Setgatt.c                                      |    4 +-
 src/Setgrid.c                                      |   12 +-
 src/Sethalo.c                                      |   56 +-
 src/Setmiss.c                                      |    4 +-
 src/Setpartab.c                                    |    8 +-
 src/Setrcaname.c                                   |    4 +-
 src/Settime.c                                      |    9 +-
 src/Setzaxis.c                                     |    4 +-
 src/Showinfo.c                                     |    2 +-
 src/Sinfo.c                                        |    2 +-
 src/Smooth9.c                                      |   10 +-
 src/Sort.c                                         |   26 +-
 src/Sorttimestamp.c                                |   16 +-
 src/Specinfo.c                                     |    2 +-
 src/Spectral.c                                     |   10 +-
 src/Spectrum.c                                     |   22 +-
 src/Split.c                                        |   44 +-
 src/Splitrec.c                                     |    4 +-
 src/Splitsel.c                                     |   10 +-
 src/Splittime.c                                    |   10 +-
 src/Splityear.c                                    |    4 +-
 src/StringUtilities.c                              |    2 +-
 src/Subtrend.c                                     |    6 +-
 src/Tee.c                                          |    4 +-
 src/Templates.c                                    |    6 +-
 src/Test.c                                         |   12 +-
 src/Tests.c                                        |    6 +-
 src/Timcount.c                                     |    6 +-
 src/Timpctl.c                                      |    6 +-
 src/Timselpctl.c                                   |    6 +-
 src/Timselstat.c                                   |   12 +-
 src/Timsort.c                                      |   22 +-
 src/Timstat.c                                      |   12 +-
 src/Timstat2.c                                     |   24 +-
 src/Timstat3.c                                     |   22 +-
 src/Tocomplex.c                                    |    6 +-
 src/Transpose.c                                    |   10 +-
 src/Trend.c                                        |   10 +-
 src/Trms.c                                         |   15 +-
 src/Tstepcount.c                                   |   10 +-
 src/Vardup.c                                       |   16 +-
 src/Vargen.c                                       |    7 +-
 src/Varrms.c                                       |   13 +-
 src/Vertint.c                                      |   80 +-
 src/Vertstat.c                                     |   18 +-
 src/Vertwind.c                                     |   20 +-
 src/Wct.c                                          |    4 +-
 src/Wind.c                                         |   12 +-
 src/Writegrid.c                                    |    4 +-
 src/Writerandom.c                                  |   14 +-
 src/YAR.c                                          |   72 +-
 src/Ydayarith.c                                    |   14 +-
 src/Ydaypctl.c                                     |    6 +-
 src/Ydaystat.c                                     |   12 +-
 src/Ydrunpctl.c                                    |   10 +-
 src/Ydrunstat.c                                    |   12 +-
 src/Yearmonstat.c                                  |   12 +-
 src/Yhourarith.c                                   |   14 +-
 src/Yhourstat.c                                    |   12 +-
 src/Ymonarith.c                                    |   14 +-
 src/Ymonpctl.c                                     |    6 +-
 src/Ymonstat.c                                     |   16 +-
 src/Yseaspctl.c                                    |    6 +-
 src/Yseasstat.c                                    |   12 +-
 src/Zonstat.c                                      |    6 +-
 src/cdo.c                                          |   20 +-
 src/cdo.h                                          |   12 +-
 src/cdo_int.h                                      |    6 +-
 src/cdo_pthread.c                                  |    2 +-
 src/cdo_vlist.c                                    |   16 +-
 src/cdotest.c                                      |    6 +-
 src/clipping/area.c                                |  647 ++
 src/clipping/area.h                                |  255 +
 src/clipping/clipping.c                            | 1026 ++++
 src/clipping/clipping.h                            |  114 +
 src/clipping/dep_list.h                            |  215 +
 src/clipping/ensure_array_size.c                   |   47 +
 src/clipping/ensure_array_size.h                   |   55 +
 src/clipping/geometry.h                            |  585 ++
 src/clipping/geometry_tools.c                      |  120 +
 src/clipping/grid.h                                |  473 ++
 src/clipping/grid_cell.c                           |  148 +
 src/clipping/grid_cell.h                           |   84 +
 src/clipping/intersection.c                        | 1395 +++++
 src/clipping/points.h                              |  103 +
 src/clipping/utils.c                               |   99 +
 src/clipping/utils.h                               |  115 +
 src/color.c                                        |    6 +-
 src/commandline.c                                  |    2 +-
 src/ecacore.c                                      |  118 +-
 src/expr.c                                         |   40 +-
 src/expr.h                                         |    2 +-
 src/expr_lex.c                                     |   76 +-
 src/expr_yacc.c                                    |  902 +--
 src/expr_yacc.h                                    |   32 +-
 src/field.c                                        |    4 +-
 src/field.h                                        |    2 +-
 src/field2.c                                       |    2 +-
 src/fieldc.c                                       |    2 +-
 src/fieldmem.c                                     |    8 +-
 src/fieldmer.c                                     |    4 +-
 src/fieldzon.c                                     |    4 +-
 src/fouriertrans.c                                 |   12 +-
 src/grid.c                                         |  276 +-
 src/grid.h                                         |   13 +
 src/grid_area.c                                    |   34 +-
 src/grid_gme.c                                     |   26 +-
 src/griddes.c                                      |   56 +-
 src/griddes_h5.c                                   |   66 +-
 src/griddes_nc.c                                   |   12 +-
 src/gridreference.c                                |    7 +-
 src/hetaeta.c                                      |  222 +-
 src/history.c                                      |    6 +-
 src/institution.c                                  |    2 +-
 src/interpol.c                                     |  269 +-
 src/job.c                                          |   22 +-
 src/kvlist.c                                       |    6 +-
 src/kvlist.h                                       |    2 +-
 src/list.c                                         |    8 +-
 src/list.h                                         |    2 +-
 src/magics_template_parser.c                       |    4 +-
 src/merge_sort2.c                                  |    2 +-
 src/modules.c                                      |   11 +-
 src/modules.h                                      |    2 +-
 src/namelist.c                                     |   10 +-
 src/namelist.h                                     |    2 +-
 src/operator_help.h                                |   40 +-
 src/percentiles.c                                  |   14 +-
 src/pipe.c                                         |   22 +-
 src/pipe.h                                         |    2 +-
 src/printinfo.h                                    |    4 +-
 src/process.c                                      |   20 +-
 src/process.h                                      |    2 +-
 src/pstream.c                                      |   41 +-
 src/pstream.h                                      |    7 +-
 src/pstream_int.h                                  |    2 +-
 src/readline.c                                     |    2 +-
 src/remap.h                                        |  204 +-
 src/remap_scrip_io.c                               |  331 +-
 src/remap_search_latbins.c                         |  125 +
 src/remaplib.c                                     | 4271 +++++++------
 src/remapsort.c                                    |   12 +-
 src/specspace.c                                    |   69 +-
 src/statistic.c                                    |   14 +-
 src/stdnametable.c                                 |   76 +
 src/stdnametable.h                                 |   18 +
 src/table.c                                        |    4 +-
 src/timer.c                                        |    2 +-
 src/userlog.c                                      |   48 +-
 src/util.c                                         |   46 +-
 src/util.h                                         |    2 +-
 src/vinterp.c                                      |    8 +-
 src/zaxis.c                                        |   12 +-
 test/Makefile.am                                   |    4 +-
 test/Makefile.in                                   |    4 +-
 test/data/Makefile.am                              |    5 +-
 test/data/Makefile.in                              |    5 +-
 test/data/hl_l19.grb                               |  Bin 4888 -> 4888 bytes
 test/data/ml2pl_ref                                |  Bin 312 -> 312 bytes
 test/data/pl_data.grb                              |  Bin 0 -> 6920 bytes
 test/data/select1_ref                              |  Bin 0 -> 5760 bytes
 test/data/select2_ref                              |  Bin 0 -> 3480 bytes
 test/data/select3_ref                              |  Bin 0 -> 2088 bytes
 test/data/select4_ref                              |  Bin 0 -> 4600 bytes
 test/data/select5_ref                              |  Bin 0 -> 1120 bytes
 test/test_Cat.sh                                   |   42 +
 test/test_Remap.sh                                 |   43 -
 test/test_Select.sh                                |   55 +
 417 files changed, 18212 insertions(+), 12342 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9e20556..f4820c2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,74 @@
+2014-02-18  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* using CDI library version 1.6.3
+	* Version 1.6.3 released
+
+2014-01-29  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* gridFromH5file: skipped if attribute >bounds< is defined [Bug #4411]
+
+2014-01-24  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* expr: select variables by name
+
+2014-01-09  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* gradsdes: added support for GRIB files >2GB [request: Ingo Kirchner]
+
+2014-01-08  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* gradsdes: added overloading of streamInqGinfo() (bug fix for GRIB1)
+
+2014-01-07  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* settaxis: added support for negativ time increment
+
+2014-01-03  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* Added test/test_Select.sh
+
+2014-01-02 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* gradsdes: changed LCC to LCCR in PDEF definition [Bug #4344]
+
+2013-12-09 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* cat: "Segmentation fault" if the output file already exist [Bug #4291]
+
+2013-12-04 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* gridFromH5file: set fclose degree to H5F_CLOSE_STRONG [Bug #4272]
+	* cdoDefineGrid: first call gridFromH5file() for HDF tags
+
+2013-11-29 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* eca_csu: added number of csu periods with more than 5days per time period [request: Moritz Maneke]
+	* eca_cfd: added number of cfd periods with more than 5days per time period  [request: Moritz Maneke]
+
+2013-11-29 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* remapdis: optimization for regular 2D source grids
+
+2013-11-28 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* remapbic: optimization for regular 2D source grids
+
+2013-11-27 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* remapbil: optimization for regular 2D source grids
+
+2013-11-25  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* remapbil: skip explicitly call to sort_add() (weights are sorted implicitly)
+
+2013-11-18  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* remaplib: cleanup and preparation for opt. reg2d grids
+
+2013-11-13  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* delete: parameter level does not work [Bug #4216]
+
 2013-11-12  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
 
 	* using CDI library version 1.6.2
diff --git a/NEWS b/NEWS
index 079339b..3309cea 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,21 @@
 CDO NEWS
 --------
 
+Version 1.6.3 (18 February 2014):
+
+   New features:
+     * remapbil, remapbic, remapdis: performance optimization for regular 2D source grids
+     * gradsdes: added support for GRIB files >2GB
+     * eca_csu: added number of csu periods with more than 5days per time period
+     * eca_cfd: added number of cfd periods with more than 5days per time period
+     * expr: select variables by name
+   Changed operators:
+     * gradsdes: added parameter map_version and removed specific operators gradsdes1 and gradsdes2
+   Fixed bugs:
+     * gradsdes: changed LCC to LCCR in PDEF definition [Bug #4344]
+     * cat: "Segmentation fault" if the output file already exist [Bug #4291]
+     * delete: parameter level does not work [Bug #4216]
+
 Version 1.6.2 (12 November 2013):
 
    New features:
diff --git a/OPERATORS b/OPERATORS
index edfb0da..c95c1b6 100644
--- a/OPERATORS
+++ b/OPERATORS
@@ -472,8 +472,7 @@ Operator catalog:
 -------------------------------------------------------------
    Miscellaneous
 -------------------------------------------------------------
-   Gradsdes      gradsdes1       GrADS data descriptor file (version 1 GRIB map)
-   Gradsdes      gradsdes2       GrADS data descriptor file (version 2 GRIB map)
+   Gradsdes      gradsdes        GrADS data descriptor file
    Filter        bandpass        Bandpass filtering
    Filter        lowpass         Lowpass filtering
    Filter        highpass        Highpass filtering
diff --git a/cdo.spec b/cdo.spec
index 055f14a..b74cc24 100644
--- a/cdo.spec
+++ b/cdo.spec
@@ -4,7 +4,7 @@
 
 Name:           cdo
 #BuildRequires:  
-Version:        1.6.2
+Version:        1.6.3
 Release:        1
 Summary:        Climate Data Operators
 License:        GNU GENERAL PUBLIC LICENSE Version 2, June 1991
diff --git a/config/default b/config/default
index 8ce0ba8..eabccef 100755
--- a/config/default
+++ b/config/default
@@ -45,8 +45,8 @@ case "${HOSTNAME}" in
                     --with-curl=/opt/local \
                     --with-libxml2=/usr \
                     --with-magics=/Users/m214003/local/magics-2.14.9 \
-	            CC=gcc CFLAGS="-g -pipe -D_REENTRANT -Wall -W -Wfloat-equal -pedantic -O3 -march=native -fopenmp -DHAVE_LIBYAC -I/Users/m214003/cdt/work/YAC/src" \
-                    LIBS="-L/opt/local/lib -lopenjpeg -L/Users/m214003/cdt/work/YAC/src -lyac"
+	            CC=gcc CFLAGS="-g -pipe -D_REENTRANT -Wall -W -Wfloat-equal -pedantic -O3 -march=native -fopenmp" \
+                    LIBS="-L/opt/local/lib -lopenjpeg"
 #                    --with-libxml2=/usr
 #                    --with-magics=/Users/m214003/local/magics-2.14.9
 	;;
@@ -56,13 +56,13 @@ case "${HOSTNAME}" in
                     --with-jasper=/opt/local \
                     --with-grib_api=$HOME/local/gribapi-1.9.16 \
                     --with-netcdf=/opt/local \
+                    --with-hdf5=/opt/local \
                     --with-szlib=$HOME/local \
                     --with-proj=/opt/local \
                     --with-curl=/opt/local \
                     --with-libxml2=/usr \
                     --with-magics=/Users/m214003/local/Magics-2.18.14nio \
-	            CC=gcc CFLAGS="-g -pipe -D_REENTRANT -Wall -W -Wfloat-equal -pedantic -O3 -march=native -fopenmp -DHAVE_LIBYAC -I/Users/m214003/cdt/work/YAC/src" \
-                    LIBS="-L/Users/m214003/cdt/work/YAC/src -lyac"
+	            CC=gcc CFLAGS="-g -pipe -D_REENTRANT -Wall -W -Wfloat-equal -pedantic -O3 -march=native -fopenmp"
 	;;
 # ia64-xxx-linux
     ds*)
@@ -76,16 +76,6 @@ case "${HOSTNAME}" in
                     --with-netcdf=/home/dkrz/m214089/local/ia64 \
                     CC=icc CFLAGS="-g -O2 -Wall -fno-alias"
 	;;
-# x86_64-suse-linux
-    tornado*)
- 	${CONFPATH}configure --prefix=$HOME/local --exec_prefix=$HOME/local/sles10-x64 \
-                    --enable-all-static \
-	            --with-netcdf=/sw/sles10-x64/netcdf-4.2-static \
-	            --with-hdf5=/sw/sles10-x64/hdf5-1.8.8-static \
-                    --with-szlib=/sw/sles10-x64/szip-2.1 \
-	            CC=gcc CFLAGS='-g -Wall -O2 -fopenmp'
-#	            CC=suncc CFLAGS="-g -fast -xopenmp"
-	;;
 # x86_64-squeeze-x64-linux
     thunder*)
         ${CONFPATH}configure --prefix=$HOME/local --exec_prefix=$HOME/local/thunder \
@@ -220,6 +210,7 @@ case "${HOSTNAME}" in
                     --with-szlib=/sw/aix61/szip-2.1-threadsafe \
                     --with-udunits2=/sw/aix61/udunits-2.1.14 \
                     --with-proj=/sw/aix53/proj-4.6.1 \
+                    --with-curl=/sw/aix61/curl-7.21.3 \
                     AR="ar -X 64"  LDFLAGS="-brtl" \
  	            CC=xlc_r CFLAGS="-g -O3 -q64 -qhot -qstrict -qarch=auto -qtune=auto -qsmp=omp -DHAVE_MMAP -qthreaded"
 	;;
diff --git a/configure b/configure
index 850ec04..ac3b58d 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for cdo 1.6.2.
+# Generated by GNU Autoconf 2.68 for cdo 1.6.3.
 #
 # Report bugs to <http://code.zmaw.de/projects/cdo>.
 #
@@ -570,8 +570,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='cdo'
 PACKAGE_TARNAME='cdo'
-PACKAGE_VERSION='1.6.2'
-PACKAGE_STRING='cdo 1.6.2'
+PACKAGE_VERSION='1.6.3'
+PACKAGE_STRING='cdo 1.6.3'
 PACKAGE_BUGREPORT='http://code.zmaw.de/projects/cdo'
 PACKAGE_URL=''
 
@@ -1374,7 +1374,7 @@ 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 cdo 1.6.2 to adapt to many kinds of systems.
+\`configure' configures cdo 1.6.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1444,7 +1444,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cdo 1.6.2:";;
+     short | recursive ) echo "Configuration of cdo 1.6.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1590,7 +1590,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cdo configure 1.6.2
+cdo configure 1.6.3
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2183,7 +2183,7 @@ 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 cdo $as_me 1.6.2, which was
+It was created by cdo $as_me 1.6.3, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3077,7 +3077,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdo'
- VERSION='1.6.2'
+ VERSION='1.6.3'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -16234,6 +16234,7 @@ case "$CC" in
   *gcc*)  COMP_VERSION=`$CC --version | head -n 1`;;
   g++*)   COMP_VERSION=`$CC --version | head -n 1`;;
   clang*) COMP_VERSION=`$CC --version | head -n 1`;;
+  icc*)   COMP_VERSION=`$CC --version | head -n 1`;;
   sxc*)   COMP_VERSION=`$CC -V 2>&1   | tail -n 1`;;
   xlc*)   COMP_VERSION=`$CC -qversion 2>&1   | head -n 1`;;
   *)      COMP_VERSION=`$CC -V 2>&1   | head -n 1` | grep -v error;;
@@ -20024,7 +20025,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by cdo $as_me 1.6.2, which was
+This file was extended by cdo $as_me 1.6.3, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -20090,7 +20091,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-cdo config.status 1.6.2
+cdo config.status 1.6.3
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 0728d92..b5837c4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
 # Process this file with autoconf to produce a configure script.
 
-AC_INIT([cdo], [1.6.2], [http://code.zmaw.de/projects/cdo])
+AC_INIT([cdo], [1.6.3], [http://code.zmaw.de/projects/cdo])
 
 CONFIG_ABORT=yes
 AC_CONFIG_AUX_DIR(config)
@@ -69,6 +69,7 @@ case "$CC" in
   *gcc*)  COMP_VERSION=`$CC --version | head -n 1`;;
   g++*)   COMP_VERSION=`$CC --version | head -n 1`;;
   clang*) COMP_VERSION=`$CC --version | head -n 1`;;
+  icc*)   COMP_VERSION=`$CC --version | head -n 1`;;
   sxc*)   COMP_VERSION=`$CC -V 2>&1   | tail -n 1`;;
   xlc*)   COMP_VERSION=`$CC -qversion 2>&1   | head -n 1`;;
   *)      COMP_VERSION=`$CC -V 2>&1   | head -n 1` | grep -v error;;
diff --git a/contrib/cdoCompletion.bash b/contrib/cdoCompletion.bash
index 1b0a0c4..b8f8b33 100644
--- a/contrib/cdoCompletion.bash
+++ b/contrib/cdoCompletion.bash
@@ -207,6 +207,7 @@ genbic -genbic \
 genbil -genbil \
 gencon -gencon \
 gencon2 -gencon2 \
+gencons -gencons \
 gendis -gendis \
 gengrid -gengrid \
 genlaf -genlaf \
@@ -219,8 +220,6 @@ gp2fc -gp2fc \
 gp2sp -gp2sp \
 gp2spl -gp2spl \
 gradsdes -gradsdes \
-gradsdes1 -gradsdes1 \
-gradsdes2 -gradsdes2 \
 graph -graph \
 grfill -grfill \
 gridarea -gridarea \
@@ -425,6 +424,7 @@ remapbil -remapbil \
 remapcon -remapcon \
 remapcon1 -remapcon1 \
 remapcon2 -remapcon2 \
+remapcons -remapcons \
 remapdis -remapdis \
 remapdis1 -remapdis1 \
 remapeta -remapeta \
@@ -449,6 +449,7 @@ runvar -runvar \
 runvar1 -runvar1 \
 scalllogo -scalllogo \
 scatter -scatter \
+sealevelpressure -sealevelpressure \
 seasavg -seasavg \
 seascount -seascount \
 seasmax -seasmax \
diff --git a/contrib/cdoCompletion.tcsh b/contrib/cdoCompletion.tcsh
index c9e5785..8b4f62b 100644
--- a/contrib/cdoCompletion.tcsh
+++ b/contrib/cdoCompletion.tcsh
@@ -207,6 +207,7 @@ genbic \
 genbil \
 gencon \
 gencon2 \
+gencons \
 gendis \
 gengrid \
 genlaf \
@@ -219,8 +220,6 @@ gp2fc \
 gp2sp \
 gp2spl \
 gradsdes \
-gradsdes1 \
-gradsdes2 \
 graph \
 grfill \
 gridarea \
@@ -425,6 +424,7 @@ remapbil \
 remapcon \
 remapcon1 \
 remapcon2 \
+remapcons \
 remapdis \
 remapdis1 \
 remapeta \
@@ -449,6 +449,7 @@ runvar \
 runvar1 \
 scalllogo \
 scatter \
+sealevelpressure \
 seasavg \
 seascount \
 seasmax \
diff --git a/contrib/cdoCompletion.zsh b/contrib/cdoCompletion.zsh
index c3a22ae..3576147 100644
--- a/contrib/cdoCompletion.zsh
+++ b/contrib/cdoCompletion.zsh
@@ -207,6 +207,7 @@ genbic -genbic \
 genbil -genbil \
 gencon -gencon \
 gencon2 -gencon2 \
+gencons -gencons \
 gendis -gendis \
 gengrid -gengrid \
 genlaf -genlaf \
@@ -219,8 +220,6 @@ gp2fc -gp2fc \
 gp2sp -gp2sp \
 gp2spl -gp2spl \
 gradsdes -gradsdes \
-gradsdes1 -gradsdes1 \
-gradsdes2 -gradsdes2 \
 graph -graph \
 grfill -grfill \
 gridarea -gridarea \
@@ -425,6 +424,7 @@ remapbil -remapbil \
 remapcon -remapcon \
 remapcon1 -remapcon1 \
 remapcon2 -remapcon2 \
+remapcons -remapcons \
 remapdis -remapdis \
 remapdis1 -remapdis1 \
 remapeta -remapeta \
@@ -449,6 +449,7 @@ runvar -runvar \
 runvar1 -runvar1 \
 scalllogo -scalllogo \
 scatter -scatter \
+sealevelpressure -sealevelpressure \
 seasavg -seasavg \
 seascount -seascount \
 seasmax -seasmax \
diff --git a/doc/cdo.pdf b/doc/cdo.pdf
index 3ef95fc..2af154a 100644
Binary files a/doc/cdo.pdf and b/doc/cdo.pdf differ
diff --git a/doc/cdo_refcard.pdf b/doc/cdo_refcard.pdf
index ff6f016..362dcd1 100644
Binary files a/doc/cdo_refcard.pdf and b/doc/cdo_refcard.pdf differ
diff --git a/libcdi/ChangeLog b/libcdi/ChangeLog
index 182d064..4a0d0fb 100644
--- a/libcdi/ChangeLog
+++ b/libcdi/ChangeLog
@@ -1,3 +1,37 @@
+2014-02-14  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* Version 1.6.3 released
+	* using CGRIBEX library version 1.6.3
+
+2014-02-03 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* gridInqUUID: changed return value from char* to void
+	* zaxisInqUUID: changed return value from char* to void
+
+2014-01-31 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* stream_cdf: added cdfDefZaxisUUID() [patch: Florian Prill]
+
+2014-01-13 Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* stream_cdf::define_all_grids: bug fix for unstructured grids and an additional undefined dimension [report: Florian Prill]
+
+2014-01-08  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* streamInqGinfo: added support for GRIB files > 2GB
+
+2014-01-03  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* streamOpenA, streamOpen: parameter recordBufIsToBeCreated missing in call to cdiStreamOpenDefaultDelegate() (bug fix)
+
+2013-12-09  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* streamOpenA: removed line "streamptr->record = record"; record is allocated in cdiStreamOpenDefaultDelegate() (bug fix)
+
+2013-11-28  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
+
+	* Merged branch cdi-pio to trunk cdi
+
 2013-11-12  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
 
 	* Version 1.6.2 released
@@ -9,7 +43,7 @@
 
 2013-11-04  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
 
-	* merged branch cdi-pio to trunk cdi
+	* Merged branch cdi-pio to trunk cdi
 
 2013-10-22  Uwe Schulzweida  <Uwe.Schulzweida at zmaw.de>
 
diff --git a/libcdi/Makefile.in b/libcdi/Makefile.in
index c02f693..a90b72d 100644
--- a/libcdi/Makefile.in
+++ b/libcdi/Makefile.in
@@ -54,6 +54,7 @@ subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(srcdir)/cdi.settings.in \
 	$(top_srcdir)/configure $(top_srcdir)/src/pkgconfig/cdi.pc.in \
+	$(top_srcdir)/src/pkgconfig/cdipio.pc.in \
 	$(top_srcdir)/util/serialrun.in AUTHORS COPYING ChangeLog \
 	INSTALL NEWS config/compile config/config.guess \
 	config/config.sub config/depcomp config/install-sh \
@@ -68,7 +69,7 @@ am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.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/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
 	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -77,7 +78,8 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
  configure.lineno config.status.lineno
 mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
 CONFIG_HEADER = $(top_builddir)/src/config.h
-CONFIG_CLEAN_FILES = util/serialrun cdi.settings src/pkgconfig/cdi.pc
+CONFIG_CLEAN_FILES = util/serialrun cdi.settings src/pkgconfig/cdi.pc \
+	src/pkgconfig/cdipio.pc
 CONFIG_CLEAN_VPATH_FILES =
 SOURCES =
 DIST_SOURCES =
@@ -149,13 +151,6 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
-BUILD_CC = @BUILD_CC@
-BUILD_CFLAGS = @BUILD_CFLAGS@
-BUILD_CXX = @BUILD_CXX@
-BUILD_F77 = @BUILD_F77@
-BUILD_FC = @BUILD_FC@
-BUILD_FCFLAGS = @BUILD_FCFLAGS@
-BUILD_LDFLAGS = @BUILD_LDFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CDI_F90_INTERFACE_FCFLAGS = @CDI_F90_INTERFACE_FCFLAGS@
@@ -393,6 +388,8 @@ cdi.settings: $(top_builddir)/config.status $(srcdir)/cdi.settings.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
 src/pkgconfig/cdi.pc: $(top_builddir)/config.status $(top_srcdir)/src/pkgconfig/cdi.pc.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
+src/pkgconfig/cdipio.pc: $(top_builddir)/config.status $(top_srcdir)/src/pkgconfig/cdipio.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
 
 mostlyclean-libtool:
 	-rm -f *.lo
diff --git a/libcdi/NEWS b/libcdi/NEWS
index 8cebf1a..9ca34ac 100644
--- a/libcdi/NEWS
+++ b/libcdi/NEWS
@@ -1,6 +1,15 @@
 CDI NEWS
 --------
 
+Version 1.6.3 (14 February 2014):
+
+   New features:
+     * streamInqGinfo: added support for GRIB files > 2GB
+   Fixed bugs:
+     * streamOpenA, streamOpen: parameter recordBufIsToBeCreated missing in call to cdiStreamOpenDefaultDelegate()
+     * streamOpenA: removed line "streamptr->record = record"; record is allocated in cdiStreamOpenDefaultDelegate()
+
+
 Version 1.6.2 (12 November 2013):
 
    New features:
diff --git a/libcdi/aclocal.m4 b/libcdi/aclocal.m4
index 5c27e11..6d55539 100644
--- a/libcdi/aclocal.m4
+++ b/libcdi/aclocal.m4
@@ -20,164 +20,6 @@ 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'.])])
 
-# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
-# serial 1 (pkg-config-0.24)
-# 
-# Copyright © 2004 Scott James Remnant <scott at netsplit.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 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.
-#
-# 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.
-
-# PKG_PROG_PKG_CONFIG([MIN-VERSION])
-# ----------------------------------
-AC_DEFUN([PKG_PROG_PKG_CONFIG],
-[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
-m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
-AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
-AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
-AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
-
-if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
-	AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
-fi
-if test -n "$PKG_CONFIG"; then
-	_pkg_min_version=m4_default([$1], [0.9.0])
-	AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
-	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
-		AC_MSG_RESULT([yes])
-	else
-		AC_MSG_RESULT([no])
-		PKG_CONFIG=""
-	fi
-fi[]dnl
-])# PKG_PROG_PKG_CONFIG
-
-# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
-#
-# Check to see whether a particular set of modules exists.  Similar
-# to PKG_CHECK_MODULES(), but does not set variables or print errors.
-#
-# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
-# only at the first occurence in configure.ac, so if the first place
-# it's called might be skipped (such as if it is within an "if", you
-# have to call PKG_CHECK_EXISTS manually
-# --------------------------------------------------------------
-AC_DEFUN([PKG_CHECK_EXISTS],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-if test -n "$PKG_CONFIG" && \
-    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
-  m4_default([$2], [:])
-m4_ifvaln([$3], [else
-  $3])dnl
-fi])
-
-# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
-# ---------------------------------------------
-m4_define([_PKG_CONFIG],
-[if test -n "$$1"; then
-    pkg_cv_[]$1="$$1"
- elif test -n "$PKG_CONFIG"; then
-    PKG_CHECK_EXISTS([$3],
-                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
-		     [pkg_failed=yes])
- else
-    pkg_failed=untried
-fi[]dnl
-])# _PKG_CONFIG
-
-# _PKG_SHORT_ERRORS_SUPPORTED
-# -----------------------------
-AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
-        _pkg_short_errors_supported=yes
-else
-        _pkg_short_errors_supported=no
-fi[]dnl
-])# _PKG_SHORT_ERRORS_SUPPORTED
-
-
-# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
-# [ACTION-IF-NOT-FOUND])
-#
-#
-# Note that if there is a possibility the first call to
-# PKG_CHECK_MODULES might not happen, you should be sure to include an
-# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
-#
-#
-# --------------------------------------------------------------
-AC_DEFUN([PKG_CHECK_MODULES],
-[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
-AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
-AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
-
-pkg_failed=no
-AC_MSG_CHECKING([for $1])
-
-_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
-_PKG_CONFIG([$1][_LIBS], [libs], [$2])
-
-m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
-and $1[]_LIBS to avoid the need to call pkg-config.
-See the pkg-config man page for more details.])
-
-if test $pkg_failed = yes; then
-   	AC_MSG_RESULT([no])
-        _PKG_SHORT_ERRORS_SUPPORTED
-        if test $_pkg_short_errors_supported = yes; then
-	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1`
-        else 
-	        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1`
-        fi
-	# Put the nasty error message in config.log where it belongs
-	echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
-
-	m4_default([$4], [AC_MSG_ERROR(
-[Package requirements ($2) were not met:
-
-$$1_PKG_ERRORS
-
-Consider adjusting the PKG_CONFIG_PATH environment variable if you
-installed software in a non-standard prefix.
-
-_PKG_TEXT])[]dnl
-        ])
-elif test $pkg_failed = untried; then
-     	AC_MSG_RESULT([no])
-	m4_default([$4], [AC_MSG_FAILURE(
-[The pkg-config script could not be found or is too old.  Make sure it
-is in your PATH or set the PKG_CONFIG environment variable to the full
-path to pkg-config.
-
-_PKG_TEXT
-
-To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
-        ])
-else
-	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
-	$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
-        AC_MSG_RESULT([yes])
-	$3
-fi[]dnl
-])# PKG_CHECK_MODULES
-
 # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
 # Foundation, Inc.
 #
@@ -850,6 +692,41 @@ AC_MSG_RESULT([$_am_result])
 rm -f confinc confmf
 ])
 
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_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, 1999, 2000, 2001, 2003, 2004, 2005, 2008
@@ -1179,5 +1056,6 @@ m4_include([m4/ltoptions.m4])
 m4_include([m4/ltsugar.m4])
 m4_include([m4/ltversion.m4])
 m4_include([m4/lt~obsolete.m4])
+m4_include([m4/pkg.m4])
 m4_include([m4/starlink_fpp.m4])
 m4_include([acinclude.m4])
diff --git a/libcdi/app/Makefile.in b/libcdi/app/Makefile.in
index 53aebcb..4253fed 100644
--- a/libcdi/app/Makefile.in
+++ b/libcdi/app/Makefile.in
@@ -67,7 +67,7 @@ am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.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/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
 	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -123,13 +123,6 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
-BUILD_CC = @BUILD_CC@
-BUILD_CFLAGS = @BUILD_CFLAGS@
-BUILD_CXX = @BUILD_CXX@
-BUILD_F77 = @BUILD_F77@
-BUILD_FC = @BUILD_FC@
-BUILD_FCFLAGS = @BUILD_FCFLAGS@
-BUILD_LDFLAGS = @BUILD_LDFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CDI_F90_INTERFACE_FCFLAGS = @CDI_F90_INTERFACE_FCFLAGS@
diff --git a/libcdi/cdi.settings.in b/libcdi/cdi.settings.in
index 2b27c67..d1ea566 100644
--- a/libcdi/cdi.settings.in
+++ b/libcdi/cdi.settings.in
@@ -44,7 +44,7 @@
     "lib"      : "@NETCDF_LIBS@",
     "include"  : "@NETCDF_INCLUDE@"
   },
-  "grip_api" : {
+  "grib_api" : {
     "lib"      : "@GRIB_API_LIBS@",
     "include"  : "@GRIB_API_INCLUDE@"
   },
diff --git a/libcdi/configure b/libcdi/configure
index bb3063b..eefae9c 100755
--- a/libcdi/configure
+++ b/libcdi/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for cdi 1.6.2.
+# Generated by GNU Autoconf 2.68 for cdi 1.6.3.
 #
 # Report bugs to <http://code.zmaw.de/projects/cdi>.
 #
@@ -570,8 +570,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='cdi'
 PACKAGE_TARNAME='cdi'
-PACKAGE_VERSION='1.6.2'
-PACKAGE_STRING='cdi 1.6.2'
+PACKAGE_VERSION='1.6.3'
+PACKAGE_STRING='cdi 1.6.3'
 PACKAGE_BUGREPORT='http://code.zmaw.de/projects/cdi'
 PACKAGE_URL=''
 
@@ -645,6 +645,8 @@ FC_MOD_FLAG
 CREATE_ISOC_FALSE
 CREATE_ISOC_TRUE
 USE_MPI
+USE_PPM_CORE_FALSE
+USE_PPM_CORE_TRUE
 USE_MPI_FALSE
 USE_MPI_TRUE
 HAVE_PARALLEL_NC4
@@ -1435,7 +1437,7 @@ 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 cdi 1.6.2 to adapt to many kinds of systems.
+\`configure' configures cdi 1.6.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1505,7 +1507,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of cdi 1.6.2:";;
+     short | recursive ) echo "Configuration of cdi 1.6.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1687,7 +1689,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-cdi configure 1.6.2
+cdi configure 1.6.3
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2448,7 +2450,7 @@ 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 cdi $as_me 1.6.2, which was
+It was created by cdi $as_me 1.6.3, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3345,7 +3347,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='cdi'
- VERSION='1.6.2'
+ VERSION='1.6.3'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -12122,6 +12124,132 @@ if test "x$ac_cv_prog_cc_c99" != xno; then :
 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
+
+
 ac_ext=${ac_fc_srcext-f}
 ac_compile='$FC -c $FCFLAGS $ac_fcflags_srcext conftest.$ac_ext >&5'
 ac_link='$FC -o conftest$ac_exeext $FCFLAGS $LDFLAGS $ac_fcflags_srcext conftest.$ac_ext $LIBS >&5'
@@ -15473,11 +15601,13 @@ fi
    rm -f conftest*
 
          done
+                  \rm a.out 2>/dev/null
 fi
       if test -z "$FPP"; then :
 
 else
   eval "$as_acx_sl_prog_fpp=\$FPP"
+
 fi
 fi
 eval ac_res=\$$as_acx_sl_prog_fpp
@@ -15632,7 +15762,7 @@ fi
       if test $ac_fpp_need_i = yes; then :
   acx_sl_prog_fc_cpp_i=no
          $as_echo "$as_me:${as_lineno-$LINENO}: Trying flag to add directories to preprocessor search path." >&5
-         mkdir conftst
+         as_dir=conftst; as_fn_mkdir_p
          cd conftst
 
    ac_ext=${ac_fc_srcext-f}
@@ -15770,9 +15900,8 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
    ac_ext="$acx_sl_fpp_srcext"
    cat > conftest.$ac_ext <<_ACEOF
                  program main
-
 #define LONG '901234567890123456789012345678901234567890123456789012345678901234567890'
-      CHARACTER*80 A
+      CHARACTER(LEN=80) :: A
       A=LONG
 
       end
@@ -15904,7 +16033,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
    ac_ext="$acx_sl_fpp_srcext"
    cat > conftest.$ac_ext <<_ACEOF
                  PROGRAM MAIN
-      CHARACTER*10 C
+      CHARACTER(LEN=10) :: C
       C = "abcde" // "fghij"; END PROGRAM
 
 
@@ -15948,7 +16077,7 @@ ac_compiler_gnu=$ac_cv_fc_compiler_gnu
    ac_ext="$acx_sl_fpp_srcext"
    cat > conftest.$ac_ext <<_ACEOF
                  PROGRAM MAIN
-      CHARACTER*10 C
+      CHARACTER(LEN=10) :: C
       C = "abcde" // "fghij"; END PROGRAM
 
 
@@ -23394,6 +23523,232 @@ else
   RANLIB="$ac_cv_prog_RANLIB"
 fi
 
+# -----------------------------------------------------------------------
+# Check endianess of system
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_bigendian=unknown
+    # See if we're dealing with a universal compiler.
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __APPLE_CC__
+	       not a universal capable compiler
+	     #endif
+	     typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+	# Check for potential -arch flags.  It is not universal unless
+	# there are at least two -arch flags with different values.
+	ac_arch=
+	ac_prev=
+	for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+	 if test -n "$ac_prev"; then
+	   case $ac_word in
+	     i?86 | x86_64 | ppc | ppc64)
+	       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+		 ac_arch=$ac_word
+	       else
+		 ac_cv_c_bigendian=universal
+		 break
+	       fi
+	       ;;
+	   esac
+	   ac_prev=
+	 elif test "x$ac_word" = "x-arch"; then
+	   ac_prev=arch
+	 fi
+       done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if sys/param.h defines the BYTE_ORDER macro.
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+	     #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+		     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+		     && LITTLE_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+		#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+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
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to _BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+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
+    if test $ac_cv_c_bigendian = unknown; then
+      # Compile a test program.
+      if test "$cross_compiling" = yes; then :
+  # Try to guess by grepping values from an object file.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+short int ascii_mm[] =
+		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+		short int ascii_ii[] =
+		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+		int use_ascii (int i) {
+		  return ascii_mm[i] + ascii_ii[i];
+		}
+		short int ebcdic_ii[] =
+		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+		short int ebcdic_mm[] =
+		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+		int use_ebcdic (int i) {
+		  return ebcdic_mm[i] + ebcdic_ii[i];
+		}
+		extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+	      ac_cv_c_bigendian=yes
+	    fi
+	    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+	      if test "$ac_cv_c_bigendian" = unknown; then
+		ac_cv_c_bigendian=no
+	      else
+		# finding both strings is unlikely to happen, but who knows?
+		ac_cv_c_bigendian=unknown
+	      fi
+	    fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+	     /* Are we little or big endian?  From Harbison&Steele.  */
+	     union
+	     {
+	       long int l;
+	       char c[sizeof (long int)];
+	     } u;
+	     u.l = 1;
+	     return u.c[sizeof (long int) - 1] == 1;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_bigendian=no
+else
+  ac_cv_c_bigendian=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
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+   yes)
+     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+   no)
+      ;; #(
+   universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+     ;; #(
+   *)
+     as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
 #  ----------------------------------------------------------------------
 # Check large file support on 32 bit systems
 # Check whether --enable-largefile was given.
@@ -23910,6 +24265,20 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+#
+# Check for non-standard builtin
+ac_fn_c_check_decl "$LINENO" "__builtin_ctz" "ac_cv_have_decl___builtin_ctz" "$ac_includes_default"
+if test "x$ac_cv_have_decl___builtin_ctz" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL___BUILTIN_CTZ $ac_have_decl
+_ACEOF
+
+
 # Check compiler version
 case "$CC" in
   pgcc*)  COMP_VERSION=`$CC -V | head -2 | tail -n 1`;;
@@ -26405,6 +26774,8 @@ if test x"${enable_mpi}" = x"yes"; then :
   USE_MPI=yes
 fi
 HAVE_PARALLEL_NC4=0
+enable_ppm=no
+
 
 
 
@@ -26653,6 +27024,7 @@ if test -n "$YAXT_CFLAGS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_YAXT_CFLAGS=`$PKG_CONFIG --cflags "yaxt" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -26669,6 +27041,7 @@ if test -n "$YAXT_LIBS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_YAXT_LIBS=`$PKG_CONFIG --libs "yaxt" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -26688,9 +27061,9 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        YAXT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "yaxt" 2>&1`
+	        YAXT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "yaxt" 2>&1`
         else
-	        YAXT_PKG_ERRORS=`$PKG_CONFIG --print-errors "yaxt" 2>&1`
+	        YAXT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "yaxt" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$YAXT_PKG_ERRORS" >&5
@@ -26749,7 +27122,6 @@ fi
 
 done
 
-                  if test $HAVE_PARALLEL_NC4 = 1; then :
 
 pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PPM_CORE" >&5
@@ -26765,6 +27137,7 @@ if test -n "$PPM_CORE_CFLAGS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_PPM_CORE_CFLAGS=`$PKG_CONFIG --cflags "scales-ppm-core" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -26781,6 +27154,7 @@ if test -n "$PPM_CORE_LIBS"; then
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; then
   pkg_cv_PPM_CORE_LIBS=`$PKG_CONFIG --libs "scales-ppm-core" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
 else
   pkg_failed=yes
 fi
@@ -26800,9 +27174,9 @@ else
         _pkg_short_errors_supported=no
 fi
         if test $_pkg_short_errors_supported = yes; then
-	        PPM_CORE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "scales-ppm-core" 2>&1`
+	        PPM_CORE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "scales-ppm-core" 2>&1`
         else
-	        PPM_CORE_PKG_ERRORS=`$PKG_CONFIG --print-errors "scales-ppm-core" 2>&1`
+	        PPM_CORE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "scales-ppm-core" 2>&1`
         fi
 	# Put the nasty error message in config.log where it belongs
 	echo "$PPM_CORE_PKG_ERRORS" >&5
@@ -26823,8 +27197,6 @@ $as_echo "#define HAVE_PPM_CORE /**/" >>confdefs.h
 
 
 fi
-
-fi
                   if test x$enable_ppm != xyes; then :
   HAVE_PARALLEL_NC4=0
 fi
@@ -26849,6 +27221,14 @@ else
   USE_MPI_FALSE=
 fi
 
+ if test $enable_ppm = yes; then
+  USE_PPM_CORE_TRUE=
+  USE_PPM_CORE_FALSE='#'
+else
+  USE_PPM_CORE_TRUE='#'
+  USE_PPM_CORE_FALSE=
+fi
+
 
 #  ----------------------------------------------------------------------
 #  Create the Fortran Interface via iso_c_binding module (Fortran 2003 Standard)
@@ -27317,24 +27697,6 @@ else
 fi
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 # Checks for compiler
 COMPILER="$CC $CFLAGS"
 
@@ -27343,10 +27705,10 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-ac_config_files="$ac_config_files tests/test_cksum_grib tests/test_cksum_nc tests/test_cksum_nc2 tests/test_cksum_nc4 tests/test_cksum_extra tests/test_cksum_service tests/test_cksum_ieg tests/test_chunk_cksum tests/pio_write_run tests/pio_cksum_mpinonb tests/pio_cksum_fpguard tests/pio_cksum_asynch tests/pio_cksum_writer tests/pio_cksum_cdf util/serialrun"
+ac_config_files="$ac_config_files tests/test_cksum_grib tests/test_cksum_nc tests/test_cksum_nc2 tests/test_cksum_nc4 tests/test_cksum_extra tests/test_cksum_service tests/test_cksum_ieg tests/test_chunk_cksum tests/pio_write_run tests/pio_write_deco2d_run tests/pio_cksum_mpinonb tests/pio_cksum_fpguard tests/pio_cksum_asynch tests/pio_cksum_writer tests/pio_cksum_cdf tests/test_resource_copy_mpi_run util/serialrun"
 
 
-ac_config_files="$ac_config_files Makefile src/Makefile interfaces/Makefile app/Makefile tests/Makefile examples/Makefile cdi.settings examples/pio/Makefile src/pkgconfig/cdi.pc"
+ac_config_files="$ac_config_files Makefile src/Makefile interfaces/Makefile app/Makefile tests/Makefile examples/Makefile cdi.settings examples/pio/Makefile src/pkgconfig/cdi.pc src/pkgconfig/cdipio.pc"
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -27481,6 +27843,7 @@ 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_CDI_LIB_TRUE}" && test -z "${ENABLE_CDI_LIB_FALSE}"; then
   as_fn_error $? "conditional \"ENABLE_CDI_LIB\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -27493,6 +27856,10 @@ if test -z "${USE_MPI_TRUE}" && test -z "${USE_MPI_FALSE}"; then
   as_fn_error $? "conditional \"USE_MPI\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${USE_PPM_CORE_TRUE}" && test -z "${USE_PPM_CORE_FALSE}"; then
+  as_fn_error $? "conditional \"USE_PPM_CORE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${CREATE_ISOC_TRUE}" && test -z "${CREATE_ISOC_FALSE}"; then
   as_fn_error $? "conditional \"CREATE_ISOC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -27933,7 +28300,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by cdi $as_me 1.6.2, which was
+This file was extended by cdi $as_me 1.6.3, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -27999,7 +28366,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-cdi config.status 1.6.2
+cdi config.status 1.6.3
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
@@ -28693,11 +29060,13 @@ do
     "tests/test_cksum_ieg") CONFIG_FILES="$CONFIG_FILES tests/test_cksum_ieg" ;;
     "tests/test_chunk_cksum") CONFIG_FILES="$CONFIG_FILES tests/test_chunk_cksum" ;;
     "tests/pio_write_run") CONFIG_FILES="$CONFIG_FILES tests/pio_write_run" ;;
+    "tests/pio_write_deco2d_run") CONFIG_FILES="$CONFIG_FILES tests/pio_write_deco2d_run" ;;
     "tests/pio_cksum_mpinonb") CONFIG_FILES="$CONFIG_FILES tests/pio_cksum_mpinonb" ;;
     "tests/pio_cksum_fpguard") CONFIG_FILES="$CONFIG_FILES tests/pio_cksum_fpguard" ;;
     "tests/pio_cksum_asynch") CONFIG_FILES="$CONFIG_FILES tests/pio_cksum_asynch" ;;
     "tests/pio_cksum_writer") CONFIG_FILES="$CONFIG_FILES tests/pio_cksum_writer" ;;
     "tests/pio_cksum_cdf") CONFIG_FILES="$CONFIG_FILES tests/pio_cksum_cdf" ;;
+    "tests/test_resource_copy_mpi_run") CONFIG_FILES="$CONFIG_FILES tests/test_resource_copy_mpi_run" ;;
     "util/serialrun") CONFIG_FILES="$CONFIG_FILES util/serialrun" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
@@ -28708,6 +29077,7 @@ do
     "cdi.settings") CONFIG_FILES="$CONFIG_FILES cdi.settings" ;;
     "examples/pio/Makefile") CONFIG_FILES="$CONFIG_FILES examples/pio/Makefile" ;;
     "src/pkgconfig/cdi.pc") CONFIG_FILES="$CONFIG_FILES src/pkgconfig/cdi.pc" ;;
+    "src/pkgconfig/cdipio.pc") CONFIG_FILES="$CONFIG_FILES src/pkgconfig/cdipio.pc" ;;
 
   *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
@@ -30523,11 +30893,13 @@ _LT_EOF
     "tests/test_cksum_ieg":F) chmod a+x "$ac_file" ;;
     "tests/test_chunk_cksum":F) chmod a+x "$ac_file" ;;
     "tests/pio_write_run":F) chmod a+x "$ac_file" ;;
+    "tests/pio_write_deco2d_run":F) chmod a+x "$ac_file" ;;
     "tests/pio_cksum_mpinonb":F) chmod a+x "$ac_file" ;;
     "tests/pio_cksum_fpguard":F) chmod a+x "$ac_file" ;;
     "tests/pio_cksum_asynch":F) chmod a+x "$ac_file" ;;
     "tests/pio_cksum_writer":F) chmod a+x "$ac_file" ;;
     "tests/pio_cksum_cdf":F) chmod a+x "$ac_file" ;;
+    "tests/test_resource_copy_mpi_run":F) chmod a+x "$ac_file" ;;
     "util/serialrun":F) chmod a+x "$ac_file" ;;
 
   esac
diff --git a/libcdi/configure.ac b/libcdi/configure.ac
index 172e342..3dd8467 100644
--- a/libcdi/configure.ac
+++ b/libcdi/configure.ac
@@ -1,6 +1,6 @@
 #  Process this file with autoconf to produce a configure script.
 
-AC_INIT([cdi], [1.6.2], [http://code.zmaw.de/projects/cdi])
+AC_INIT([cdi], [1.6.3], [http://code.zmaw.de/projects/cdi])
 
 echo "configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}"
 
@@ -22,6 +22,7 @@ LT_INIT([pic-only])
 # Check building environment
 AC_CHECK_TOOL([CC],[gcc],[:])
 AC_PROG_CC_C99
+AM_PROG_CC_C_O
 AC_PROG_FC
 AS_IF([test -n "$FC" && test "X$FC" != "Xno"],
   [AC_FC_SRCEXT([f90])
@@ -42,6 +43,9 @@ AC_CHECK_TOOL([DLLTOOL],[dlltool],[:])
 AC_CHECK_TOOL([OBJDUMP],[objdump],[:])
 AC_CHECK_TOOL([STRIP],[strip],[:])
 AC_CHECK_TOOL([RANLIB],[ranlib],[:])
+# -----------------------------------------------------------------------
+# Check endianess of system
+AC_C_BIGENDIAN
 #  ----------------------------------------------------------------------
 # Check large file support on 32 bit systems
 AC_SYS_LARGEFILE
@@ -66,6 +70,10 @@ AC_CHECK_FUNCS([getline])
 AC_CHECK_DECLS([isnan],,,[AC_INCLUDES_DEFAULT
 @%:@include <math.h>])
 
+#
+# Check for non-standard builtin
+AC_CHECK_DECLS([__builtin_ctz])
+
 # Check compiler version
 case "$CC" in
   pgcc*)  COMP_VERSION=`$CC -V | head -2 | tail -n 1`;;
@@ -109,6 +117,7 @@ AC_ARG_ENABLE(mpi,AS_HELP_STRING([--enable-mpi],[Compile with MPI compiler [defa
 AS_IF([test x"${enable_mpi}" = x"yes"],
       [USE_MPI=yes])
 HAVE_PARALLEL_NC4=0
+enable_ppm=no
 AS_IF([test x"$USE_MPI" = xyes],
   [AC_DEFINE([USE_MPI],[1],[parallel I/O requested and available])
    AC_PATH_PROGS([MPI_LAUNCH],[mpirun mpiexec],[true])
@@ -172,14 +181,12 @@ main(int argc, char **argv)
 ])
       dnl parallel netCDF support still requires ScalES-PPM and YAXT to
       dnl re-arrange the data when running with more than one collector
-      AS_IF([test $HAVE_PARALLEL_NC4 = 1],
-        [PKG_CHECK_MODULES([PPM_CORE],[scales-ppm-core],
-           [enable_ppm=yes
-            AC_DEFINE([HAVE_PPM_CORE],,
-              [ScalES PPM C core library is available])
-           ],
-           [enable_ppm=no])
-        ])
+      PKG_CHECK_MODULES([PPM_CORE],[scales-ppm-core],
+        [enable_ppm=yes
+         AC_DEFINE([HAVE_PPM_CORE],,
+           [ScalES PPM C core library is available])
+        ],
+        [enable_ppm=no])
       dnl if not both scales-ppm and yaxt are available, netcdf can only be
       dnl used in serial mode
       AS_IF([test x$enable_ppm != xyes],
@@ -193,6 +200,7 @@ AS_IF([test $HAVE_PARALLEL_NC4 -gt 0],
              [netCDF library does support MPI parallel invocations])])
 AC_SUBST([HAVE_PARALLEL_NC4])
 AM_CONDITIONAL([USE_MPI],[test x"$USE_MPI" = xyes])
+AM_CONDITIONAL([USE_PPM_CORE],[test $enable_ppm = yes])
 AC_SUBST([USE_MPI])
 #  ----------------------------------------------------------------------
 #  Create the Fortran Interface via iso_c_binding module (Fortran 2003 Standard)
@@ -275,31 +283,38 @@ AM_CONDITIONAL(CREATE_INTERFACES, [test  "x$enable_ruby" = "xyes" -o "x$enable_p
 #  ----------------------------------------------------------------------
 #  Check C / Fortran interface
 ACX_CHECK_CFINT([$srcdir/src/cfortran.h])
-AM_CONDITIONAL([USE_FC],[test -n "$FC" && test "X$FC" != "Xno" && test x$acx_cv_check_cfint = "xyes"])
-
-AC_SUBST([CPPFLAGS])
-
+AM_CONDITIONAL([USE_FC],[test -n "$FC" && test "X$FC" != "Xno" && test x$acx_cv_check_cfint = "xyes"])dnl
+dnl
+AC_SUBST([CPPFLAGS])dnl
+dnl
 AC_ARG_VAR([BUILD_CFLAGS],
-  [append to CFLAGS during build but not in configure phase])
-AC_CONFIG_COMMANDS_PRE([CFLAGS="$CFLAGS${BUILD_CFLAGS+ $BUILD_CFLAGS}"])
+  [append to CFLAGS during build but not in configure phase])dnl
+AC_CONFIG_COMMANDS_PRE([CFLAGS="$CFLAGS${BUILD_CFLAGS+ $BUILD_CFLAGS}"])dnl
+AM_SUBST_NOTMAKE([BUILD_CFLAGS])dnl
 AC_ARG_VAR([BUILD_FCFLAGS],
-  [append to FCFLAGS during build but not in configure phase])
-AC_CONFIG_COMMANDS_PRE([FCFLAGS="$FCFLAGS${BUILD_FCFLAGS+ $BUILD_FCFLAGS}"])
+  [append to FCFLAGS during build but not in configure phase])dnl
+AC_CONFIG_COMMANDS_PRE([FCFLAGS="$FCFLAGS${BUILD_FCFLAGS+ $BUILD_FCFLAGS}"])dnl
+AM_SUBST_NOTMAKE([BUILD_FCFLAGS])dnl
 AC_ARG_VAR([BUILD_LDFLAGS],
-  [append to LDFLAGS during build but not in configure phase])
-AC_CONFIG_COMMANDS_PRE([LDFLAGS="$LDFLAGS${BUILD_LDFLAGS+ $BUILD_LDFLAGS}"])
+  [append to LDFLAGS during build but not in configure phase])dnl
+AC_CONFIG_COMMANDS_PRE([LDFLAGS="$LDFLAGS${BUILD_LDFLAGS+ $BUILD_LDFLAGS}"])dnl
+AM_SUBST_NOTMAKE([BUILD_LDFLAGS])dnl
 AC_ARG_VAR([BUILD_CC],
-  [replace CC with expansion of $BUILD_CC during build but not in configure phase])
-AC_CONFIG_COMMANDS_PRE([CC="${BUILD_CC-$CC}"])
+  [replace CC with expansion of $BUILD_CC during build but not in configure phase])dnl
+AC_CONFIG_COMMANDS_PRE([CC="${BUILD_CC-$CC}"])dnl
+AM_SUBST_NOTMAKE([BUILD_CC])dnl
 AC_ARG_VAR([BUILD_CXX],
-  [replace CXX with expansion of $BUILD_CXX during build but not in configure phase])
-AC_CONFIG_COMMANDS_PRE([CXX="${BUILD_CXX-$CXX}"])
+  [replace CXX with expansion of $BUILD_CXX during build but not in configure phase])dnl
+AC_CONFIG_COMMANDS_PRE([CXX="${BUILD_CXX-$CXX}"])dnl
+AM_SUBST_NOTMAKE([BUILD_CXX])dnl
 AC_ARG_VAR([BUILD_FC],
-  [replace FC with expansion of $BUILD_FC during build but not in configure phase])
-AC_CONFIG_COMMANDS_PRE([FC="${BUILD_FC-$FC}"])
+  [replace FC with expansion of $BUILD_FC during build but not in configure phase])dnl
+AC_CONFIG_COMMANDS_PRE([FC="${BUILD_FC-$FC}"])dnl
+AM_SUBST_NOTMAKE([BUILD_FC])dnl
 AC_ARG_VAR([BUILD_F77],
-  [replace F77 with expansion of $BUILD_F77 during build but not in configure phase])
-AC_CONFIG_COMMANDS_PRE([F77="${BUILD_F77-$F77}"])
+  [replace F77 with expansion of $BUILD_F77 during build but not in configure phase])dnl
+AC_CONFIG_COMMANDS_PRE([F77="${BUILD_F77-$F77}"])dnl
+AM_SUBST_NOTMAKE([BUILD_F77])dnl
 
 
 # Checks for compiler
@@ -315,16 +330,18 @@ AC_CONFIG_FILES([tests/test_cksum_grib \
                  tests/test_cksum_ieg \
                  tests/test_chunk_cksum \
                  tests/pio_write_run \
+                 tests/pio_write_deco2d_run \
                  tests/pio_cksum_mpinonb \
                  tests/pio_cksum_fpguard \
                  tests/pio_cksum_asynch \
                  tests/pio_cksum_writer \
                  tests/pio_cksum_cdf \
+                 tests/test_resource_copy_mpi_run \
                  util/serialrun],[chmod a+x "$ac_file"])
 
 AC_OUTPUT([Makefile src/Makefile interfaces/Makefile app/Makefile \
 	tests/Makefile examples/Makefile cdi.settings \
-	examples/pio/Makefile src/pkgconfig/cdi.pc])
+	examples/pio/Makefile src/pkgconfig/cdi.pc src/pkgconfig/cdipio.pc])
 
 #  ----------------------------------------------------------------------
 #  Show configuration
diff --git a/libcdi/doc/cdi_cman.pdf b/libcdi/doc/cdi_cman.pdf
index 90a0845..a72e359 100644
Binary files a/libcdi/doc/cdi_cman.pdf and b/libcdi/doc/cdi_cman.pdf differ
diff --git a/libcdi/doc/cdi_fman.pdf b/libcdi/doc/cdi_fman.pdf
index 5aa2586..36d2ad1 100644
Binary files a/libcdi/doc/cdi_fman.pdf and b/libcdi/doc/cdi_fman.pdf differ
diff --git a/libcdi/examples/Makefile.am b/libcdi/examples/Makefile.am
index 30217b3..e0a0d84 100644
--- a/libcdi/examples/Makefile.am
+++ b/libcdi/examples/Makefile.am
@@ -37,12 +37,5 @@ cdi_read_LDFLAGS         = -all-static
 cdi_copy_LDFLAGS         = -all-static
 cdi_read_f2003_LDFLAGS   = -all-static
 cdi_write_f2003_LDFLAGS  = -all-static
-cdi_read_f2003_LDFLAGS  = -all-static
-cdi_write_f2003_LDFLAGS = -all-static
 endif
-cdi_read_f2003_SOURCES  = cdi_read_f2003.f90
-cdi_read_f2003_LDADD    = $(top_builddir)/src/libcdi.la $(top_builddir)/src/mo_cdi.o
-
-cdi_write_f2003_SOURCES = cdi_write_f2003.f90
-cdi_write_f2003_LDADD   = $(top_builddir)/src/libcdi.la $(top_builddir)/src/mo_cdi.o
 
diff --git a/libcdi/examples/Makefile.in b/libcdi/examples/Makefile.in
index 90281f3..78113c8 100644
--- a/libcdi/examples/Makefile.in
+++ b/libcdi/examples/Makefile.in
@@ -67,7 +67,7 @@ am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.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/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
 	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -161,13 +161,6 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
-BUILD_CC = @BUILD_CC@
-BUILD_CFLAGS = @BUILD_CFLAGS@
-BUILD_CXX = @BUILD_CXX@
-BUILD_F77 = @BUILD_F77@
-BUILD_FC = @BUILD_FC@
-BUILD_FCFLAGS = @BUILD_FCFLAGS@
-BUILD_LDFLAGS = @BUILD_LDFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CDI_F90_INTERFACE_FCFLAGS = @CDI_F90_INTERFACE_FCFLAGS@
@@ -366,8 +359,10 @@ cdi_read_LDADD = $(top_builddir)/src/libcdi.la
 #
 cdi_copy_SOURCES = cdi_copy.c
 cdi_copy_LDADD = $(top_builddir)/src/libcdi.la
+#
 cdi_read_f2003_SOURCES = cdi_read_f2003.f90
 cdi_read_f2003_LDADD = $(top_builddir)/src/libcdi.la $(top_builddir)/src/mo_cdi.o
+#
 cdi_write_f2003_SOURCES = cdi_write_f2003.f90
 cdi_write_f2003_LDADD = $(top_builddir)/src/libcdi.la $(top_builddir)/src/mo_cdi.o
 #
diff --git a/libcdi/examples/pio/Makefile.am b/libcdi/examples/pio/Makefile.am
index b7f9222..5f28c90 100644
--- a/libcdi/examples/pio/Makefile.am
+++ b/libcdi/examples/pio/Makefile.am
@@ -14,16 +14,15 @@ endif
 
 collectData_SOURCES=collectData.c
 
-collectData_LDADD=$(top_builddir)/src/libcdi.la
+if USE_MPI
+LDADD=$(top_builddir)/src/libcdipio.la
+else
+LDADD=
+endif
+LDADD+=$(top_builddir)/src/libcdi.la
 
 collectData2003_SOURCES=collectData2003.F90
 
-collectData2003_LDADD=$(top_builddir)/src/libcdi.la
-
 collectDataNStreams_SOURCES=collectDataNStreams.c
 
-collectDataNStreams_LDADD=$(top_builddir)/src/libcdi.la
-
 compareResourcesArray_SOURCES=compareResourcesArray.c
-
-compareResourcesArray_LDADD=$(top_builddir)/src/libcdi.la
diff --git a/libcdi/examples/pio/Makefile.in b/libcdi/examples/pio/Makefile.in
index b6e4c57..90c57b1 100644
--- a/libcdi/examples/pio/Makefile.in
+++ b/libcdi/examples/pio/Makefile.in
@@ -68,7 +68,7 @@ am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.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/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
 	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -82,16 +82,36 @@ CONFIG_CLEAN_VPATH_FILES =
 PROGRAMS = $(noinst_PROGRAMS)
 am_collectData_OBJECTS = collectData.$(OBJEXT)
 collectData_OBJECTS = $(am_collectData_OBJECTS)
-collectData_DEPENDENCIES = $(top_builddir)/src/libcdi.la
+collectData_LDADD = $(LDADD)
+ at USE_MPI_FALSE@collectData_DEPENDENCIES =  \
+ at USE_MPI_FALSE@	$(top_builddir)/src/libcdi.la
+ at USE_MPI_TRUE@collectData_DEPENDENCIES =  \
+ at USE_MPI_TRUE@	$(top_builddir)/src/libcdipio.la \
+ at USE_MPI_TRUE@	$(top_builddir)/src/libcdi.la
 am_collectData2003_OBJECTS = collectData2003.$(OBJEXT)
 collectData2003_OBJECTS = $(am_collectData2003_OBJECTS)
-collectData2003_DEPENDENCIES = $(top_builddir)/src/libcdi.la
+collectData2003_LDADD = $(LDADD)
+ at USE_MPI_FALSE@collectData2003_DEPENDENCIES =  \
+ at USE_MPI_FALSE@	$(top_builddir)/src/libcdi.la
+ at USE_MPI_TRUE@collectData2003_DEPENDENCIES =  \
+ at USE_MPI_TRUE@	$(top_builddir)/src/libcdipio.la \
+ at USE_MPI_TRUE@	$(top_builddir)/src/libcdi.la
 am_collectDataNStreams_OBJECTS = collectDataNStreams.$(OBJEXT)
 collectDataNStreams_OBJECTS = $(am_collectDataNStreams_OBJECTS)
-collectDataNStreams_DEPENDENCIES = $(top_builddir)/src/libcdi.la
+collectDataNStreams_LDADD = $(LDADD)
+ at USE_MPI_FALSE@collectDataNStreams_DEPENDENCIES =  \
+ at USE_MPI_FALSE@	$(top_builddir)/src/libcdi.la
+ at USE_MPI_TRUE@collectDataNStreams_DEPENDENCIES =  \
+ at USE_MPI_TRUE@	$(top_builddir)/src/libcdipio.la \
+ at USE_MPI_TRUE@	$(top_builddir)/src/libcdi.la
 am_compareResourcesArray_OBJECTS = compareResourcesArray.$(OBJEXT)
 compareResourcesArray_OBJECTS = $(am_compareResourcesArray_OBJECTS)
-compareResourcesArray_DEPENDENCIES = $(top_builddir)/src/libcdi.la
+compareResourcesArray_LDADD = $(LDADD)
+ at USE_MPI_FALSE@compareResourcesArray_DEPENDENCIES =  \
+ at USE_MPI_FALSE@	$(top_builddir)/src/libcdi.la
+ at USE_MPI_TRUE@compareResourcesArray_DEPENDENCIES =  \
+ at USE_MPI_TRUE@	$(top_builddir)/src/libcdipio.la \
+ at USE_MPI_TRUE@	$(top_builddir)/src/libcdi.la
 DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)/src
 depcomp = $(SHELL) $(top_srcdir)/config/depcomp
 am__depfiles_maybe = depfiles
@@ -136,13 +156,6 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
-BUILD_CC = @BUILD_CC@
-BUILD_CFLAGS = @BUILD_CFLAGS@
-BUILD_CXX = @BUILD_CXX@
-BUILD_F77 = @BUILD_F77@
-BUILD_FC = @BUILD_FC@
-BUILD_FCFLAGS = @BUILD_FCFLAGS@
-BUILD_LDFLAGS = @BUILD_LDFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CDI_F90_INTERFACE_FCFLAGS = @CDI_F90_INTERFACE_FCFLAGS@
@@ -323,13 +336,12 @@ top_srcdir = @top_srcdir@
 AM_CPPFLAGS = -I$(top_srcdir)/src $(YAXT_CFLAGS)
 AM_FCFLAGS = $(FPP_INCOPT)$(top_srcdir)/src $(am__append_2)
 collectData_SOURCES = collectData.c
-collectData_LDADD = $(top_builddir)/src/libcdi.la
+ at USE_MPI_FALSE@LDADD = $(top_builddir)/src/libcdi.la
+ at USE_MPI_TRUE@LDADD = $(top_builddir)/src/libcdipio.la \
+ at USE_MPI_TRUE@	$(top_builddir)/src/libcdi.la
 collectData2003_SOURCES = collectData2003.F90
-collectData2003_LDADD = $(top_builddir)/src/libcdi.la
 collectDataNStreams_SOURCES = collectDataNStreams.c
-collectDataNStreams_LDADD = $(top_builddir)/src/libcdi.la
 compareResourcesArray_SOURCES = compareResourcesArray.c
-compareResourcesArray_LDADD = $(top_builddir)/src/libcdi.la
 all: all-am
 
 .SUFFIXES:
diff --git a/libcdi/examples/pio/collectData.c b/libcdi/examples/pio/collectData.c
index faddca7..9bda63b 100644
--- a/libcdi/examples/pio/collectData.c
+++ b/libcdi/examples/pio/collectData.c
@@ -17,6 +17,8 @@ typedef int MPI_Comm;
 #include "pio_util.h"
 
 #ifdef USE_MPI
+#include "cdipio.h"
+
 static int
 uniform_partition_start(int set_interval[2], int nparts, int part_idx);
 #endif
@@ -159,7 +161,8 @@ static void modelRun(MPI_Comm commModel)
 #endif
 }
 
-struct {
+#ifdef USE_MPI
+static struct {
   char *text;
   int mode;
 } mode_map[] = {
@@ -169,6 +172,7 @@ struct {
   { "PIO_WRITER", PIO_WRITER },
   { "PIO_FPGUARD", PIO_FPGUARD},
 };
+#endif
 
 
 int main (int argc, char *argv[])
@@ -217,13 +221,17 @@ int main (int argc, char *argv[])
       }
   }
 
-  commModel = pioInit(commGlob, nProcsIO, IOMode, &pioNamespace, 1.0f);
-  pioNamespaceSetActive(pioNamespace);
+  commModel = pioInit(commGlob, nProcsIO, IOMode, &pioNamespace, 1.0f,
+                      cdiPioNoPostCommSetup);
+  if (commModel != MPI_COMM_NULL)
+    {
+      namespaceSetActive(pioNamespace);
 #endif
 
-  modelRun(commModel);
+      modelRun(commModel);
 
 #ifdef USE_MPI
+    }
   pioFinalize ();
   xt_finalize();
   MPI_Finalize ();
diff --git a/libcdi/examples/pio/collectData2003.F90 b/libcdi/examples/pio/collectData2003.F90
index 111b6bc..25d2019 100644
--- a/libcdi/examples/pio/collectData2003.F90
+++ b/libcdi/examples/pio/collectData2003.F90
@@ -1,7 +1,3 @@
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
 PROGRAM collectdata2003
 #ifdef USE_MPI
   USE yaxt, ONLY: xt_initialize, xt_finalize, xt_idxlist, xt_idxstripes_new, &
@@ -11,6 +7,7 @@ PROGRAM collectdata2003
   IMPLICIT NONE
 
   INCLUDE 'cdi.inc'
+  INCLUDE 'cdipio.inc'
 
 #ifdef USE_MPI
   INCLUDE 'mpif.h'
@@ -29,6 +26,11 @@ PROGRAM collectdata2003
   INTEGER, PARAMETER :: IOMode       = PIO_FPGUARD
 
   INTEGER ::commGlob, commModel, error, pio_namespace
+#ifdef USE_MPI
+  LOGICAL :: run_model
+#else
+  LOGICAL, PARAMETER :: run_model = .TRUE.
+#endif
 
   ! Start parallel environment
 #ifdef USE_MPI
@@ -38,16 +40,18 @@ PROGRAM collectdata2003
 
   ! For parallel IO:
   ! Initialize environment.
-  commModel = pioInit(commGlob, nProcsIO, IOMode, pio_namespace, 1.1)
-  CALL pioNamespaceSetActive(pio_namespace)
+  commModel = pioInit(commGlob, nProcsIO, IOMode, pio_namespace, 1.1, &
+       cdiPioNoPostCommSetup)
+  run_model = commModel /= MPI_COMM_NULL
+  IF (run_model) CALL namespaceSetActive(pio_namespace)
 #endif
 
-  CALL modelrun ( commModel )
+  IF (run_model) CALL modelrun ( commModel )
 
 #ifdef USE_MPI
   ! For parallel IO:
   ! Cleanup environment.
-  CALL pioFinalize ()
+  IF (run_model) CALL pioFinalize ()
   CALL xt_finalize
   CALL MPI_FINALIZE ( error )
 #endif
diff --git a/libcdi/examples/pio/collectDataNStreams.c b/libcdi/examples/pio/collectDataNStreams.c
index a011b28..20f6266 100644
--- a/libcdi/examples/pio/collectDataNStreams.c
+++ b/libcdi/examples/pio/collectDataNStreams.c
@@ -12,6 +12,10 @@ typedef int MPI_Comm;
 #include "cdi.h"
 #include "pio_util.h"
 
+#ifdef USE_MPI
+#include "cdipio.h"
+#endif
+
 static void hoursPassingHack ( int * vdate, int * vtime, int hoursPassed )
 {
   int sum, days, hours, oldDays;
@@ -223,7 +227,9 @@ int main (int argc, char *argv[])
     nProcsIODef    = 3,
     //IOModeDef       = PIO_NONE,
     //IOModeDef       = PIO_MPI,
+#ifdef USE_MPI
     IOModeDef       = PIO_FPGUARD,
+#endif
     //IOModeDef       = PIO_ASYNCH,
     //IOModeDef       = PIO_WRITER,
   };
@@ -257,13 +263,17 @@ int main (int argc, char *argv[])
       nProcsIO = nProcsIODef;
     }
 
-  commModel = pioInit(commGlob, nProcsIO, IOMode, &pioNamespace, 1.0f);
-  pioNamespaceSetActive(pioNamespace);
+  commModel = pioInit(commGlob, nProcsIO, IOMode, &pioNamespace, 1.0f,
+                      cdiPioNoPostCommSetup);
+  if (commModel != MPI_COMM_NULL)
+    {
+      namespaceSetActive(pioNamespace);
 #endif
 
-  modelRun(commModel);
+      modelRun(commModel);
 
 #ifdef USE_MPI
+    }
   pioFinalize ();
   xt_finalize();
   MPI_Finalize ();
@@ -282,3 +292,13 @@ uniform_partition_start(int set_interval[2], int nparts, int part_idx)
   return start;
 }
 #endif
+
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
diff --git a/libcdi/examples/pio/compareResourcesArray.c b/libcdi/examples/pio/compareResourcesArray.c
index aaf246b..f7e0b9f 100644
--- a/libcdi/examples/pio/compareResourcesArray.c
+++ b/libcdi/examples/pio/compareResourcesArray.c
@@ -8,6 +8,8 @@
 #include <mpi.h>
 #include <yaxt.h>
 #include "cdi.h"
+#include "cdipio.h"
+#include "dmemory.h"
 #include "pio_util.h"
 #include "resource_handle.h"
 #include "resource_unpack.h"
@@ -190,7 +192,7 @@ static void modelRun ( MPI_Comm comm )
   int bufferSize, differ;
   MPI_Status status;
 
-  pioNamespaceSetActive ( 0 );
+  namespaceSetActive ( 0 );
 
   gridID  = defineGrid      ();
   zaxisID = defineZaxis     ();
@@ -208,7 +210,7 @@ static void modelRun ( MPI_Comm comm )
   xmpi ( MPI_Recv ( recvBuffer, bufferSize, MPI_PACKED, 0,
 		    0, comm, &status ));
 
-  pioNamespaceSetActive ( 1 );
+  namespaceSetActive ( 1 );
   reshUnpackResources(recvBuffer, bufferSize, &comm);
   free ( recvBuffer );
   reshPackBufferDestroy ( &sendBuffer );
@@ -217,7 +219,7 @@ static void modelRun ( MPI_Comm comm )
   printf ( "The resource arrays %s.\n", differ ? "differ" : "are equal" );
   printResources();
 
-  pioNamespaceSetActive ( 0 );
+  namespaceSetActive ( 0 );
   streamClose(streamID);
   return;
 }
@@ -242,8 +244,9 @@ int main (int argc, char *argv[])
   if ( nProcsIO != 1 )
     xabort ( "bad distribution of tasks on PEs" );
 
-  commModel = pioInit(commGlob, nProcsIO, IOMode, &pioNamespace, 1.0f);
-  pioNamespaceSetActive(pioNamespace);
+  commModel = pioInit(commGlob, nProcsIO, IOMode, &pioNamespace, 1.0f,
+                      cdiPioNoPostCommSetup);
+  namespaceSetActive(pioNamespace);
 
   modelRun ( commModel );
 
diff --git a/libcdi/interfaces/Makefile.in b/libcdi/interfaces/Makefile.in
index e1fc0c3..be51760 100644
--- a/libcdi/interfaces/Makefile.in
+++ b/libcdi/interfaces/Makefile.in
@@ -74,7 +74,7 @@ am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.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/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
 	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -140,13 +140,6 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
-BUILD_CC = @BUILD_CC@
-BUILD_CFLAGS = @BUILD_CFLAGS@
-BUILD_CXX = @BUILD_CXX@
-BUILD_F77 = @BUILD_F77@
-BUILD_FC = @BUILD_FC@
-BUILD_FCFLAGS = @BUILD_FCFLAGS@
-BUILD_LDFLAGS = @BUILD_LDFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CDI_F90_INTERFACE_FCFLAGS = @CDI_F90_INTERFACE_FCFLAGS@
diff --git a/libcdi/m4/pkg.m4 b/libcdi/m4/pkg.m4
new file mode 100644
index 0000000..9a71878
--- /dev/null
+++ b/libcdi/m4/pkg.m4
@@ -0,0 +1,159 @@
+# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
+# serial 1 (pkg-config-0.24)
+# 
+# Copyright © 2004 Scott James Remnant <scott at netsplit.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 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.
+#
+# 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.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=m4_default([$1], [0.9.0])
+	AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		AC_MSG_RESULT([yes])
+	else
+		AC_MSG_RESULT([no])
+		PKG_CONFIG=""
+	fi
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists.  Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+# only at the first occurence in configure.ac, so if the first place
+# it's called might be skipped (such as if it is within an "if", you
+# have to call PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+  m4_default([$2], [:])
+m4_ifvaln([$3], [else
+  $3])dnl
+fi])
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+    pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+    PKG_CHECK_EXISTS([$3],
+                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes ],
+		     [pkg_failed=yes])
+ else
+    pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+   	AC_MSG_RESULT([no])
+        _PKG_SHORT_ERRORS_SUPPORTED
+        if test $_pkg_short_errors_supported = yes; then
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+        else 
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+	m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+        ])
+elif test $pkg_failed = untried; then
+     	AC_MSG_RESULT([no])
+	m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
+        ])
+else
+	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+	$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+        AC_MSG_RESULT([yes])
+	$3
+fi[]dnl
+])# PKG_CHECK_MODULES
diff --git a/libcdi/m4/starlink_fpp.m4 b/libcdi/m4/starlink_fpp.m4
index 0d9e6df..7fb29d2 100644
--- a/libcdi/m4/starlink_fpp.m4
+++ b/libcdi/m4/starlink_fpp.m4
@@ -171,11 +171,15 @@ AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_SUBS],
 # to macro substitution.
 # If not, this gives an "unterminated character constant" error
 AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_WRAP],
-[AC_LANG_PROGRAM(,[
-@%:@define LONG '901234567890123456789012345678901234567890123456789012345678901234567890'
+[AC_LANG_PROGRAM(,[m4_case(_AC_LANG,[Fortran],
+[@%:@define LONG '901234567890123456789012345678901234567890123456789012345678901234567890'
+      CHARACTER(LEN=80) :: A
+      A=LONG
+],[Fortran 77],
+[@%:@define LONG '901234567890123456789012345678901234567890123456789012345678901234567890'
       CHARACTER*80 A
       A=LONG
-])])#_ACX_SL_LANG_PROGRAM_FPP_WRAP
+],[m4_fatal([$0: current language is not Fortran: ] _AC_LANG)])])])#_ACX_SL_LANG_PROGRAM_FPP_WRAP
 
 
 # _ACX_SL_LANG_PROGRAM_FPP_CSTYLE
@@ -190,11 +194,15 @@ AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_CSTYLE],
 # ---------------------------
 # Test program for C++ style comments
 AC_DEFUN([_ACX_SL_LANG_PROGRAM_FPP_CXXSTYLE],
-[AC_LANG_SOURCE([dnl
-      PROGRAM MAIN
+[AC_LANG_SOURCE([m4_case(_AC_LANG,[Fortran],dnl
+[      PROGRAM MAIN
+      CHARACTER(LEN=10) :: C
+      C = "abcde" // "fghij"; END PROGRAM
+],[Fortran 77],
+[      PROGRAM MAIN
       CHARACTER*10 C
       C = "abcde" // "fghij"; END PROGRAM
-])
+])])
 ])#_ACX_SL_LANG_PROGRAM_FPP_CXXSTYLE
 
 # _ACX_SL_SET_FPP_FEATURE_VARS ([feature list])
@@ -317,9 +325,12 @@ AC_DEFUN([_ACX_SL_PROG_FPP],dnl
            _ACX_SL_TEST_FPP([$ac_fpp -P],[$acx_sl_fpp_srcext],dnl
              [FPP="$ac_fpp -P"
               break])
-         done])
+         done
+         dnl the above tests might generate an executable
+         \rm a.out 2>/dev/null])
       AS_IF([test -z "$FPP"], [$3],
-        [AS_VAR_SET([acx_sl_prog_fpp], [$FPP])])])
+        [AS_VAR_SET([acx_sl_prog_fpp], [$FPP])
+         $2])])
    AS_VAR_PUSHDEF([acx_sl_prog_fpp])
 ])# _ACX_SL_PROG_FPP
 
@@ -373,7 +384,7 @@ m4_define([_ACX_FPP_COMPILE_IFELSE],dnl
      [_AC_RUN_LOG([$FPP $FPPFLAGS m4_ifval([$1],[$1 ])conftest.$acx_sl_fpp_srcext \
         >conftest.${ac_ext}.tmp],
         [echo Running preprocessor $FPP $FPPFLAGS m4_ifval([$1],[$1 ])conftest.$acx_sl_fpp_srcext])])
-   m4_if([$2],[direct], [FCFLAGS="$FPPFLAGS $1 $ac_save_FCFLAGS"])
+   m4_if([$2],[direct],[FCFLAGS="$FPPFLAGS $1 $ac_save_FCFLAGS"])
    mv conftest.${ac_ext}.tmp conftest.${ac_ext}
    AC_COMPILE_IFELSE(,[$3],[$4])])
 
@@ -444,7 +455,7 @@ AC_DEFUN([ACX_SL_PROG_FC_FPP_FEATURES],
       AS_IF([test $ac_fpp_need_i = yes],
         [acx_sl_prog_fc_cpp_i=no
          _AS_ECHO_LOG([Trying flag to add directories to preprocessor search path.])
-         mkdir conftst
+         AS_MKDIR_P([conftst])
          cd conftst
          ACX_LANG_OTHER_SUFFIX_CONFTEST([inc],dnl
            [AC_LANG_SOURCE([!     This statement overrides the IMPLICIT statement in the program
diff --git a/libcdi/src/Makefile.am b/libcdi/src/Makefile.am
index 8e31955..4d17f8f 100644
--- a/libcdi/src/Makefile.am
+++ b/libcdi/src/Makefile.am
@@ -27,13 +27,18 @@ libcdi_la_SOURCES = 	 \
 	cdi_limits.h	 \
 	cdi_util.c       \
 	cdiFortran.c     \
-	cdiFortran.h     \
 	cfortran.h       \
 	cgribex.h	 \
 	cgribexlib.c  	 \
 	datetime.h	 \
 	dmemory.c      	 \
 	dmemory.h	 \
+	cksum.c		\
+	cksum.h		\
+	cdi_cksum.c	\
+	cdi_cksum.h	\
+	pio_util.c							\
+	pio_util.h							\
 	dtypes.h	 \
 	error.c        	 \
 	error.h	 	 \
@@ -57,33 +62,6 @@ libcdi_la_SOURCES = 	 \
 	namespace.h      \
 	serialize.h	\
 	serialize.c	\
-	pio.c            \
-	pio.h            \
-	pio_comm.c       \
-	pio_comm.h       \
-	pio_dbuffer.c    \
-	pio_impl.h 	 \
-	pio_interface.c  \
-	pio_interface.h	 \
-	pio_mpinonb.c    \
-	pio_record_send.c\
-	pio_posixasynch.c\
-	pio_posixfpguardsendrecv.c \
-	pio_posixnonb.c  \
-	pio_list_set.c	 \
-	resource_unpack.h \
-	resource_unpack.c \
-	pio_rpc.h        \
-	pio_client.c	\
-	pio_client.h	\
-	pio_server.c     \
-	pio_server.h     \
-	pio_util.c       \
-	pio_util.h       \
-	pio_serialize.h	\
-	pio_serialize.c	\
-	pio_cdf_int.c	\
-	pio_cdf_int.h	\
 	resource_handle.c\
 	resource_handle.h\
 	service.h	 \
@@ -131,8 +109,50 @@ libcdi_la_SOURCES = 	 \
         stream.c         \
         swap.c
 
+if USE_MPI
+if ENABLE_CDI_LIB
+lib_LTLIBRARIES += libcdipio.la
+include_HEADERS += cdipio.h cdipio.inc
+else
+noinst_LTLIBRARIES += libcdipio.la
+endif
+endif
+
+libcdipio_la_SOURCES =							\
+	cdipio.h							\
+	cdipioFortran.c							\
+	cfortran.h							\
+	pio.c								\
+	pio.h								\
+	pio_comm.c							\
+	pio_comm.h							\
+	pio_dbuffer.c							\
+	pio_impl.h							\
+	pio_interface.c							\
+	pio_interface.h							\
+	pio_mpinonb.c							\
+	pio_record_send.c						\
+	pio_posixasynch.c						\
+	pio_posixfpguardsendrecv.c					\
+	pio_posixnonb.c							\
+	pio_list_set.c							\
+	resource_unpack.h						\
+	resource_unpack.c						\
+	pio_rpc.h							\
+	pio_client.c							\
+	pio_client.h							\
+	pio_server.c							\
+	pio_server.h							\
+	pio_serialize.h							\
+	pio_serialize.c							\
+	pio_cdf_int.c							\
+	pio_cdf_int.h
+
+libcdipio_la_LIBADD    = libcdi.la $(PPM_CORE_LIBS) $(YAXT_LIBS)
+
+
 #libcdi_la_CPPFLAGS  = @CPPFLAGS@
-libcdi_la_LIBADD    = $(PPM_CORE_LIBS) $(YAXT_LIBS)
+libcdi_la_LIBADD    =
 #
 #cdilib.c:
 #	$(top_srcdir)/src/make_cdilib $(top_srcdir)/src
@@ -140,9 +160,12 @@ libcdi_la_LIBADD    = $(PPM_CORE_LIBS) $(YAXT_LIBS)
 #cdilib.o: cdilib.c
 #	$(COMPILE) -c $<
 
-LOCALTARGETS  = 
+LOCALTARGETS  =
 if ENABLE_CDI_LIB
 LOCALTARGETS += pkgconfig/cdi.pc
+if USE_MPI
+LOCALTARGETS += pkgconfig/cdipio.pc
+endif
 endif
 
 if CREATE_ISOC
@@ -160,8 +183,11 @@ mo_cdi.$(FCMODEXT): mo_cdi.f90
 
 pkgconfig/cdi.pc: pkgconfig/cdi.pc.in ../config.status
 	(cd .. ; ./config.status src/pkgconfig/cdi.pc)
+
+pkgconfig/cdipio.pc: pkgconfig/cdipio.pc.in ../config.status
+	(cd .. ; ./config.status src/pkgconfig/cdipio.pc)
 #
-all-local: $(LOCALTARGETS) 
+all-local: $(LOCALTARGETS)
 #
 CLEANFILES  = `ls *~`
 #CLEANFILES += cdilib.c
@@ -170,15 +196,28 @@ CLEANFILES += $(top_builddir)/src/mo_cdi.$(FCMODEXT) $(top_builddir)/src/mo_cdi.
 endif
 
 if ENABLE_CDI_LIB
+PKGCONFIG_FILES = pkgconfig/cdi.pc
 CLEANFILES += pkgconfig/cdi.pc
+if USE_MPI
+CLEANFILES += pkgconfig/cdipio.pc
+PKGCONFIG_FILES += pkgconfig/cdipio.pc
+endif
 
-install-exec-local: pkgconfig/cdi.pc
+install-exec-local: $(PKGCONFIG_FILES)
 	$(mkinstalldirs) "$(DESTDIR)$(libdir)/pkgconfig"
-	$(install_sh_DATA) pkgconfig/cdi.pc "$(DESTDIR)$(libdir)/pkgconfig/cdi.pc"
+	@for pkgconfigfile in $(PKGCONFIG_FILES) ; do \
+		echo $(install_sh_DATA) $$pkgconfigfile \
+		"$(DESTDIR)$(libdir)/$$pkgconfigfile" ; \
+		$(install_sh_DATA) $$pkgconfigfile \
+		"$(DESTDIR)$(libdir)/$$pkgconfigfile" ; \
+	done
 
 uninstall-local:
-	rm -f "$(DESTDIR)$(libdir)/pkgconfig/cdi.pc"
-	rmdir "$(DESTDIR)$(libdir)/pkgconfig"
+	@for pkgconfigfile in $(PKGCONFIG_FILES) ; do \
+		echo rm -f "$(DESTDIR)$(libdir)/$$pkgconfigfile" ; \
+		rm -f "$(DESTDIR)$(libdir)/$$pkgconfigfile" ; \
+	done
+	- at rmdir "$(DESTDIR)$(libdir)/pkgconfig"
 
 endif
 
diff --git a/libcdi/src/Makefile.in b/libcdi/src/Makefile.in
index 8dcb3d5..46d95e8 100644
--- a/libcdi/src/Makefile.in
+++ b/libcdi/src/Makefile.in
@@ -52,11 +52,17 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
- at ENABLE_CDI_LIB_TRUE@am__append_1 = pkgconfig/cdi.pc
- at CREATE_ISOC_TRUE@am__append_2 = mo_cdi.o mo_cdi.$(FCMODEXT)
-#CLEANFILES += cdilib.c
- at CREATE_ISOC_TRUE@am__append_3 = $(top_builddir)/src/mo_cdi.$(FCMODEXT) $(top_builddir)/src/mo_cdi.o
+ at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_1 = libcdipio.la
+ at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_2 = cdipio.h cdipio.inc
+ at ENABLE_CDI_LIB_FALSE@@USE_MPI_TRUE at am__append_3 = libcdipio.la
 @ENABLE_CDI_LIB_TRUE at am__append_4 = pkgconfig/cdi.pc
+ at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_5 = pkgconfig/cdipio.pc
+ at CREATE_ISOC_TRUE@am__append_6 = mo_cdi.o mo_cdi.$(FCMODEXT)
+#CLEANFILES += cdilib.c
+ at CREATE_ISOC_TRUE@am__append_7 = $(top_builddir)/src/mo_cdi.$(FCMODEXT) $(top_builddir)/src/mo_cdi.o
+ at ENABLE_CDI_LIB_TRUE@am__append_8 = pkgconfig/cdi.pc
+ at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_9 = pkgconfig/cdipio.pc
+ at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am__append_10 = pkgconfig/cdipio.pc
 subdir = src
 DIST_COMMON = $(am__include_HEADERS_DIST) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(srcdir)/config.h.in
@@ -70,7 +76,7 @@ am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.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/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
 	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -108,27 +114,34 @@ am__uninstall_files_from_dir = { \
   }
 am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
 LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
-am__DEPENDENCIES_1 =
-libcdi_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+libcdi_la_DEPENDENCIES =
 am_libcdi_la_OBJECTS = basetime.lo binary.lo calendar.lo cdf.lo \
 	cdf_int.lo cdi_error.lo cdi_util.lo cdiFortran.lo \
-	cgribexlib.lo dmemory.lo error.lo extralib.lo file.lo \
-	gaussgrid.lo gribapi.lo grid.lo ieglib.lo institution.lo \
-	model.lo namespace.lo serialize.lo pio.lo pio_comm.lo \
-	pio_dbuffer.lo pio_interface.lo pio_mpinonb.lo \
-	pio_record_send.lo pio_posixasynch.lo \
-	pio_posixfpguardsendrecv.lo pio_posixnonb.lo pio_list_set.lo \
-	resource_unpack.lo pio_client.lo pio_server.lo pio_util.lo \
-	pio_serialize.lo pio_cdf_int.lo resource_handle.lo \
-	servicelib.lo stream_cdf.lo stream_cgribex.lo stream_ext.lo \
-	stream_grb.lo stream_gribapi.lo stream_history.lo \
-	stream_ieg.lo cdi_int.lo stream_record.lo stream_srv.lo \
-	stream_var.lo table.lo taxis.lo timebase.lo tsteps.lo util.lo \
-	varscan.lo version.lo vlist.lo vlist_att.lo vlist_var.lo \
-	zaxis.lo stream.lo swap.lo
+	cgribexlib.lo dmemory.lo cksum.lo cdi_cksum.lo pio_util.lo \
+	error.lo extralib.lo file.lo gaussgrid.lo gribapi.lo grid.lo \
+	ieglib.lo institution.lo model.lo namespace.lo serialize.lo \
+	resource_handle.lo servicelib.lo stream_cdf.lo \
+	stream_cgribex.lo stream_ext.lo stream_grb.lo \
+	stream_gribapi.lo stream_history.lo stream_ieg.lo cdi_int.lo \
+	stream_record.lo stream_srv.lo stream_var.lo table.lo taxis.lo \
+	timebase.lo tsteps.lo util.lo varscan.lo version.lo vlist.lo \
+	vlist_att.lo vlist_var.lo zaxis.lo stream.lo swap.lo
 libcdi_la_OBJECTS = $(am_libcdi_la_OBJECTS)
 @ENABLE_CDI_LIB_FALSE at am_libcdi_la_rpath =
 @ENABLE_CDI_LIB_TRUE at am_libcdi_la_rpath = -rpath $(libdir)
+am__DEPENDENCIES_1 =
+libcdipio_la_DEPENDENCIES = libcdi.la $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
+am_libcdipio_la_OBJECTS = cdipioFortran.lo pio.lo pio_comm.lo \
+	pio_dbuffer.lo pio_interface.lo pio_mpinonb.lo \
+	pio_record_send.lo pio_posixasynch.lo \
+	pio_posixfpguardsendrecv.lo pio_posixnonb.lo pio_list_set.lo \
+	resource_unpack.lo pio_client.lo pio_server.lo \
+	pio_serialize.lo pio_cdf_int.lo
+libcdipio_la_OBJECTS = $(am_libcdipio_la_OBJECTS)
+ at ENABLE_CDI_LIB_FALSE@@USE_MPI_TRUE at am_libcdipio_la_rpath =
+ at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE at am_libcdipio_la_rpath = -rpath \
+ at ENABLE_CDI_LIB_TRUE@@USE_MPI_TRUE@	$(libdir)
 DEFAULT_INCLUDES = -I. at am__isrc@
 depcomp = $(SHELL) $(top_srcdir)/config/depcomp
 am__depfiles_maybe = depfiles
@@ -142,14 +155,14 @@ CCLD = $(CC)
 LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
 	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
-SOURCES = $(libcdi_la_SOURCES)
-DIST_SOURCES = $(libcdi_la_SOURCES)
+SOURCES = $(libcdi_la_SOURCES) $(libcdipio_la_SOURCES)
+DIST_SOURCES = $(libcdi_la_SOURCES) $(libcdipio_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__include_HEADERS_DIST = cdi.h cdi.inc
+am__include_HEADERS_DIST = cdi.h cdi.inc cdipio.h cdipio.inc
 HEADERS = $(include_HEADERS)
 ETAGS = etags
 CTAGS = ctags
@@ -162,13 +175,6 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
-BUILD_CC = @BUILD_CC@
-BUILD_CFLAGS = @BUILD_CFLAGS@
-BUILD_CXX = @BUILD_CXX@
-BUILD_F77 = @BUILD_F77@
-BUILD_FC = @BUILD_FC@
-BUILD_FCFLAGS = @BUILD_FCFLAGS@
-BUILD_LDFLAGS = @BUILD_LDFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CDI_F90_INTERFACE_FCFLAGS = @CDI_F90_INTERFACE_FCFLAGS@
@@ -349,9 +355,9 @@ top_srcdir = @top_srcdir@
 
 #
 EXTRA_DIST = cdilib.c mo_cdi.f90
- at ENABLE_CDI_LIB_TRUE@lib_LTLIBRARIES = libcdi.la
- at ENABLE_CDI_LIB_TRUE@include_HEADERS = cdi.h cdi.inc
- at ENABLE_CDI_LIB_FALSE@noinst_LTLIBRARIES = libcdi.la
+ at ENABLE_CDI_LIB_TRUE@lib_LTLIBRARIES = libcdi.la $(am__append_1)
+ at ENABLE_CDI_LIB_TRUE@include_HEADERS = cdi.h cdi.inc $(am__append_2)
+ at ENABLE_CDI_LIB_FALSE@noinst_LTLIBRARIES = libcdi.la $(am__append_3)
 AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS)
 libcdi_la_SOURCES = \
 	basetime.c     	 \
@@ -369,13 +375,18 @@ libcdi_la_SOURCES = \
 	cdi_limits.h	 \
 	cdi_util.c       \
 	cdiFortran.c     \
-	cdiFortran.h     \
 	cfortran.h       \
 	cgribex.h	 \
 	cgribexlib.c  	 \
 	datetime.h	 \
 	dmemory.c      	 \
 	dmemory.h	 \
+	cksum.c		\
+	cksum.h		\
+	cdi_cksum.c	\
+	cdi_cksum.h	\
+	pio_util.c							\
+	pio_util.h							\
 	dtypes.h	 \
 	error.c        	 \
 	error.h	 	 \
@@ -399,33 +410,6 @@ libcdi_la_SOURCES = \
 	namespace.h      \
 	serialize.h	\
 	serialize.c	\
-	pio.c            \
-	pio.h            \
-	pio_comm.c       \
-	pio_comm.h       \
-	pio_dbuffer.c    \
-	pio_impl.h 	 \
-	pio_interface.c  \
-	pio_interface.h	 \
-	pio_mpinonb.c    \
-	pio_record_send.c\
-	pio_posixasynch.c\
-	pio_posixfpguardsendrecv.c \
-	pio_posixnonb.c  \
-	pio_list_set.c	 \
-	resource_unpack.h \
-	resource_unpack.c \
-	pio_rpc.h        \
-	pio_client.c	\
-	pio_client.h	\
-	pio_server.c     \
-	pio_server.h     \
-	pio_util.c       \
-	pio_util.h       \
-	pio_serialize.h	\
-	pio_serialize.c	\
-	pio_cdf_int.c	\
-	pio_cdf_int.h	\
 	resource_handle.c\
 	resource_handle.h\
 	service.h	 \
@@ -473,18 +457,51 @@ libcdi_la_SOURCES = \
         stream.c         \
         swap.c
 
+libcdipio_la_SOURCES = \
+	cdipio.h							\
+	cdipioFortran.c							\
+	cfortran.h							\
+	pio.c								\
+	pio.h								\
+	pio_comm.c							\
+	pio_comm.h							\
+	pio_dbuffer.c							\
+	pio_impl.h							\
+	pio_interface.c							\
+	pio_interface.h							\
+	pio_mpinonb.c							\
+	pio_record_send.c						\
+	pio_posixasynch.c						\
+	pio_posixfpguardsendrecv.c					\
+	pio_posixnonb.c							\
+	pio_list_set.c							\
+	resource_unpack.h						\
+	resource_unpack.c						\
+	pio_rpc.h							\
+	pio_client.c							\
+	pio_client.h							\
+	pio_server.c							\
+	pio_server.h							\
+	pio_serialize.h							\
+	pio_serialize.c							\
+	pio_cdf_int.c							\
+	pio_cdf_int.h
+
+libcdipio_la_LIBADD = libcdi.la $(PPM_CORE_LIBS) $(YAXT_LIBS)
 
 #libcdi_la_CPPFLAGS  = @CPPFLAGS@
-libcdi_la_LIBADD = $(PPM_CORE_LIBS) $(YAXT_LIBS)
+libcdi_la_LIBADD = 
 #
 #cdilib.c:
 #	$(top_srcdir)/src/make_cdilib $(top_srcdir)/src
 #
 #cdilib.o: cdilib.c
 #	$(COMPILE) -c $<
-LOCALTARGETS = $(am__append_1) $(am__append_2)
+LOCALTARGETS = $(am__append_4) $(am__append_5) $(am__append_6)
 #
-CLEANFILES = `ls *~` $(am__append_3) $(am__append_4)
+CLEANFILES = `ls *~` $(am__append_7) $(am__append_8) $(am__append_9)
+ at ENABLE_CDI_LIB_TRUE@PKGCONFIG_FILES = pkgconfig/cdi.pc \
+ at ENABLE_CDI_LIB_TRUE@	$(am__append_10)
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-am
 
@@ -578,6 +595,8 @@ clean-noinstLTLIBRARIES:
 	done
 libcdi.la: $(libcdi_la_OBJECTS) $(libcdi_la_DEPENDENCIES) $(EXTRA_libcdi_la_DEPENDENCIES) 
 	$(LINK) $(am_libcdi_la_rpath) $(libcdi_la_OBJECTS) $(libcdi_la_LIBADD) $(LIBS)
+libcdipio.la: $(libcdipio_la_OBJECTS) $(libcdipio_la_DEPENDENCIES) $(EXTRA_libcdipio_la_DEPENDENCIES) 
+	$(LINK) $(am_libcdipio_la_rpath) $(libcdipio_la_OBJECTS) $(libcdipio_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -591,10 +610,13 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdf.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdf_int.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdiFortran.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_cksum.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_error.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_int.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdi_util.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdipioFortran.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cgribexlib.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cksum.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dmemory.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/error.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/extralib.Plo at am__quote@
@@ -925,16 +947,27 @@ mo_cdi.$(FCMODEXT): mo_cdi.f90
 
 pkgconfig/cdi.pc: pkgconfig/cdi.pc.in ../config.status
 	(cd .. ; ./config.status src/pkgconfig/cdi.pc)
+
+pkgconfig/cdipio.pc: pkgconfig/cdipio.pc.in ../config.status
+	(cd .. ; ./config.status src/pkgconfig/cdipio.pc)
 #
-all-local: $(LOCALTARGETS) 
+all-local: $(LOCALTARGETS)
 
- at ENABLE_CDI_LIB_TRUE@install-exec-local: pkgconfig/cdi.pc
+ at ENABLE_CDI_LIB_TRUE@install-exec-local: $(PKGCONFIG_FILES)
 @ENABLE_CDI_LIB_TRUE@	$(mkinstalldirs) "$(DESTDIR)$(libdir)/pkgconfig"
- at ENABLE_CDI_LIB_TRUE@	$(install_sh_DATA) pkgconfig/cdi.pc "$(DESTDIR)$(libdir)/pkgconfig/cdi.pc"
+ at ENABLE_CDI_LIB_TRUE@	@for pkgconfigfile in $(PKGCONFIG_FILES) ; do \
+ at ENABLE_CDI_LIB_TRUE@		echo $(install_sh_DATA) $$pkgconfigfile \
+ at ENABLE_CDI_LIB_TRUE@		"$(DESTDIR)$(libdir)/$$pkgconfigfile" ; \
+ at ENABLE_CDI_LIB_TRUE@		$(install_sh_DATA) $$pkgconfigfile \
+ at ENABLE_CDI_LIB_TRUE@		"$(DESTDIR)$(libdir)/$$pkgconfigfile" ; \
+ at ENABLE_CDI_LIB_TRUE@	done
 
 @ENABLE_CDI_LIB_TRUE at uninstall-local:
- at ENABLE_CDI_LIB_TRUE@	rm -f "$(DESTDIR)$(libdir)/pkgconfig/cdi.pc"
- at ENABLE_CDI_LIB_TRUE@	rmdir "$(DESTDIR)$(libdir)/pkgconfig"
+ at ENABLE_CDI_LIB_TRUE@	@for pkgconfigfile in $(PKGCONFIG_FILES) ; do \
+ at ENABLE_CDI_LIB_TRUE@		echo rm -f "$(DESTDIR)$(libdir)/$$pkgconfigfile" ; \
+ at ENABLE_CDI_LIB_TRUE@		rm -f "$(DESTDIR)$(libdir)/$$pkgconfigfile" ; \
+ at ENABLE_CDI_LIB_TRUE@	done
+ at ENABLE_CDI_LIB_TRUE@	- at rmdir "$(DESTDIR)$(libdir)/pkgconfig"
 
 install-exec-hook:
 	- at rmdir "$(DESTDIR)$(libdir)"
diff --git a/libcdi/src/cdi.h b/libcdi/src/cdi.h
index 41a221a..4bdc195 100644
--- a/libcdi/src/cdi.h
+++ b/libcdi/src/cdi.h
@@ -4,8 +4,8 @@
   This is the only file that must be included to use the CDI library from C.
 */
 
-#ifndef  _CDI_H
-#define  _CDI_H
+#ifndef  CDI_H_
+#define  CDI_H_
 
 #include <sys/types.h>
 
@@ -172,20 +172,20 @@ extern "C" {
 
 /* TSTEP types */
 
-#define  TSTEP_CONSTANT           0
-#define  TSTEP_INSTANT            1
-#define  TSTEP_AVG                2
-#define  TSTEP_ACCUM              3
-#define  TSTEP_MAX                4
-#define  TSTEP_MIN                5
-#define  TSTEP_DIFF               6
-#define  TSTEP_RMS                7
-#define  TSTEP_SD                 8
-#define  TSTEP_COV                9
-#define  TSTEP_RATIO             10
-#define  TSTEP_RANGE             11
-#define  TSTEP_INSTANT2          12
-#define  TSTEP_INSTANT3          13
+#define  TSTEP_CONSTANT             0  /* Constant            */
+#define  TSTEP_INSTANT              1  /* Instant             */
+#define  TSTEP_AVG                  2  /* Average             */
+#define  TSTEP_ACCUM                3  /* Accumulation        */
+#define  TSTEP_MAX                  4  /* Maximum             */
+#define  TSTEP_MIN                  5  /* Minimum             */
+#define  TSTEP_DIFF                 6  /* Difference          */
+#define  TSTEP_RMS                  7  /* Root mean square    */
+#define  TSTEP_SD                   8  /* Standard deviation  */
+#define  TSTEP_COV                  9  /* Covariance          */
+#define  TSTEP_RATIO               10  /* Ratio               */
+#define  TSTEP_RANGE               11
+#define  TSTEP_INSTANT2            12
+#define  TSTEP_INSTANT3            13
 
 /* TAXIS types */
 
@@ -214,38 +214,6 @@ extern "C" {
 #define  CALENDAR_366DAYS         4
 #define  CALENDAR_NONE            5
 
-/* parallel IO IOMode */
-
-#define  PIO_NONE                 0
-#define  PIO_MPI                  1
-#define  PIO_WRITER               2
-#define  PIO_ASYNCH               3
-#define  PIO_FPGUARD              4
-
-#define  PIO_MINIOMODE                  PIO_NONE
-#define  PIO_MAXIOMODE                  PIO_FPGUARD
-#define  PIO_MINIOMODEWITHSPECIALPROCS  PIO_WRITER
-
-/* parallel IO routines */
-#ifdef MPI_VERSION
-#  include <yaxt.h>
-#endif
-
-#ifdef MPI_VERSION /* make_fint keep */
-void     pioEndDef             ( void );
-void     pioEndTimestepping    ( void );
-void     pioFinalize           ( void );
-/*      pioInit: initialize I/O server processes and communication */
-MPI_Comm pioInit(MPI_Comm commSuper, int nProcsIO, int IOMode,
-                 int *pioNamespace, float partInflate);
-void     pioWriteTimestep();
-
-void     streamWriteVarPart    (int streamID, int varID,
-                                const void *data, int nmiss,
-                                Xt_idxlist partDesc);
-
-#endif /* make_fint keep */
-void     pioNamespaceSetActive ( int );
 
 /* CDI control routines */
 
@@ -264,6 +232,11 @@ void    cdiDefMissval(double missval);
 double  cdiInqMissval(void);
 void    cdiDefGlobal(const char *string, int val);
 
+int     namespaceNew();
+void    namespaceSetActive(int namespaceID);
+void    namespaceDelete(int namespaceID);
+
+
 /* CDI converter routines */
 
 /* parameter */
@@ -330,6 +303,9 @@ int     streamInqCompLevel(int streamID);
 /*      streamDefTimestep: Define time step */
 int     streamDefTimestep(int streamID, int tsID);
 
+/* query currently set timestep id  */
+int streamInqCurTimestepID(int streamID);
+
 /*      streamInqTimestep: Get time step */
 int     streamInqTimestep(int streamID, int tsID);
 
@@ -369,7 +345,7 @@ void    streamWriteRecord(int streamID, const double *data_vec, int nmiss);
 void    streamWriteRecordF(int streamID, const float *data_vec, int nmiss);
 void    streamCopyRecord(int streamIDdest, int streamIDsrc);
 
-void    streamInqGinfo(int streamID, int *intnum, float *fltnum);
+void    streamInqGinfo(int streamID, int *intnum, float *fltnum, off_t *bignum);
 
 /* VLIST routines */
 
@@ -759,7 +735,7 @@ int     gridInqReference(int gridID, char *reference);
 void    gridDefUUID(int gridID, const char *uuid_cbuf);
 
 /*      gridInqUUID: Get the UUID of an unstructured grid */
-char   *gridInqUUID(int gridID, char *uuid_cbuf);
+void    gridInqUUID(int gridID, char *uuid_cbuf);
 
 
 /* Lambert Conformal Conic grid (GRIB version) */
@@ -855,7 +831,7 @@ int     zaxisInqNumber(int gridID);
 void    zaxisDefUUID(int zaxisID, const char *uuid_cbuf);
 
 /*      zaxisInqUUID: Get the UUID of a generalized Z-axis */
-char   *zaxisInqUUID(int zaxisID, char *uuid_cbuf);
+void    zaxisInqUUID(int zaxisID, char *uuid_cbuf);
 
 /*      zaxisDefName: Define the name of a Z-axis */
 void    zaxisDefName(int zaxisID, const char *name);
@@ -1026,7 +1002,7 @@ void    streamInqHistoryString(int streamID, char *history);
 }
 #endif
 
-#endif  /* _CDI_H */
+#endif  /* CDI_H_ */
 /*
  * Local Variables:
  * c-file-style: "Java"
diff --git a/libcdi/src/cdi.inc b/libcdi/src/cdi.inc
index 169089e..789a555 100644
--- a/libcdi/src/cdi.inc
+++ b/libcdi/src/cdi.inc
@@ -1,10 +1,10 @@
 ! This file was automatically generated, don't edit!
 !
-! Fortran interface for CDI library version 1.6.2
+! Fortran interface for CDI library version 1.6.3
 !
 ! Author:
 ! -------
-! Uwe Schulzweida, MPI-MET, Hamburg,   November 2013
+! Uwe Schulzweida, MPI-MET, Hamburg,   February 2014
 !
 
       INTEGER    CDI_MAX_NAME          
@@ -364,54 +364,6 @@
       INTEGER    CALENDAR_NONE         
       PARAMETER (CALENDAR_NONE          =  5)
 !
-!  parallel IO IOMode
-!
-      INTEGER    PIO_NONE              
-      PARAMETER (PIO_NONE               =  0)
-      INTEGER    PIO_MPI               
-      PARAMETER (PIO_MPI                =  1)
-      INTEGER    PIO_WRITER            
-      PARAMETER (PIO_WRITER             =  2)
-      INTEGER    PIO_ASYNCH            
-      PARAMETER (PIO_ASYNCH             =  3)
-      INTEGER    PIO_FPGUARD           
-      PARAMETER (PIO_FPGUARD            =  4)
-!
-!  parallel IO routines
-!
-!                     pioEndDef
-      EXTERNAL        pioEndDef
-
-!                     pioEndTimestepping
-      EXTERNAL        pioEndTimestepping
-
-!                     pioFinalize
-      EXTERNAL        pioFinalize
-
-      INTEGER         pioInit
-!                                    (INTEGER         commSuper,
-!                                     INTEGER         nProcsIO,
-!                                     INTEGER         IOMode,
-!                                     INTEGER         pioNamespace,
-!                                     REAL            partInflate)
-      EXTERNAL        pioInit
-
-!                     pioWriteTimestep
-      EXTERNAL        pioWriteTimestep
-
-!                     streamWriteVarPart
-!                                    (INTEGER         streamID,
-!                                     INTEGER         varID,
-!                                     CHOICE          data,
-!                                     INTEGER         nmiss,
-!                                     TYPE(XT_IDXLIST)partDesc)
-      EXTERNAL        streamWriteVarPart
-
-!                     pioNamespaceSetActive
-!                                    (INTEGER         )
-      EXTERNAL        pioNamespaceSetActive
-
-!
 !  CDI control routines
 !
 !                     cdiReset
@@ -447,6 +399,17 @@
 !                                     INTEGER         val)
       EXTERNAL        cdiDefGlobal
 
+      INTEGER         namespaceNew
+      EXTERNAL        namespaceNew
+
+!                     namespaceSetActive
+!                                    (INTEGER         namespaceID)
+      EXTERNAL        namespaceSetActive
+
+!                     namespaceDelete
+!                                    (INTEGER         namespaceID)
+      EXTERNAL        namespaceDelete
+
 !
 !  CDI converter routines
 !
@@ -577,6 +540,13 @@
 !                                     INTEGER         tsID)
       EXTERNAL        streamDefTimestep
 
+!
+!  query currently set timestep id
+!
+      INTEGER         streamInqCurTimestepID
+!                                    (INTEGER         streamID)
+      EXTERNAL        streamInqCurTimestepID
+
       INTEGER         streamInqTimestep
 !                                    (INTEGER         streamID,
 !                                     INTEGER         tsID)
@@ -692,12 +662,6 @@
 !                                     INTEGER         streamIDsrc)
       EXTERNAL        streamCopyRecord
 
-!                     streamInqGinfo
-!                                    (INTEGER         streamID,
-!                                     INTEGER         intnum,
-!                                     REAL            fltnum)
-      EXTERNAL        streamInqGinfo
-
 !
 !  VLIST routines
 !
@@ -1663,7 +1627,7 @@
 !                                     CHARACTER*(*)   uuid_cbuf)
       EXTERNAL        gridDefUUID
 
-      CHARACTER(80)   gridInqUUID
+!                     gridInqUUID
 !                                    (INTEGER         gridID,
 !                                     CHARACTER*(*)   uuid_cbuf)
       EXTERNAL        gridInqUUID
@@ -1885,7 +1849,7 @@
 !                                     CHARACTER*(*)   uuid_cbuf)
       EXTERNAL        zaxisDefUUID
 
-      CHARACTER(80)   zaxisInqUUID
+!                     zaxisInqUUID
 !                                    (INTEGER         zaxisID,
 !                                     CHARACTER*(*)   uuid_cbuf)
       EXTERNAL        zaxisInqUUID
diff --git a/libcdi/src/cdiFortran.c b/libcdi/src/cdiFortran.c
index 6d11efa..4abf9d9 100644
--- a/libcdi/src/cdiFortran.c
+++ b/libcdi/src/cdiFortran.c
@@ -4,16 +4,7 @@
 #  include "config.h"
 #endif
 
-#if USE_MPI
-#  include <mpi.h>
-#  include <yaxt.h>
-#else
-#define MPI_Comm int
-#define MPI_Comm_f2c(c) (c)
-#define MPI_Comm_c2f(c) (c)
-#endif
-
-#if ! defined (_CDI_H)
+#if ! defined (CDI_H_)
 #  include "cdi.h"
 #endif
 
@@ -23,10 +14,6 @@
 #  include "cfortran.h"
 #endif
 
-#if ! defined (_CDIFORTRAN_H)
-#  include "cdiFortran.h"
-#endif
-
 
 /*  Byte order  */
 
@@ -70,31 +57,6 @@
 /*  CALENDAR types  */
 
 
-/*  parallel IO IOMode  */
-
-
-/*  parallel IO routines  */
-
-#ifdef MPI_VERSION /* make_fint keep */
-FCALLSCSUB0 (pioEndDef, PIOENDDEF, pioenddef)
-FCALLSCSUB0 (pioEndTimestepping, PIOENDTIMESTEPPING, pioendtimestepping)
-FCALLSCSUB0 (pioFinalize, PIOFINALIZE, piofinalize)
-static int pioInit_fwrap(int commSuper, int nProcsIO, int IOMode, int * pioNamespace, float partInflate)
-{
-  MPI_Comm v;
-  v = pioInit(MPI_Comm_f2c(commSuper),  nProcsIO,  IOMode,  pioNamespace,  partInflate);
-  return MPI_Comm_c2f(v);
-}
-FCALLSCFUN5 (INT, pioInit_fwrap, PIOINIT, pioinit, INT, INT, INT, PINT, FLOAT)
-FCALLSCSUB0 (pioWriteTimestep, PIOWRITETIMESTEP, piowritetimestep)
-static void streamWriteVarPart_fwrap(int streamID, int varID, const void * data, int nmiss, void * partDesc)
-{
-  streamWriteVarPart( streamID,  varID,  data,  nmiss, (*(Xt_idxlist *)partDesc));
-}
-FCALLSCSUB5 (streamWriteVarPart_fwrap, STREAMWRITEVARPART, streamwritevarpart, INT, INT, PVOID, INT, PVOID)
-#endif /* make_fint keep */
-FCALLSCSUB1 (pioNamespaceSetActive, PIONAMESPACESETACTIVE, pionamespacesetactive, INT)
-
 /*  CDI control routines  */
 
 FCALLSCSUB0 (cdiReset, CDIRESET, cdireset)
@@ -106,6 +68,9 @@ FCALLSCFUN1 (INT, cdiHaveFiletype, CDIHAVEFILETYPE, cdihavefiletype, INT)
 FCALLSCSUB1 (cdiDefMissval, CDIDEFMISSVAL, cdidefmissval, DOUBLE)
 FCALLSCFUN0 (DOUBLE, cdiInqMissval, CDIINQMISSVAL, cdiinqmissval)
 FCALLSCSUB2 (cdiDefGlobal, CDIDEFGLOBAL, cdidefglobal, STRING, INT)
+FCALLSCFUN0 (INT, namespaceNew, NAMESPACENEW, namespacenew)
+FCALLSCSUB1 (namespaceSetActive, NAMESPACESETACTIVE, namespacesetactive, INT)
+FCALLSCSUB1 (namespaceDelete, NAMESPACEDELETE, namespacedelete, INT)
 
 /*  CDI converter routines  */
 
@@ -144,6 +109,10 @@ FCALLSCSUB2 (streamDefCompLevel, STREAMDEFCOMPLEVEL, streamdefcomplevel, INT, IN
 FCALLSCFUN1 (INT, streamInqCompType, STREAMINQCOMPTYPE, streaminqcomptype, INT)
 FCALLSCFUN1 (INT, streamInqCompLevel, STREAMINQCOMPLEVEL, streaminqcomplevel, INT)
 FCALLSCFUN2 (INT, streamDefTimestep, STREAMDEFTIMESTEP, streamdeftimestep, INT, INT)
+
+/*  query currently set timestep id  */
+
+FCALLSCFUN1 (INT, streamInqCurTimestepID, STREAMINQCURTIMESTEPID, streaminqcurtimestepid, INT)
 FCALLSCFUN2 (INT, streamInqTimestep, STREAMINQTIMESTEP, streaminqtimestep, INT, INT)
 FCALLSCFUN1 (STRING, streamFilename, STREAMFILENAME, streamfilename, INT)
 FCALLSCFUN1 (STRING, streamFilesuffix, STREAMFILESUFFIX, streamfilesuffix, INT)
@@ -168,7 +137,6 @@ FCALLSCSUB3 (streamReadRecord, STREAMREADRECORD, streamreadrecord, INT, PDOUBLE,
 FCALLSCSUB3 (streamWriteRecord, STREAMWRITERECORD, streamwriterecord, INT, PDOUBLE, INT)
 FCALLSCSUB3 (streamWriteRecordF, STREAMWRITERECORDF, streamwriterecordf, INT, PFLOAT, INT)
 FCALLSCSUB2 (streamCopyRecord, STREAMCOPYRECORD, streamcopyrecord, INT, INT)
-FCALLSCSUB3 (streamInqGinfo, STREAMINQGINFO, streaminqginfo, INT, PINT, PFLOAT)
 
 /*  VLIST routines  */
 
@@ -292,10 +260,10 @@ FCALLSCFUN6 (INT, vlistInqAtt, VLISTINQATT, vlistinqatt, INT, INT, INT, PSTRING,
 FCALLSCFUN3 (INT, vlistDelAtt, VLISTDELATT, vlistdelatt, INT, INT, STRING)
 FCALLSCFUN6 (INT, vlistDefAttInt, VLISTDEFATTINT, vlistdefattint, INT, INT, STRING, INT, INT, PINT)
 FCALLSCFUN6 (INT, vlistDefAttFlt, VLISTDEFATTFLT, vlistdefattflt, INT, INT, STRING, INT, INT, PDOUBLE)
-FCALLSCFUN5 (INT, vlistDefAttTxt, VLISTDEFATTTXT, vlistdefatttxt, INT, INT, STRING, INT, CBUF)
+FCALLSCFUN5 (INT, vlistDefAttTxt, VLISTDEFATTTXT, vlistdefatttxt, INT, INT, STRING, INT, PPSTRING)
 FCALLSCFUN5 (INT, vlistInqAttInt, VLISTINQATTINT, vlistinqattint, INT, INT, STRING, INT, PINT)
 FCALLSCFUN5 (INT, vlistInqAttFlt, VLISTINQATTFLT, vlistinqattflt, INT, INT, STRING, INT, PDOUBLE)
-FCALLSCFUN5 (INT, vlistInqAttTxt, VLISTINQATTTXT, vlistinqatttxt, INT, INT, STRING, INT, CBUF)
+FCALLSCFUN5 (INT, vlistInqAttTxt, VLISTINQATTTXT, vlistinqatttxt, INT, INT, STRING, INT, PPSTRING)
 
 /*  GRID routines  */
 
@@ -372,8 +340,8 @@ FCALLSCSUB2 (gridDefPosition, GRIDDEFPOSITION, griddefposition, INT, INT)
 FCALLSCFUN1 (INT, gridInqPosition, GRIDINQPOSITION, gridinqposition, INT)
 FCALLSCSUB2 (gridDefReference, GRIDDEFREFERENCE, griddefreference, INT, STRING)
 FCALLSCFUN2 (INT, gridInqReference, GRIDINQREFERENCE, gridinqreference, INT, PSTRING)
-FCALLSCSUB2 (gridDefUUID, GRIDDEFUUID, griddefuuid, INT, CBUF)
-FCALLSCFUN2 (STRING, gridInqUUID, GRIDINQUUID, gridinquuid, INT, CBUF)
+FCALLSCSUB2 (gridDefUUID, GRIDDEFUUID, griddefuuid, INT, PPSTRING)
+FCALLSCSUB2 (gridInqUUID, GRIDINQUUID, gridinquuid, INT, PPSTRING)
 
 /*  Lambert Conformal Conic grid (GRIB version)  */
 
@@ -422,8 +390,8 @@ FCALLSCSUB2 (zaxisDefNlevRef, ZAXISDEFNLEVREF, zaxisdefnlevref, INT, INT)
 FCALLSCFUN1 (INT, zaxisInqNlevRef, ZAXISINQNLEVREF, zaxisinqnlevref, INT)
 FCALLSCSUB2 (zaxisDefNumber, ZAXISDEFNUMBER, zaxisdefnumber, INT, INT)
 FCALLSCFUN1 (INT, zaxisInqNumber, ZAXISINQNUMBER, zaxisinqnumber, INT)
-FCALLSCSUB2 (zaxisDefUUID, ZAXISDEFUUID, zaxisdefuuid, INT, CBUF)
-FCALLSCFUN2 (STRING, zaxisInqUUID, ZAXISINQUUID, zaxisinquuid, INT, CBUF)
+FCALLSCSUB2 (zaxisDefUUID, ZAXISDEFUUID, zaxisdefuuid, INT, PPSTRING)
+FCALLSCSUB2 (zaxisInqUUID, ZAXISINQUUID, zaxisinquuid, INT, PPSTRING)
 FCALLSCSUB2 (zaxisDefName, ZAXISDEFNAME, zaxisdefname, INT, STRING)
 FCALLSCSUB2 (zaxisDefLongname, ZAXISDEFLONGNAME, zaxisdeflongname, INT, STRING)
 FCALLSCSUB2 (zaxisDefUnits, ZAXISDEFUNITS, zaxisdefunits, INT, STRING)
diff --git a/libcdi/src/cdiFortran.h b/libcdi/src/cdiFortran.h
deleted file mode 100644
index 500a2bc..0000000
--- a/libcdi/src/cdiFortran.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef  _CDIFORTRAN_H
-#define  _CDIFORTRAN_H
-
-/*******************************************************************************
- * Character buffer:
- */
-
-#define CBUF_cfINT(N,A,B,X,Y,Z)		STRING_cfINT(N,A,B,X,Y,Z)
-#define CBUF_cfSEP(T,  B)		STRING_cfSEP(T,B)
-#define CBUF_cfN(  T,A)			STRING_cfN(T,A)
-#define CBUF_cfSTR(N,T,A,B,C,D,E)	STRING_cfSTR(N,T,A,B,C,D,E)
-#if defined(vmsFortran)
-#   define CBUF_cfT(M,I,A,B,D)		A->dsc$a_pointer
-#elif defined(CRAYFortran)
-#   define CBUF_cfT(M,I,A,B,D)		_fcdtocp(A)
-#else
-#   define CBUF_cfT(M,I,A,B,D)		A
-#endif
-
-#endif
diff --git a/libcdi/src/cdi_cksum.c b/libcdi/src/cdi_cksum.c
new file mode 100644
index 0000000..6680c51
--- /dev/null
+++ b/libcdi/src/cdi_cksum.c
@@ -0,0 +1,17 @@
+#include <inttypes.h>
+#include <stdlib.h>
+
+#include "cdi_cksum.h"
+#include "cksum.h"
+#include "error.h"
+#include "serialize.h"
+
+uint32_t cdiCheckSum(int type, int count, void *buffer)
+{
+  uint32_t s = 0U;
+  xassert(count >= 0);
+  size_t elemSize = (size_t)serializeGetSizeInCore(1, type, NULL);
+  memcrc_r_eswap(&s, buffer, count, elemSize);
+  s = memcrc_finish(&s, elemSize * (size_t)count);
+  return s;
+}
diff --git a/libcdi/src/cdi_cksum.h b/libcdi/src/cdi_cksum.h
new file mode 100644
index 0000000..85555c7
--- /dev/null
+++ b/libcdi/src/cdi_cksum.h
@@ -0,0 +1,8 @@
+#ifndef CDI_CKSUM_H_
+#define CDI_CKSUM_H_
+
+#include <inttypes.h>
+
+uint32_t cdiCheckSum(int type, int count, void *data);
+
+#endif
diff --git a/libcdi/src/cdi_int.c b/libcdi/src/cdi_int.c
index 73ad427..58bc2eb 100644
--- a/libcdi/src/cdi_int.c
+++ b/libcdi/src/cdi_int.c
@@ -2,22 +2,18 @@
 #  include "config.h"
 #endif
 
-#include <stdio.h>
 #include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <math.h>
 #include <ctype.h>
 
 #include "dmemory.h"
 
 #include "cdi.h"
+#include "cdi_cksum.h"
 #include "cdi_int.h"
 #include "gribapi.h"
 #ifdef HAVE_LIBNETCDF
 #include "stream_cdf.h"
 #endif
-#include "pio_util.h"
 #include "namespace.h"
 #include "serialize.h"
 #include "resource_handle.h"
@@ -716,7 +712,7 @@ streamGetPackSize(void * voidP, void *context)
   stream_t * streamP = ( stream_t * ) voidP;
   int packBufferSize
     = serializeGetSize(streamNint, DATATYPE_INT, context)
-    + serializeGetSize(2, DATATYPE_FLT64, context)
+    + serializeGetSize(2, DATATYPE_UINT32, context)
     + serializeGetSize((int)strlen(streamP->filename) + 1,
                        DATATYPE_TXT, context)
     + serializeGetSize(1, DATATYPE_FLT64, context);
@@ -730,7 +726,6 @@ streamPack(void * streamptr, void * packBuffer, int packBufferSize,
 {
   stream_t * streamP = ( stream_t * ) streamptr;
   int intBuffer[streamNint];
-  double d;
 
   intBuffer[0]  = streamP->self;
   intBuffer[1]  = streamP->filetype;
@@ -745,13 +740,13 @@ streamPack(void * streamptr, void * packBuffer, int packBufferSize,
   intBuffer[10] = cdiHaveMissval;
 
   serializePack(intBuffer, streamNint, DATATYPE_INT, packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum(DATATYPE_INT, streamNint, intBuffer);
-  serializePack(&d, 1, DATATYPE_FLT64, packBuffer, packBufferSize, packBufferPos, context);
+  uint32_t d = cdiCheckSum(DATATYPE_INT, streamNint, intBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
 
   serializePack(&cdiDefaultMissval, 1, DATATYPE_FLT64, packBuffer, packBufferSize, packBufferPos, context);
   serializePack(streamP->filename, intBuffer[2], DATATYPE_TXT, packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum(DATATYPE_TXT, intBuffer[2], &streamP->filename);
-  serializePack(&d, 1, DATATYPE_FLT64, packBuffer, packBufferSize, packBufferPos, context);
+  d = cdiCheckSum(DATATYPE_TXT, intBuffer[2], streamP->filename);
+  serializePack(&d, 1, DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
 }
 
 struct streamAssoc
@@ -759,22 +754,22 @@ streamUnpack(char * unpackBuffer, int unpackBufferSize,
              int * unpackBufferPos, int nspTarget, void *context)
 {
   int intBuffer[streamNint], streamID;
-  double d;
+  uint32_t d;
   char filename[CDI_MAX_NAME];
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   intBuffer, streamNint, DATATYPE_INT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
-  xassert(xchecksum(DATATYPE_INT, streamNint, intBuffer ) == d);
+                  &d, 1, DATATYPE_UINT32, context);
+  xassert(cdiCheckSum(DATATYPE_INT, streamNint, intBuffer) == d);
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   &cdiDefaultMissval, 1, DATATYPE_FLT64, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   &filename, intBuffer[2], DATATYPE_TXT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
-  xassert(d == xchecksum(DATATYPE_TXT, intBuffer[2], filename));
+                  &d, 1, DATATYPE_UINT32, context);
+  xassert(d == cdiCheckSum(DATATYPE_TXT, intBuffer[2], filename));
   streamID = streamOpenWrite ( filename, intBuffer[1] );
   xassert ( streamID >= 0 &&
             namespaceAdaptKey ( intBuffer[0], nspTarget ) == streamID );
diff --git a/libcdi/src/cdi_int.h b/libcdi/src/cdi_int.h
index a41caab..0336bac 100644
--- a/libcdi/src/cdi_int.h
+++ b/libcdi/src/cdi_int.h
@@ -7,7 +7,9 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <string.h>
+#include <errno.h>
 #include <math.h>
 #include <sys/types.h>
 
diff --git a/libcdi/src/cdilib.c b/libcdi/src/cdilib.c
index f481cf7..e8c64ba 100644
--- a/libcdi/src/cdilib.c
+++ b/libcdi/src/cdilib.c
@@ -1,7 +1,7 @@
 
-/* Automatically generated by m214003 at 2013-11-08, do not edit */
+/* Automatically generated by m214003 at 2014-02-12, do not edit */
 
-/* CDILIB_VERSION="1.6.2" */
+/* CDILIB_VERSION="1.6.3" */
 
 #ifdef _ARCH_PWR6
 #pragma options nostrict
@@ -151,6 +151,13 @@ int    reshGetStatus ( cdiResH, resOps * );
 
 void   reshLock   ( void );
 void   reshUnlock ( void );
+
+enum reshListMismatch {
+  cdiResHListOccupationMismatch,
+  cdiResHListResourceTypeMismatch,
+  cdiResHListResourceContentMismatch,
+};
+
 int reshListCompare(int nsp0, int nsp1);
 void reshListPrint(FILE *fp);
 
@@ -203,7 +210,9 @@ double  cdiEncodeTimeval(int date, int time, taxis_t *taxis);
 void    timeval2vtime(double timevalue, taxis_t *taxis, int *vdate, int *vtime);
 double  vtime2timeval(int vdate, int vtime, taxis_t *taxis);
 
+#if !defined (SX)
 extern resOps taxisOps;
+#endif
 
 int
 taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
@@ -543,8 +552,8 @@ int  iegDefDataDP(iegrec_t *iegp, const double *data);
   This is the only file that must be included to use the CDI library from C.
 */
 
-#ifndef  _CDI_H
-#define  _CDI_H
+#ifndef  CDI_H_
+#define  CDI_H_
 
 #include <sys/types.h>
 
@@ -711,20 +720,20 @@ extern "C" {
 
 /* TSTEP types */
 
-#define  TSTEP_CONSTANT           0
-#define  TSTEP_INSTANT            1
-#define  TSTEP_AVG                2
-#define  TSTEP_ACCUM              3
-#define  TSTEP_MAX                4
-#define  TSTEP_MIN                5
-#define  TSTEP_DIFF               6
-#define  TSTEP_RMS                7
-#define  TSTEP_SD                 8
-#define  TSTEP_COV                9
-#define  TSTEP_RATIO             10
-#define  TSTEP_RANGE             11
-#define  TSTEP_INSTANT2          12
-#define  TSTEP_INSTANT3          13
+#define  TSTEP_CONSTANT             0  /* Constant            */
+#define  TSTEP_INSTANT              1  /* Instant             */
+#define  TSTEP_AVG                  2  /* Average             */
+#define  TSTEP_ACCUM                3  /* Accumulation        */
+#define  TSTEP_MAX                  4  /* Maximum             */
+#define  TSTEP_MIN                  5  /* Minimum             */
+#define  TSTEP_DIFF                 6  /* Difference          */
+#define  TSTEP_RMS                  7  /* Root mean square    */
+#define  TSTEP_SD                   8  /* Standard deviation  */
+#define  TSTEP_COV                  9  /* Covariance          */
+#define  TSTEP_RATIO               10  /* Ratio               */
+#define  TSTEP_RANGE               11
+#define  TSTEP_INSTANT2            12
+#define  TSTEP_INSTANT3            13
 
 /* TAXIS types */
 
@@ -753,38 +762,6 @@ extern "C" {
 #define  CALENDAR_366DAYS         4
 #define  CALENDAR_NONE            5
 
-/* parallel IO IOMode */
-
-#define  PIO_NONE                 0
-#define  PIO_MPI                  1
-#define  PIO_WRITER               2
-#define  PIO_ASYNCH               3
-#define  PIO_FPGUARD              4
-
-#define  PIO_MINIOMODE                  PIO_NONE
-#define  PIO_MAXIOMODE                  PIO_FPGUARD
-#define  PIO_MINIOMODEWITHSPECIALPROCS  PIO_WRITER
-
-/* parallel IO routines */
-#ifdef MPI_VERSION
-#  include <yaxt.h>
-#endif
-
-#ifdef MPI_VERSION /* make_fint keep */
-void     pioEndDef             ( void );
-void     pioEndTimestepping    ( void );
-void     pioFinalize           ( void );
-/*      pioInit: initialize I/O server processes and communication */
-MPI_Comm pioInit(MPI_Comm commSuper, int nProcsIO, int IOMode,
-                 int *pioNamespace, float partInflate);
-void     pioWriteTimestep();
-
-void     streamWriteVarPart    (int streamID, int varID,
-                                const void *data, int nmiss,
-                                Xt_idxlist partDesc);
-
-#endif /* make_fint keep */
-void     pioNamespaceSetActive ( int );
 
 /* CDI control routines */
 
@@ -803,6 +780,11 @@ void    cdiDefMissval(double missval);
 double  cdiInqMissval(void);
 void    cdiDefGlobal(const char *string, int val);
 
+int     namespaceNew();
+void    namespaceSetActive(int namespaceID);
+void    namespaceDelete(int namespaceID);
+
+
 /* CDI converter routines */
 
 /* parameter */
@@ -869,6 +851,9 @@ int     streamInqCompLevel(int streamID);
 /*      streamDefTimestep: Define time step */
 int     streamDefTimestep(int streamID, int tsID);
 
+/* query currently set timestep id  */
+int streamInqCurTimestepID(int streamID);
+
 /*      streamInqTimestep: Get time step */
 int     streamInqTimestep(int streamID, int tsID);
 
@@ -908,7 +893,7 @@ void    streamWriteRecord(int streamID, const double *data_vec, int nmiss);
 void    streamWriteRecordF(int streamID, const float *data_vec, int nmiss);
 void    streamCopyRecord(int streamIDdest, int streamIDsrc);
 
-void    streamInqGinfo(int streamID, int *intnum, float *fltnum);
+void    streamInqGinfo(int streamID, int *intnum, float *fltnum, off_t *bignum);
 
 /* VLIST routines */
 
@@ -1298,7 +1283,7 @@ int     gridInqReference(int gridID, char *reference);
 void    gridDefUUID(int gridID, const char *uuid_cbuf);
 
 /*      gridInqUUID: Get the UUID of an unstructured grid */
-char   *gridInqUUID(int gridID, char *uuid_cbuf);
+void    gridInqUUID(int gridID, char *uuid_cbuf);
 
 
 /* Lambert Conformal Conic grid (GRIB version) */
@@ -1394,7 +1379,7 @@ int     zaxisInqNumber(int gridID);
 void    zaxisDefUUID(int zaxisID, const char *uuid_cbuf);
 
 /*      zaxisInqUUID: Get the UUID of a generalized Z-axis */
-char   *zaxisInqUUID(int zaxisID, char *uuid_cbuf);
+void    zaxisInqUUID(int zaxisID, char *uuid_cbuf);
 
 /*      zaxisDefName: Define the name of a Z-axis */
 void    zaxisDefName(int zaxisID, const char *name);
@@ -1565,7 +1550,7 @@ void    streamInqHistoryString(int streamID, char *history);
 }
 #endif
 
-#endif  /* _CDI_H */
+#endif  /* CDI_H_ */
 /*
  * Local Variables:
  * c-file-style: "Java"
@@ -1681,6 +1666,7 @@ enum namespaceSwitch
 {
   NSSWITCH_NO_SUCH_SWITCH = -1,
   NSSWITCH_ABORT,
+  NSSWITCH_WARNING,
   NSSWITCH_SERIALIZE_GET_SIZE,
   NSSWITCH_SERIALIZE_PACK,
   NSSWITCH_SERIALIZE_UNPACK,
@@ -1692,6 +1678,7 @@ enum namespaceSwitch
   NSSWITCH_STREAM_WRITE_VAR_,
   NSSWITCH_STREAM_WRITE_VAR_CHUNK_,
   NSSWITCH_STREAM_WRITE_VAR_PART_,
+  NSSWITCH_STREAM_WRITE_SCATTERED_VAR_PART_,
   NSSWITCH_STREAM_CLOSE_BACKEND,
   NSSWITCH_STREAM_DEF_TIMESTEP_,
   NSSWITCH_STREAM_SYNC,
@@ -1717,6 +1704,7 @@ int              namespaceNew();
 void             namespaceDelete(int namespaceID);
 void             namespaceCleanup      ( void );
 int              namespaceGetNumber    ( void );
+void namespaceSetActive(int namespaceID);
 int              namespaceGetActive    ( void );
 int              namespaceIdxEncode    ( namespaceTuple_t );
 int              namespaceIdxEncode2   ( int, int );
@@ -1740,6 +1728,34 @@ union namespaceSwitchValue namespaceSwitchGet(enum namespaceSwitch sw);
  * require-trailing-newline: t
  * End:
  */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <sys/types.h>
+
+void
+memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len);
+
+void
+memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
+               size_t elem_size);
+
+uint32_t
+memcrc_finish(uint32_t *state, off_t total_size);
+
+uint32_t
+memcrc(const unsigned char *b, size_t n);
+
+#ifndef CDI_CKSUM_H_
+#define CDI_CKSUM_H_
+
+#include <inttypes.h>
+
+uint32_t cdiCheckSum(int type, int count, void *data);
+
+#endif
 #if defined (HAVE_CONFIG_H)
 #  include "config.h"
 #endif
@@ -1827,6 +1843,9 @@ cdiAbortC_serial(const char *caller, const char *filename,
   exit(EXIT_FAILURE);
 }
 
+typedef void (*cdiWarningFunc)(const char * caller, const char * fmt,
+                               va_list ap);
+
 void Warning_(const char *caller, const char *fmt, ...)
 {
   va_list args;
@@ -1835,14 +1854,21 @@ void Warning_(const char *caller, const char *fmt, ...)
 
   if ( _Verbose )
     {
-       fprintf(stderr, "Warning (%s) : ", caller);
-      vfprintf(stderr, fmt, args);
-       fprintf(stderr, "\n");
+      cdiWarningFunc cdiWarning_p
+        = (cdiWarningFunc)namespaceSwitchGet(NSSWITCH_WARNING).func;
+      cdiWarning_p(caller, fmt, args);
     }
 
   va_end(args);
 }
 
+void cdiWarning(const char *caller, const char *fmt, va_list ap)
+{
+  fprintf(stderr, "Warning (%s) : ", caller);
+  vfprintf(stderr, fmt, ap);
+  fputc('\n', stderr);
+}
+
 
 void Message_(const char *caller, const char *fmt, ...)
 {
@@ -1886,6 +1912,8 @@ extern int _Debug;        /* If set to 1, debuggig (default 0)            */
 void SysError_(const char *caller, const char *fmt, ...);
 void    Error_(const char *caller, const char *fmt, ...);
 void  Warning_(const char *caller, const char *fmt, ...);
+/* delegate used by Warning_ unless mode is PIO */
+void cdiWarning(const char *caller, const char *fmt, va_list ap);
 void  Message_(const char *caller, const char *fmt, ...);
 
 #if  defined  WITH_CALLER_NAME
@@ -1950,7 +1978,9 @@ cdiAbortC_serial(const char *caller, const char *filename,
 
 #include <assert.h>
 #include <stdio.h>
+#include <stdbool.h>
 #include <string.h>
+#include <errno.h>
 #include <math.h>
 #include <sys/types.h>
 
@@ -2577,7 +2607,7 @@ int   gribFileSeek(int fileID, long *offset);
 int   gribReadSize(int fileID);
 int   gribVersion(unsigned char *buffer, size_t buffersize);
 
-int   gribGinfo(long recpos, long recsize, unsigned char *gribbuffer, int *intnum, float *fltnum);
+int   gribGinfo(off_t recpos, long recsize, unsigned char *gribbuffer, int *intnum, float *fltnum, off_t *bignum);
 
 double calculate_pfactor(const double* spectralField, long fieldTruncation, long subsetTruncation);
 
@@ -4775,6 +4805,8 @@ typedef struct
 }
 levinfo_t;
 
+#define DEFAULT_LEVINFO(levID) \
+  (levinfo_t){ .flag = 0, .index = -1, .flevelID = levID, .mlevelID = levID}
 
 typedef struct
 {
@@ -4795,7 +4827,6 @@ ensinfo_t;
 typedef struct
 {
   int         flag;
-  int         nlevs;
   int         isUsed;
   int         mvarID;
   int         fvarID;
@@ -4916,10 +4947,7 @@ extern char* cdiAdditionalGRIBKeys[];
 #include "vlist.h"
 #endif
 
-int  vlistInqVarDecoChunk ( int, int, int );
-int  vlistInqVarDecoOff   ( int, int, int );
-
-int  vlistVarGetSize(vlist_t *p, int varID, void *context);
+int  vlistVarGetPackSize(vlist_t *p, int varID, void *context);
 void vlistVarPack(vlist_t *p, int varID,
                   char * buffer, int bufferSize, int * pos, void *context);
 void vlistVarUnpack(int vlistID,
@@ -4927,6 +4955,8 @@ void vlistVarUnpack(int vlistID,
 void vlistDefVarIOrank    ( int, int, int );
 int  vlistInqVarIOrank    ( int, int );
 
+void cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID);
+
 #endif
 /*
  * Local Variables:
@@ -5002,89 +5032,6 @@ instituteUnpack(void *buf, int size, int *position, int,
  * require-trailing-newline: t
  * End:
  */
-#ifndef NAMESPACE_H
-#define NAMESPACE_H
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-
-typedef enum {
-  STAGE_DEFINITION = 0,
-  STAGE_TIMELOOP   = 1,
-  STAGE_CLEANUP    = 2,
-  STAGE_UNUSED     = 3,
-} statusCode;
-
-typedef struct {
-  int idx;
-  int nsp;
-} namespaceTuple_t;
-
-enum namespaceSwitch
-{
-  NSSWITCH_NO_SUCH_SWITCH = -1,
-  NSSWITCH_ABORT,
-  NSSWITCH_SERIALIZE_GET_SIZE,
-  NSSWITCH_SERIALIZE_PACK,
-  NSSWITCH_SERIALIZE_UNPACK,
-  NSSWITCH_FILE_OPEN,
-  NSSWITCH_FILE_WRITE,
-  NSSWITCH_FILE_CLOSE,
-  NSSWITCH_STREAM_OPEN_BACKEND,
-  NSSWITCH_STREAM_DEF_VLIST_,
-  NSSWITCH_STREAM_WRITE_VAR_,
-  NSSWITCH_STREAM_WRITE_VAR_CHUNK_,
-  NSSWITCH_STREAM_WRITE_VAR_PART_,
-  NSSWITCH_STREAM_CLOSE_BACKEND,
-  NSSWITCH_STREAM_DEF_TIMESTEP_,
-  NSSWITCH_STREAM_SYNC,
-#ifdef HAVE_LIBNETCDF
-  NSSWITCH_NC__CREATE,
-  NSSWITCH_CDF_DEF_VAR,
-  NSSWITCH_CDF_DEF_TIMESTEP,
-  NSSWITCH_CDF_STREAM_SETUP,
-#endif
-  NUM_NAMESPACE_SWITCH,
-};
-
-union namespaceSwitchValue
-{
-  void *data;
-  void (*func)();
-};
-
-#define NSSW_FUNC(p) ((union namespaceSwitchValue){ .func = (void (*)())(p) })
-#define NSSW_DATA(p) ((union namespaceSwitchValue){ .data = (void *)(p) })
-
-int              namespaceNew();
-void             namespaceDelete(int namespaceID);
-void             namespaceCleanup      ( void );
-int              namespaceGetNumber    ( void );
-int              namespaceGetActive    ( void );
-int              namespaceIdxEncode    ( namespaceTuple_t );
-int              namespaceIdxEncode2   ( int, int );
-namespaceTuple_t namespaceResHDecode   ( int );
-int              namespaceAdaptKey     ( int, int );
-int              namespaceAdaptKey2    ( int );
-void             namespaceDefResStatus ( statusCode );
-statusCode       namespaceInqResStatus ( void );
-void namespaceSwitchSet(enum namespaceSwitch sw,
-                        union namespaceSwitchValue value);
-union namespaceSwitchValue namespaceSwitchGet(enum namespaceSwitch sw);
-
-
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
 #ifndef RESOURCE_UNPACK_H
 #define RESOURCE_UNPACK_H
 
@@ -5111,319 +5058,6 @@ void reshUnpackResources(char * unpackBuffer, int unpackBufferSize,
                          void *context);
 
 #endif
-#ifndef PIO_UTIL_
-#define PIO_UTIL_
-
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifdef USE_MPI
-#include "mpi.h"
-#endif
-
-#ifndef _ERROR_H
-#include "error.h"
-#endif
-
-#define MAXDEBUG           3
-
-#define ddebug             0
-
-#define debugString "#####"
-
-#ifdef USE_MPI
-void
-cdiAbortC_MPI(const char * caller, const char * filename,
-              const char *functionname, int line,
-              const char * errorString, va_list ap)
-  __attribute__((noreturn));
-#endif
-
-#ifdef USE_MPI
-static inline int
-callsToMPIAreAllowed()
-{
-  int init_flag = 0, finished_flag = 0;
-  return MPI_Initialized(&init_flag) == MPI_SUCCESS && init_flag
-    && MPI_Finalized(&finished_flag) == MPI_SUCCESS && !finished_flag;
-}
-
-static inline int
-getMPICommWorldRank()
-{
-  int rank = -1;
-  if (callsToMPIAreAllowed())
-    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-  return rank;
-}
-#endif
-
-#ifdef USE_MPI
-#define xdebug(fmt, ...)                                                \
-  if ( ddebug ){                                                        \
-    int rank = getMPICommWorldRank();                                   \
-    fprintf ( stderr, "%s pe%d in %s, %s, line %d: " fmt "\n",          \
-              debugString, rank,  __func__, __FILE__,  __LINE__,        \
-              __VA_ARGS__ );                                            \
-  }
-
-#else
-#define xdebug(fmt, ...)                                           \
-  if ( ddebug ){                                                   \
-    fprintf ( stderr, "%s %s, %s, line %d: " fmt "\n",             \
-              debugString, __func__, __FILE__,  __LINE__,          \
-              __VA_ARGS__ );                                       \
-  }
-#endif
-
-
-#ifdef USE_MPI
-#define xdebug3(fmt, ...)                                               \
-  if ( ddebug == MAXDEBUG ){                                            \
-    int rank = getMPICommWorldRank();                                   \
-    fprintf ( stderr, "pe%d in %s, %s, line %d: " fmt "\n",             \
-              rank,  __func__, __FILE__,  __LINE__,                     \
-              __VA_ARGS__ );                                            \
-  }
-
-#else
-#define xdebug3(fmt, ...)					\
-  if ( ddebug == MAXDEBUG ){                                    \
-    fprintf ( stderr, "%s, %s, line %d: " fmt "\n",             \
-              __func__, __FILE__,  __LINE__,                    \
-              __VA_ARGS__ );                                 \
-  }
-#endif
-
-#ifdef USE_MPI
-#define xwarning(fmt, ...)						\
-  if ( ddebug ){							\
-    int rank = getMPICommWorldRank();                                   \
-    fprintf ( stderr, "WARNING: pe%d in %s, %s, line %d: " fmt "\n",	\
-              rank,  __func__, __FILE__,  __LINE__,			\
-              __VA_ARGS__ );						\
-  }
-#else
-#define xwarning(fmt, ...)					\
-  if ( ddebug ){                                                \
-    fprintf ( stderr, "WARNING: %s, %s, line %d: " fmt "\n",    \
-              __func__, __FILE__,  __LINE__,                    \
-              __VA_ARGS__ );                                 \
-  }
-#endif
-
-void * pcdiXmalloc ( size_t, const char *, const char *, int );
-#define xmalloc(size) pcdiXmalloc ( size, __FILE__, __func__,  __LINE__ )
-
-void * pcdiXcalloc ( size_t, size_t, const char *, const char *, int );
-#define xcalloc(nmemb,size) pcdiXcalloc(nmemb, size,            \
-                                        __FILE__, __func__, __LINE__)
-
-void * pcdiXrealloc ( void *, size_t, const char *, const char *, int );
-#define xrealloc(p,size) pcdiXrealloc(p, size,            \
-                                      __FILE__, __func__, __LINE__)
-
-void pcdiXMPI(int iret, const char *, int);
-#define xmpi(ret) do {                                  \
-    int tmpIRet = (ret);                                   \
-    if (tmpIRet != MPI_SUCCESS)                            \
-      pcdiXMPI(tmpIRet, __FILE__, __LINE__ );              \
-  } while(0)
-
-#ifdef USE_MPI
-void pcdiXMPIStat ( int, const char *, int, MPI_Status * );
-#define xmpiStat(ret,stat) pcdiXMPIStat ( ret, __FILE__, __LINE__, stat )
-
-void pcdiDebugComm ( const char *filename, const char *functionname, int line, \
-                     MPI_Comm *comm );
-#define xdebugComm(comm)\
-  if ( ddebug ) pcdiDebugComm (  __FILE__, __func__, __LINE__, comm )
-#endif
-
-void pcdiDebugMsg ( const char * cdiDebugString, const char *filename, const char *functionname, int line, \
-                    int tag, int source, int nfinished );
-#define xdebugMsg(tag,source,nfinished) \
-  if ( ddebug ) \
-      pcdiDebugMsg ( debugString, __FILE__, __func__, __LINE__, tag, source, nfinished )
-
-void pcdiDebugMsg2 ( const char *filename, const char *functionname, int line, \
-                    int tag, int source, char * text );
-#define xdebugMsg2(tag,source,text) \
-  if ( ddebug ) pcdiDebugMsg ( __FILE__, __func__,  __LINE__, tag, source, text )
-
-int xmaxInt ( int, int );
-int xminInt ( int, int );
-int xsum ( int, int * );
-
-double xchecksum ( int, int, void * );
- 
-void printArray ( const char *, char *, const void *, int, int, const char *, const char *, int );
-#define xprintArray(ps,array,n,datatype)                                \
-  if ( ddebug )                                                         \
-      printArray ( debugString, ps, array, n, datatype,  __func__, __FILE__, __LINE__ )
- 
-#define xprintArray3(ps,array,n,datatype)                                \
-  if ( ddebug == MAXDEBUG )                                                         \
-      printArray ( debugString, ps, array, n, datatype,  __func__, __FILE__, __LINE__ )
-
-/**
- * @return number of dimensions
- */
-int
-cdiPioQueryVarDims(int varShape[3], int vlistID, int varID);
-
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _PIO_H
-#define _PIO_H
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#ifdef USE_MPI
-#include <stdlib.h>
-#include <mpi.h>
-
-#include "cdi_int.h"
-
-void   backendCleanup  ( void );
-void   backendInit     ( void );
-void   backendFinalize ( void );
-int pioFileOpen(const char *filename, const char *mode);
-int    pioFileClose    ( int );
-size_t cdiPioFileWrite(int fileID, const void *restrict buffer, size_t len,
-                       int tsID);
-#else
-typedef int MPI_Comm;
-#endif
-
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifndef _PIO_IMPL_H
-#define _PIO_IMPL_H
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include <stdbool.h>
-
-#ifdef USE_MPI
-#include "mpi.h"
-
-typedef enum 
-{
-  IO_Open_file,
-  IO_Close_file,
-  IO_Get_fp,
-  IO_Set_fp,
-  IO_Send_buffer,
-  IO_Finalize
-} IO_Server_command;
-
-struct dBuffer
-{
-  size_t wr_pointer;
-  size_t size;
-  unsigned char * buffer;
-};
-
-typedef int ( * valDestroyFunction ) ( void * );
-typedef bool (*eqPredicate)(void *, void *);
-
-typedef struct listSet listSet;
-
-struct fileOpTag
-{
-  int id;
-  int command;
-};
-
-/* pio.c */
-int encodeFileOpTag(int fileID, int command);
-struct fileOpTag decodeFileOpTag(int);
-
-/* pio_dbuffer.c */
-int       dbuffer_init ( struct dBuffer **, size_t );
-int       dbuffer_push(struct dBuffer *, const void *, size_t);
-size_t    dbuffer_data_size ( struct dBuffer * );
-int       dbuffer_reset ( struct dBuffer * );
-void      dbuffer_cleanup ( struct dBuffer ** );
-
-/* pio_list_set.c */
-listSet *listSetNew(valDestroyFunction, eqPredicate);
-void listSetDelete(listSet *);
-int listSetAdd(listSet *, void *);
-bool listSetIsEmpty(listSet *);
-int listSetRemove(listSet *, int (*predicate)(void *, void *),
-                  void *data);
-void *listSetGet(listSet *q, int (*predicate)(void *, void *), void *data);
-
-typedef void (*elemOp)(void *elem, void *data);
-void listSetForeach(listSet *q, elemOp func, void *data);
-
-/* pio_mpinonb.c */
-int       fowMPINONB ( const char * );
-int       fcMPINONB ( int );
-size_t    fwMPINONB( int, int, const void *, size_t );
-void      initMPINONB ( void );
-void      finalizeMPINONB ( void );
-
-
-/* common functionality for file split between collectors and writer(s) */
-int pioSendClose(int);
-int pioSendOpen(const char *);
-size_t pioSendWrite(int, int, const void *, size_t);
-void pioSendInitialize(void);
-void pioSendFinalize(void);
-
-
-/* pio_posixasynch.c */
-#ifndef _SX
-void pioWriterAIO(void);
-#endif
-
-/* pio_posixfpguardsendrecv.c */
-void      fpgPOSIXFPGUARDSENDRECV ( void );
-int       fowPOSIXFPGUARDSENDRECV ( const char * );
-int       fcPOSIXFPGUARDSENDRECV ( int );
-size_t    fwPOSIXFPGUARDSENDRECV ( int, int, const void *, size_t );
-void      initPOSIXFPGUARDSENDRECV ( void );
-void      finalizePOSIXFPGUARDSENDRECV ( void );
-
-/* pio_posixnonb.c */
-void pioWriterStdIO(void);
-
-#endif
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
 #endif
@@ -5431,8 +5065,6 @@ void pioWriterStdIO(void);
 #ifndef SERIALIZE_H
 #define SERIALIZE_H
 
-#include "cdi.h"
-
 /*
  * Generic interfaces for (de-)marshalling
  */
@@ -5987,6 +5619,35 @@ void Free(const char *caller, const char *file, int line, void *ptr)
   free(ptr);
 }
 
+void *cdiXmalloc(size_t size, const char *filename, const char *functionname,
+                 int line)
+{
+  void * value = calloc (1, size );
+  if ( value == NULL )
+    cdiAbort(filename, functionname, line, "malloc failed: %s",
+             strerror(errno));
+  return value;
+}
+
+void *cdiXcalloc(size_t nmemb, size_t size, const char *filename,
+                 const char *functionname, int line)
+{
+  void * value = calloc ( nmemb, size );
+  if ( value == NULL )
+    cdiAbort(filename, functionname, line, "calloc failed: %s",
+             strerror(errno) );
+  return value;
+}
+
+void *cdiXrealloc(void *p, size_t size, const char *functionname,
+                  const char *filename, int line)
+{
+  void *value = realloc(p, size);
+  if ( value == NULL )
+    cdiAbort(filename, functionname, line, "realloc failed: %s",
+             strerror(errno));
+  return value;
+}
 
 size_t memTotal(void)
 {
@@ -6073,6 +5734,17 @@ extern void    Free   (const char *caller, const char *file, int line, void *ptr
 
 #endif /* DEBUG_MEMORY */
 
+void *cdiXmalloc(size_t, const char *, const char *, int);
+#define xmalloc(size) cdiXmalloc((size), __FILE__, __func__,  __LINE__ )
+
+void *cdiXcalloc(size_t, size_t, const char *, const char *, int);
+#define xcalloc(nmemb,size) cdiXcalloc((nmemb), (size),        \
+                                        __FILE__, __func__, __LINE__)
+
+void *cdiXrealloc(void *, size_t, const char *, const char *, int);
+#define xrealloc(p,size) cdiXrealloc((p), (size),              \
+                                      __FILE__, __func__, __LINE__)
+
 #endif /* _DMEMORY_H */
 /*
  * Local Variables:
@@ -6083,6 +5755,200 @@ extern void    Free   (const char *caller, const char *file, int line, void *ptr
  * require-trailing-newline: t
  * End:
  */
+#include <inttypes.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+static const uint32_t crctab[] = {
+  0x00000000,
+  0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
+  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
+  0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+  0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
+  0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
+  0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
+  0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
+  0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
+  0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
+  0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+  0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
+  0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
+  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
+  0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+  0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
+  0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
+  0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
+  0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
+  0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
+  0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
+  0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+  0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
+  0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
+  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
+  0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+  0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
+  0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
+  0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
+  0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
+  0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
+  0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
+  0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+  0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
+  0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
+  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
+  0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+  0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
+  0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
+  0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
+  0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
+  0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
+  0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
+  0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+  0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
+  0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
+  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
+  0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+};
+
+
+uint32_t
+memcrc(const unsigned char *b, size_t n)
+{
+/*  Input arguments:
+ *  const char*   b == byte sequence to checksum
+ *  size_t        n == length of sequence
+ */
+
+
+  register uint32_t i, c, s = 0;
+
+
+  for (i = n; i > 0; --i) {
+    c = (uint32_t)(*b++);
+    s = (s << 8) ^ crctab[(s >> 24) ^ c];
+  }
+
+
+  /* Extend with the length of the string. */
+  while (n != 0) {
+    c = n & 0377;
+    n >>= 8;
+    s = (s << 8) ^ crctab[(s >> 24) ^ c];
+  }
+
+
+  return ~s;
+}
+
+void
+memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len)
+{
+/*  Input arguments:
+ *  const char*   b == byte sequence to checksum
+ *  size_t        n == length of sequence
+ */
+
+
+  register uint32_t i, c, s = *state;
+  register size_t n = block_len;
+  register const unsigned char *b = block;
+
+  for (i = n; i > 0; --i) {
+    c = (uint32_t)(*b++);
+    s = (s << 8) ^ crctab[(s >> 24) ^ c];
+  }
+
+  *state = s;
+}
+
+#define SWAP_CSUM(BITWIDTH,BYTEWIDTH)                             \
+  do {                                                            \
+  for (size_t i = num_elems; i > 0; --i) {                        \
+    {                                                             \
+      uint##BITWIDTH##_t accum = *(uint##BITWIDTH##_t *)b++;      \
+      for (j = 0; j < BYTEWIDTH; ++j)                             \
+      {                                                           \
+        uint32_t c = (uint32_t)(accum & UCHAR_MAX);               \
+        s = (s << 8) ^ crctab[(s >> 24) ^ c];                     \
+        accum >>= 8;                                              \
+      }                                                           \
+    }                                                             \
+  } while (0)
+
+
+
+/**
+ *  Does endian-swapping prior to checksumming in case platform is big-endian
+ *
+ *  @param elems points to first first element with alignment elem_size
+ *  @param num_elems number of elements to process
+ *  @param elem_size size of each element in bytes
+ */
+void
+memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
+               size_t elem_size)
+{
+#ifdef WORDS_BIGENDIAN
+  register uint32_t c, s = *state;
+  register size_t n = block_len;
+  register unsigned char *b = elems;
+
+  switch (elem_size)
+  {
+  case 1:
+    return memcrc_r(state, elems, num_elems, elem_size);
+  case 2:
+    SWAP_CSUM(16,2);
+    break;
+  case 4:
+    SWAP_CSUM(32,4);
+    break;
+  case 8:
+    SWAP_CSUM(64,8);
+    break;
+  case 16:
+    SWAP_CSUM(64,8);
+    break;
+  }
+  *state = s;
+#else
+  memcrc_r(state, elems, num_elems * elem_size);
+#endif
+}
+
+
+uint32_t
+memcrc_finish(uint32_t *state, off_t total_size)
+{
+  register uint32_t c, s = *state;
+  register off_t n = total_size;
+
+  /* Extend with the length of the string. */
+  while (n != 0) {
+    c = n & 0377;
+    n >>= 8;
+    s = (s << 8) ^ crctab[(s >> 24) ^ c];
+  }
+
+  return ~s;
+}
+#include <inttypes.h>
+#include <stdlib.h>
+
+
+uint32_t cdiCheckSum(int type, int count, void *buffer)
+{
+  uint32_t s = 0U;
+  xassert(count >= 0);
+  size_t elemSize = (size_t)serializeGetSizeInCore(1, type, NULL);
+  memcrc_r_eswap(&s, buffer, count, elemSize);
+  s = memcrc_finish(&s, elemSize * (size_t)count);
+  return s;
+}
 #if defined (HAVE_CONFIG_H)
 #endif
 
@@ -6367,7 +6233,7 @@ void taxisDefType(int taxisID, int type)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -6448,7 +6314,7 @@ void taxisDefRdate(int taxisID, int rdate)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -6479,7 +6345,7 @@ void taxisDefRtime(int taxisID, int rtime)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -6512,7 +6378,7 @@ void taxisDefCalendar(int taxisID, int calendar)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -6530,7 +6396,7 @@ void taxisDefTunit(int taxisID, int unit)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -6548,7 +6414,7 @@ void taxisDefNumavg(int taxisID, int numavg)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -6593,7 +6459,7 @@ void taxisDeleteBounds(int taxisID)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -6682,7 +6548,7 @@ void taxisDefVdateBounds(int taxisID, int vdate_lb, int vdate_ub)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -6743,7 +6609,7 @@ void taxisDefVtimeBounds(int taxisID, int vtime_lb, int vtime_ub)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -7383,7 +7249,7 @@ taxisGetPackSize(void *p, void *context)
   taxis_t *taxisptr = p;
   int packBufferSize
     = serializeGetSize(taxisNint, DATATYPE_INT, context)
-    + serializeGetSize(1, DATATYPE_FLT64, context)
+    + serializeGetSize(1, DATATYPE_UINT32, context)
     + (taxisptr->name ?
        serializeGetSize(strlen(taxisptr->name), DATATYPE_TXT, context) : 0)
     + (taxisptr->longname ?
@@ -7398,14 +7264,14 @@ taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
 {
   taxis_t * taxisP;
   int intBuffer[taxisNint];
-  double d;
+  uint32_t d;
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   intBuffer, taxisNint, DATATYPE_INT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
+                  &d, 1, DATATYPE_UINT32, context);
 
-  xassert(xchecksum(DATATYPE_INT, taxisNint, intBuffer) == d);
+  xassert(cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer) == d);
 
   taxisInit();
 
@@ -7460,7 +7326,7 @@ taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferP
 {
   taxis_t *taxisP = (taxis_t *)voidP;
   int intBuffer[taxisNint];
-  double d;
+  uint32_t d;
 
   intBuffer[0]  = taxisP->self;
   intBuffer[1]  = taxisP->used;
@@ -7479,11 +7345,12 @@ taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferP
   intBuffer[14] = taxisP->vtime_ub;
   intBuffer[15] = taxisP->name ? strlen(taxisP->name) : 0;
   intBuffer[16] = taxisP->longname ? strlen(taxisP->longname) : 0;
+  intBuffer[17] = taxisP->climatology;
 
   serializePack(intBuffer, taxisNint, DATATYPE_INT,
                 packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum(DATATYPE_INT, taxisNint, intBuffer);
-  serializePack(&d, 1, DATATYPE_FLT64,
+  d = cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
                 packBuffer, packBufferSize, packBufferPos, context);
   if (taxisP->name)
     serializePack(taxisP->name, intBuffer[15], DATATYPE_TXT,
@@ -7492,7 +7359,6 @@ taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferP
     serializePack(taxisP->longname, intBuffer[16], DATATYPE_TXT,
                   packBuffer, packBufferSize, packBufferPos, context);
 
-  intBuffer[17] = taxisP->climatology;
 }
 
 /*
@@ -8595,24 +8461,25 @@ institute_t * instituteNewEntry ( void )
 static
 void instituteDefaultEntries ( void )
 {
-  cdiResH resH[12];
-  int i;
-
-  resH[0]  = ECMWF   = institutDef( 98,   0, "ECMWF",     "European Centre for Medium-Range Weather Forecasts");
-  resH[1]  = MPIMET  = institutDef( 98, 232, "MPIMET",    "Max-Planck-Institute for Meteorology");
-  resH[2]  =           institutDef( 98, 255, "MPIMET",    "Max-Planck-Institute for Meteorology");
-  resH[3]  =           institutDef( 98, 232, "MPIMET",    "Max-Planck Institute for Meteorology");
-  resH[4]  =           institutDef( 78, 255, "DWD",       "Deutscher Wetterdienst");
-  resH[5]  = MCH     = institutDef(215, 255, "MCH",       "MeteoSwiss");
-  resH[6]  =           institutDef(  7,   0, "NCEP",      "National Centers for Environmental Prediction");
-  resH[7]  =           institutDef(  7,   1, "NCEP",      "National Centers for Environmental Prediction");
-  resH[8]  =           institutDef( 60,   0, "NCAR",      "National Center for Atmospheric Research");
-  resH[9]  =           institutDef( 74,   0, "METOFFICE", "U.K. Met Office");
-  resH[10] =           institutDef( 97,   0, "ESA",       "European Space Agency ");
-  resH[11] =           institutDef( 99,   0, "KNMI",      "Royal Netherlands Meteorological Institute");
+  cdiResH resH[64];
+  int i, n=0;
+
+  resH[n++]  = ECMWF   = institutDef( 98,   0, "ECMWF",     "European Centre for Medium-Range Weather Forecasts");
+  resH[n++]  = MPIMET  = institutDef( 98, 232, "MPIMET",    "Max-Planck-Institute for Meteorology");
+  resH[n++]  =           institutDef( 98, 255, "MPIMET",    "Max-Planck-Institute for Meteorology");
+  resH[n++]  =           institutDef( 98, 232, "MPIMET",    "Max-Planck Institute for Meteorology");
+  resH[n++]  =           institutDef( 78,   0, "DWD",       "Deutscher Wetterdienst");
+  resH[n++]  =           institutDef( 78, 255, "DWD",       "Deutscher Wetterdienst");
+  resH[n++]  = MCH     = institutDef(215, 255, "MCH",       "MeteoSwiss");
+  resH[n++]  =           institutDef(  7,   0, "NCEP",      "National Centers for Environmental Prediction");
+  resH[n++]  =           institutDef(  7,   1, "NCEP",      "National Centers for Environmental Prediction");
+  resH[n++]  =           institutDef( 60,   0, "NCAR",      "National Center for Atmospheric Research");
+  resH[n++]  =           institutDef( 74,   0, "METOFFICE", "U.K. Met Office");
+  resH[n++]  =           institutDef( 97,   0, "ESA",       "European Space Agency");
+  resH[n++]  =           institutDef( 99,   0, "KNMI",      "Royal Netherlands Meteorological Institute");
   /*     (void) institutDef(  0,   0, "IPSL", "IPSL (Institut Pierre Simon Laplace, Paris, France)"); */
 
-  for ( i = 0; i < 12 ; i++ )
+  for ( i = 0; i < n ; i++ )
     reshSetStatus(resH[i], &instituteOps, SUSPENDED);
 }
 
@@ -8654,7 +8521,7 @@ int instituteCount ( void )
 int instituteCompareKernel ( institute_t *  ip1, institute_t * ip2 )
 {
   int differ = 0;
-  size_t len;
+  size_t len1, len2;
 
   if ( ip1->name )
     {
@@ -8665,8 +8532,9 @@ int instituteCompareKernel ( institute_t *  ip1, institute_t * ip2 )
         {
           if ( ip2->name )
             {
-              len = strlen(ip2->name);
-              if ( memcmp(ip2->name, ip1->name, len)) differ = 1;
+              len1 = strlen(ip1->name);
+              len2 = strlen(ip2->name);
+              if ( (len1 != len2) || memcmp(ip2->name, ip1->name, len2) ) differ = 1;
             }
         }
     }
@@ -8674,8 +8542,9 @@ int instituteCompareKernel ( institute_t *  ip1, institute_t * ip2 )
     {
       if ( ip2->longname )
         {
-          len = strlen(ip2->longname);
-          if ( memcmp(ip2->longname, ip1->longname, len)) differ = 1;
+          len1 = strlen(ip1->longname);
+          len2 = strlen(ip2->longname);
+          if ( (len1 < len2) || memcmp(ip2->longname, ip1->longname, len2) ) differ = 1;
         }
     }
   else
@@ -10730,11 +10599,11 @@ int dblcmp(const void *s1, const void *s2)
 }
 */
 static
-int cmpLevelTable(const void *s1, const void *s2)
+int cmpLevelTable(const void* s1, const void* s2)
 {
   int cmp = 0;
-  leveltable_t *x = (leveltable_t *) s1;
-  leveltable_t *y = (leveltable_t *) s2;
+  const leveltable_t* x = s1;
+  const leveltable_t* y = s2;
   /*
   printf("%g %g  %d %d\n", x->leve11, y->level1, x, y);
   */
@@ -10744,6 +10613,21 @@ int cmpLevelTable(const void *s1, const void *s2)
   return (cmp);
 }
 
+static
+int cmpLevelTableInv(const void* s1, const void* s2)
+{
+  int cmp = 0;
+  const leveltable_t* x = s1;
+  const leveltable_t* y = s2;
+  /*
+  printf("%g %g  %d %d\n", x->leve11, y->level1, x, y);
+  */
+  if      ( x->level1 < y->level1 ) cmp =  1;
+  else if ( x->level1 > y->level1 ) cmp = -1;
+
+  return (cmp);
+}
+
 
 typedef struct
 {
@@ -10755,11 +10639,11 @@ param_t;
 
 
 static
-int cmpparam(const void *s1, const void *s2)
+int cmpparam(const void* s1, const void* s2)
 {
   int cmp = 0;
-  param_t *x = (param_t *) s1;
-  param_t *y = (param_t *) s2;
+  const param_t* x = s1;
+  const param_t* y = s2;
 
   if      ( x->param > y->param ) cmp =  1;
   else if ( x->param < y->param ) cmp = -1;
@@ -10769,11 +10653,11 @@ int cmpparam(const void *s1, const void *s2)
 
 
 static
-int cmpltype(const void *s1, const void *s2)
+int cmpltype(const void* s1, const void* s2)
 {
   int cmp = 0;
-  param_t *x = (param_t *) s1;
-  param_t *y = (param_t *) s2;
+  const param_t* x = s1;
+  const param_t* y = s2;
 
   if      ( x->ltype > y->ltype ) cmp =  1;
   else if ( x->ltype < y->ltype ) cmp = -1;
@@ -10873,39 +10757,47 @@ void cdi_generate_vars(stream_t *streamptr)
 
       if ( nlevels > 1 )
 	{
-	  int linc = FALSE, ldec = FALSE;
-	  /* check increasing of levels */
-	  for ( levelID = 1; levelID < nlevels; levelID++ )
-	    if ( dlevels[levelID] < dlevels[levelID-1] ) break;
-
-	  if ( levelID == nlevels ) linc = TRUE;
-
-	  if ( linc == FALSE )
-	    {
-	      /* check decreasing of levels */
-	      for ( levelID = 1; levelID < nlevels; levelID++ )
-		if ( dlevels[levelID] > dlevels[levelID-1] ) break;
-
-	      if ( levelID == nlevels ) ldec = TRUE;
-
-	      if ( ldec == FALSE ||
-		   zaxistype == ZAXIS_HYBRID ||
-		   zaxistype == ZAXIS_DEPTH_BELOW_LAND )
-		{
-		  /*
-		  qsort(dlevels, nlevels, sizeof(double), dblcmp);
-		  */
-		  qsort(vartable[varid].levelTable, nlevels, sizeof(leveltable_t), cmpLevelTable);
+          bool linc = true, ldec = true, lsort = false;
+          for ( levelID = 1; levelID < nlevels; levelID++ )
+            {
+              /* check increasing of levels */
+              linc &= (dlevels[levelID] > dlevels[levelID-1]);
+              /* check decreasing of levels */
+              ldec &= (dlevels[levelID] < dlevels[levelID-1]);
+            }
+          /*
+           * always sort pressure z-axis to ensure
+           * vartable[varid].levelTable[levelID1].level1 < vartable[varid].levelTable[levelID2].level1 <=> levelID1 > levelID2
+           * unless already sorted in decreasing order
+           */
+          if ( !ldec && zaxistype == ZAXIS_PRESSURE )
+            {
+              qsort(vartable[varid].levelTable, (size_t)nlevels, sizeof(leveltable_t), cmpLevelTableInv);
+              lsort = true;
+            }
+          /*
+           * always sort hybrid and depth-below-land z-axis to ensure
+           * vartable[varid].levelTable[levelID1].level1 < vartable[varid].levelTable[levelID2].level1 <=> levelID1 < levelID2
+           * unless already sorted in increasing order
+           */
+          else if ( (!linc && !ldec) ||
+                    zaxistype == ZAXIS_HYBRID ||
+                    zaxistype == ZAXIS_DEPTH_BELOW_LAND )
+            {
+              qsort(vartable[varid].levelTable, (size_t)nlevels, sizeof(leveltable_t), cmpLevelTable);
+              lsort = true;
+            }
 
-		  if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
-		    for ( levelID = 0; levelID < nlevels; levelID++ )
-		      dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
-					  level_sf*vartable[varid].levelTable[levelID].level2)/2.;
-		  else
-		    for ( levelID = 0; levelID < nlevels; levelID++ )
-		      dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
-		}
-	    }
+          if ( lsort )
+            {
+              if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
+                for ( levelID = 0; levelID < nlevels; levelID++ )
+                  dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
+                                      level_sf*vartable[varid].levelTable[levelID].level2)/2.;
+              else
+                for ( levelID = 0; levelID < nlevels; levelID++ )
+                  dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
+            }
 	}
 
       if ( lbounds )
@@ -10916,7 +10808,7 @@ void cdi_generate_vars(stream_t *streamptr)
 	  dlevels2 = (double *) malloc(nlevels*sizeof(double));
 	  for ( levelID = 0; levelID < nlevels; levelID++ )
 	    dlevels2[levelID] = level_sf*vartable[varid].levelTable[levelID].level2;
-	}
+        }
 
       char *unitptr = cdiUnitNamePtr(vartable[varid].level_unit);
       zaxisID = varDefZaxis(vlistID, zaxistype, nlevels, dlevels, lbounds, dlevels1, dlevels2,
@@ -11642,7 +11534,7 @@ vlist_delete(vlist_t *vlistptr)
 
 @Prototype void vlistDestroy(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
 
 @EndFunction
 */
@@ -11661,8 +11553,8 @@ void vlistDestroy(int vlistID)
 
 @Prototype void vlistCopy(int vlistID2, int vlistID1)
 @Parameter
-    @Item  vlistID2  Target variable list ID
-    @Item  vlistID1  Source variable list ID
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
 
 @Description
 The function @func{vlistCopy} copies all entries from vlistID1 to vlistID2.
@@ -11686,7 +11578,7 @@ void vlistCopy(int vlistID2, int vlistID1)
   if ( vlistptr1->vars )
     {
       int nvars = vlistptr1->nvars;
-      int nlevs, varID;
+      int varID;
 
       //vlistptr2->varsAllocated = nvars;
       vlistptr2->vars = (var_t *) malloc(vlistptr2->varsAllocated*sizeof(var_t));
@@ -11737,10 +11629,13 @@ void vlistCopy(int vlistID2, int vlistID1)
 	  vlistptr2->vars[varID].atts.nelems = 0;
 	  vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
 
-          nlevs = vlistptr1->vars[varID].nlevs;
-          vlistptr2->vars[varID].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
-          memcpy(vlistptr2->vars[varID].levinfo,
-                 vlistptr1->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
+          if ( vlistptr1->vars[varID].levinfo )
+            {
+              int nlevs = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
+              vlistptr2->vars[varID].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
+              memcpy(vlistptr2->vars[varID].levinfo,
+                     vlistptr1->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
+            }
 	}
     }
 }
@@ -11751,7 +11646,7 @@ void vlistCopy(int vlistID2, int vlistID1)
 
 @Prototype int vlistDuplicate(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
 @Description
 The function @func{vlistDuplicate} duplicates the variable list from vlistID1.
@@ -11788,9 +11683,13 @@ void vlistClearFlag(int vlistID)
   for ( varID = 0; varID < vlistptr->nvars; varID++ )
     {
       vlistptr->vars[varID].flag = FALSE;
-      for ( levID = 0; levID < vlistptr->vars[varID].nlevs; levID++ )
+      if ( vlistptr->vars[varID].levinfo )
         {
-          vlistptr->vars[varID].levinfo[levID].flag = FALSE;
+          int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
+          for ( levID = 0; levID < nlevs; levID++ )
+            {
+              vlistptr->vars[varID].levinfo[levID].flag = FALSE;
+            }
         }
     }
 }
@@ -11883,8 +11782,8 @@ int vlist_generate_zaxis(int vlistID, int zaxistype, int nlevels, double *levels
 
 @Prototype void vlistCopyFlag(int vlistID2, int vlistID1)
 @Parameter
-    @Item  vlistID2  Target variable list ID
-    @Item  vlistID1  Source variable list ID
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
 
 @Description
 The function @func{vlistCopyFlag} copies all entries with a flag from vlistID1 to vlistID2.
@@ -11985,10 +11884,11 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 	    vlistptr2->vars[varID2].atts.nelems = 0;
 	    vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
 
-	    nlevs  = vlistptr1->vars[varID].nlevs;
+	    nlevs  = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
 	    nlevs2 = 0;
-	    for ( levID = 0; levID < nlevs; levID++ )
-	      if ( vlistptr1->vars[varID].levinfo[levID].flag ) nlevs2++;
+            if ( vlistptr1->vars[varID].levinfo )
+              for ( levID = 0; levID < nlevs; levID++ )
+                if ( vlistptr1->vars[varID].levinfo[levID].flag ) nlevs2++;
 
 	    vlistptr2->vars[varID2].levinfo = (levinfo_t *) malloc(nlevs2*sizeof(levinfo_t));
 
@@ -12005,6 +11905,8 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 		zaxisID = vlistptr1->vars[varID].zaxisID;
 		levels = (double *) malloc(nlevs2*sizeof(double));
 		levID2 = 0;
+                if (!vlistptr1->vars[varID].levinfo)
+                  cdiVlistCreateVarLevInfo(vlistptr1, varID);
 		for ( levID = 0; levID < nlevs; ++levID )
 		  if ( vlistptr1->vars[varID].levinfo[levID].flag )
 		    {
@@ -12060,7 +11962,6 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 
 		zaxisID = zaxisID2;
 		vlistptr2->vars[varID2].zaxisID = zaxisID2;
-		vlistptr2->vars[varID2].nlevs   = nlevs2;
 	      }
 
 	    for ( levID = 0; levID < nlevs2; levID++ )
@@ -12109,8 +12010,8 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 
 @Prototype void vlistCat(int vlistID2, int vlistID1)
 @Parameter
-    @Item  vlistID2  Target variable list ID
-    @Item  vlistID1  Source variable list ID
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
 
 @Description
 Concatenate the variable list vlistID1 at the end of vlistID2.
@@ -12171,9 +12072,12 @@ void vlistCat(int vlistID2, int vlistID1)
       if ( vlistptr1->vars[varID].units )
         vlistptr2->vars[varID2].units = strdupx(vlistptr1->vars[varID].units);
 
-      nlevs = vlistptr1->vars[varID].nlevs;
-      vlistptr2->vars[varID2].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
-      memcpy(vlistptr2->vars[varID2].levinfo, vlistptr1->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
+      nlevs = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
+      if (vlistptr1->vars[varID].levinfo)
+        {
+          vlistptr2->vars[varID2].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
+          memcpy(vlistptr2->vars[varID2].levinfo, vlistptr1->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
+        }
 
       if ( vlistptr1->vars[varID].ensdata )
         {
@@ -12236,8 +12140,8 @@ void vlistCat(int vlistID2, int vlistID1)
 
 @Prototype void vlistMerge(int vlistID2, int vlistID1)
 @Parameter
-    @Item  vlistID2  Target variable list ID
-    @Item  vlistID1  Source variable list ID
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
 
 @Description
 Merge the variable list vlistID1 to the variable list vlistID2.
@@ -12290,21 +12194,24 @@ void vlistMerge(int vlistID2, int vlistID1)
           vlistptr1->vars[varID].mvarID = varID;
           vlistptr2->vars[varID].mvarID = varID;
 
-          nlevs1 = vlistptr1->vars[varID].nlevs;
-          nlevs2 = vlistptr2->vars[varID].nlevs;
+          nlevs1 = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
+          nlevs2 = zaxisInqSize(vlistptr2->vars[varID].zaxisID);
 
           nlevs = nlevs1 + nlevs2;
 
-          vlistptr2->vars[varID].nlevs = nlevs;
           /*
           fprintf(stderr, "var %d %d %d %d %d\n", varID, nlevs1, nlevs2, nlevs, sizeof(levinfo_t));
           */
-          vlistptr2->vars[varID].levinfo =
-            (levinfo_t *) realloc(vlistptr2->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
-
-	  memcpy(vlistptr2->vars[varID].levinfo+nlevs2,
-		 vlistptr1->vars[varID].levinfo, nlevs1*sizeof(levinfo_t));
+          if (vlistptr1->vars[varID].levinfo)
+            {
+              vlistptr2->vars[varID].levinfo =
+                xrealloc(vlistptr2->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
 
+              memcpy(vlistptr2->vars[varID].levinfo+nlevs2,
+                     vlistptr1->vars[varID].levinfo, nlevs1*sizeof(levinfo_t));
+            }
+          else
+            cdiVlistCreateVarLevInfo(vlistptr1, varID);
 	  for ( levID = 0; levID < nlevs1; levID++ )
 	    {
 	      vlistptr1->vars[varID].levinfo[levID].mlevelID = nlevs2 + levID;
@@ -12321,8 +12228,8 @@ void vlistMerge(int vlistID2, int vlistID1)
           zaxisID1 = vlistptr1->vars[varID].zaxisID;
           zaxisID2 = vlistptr2->vars[varID].zaxisID;
           /*
-          nlevs1 = vlistptr1->vars[varID].nlevs;
-          nlevs2 = vlistptr2->vars[varID].nlevs;
+          nlevs1 = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
+          nlevs2 = zaxisInqSize(vlistptr2->vars[varID].zaxisID);
           */
           nlevs1 = zaxisInqSize(zaxisID1);
           nlevs2 = zaxisInqSize(zaxisID2);
@@ -12373,7 +12280,7 @@ void vlistMerge(int vlistID2, int vlistID1)
 
 @Prototype int vlistNvars(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
 @Description
 The function @func{vlistNvars} returns the number of variables in the variable list vlistID.
@@ -12405,7 +12312,7 @@ int vlistNrecs(int vlistID)
   vlist_check_ptr(__func__, vlistptr);
 
   for ( varID = 0; varID < vlistptr->nvars; varID++ )
-    nrecs +=  vlistptr->vars[varID].nlevs;
+    nrecs +=  zaxisInqSize(vlistptr->vars[varID].zaxisID);
 
   return (nrecs);
 }
@@ -12450,7 +12357,7 @@ int vlistNumber(int vlistID)
 
 @Prototype int vlistNgrids(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
 @Description
 The function @func{vlistNgrids} returns the number of grids in the variable list vlistID.
@@ -12477,7 +12384,7 @@ int vlistNgrids(int vlistID)
 
 @Prototype int vlistNzaxis(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
 @Description
 The function @func{vlistNzaxis} returns the number of zaxis in the variable list vlistID.
@@ -12509,7 +12416,7 @@ void vlistDefNtsteps(int vlistID, int nts)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -12558,7 +12465,7 @@ vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
 
   if ( nvars > 0 )
     {
-      fprintf(fp, " varID param    gridID zaxisID tsteptype nlevel flag "
+      fprintf(fp, " varID param    gridID zaxisID tsteptype flag "
               " name     longname iorank\n");
       for ( varID = 0; varID < nvars; varID++ )
         {
@@ -12566,7 +12473,6 @@ vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
           gridID   = vlistptr->vars[varID].gridID;
           zaxisID  = vlistptr->vars[varID].zaxisID;
 	  tsteptype= vlistptr->vars[varID].tsteptype;
-          nlevs    = vlistptr->vars[varID].nlevs;
           name     = vlistptr->vars[varID].name;
           longname = vlistptr->vars[varID].longname;
           units    = vlistptr->vars[varID].units;
@@ -12574,9 +12480,9 @@ vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
           iorank   = vlistptr->vars[varID].iorank;
 
           cdiParamToString(param, paramstr, sizeof(paramstr));
-          fprintf(fp, "%6d %-8s %6d %6d %6d %6d %5d %-8s"
+          fprintf(fp, "%6d %-8s %6d %6d %6d %5d %-8s"
                   " %s %6d",
-                  varID, paramstr, gridID, zaxisID, tsteptype, nlevs, flag,
+                  varID, paramstr, gridID, zaxisID, tsteptype, flag,
                   name ? name : "", longname ? longname : "",
                   iorank);
 
@@ -12588,18 +12494,24 @@ vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
       fprintf(fp, " varID  levID fvarID flevID mvarID mlevID  index  dtype  flag  level\n");
       for ( varID = 0; varID < nvars; varID++ )
         {
-          nlevs    = vlistptr->vars[varID].nlevs;
           zaxisID  = vlistptr->vars[varID].zaxisID;
+          nlevs    = zaxisInqSize(zaxisID);
           fvarID   = vlistptr->vars[varID].fvarID;
           mvarID   = vlistptr->vars[varID].mvarID;
           dtype    = vlistptr->vars[varID].datatype;
           for ( levID = 0; levID < nlevs; levID++ )
             {
-              flevID = vlistptr->vars[varID].levinfo[levID].flevelID;
-              mlevID = vlistptr->vars[varID].levinfo[levID].mlevelID;
-              index  = vlistptr->vars[varID].levinfo[levID].index;
-              flag   = vlistptr->vars[varID].levinfo[levID].flag;
+              levinfo_t li;
+              if (vlistptr->vars[varID].levinfo)
+                li = vlistptr->vars[varID].levinfo[levID];
+              else
+                li = DEFAULT_LEVINFO(levID);
+              flevID = li.flevelID;
+              mlevID = li.mlevelID;
+              index  = li.index;
+              flag   = li.flag;
               level  = zaxisInqLevel(zaxisID, levID);
+
               fprintf(fp, "%6d %6d %6d %6d %6d %6d %6d %6d %5d  %.9g\n",
                       varID, levID, fvarID, flevID, mvarID, mlevID, index,
                       dtype, flag, level);
@@ -12610,7 +12522,7 @@ vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
       fprintf(fp, " varID  size iorank\n");
       for ( varID = 0; varID < nvars; varID++ )
         fprintf(fp, "%3d %8d %6d\n", varID,
-                vlistptr->vars[varID].nlevs
+                zaxisInqSize(vlistptr->vars[varID].zaxisID)
                 * gridInqSize(vlistptr->vars[varID].gridID),
                 vlistptr->vars[varID].iorank);
     }
@@ -12634,8 +12546,8 @@ void vlistPrint(int vlistID)
 
 @Prototype void vlistDefTaxis(int vlistID, int taxisID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}.
 
 @Description
 The function @func{vlistDefTaxis} defines the time axis of a variable list.
@@ -12652,7 +12564,7 @@ void vlistDefTaxis(int vlistID, int taxisID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -12665,7 +12577,7 @@ void vlistDefTaxis(int vlistID, int taxisID)
 
 @Prototype int vlistInqTaxis(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
 @Description
 The function @func{vlistInqTaxis} returns the time axis of a variable list.
@@ -12697,7 +12609,7 @@ void  vlistDefTable(int vlistID, int tableID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -12727,9 +12639,7 @@ void vlistDefInstitut(int vlistID, int instID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
-
-      xdebug("%s", "");
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -12775,7 +12685,7 @@ void vlistDefModel(int vlistID, int modelID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -12879,7 +12789,7 @@ void vlistChangeGridIndex(int vlistID, int index, int gridID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -12905,7 +12815,7 @@ void vlistChangeGrid(int vlistID, int gridID1, int gridID2)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -12972,7 +12882,7 @@ void vlistChangeZaxisIndex(int vlistID, int index, int zaxisID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -12986,19 +12896,14 @@ void vlistChangeZaxisIndex(int vlistID, int index, int zaxisID)
         vlistptr->vars[varID].zaxisID = zaxisID;
 
         nlevs = zaxisInqSize(zaxisID);
-        if ( nlevs != vlistptr->vars[varID].nlevs )
+        if ( vlistptr->vars[varID].levinfo
+             && nlevs != zaxisInqSize(zaxisIDold) )
           {
-            vlistptr->vars[varID].nlevs   = nlevs;
             vlistptr->vars[varID].levinfo = (levinfo_t *) realloc(vlistptr->vars[varID].levinfo,
                                                                      nlevs*sizeof(levinfo_t));
 
             for ( levID = 0; levID < nlevs; levID++ )
-              {
-                vlistptr->vars[varID].levinfo[levID].flevelID = levID;
-                vlistptr->vars[varID].levinfo[levID].mlevelID = levID;
-                vlistptr->vars[varID].levinfo[levID].index    = -1;
-                vlistptr->vars[varID].levinfo[levID].flag     = FALSE;
-              }
+              vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO(levID);
           }
       }
 }
@@ -13008,7 +12913,7 @@ void vlistChangeZaxis(int vlistID, int zaxisID1, int zaxisID2)
 {
   int varID, nvars;
   int index, nzaxis;
-  int nlevs, levID;
+  int nlevs1 = zaxisInqSize(zaxisID1), nlevs2 = zaxisInqSize(zaxisID2), levID;
   vlist_t *vlistptr;
 
   vlistptr = vlist_to_pointer(vlistID);
@@ -13017,7 +12922,7 @@ void vlistChangeZaxis(int vlistID, int zaxisID1, int zaxisID2)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -13037,20 +12942,14 @@ void vlistChangeZaxis(int vlistID, int zaxisID1, int zaxisID2)
       {
         vlistptr->vars[varID].zaxisID = zaxisID2;
 
-        nlevs = zaxisInqSize(zaxisID2);
-        if ( nlevs != vlistptr->vars[varID].nlevs )
+        if ( vlistptr->vars[varID].levinfo && nlevs2 != nlevs1 )
           {
-            vlistptr->vars[varID].nlevs   = nlevs;
-            vlistptr->vars[varID].levinfo = (levinfo_t *) realloc(vlistptr->vars[varID].levinfo,
-                                                                     nlevs*sizeof(levinfo_t));
+            vlistptr->vars[varID].levinfo
+              = realloc(vlistptr->vars[varID].levinfo,
+                        nlevs2 * sizeof(levinfo_t));
 
-            for ( levID = 0; levID < nlevs; levID++ )
-              {
-                vlistptr->vars[varID].levinfo[levID].flevelID = levID;
-                vlistptr->vars[varID].levinfo[levID].mlevelID = levID;
-                vlistptr->vars[varID].levinfo[levID].index    = -1;
-                vlistptr->vars[varID].levinfo[levID].flag     = FALSE;
-              }
+            for ( levID = 0; levID < nlevs2; levID++ )
+              vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO(levID);
           }
       }
 }
@@ -13095,7 +12994,7 @@ int  vlistGetSizeP ( void * vlistptr, void *context)
   txsize = serializeGetSize(vlist_nints, DATATYPE_INT, context);
   txsize += vlistAttsGetSize(p, CDI_GLOBAL, context);
   for ( varID = 0; varID <  p->nvars; varID++ )
-    txsize += vlistVarGetSize(p, varID, context);
+    txsize += vlistVarGetPackSize(p, varID, context);
   return txsize;
 }
 
@@ -13128,10 +13027,11 @@ void vlistUnpack(char * buf, int size, int *position, int nspTarget, void *conte
   serializeUnpack(buf, size, position, tempbuf, vlist_nints, DATATYPE_INT, context);
   newvlist = vlistCreate();
   /* xassert(newvlist == tempbuf[0]); */
-  vlistDefTaxis ( newvlist, namespaceAdaptKey ( tempbuf[3], nspTarget ));
-  vlistDefTable(newvlist, tempbuf[4]);
-  vlistDefInstitut ( newvlist, namespaceAdaptKey ( tempbuf[5], nspTarget ));
-  vlistDefModel ( newvlist, namespaceAdaptKey ( tempbuf[6], nspTarget ));
+  vlist_t *p = vlist_to_pointer(newvlist);
+  p->taxisID = namespaceAdaptKey(tempbuf[3], nspTarget);
+  p->tableID = tempbuf[4];
+  p->instID = namespaceAdaptKey(tempbuf[5], nspTarget);
+  p->modelID = namespaceAdaptKey(tempbuf[6], nspTarget);
   vlistAttsUnpack(newvlist, CDI_GLOBAL, buf, size, position, context);
   for ( varID = 0; varID < tempbuf[1]; varID++ )
     vlistVarUnpack(newvlist, buf, size, position, nspTarget, context);
@@ -13246,7 +13146,7 @@ void fill_att(cdi_att_t *attp, int indtype, int exdtype, size_t nelems, size_t x
 
 @Prototype int vlistInqNatts(int vlistID, int varID, int *nattsp)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
     @Item  nattsp   Pointer to location for returned number of variable attributes.
 
@@ -13277,7 +13177,7 @@ int vlistInqNatts(int vlistID, int varID, int *nattsp)
 
 @Prototype int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
     @Item  attnum   Attribute number (from 0 to natts-1).
     @Item  name     Pointer to the location for the returned attribute name. The caller must allocate space for the 
@@ -13530,7 +13430,7 @@ int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char
 
 @Prototype int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
     @Item  name     Attribute name.
     @Item  mlen     Number of allocated values provided for the attribute.
@@ -13552,7 +13452,7 @@ int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
 
 @Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
     @Item  name     Attribute name.
     @Item  mlen     Number of allocated values provided for the attribute.
@@ -13574,7 +13474,7 @@ int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *d
 
 @Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
     @Item  name     Attribute name.
     @Item  mlen     Number of allocated values provided for the attribute.
@@ -13758,6 +13658,7 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].tsteptype     = TSTEP_INSTANT;
   vlistptr->vars[varID].timave        = 0;
   vlistptr->vars[varID].timaccu       = 0;
+  vlistptr->vars[varID].typeOfGeneratingProcess = 0;
   vlistptr->vars[varID].chunktype     = cdiChunkType;
   vlistptr->vars[varID].xyz           = 0;
   vlistptr->vars[varID].gridID        = CDI_UNDEFID;
@@ -13774,7 +13675,6 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].stdname       = NULL;
   vlistptr->vars[varID].units         = NULL;
   vlistptr->vars[varID].extra         = NULL;
-  vlistptr->vars[varID].nlevs         = 0;
   vlistptr->vars[varID].levinfo       = NULL;
   vlistptr->vars[varID].comptype      = COMPRESS_NONE;
   vlistptr->vars[varID].complevel     = 1;
@@ -13925,15 +13825,13 @@ vlistDestroy(vlistID);
 int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
 {
   int varID;
-  int nlevs;
-  int levID;
   int index;
   vlist_t *vlistptr;
 
   vlistptr = vlist_to_pointer(vlistID);
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return CDI_UNDEFID;
     }
 
@@ -13954,20 +13852,6 @@ int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
       vlistptr->vars[varID].tsteptype = TSTEP_INSTANT;
     }
 
-  nlevs = zaxisInqSize(zaxisID);
-
-  vlistptr->vars[varID].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
-
-  for ( levID = 0; levID < nlevs; levID++ )
-    {
-      vlistptr->vars[varID].levinfo[levID].flag     = 0;
-      vlistptr->vars[varID].levinfo[levID].index    = -1;
-      vlistptr->vars[varID].levinfo[levID].flevelID = levID;
-      vlistptr->vars[varID].levinfo[levID].mlevelID = levID;
-    }
-
-  vlistptr->vars[varID].nlevs = nlevs;
-
   for ( index = 0; index < vlistptr->ngrids; index++ )
     if ( gridID == vlistptr->gridIDs[index] ) break;
 
@@ -13997,6 +13881,20 @@ int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
   return (varID);
 }
 
+void
+cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID)
+{
+  xassert(varID >= 0 && varID < vlistptr->nvars
+          && vlistptr->vars[varID].levinfo == NULL);
+  int zaxisID = vlistptr->vars[varID].zaxisID;
+  int nlevs = zaxisInqSize(zaxisID);
+
+  vlistptr->vars[varID].levinfo = malloc(nlevs * sizeof(levinfo_t));
+
+  for (int levID = 0; levID < nlevs; levID++ )
+      vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO(levID);
+}
+
 /*
 @Function  vlistDefVarParam
 @Title     Define the parameter number of a Variable
@@ -14022,7 +13920,7 @@ void vlistDefVarParam(int vlistID, int varID, int param)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -14055,14 +13953,14 @@ void vlistDefVarCode(int vlistID, int varID, int code)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
   param = vlistptr->vars[varID].param;
 
   cdiDecodeParam(param, &pnum, &pcat, &pdis);
-  
+
   vlistptr->vars[varID].param = cdiEncodeParam(code, pcat, pdis);
 }
 
@@ -14088,7 +13986,7 @@ void vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *tstepty
 
 @Prototype int vlistInqVarGrid(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -14116,7 +14014,7 @@ int vlistInqVarGrid(int vlistID, int varID)
 
 @Prototype int vlistInqVarZaxis(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -14144,7 +14042,7 @@ int vlistInqVarZaxis(int vlistID, int varID)
 
 @Prototype int vlistInqVarParam(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -14175,7 +14073,7 @@ int vlistInqVarParam(int vlistID, int varID)
 
 @Prototype int vlistInqVarCode(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -14262,7 +14160,7 @@ const char *vlistInqVarUnitsPtr(int vlistID, int varID)
 
 @Prototype void vlistInqVarName(int vlistID, int varID, char *name)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
     @Item  name     Returned variable name. The caller must allocate space for the 
                     returned string. The maximum possible length, in characters, of
@@ -14316,7 +14214,7 @@ void vlistInqVarName(int vlistID, int varID, char *name)
 
 @Prototype void vlistInqVarLongname(int vlistID, int varID, char *longname)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
     @Item  longname Long name of the variable. The caller must allocate space for the 
                     returned string. The maximum possible length, in characters, of
@@ -14368,7 +14266,7 @@ void vlistInqVarLongname(int vlistID, int varID, char *longname)
 
 @Prototype void vlistInqVarStdname(int vlistID, int varID, char *stdname)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
     @Item  stdname  Standard name of the variable. The caller must allocate space for the 
                     returned string. The maximum possible length, in characters, of
@@ -14407,7 +14305,7 @@ void vlistInqVarStdname(int vlistID, int varID, char *stdname)
 
 @Prototype void vlistInqVarUnits(int vlistID, int varID, char *units)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
     @Item  units    Units of the variable. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
@@ -14499,7 +14397,7 @@ int vlistInqVarSize(int vlistID, int varID)
 
 @Prototype int vlistInqVarDatatype(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -14569,7 +14467,7 @@ void vlistDefVarDatatype(int vlistID, int varID, int datatype)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -14596,7 +14494,7 @@ void vlistDefVarInstitut(int vlistID, int varID, int instID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -14620,7 +14518,7 @@ void vlistDefVarModel(int vlistID, int varID, int modelID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -14646,7 +14544,7 @@ void vlistDefVarTable(int vlistID, int varID, int tableID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -14701,7 +14599,7 @@ void vlistDefVarName(int vlistID, int varID, const char *name)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -14742,7 +14640,7 @@ void vlistDefVarLongname(int vlistID, int varID, const char *longname)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -14783,7 +14681,7 @@ void vlistDefVarStdname(int vlistID, int varID, const char *stdname)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -14824,7 +14722,7 @@ void vlistDefVarUnits(int vlistID, int varID, const char *units)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -14850,7 +14748,7 @@ void vlistDefVarUnits(int vlistID, int varID, const char *units)
 
 @Prototype double vlistInqVarMissval(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -14920,7 +14818,7 @@ void vlistDefVarExtra(int vlistID, int varID, const char *extra)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -14946,7 +14844,7 @@ void vlistDefVarExtra(int vlistID, int varID, const char *extra)
 
 @Prototype void vlistInqVarExtra(int vlistID, int varID, char *extra)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
     @Item  extra    Returned variable extra information. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
@@ -15016,7 +14914,7 @@ double vlistInqVarScalefactor(int vlistID, int varID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return 1.0;
     }
 
@@ -15045,7 +14943,7 @@ void vlistDefVarScalefactor(int vlistID, int varID, double scalefactor)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -15063,7 +14961,7 @@ void vlistDefVarAddoffset(int vlistID, int varID, double addoffset)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -15081,7 +14979,7 @@ void vlistDefVarTsteptype(int vlistID, int varID, int tsteptype)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -15107,7 +15005,7 @@ void vlistDefVarTimave(int vlistID, int varID, int timave)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -15133,7 +15031,7 @@ void vlistDefVarTimaccu(int vlistID, int varID, int timaccu)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -15159,7 +15057,7 @@ void vlistDefVarTypeOfGeneratingProcess(int vlistID, int varID, int typeOfGenera
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -15251,14 +15149,33 @@ void vlistDefFlag(int vlistID, int varID, int levID, int flag)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  vlistptr->vars[varID].flag = flag;
+  levinfo_t li = DEFAULT_LEVINFO(levID);
+  if (vlistptr->vars[varID].levinfo)
+    ;
+  else if (flag != li.flag)
+    cdiVlistCreateVarLevInfo(vlistptr, varID);
+  else
+    return;
+
   vlistptr->vars[varID].levinfo[levID].flag = flag;
+
+  vlistptr->vars[varID].flag = 0;
+
+  int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
+  for ( int levelID = 0; levelID < nlevs; levelID++ )
+    {
+      if ( vlistptr->vars[varID].levinfo[levelID].flag )
+        {
+          vlistptr->vars[varID].flag = 1;
+          break;
+        }
+    }
 }
 
 
@@ -15268,7 +15185,13 @@ int vlistInqFlag(int vlistID, int varID, int levID)
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  return (vlistptr->vars[varID].levinfo[levID].flag);
+  if (vlistptr->vars[varID].levinfo)
+    return (vlistptr->vars[varID].levinfo[levID].flag);
+  else
+    {
+      levinfo_t li = DEFAULT_LEVINFO(levID);
+      return li.flag;
+    }
 }
 
 
@@ -15290,7 +15213,7 @@ int vlistFindVar(int vlistID, int fvarID)
       Message("varID not found for fvarID %d in vlistID %d!", fvarID, vlistID);
     }
 
-  return (varID);  
+  return (varID);
 }
 
 
@@ -15306,12 +15229,13 @@ int vlistFindLevel(int vlistID, int fvarID, int flevelID)
 
   if ( varID != -1 )
     {
-      for ( levelID = 0; levelID < vlistptr->vars[varID].nlevs; levelID++ )
+      int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
+      for ( levelID = 0; levelID < nlevs; levelID++ )
 	{
 	  if ( vlistptr->vars[varID].levinfo[levelID].flevelID == flevelID ) break;
 	}
 
-      if ( levelID == vlistptr->vars[varID].nlevs )
+      if ( levelID == nlevs )
 	{
 	  levelID = -1;
 	  Message("levelID not found for fvarID %d and levelID %d in vlistID %d!",
@@ -15319,7 +15243,7 @@ int vlistFindLevel(int vlistID, int fvarID, int flevelID)
 	}
     }
 
-  return (levelID);  
+  return (levelID);
 }
 
 
@@ -15329,7 +15253,7 @@ int vlistMergedVar(int vlistID, int varID)
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  return (vlistptr->vars[varID].mvarID);  
+  return (vlistptr->vars[varID].mvarID);
 }
 
 
@@ -15339,7 +15263,13 @@ int vlistMergedLevel(int vlistID, int varID, int levelID)
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  return (vlistptr->vars[varID].levinfo[levelID].mlevelID);  
+  if (vlistptr->vars[varID].levinfo)
+    return vlistptr->vars[varID].levinfo[levelID].mlevelID;
+  else
+    {
+      levinfo_t li = DEFAULT_LEVINFO(levelID);
+      return li.mlevelID;
+    }
 }
 
 
@@ -15349,13 +15279,20 @@ void vlistDefIndex(int vlistID, int varID, int levelID, int index)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  vlistptr->vars[varID].levinfo[levelID].index = index;  
+  levinfo_t li = DEFAULT_LEVINFO(levelID);
+  if (vlistptr->vars[varID].levinfo)
+    ;
+  else if (index != li.index)
+    cdiVlistCreateVarLevInfo(vlistptr, varID);
+  else
+    return;
+  vlistptr->vars[varID].levinfo[levelID].index = index;
 }
 
 
@@ -15365,7 +15302,13 @@ int vlistInqIndex(int vlistID, int varID, int levelID)
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  return (vlistptr->vars[varID].levinfo[levelID].index);  
+  if (vlistptr->vars[varID].levinfo)
+    return (vlistptr->vars[varID].levinfo[levelID].index);
+  else
+    {
+      levinfo_t li = DEFAULT_LEVINFO(levelID);
+      return li.index;
+    }
 }
 
 
@@ -15377,7 +15320,7 @@ void vlistChangeVarZaxis(int vlistID, int varID, int zaxisID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -15427,7 +15370,7 @@ void vlistChangeVarGrid(int vlistID, int varID, int gridID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -15475,7 +15418,7 @@ void vlistDefVarCompType(int vlistID, int varID, int comptype)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -15501,7 +15444,7 @@ void vlistDefVarCompLevel(int vlistID, int varID, int complevel)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -15776,7 +15719,7 @@ void     vlistDefVarIOrank   ( int vlistID, int varID, int iorank )
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -15801,7 +15744,7 @@ enum {
   vlistvar_ndbls = 3,
 };
 
-int vlistVarGetSize(vlist_t *p, int varID, void *context)
+int vlistVarGetPackSize(vlist_t *p, int varID, void *context)
 {
   var_t *var = p->vars + varID;
   int varsize = serializeGetSize(vlistvar_nints, DATATYPE_INT, context)
@@ -15814,7 +15757,8 @@ int vlistVarGetSize(vlist_t *p, int varID, void *context)
     varsize += serializeGetSize(strlen(var->stdname), DATATYPE_TXT, context);
   if (var->units)
     varsize += serializeGetSize(strlen(var->units), DATATYPE_TXT, context);
-  varsize += serializeGetSize(4 * var->nlevs, DATATYPE_INT, context);
+  varsize += serializeGetSize(4 * zaxisInqSize(var->zaxisID),
+                              DATATYPE_INT, context);
   varsize += vlistAttsGetSize(p, varID, context);
   return varsize;
 }
@@ -15824,7 +15768,7 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
 {
   double dtempbuf[vlistvar_ndbls];
   var_t *var = p->vars + varID;
-  int tempbuf[vlistvar_nints], namesz, longnamesz, stdnamesz, unitssz, i;
+  int tempbuf[vlistvar_nints], namesz, longnamesz, stdnamesz, unitssz;
 
   tempbuf[0] = var->flag;
   tempbuf[1] = var->gridID;
@@ -15844,7 +15788,8 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
   tempbuf[15] = var->missvalused;
   tempbuf[16] = var->comptype;
   tempbuf[17] = var->complevel;
-  tempbuf[18] = var->nlevs;
+  int nlevs = var->levinfo ? zaxisInqSize(var->zaxisID) : 0;
+  tempbuf[18] = nlevs;
   tempbuf[19] = var->iorank;
   dtempbuf[0] = var->missval;
   dtempbuf[1] = var->scalefactor;
@@ -15864,18 +15809,19 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
   if (unitssz)
     serializePack(var->units, unitssz, DATATYPE_TXT,
                   buf, size, position, context);
-  {
-    int levbuf[var->nlevs][4];
-    for (i = 0; i < var->nlevs; ++i)
+  if (nlevs)
     {
-      levbuf[i][0] = var->levinfo[i].flag;
-      levbuf[i][1] = var->levinfo[i].index;
-      levbuf[i][2] = var->levinfo[i].mlevelID;
-      levbuf[i][3] = var->levinfo[i].flevelID;
+      int levbuf[nlevs][4];
+      for (int levID = 0; levID < nlevs; ++levID)
+        {
+          levbuf[levID][0] = var->levinfo[levID].flag;
+          levbuf[levID][1] = var->levinfo[levID].index;
+          levbuf[levID][2] = var->levinfo[levID].mlevelID;
+          levbuf[levID][3] = var->levinfo[levID].flevelID;
+        }
+      serializePack(levbuf, nlevs * 4, DATATYPE_INT,
+                    buf, size, position, context);
     }
-    serializePack(levbuf, var->nlevs * 4, DATATYPE_INT,
-                  buf, size, position, context);
-  }
   vlistAttsPack(p, varID, buf, size, position, context);
 }
 
@@ -15893,6 +15839,7 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
   int tempbuf[vlistvar_nints];
   int newvar;
   char *varname = NULL;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
   serializeUnpack(buf, size, position,
                   tempbuf, vlistvar_nints, DATATYPE_INT, context);
   serializeUnpack(buf, size, position,
@@ -15950,25 +15897,27 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
   vlistDefVarAddoffset(vlistID, newvar, dtempbuf[2]);
   vlistDefVarCompType(vlistID, newvar, tempbuf[16]);
   vlistDefVarCompLevel(vlistID, newvar, tempbuf[17]);
-  {
-    int levbuf[tempbuf[18]][4];
-    var_t *var = vlist_to_pointer(vlistID)->vars + newvar;
-    int nlevs=tempbuf[18], i, flagSetLev = 0;
-    xassert(nlevs == var->nlevs);
-    serializeUnpack(buf, size, position,
-                    levbuf, nlevs * 4, DATATYPE_INT, context);
-    for (i = 0; i < nlevs; ++i)
-    {
-      vlistDefFlag(vlistID, newvar, i, levbuf[i][0]);
-      vlistDefIndex(vlistID, newvar, i, levbuf[i][1]);
-      // FIXME: these lack an accessor function
-      var->levinfo[i].mlevelID = levbuf[i][2];
-      var->levinfo[i].flevelID = levbuf[i][3];
-      if (levbuf[i][0] == tempbuf[0])
-        flagSetLev = i;
-    }
-    vlistDefFlag(vlistID, newvar, flagSetLev, levbuf[flagSetLev][0]);
-  }
+  int nlevs = tempbuf[18];
+  if (nlevs)
+    {
+      int levbuf[nlevs][4];
+      var_t *var = vlistptr->vars + newvar;
+      int i, flagSetLev = 0;
+      cdiVlistCreateVarLevInfo(vlistptr, newvar);
+      serializeUnpack(buf, size, position,
+                      levbuf, nlevs * 4, DATATYPE_INT, context);
+      for (i = 0; i < nlevs; ++i)
+        {
+          vlistDefFlag(vlistID, newvar, i, levbuf[i][0]);
+          vlistDefIndex(vlistID, newvar, i, levbuf[i][1]);
+          // FIXME: these lack an accessor function
+          var->levinfo[i].mlevelID = levbuf[i][2];
+          var->levinfo[i].flevelID = levbuf[i][3];
+          if (levbuf[i][0] == tempbuf[0])
+            flagSetLev = i;
+        }
+      vlistDefFlag(vlistID, newvar, flagSetLev, levbuf[flagSetLev][0]);
+    }
   vlistDefVarIOrank(vlistID, newvar, tempbuf[19]);
   vlistAttsUnpack(vlistID, newvar, buf, size, position, context);
 }
@@ -17947,7 +17896,7 @@ void grid_init(grid_t *gridptr)
   gridptr->yunits[0]    = 0;
   gridptr->xstdname[0]  = 0;
   gridptr->ystdname[0]  = 0;
-  gridptr->uuid[0]      = 0;
+  memset(gridptr->uuid, 0, 16);
   gridptr->name         = NULL;
 }
 
@@ -18388,7 +18337,7 @@ void gridDefXname(int gridID, const char *xname)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning ("%s", "Operation not executed." );
+      Warning ("%s", "Operation not executed." );
       return;
     }
 
@@ -18420,7 +18369,7 @@ void gridDefXlongname(int gridID, const char *xlongname)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning ("%s", "Operation not executed." );
+      Warning ("%s", "Operation not executed." );
       return;
     }
 
@@ -18450,7 +18399,7 @@ void gridDefXunits(int gridID, const char *xunits)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -18482,7 +18431,7 @@ void gridDefYname(int gridID, const char *yname)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -18514,7 +18463,7 @@ void gridDefYlongname(int gridID, const char *ylongname)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -18546,7 +18495,7 @@ void gridDefYunits(int gridID, const char *yunits)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -18564,8 +18513,8 @@ void gridDefYunits(int gridID, const char *yunits)
 
 @Prototype void gridInqXname(int gridID, char *name)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  name     Name of the X-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  name     Name of the X-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -18594,8 +18543,8 @@ void gridInqXname(int gridID, char *xname)
 
 @Prototype void gridInqXlongname(int gridID, char *longname)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  longname Longname of the X-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  longname Longname of the X-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -18624,8 +18573,8 @@ void gridInqXlongname(int gridID, char *xlongname)
 
 @Prototype void gridInqXunits(int gridID, char *units)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  units    Units of the X-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  units    Units of the X-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -18666,8 +18615,8 @@ void gridInqXstdname(int gridID, char *xstdname)
 
 @Prototype void gridInqYname(int gridID, char *name)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  name     Name of the Y-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  name     Name of the Y-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -18696,8 +18645,8 @@ void gridInqYname(int gridID, char *yname)
 
 @Prototype void gridInqXlongname(int gridID, char *longname)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  longname Longname of the Y-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  longname Longname of the Y-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -18726,8 +18675,8 @@ void gridInqYlongname(int gridID, char *ylongname)
 
 @Prototype void gridInqYunits(int gridID, char *units)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  units    Units of the Y-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  units    Units of the Y-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -18767,7 +18716,7 @@ void gridInqYstdname(int gridID, char *ystdname)
 
 @Prototype int gridInqType(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqType} returns the type of a Grid.
@@ -18799,7 +18748,7 @@ int gridInqType(int gridID)
 
 @Prototype int gridInqSize(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqSize} returns the size of a Grid.
@@ -18883,7 +18832,7 @@ void gridDefTrunc(int gridID, int trunc)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -18914,7 +18863,7 @@ void gridDefXsize(int gridID, int xsize)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -18955,7 +18904,7 @@ void gridDefPrec(int gridID, int prec)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -18993,7 +18942,7 @@ int gridInqPrec(int gridID)
 
 @Prototype int gridInqXsize(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqXsize} returns the number of values of a X-axis.
@@ -19034,7 +18983,7 @@ void gridDefYsize(int gridID, int ysize)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -19065,7 +19014,7 @@ void gridDefYsize(int gridID, int ysize)
 
 @Prototype int gridInqYsize(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqYsize} returns the number of values of a Y-axis.
@@ -19107,7 +19056,7 @@ void gridDefNP(int gridID, int np)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning ("%s", "Operation not executed." );
+      Warning ("%s", "Operation not executed." );
       return;
     }
 
@@ -19124,7 +19073,7 @@ void gridDefNP(int gridID, int np)
 
 @Prototype int gridInqNP(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqNP} returns the number of parallels between a pole and the equator
@@ -19162,7 +19111,7 @@ void gridDefRowlon(int gridID, int nrowlon, const int *rowlon)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -19231,7 +19180,7 @@ void gridDefMask(int gridID, const int *mask)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -19294,7 +19243,7 @@ void gridDefMaskGME(int gridID, const int *mask)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -19322,7 +19271,7 @@ void gridDefMaskGME(int gridID, const int *mask)
 
 @Prototype int gridInqXvals(int gridID, double *xvals)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
     @Item  xvals    Pointer to the location into which the X-values are read.
                     The caller must allocate space for the returned values.
 
@@ -19385,7 +19334,7 @@ void gridDefXvals(int gridID, const double *xvals)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -19419,7 +19368,7 @@ void gridDefXvals(int gridID, const double *xvals)
 
 @Prototype int gridInqYvals(int gridID, double *yvals)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
     @Item  yvals    Pointer to the location into which the Y-values are read.
                     The caller must allocate space for the returned values.
 
@@ -19480,7 +19429,7 @@ void gridDefYvals(int gridID, const double *yvals)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -19671,7 +19620,7 @@ void gridDefXpole(int gridID, double xpole)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -19723,7 +19672,7 @@ void gridDefYpole(int gridID, double ypole)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -19775,7 +19724,7 @@ void gridDefAngle(int gridID, double angle)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -19824,7 +19773,7 @@ void gridDefGMEnd(int gridID, int nd)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -19872,7 +19821,7 @@ void gridDefGMEni(int gridID, int ni)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -19920,7 +19869,7 @@ void gridDefGMEni2(int gridID, int ni2)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
   gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
@@ -19957,7 +19906,7 @@ void gridDefGMEni3(int gridID, int ni3)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -20737,8 +20686,7 @@ int gridGenerate(grid_t grid)
 
 @Prototype int gridDuplicate(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate},
-                    @fref{gridDuplicate} or @fref{vlistInqVarGrid}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridDuplicate} duplicates a horizontal Grid.
@@ -20938,7 +20886,7 @@ void gridDefArea(int gridID, const double *area)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -21009,7 +20957,7 @@ void gridDefNvertex(int gridID, int nvertex)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -21054,7 +21002,7 @@ void gridDefXbounds(int gridID, const double *xbounds)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning ("%s", "Operation not executed.");
+      Warning ("%s", "Operation not executed.");
       return;
     }
 
@@ -21091,7 +21039,7 @@ void gridDefXbounds(int gridID, const double *xbounds)
 
 @Prototype int gridInqXbounds(int gridID, double *xbounds)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
     @Item  xbounds  Pointer to the location into which the X-bounds are read.
                     The caller must allocate space for the returned values.
 
@@ -21169,7 +21117,7 @@ void gridDefYbounds(int gridID, const double *ybounds)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -21206,7 +21154,7 @@ void gridDefYbounds(int gridID, const double *ybounds)
 
 @Prototype int gridInqYbounds(int gridID, double *ybounds)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
     @Item  ybounds  Pointer to the location into which the Y-bounds are read.
                     The caller must allocate space for the returned values.
 
@@ -21731,7 +21679,7 @@ void gridDefLCC(int gridID, double originLon, double originLat, double lonParY,
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -21763,7 +21711,7 @@ void gridDefLCC(int gridID, double originLon, double originLat, double lonParY,
 
 @Prototype void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY, double *lat1, double *lat2, double *xinc, double *yinc, int *projflag, int *scanflag)
 @Parameter
-    @Item  gridID    Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID    Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
     @Item  originLon Longitude of the first grid point.
     @Item  originLat Latitude of the first grid point.
     @Item  lonParY   The East longitude of the meridian which is parallel to the Y-axis.
@@ -21817,7 +21765,7 @@ void gridDefLcc2(int gridID, double earth_radius, double lon_0, double lat_0, do
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -21872,7 +21820,7 @@ void gridDefLaea(int gridID, double earth_radius, double lon_0, double lat_0)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -21924,7 +21872,7 @@ void gridDefComplexPacking(int gridID, int lcomplex)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -21970,7 +21918,7 @@ void gridDefNumber(int gridID, const int number)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -21987,7 +21935,7 @@ void gridDefNumber(int gridID, const int number)
 
 @Prototype int gridInqNumber(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqNumber} returns the reference number to an unstructured grid.
@@ -22027,7 +21975,7 @@ void gridDefPosition(int gridID, int position)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -22044,7 +21992,7 @@ void gridDefPosition(int gridID, int position)
 
 @Prototype int gridInqPosition(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqPosition} returns the position of grid in the reference file.
@@ -22084,7 +22032,7 @@ void gridDefReference(int gridID, const char *reference)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -22110,7 +22058,7 @@ void gridDefReference(int gridID, const char *reference)
 
 @Prototype char *gridInqReference(int gridID, char *reference)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqReference} returns the reference URI to an unstructured grid.
@@ -22159,7 +22107,7 @@ void gridDefUUID(int gridID, const char *uuid)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -22176,18 +22124,18 @@ void gridDefUUID(int gridID, const char *uuid)
 @Function  gridInqUUID
 @Title     Get the UUID to an unstructured grid
 
- at Prototype char *gridInqUUID(int gridID, char *uuid)
+ at Prototype void gridInqUUID(int gridID, char *uuid)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqUUID} returns the UUID to an unstructured grid.
 
 @Result
- at func{gridInqUUID} returns the UUID to an unstructured grid.
+ at func{gridInqUUID} returns the UUID to an unstructured grid to the parameter uuid.
 @EndFunction
 */
-char *gridInqUUID(int gridID, char *uuid)
+void gridInqUUID(int gridID, char *uuid)
 {
   grid_t *gridptr;
 
@@ -22196,8 +22144,6 @@ char *gridInqUUID(int gridID, char *uuid)
   grid_check_ptr(gridID, gridptr);
 
   memcpy(uuid, gridptr->uuid, 16);
-
-  return (uuid);
 }
 
 
@@ -22214,7 +22160,7 @@ gridTxCode ()
 }
 
 enum { gridNint    = 27,
-       gridNdouble = 25,
+       gridNdouble = 24,
        gridNstrings= 8,
        gridHasMaskFlag = 1 << 0,
        gridHasGMEMaskFlag = 1 << 1,
@@ -22251,13 +22197,13 @@ gridGetPackSize(void * voidP, void *context)
   int packBuffSize = 0, count;
 
   packBuffSize += serializeGetSize(gridNint, DATATYPE_INT, context)
-    + serializeGetSize(1, DATATYPE_FLT64, context);
+    + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if (gridP->rowlon)
     {
       xassert(gridP->nrowlon);
       packBuffSize += serializeGetSize(gridP->nrowlon, DATATYPE_INT, context)
-        + serializeGetSize( 1, DATATYPE_FLT64, context);
+        + serializeGetSize( 1, DATATYPE_UINT32, context);
     }
 
   packBuffSize += serializeGetSize(gridNdouble, DATATYPE_FLT64, context);
@@ -22269,7 +22215,8 @@ gridGetPackSize(void * voidP, void *context)
       else
 	count = gridP->xsize;
       xassert(count);
-      packBuffSize += serializeGetSize(count + 1, DATATYPE_FLT64, context);
+      packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->yvals)
@@ -22279,14 +22226,16 @@ gridGetPackSize(void * voidP, void *context)
       else
 	count = gridP->ysize;
       xassert(count);
-      packBuffSize += serializeGetSize(count + 1, DATATYPE_FLT64, context);
+      packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->area)
     {
       xassert(gridP->size);
       packBuffSize +=
-        serializeGetSize(gridP->size + 1, DATATYPE_FLT64, context);
+        serializeGetSize(gridP->size, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->xbounds)
@@ -22298,7 +22247,8 @@ gridGetPackSize(void * voidP, void *context)
 	count = gridP->xsize;
       xassert(count);
       packBuffSize
-        += serializeGetSize(gridP->nvertex * count + 1, DATATYPE_FLT64, context);
+        += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
+            + serializeGetSize(1, DATATYPE_UINT32, context));
     }
 
   if (gridP->ybounds)
@@ -22310,18 +22260,19 @@ gridGetPackSize(void * voidP, void *context)
 	count = gridP->ysize;
       xassert(count);
       packBuffSize
-        += serializeGetSize(gridP->nvertex * count + 1, DATATYPE_FLT64, context);
+        += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
+            + serializeGetSize(1, DATATYPE_UINT32, context));
     }
 
   packBuffSize +=
     serializeGetSize(gridNstrings * CDI_MAX_NAME , DATATYPE_TXT, context)
-    + serializeGetSize(1, DATATYPE_FLT64, context);
+    + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if (gridP->reference)
     {
       packBuffSize += serializeGetSize(1, DATATYPE_INT, context)
         + serializeGetSize(strlen(gridP->reference) + 1, DATATYPE_TXT, context)
-        + serializeGetSize(1, DATATYPE_FLT64, context);
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->mask)
@@ -22329,14 +22280,14 @@ gridGetPackSize(void * voidP, void *context)
       xassert(gridP->size);
       packBuffSize
         += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
-        + serializeGetSize(1, DATATYPE_FLT64, context);
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->mask_gme)
     {
       xassert(gridP->size);
       packBuffSize += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
-        + serializeGetSize( 1, DATATYPE_FLT64, context);
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   return packBuffSize;
@@ -22348,8 +22299,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
            int * unpackBufferPos, int nspTarget, void *context)
 {
   grid_t * gridP;
+  uint32_t d;
   int memberMask, size;
-  double d;
   char charBuffer[gridNstrings * CDI_MAX_NAME];
 
   gridInit();
@@ -22361,9 +22312,9 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
     serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                     intBuffer, gridNint, DATATYPE_INT, context);
     serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    &d, 1, DATATYPE_FLT64, context);
+                    &d, 1, DATATYPE_UINT32, context);
 
-    xassert(xchecksum(DATATYPE_INT, gridNint, intBuffer) == d);
+    xassert(cdiCheckSum(DATATYPE_INT, gridNint, intBuffer) == d);
     xassert(namespaceAdaptKey(intBuffer[0], nspTarget) == gridP->self);
 
     gridP->type          =   intBuffer[1];
@@ -22401,16 +22352,17 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->rowlon, gridP->nrowlon , DATATYPE_INT, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_INT, gridP->nrowlon, gridP->rowlon) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_INT, gridP->nrowlon, gridP->rowlon) == d);
     }
 
   {
     double doubleBuffer[gridNdouble];
     serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                     doubleBuffer, gridNdouble, DATATYPE_FLT64, context);
-    xassert(doubleBuffer[24]
-            == xchecksum(DATATYPE_FLT, gridNdouble, doubleBuffer));
+    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                    &d, 1, DATATYPE_UINT32, context);
+    xassert(d == cdiCheckSum(DATATYPE_FLT, gridNdouble, doubleBuffer));
 
     gridP->xfirst = doubleBuffer[0];
     gridP->yfirst = doubleBuffer[1];
@@ -22449,8 +22401,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->xvals, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, gridP->xvals) == d );
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xvals) == d );
     }
 
   if (memberMask & gridHasYValsFlag)
@@ -22464,8 +22416,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->yvals, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, gridP->yvals ) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->yvals) == d);
     }
 
   if (memberMask & gridHasAreaFlag)
@@ -22475,8 +22427,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->area, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, gridP->area) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->area) == d);
     }
 
   if (memberMask & gridHasXBoundsFlag)
@@ -22491,8 +22443,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->xbounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, gridP->xbounds ) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds) == d);
     }
 
   if (memberMask & gridHasYBoundsFlag)
@@ -22507,16 +22459,16 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
 			  gridP->ybounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, gridP->ybounds ) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds) == d);
     }
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   charBuffer, gridNstrings * CDI_MAX_NAME, DATATYPE_TXT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
+                  &d, 1, DATATYPE_UINT32, context);
 
-  xassert(d == xchecksum(DATATYPE_TXT, gridNstrings * CDI_MAX_NAME, charBuffer));
+  xassert(d == cdiCheckSum(DATATYPE_TXT, gridNstrings * CDI_MAX_NAME, charBuffer));
 
   memcpy ( gridP->xname    , &charBuffer[CDI_MAX_NAME * 0], CDI_MAX_NAME );
   memcpy ( gridP->yname    , &charBuffer[CDI_MAX_NAME * 1], CDI_MAX_NAME );
@@ -22536,8 +22488,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->reference, referenceSize, DATATYPE_TXT, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_TXT, referenceSize, gridP->reference ) == d );
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_TXT, referenceSize, gridP->reference) == d);
     }
 
   if (memberMask & gridHasMaskFlag)
@@ -22547,8 +22499,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->mask, gridP->size, DATATYPE_UCHAR, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_TXT, gridP->size, gridP->mask ) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_UCHAR, gridP->size, gridP->mask) == d);
     }
 
   if (memberMask & gridHasGMEMaskFlag)
@@ -22558,8 +22510,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->mask_gme, gridP->size, DATATYPE_UCHAR, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_TXT, gridP->size, gridP->mask_gme ) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_UCHAR, gridP->size, gridP->mask_gme) == d);
     }
 }
 
@@ -22570,7 +22522,7 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 {
   grid_t   * gridP = ( grid_t * )   voidP;
   int size;
-  double d;
+  uint32_t d;
   char charBuffer[gridNstrings * CDI_MAX_NAME];
 
   {
@@ -22606,8 +22558,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
     serializePack(intBuffer, gridNint, DATATYPE_INT,
                   packBuffer, packBufferSize, packBufferPos, context);
-    d = xchecksum(DATATYPE_INT, gridNint, intBuffer);
-    serializePack(&d, 1, DATATYPE_FLT64,
+    d = cdiCheckSum(DATATYPE_INT, gridNint, intBuffer);
+    serializePack(&d, 1, DATATYPE_UINT32,
                   packBuffer, packBufferSize, packBufferPos, context);
   }
 
@@ -22616,8 +22568,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
       xassert((size = gridP->nrowlon));
       serializePack(gridP->rowlon, size, DATATYPE_INT,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_INT , size, gridP->rowlon);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_INT , size, gridP->rowlon);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -22648,10 +22600,12 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
     doubleBuffer[21] = gridP->xpole;
     doubleBuffer[22] = gridP->ypole;
     doubleBuffer[23] = gridP->angle;
-    doubleBuffer[24] = xchecksum(DATATYPE_FLT, gridNdouble - 1, doubleBuffer);
 
     serializePack(doubleBuffer, gridNdouble, DATATYPE_FLT64,
                   packBuffer, packBufferSize, packBufferPos, context);
+    d = cdiCheckSum(DATATYPE_FLT, gridNdouble, doubleBuffer);
+    serializePack(&d, 1, DATATYPE_UINT32,
+                  packBuffer, packBufferSize, packBufferPos, context);
   }
 
   if (gridP->xvals)
@@ -22664,8 +22618,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(gridP->xvals, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, size, gridP->xvals);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->xvals);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -22678,8 +22632,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
       xassert(size);
       serializePack(gridP->yvals, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, size, gridP->yvals);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->yvals);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -22689,8 +22643,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(gridP->area, gridP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, gridP->size, gridP->area);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, gridP->size, gridP->area);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -22705,8 +22659,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(gridP->xbounds, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, size, gridP->xbounds);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -22721,8 +22675,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(gridP->ybounds, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, size, gridP->ybounds);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -22737,8 +22691,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
   serializePack( charBuffer, gridNstrings * CDI_MAX_NAME, DATATYPE_TXT,
 		    packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum(DATATYPE_TXT, gridNstrings * CDI_MAX_NAME, charBuffer);
-  serializePack(&d, 1, DATATYPE_FLT64,
+  d = cdiCheckSum(DATATYPE_TXT, gridNstrings * CDI_MAX_NAME, charBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
                 packBuffer, packBufferSize, packBufferPos, context);
 
   if ( gridP->reference )
@@ -22748,8 +22702,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
                     packBuffer, packBufferSize, packBufferPos, context);
       serializePack(gridP->reference, size, DATATYPE_TXT,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_TXT, size, gridP->reference);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_TXT, size, gridP->reference);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -22758,8 +22712,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
       xassert((size = gridP->size));
       serializePack(gridP->mask, size, DATATYPE_UCHAR,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_TXT, size, gridP->mask);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -22769,8 +22723,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(gridP->mask_gme, size, DATATYPE_UCHAR,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_TXT, size, gridP->mask);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask_gme);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 }
@@ -23117,7 +23071,7 @@ void zaxisDefName(int zaxisID, const char *name)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23149,7 +23103,7 @@ void zaxisDefLongname(int zaxisID, const char *longname)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23181,7 +23135,7 @@ void zaxisDefUnits(int zaxisID, const char *units)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23199,7 +23153,7 @@ void zaxisDefUnits(int zaxisID, const char *units)
 
 @Prototype void zaxisInqName(int zaxisID, char *name)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
     @Item  name     Name of the Z-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
@@ -23229,7 +23183,7 @@ void zaxisInqName(int zaxisID, char *name)
 
 @Prototype void zaxisInqLongname(int zaxisID, char *longname)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
     @Item  longname Longname of the Z-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
@@ -23259,7 +23213,7 @@ void zaxisInqLongname(int zaxisID, char *longname)
 
 @Prototype void zaxisInqUnits(int zaxisID, char *units)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
     @Item  units    Units of the Z-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
@@ -23302,7 +23256,7 @@ void zaxisDefPrec(int zaxisID, int prec)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23332,7 +23286,7 @@ void zaxisDefPositive(int zaxisID, int positive)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23362,7 +23316,7 @@ void zaxisDefLtype(int zaxisID, int ltype)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23408,7 +23362,7 @@ void zaxisDefLevels(int zaxisID, const double *levels)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23445,7 +23399,7 @@ void zaxisDefLevel(int zaxisID, int levelID, double level)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23464,7 +23418,7 @@ void zaxisDefNlevRef(int zaxisID, const int nhlev)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23510,7 +23464,7 @@ void zaxisDefNumber(int zaxisID, const int number)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23527,7 +23481,7 @@ void zaxisDefNumber(int zaxisID, const int number)
 
 @Prototype int zaxisInqNumber(int zaxisID)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
 
 @Description
 The function @func{zaxisInqNumber} returns the reference number to a generalized Z-axis.
@@ -23570,7 +23524,7 @@ void zaxisDefUUID(int zaxisID, const char *uuid)
 
     if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23587,18 +23541,18 @@ void zaxisDefUUID(int zaxisID, const char *uuid)
 @Function  zaxisInqUUID
 @Title     Get the uuid to a generalized Z-axis
 
- at Prototype char *zaxisInqUUID(int zaxisID, char *uuid)
+ at Prototype void zaxisInqUUID(int zaxisID, char *uuid)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
 
 @Description
 The function @func{zaxisInqUUID} returns the UUID to a generalized Z-axis.
 
 @Result
- at func{zaxisInqUUID} returns the UUID to a generalized Z-axis.
+ at func{zaxisInqUUID} returns the UUID to a generalized Z-axis to the parameter uuid.
 @EndFunction
 */
-char *zaxisInqUUID(int zaxisID, char *uuid)
+void zaxisInqUUID(int zaxisID, char *uuid)
 {
   zaxis_t *zaxisptr;
 
@@ -23607,8 +23561,6 @@ char *zaxisInqUUID(int zaxisID, char *uuid)
   zaxis_check_ptr(zaxisID, zaxisptr);
 
   memcpy(uuid, zaxisptr->uuid, 16);
-
-  return (uuid);
 }
 
 /*
@@ -23617,7 +23569,7 @@ char *zaxisInqUUID(int zaxisID, char *uuid)
 
 @Prototype double zaxisInqLevel(int zaxisID, int levelID)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
     @Item  levelID  Level index (range: 0 to nlevel-1).
 
 @Description
@@ -23693,7 +23645,7 @@ const double *zaxisInqLevelsPtr(int zaxisID)
 
 @Prototype void zaxisInqLevels(int zaxisID, double *levels)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
     @Item  levels   Pointer to the location into which the levels are read.
                     The caller must allocate space for the returned values.
 
@@ -23815,7 +23767,7 @@ int zaxisInqLevelID(int zaxisID, double level)
 
 @Prototype int zaxisInqType(int zaxisID)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
 
 @Description
 The function @func{zaxisInqType} returns the type of a Z-axis.
@@ -23851,7 +23803,7 @@ int zaxisInqType(int zaxisID)
 
 @Prototype int zaxisInqSize(int zaxisID)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
 
 @Description
 The function @func{zaxisInqSize} returns the size of a Z-axis.
@@ -23929,7 +23881,7 @@ void zaxisDefVct(int zaxisID, int size, const double *vct)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -23992,7 +23944,7 @@ void zaxisDefLbounds(int zaxisID, const double *lbounds)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -24020,7 +23972,7 @@ void zaxisDefUbounds(int zaxisID, const double *ubounds)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -24048,7 +24000,7 @@ void zaxisDefWeights(int zaxisID, const double *weights)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -24423,31 +24375,36 @@ zaxisGetPackSize(void * voidP, void *context)
 {
   zaxis_t * zaxisP = ( zaxis_t * ) voidP;
   int packBufferSize = serializeGetSize(zaxisNint, DATATYPE_INT, context)
-    + serializeGetSize(1, DATATYPE_FLT64, context);
+    + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if (zaxisP->vals || zaxisP->lbounds || zaxisP->ubounds || zaxisP->weights)
     xassert(zaxisP->size);
 
   if ( zaxisP->vals )
-    packBufferSize += serializeGetSize( zaxisP->size + 1, DATATYPE_FLT64, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->lbounds )
-    packBufferSize += serializeGetSize(zaxisP->size + 1, DATATYPE_FLT64, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->ubounds )
-    packBufferSize += serializeGetSize(zaxisP->size + 1, DATATYPE_FLT64, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->weights )
-    packBufferSize += serializeGetSize(zaxisP->size + 1, DATATYPE_FLT64, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->vct )
     {
       xassert ( zaxisP->vctsize );
-      packBufferSize += serializeGetSize(zaxisP->vctsize + 1, DATATYPE_FLT64, context);
+      packBufferSize += serializeGetSize(zaxisP->vctsize, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   packBufferSize += serializeGetSize(zaxisNstrings * CDI_MAX_NAME, DATATYPE_TXT, context)
-    + serializeGetSize(1, DATATYPE_FLT64, context)
+    + serializeGetSize(1, DATATYPE_UINT32, context)
     + serializeGetSize(1, DATATYPE_UCHAR, context);
   return packBufferSize;
 }
@@ -24459,15 +24416,15 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
 {
   zaxis_t * zaxisP;
   int intBuffer[zaxisNint], memberMask;
-  double d;
+  uint32_t d;
   char charBuffer[zaxisNstrings * CDI_MAX_NAME];
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   intBuffer, zaxisNint, DATATYPE_INT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
+                  &d, 1, DATATYPE_UINT32, context);
 
-  xassert ( xchecksum ( DATATYPE_INT, zaxisNint, intBuffer ) == d );
+  xassert(cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer) == d);
 
   zaxisInit ();
 
@@ -24493,8 +24450,8 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       zaxisP->vals, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, zaxisP->vals) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->vals) == d);
     }
 
   if (memberMask & lbounds)
@@ -24506,8 +24463,8 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       zaxisP->lbounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, zaxisP->lbounds) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->lbounds) == d);
     }
 
   if (memberMask & ubounds)
@@ -24519,8 +24476,8 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       zaxisP->ubounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, zaxisP->ubounds) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->ubounds) == d);
     }
 
   if (memberMask & weights)
@@ -24532,8 +24489,8 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       zaxisP->weights, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, zaxisP->weights) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->weights) == d);
     }
 
   if ( memberMask & vct )
@@ -24545,16 +24502,16 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       zaxisP->vct, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, zaxisP->vct) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT64, size, zaxisP->vct) == d);
     }
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   charBuffer, zaxisNstrings * CDI_MAX_NAME, DATATYPE_TXT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
+                  &d, 1, DATATYPE_UINT32, context);
 
-  xassert(d == xchecksum(DATATYPE_TXT, zaxisNstrings * CDI_MAX_NAME, charBuffer));
+  xassert(d == cdiCheckSum(DATATYPE_TXT, zaxisNstrings * CDI_MAX_NAME, charBuffer));
 
   memcpy ( zaxisP->name,     &charBuffer[CDI_MAX_NAME * 0], CDI_MAX_NAME );
   memcpy ( zaxisP->longname, &charBuffer[CDI_MAX_NAME * 1], CDI_MAX_NAME );
@@ -24571,7 +24528,7 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 {
   zaxis_t   * zaxisP = ( zaxis_t * ) voidP;
   int intBuffer[zaxisNint];
-  double d;
+  uint32_t d;
   char charBuffer[zaxisNstrings * CDI_MAX_NAME];
 
   intBuffer[0]  = zaxisP->self;
@@ -24585,8 +24542,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 
   serializePack(intBuffer, zaxisNint, DATATYPE_INT,
                 packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum ( DATATYPE_INT, zaxisNint, intBuffer );
-  serializePack(&d, 1, DATATYPE_FLT64,
+  d = cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
                 packBuffer, packBufferSize, packBufferPos, context);
 
 
@@ -24595,8 +24552,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
       xassert(zaxisP->size);
       serializePack(zaxisP->vals, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, zaxisP->size, zaxisP->vals );
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->vals );
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -24605,8 +24562,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
       xassert(zaxisP->size);
       serializePack(zaxisP->lbounds, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, zaxisP->size, zaxisP->lbounds);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->lbounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -24616,8 +24573,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(zaxisP->ubounds, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, zaxisP->size, zaxisP->ubounds);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->ubounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -24627,8 +24584,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(zaxisP->weights, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, zaxisP->size, zaxisP->weights);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->weights);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -24638,8 +24595,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(zaxisP->vct, zaxisP->vctsize, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, zaxisP->vctsize, zaxisP->vct);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT64, zaxisP->vctsize, zaxisP->vct);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -24650,8 +24607,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 
   serializePack(charBuffer, zaxisNstrings * CDI_MAX_NAME, DATATYPE_TXT,
                 packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum(DATATYPE_TXT, zaxisNstrings * CDI_MAX_NAME, charBuffer);
-  serializePack(&d, 1, DATATYPE_FLT64,
+  d = cdiCheckSum(DATATYPE_TXT, zaxisNstrings * CDI_MAX_NAME, charBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
                 packBuffer, packBufferSize, packBufferPos, context);
 
   serializePack(&zaxisP->positive, 1, DATATYPE_UCHAR,
@@ -25665,11 +25622,7 @@ char *cdiUnitNamePtr(int cdi_unit)
 #if defined (HAVE_CONFIG_H)
 #endif
 
-#include <stdio.h>
 #include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <math.h>
 #include <ctype.h>
 
 
@@ -26368,7 +26321,7 @@ streamGetPackSize(void * voidP, void *context)
   stream_t * streamP = ( stream_t * ) voidP;
   int packBufferSize
     = serializeGetSize(streamNint, DATATYPE_INT, context)
-    + serializeGetSize(2, DATATYPE_FLT64, context)
+    + serializeGetSize(2, DATATYPE_UINT32, context)
     + serializeGetSize((int)strlen(streamP->filename) + 1,
                        DATATYPE_TXT, context)
     + serializeGetSize(1, DATATYPE_FLT64, context);
@@ -26382,7 +26335,6 @@ streamPack(void * streamptr, void * packBuffer, int packBufferSize,
 {
   stream_t * streamP = ( stream_t * ) streamptr;
   int intBuffer[streamNint];
-  double d;
 
   intBuffer[0]  = streamP->self;
   intBuffer[1]  = streamP->filetype;
@@ -26397,13 +26349,13 @@ streamPack(void * streamptr, void * packBuffer, int packBufferSize,
   intBuffer[10] = cdiHaveMissval;
 
   serializePack(intBuffer, streamNint, DATATYPE_INT, packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum(DATATYPE_INT, streamNint, intBuffer);
-  serializePack(&d, 1, DATATYPE_FLT64, packBuffer, packBufferSize, packBufferPos, context);
+  uint32_t d = cdiCheckSum(DATATYPE_INT, streamNint, intBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
 
   serializePack(&cdiDefaultMissval, 1, DATATYPE_FLT64, packBuffer, packBufferSize, packBufferPos, context);
   serializePack(streamP->filename, intBuffer[2], DATATYPE_TXT, packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum(DATATYPE_TXT, intBuffer[2], &streamP->filename);
-  serializePack(&d, 1, DATATYPE_FLT64, packBuffer, packBufferSize, packBufferPos, context);
+  d = cdiCheckSum(DATATYPE_TXT, intBuffer[2], streamP->filename);
+  serializePack(&d, 1, DATATYPE_UINT32, packBuffer, packBufferSize, packBufferPos, context);
 }
 
 struct streamAssoc
@@ -26411,22 +26363,22 @@ streamUnpack(char * unpackBuffer, int unpackBufferSize,
              int * unpackBufferPos, int nspTarget, void *context)
 {
   int intBuffer[streamNint], streamID;
-  double d;
+  uint32_t d;
   char filename[CDI_MAX_NAME];
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   intBuffer, streamNint, DATATYPE_INT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
-  xassert(xchecksum(DATATYPE_INT, streamNint, intBuffer ) == d);
+                  &d, 1, DATATYPE_UINT32, context);
+  xassert(cdiCheckSum(DATATYPE_INT, streamNint, intBuffer) == d);
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   &cdiDefaultMissval, 1, DATATYPE_FLT64, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   &filename, intBuffer[2], DATATYPE_TXT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
-  xassert(d == xchecksum(DATATYPE_TXT, intBuffer[2], filename));
+                  &d, 1, DATATYPE_UINT32, context);
+  xassert(d == cdiCheckSum(DATATYPE_TXT, intBuffer[2], filename));
   streamID = streamOpenWrite ( filename, intBuffer[1] );
   xassert ( streamID >= 0 &&
             namespaceAdaptKey ( intBuffer[0], nspTarget ) == streamID );
@@ -26882,7 +26834,7 @@ void streamDefByteorder(int streamID, int byteorder)
 
   if ( reshGetStatus ( streamID, &streamOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -27178,10 +27130,11 @@ int streamOpen(const char *filename, const char *filemode, int filetype)
 
   {
     int (*streamOpenDelegate)(const char *filename, const char *filemode,
-                              int filetype, stream_t *streamptr)
-      = (int (*)(const char *, const char *, int, stream_t *))
+                              int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
+      = (int (*)(const char *, const char *, int, stream_t *, int))
       namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
-    fileID = streamOpenDelegate(filename, filemode, filetype, streamptr);
+
+    fileID = streamOpenDelegate(filename, filemode, filetype, streamptr, 1);
   }
 
   if (fileID < 0)
@@ -27226,51 +27179,45 @@ static int streamOpenA(const char *filename, const char *filemode, int filetype)
   int fileID = CDI_UNDEFID;
   int streamID = CDI_ESYSTEM;
   int status;
-  Record *record = NULL;
   stream_t *streamptr = stream_new_entry();
+  vlist_t *vlistptr;
 
   if ( CDI_Debug )
-    Message("Open %s mode %c file %s", strfiletype(filetype), (int) *filemode, filename);
+    Message("Open %s file (mode=%c); filename: %s", strfiletype(filetype), (int) *filemode, filename);
+  if ( CDI_Debug ) printf("streamOpenA: %s\n", filename); // seg fault without this line on thunder/squall with "cdo cat x y"
 
   if ( ! filename || ! filemode || filetype < 0 ) return (CDI_EINVAL);
 
   {
     int (*streamOpenDelegate)(const char *filename, const char *filemode,
-                              int filetype, stream_t *streamptr)
-      = (int (*)(const char *, const char *, int, stream_t *))
+                              int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
+      = (int (*)(const char *, const char *, int, stream_t *, int))
       namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
-    fileID = streamOpenDelegate(filename, "r", filetype, streamptr);
+
+    fileID = streamOpenDelegate(filename, "r", filetype, streamptr, 1);
   }
 
-  if (fileID == CDI_UNDEFID || fileID == CDI_ELIBNAVAIL
-      || fileID == CDI_ESYSTEM )
-    {
-      streamID = fileID;
-      return (streamID);
-    }
-  else
-    {
-      vlist_t *vlistptr;
-      streamID = streamptr->self;
+  if ( fileID == CDI_UNDEFID || fileID == CDI_ELIBNAVAIL || fileID == CDI_ESYSTEM ) return (fileID);
 
-      streamptr->record   = record;
-      streamptr->filetype = filetype;
-      streamptr->filemode = tolower(*filemode);
-      streamptr->filename = strdupx(filename);
-      streamptr->fileID   = fileID;
+  streamID = streamptr->self;
 
-      streamptr->vlistID = vlistCreate();
-      /* cdiReadByteorder(streamID); */
-      status = cdiInqContents(streamptr);
-      if ( status < 0 ) return (status);
-      vlistptr = vlist_to_pointer(streamptr->vlistID);
-      vlistptr->ntsteps = cdiInqTimeSize(streamID);
-    }
+  streamptr->filetype = filetype;
+  streamptr->filemode = tolower(*filemode);
+  streamptr->filename = strdupx(filename);
+  streamptr->fileID   = fileID;
+
+  streamptr->vlistID = vlistCreate();
+  /* cdiReadByteorder(streamID); */
+  status = cdiInqContents(streamptr);
+  if ( status < 0 ) return (status);
+  vlistptr = vlist_to_pointer(streamptr->vlistID);
+  vlistptr->ntsteps = cdiInqTimeSize(streamID);
 
   {
     void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
       = (void (*)(stream_t *, int))
       namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
+
     streamCloseDelegate(streamptr, 0);
   }
 
@@ -27336,7 +27283,7 @@ static int streamOpenA(const char *filename, const char *filemode, int filetype)
   if ( fileID == CDI_UNDEFID )
     streamID = CDI_UNDEFID;
   else
-    streamptr->fileID   = fileID;
+    streamptr->fileID = fileID;
 
   return (streamID);
 }
@@ -27554,7 +27501,7 @@ cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDeleted)
 #endif
       default:
         {
-          Error("%s support not compiled in!", strfiletype(filetype));
+          Error("%s support not compiled in (fileID = %d)!", strfiletype(filetype), fileID);
           break;
         }
       }
@@ -27593,15 +27540,15 @@ void streamClose(int streamID)
     = (void (*)(stream_t *, int))
     namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
 
-  streamCloseDelegate(streamptr, 1);
+  if ( streamptr->filetype != -1 ) streamCloseDelegate(streamptr, 1);
 
   if ( streamptr->record )
-      {
-	  if ( streamptr->record->buffer )
-              free(streamptr->record->buffer);
+    {
+      if ( streamptr->record->buffer )
+        free(streamptr->record->buffer);
 
-	  free(streamptr->record);
-      }
+      free(streamptr->record);
+    }
 
   streamptr->filetype = 0;
   if ( streamptr->filename ) free(streamptr->filename);
@@ -27809,6 +27756,13 @@ int streamDefTimestep(int streamID, int tsID)
   return myStreamDefTimestep_(streamptr, tsID);
 }
 
+int streamInqCurTimestepID(int streamID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
+  return streamptr->curTsID;
+}
+
+
 /*
 @Function  streamInqTimestep
 @Title     Get time step
@@ -28046,7 +28000,8 @@ cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data,
 
   stream_check_ptr(__func__, streamptr);
 
-  // streamDefineTaxis(streamID);
+  // check taxis
+  if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
 
   filetype = streamptr->filetype;
 
@@ -28229,6 +28184,9 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
 
   stream_check_ptr(__func__, streamptr);
 
+  // check taxis
+  if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
+
   filetype = streamptr->filetype;
 
   switch (filetype)
@@ -28654,7 +28612,7 @@ void streamDefCompType(int streamID, int comptype)
 
   if ( reshGetStatus ( streamID, &streamOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -28672,7 +28630,7 @@ void streamDefCompLevel(int streamID, int complevel)
 
   if ( reshGetStatus ( streamID, &streamOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -30184,7 +30142,7 @@ int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri
 
       *nmiss = 0;
       for ( i = 0; i < gridsize; i++ )
-        if ( (abs(data[i]-undef_pds) < undef_eps) || IS_EQUAL(data[i],FSEC3_MissVal) ) {
+        if ( (fabs(data[i]-undef_pds) < undef_eps) || IS_EQUAL(data[i],FSEC3_MissVal) ) {
           data[i] = missval;
           (*nmiss)++;
         }
@@ -30347,13 +30305,15 @@ int cgribexDefDateTime(int *isec1, int timeunit, int date, int time)
 static
 void cgribexDefTime(int *isec1, int vdate, int vtime, int tsteptype, int numavg, int taxisID)
 {
-  int timetype = -1;
+  int timetype = TAXIS_ABSOLUTE;
   int timerange = 0;
-  int timeunit;
-
-  if ( taxisID != -1 ) timetype = taxisInqType(taxisID);
+  int timeunit = TUNIT_HOUR;
 
-  timeunit = taxisInqTunit(taxisID);
+  if ( taxisID != -1 ) 
+    {
+      timetype = taxisInqType(taxisID);
+      timeunit = taxisInqTunit(taxisID);
+    }
 
   if ( timetype == TAXIS_RELATIVE )
     {
@@ -30418,8 +30378,8 @@ static
 void cgribexDefGrid(int *isec1, int *isec2, int *isec4, int gridID)
 {
   int gridtype;
-  int lcurvi = FALSE;
-  static short lwarn = TRUE;
+  bool lcurvi = false;
+  static bool lwarning = true;
 
   memset(isec2, 0, 16*sizeof(int));
 
@@ -30440,7 +30400,7 @@ void cgribexDefGrid(int *isec1, int *isec2, int *isec4, int gridID)
       if ( (ysize ==  32 || ysize ==  48 || ysize ==  64 ||
 	    ysize ==  96 || ysize == 160 || ysize == 192 ||
 	    ysize == 240 || ysize == 320 || ysize == 384 ||
-	    ysize == 480 || ysize == 768 ) && 
+	    ysize == 480 || ysize == 768 ) &&
 	   (xsize == 2*ysize || xsize == 1) )
 	{
 	  gridtype = GRID_GAUSSIAN;
@@ -30459,13 +30419,13 @@ void cgribexDefGrid(int *isec1, int *isec2, int *isec4, int gridID)
     }
   else if ( gridtype == GRID_CURVILINEAR )
     {
-      if ( lwarn && gridInqSize(gridID) > 1 )
+      if ( lwarning && gridInqSize(gridID) > 1 )
 	{
-	  lwarn = FALSE;
+	  lwarning = false;
 	  Warning("Curvilinear grids are unsupported in GRIB1! Created wrong GDS!");
 	}
       gridtype = GRID_LONLAT;
-      lcurvi = TRUE;
+      lcurvi = true;
     }
 
   ISEC2_Reduced  = FALSE;
@@ -30669,8 +30629,8 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
 {
   double level;
   int ilevel, zaxistype, ltype;
-  static int warning = 1;
-  static int vct_warning = 1;
+  static bool lwarning = true;
+  static bool lwarning_vct = true;
 
   zaxistype = zaxisInqType(zaxisID);
   ltype = zaxisInqLtype(zaxisID);
@@ -30764,18 +30724,18 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
 	  }
 
 	vctsize = zaxisInqVctSize(zaxisID);
-	if ( vctsize == 0 && warning )
+	if ( vctsize == 0 && lwarning )
 	  {
 	    Warning("VCT missing. ( param = %d, zaxisID = %d )", ISEC1_Parameter, zaxisID);
-	    warning = 0;
+	    lwarning = false;
 	  }
 	if ( vctsize > 255 )
 	  {
 	    ISEC2_NumVCP = 0;
-	    if ( vct_warning )
+	    if ( lwarning_vct )
 	      {
 		Warning("VCT size of %d is too large (maximum is 255). Set to 0!", vctsize);
-		vct_warning = 0;
+		lwarning_vct = false;
 	      }
 	  }
 	else
@@ -32005,7 +31965,7 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
       if ( linitial_field )
 	{
 	  if ( grib_get_double(gh, cdiAdditionalGRIBKeys[i], &dval) == 0 )
-            varDefOptGribInt(varID, dval, cdiAdditionalGRIBKeys[i]);
+            varDefOptGribDbl(varID, dval, cdiAdditionalGRIBKeys[i]);
 	}
       /* note: if the key is not defined, we do not throw an error! */
     }
@@ -33649,7 +33609,8 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int ljpeg, i
 	    GRIB_CHECK(grib_set_long(gh, "numberOfGridUsed", number), 0);
 	    GRIB_CHECK(grib_set_long(gh, "numberOfGridInReference", position), 0);
             len = 16;
-	    if (grib_set_bytes(gh, "uuidOfHGrid", (unsigned char *) gridInqUUID(gridID, uuid), &len) != 0)
+            gridInqUUID(gridID, uuid);
+	    if (grib_set_bytes(gh, "uuidOfHGrid", (unsigned char *) uuid, &len) != 0)
 	      Warning("Can't write UUID!");
 	  }
 
@@ -33944,7 +33905,8 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
                 GRIB_CHECK(grib_set_long(gh, "nlev", zaxisInqNlevRef(zaxisID)), 0);
                 GRIB_CHECK(grib_set_long(gh, "numberOfVGridUsed", number), 0);
                 len = 16;
-                if (grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) zaxisInqUUID(zaxisID, uuid), &len) != 0)
+                zaxisInqUUID(zaxisID, uuid);
+                if (grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) uuid, &len) != 0)
                   Warning("Can't write UUID!");
                 GRIB_CHECK(grib_set_long(gh, "topLevel", (long) dlevel1), 0);
                 GRIB_CHECK(grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
@@ -33962,7 +33924,8 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
                 GRIB_CHECK(grib_set_long(gh, "nlev", zaxisInqNlevRef(zaxisID)), 0);
                 GRIB_CHECK(grib_set_long(gh, "numberOfVGridUsed", number), 0);
                 len = 16;
-                if (grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) zaxisInqUUID(zaxisID, uuid), &len) != 0)
+                zaxisInqUUID(zaxisID, uuid);
+                if (grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) uuid, &len) != 0)
                   Warning("Can't write UUID!");
                 GRIB_CHECK(grib_set_double(gh, "level", level), 0);
               }
@@ -34092,13 +34055,25 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
     int i;
     for (i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
       {
-	GRIB_CHECK(grib_set_double(gh, vlistptr->vars[varID].opt_grib_dbl_keyword[i],
-				   vlistptr->vars[varID].opt_grib_dbl_val[i]), 0);
+	int ret = grib_set_double(gh, vlistptr->vars[varID].opt_grib_dbl_keyword[i],
+                                  vlistptr->vars[varID].opt_grib_dbl_val[i]);
+	if (ret != 0) {
+	    fprintf(stderr, "key \"%s\"  :   value = %g\n",
+                    vlistptr->vars[varID].opt_grib_dbl_keyword[i],
+		    vlistptr->vars[varID].opt_grib_dbl_val[i]);
+	}
+	GRIB_CHECK(ret, 0);
       }
     for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
       {
-	GRIB_CHECK(grib_set_long(gh, vlistptr->vars[varID].opt_grib_int_keyword[i],
-				 vlistptr->vars[varID].opt_grib_int_val[i]), 0);
+	int ret = grib_set_long(gh, vlistptr->vars[varID].opt_grib_int_keyword[i],
+	                        vlistptr->vars[varID].opt_grib_int_val[i]);
+	if (ret != 0) {
+	    fprintf(stderr, "key \"%s\"  :   value = %d\n",
+		    vlistptr->vars[varID].opt_grib_int_keyword[i],
+		    vlistptr->vars[varID].opt_grib_int_val[i]);
+	}
+	GRIB_CHECK(ret, 0);
       }
   }
 
@@ -34863,7 +34838,7 @@ int grb_write_record(stream_t * streamptr, int memtype, const void *data, int nm
 }
 
 
-void streamInqGinfo(int streamID, int *intnum, float *fltnum)
+void streamInqGinfo(int streamID, int *intnum, float *fltnum, off_t *bignum)
 {
   int recID, vrecID, tsID;
   int filetype;
@@ -34893,7 +34868,7 @@ void streamInqGinfo(int streamID, int *intnum, float *fltnum)
       if ( zip > 0 )
 	Error("Compressed GRIB records unsupported!");
       else
-	gribGinfo(recpos, gribbuffersize, (unsigned char *) gribbuffer, intnum, fltnum);
+	gribGinfo(recpos, gribbuffersize, (unsigned char *) gribbuffer, intnum, fltnum, bignum);
     }
 }
 /*
@@ -40348,6 +40323,26 @@ void cdfDefGridUUID(stream_t *streamptr, int gridID)
 }
 
 static
+void cdfDefZaxisUUID(stream_t *streamptr, int zaxisID)
+{
+  char uuidOfVGrid[17];
+  zaxisInqUUID(zaxisID, uuidOfVGrid);
+
+  if ( uuidOfVGrid[0] != 0 )
+    {
+      char uuidOfVGridStr[37];
+      uuid2str(uuidOfVGrid, uuidOfVGridStr);
+      if ( uuidOfVGridStr[0] != 0 && strlen(uuidOfVGridStr) == 36 )
+        {
+          int fileID  = streamptr->fileID;
+          if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+          cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfVGrid", 36, uuidOfVGridStr);
+          if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+        }
+    }
+}
+
+static
 void cdfDefUnstructured(stream_t *streamptr, int gridID)
 {
   char xunits[CDI_MAX_NAME];
@@ -40717,6 +40712,9 @@ void cdfDefZaxis(stream_t *streamptr, int zaxisID)
 
       if ( ilevel ) sprintf(&axisname[strlen(axisname)], "_%1d", ilevel+1);
 
+      if ( type == ZAXIS_REFERENCE )
+	cdfDefZaxisUUID(streamptr, zaxisID);
+
       if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
         {
           if ( type == ZAXIS_HYBRID )
@@ -42109,6 +42107,55 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
 }
 #endif
 
+static
+int set_validrange(long gridsize, double *data, double missval, double validmin, double validmax)
+{
+  long i;
+  int nmiss = 0;
+  /*
+  for ( i = 0; i < gridsize; i++, data++ )
+    {
+      if ( IS_NOT_EQUAL(validmin, VALIDMISS) && (*data) < validmin ) *data = missval;
+      if ( IS_NOT_EQUAL(validmax, VALIDMISS) && (*data) > validmax ) *data = missval;
+      if ( DBL_IS_EQUAL((*data), missval) ) nmiss++;
+    }
+  */
+  // 21/01/2014 Florian Prill: SX-9 vectorization
+
+  if ( IS_NOT_EQUAL(validmin, VALIDMISS) && !IS_NOT_EQUAL(validmax, VALIDMISS) )
+    {
+      for ( i = 0; i < gridsize; i++, data++ )
+        {
+          if ( (*data) < validmin )  { (*data) = missval; nmiss++; }
+          else if ( DBL_IS_EQUAL((*data), missval) )  nmiss++;
+        } // i
+    }
+  else if ( IS_NOT_EQUAL(validmax, VALIDMISS) && !IS_NOT_EQUAL(validmin, VALIDMISS))
+    {
+      for ( i = 0; i < gridsize; i++, data++ )
+        {
+          if ( (*data) > validmax )  { (*data) = missval; nmiss++; }
+          else if ( DBL_IS_EQUAL((*data), missval) )  nmiss++;
+        } // i
+    }
+  else if ( IS_NOT_EQUAL(validmin, VALIDMISS) && IS_NOT_EQUAL(validmax, VALIDMISS))
+    {
+      for ( i = 0; i < gridsize; i++, data++ )
+        {
+          if      ( (*data) < validmin )  { (*data) = missval; nmiss++; }
+          else if ( (*data) > validmax )  { (*data) = missval; nmiss++; }
+          else if ( DBL_IS_EQUAL((*data), missval) )  nmiss++;
+        } // i
+    }
+  else
+    {
+      for ( i = 0; i < gridsize; i++, data++ )
+        if ( DBL_IS_EQUAL((*data), missval) ) nmiss++;
+    }
+
+  return (nmiss);
+}
+
 
 int cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss)
 {
@@ -42268,15 +42315,15 @@ int cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data,
       lvalidrange = vlistInqVarValidrange(vlistID, varID, validrange);
       // printf("readvarslice: validrange %d %g %g\n", lvalidrange, validrange[0], validrange[1]);
       if ( lvalidrange )
-        for ( i = 0; i < gridsize; i++ )
-          {
-            if ( IS_NOT_EQUAL(validrange[0], VALIDMISS) && data[i] < validrange[0] ) data[i] = missval;
-            if ( IS_NOT_EQUAL(validrange[1], VALIDMISS) && data[i] > validrange[1] ) data[i] = missval;
-          }
-
-      // printf("XXX %31.0f %31.0f %31.0f %31.0f\n", missval, (float)data[0]);
-      for ( i = 0; i < gridsize; i++ )
-        if ( DBL_IS_EQUAL(data[i], missval) ) *nmiss += 1;
+        {
+          *nmiss = set_validrange(gridsize, data, missval, validrange[0], validrange[1]);
+        }
+      else
+        {
+          double *data_ptr = data; 
+          for ( i = 0; i < gridsize; i++, data_ptr++ )
+            if ( DBL_IS_EQUAL((*data_ptr), missval) ) (*nmiss)++;
+        }
     }
 
   addoffset    = vlistInqVarAddoffset(vlistID, varID);
@@ -43988,8 +44035,7 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 		{
 		  if ( ncvars[xvarid].ndims != ncvars[yvarid].ndims )
 		    {
-		      Warning("Inconsistent grid structure for variable %s!",
-			      ncvars[ncvarid].name);
+		      Warning("Inconsistent grid structure for variable %s!", ncvars[ncvarid].name);
 		      ncvars[ncvarid].xvarid = UNDEFID;
 		      ncvars[ncvarid].yvarid = UNDEFID;
 		      xvarid = UNDEFID;
@@ -44165,7 +44211,7 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 
 	      if      ( (int) ysize == 0 ) size = xsize;
 	      else if ( (int) xsize == 0 ) size = ysize;
-	      else if ( ncvars[ncvarid].gridtype == GRID_UNSTRUCTURED ) size = xsize; 
+	      else if ( ncvars[ncvarid].gridtype == GRID_UNSTRUCTURED ) size = xsize;
 	      else                         size = xsize*ysize;
 	    }
 
@@ -44379,6 +44425,46 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 		}
 	    }
 
+          if ( grid.type == GRID_UNSTRUCTURED )
+            {
+              int zdimid = UNDEFID;
+              int xdimidx = -1, ydimidx = -1;
+
+              for ( i = 0; i < ndims; i++ )
+                {
+                  if      ( ncvars[ncvarid].dimtype[i] == X_AXIS ) xdimidx = i;
+                  else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) ydimidx = i;
+                  else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) zdimid = ncvars[ncvarid].dimids[i];
+                }
+
+              if ( xdimid != UNDEFID && ydimid != UNDEFID && zdimid == UNDEFID )
+                {
+                  if ( grid.xsize > grid.ysize && grid.ysize < 1000 )
+                    {
+                      ncvars[ncvarid].dimtype[ydimidx] = Z_AXIS;
+                      ydimid = UNDEFID;
+                      grid.size  = grid.xsize;
+                      grid.ysize = 0;
+                    }
+                  else if ( grid.ysize > grid.xsize && grid.xsize < 1000 )
+                    {
+                      ncvars[ncvarid].dimtype[xdimidx] = Z_AXIS;
+                      xdimid = ydimid;
+                      ydimid = UNDEFID;
+                      grid.size  = grid.ysize;
+                      grid.xsize = grid.ysize;
+                      grid.ysize = 0;
+                    }
+                }
+
+              if ( grid.size != grid.xsize )
+                {
+                  Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+                  ncvars[ncvarid].isvar = -1;
+                  continue;
+                }
+            }
+
 #if defined (PROJECTION_TEST)
 	  if ( proj.type == GRID_PROJECTION )
 	    {
@@ -44418,10 +44504,16 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 
           if ( grid.type == GRID_UNSTRUCTURED )
             {
-              if ( ncvars[ncvarid].position > 0 ) gridDefPosition(ncvars[ncvarid].gridID, ncvars[ncvarid].position);
+              if ( CDI_Debug)
+                {
+                  if ( grid.number != UNDEFID ) printf("number : %d\n", grid.number);
+                  if ( ncvars[ncvarid].position > 0 ) printf("position : %d\n", ncvars[ncvarid].position);
+                  if ( gridfile[0] != 0 ) printf("gridfile: %s\n", gridfile);
+                  if ( uuidOfHGrid[0] != 0 ) printf("uuidOfHGrid: defined\n");
+                }
 
+              if ( ncvars[ncvarid].position > 0 ) gridDefPosition(ncvars[ncvarid].gridID, ncvars[ncvarid].position);
               if ( gridfile[0] != 0 ) gridDefReference(ncvars[ncvarid].gridID, gridfile);
-
               if ( uuidOfHGrid[0] != 0 ) gridDefUUID(ncvars[ncvarid].gridID, uuidOfHGrid);
             }
 
@@ -44453,26 +44545,43 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 	  streamptr->xdimID[gridindex] = xdimid;
 	  streamptr->ydimID[gridindex] = ydimid;
 
-	  grid_free(&grid);
-	  grid_free(&proj);
-
 	  if ( CDI_Debug )
 	    Message("gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid, ncvars[ncvarid].name);
 
 	  for ( ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
 	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].gridID == UNDEFID )
 	      {
-		int xdimid2 = -1, ydimid2 = -1;
-		ndims = ncvars[ncvarid2].ndims;
-		for ( i = 0; i < ndims; i++ )
+		int xdimid2 = UNDEFID, ydimid2 = UNDEFID, zdimid2 = UNDEFID;
+                int xdimidx = -1, ydimidx = -1;
+		int ndims2 = ncvars[ncvarid2].ndims;
+
+		for ( i = 0; i < ndims2; i++ )
 		  {
 		    if ( ncvars[ncvarid2].dimtype[i] == X_AXIS )
-		      xdimid2 = ncvars[ncvarid2].dimids[i];
+		      { xdimid2 = ncvars[ncvarid2].dimids[i]; xdimidx = i; }
 		    else if ( ncvars[ncvarid2].dimtype[i] == Y_AXIS )
-		      ydimid2 = ncvars[ncvarid2].dimids[i];
+		      { ydimid2 = ncvars[ncvarid2].dimids[i]; ydimidx = i; }
+		    else if ( ncvars[ncvarid2].dimtype[i] == Z_AXIS )
+		      { zdimid2 = ncvars[ncvarid2].dimids[i]; }
 		  }
 
-		if ( xdimid == xdimid2 &&
+                if ( ncvars[ncvarid2].gridtype == UNDEFID && grid.type == GRID_UNSTRUCTURED )
+                  {
+                    if ( xdimid == xdimid2 && ydimid2 != UNDEFID && zdimid2 == UNDEFID )
+                      {
+                        ncvars[ncvarid2].dimtype[ydimidx] = Z_AXIS;
+                        ydimid2 = UNDEFID;
+                      }
+
+                    if ( xdimid == ydimid2 && xdimid2 != UNDEFID && zdimid2 == UNDEFID )
+                      {
+                        ncvars[ncvarid2].dimtype[xdimidx] = Z_AXIS;
+                        xdimid2 = ydimid2;
+                        ydimid2 = UNDEFID;
+                      }
+                  }
+
+                if ( xdimid == xdimid2 &&
 		    (ydimid == ydimid2 || (xdimid == ydimid && ydimid2 == UNDEFID)) )
 		  {
 		    int same_grid = TRUE;
@@ -44491,13 +44600,15 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 		    if ( same_grid )
 		      {
 			if ( CDI_Debug )
-			  Message("Same gridID %d %d %s",
-				  ncvars[ncvarid].gridID, ncvarid2, ncvars[ncvarid2].name);
+			  Message("Same gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid2, ncvars[ncvarid2].name);
 			ncvars[ncvarid2].gridID = ncvars[ncvarid].gridID;
 			ncvars[ncvarid2].chunktype = ncvars[ncvarid].chunktype;
 		      }
 		  }
 	      }
+
+	  grid_free(&grid);
+	  grid_free(&proj);
 	}
     }
 }
@@ -48265,9 +48376,9 @@ size_t fileWrite(int fileID, const void *restrict ptr, size_t size)
  * End:
  */
 
-/* Automatically generated by m214003 at 2013-10-09, do not edit */
+/* Automatically generated by m214003 at 2014-01-08, do not edit */
 
-/* CGRIBEXLIB_VERSION="1.6.2" */
+/* CGRIBEXLIB_VERSION="1.6.3" */
 
 #ifdef _ARCH_PWR6
 #pragma options nostrict
@@ -57802,14 +57913,14 @@ int grib2Sections(unsigned char *gribbuffer, long bufsize, unsigned char **idsp,
 }
 
 
-int gribGinfo(long recpos, long recsize, unsigned char *gribbuffer,
-	      int *intnum, float *fltnum)
+int gribGinfo(off_t recpos, long recsize, unsigned char *gribbuffer,
+	      int *intnum, float *fltnum, off_t *bignum)
 {
   unsigned char *pds, *gds, *bms, *bds;
   unsigned char *bufpointer, *is, *section;
   int gribversion, grib1offset;
   long gribsize = 0;
-  int dpos, bpos = 0;
+  off_t dpos, bpos = 0;
   int bdslen;
   float bsf;
 
@@ -57886,10 +57997,10 @@ int gribGinfo(long recpos, long recsize, unsigned char *gribbuffer,
   if ( bsf > 32767 ) bsf = 32768-bsf;
   bsf = pow(2.0,(double)bsf);
 
-  intnum[0] = dpos;
-  if ( bms ) intnum[1] = bpos;
-  else       intnum[1] = -999;
-  intnum[2] = BDS_NumBits;
+  bignum[0] = dpos;
+  if ( bms ) bignum[1] = bpos;
+  else       bignum[1] = -999;
+  intnum[0] = BDS_NumBits;
 
   /*  fltnum[0] = 1.0; */
   fltnum[0] = pow(10.0, (double)PDS_DecimalScale);
@@ -59093,7 +59204,7 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 
   return (gribLen);
 }
-static const char grb_libvers[] = "1.6.2" " of ""Oct  9 2013"" ""11:03:55";
+static const char grb_libvers[] = "1.6.3" " of ""Jan  8 2014"" ""19:55:18";
 const char *
 cgribexLibraryVersion(void)
 {
@@ -59778,10 +59889,18 @@ void cdfClose(int fileID)
  * require-trailing-newline: t
  * End:
  */
+#if defined (HAVE_CONFIG_H)
+#endif
+
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
+#endif
+
 #include <limits.h>
 #include <stdlib.h>
 #include <stdio.h>
 
+
 static int nNamespaces = 1;
 static int activeNamespace = 0;
 
@@ -59796,8 +59915,31 @@ static int activeNamespace = 0;
 #define CDI_NETCDF_SWITCHES
 #endif
 
+#if defined (SX)
+static const union namespaceSwitchValue defaultSwitches[NUM_NAMESPACE_SWITCH] = {
+    { .func = (void (*)()) cdiAbortC_serial },
+    { .func = (void (*)()) cdiWarning },
+    { .func = (void (*)()) serializeGetSizeInCore },
+    { .func = (void (*)()) serializePackInCore },
+    { .func = (void (*)()) serializeUnpackInCore },
+    { .func = (void (*)()) fileOpen_serial },
+    { .func = (void (*)()) fileWrite },
+    { .func = (void (*)()) fileClose_serial },
+    { .func = (void (*)()) cdiStreamOpenDefaultDelegate },
+    { .func = (void (*)()) cdiStreamDefVlist_ },
+    { .func = (void (*)()) cdiStreamWriteVar_ },
+    { .func = (void (*)()) cdiStreamwriteVarChunk_ },
+    { .func = (void (*)()) 0 },
+    { .func = (void (*)()) 0 },
+    { .func = (void (*)()) cdiStreamCloseDefaultDelegate },
+    { .func = (void (*)()) cdiStreamDefTimestep_ },
+    { .func = (void (*)()) cdiStreamSync_ },
+    CDI_NETCDF_SWITCHES
+};
+#else
 #define defaultSwitches {                                   \
     { .func = (void (*)()) cdiAbortC_serial },              \
+    { .func = (void (*)()) cdiWarning },                    \
     { .func = (void (*)()) serializeGetSizeInCore },        \
     { .func = (void (*)()) serializePackInCore },           \
     { .func = (void (*)()) serializeUnpackInCore },         \
@@ -59808,12 +59950,14 @@ static int activeNamespace = 0;
     { .func = (void (*)()) cdiStreamDefVlist_ },            \
     { .func = (void (*)()) cdiStreamWriteVar_ },            \
     { .func = (void (*)()) cdiStreamwriteVarChunk_ },       \
-    { .data = NULL },                                       \
+    { .func = (void (*)()) 0 },                             \
+    { .func = (void (*)()) 0 },                             \
     { .func = (void (*)()) cdiStreamCloseDefaultDelegate }, \
     { .func = (void (*)()) cdiStreamDefTimestep_ }, \
     { .func = (void (*)()) cdiStreamSync_ },                \
     CDI_NETCDF_SWITCHES                        \
     }
+#endif
 
 struct namespace
 {
@@ -59821,7 +59965,30 @@ struct namespace
   union namespaceSwitchValue switches[NUM_NAMESPACE_SWITCH];
 } initialNamespace = {
   .resStage = STAGE_DEFINITION,
+#if defined (SX)
+  .switches = {
+    { .func = (void (*)()) cdiAbortC_serial },
+    { .func = (void (*)()) cdiWarning },
+    { .func = (void (*)()) serializeGetSizeInCore },
+    { .func = (void (*)()) serializePackInCore },
+    { .func = (void (*)()) serializeUnpackInCore },
+    { .func = (void (*)()) fileOpen_serial },
+    { .func = (void (*)()) fileWrite },
+    { .func = (void (*)()) fileClose_serial },
+    { .func = (void (*)()) cdiStreamOpenDefaultDelegate },
+    { .func = (void (*)()) cdiStreamDefVlist_ },
+    { .func = (void (*)()) cdiStreamWriteVar_ },
+    { .func = (void (*)()) cdiStreamwriteVarChunk_ },
+    { .func = (void (*)()) 0 },
+    { .func = (void (*)()) 0 },
+    { .func = (void (*)()) cdiStreamCloseDefaultDelegate },
+    { .func = (void (*)()) cdiStreamDefTimestep_ },
+    { .func = (void (*)()) cdiStreamSync_ },
+    CDI_NETCDF_SWITCHES
+}
+#else
   .switches = defaultSwitches
+#endif
 };
 
 struct namespace *namespaces = &initialNamespace;
@@ -59831,13 +59998,28 @@ static int namespacesSize = 1;
 #if  defined  (HAVE_LIBPTHREAD)
 #  include <pthread.h>
 
-static pthread_mutex_t namespaceMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_once_t  namespaceOnce = PTHREAD_ONCE_INIT;
+static pthread_mutex_t namespaceMutex;
+
+static void
+namespaceInitialize(void)
+{
+  pthread_mutexattr_t ma;
+  pthread_mutexattr_init(&ma);
+  pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
+  pthread_mutex_init(&namespaceMutex, &ma);
+  pthread_mutexattr_destroy(&ma);
+}
 
 #  define NAMESPACE_LOCK()         pthread_mutex_lock(&namespaceMutex)
 #  define NAMESPACE_UNLOCK()       pthread_mutex_unlock(&namespaceMutex)
+#  define NAMESPACE_INIT()         pthread_once(&namespaceOnce, \
+                                                namespaceInitialize)
+
 
 #else
 
+#  define NAMESPACE_INIT() do { } while (0)
 #  define NAMESPACE_LOCK()
 #  define NAMESPACE_UNLOCK()
 
@@ -59858,25 +60040,6 @@ enum {
 };
 
 
-#if 0
-void namespaceShowbits ( int n, char *name )
-{
-  int i;
-  unsigned mask;
-  char bitvalues[intbits + 1];
-
-  mask = 1;
-  for ( i = 0; i < intbits; i++ )
-    {
-      bitvalues[i] = ((unsigned)n & mask) ? '1':'0';
-      mask <<= 1;
-    }
-  bitvalues[intbits] = '\0';
-  fprintf (stdout, "%s: %s\n", name, bitvalues );
-}
-#endif
-
-
 int namespaceIdxEncode ( namespaceTuple_t tin )
 {
   xassert ( tin.nsp < NUM_NAMESPACES && tin.idx < NUM_IDX);
@@ -59904,6 +60067,7 @@ int
 namespaceNew()
 {
   int newNamespaceID = -1;
+  NAMESPACE_INIT();
   NAMESPACE_LOCK();
   if (namespacesSize > nNamespaces)
     {
@@ -59941,9 +60105,14 @@ namespaceNew()
   xassert(newNamespaceID >= 0 && newNamespaceID < NUM_NAMESPACES);
   ++nNamespaces;
   namespaces[newNamespaceID].resStage = STAGE_DEFINITION;
+#if defined (SX)
+  memcpy(namespaces[newNamespaceID].switches, defaultSwitches,
+         sizeof (namespaces[newNamespaceID].switches));
+#else
   memcpy(namespaces[newNamespaceID].switches,
          (union namespaceSwitchValue[NUM_NAMESPACE_SWITCH])defaultSwitches,
          sizeof (namespaces[newNamespaceID].switches));
+#endif
   reshListCreate(newNamespaceID);
   NAMESPACE_UNLOCK();
   return newNamespaceID;
@@ -59952,6 +60121,7 @@ namespaceNew()
 void
 namespaceDelete(int namespaceID)
 {
+  NAMESPACE_INIT();
   NAMESPACE_LOCK();
   xassert(namespaceID < namespacesSize && nNamespaces);
   reshListDestruct(namespaceID);
@@ -59960,25 +60130,13 @@ namespaceDelete(int namespaceID)
   NAMESPACE_UNLOCK();
 }
 
-void namespaceCleanup ( void )
-{
-  if ( nNamespaces > 1 )
-    {
-      initialNamespace = namespaces[0];
-      free(namespaces);
-      namespaces = &initialNamespace;
-      nNamespaces = 1;
-    }
-}
-
-
 int namespaceGetNumber ()
 {
   return nNamespaces;
 }
 
 
-void pioNamespaceSetActive ( int nId )
+void namespaceSetActive ( int nId )
 {
   xassert(nId < namespacesSize && nId >= 0
           && namespaces[nId].resStage != STAGE_UNUSED);
@@ -60054,10 +60212,16 @@ union namespaceSwitchValue namespaceSwitchGet(enum namespaceSwitch sw)
 
 void cdiReset(void)
 {
+  NAMESPACE_INIT();
   NAMESPACE_LOCK();
   for (int namespaceID = 0; namespaceID < namespacesSize; ++namespaceID)
-    namespaceDelete(namespaceID);
-  namespaces = &initialNamespace;
+    if (namespaces[namespaceID].resStage != STAGE_UNUSED)
+      namespaceDelete(namespaceID);
+  if (namespaces != &initialNamespace)
+    {
+      free(namespaces);
+      namespaces = &initialNamespace;
+    }
   namespacesSize = 1;
   nNamespaces = 1;
   activeNamespace = 0;
@@ -60075,6 +60239,7 @@ void cdiReset(void)
  */
 #include <inttypes.h>
 #include <limits.h>
+#include <string.h>
 
 
 int
@@ -60120,9 +60285,13 @@ serializeGetSizeInCore(int count, int datatype, void *context)
   case DATATYPE_INT16:
     elemSize = sizeof (int16_t);
     break;
+  case DATATYPE_UINT32:
+    elemSize = sizeof (uint32_t);
+    break;
   case DATATYPE_INT:
     elemSize = sizeof (int);
     break;
+  case DATATYPE_FLT:
   case DATATYPE_FLT64:
     elemSize = sizeof (double);
     break;
@@ -60270,10 +60439,11 @@ reshListCreate(int namespaceID)
 void
 reshListDestruct(int namespaceID)
 {
+  LIST_INIT();
   LIST_LOCK();
   xassert(resHList && namespaceID >= 0 && namespaceID < resHListSize);
   int callerNamespaceID = namespaceGetActive();
-  pioNamespaceSetActive(namespaceID);
+  namespaceSetActive(namespaceID);
   if (resHList[namespaceID].resources)
     {
       for ( int j = 0; j < resHList[namespaceID].size; j++ )
@@ -60286,7 +60456,7 @@ reshListDestruct(int namespaceID)
       reshListClearEntry(namespaceID);
     }
   if (resHList[callerNamespaceID].resources)
-    pioNamespaceSetActive(callerNamespaceID);
+    namespaceSetActive(callerNamespaceID);
   LIST_UNLOCK();
 }
 
@@ -60299,6 +60469,7 @@ static void listDestroy ( void )
       namespaceDelete(i);
   free(resHList);
   resHList = NULL;
+  cdiReset();
   LIST_UNLOCK();
 }
 
@@ -60741,65 +60912,47 @@ void reshUnlock ()
 
 int reshListCompare ( int nsp0, int nsp1 )
 {
-  int valCompare = 0;
-  int i;
-
-
   LIST_INIT();
   LIST_LOCK();
 
-  xassert(resHListSize > xmaxInt ( nsp0, nsp1 ) &&
-          xminInt ( nsp0, nsp1 ) >= 0 );
+  xassert(resHListSize > nsp0 && resHListSize > nsp1 &&
+          nsp0 >= 0 && nsp1 >= 0);
 
-  for ( i = 0; i < resHList[nsp0].size; i++ )
-    {
-      listElem_t *listElem0 = resHList[nsp0].resources + i,
-        *listElem1 = resHList[nsp1].resources + i;
-      if ( listElem0->val )
-	{
-	  if ( i >= resHList[nsp1].size )
-	    {
-              valCompare = 1;
-	      xdebug("%s %d", "namespace active length mismatch at resource",
-                     i);
-	      break;
-	    }
-
-	  if ( !listElem1->val )
-	    {
-              valCompare = 1;
-	      xdebug("%s %d", "namespace occupation mismatch at resource", i);
-              break;
-	    }
-
-	  if ( listElem0->ops != listElem1->ops || listElem0->ops == NULL )
-	    {
-              valCompare = 1;
-	      xdebug("%s %d", "resource type mismatch at resource", i);
-              break;
-	    }
-
-	  valCompare = listElem0->ops->valCompare(listElem0->val,
-                                                  listElem1->val);
-          if (valCompare)
-            break;
-	}
-      else if ( listElem1->val )
+  int valCompare = 0;
+  int i, listSizeMin = (resHList[nsp0].size <= resHList[nsp1].size)
+    ? resHList[nsp0].size : resHList[nsp1].size;
+  listElem_t *resources0 = resHList[nsp0].resources,
+    *resources1 = resHList[nsp1].resources;
+  for (i = 0; i < listSizeMin; i++)
+    {
+      int occupied0 = resources0[i].val != NULL,
+        occupied1 = resources1[i].val != NULL;
+      /* occupation mismatch ? */
+      int diff = occupied0 ^ occupied1;
+      valCompare |= (diff << cdiResHListOccupationMismatch);
+      if (!diff && occupied0)
         {
-          valCompare = 1;
-          xdebug("namespace 1 has value at empty place %d of namespace 0",
-                 i);
-          break;
+          /* both occupied, do resource types match? */
+          diff = (resources0[i].ops != resources1[i].ops
+                  || resources0[i].ops == NULL);
+          valCompare |= (diff << cdiResHListResourceTypeMismatch);
+          if (!diff)
+            {
+              /* types match, does content match also? */
+              diff = resources0[i].ops->valCompare(resources0[i].val,
+                                                   resources1[i].val);
+              valCompare |= (diff << cdiResHListResourceContentMismatch);
+            }
         }
     }
-
-  if (!valCompare)
-    {
-      for ( ; i < resHList[nsp1].size; i++ )
-        valCompare = valCompare || resHList[nsp1].resources[i].val != NULL;
-      if (valCompare)
-        xdebug("%s", "extra elements in second namespace");
-    }
+  /* find resources in nsp 0 beyond end of nsp 1 */
+  for (int j = listSizeMin; j < resHList[nsp0].size; ++j)
+    valCompare |= ((resources0[j].val != NULL)
+                   << cdiResHListOccupationMismatch);
+  /* find resources in nsp 1 beyond end of nsp 0 */
+  for (; i < resHList[nsp1].size; ++i)
+    valCompare |= ((resources1[i].val != NULL)
+                   << cdiResHListOccupationMismatch);
 
   LIST_UNLOCK();
 
@@ -60823,7 +60976,7 @@ void reshListPrint(FILE *fp)
 
   for ( i = 0; i < namespaceGetNumber (); i++ )
     {
-      pioNamespaceSetActive ( i );
+      namespaceSetActive ( i );
 
       fprintf ( fp, "\n" );
       fprintf ( fp, "##################################\n" );
@@ -60847,7 +61000,7 @@ void reshListPrint(FILE *fp)
   fprintf ( fp, "#\n#  end global resource list" \
             "\n#\n##########################################\n\n" );
 
-  pioNamespaceSetActive ( temp );
+  namespaceSetActive ( temp );
 }
 
 
@@ -60860,3606 +61013,200 @@ void reshListPrint(FILE *fp)
  * require-trailing-newline: t
  * End:
  */
-#ifdef HAVE_CONFIG_H
-#endif
-
-
-extern void   gridUnpack ( char *, int, int *, int, void *context);
-extern void  zaxisUnpack ( char *, int, int *, int, void *context);
-extern int streamNint;
-
-
-/*****************************************************************************/
-
-
-
-void reshUnpackResources(char * unpackBuffer, int unpackBufferSize,
-                         void *context)
+   static char cdi_libvers[] = "1.6.3" " of ""Feb 12 2014"" ""10:17:39";
+char *cdiLibraryVersion(void);
+char *cdiLibraryVersion(void)
 {
-  int token1, token2, nspTarget;
-  int unpackBufferPos = 0;
-  int numAssociations = 0, sizeAssociations = 16;
-  struct streamAssoc *associations
-    = xmalloc(sizeof (associations[0]) * sizeAssociations);
+  return (cdi_libvers);
+}
+#if defined (HAVE_CF_INTERFACE)
+#undef realloc
+#undef malloc
+#undef calloc
+#undef free
+#undef DOUBLE_PRECISION
+/* cfortran.h  4.3 */
+/* http://www-zeus.desy.de/~burow/cfortran/                   */
+/* Burkhard Burow  burow at desy.de                 1990 - 2001. */
 
-  while ( unpackBufferPos < unpackBufferSize )
-    {
-      serializeUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
-                      &token1, 1, DATATYPE_INT, context);
+/* 02/12/2002 Uwe Schulzweida : UXP Fortran support           */
+/* 02/05/2003 Uwe Schulzweida : Linux Fortran support on i386 */
+/* 09/09/2005 Uwe Schulzweida : Linux Fortran support on ia64 */
 
-      if (token1 == END)
-        break;
-      switch (token1)
-	{
-	case START:
-	  serializeUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
-                          &nspTarget, 1, DATATYPE_INT, context);
-	  break;
-	case GRID:
-	  gridUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
-                     nspTarget, context );
-	  break;
-	case ZAXIS:
-	  zaxisUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
-                      nspTarget, context);
-	  break;
-	case TAXIS:
-	  taxisUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
-                      nspTarget, context, 1);
-	  break;
-	case INSTITUTE:
-          instituteUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
-                          nspTarget, context);
-	  break;
-	case MODEL:
-          modelUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
-                      nspTarget, context);
-	  break;
-	case STREAM:
-          if (sizeAssociations == numAssociations)
-            associations
-              = xrealloc(associations,
-                         sizeof (associations[0]) * (sizeAssociations *= 2));
-	  associations[numAssociations]
-            = streamUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
-                           nspTarget, context);
-          ++numAssociations;
-	  break;
-	case VLIST:
-          vlistUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
-                      nspTarget, context);
-	  break;
-	default:
-	  xabort ( "TOKEN MAPS NO VALID DATATYPE" );
-	}
+#ifndef __CFORTRAN_LOADED
+#define __CFORTRAN_LOADED
 
-      serializeUnpack(unpackBuffer, unpackBufferSize, &unpackBufferPos,
-                       &token2, 1, DATATYPE_INT, context);
-      xassert ( token2 == SEPARATOR );
-    }
-  for (int i = 0; i < numAssociations; ++i)
-    {
-      cdiStreamSetupVlist(stream_to_pointer(associations[i].streamID),
-                          namespaceAdaptKey(associations[i].vlistID,
-                                            nspTarget),
-                          namespaceAdaptKey(associations[i].vlistIDorig,
-                                            nspTarget));
-    }
-  free(associations);
-}
+/* 
+   THIS FILE IS PROPERTY OF BURKHARD BUROW. IF YOU ARE USING THIS FILE YOU
+   SHOULD ALSO HAVE ACCESS TO CFORTRAN.DOC WHICH PROVIDES TERMS FOR USING,
+   MODIFYING, COPYING AND DISTRIBUTING THE CFORTRAN.H PACKAGE.
+*/
+
+/* 
+  Avoid symbols already used by compilers and system *.h:
+  __ - OSF1 zukal06 V3.0 347 alpha, cc -c -std1 cfortest.c
 
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
  */
-#ifdef HAVE_CONFIG_H
-#endif
 
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
 
+/* First prepare for the C compiler. */
 
-#ifdef USE_MPI
-static
-char commands[][13] = { "FINALIZE\0",
-                        "RESOURCES\0",
-                        "WINCREATE\0",
-                        "WRITETS\0"};
+#ifndef ANSI_C_preprocessor /* i.e. user can override. */
+#ifdef __CF__KnR
+#define ANSI_C_preprocessor 0
+#else
+#ifdef __STDC__
+#define ANSI_C_preprocessor 1
+#else
+#define _cfleft             1
+#define _cfright 
+#define _cfleft_cfright     0
+#define ANSI_C_preprocessor _cfleft/**/_cfright
 #endif
-
-
-/*****************************************************************************/
-#ifdef USE_MPI
-void
-cdiAbortC_MPI(const char *caller, const char *filename,
-              const char *functionname, int line,
-              const char *errorString, va_list ap)
-{
-  {
-    int rank = getMPICommWorldRank();
-    fprintf(stderr, "ERROR, pe%d in %s, %s, line %d%s"
-            "%s\nerrorString: \"", rank, functionname, filename, line,
-            caller?", called from ":"", caller?caller:"");
-  }
-  vfprintf(stderr, errorString, ap);
-  fputs("\"\n", stderr);
-  if (callsToMPIAreAllowed())
-    MPI_Abort(MPI_COMM_WORLD, 1);
-  else
-    abort();
-  exit(EXIT_FAILURE);
-  va_end(ap);
-}
 #endif
-
-/*****************************************************************************/
-
-void * pcdiXmalloc ( size_t size, const char *filename, const char *functionname,
-		     int line )
-{
-  void * value = calloc (1, size );
-  if ( value == NULL )
-    cdiAbort(filename, functionname, line, "malloc failed: %s",
-             strerror(errno));
-  return value;
-}
-
-void * pcdiXcalloc ( size_t nmemb, size_t size, const char *filename,
-		     const char *functionname, int line )
-{
-  void * value = calloc ( nmemb, size );
-  if ( value == NULL )
-    cdiAbort(filename, functionname, line, "calloc failed: %s",
-             strerror(errno) );
-  return value;
-}
-
-void * pcdiXrealloc ( void *p, size_t size, const char *functionname,
-		      const char *filename, int line )
-{
-  void * value = realloc ( p, size );
-  if ( value == NULL )
-    cdiAbort(filename, functionname, line, "realloc failed: %s",
-             strerror(errno));
-  return value;
-}
-
-/***************************************************************/
-
-#ifdef USE_MPI
-void pcdiXMPI(int iret, const char *filename, int line)
-{
-  char errorString[2][MPI_MAX_ERROR_STRING + 1];
-  int len, errorClass, rank = getMPICommWorldRank();
-  MPI_Error_class(iret, &errorClass);
-  MPI_Error_string(errorClass, errorString[0], &len);
-  errorString[0][len] = '\0';
-  MPI_Error_string(iret, errorString[1], &len);
-  errorString[1][len] = '\0';
-  fprintf(stderr, "MPI ERROR, pe%d, %s, line %d,"
-          "errorClass: \"%s\""
-          "errorString: \"%s\"\n",
-          rank, filename, line,
-          errorString[0], errorString[1]);
-  MPI_Abort(MPI_COMM_WORLD, iret);
-}
-
-/*****************************************************************************/
-
-void pcdiXMPIStat ( int iret, const char *filename, int line, MPI_Status *status )
-{
-  char errorString[MPI_MAX_ERROR_STRING + 1];
-  int len, rank = getMPICommWorldRank();
-
-  if ( iret == MPI_ERR_IN_STATUS )
-    {
-      switch ( status->MPI_ERROR )
-        {
-          fprintf ( stderr, "------- checking error in request ----------\n" );
-        case MPI_SUCCESS :
-          fprintf ( stderr, "-------- mpi_success -----------\n" );
-          break;
-        case MPI_ERR_PENDING:
-          fprintf ( stderr, "-------- mpi_err_pending ----------\n");
-          break;
-        default:
-          MPI_Error_string ( status->MPI_ERROR, errorString, &len );
-          errorString[len] = '\0';
-          fprintf ( stderr,"MPI ERROR in request, pe%d, %s, line %d,"
-                    "return value: %d, error_string: %s\n",
-                    rank, filename, line, iret, errorString );
-          MPI_Abort ( MPI_COMM_WORLD, iret );
-        }
-    }
-  else
-    xmpi ( iret );
-
-  return;
-}
 #endif
 
-/****************************************************/
-
-#ifdef USE_MPI
-void pcdiDebugComm ( const char *filename, const char *functionname, int line, MPI_Comm *comm )
-{
-  int rank = -1, size, len, rankGlob = -1;
-  char *name;
-
-  name = ( char * ) xmalloc ( MPI_MAX_OBJECT_NAME );
-  memset ( name, 0, ( MPI_MAX_OBJECT_NAME ) * sizeof ( char ));
-  MPI_Comm_get_name ( * comm, name, &len );
-  MPI_Comm_size ( * comm, &size );
-  {
-    int init_flag = 0, finished_flag = 0;
-    if (MPI_Initialized(&init_flag) == MPI_SUCCESS && init_flag
-        && MPI_Finalized(&finished_flag) == MPI_SUCCESS && !finished_flag)
-      {
-        MPI_Comm_rank(*comm, &rank);
-        MPI_Comm_rank(MPI_COMM_WORLD, &rankGlob);
-      }
-  }
-  fprintf ( stdout,
-            "pe%d in %s, %s, line %d: comm: name=%s, size=%d, rank=%d\n",
-            rankGlob, functionname, filename, line,
-            name, size, rank );
-  free ( name );
-
-}
+#if ANSI_C_preprocessor
+#define _0(A,B)   A##B
+#define  _(A,B)   _0(A,B)  /* see cat,xcat of K&R ANSI C p. 231 */
+#define _2(A,B)   A##B     /* K&R ANSI C p.230: .. identifier is not replaced */
+#define _3(A,B,C) _(A,_(B,C))
+#else                      /* if it turns up again during rescanning.         */
+#define  _(A,B)   A/**/B
+#define _2(A,B)   A/**/B
+#define _3(A,B,C) A/**/B/**/C
 #endif
 
-/****************************************************/
-
-#ifdef USE_MPI
-void pcdiDebugMsg ( const char * cdiPioDebugString, const char *filename,
-                    const char *functionname, int line, int tag, int source,
-                    int nfinished )
-{
-  int rank = getMPICommWorldRank();
-
-  fprintf ( stdout,
-            "%s pe%d in %s, %s, line %d: command %s, source %d, finalized=%d\n",
-            cdiPioDebugString, rank, functionname, filename, line,
-            &commands[tag][0], source, nfinished );
-}
+#if (defined(vax)&&defined(unix)) || (defined(__vax__)&&defined(__unix__))
+#define VAXUltrix
 #endif
-/****************************************************/
-
-#ifdef USE_MPI
-void pcdiDebugMsg2 ( const char *filename, const char *functionname, int line,
-                   int tag, int source, char * text )
-{
-  int rank = getMPICommWorldRank();
 
-  fprintf ( stdout,
-            "pe%d in %s, %s, line %d: command %s, source %d, %s\n",
-            rank, functionname, filename, line,
-            &commands[tag][0], source, text );
-}
+#include <stdio.h>     /* NULL [in all machines stdio.h]                      */
+#include <string.h>    /* strlen, memset, memcpy, memchr.                     */
+#if !( defined(VAXUltrix) || defined(sun) || (defined(apollo)&&!defined(__STDCPP__)) )
+#include <stdlib.h>    /* malloc,free                                         */
+#else
+#include <malloc.h>    /* Had to be removed for DomainOS h105 10.4 sys5.3 425t*/
+#ifdef apollo
+#define __CF__APOLLO67 /* __STDCPP__ is in Apollo 6.8 (i.e. ANSI) and onwards */
 #endif
+#endif
+#include <limits.h>    /* LONG_MAX */
 
+#if !defined(__GNUC__) && !defined(__sun) && (defined(sun)||defined(VAXUltrix)||defined(lynx))
+#define __CF__KnR     /* Sun, LynxOS and VAX Ultrix cc only supports K&R.     */
+                      /* Manually define __CF__KnR for HP if desired/required.*/
+#endif                /*       i.e. We will generate Kernighan and Ritchie C. */
+/* Note that you may define __CF__KnR before #include cfortran.h, in order to
+generate K&R C instead of the default ANSI C. The differences are mainly in the
+function prototypes and declarations. All machines, except the Apollo, work
+with either style. The Apollo's argument promotion rules require ANSI or use of
+the obsolete std_$call which we have not implemented here. Hence on the Apollo,
+only C calling FORTRAN subroutines will work using K&R style.*/
 
-/****************************************************/
-
-
-int xmaxInt ( int a, int b )
-{
-  return a >= b ? a : b;
-}
-
-
-/****************************************************/
 
+/* Remainder of cfortran.h depends on the Fortran compiler. */
 
-int xminInt ( int a, int b )
-{
-  return a <= b ? a : b;
-}
+#if defined(CLIPPERFortran) || defined(pgiFortran)
+#define f2cFortran
+#endif
 
+/* VAX/VMS does not let us \-split long #if lines. */ 
+/* Split #if into 2 because some HP-UX can't handle long #if */
+#if !(defined(NAGf90Fortran)||defined(f2cFortran)||defined(hpuxFortran)||defined(apolloFortran)||defined(sunFortran)||defined(IBMR2Fortran)||defined(CRAYFortran))
+#if !(defined(mipsFortran)||defined(DECFortran)||defined(vmsFortran)||defined(CONVEXFortran)||defined(PowerStationFortran)||defined(AbsoftUNIXFortran)||defined(AbsoftProFortran)||defined(SXFortran))
+/* If no Fortran compiler is given, we choose one for the machines we know.   */
+#if defined(__linux__) && defined(__i386__)
+#define f2cFortran
+#endif
+#if defined(__linux__) && defined(__ia64__)
+#define f2cFortran
+#endif
+#if defined(__linux__) && defined(__x86_64__)
+#define f2cFortran
+#endif
+#if defined(lynx) || defined(VAXUltrix)
+#define f2cFortran    /* Lynx:      Only support f2c at the moment.
+                         VAXUltrix: f77 behaves like f2c.
+                           Support f2c or f77 with gcc, vcc with f2c. 
+                           f77 with vcc works, missing link magic for f77 I/O.*/
+#endif
+#if defined(__hpux)             /* 921107: Use __hpux instead of __hp9000s300 */
+#define       hpuxFortran       /*         Should also allow hp9000s7/800 use.*/
+#endif
+#if       defined(apollo)
+#define           apolloFortran /* __CF__APOLLO67 also defines some behavior. */
+#endif
+#if          defined(sun) || defined(__sun) 
+#define              sunFortran
+#endif
+#if       defined(_IBMR2)
+#define            IBMR2Fortran
+#endif
+#if        defined(_CRAY)
+#define             CRAYFortran /*       _CRAYT3E also defines some behavior. */
+#endif
+#if        defined(_SX)
+#define               SXFortran
+#endif
+#if        defined(__uxp__)
+#define               UXPFortran
+#endif
+#if         defined(mips) || defined(__mips)
+#define             mipsFortran
+#endif
+#if          defined(vms) || defined(__vms)
+#define              vmsFortran
+#endif
+#if      defined(__alpha) && defined(__unix__)
+#define              DECFortran
+#endif
+#if   defined(__convex__)
+#define           CONVEXFortran
+#endif
+#if   defined(VISUAL_CPLUSPLUS)
+#define     PowerStationFortran
+#endif
+#endif /* ...Fortran */
+#endif /* ...Fortran */
 
-/****************************************************/
+/* Split #if into 2 because some HP-UX can't handle long #if */
+#if !(defined(NAGf90Fortran)||defined(f2cFortran)||defined(hpuxFortran)||defined(apolloFortran)||defined(sunFortran)||defined(IBMR2Fortran)||defined(CRAYFortran))
+#if !(defined(mipsFortran)||defined(DECFortran)||defined(vmsFortran)||defined(CONVEXFortran)||defined(PowerStationFortran)||defined(AbsoftUNIXFortran)||defined(AbsoftProFortran)||defined(SXFortran)||defined(UXPFortran))
+/* If your compiler barfs on ' #error', replace # with the trigraph for #     */
+ #error "cfortran.h:  Can't find your environment among:\
+    - MIPS cc and f77 2.0. (e.g. Silicon Graphics, DECstations, ...)     \
+    - IBM AIX XL C and FORTRAN Compiler/6000 Version 01.01.0000.0000     \
+    - VAX   VMS CC 3.1 and FORTRAN 5.4.                                  \
+    - Alpha VMS DEC C 1.3 and DEC FORTRAN 6.0.                           \
+    - Alpha OSF DEC C and DEC Fortran for OSF/1 AXP Version 1.2          \
+    - Apollo DomainOS 10.2 (sys5.3) with f77 10.7 and cc 6.7.            \
+    - CRAY                                                               \
+    - NEC SX-4 SUPER-UX                                                  \
+    - CONVEX                                                             \
+    - Sun                                                                \
+    - PowerStation Fortran with Visual C++                               \
+    - HP9000s300/s700/s800 Latest test with: HP-UX A.08.07 A 9000/730    \
+    - LynxOS: cc or gcc with f2c.                                        \
+    - VAXUltrix: vcc,cc or gcc with f2c. gcc or cc with f77.             \
+    -            f77 with vcc works; but missing link magic for f77 I/O. \
+    -            NO fort. None of gcc, cc or vcc generate required names.\
+    - f2c    : Use #define    f2cFortran, or cc -Df2cFortran             \
+    - NAG f90: Use #define NAGf90Fortran, or cc -DNAGf90Fortran          \
+    - Absoft UNIX F77: Use #define AbsoftUNIXFortran or cc -DAbsoftUNIXFortran \
+    - Absoft Pro Fortran: Use #define AbsoftProFortran \
+    - Portland Group Fortran: Use #define pgiFortran"
+/* Compiler must throw us out at this point! */
+#endif
+#endif
 
 
-int xsum ( int n, int * argarray )
-{
-  int i, sum = 0;
+#if defined(VAXC) && !defined(__VAXC)
+#define OLD_VAXC
+#pragma nostandard                       /* Prevent %CC-I-PARAMNOTUSED.       */
+#endif
 
-  for ( i = 0; i < n; i++ )
-    sum += * ( argarray + i );
-
-  return sum;
-}
-
-
-/****************************************************/
-
-
-double xchecksum ( int type, int count, void * buffer )
-{
-  return 0.0;
-}
-
-
-/****************************************************/
-
-void printArray ( const char * cdiPioDebugString, char * ps, const void * array, int n,
-                  int datatype, const char * funname, const char * filename, int line )
-{
-  int i;
-  int * iArray;
-  double * dArray;
-
-#ifdef USE_MPI
-  {
-    int rank = getMPICommWorldRank();
-    fprintf ( stdout, "%s pe%d in %s, %s, line %d: %s = ",
-              cdiPioDebugString, rank, funname, filename, line, ps );
-  }
-#else
-  fprintf ( stdout, "%s %s, %s, line %d: %s = ",
-	    cdiPioDebugString, funname, filename, line, ps );
-#endif
-
-  switch ( datatype )
-    {
-    case DATATYPE_INT:
-      iArray = ( int * ) array;
-      for ( i = 0; i < n-1; i++ )
-	fprintf ( stdout, "%d ", * ( iArray + i ));
-      fprintf ( stdout, "%d\n", * ( iArray + n - 1 ));
-      break;
-    case DATATYPE_FLT:
-      dArray = ( double * ) array;
-      for ( i = 0; i < n-1; i++ )
-	fprintf ( stdout, "%.2f ", * ( dArray + i ));
-      fprintf ( stdout, "%.2f\n", * ( dArray + n-1 ));
-      break;
-    default:
-      fprintf ( stdout, " ... no datatype defined\n" );
-    }
-
-  return;
-}
-
-int
-cdiPioQueryVarDims(int varShape[3], int vlistID, int varID)
-{
-  int gridID = vlistInqVarGrid(vlistID, varID);
-  int zaxisID = vlistInqVarZaxis(vlistID, varID);
-  int gridType = gridInqType(gridID);
-  switch (gridType)
-    {
-    case GRID_LONLAT:
-    case GRID_GAUSSIAN:
-      varShape[0] = gridInqXsize(gridID);
-      varShape[1] = gridInqYsize(gridID);
-      break;
-    case GRID_SPECTRAL:
-      varShape[0] = 2;
-      varShape[1] = gridInqSize(gridID) / 2;
-      break;
-    case GRID_GENERIC:
-    case GRID_LCC:
-    case GRID_GME:
-    case GRID_CURVILINEAR:
-    case GRID_UNSTRUCTURED:
-      xabort("unimplemented grid type: %d", gridType);
-      break;
-    }
-  varShape[2] = zaxisInqSize(zaxisID);
-  /* FIXME: other grids have different dimensionality */
-  return (varShape[2] == 1)?2:3;
-}
-
-/****************************************************/
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
-#endif
-
-
-#ifdef USE_MPI
-
-#include <ctype.h>
-#include <yaxt.h>
-
-
-
-char * command2charP[6] = {"IO_Open_file", "IO_Close_file",
-                           "IO_Get_fp","IO_Set_fp",
-                           "IO_Send_buffer", "IO_Finalize"};
-
-long initial_buffersize = 16 * 1024 * 1024;
-/*  4 KB <= x < 256 MB */
-/* 16 * 1024 * 1024; */
-/* 16 * 1024; */
-/* 4 * 1024; */
-
-enum {
-  tagKey = 100,
-};
-
-double accumProbe   = 0.0;
-double accumRecv    = 0.0;
-double accumSend    = 0.0;
-double accumSuspend = 0.0;
-double accumWait    = 0.0;
-double accumWrite   = 0.0;
-
-char *token = "%";
-
-/***************************************************************/
-
-int encodeFileOpTag(int ID, int sc)
-{
-  return ID * tagKey + sc;
-}
-
-/***************************************************************/
-
-struct fileOpTag decodeFileOpTag(int tag)
-{
-  struct fileOpTag rtag;
-
-  rtag.id = tag / tagKey;
-  rtag.command = tag % tagKey;
-
-  return rtag;
-}
-
-/***************************************************************/
-
-size_t
-cdiPioFileWrite(int fileID, const void *restrict buffer, size_t len, int tsID)
-{
-  size_t iret = CDI_UNDEFID;
-
-  switch ( commInqIOMode ())
-    {
-    case PIO_MPI:
-      iret = fwMPINONB ( fileID, tsID, buffer, len );
-      break;
-#ifndef _SX
-    case PIO_ASYNCH:
-#endif
-    case PIO_WRITER:
-      iret = pioSendWrite(fileID, tsID, buffer, len);
-      break;
-    case PIO_FPGUARD:
-      iret = fwPOSIXFPGUARDSENDRECV ( fileID, tsID, buffer, len );
-      break;
-    }
-
-  return iret;
-}
-
-/***************************************************************/
-
-int pioFileClose ( int id )
-{
-  int iret = CDI_UNDEFID;
-  switch ( commInqIOMode ())
-    {
-    case PIO_MPI:
-      iret = fcMPINONB ( id );
-      break;
-#ifndef _SX
-    case PIO_ASYNCH:
-#endif
-    case PIO_WRITER:
-      iret = pioSendClose(id);
-      break;
-    case PIO_FPGUARD:
-      iret = fcPOSIXFPGUARDSENDRECV ( id );
-      break;
-    }
-
-  return iret;
-}
-
-/***************************************************************/
-
-int pioFileOpen(const char *filename, const char *mode)
-{
-  int iret = CDI_UNDEFID;
-
-  if ((mode[0] != 'w' && mode[0] != 'W') || mode[0] == 0 || mode[1] != 0)
-    xabort("Unsupported mode \"%s\" in parallel file open.", mode);
-
-  switch ( commInqIOMode ())
-    {
-    case PIO_MPI:
-      iret = fowMPINONB ( filename );
-      break;
-#ifndef _SX
-    case PIO_ASYNCH:
-#endif
-    case PIO_WRITER:
-      iret = pioSendOpen(filename);
-      break;
-    case PIO_FPGUARD:
-      iret = fowPOSIXFPGUARDSENDRECV ( filename );
-      break;
-    }
-
-  return iret;
-}
-
-/***************************************************************/
-
-void backendInit ( void )
-{
-  int IOMode = commInqIOMode ();
-
-  commDefCommNode ();
-
-  xassert ( IOMode != PIO_NONE  || commInqSizeNode () == 1 );
-
-  switch ( IOMode )
-    {
-    case PIO_NONE:
-      commDefCommColl ( 1 );
-      commSendNodeInfo ();
-      commRecvNodeMap ();
-      commDefCommsIO ();
-      break;
-    case PIO_MPI:
-      initMPINONB ();
-      break;
-#ifndef _SX
-    case PIO_ASYNCH:
-#endif
-    case PIO_WRITER:
-      pioSendInitialize();
-      break;
-    case PIO_FPGUARD:
-      initPOSIXFPGUARDSENDRECV ();
-      break;
-    }
-}
-
-/***************************************************************/
-
-void backendCleanup ( void )
-{
-  int IOMode = commInqIOMode ();
-  switch ( IOMode )
-    {
-    case PIO_NONE:
-      break;
-    case PIO_MPI:
-      finalizeMPINONB ();
-      break;
-#ifndef _SX
-    case PIO_ASYNCH:
-#endif
-    case PIO_WRITER:
-      pioSendFinalize();
-      break;
-    case PIO_FPGUARD:
-      finalizePOSIXFPGUARDSENDRECV ();
-      break;
-    default:
-      xdebug("%s", " BACKENDCLEANUP FUNCTION NOT IMPLEMENTED YET.");
-    }
-}
-
-/***************************************************************/
-
-void backendFinalize ( void )
-{
-  commDestroy ();
-  MPI_Finalize ();
-  exit ( EXIT_SUCCESS );
-}
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
-#endif
-
-#include <limits.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#ifdef USE_MPI
-#include <mpi.h>
-#include <yaxt.h>
-#endif
-
-
-#ifdef USE_MPI
-
-extern resOps streamOps;
-
-
-static struct rdmaWin
-{
-  size_t size;
-  unsigned char *buffer, *head;
-  MPI_Win win;
-  int postSet, refuseFuncCall;
-  MPI_Group ioGroup;
-  int dictSize, dictDataUsed, dictRPCUsed, dict;
-} *txWin = NULL;
-
-
-const char * const funcMap[numRPCFuncs] = {
-  "streamOpen",
-  "streamDefVlist",
-  "streamClose",
-  "streamDefTimestep",
-};
-
-float cdiPIOpartInflate_;
-
-/****************************************************/
-
-static int cmp ( const void * va, const void * vb )
-{
-    const int ** a, ** b;
-
-  a = ( const int ** ) va;
-  b = ( const int ** ) vb;
-
-  return (( **a < **b ) - ( **a > **b ));
-}
-
-/****************************************************/
-
-static void
-mapProblems(int problemSizes[], int * problemMapping, int nProblems,
-            int nWriter, double * w)
-{
-  int *ip[nProblems];
-  int dummy[nProblems];
-  int buckets[nWriter];
-  int currCapacity, nextCapacity;
-  double meanBucket[nWriter];
-  int sum = 0;
-  int writerIdx = 0;
-  int i, j;
-
-
-  for ( i = 0; i < nProblems; i++ )
-    {
-      ip[i] = &problemSizes[i];
-      sum += problemSizes[i];
-    }
-
-  qsort ( ip, nProblems, sizeof ( int * ), cmp );
-
-  for ( i = 0; i < nProblems; i++ )
-    dummy[i] = ip[i] - problemSizes;
-
-  for ( j = 0; j < nWriter; j++ )
-    meanBucket[j] = ( double ) sum * ( * ( w + j ));
-
-  memset(buckets, 0, sizeof (buckets));
-
-  for ( i = 0; i < nProblems; i++ )
-    {
-      currCapacity = INT_MIN;
-
-      for ( j = 0; j < nWriter; j++ )
-	{
-	  nextCapacity = meanBucket[j] - ( buckets[j] + ( *ip[i] ));
-
-	  if ( nextCapacity > currCapacity )
-	    {
-	      currCapacity = nextCapacity;
-	      writerIdx = j;
-	    }
-	}
-      problemMapping[ dummy[i] ] = writerIdx;
-      buckets[writerIdx] +=  *ip[i];
-    }
-
-  if ( ddebug )
-    {
-      xprintArray3 (  "problemSizes = ", problemSizes, nProblems, DATATYPE_INT );
-      xprintArray3 ( "vector of indices, qsort of problemSizes", dummy,
-                    nProblems, DATATYPE_INT );
-      xprintArray3 ( "problemMapping", problemMapping, nProblems, DATATYPE_INT );
-      xprintArray3 ( "meanBucket", meanBucket, nWriter, DATATYPE_FLT );
-      xprintArray3 ( "actual buckets", buckets, nWriter, DATATYPE_INT );
-    }
-}
-
-/****************************************************/
-
-/**
-   @brief is encapsulated in CDI library.
-
-   @param vSizes array with number of levels for all var_t 's in order of streams
-
-   @param sSizes array with number of var_t for all stream_t 's
-
-   @param varMapping return value, array with ranks of I/O PEs assigned to var_t 's
-in order of vSizes
-
-   @param nStreams number of stream_t 's
-
-   @param nodeSizes array of number of I/O PEs on each physical nodes, increasing
-   order of ranks assumed
-
-   @param nNodes number of physical nodes hosting I/O PEs
-
-   @return
-*/
-
-static void
-varMapGen(int *vSizes, int *sSizes, int *varMapping,
-          int nStreams, int *nodeSizes, int nNodes)
-{
-
-  int weightsStreams[nStreams];
-  int streamMapping[nStreams];
-  int nPEs = 0, nVars = 0;
-  int i, j, k, offset = 0, offsetN = 0;
-  double * w;
-
-  int * weightsVarsNode;
-  int * varMappingNode;
-  int nVarsNode, summandRank = 0;
-  int nProcsColl = commInqNProcsColl ();
-
-  int buckets[nProcsColl];
-
-  for ( i = 0; i < nStreams; i++ )
-    {
-      nVars += * ( sSizes + i );
-      weightsStreams[i] = 0;
-      for ( j = 0; j < * ( sSizes + i ); j++ )
-	weightsStreams[i] += * ( vSizes + offset++ );
-    }
-
-  w = ( double * ) xmalloc ( nNodes * sizeof ( double ));
-  for ( j = 0; j < nNodes; j++ )
-    nPEs += * ( nodeSizes + j );
-
-  for ( j = 0; j < nNodes; j++ )
-    w[j] = ( double ) * ( nodeSizes + j ) / ( double ) nPEs;
-
-  mapProblems ( weightsStreams, streamMapping, nStreams, nNodes, w );
-  free ( w );
-
-  for ( i = 0; i < nNodes; i++ )
-    {
-      nVarsNode = 0;
-      for ( j = 0; j < nStreams; j++ )
-	if ( * ( streamMapping + j ) == i )
-	  nVarsNode += * ( sSizes + j );
-
-      weightsVarsNode = ( int * ) xmalloc ( nVarsNode * sizeof ( int ));
-      varMappingNode = ( int * ) xmalloc ( nVarsNode * sizeof ( int ));
-      w = ( double * ) xmalloc ( * ( nodeSizes + i ) * sizeof ( double ));
-      offset = 0;
-      offsetN = 0;
-
-      for ( j = 0; j < nStreams; j++ )
-	if ( * ( streamMapping + j ) == i )
-	  for ( k = 0; k < * ( sSizes + j ); k ++ )
-	    * ( weightsVarsNode + offsetN++ ) = * ( vSizes + offset++ );
-	else
-	  offset += * ( sSizes + j );
-
-      for ( j = 0; j < * ( nodeSizes + i ); j ++ )
-	w[j] = 1.0 / ( double ) * ( nodeSizes + i );
-
-      mapProblems ( weightsVarsNode, varMappingNode, nVarsNode,
-		    * ( nodeSizes + i ),  w );
-
-      offset = 0;
-      offsetN = 0;
-
-      for ( j = 0; j < nStreams; j++ )
-	if ( * ( streamMapping + j ) == i )
-	  for ( k = 0; k < * ( sSizes + j ); k ++ )
-	    * ( varMapping + offset ++ ) =
-              commCollID2RankGlob ( * ( varMappingNode + offsetN ++ ) +
-                                    summandRank );
-	else
-	  offset += * ( sSizes + j );
-
-      summandRank += * ( nodeSizes + i );
-
-      free ( w );
-      free ( varMappingNode );
-      free ( weightsVarsNode );
-    }
-
-  if ( ddebug )
-    {
-      xprintArray ( "varMapping", varMapping, nVars, DATATYPE_INT  );
-      for ( i = 0; i < nProcsColl; i++ )
-	buckets[i] = 0;
-      for ( i = 0; i < nVars; i ++ )
-	buckets[commRankGlob2CollID ( *(varMapping + i ))] += * ( vSizes + i );
-      xprintArray ( "buckets", buckets, nProcsColl, DATATYPE_INT );
-    }
-}
-
-/************************************************************************/
-
-static void
-varsMapNDeco(int nNodes, int *nodeSizes)
-{
-  int nStreams, nVars, * resHs, * streamSizes, * varSizes, * varMapping,
-    * collectsData;
-  int i, j, k = 0;
-  int nProcsColl = commInqNProcsColl ();
-
-  xdebug ( "START, nProcsColl=%d", nProcsColl );
-
-  nStreams = streamSize ();
-
-  resHs       = xmalloc ( nStreams * sizeof ( resHs[0] ));
-  streamSizes = xmalloc ( nStreams * sizeof ( streamSizes[0] ));
-  collectsData = xmalloc ( nProcsColl * sizeof ( collectsData[0] ));
-  streamGetIndexList ( nStreams, resHs );
-
-  for ( i = 0; i < nStreams; i++ )
-    streamSizes[i] = streamInqNvars ( * ( resHs + i ));
-
-  nVars = xsum ( nStreams, streamSizes );
-  varSizes   = xmalloc ( nVars * sizeof ( varSizes[0] ));
-  varMapping = xmalloc ( nVars * sizeof ( varMapping[0] ));
-
-  for ( i = 0; i < nStreams; i++ )
-    for ( j = 0; j < * ( streamSizes + i ); j++ )
-      varSizes[k++] += vlistInqVarSize ( streamInqVlist ( * ( resHs + i )), j );
-
-  xassert ( k == nVars );
-
-  varMapGen ( varSizes, streamSizes, varMapping,
-	      nStreams, nodeSizes, nNodes );
-
-  k = 0;
-  for ( i = 0; i < nStreams; i++ )
-    for ( j = 0; j < * ( streamSizes + i ); j++ )
-      {
-        vlistDefVarIOrank ( streamInqVlist ( * ( resHs + i )), j,
-                            * ( varMapping + k ));
-        vlistDefVarIOrank ( streamInqVlistIDorig ( * ( resHs + i )), j,
-                            * ( varMapping + k ));
-        collectsData[commRankGlob2CollID ( varMapping[k++] )] = 1;
-      }
-
-  for ( j = 0; j < nProcsColl; j++ )
-    if ( collectsData[j] == 0 )
-      xabort("AT LEAST ONE COLLECTOR PROCESS IDLES, "
-             "CURRENTLY NOT COVERED: "
-             "PE%d collects no data",
-             commCollID2RankGlob(j));
-
-  if ( varMapping )   free ( varMapping );
-  if ( varSizes )     free ( varSizes );
-  if ( collectsData ) free ( collectsData );
-  if ( streamSizes )  free ( streamSizes );
-  if ( resHs )        free ( resHs );
-
-  xdebug("%s", "RETURN");
-}
-
-/************************************************************************/
-
-static
-void modelWinCleanup ( void )
-{
-  int collID;
-
-  xdebug("%s", "START");
-  if (txWin != NULL)
-    {
-      for ( collID = 0; collID < commInqNProcsColl (); collID ++ )
-        {
-          if (txWin[collID].postSet)
-            xmpi(MPI_Win_wait(txWin[collID].win));
-          xmpi(MPI_Win_free(&txWin[collID].win));
-          xmpi ( MPI_Free_mem ( txWin[collID].buffer ));
-          xmpi(MPI_Group_free(&txWin[collID].ioGroup));
-        }
-      free(txWin);
-    }
-
-  xdebug("%s", "RETURN. CLEANED UP MPI_WIN'S");
-}
-
-/************************************************************************/
-
-struct collDesc
-{
-  int numDataRecords, numRPCRecords;
-};
-
-static void
-modelWinDefBufferSizes(void)
-{
-  int collID, nstreams, * streamIndexList, streamNo, nvars, varID;
-  int sumWinBufferSize = 0;
-  int nProcsColl  = commInqNProcsColl ();
-  int rankGlob    = commInqRankGlob ();
-  int root = commInqRootGlob ();
-  struct collDesc *collIndex;
-
-  xdebug("%s", "START");
-  xassert(txWin != NULL);
-
-  nstreams = reshCountType ( &streamOps );
-  streamIndexList = xmalloc ( nstreams * sizeof ( streamIndexList[0] ));
-  collIndex = xcalloc(nProcsColl, sizeof (collIndex[0]));
-  reshGetResHListOfType ( nstreams, streamIndexList, &streamOps );
-  for ( streamNo = 0; streamNo < nstreams; streamNo++ )
-    {
-      // memory required for data
-      int streamID = streamIndexList[streamNo];
-      int vlistID = streamInqVlist(streamID);
-      nvars = vlistNvars ( vlistID );
-      for ( varID = 0; varID < nvars; varID++ )
-        {
-          int collID = commRankGlob2CollID(vlistInqVarIOrank(vlistID, varID));
-          int collIDchunk;
-          {
-            int varSize = vlistInqVarSize(vlistID, varID);
-            int nProcsModel = commInqNProcsModel();
-            collIDchunk = (int)ceilf(cdiPIOpartInflate_
-                                     * (varSize + nProcsModel - 1)/nProcsModel);
-          }
-          xassert ( collID != CDI_UNDEFID && collIDchunk > 0 );
-          collIndex[collID].numDataRecords += 2;
-          txWin[collID].size += (size_t)collIDchunk * sizeof (double)
-            /* re-align chunks to multiple of double size */
-            + sizeof (double) - 1
-            /* one header for data record, one for corresponding part
-             * descriptor*/
-            + 2 * sizeof (union winHeaderEntry)
-            /* FIXME: heuristic for size of packed Xt_idxlist */
-            + sizeof (Xt_int) * collIDchunk * 3;
-        }
-
-      // memory required for the function calls encoded
-      // for remote execution
-      // once per stream and timestep for all collprocs only on the modelproc root
-      if ( rankGlob == root )
-        for ( collID = 0; collID < nProcsColl; collID++ )
-          {
-            collIndex[collID].numRPCRecords += numRPCFuncs;
-            txWin[collID].size +=
-              numRPCFuncs * sizeof (union winHeaderEntry)
-              + MAXDATAFILENAME
-              /* data part of streamDefTimestep */
-              + (2 * CDI_MAX_NAME + sizeof (taxis_t));
-          }
-    }
-  for (collID = 0; collID < nProcsColl; ++collID)
-    {
-      int numRecords = 1 + collIndex[collID].numDataRecords
-        + collIndex[collID].numRPCRecords;
-      txWin[collID].dictSize = numRecords;
-      txWin[collID].dictDataUsed = 1;
-      txWin[collID].dictRPCUsed = 0;
-      /* account for size header */
-      txWin[collID].size += sizeof (union winHeaderEntry);
-      txWin[collID].size = roundUpToMultiple(txWin[collID].size,
-                                             PIO_WIN_ALIGN);
-      sumWinBufferSize += txWin[collID].size;
-    }
-  free(collIndex);
-  free ( streamIndexList );
-
-  xdebug("sumWinBufferSize=%zu, MAXWINBUFFERSIZE=%zu", (size_t)sumWinBufferSize,
-         (size_t)MAXWINBUFFERSIZE);
-  xassert ( sumWinBufferSize <= MAXWINBUFFERSIZE );
-  xdebug("%s", "RETURN");
-}
-
-
-/************************************************************************/
-
-
-static
-  void modelWinFlushBuffer ( int collID )
-{
-  int nProcsColl = commInqNProcsColl ();
-
-  xassert ( collID                >= 0         &&
-            collID                < nProcsColl &&
-            txWin[collID].buffer     != NULL      &&
-            txWin != NULL      &&
-            txWin[collID].size >= 0         &&
-            txWin[collID].size <= MAXWINBUFFERSIZE);
-  memset(txWin[collID].buffer, 0, txWin[collID].size);
-  txWin[collID].head = txWin[collID].buffer
-    + txWin[collID].dictSize * sizeof (union winHeaderEntry);
-  txWin[collID].refuseFuncCall = 0;
-  txWin[collID].dictDataUsed = 1;
-  txWin[collID].dictRPCUsed = 0;
-}
-
-
-/************************************************************************/
-
-
-static
-void modelWinCreate ( void )
-{
-  int collID, ranks[1];
-  int nProcsColl = commInqNProcsColl ();
-
-  xdebug("%s", "START");
-  txWin = xmalloc(nProcsColl * sizeof (txWin[0]));
-
-  modelWinDefBufferSizes ();
-  ranks[0] = commInqNProcsModel ();
-
-  for ( collID = 0; collID < nProcsColl; collID ++ )
-    {
-      xassert(txWin[collID].size > 0);
-      txWin[collID].buffer = NULL;
-      xmpi(MPI_Alloc_mem((MPI_Aint)txWin[collID].size, MPI_INFO_NULL,
-                         &txWin[collID].buffer));
-      xassert ( txWin[collID].buffer != NULL );
-      txWin[collID].head = txWin[collID].buffer
-        + txWin[collID].dictSize * sizeof (union winHeaderEntry);
-      xmpi(MPI_Win_create(txWin[collID].buffer, (MPI_Aint)txWin[collID].size, 1,
-                          MPI_INFO_NULL, commInqCommsIO(collID),
-                          &txWin[collID].win));
-      xmpi(MPI_Comm_group(commInqCommsIO(collID), &txWin[collID].ioGroup));
-      xmpi(MPI_Group_incl(txWin[collID].ioGroup, 1, ranks,
-                          &txWin[collID].ioGroup ));
-    }
-  xdebug("%s", "RETURN, CREATED MPI_WIN'S");
-}
-
-/************************************************************************/
-
-static void
-modelWinEnqueue(int collID,
-                union winHeaderEntry header, const void *data, size_t size)
-{
-  union winHeaderEntry *winDict
-    = (union winHeaderEntry *)txWin[collID].buffer;
-  int targetEntry;
-  if (header.dataRecord.streamID > 0)
-    {
-      targetEntry = (txWin[collID].dictDataUsed)++;
-      int offset = header.dataRecord.offset
-        = (int)roundUpToMultiple(txWin[collID].head - txWin[collID].buffer,
-                                 sizeof (double));
-      memcpy(txWin[collID].buffer + offset, data, size);
-      txWin[collID].head = txWin[collID].buffer + offset + size;
-    }
-  else if (header.partDesc.partDescMarker == PARTDESCMARKER)
-    {
-      targetEntry = (txWin[collID].dictDataUsed)++;
-      Xt_uid uid = header.partDesc.uid;
-      int offset = -1;
-      /* search if same uid entry has already been enqueued */
-      for (int entry = 2; entry < targetEntry; entry += 2)
-        {
-          xassert(winDict[entry].partDesc.partDescMarker
-                  == PARTDESCMARKER);
-          if (winDict[entry].partDesc.uid == uid)
-            {
-              offset = winDict[entry].partDesc.offset;
-              break;
-            }
-        }
-      if (offset == -1)
-        {
-          /* not yet used partition descriptor, serialize at
-           * current position */
-          int position = 0;
-          MPI_Comm comm = commInqCommsIO(collID);
-          header.partDesc.offset
-            = (int)(txWin[collID].head - txWin[collID].buffer);
-          size_t size = xt_idxlist_get_pack_size((Xt_idxlist)data, comm);
-          size_t remaining_size = txWin[collID].size
-            - (txWin[collID].head - txWin[collID].buffer);
-          xassert(size <= remaining_size);
-          xt_idxlist_pack((Xt_idxlist)data, txWin[collID].head,
-                          (int)remaining_size, &position, comm);
-          txWin[collID].head += position;
-        }
-      else
-        /* duplicate entries are copied only once per timestep */
-        header.partDesc.offset = offset;
-    }
-  else
-    {
-      targetEntry = txWin[collID].dictSize - ++(txWin[collID].dictRPCUsed);
-      if (header.funcCall.funcID == STREAMOPEN)
-        {
-          header.funcCall.funcArgs.newFile.offset
-            = (int)(txWin[collID].head - txWin[collID].buffer);
-          memcpy(txWin[collID].head, data, size);
-          txWin[collID].head += size;
-        }
-      else if (header.funcCall.funcID == STREAMDEFTIMESTEP)
-        {
-          header.funcCall.funcArgs.streamNewTimestep.offset
-            = (int)(txWin[collID].head - txWin[collID].buffer);
-          memcpy(txWin[collID].head, data, size);
-          txWin[collID].head += size;
-        }
-    }
-  winDict[targetEntry] = header;
-}
-
-void
-pioBufferPartData(int streamID, int varID, const double *data,
-                  int nmiss, Xt_idxlist partDesc)
-{
-  int vlistID, collID = CDI_UNDEFID;
-
-  vlistID  = streamInqVlist ( streamID );
-  collID   = commRankGlob2CollID ( vlistInqVarIOrank ( vlistID, varID ));
-  xassert ( collID         >= 0                    &&
-            collID         <  commInqNProcsColl () &&
-            txWin != NULL);
-
-  if (txWin[collID].postSet)
-    {
-      xmpi(MPI_Win_wait(txWin[collID].win));
-      txWin[collID].postSet = 0;
-      modelWinFlushBuffer ( collID );
-    }
-
-  Xt_int chunk = xt_idxlist_get_num_indices(partDesc);
-  xassert(chunk <= INT_MAX);
-
-  union winHeaderEntry dataHeader
-    = { .dataRecord = { streamID, varID, -1, nmiss } };
-  modelWinEnqueue(collID, dataHeader, data, chunk * sizeof (data[0]));
-  {
-    union winHeaderEntry partHeader
-      = { .partDesc = { .partDescMarker = PARTDESCMARKER,
-                        .uid = xt_idxlist_get_uid(partDesc),
-                        .offset = 0 } };
-    modelWinEnqueue(collID, partHeader, partDesc, 0);
-  }
-
-  txWin[collID].refuseFuncCall = 1;
-}
-
-/************************************************************************/
-
-void pioBufferFuncCall(union winHeaderEntry header,
-                       const void *data, size_t data_len)
-{
-  int rankGlob = commInqRankGlob ();
-  int root = commInqRootGlob ();
-  int collID, nProcsColl = commInqNProcsColl ();
-  int funcID = header.funcCall.funcID;
-
-  xassert(funcID >= MINFUNCID && funcID <= MAXFUNCID);
-  xdebug("%s, func: %s", "START", funcMap[(-1 - funcID)]);
-
-  if ( rankGlob != root ) return;
-
-  xassert(txWin != NULL);
-
-  for (collID = 0; collID < nProcsColl; ++collID)
-    {
-      if (txWin[collID].postSet)
-        {
-          xmpi(MPI_Win_wait(txWin[collID].win));
-          txWin[collID].postSet = 0;
-          modelWinFlushBuffer ( collID );
-        }
-      xassert(txWin[collID].dictRPCUsed + txWin[collID].dictDataUsed
-              < txWin[collID].dictSize);
-      xassert(txWin[collID].refuseFuncCall == 0);
-      modelWinEnqueue(collID, header, data, data_len);
-    }
-
-  xdebug("%s", "RETURN");
-}
-
-#endif
-
-/*****************************************************************************/
-
-/* pioInit definition must currently compile even in non-MPI configurations */
-#ifndef MPI_VERSION
-#  define MPI_Comm int
-#endif
-/**
-   @brief initializes the MPI_Communicators needed for the
-  communication between the calculator PEs and the I/O PEs and within the
-  group of I/O PEs.
-
-  commGlob: all PEs
-
-  commPIO: I/O PEs, PEs with highest ranks in commGlob
-
-  commModel: calculating PEs, no I/O PEs
-
-  commsIO[i]:
-
-  Collective call
-
-  @param comm MPI_Communicator of all calling PEs
-  @param nIOP number of I/O PEs
-  @param partInflate allow for array partitions on comute
-  PE that are at most sized \f$ partInflate * \lceil arraySize /
-  numComputePEs \rceil \f$
-  @return int indicating wether the calling PE is a calcutator (1) or not (0)
-*/
-
-#ifdef USE_MPI
-static int pioNamespace_ = -1;
-static int xtInitByCDI = 0;
-#endif
-
-MPI_Comm
-pioInit(MPI_Comm commGlob, int nProcsIO, int IOMode,
-        int *pioNamespace, float partInflate)
-{
-#ifdef USE_MPI
-  int sizeGlob;
-
-  if ( IOMode < PIO_MINIOMODE || IOMode > PIO_MAXIOMODE )
-    xabort ( "IOMODE IS NOT VALID." );
-
-#ifdef _SX
-  if ( IOMode ==  PIO_ASYNCH )
-    xabort ( "PIO_ASYNCH DOES NOT WORK ON SX." );
-#endif
-
-  if ((xtInitByCDI = (!xt_initialized() || xt_finalized())))
-    {
-      xt_initialize(commGlob);
-    }
-  commInit ();
-  commDefCommGlob ( commGlob );
-  sizeGlob = commInqSizeGlob ();
-
-  if (((IOMode != PIO_NONE && (nProcsIO <= 0 || nProcsIO > sizeGlob - 1)))
-      || (IOMode == PIO_NONE && nProcsIO != 1))
-    xabort("DISTRIBUTION OF TASKS ON PROCS IS NOT VALID.\n"
-           "nProcsIO=%d, sizeGlob=%d\n", nProcsIO, sizeGlob);
-
-  commDefNProcsIO ( nProcsIO );
-  commDefIOMode   ( IOMode, PIO_MAXIOMODE, PIO_MINIOMODEWITHSPECIALPROCS );
-  commDefCommPio  ();
-
-  xassert(partInflate >= 1.0);
-  cdiPIOpartInflate_ = partInflate;
-
-  // JUST FOR TEST CASES WITH ONLY ONE MPI TASK
-  if ( commInqSizeGlob () == 1 )
-    {
-      pioNamespace_ = *pioNamespace = namespaceNew();
-      return commInqCommGlob ();
-    }
-
-  if ( commInqIsProcIO ())
-    {
-      serializeSetMPI();
-      namespaceSwitchSet(NSSWITCH_ABORT, NSSW_FUNC(cdiAbortC_MPI));
-      namespaceSwitchSet(NSSWITCH_FILE_OPEN, NSSW_FUNC(pioFileOpen));
-      namespaceSwitchSet(NSSWITCH_FILE_CLOSE, NSSW_FUNC(pioFileClose));
-      IOServer ();
-      namespaceDelete(0);
-      commDestroy ();
-      xt_finalize();
-      MPI_Finalize ();
-      exit ( EXIT_SUCCESS );
-    }
-  else
-    cdiPioClientSetup(&pioNamespace_, pioNamespace);
-
-  xdebug ( "nProcsGlob=%d, RETURN", sizeGlob );
-  return commInqCommModel ();
-#else
-  abort();
-#endif
-}
-
-#ifndef MPI_VERSION
-#  undef MPI_Comm
-#endif
-
-/*****************************************************************************/
-
-void  pioEndDef ( void )
-{
-#ifdef USE_MPI
-  char   * buffer;
-  int bufferSize;
-  int rankGlob = commInqRankGlob ();
-
-  xdebug("%s", "START");
-
-  varsMapNDeco ( commInqNNodes (), commInqNodeSizes ());
-
-  if ( rankGlob < commInqNProcsColl ())
-    {
-      MPI_Comm comm = commInqCommsIO ( rankGlob );
-      reshPackBufferCreate(&buffer, &bufferSize, &comm);
-
-      xmpi ( MPI_Send ( buffer, bufferSize, MPI_PACKED, commInqNProcsModel (),
-                        RESOURCES, commInqCommsIO ( rankGlob )));
-
-      xdebug("%s", "SENT MESSAGE WITH TAG \"RESOURCES\"");
-
-      reshPackBufferDestroy ( &buffer );
-    }
-
-  modelWinCreate ();
-  namespaceDefResStatus ( STAGE_TIMELOOP );
-  xdebug("%s", "RETURN");
-#endif
-}
-
-/************************************************************************/
-
-void  pioEndTimestepping ( void )
-{
-#ifdef USE_MPI
-  xdebug("%s", "START");
-  namespaceDefResStatus ( STAGE_CLEANUP );
-  xdebug("%s", "RETURN");
-#endif
-}
-
-
-/****************************************************/
-
-
-/**
-  @brief is invoked by the calculator PEs, to inform
-  the I/O PEs that no more data will be written.
-
-  @param
-
-  @return
-*/
-
-void pioFinalize ( void )
-{
-#ifdef USE_MPI
-  int collID, ibuffer = 1111;
-  xdebug("%s", "START");
-  namespaceDelete(pioNamespace_);
-  for ( collID = 0; collID < commInqNProcsColl (); collID++ )
-    {
-      xmpi ( MPI_Send ( &ibuffer, 1, MPI_INT, commInqNProcsModel (),
-                        FINALIZE, commInqCommsIO ( collID )));
-      xdebug("%s", "SENT MESSAGE WITH TAG \"FINALIZE\"");
-    }
-  modelWinCleanup ();
-  commDestroy ();
-  if (xtInitByCDI)
-    xt_finalize();
-  xdebug("%s", "RETURN");
-#endif
-}
-
- /************************************************************************/
-
-void pioWriteTimestep()
-{
-#ifdef USE_MPI
-  int collID, iAssert = 0;
-  /* int tokenEnd = END; */
-  int rankGlob = commInqRankGlob ();
-  int nProcsColl = commInqNProcsColl ();
-  int nProcsModel = commInqNProcsModel ();
-
-  xdebug("%s", "START");
-
-  xassert(txWin != NULL);
-
-  if ( rankGlob < nProcsColl )
-    {
-      xmpi(MPI_Send(NULL, 0, MPI_INT, nProcsModel,
-                    WRITETS, commInqCommsIO(rankGlob)));
-      xdebug("%s", "SENT MESSAGE WITH TAG \"WRITETS\"");
-    }
-
-  for ( collID = 0; collID < nProcsColl; collID++ )
-    {
-      if (txWin[collID].postSet)
-        {
-          xmpi(MPI_Win_wait(txWin[collID].win));
-          txWin[collID].postSet = 0;
-          modelWinFlushBuffer ( collID );
-        }
-      union winHeaderEntry header
-        = { .headerSize = { .sizeID = HEADERSIZEMARKER,
-                            .numDataEntries = txWin[collID].dictDataUsed,
-                            .numRPCEntries = txWin[collID].dictRPCUsed } };
-      union winHeaderEntry *winDict
-        = (union winHeaderEntry *)txWin[collID].buffer;
-      winDict[0] = header;
-
-      xmpi(MPI_Win_post(txWin[collID].ioGroup, iAssert, txWin[collID].win));
-      txWin[collID].postSet = 1;
-    }
-
-  xdebug("%s", "RETURN. messages sent, windows posted");
-
-#endif
-}
-
-#if defined USE_MPI
-void
-streamWriteVarPart(int streamID, int varID, const void *data,
-                   int nmiss, Xt_idxlist partDesc)
-{
-  if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
-
-  check_parg(data);
-
-  void (*myStreamWriteVarPart)(int streamID, int varID, const void *data,
-                               int nmiss, Xt_idxlist partDesc)
-    = (void (*)(int, int, const void *, int, Xt_idxlist))
-    namespaceSwitchGet(NSSWITCH_STREAM_WRITE_VAR_PART_).func;
-
-  if (!myStreamWriteVarPart)
-    xabort("local part writing is unsupported!");
-
-  myStreamWriteVarPart(streamID, varID, data, nmiss, partDesc);
-}
-#endif
-
-
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
-#endif
-
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-
-#ifdef USE_MPI
-
-bool localDebug    =false;
-
-
-int dbuffer_init ( struct dBuffer **dbuffer, size_t size )
-{
-  struct dBuffer *db;
-  int status;
-  size_t pagesize;
-
-
-#ifndef _SX
-  pagesize = ( size_t ) sysconf ( _SC_PAGESIZE );
-
-  if ( localDebug ) 
-    fprintf ( stdout, "dbuffer_init(): pagesize = %zu bytes, size = %zu \n", pagesize, size );
-
-  if ( dbuffer == NULL || size < pagesize )
-    {
-
-      fprintf ( stdout, "dbuffer_init: dbuffer=NULL\n" );
-      return 1;
-    }
-  db = ( struct dBuffer * ) malloc ( sizeof ( struct dBuffer ));
-
-  if ( db == NULL )
-    {
-      perror ( "Not enough memory" );
-      return 1;
-    }
-  
-  db->size = pagesize;
-  while ( db->size < size )
-    {
-      db->size <<= 1;
-      if ( localDebug ) 
-	fprintf ( stdout,"size correction: %zu\n", db->size );
-    }
-  
-  db->wr_pointer = 0;
-
-  if ( ( status = posix_memalign ( ( void ** ) &db->buffer, pagesize, 
-				   sizeof ( char ) * ( db->size ))) != 0 ) 
-    {
-      switch ( status )
-	{
-	case EINVAL:
-	  fprintf ( stderr, 
-		    "The alignment argument was not a power of two, or was not a multiple of sizeof(void *).\n" );
-	  break;
-	case ENOMEM:
-	  fprintf ( stderr, 
-		    "There was insufficient memory to fulfill the allocation request.\n" );
-	  break;
-	}
-    }
-#else
-
-  if ( dbuffer == NULL )
-    {
-      fprintf ( stdout, "dbuffer_init: dbuffer=NULL\n" );
-      return 1;
-    }
-
-  db = ( struct dBuffer * ) malloc ( sizeof ( struct dBuffer ));
-  
-  if ( db == NULL )
-    {
-      perror ( "Not enough memory" );
-      return 1;
-    }
-  
-  db->size = size;
-  
-  db->wr_pointer = 0;
-
-  db->buffer = ( unsigned char * ) malloc ( sizeof ( unsigned char ) * ( db->size ));
-  if ( db->buffer == NULL )
-  {
-      perror ( "Not enough memory" );
-      return 1 ;
-  }
-#endif
-
-  *dbuffer = db;
-  
-  return 0;
-}
-
-void dbuffer_cleanup ( struct dBuffer **dbuffer )
-{
-  struct dBuffer *db;
-
-  db = *dbuffer;
-
-  free ( db->buffer );
-  free ( db );
-
-  return;
-}
-
-size_t dbuffer_data_size ( struct dBuffer *dbuffer )
-{
-  size_t data_size;
-
-  data_size = ( size_t )( dbuffer->wr_pointer & ( dbuffer->size-1 ));
-
-  return data_size;
-}
-
-static size_t
-dbuffer_freesize(struct dBuffer *dbuffer)
-{
-  size_t free_size;
-
-  free_size = ( size_t )( dbuffer->size - 1 - dbuffer_data_size ( dbuffer ));
-
-  return free_size;
-}
-
-int dbuffer_reset ( struct dBuffer *dbuffer )
-{
-  dbuffer->wr_pointer = 0;
-  
-  return 0;
-}
-
-int
-dbuffer_push(struct dBuffer *dbuffer, const void *buffer, size_t len)
-{
-  size_t space_left;
-  size_t wr_ptr;
-
-  space_left = dbuffer_freesize(dbuffer);
-  if ( len > space_left )
-    {
-      return 1; /* not enough space left */
-    }
-  
-  wr_ptr = dbuffer->wr_pointer;
-  memcpy ( dbuffer->buffer + wr_ptr, buffer, len );
-  dbuffer->wr_pointer = wr_ptr + len;
-
-  return 0;
-}
-
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
-#endif
-
-#ifdef USE_MPI
-
-#include <inttypes.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <mpi.h>
-
-
-extern char * command2charP[6];
-
-extern long initial_buffersize;
-
-extern double accumWait;
-
-typedef struct
-{
-  size_t size;
-  struct dBuffer *db1;
-  struct dBuffer *db2;
-  struct dBuffer *db;
-  MPI_File fh;
-  MPI_Request request;
-  int fileID;
-  int tsID;
-  bool finished;
-  char name[];
-} aFiledataM;
-
-static listSet *bibAFiledataM;
-
-static int
-fileIDTest(void *a, void *fileID)
-{
-  return ((aFiledataM *)a)->fileID == (int)(intptr_t)fileID;
-}
-
-
-/***************************************************************/
-
-static aFiledataM *initAFiledataMPINONB ( const char *filename, size_t bs )
-{
-  aFiledataM *of = NULL;
-  int iret;
-  MPI_Comm commNode = commInqCommNode ();
-
-  of = xmalloc(sizeof (*of) + strlen(filename) + 1);
-
-  strcpy(of->name, filename);
-  of->size = bs;
-  of->db1 = NULL;
-  of->db2 = NULL;
-
-  /* init output buffer */
-   
-  iret = dbuffer_init ( &( of->db1 ), of->size );
-  iret += dbuffer_init ( &( of->db2 ), of->size );
-
-  if ( iret > 0 ) xabort ( "dbuffer_init did not succeed" );
-
-  of->db = of->db1;
-
-  of->tsID = CDI_UNDEFID;
-
-  /* open file */
-  xmpi(MPI_File_open(commNode, of->name, MPI_MODE_CREATE|MPI_MODE_WRONLY,
-                     MPI_INFO_NULL, &( of->fh )));
-  of->request = MPI_REQUEST_NULL;
-  of->finished = false;
-  
-  return of;
-}
-
-/***************************************************************/
-
-int destroyAFiledataMPINONB ( void *v )
-{
-  int iret = 0;
-  aFiledataM *of;
-  MPI_Status status;
-  int rankNode = commInqRankNode ();
-  double startTime;
-  MPI_Offset endpos;
-
-  of = (aFiledataM * ) v;
-
-  xdebug ( "IOPE%d: close file %d, name=\"%s\"",
-           rankNode, of->fileID, of->name );
-  
-  /* close file */
-
-  startTime = MPI_Wtime ();
-  xmpi ( MPI_Wait ( & ( of->request ), &status )); 
-  xmpi(MPI_Barrier(commInqCommNode()));
-  accumWait += ( MPI_Wtime () - startTime );
-  xmpi(MPI_File_get_position_shared(of->fh, &endpos));
-  xmpi(MPI_File_set_size(of->fh, endpos));
-  iret = MPI_File_close ( & ( of->fh ));
-
-  /* file closed, cleanup */
-  
-  dbuffer_cleanup ( & ( of->db1 ));
-  dbuffer_cleanup ( & ( of->db2 ));
-
-  free ( of );
-
-  xdebug ( "IOPE%d: closed file, cleaned up, return", 
-           rankNode );
-
-  return iret == MPI_SUCCESS ? 0 : -1;
-}
-
-/***************************************************************/
-
-static bool
-compareNamesMPINONB(void *v1, void *v2)
-{
-  aFiledataM *afm1 = v1, *afm2 = v2;
-  return !strcmp(afm1->name, afm2->name);
-}
-
-/***************************************************************/
-
-void writeMPINONB(aFiledataM *of)
-{
-  int amount;
-  MPI_Status status;
-  int rankNode = commInqRankNode ();
-  int fileID = of->fileID;
-
-  /* write buffer */
-  
-  amount = ( int ) dbuffer_data_size ( of->db );
-
-  if ( amount == 0 ) return;
-
-  xdebug3 ( "IOPI%d: Write buffer, size %d bytes, in", 
-           rankNode, amount );
-  
-  xmpi ( MPI_Wait ( & ( of->request ), &status ));
-  xmpi ( MPI_File_iwrite_shared ( of->fh, of->db->buffer, amount, MPI_CHAR, 
-                                  & ( of->request )));
-  xdebug ( "%d bytes written for fileID=%d", amount, fileID );
-
-  /* change outputBuffer */
-  
-  dbuffer_reset ( of->db );
-  
-  if ( of->db == of->db1 )
-    {
-        xdebug3 ( "IOPE%d: fileID=%d, change to buffer 2 ...", 
-                 rankNode, fileID );
-      of->db =  of->db2;
-    }
-  else 
-    {
-        xdebug3 ( "IOPE%d: fileID=%d, change to buffer 1 ...", 
-		  rankNode, fileID );
-      of->db =  of->db1;
-    }
-
-  return;
-}
-
-/***************************************************************/
-
-size_t fwMPINONB ( int fileID, int tsID, const void *buffer, size_t len )
-{  
-  int error = 0;
-  int filled = 0;
-  aFiledataM *of;
-  int rankNode = commInqRankNode ();
-
-  of = listSetGet(bibAFiledataM, fileIDTest, (void *)(intptr_t)fileID);
-  xassert(of);
-
-  bool flush = tsID != of->tsID;
-
-  if (flush)
-    {
-      xdebug3("IOPE%d: tsID = %d, flush buffer", rankNode, tsID);
-      writeMPINONB(of);
-      of->tsID = tsID;
-      MPI_Status status;
-      xmpi(MPI_Wait(&(of->request), &status));
-      xmpi(MPI_Barrier(commInqCommNode()));
-    }
-
-  filled = dbuffer_push ( of->db, ( unsigned char * ) buffer, len );
-
-  xdebug3 ( "IOPE%d: fileID = %d, tsID = %d,"
-           " pushed data on buffer, filled = %d", 
-           rankNode, fileID, tsID, filled ); 
-
-  if ( filled == 1 ) 
-    {
-      if ( flush )
-	error = filled;
-      else
-	{
-	  writeMPINONB(of);
-     
-	  error = dbuffer_push ( of->db, ( unsigned char * ) buffer, len );
-	}
-    }
-  
-  if ( error == 1 )
-    xabort("did not succeed filling output buffer, fileID=%d", fileID);
-
-  return len;
-}
-
-/***************************************************************/
-
-int fcMPINONB ( int fileID )
-{
-  aFiledataM *of;
-  int iret;
-  double accumWaitMax;
-  MPI_Comm commNode = commInqCommNode ();
-  int rankNode = commInqRankNode ();
-
-  xdebug("IOPE%d: write buffer, close file and cleanup, in %d",
-         rankNode, fileID );
-
-  if (!(of = listSetGet(bibAFiledataM, fileIDTest, (void *)(intptr_t)fileID)))
-    xabort("listSet, fileID=%d not found", fileID);
-
-  writeMPINONB(of);
-
-  /* remove file element */
-  iret = listSetRemove(bibAFiledataM, fileIDTest, (void *)(intptr_t)fileID);
-
-  /* timer output */
-
-  if ( ddebug == MAXDEBUG )
-    {
-      xmpi ( MPI_Reduce ( &accumWait, &accumWaitMax, 
-                          1, MPI_DOUBLE, MPI_MAX, 0, commNode  ));
-      xdebug ( "IOPE%d: Wait time %15.10lf s",
-               rankNode, accumWait );
-      if ( rankNode == 0 )
-          xdebug ( "IOPE%d: Max wait time %15.10lf s",
-                   rankNode, accumWaitMax );
-    }
-
-  return iret;
-}
-
-/***************************************************************/
-static void
-elemCheck(void *q, void *nm)
-{
-  aFiledataM *afm = q;
-  const char *name = nm;
-
-  if (!strcmp(name, afm->name))
-    xabort("Filename %s has already been added to set\n", name);
-}
-
-
-int fowMPINONB ( const char *filename )
-{
-  static aFiledataM *of;
-  static long buffersize = 0; 
-  int id, bcastRank = 0; 
-  MPI_Comm commNode = commInqCommNode ();
-  int rankNode = commInqRankNode ();
-
-  /* broadcast buffersize to collectors ( just once, for all files )*/
-  
-  if ( ! buffersize )
-    {
-        xdebug ( "IOPE%d: Broadcast buffersize to collectors ...", 
-		  rankNode );
-      
-      if  ( rankNode == bcastRank )
-	{ 
-	  if ( getenv( "BUFSIZE" ) != NULL )
-	    buffersize = atol ( getenv ( "BUFSIZE" ));
-	  if ( buffersize < initial_buffersize )
-	    buffersize = initial_buffersize;
-	}
-      
-      xmpi ( MPI_Bcast ( &buffersize, 1, MPI_LONG, bcastRank, commNode ));
-    }
-
-  xdebug("buffersize=%ld", buffersize);
-
-  listSetForeach(bibAFiledataM, elemCheck, (void *)filename);
-  of = initAFiledataMPINONB(filename, buffersize);
-
-  if ((id = listSetAdd(bibAFiledataM, of)) < 0 )
-    xabort("filename %s not unique", of->name);
-
-  xdebug("IOPE%d: name=%s, init and added aFiledataM, return id = %d",
-         rankNode, filename, id);
-  of->fileID = id;
-  return id;
-}
-
-/***************************************************************/
-
-void finalizeMPINONB(void)
-{
-  if (!listSetIsEmpty(bibAFiledataM))
-    xabort("set bibAFiledataM not empty");
-  else
-    {
-      xdebug("%s", "destroy set");
-      listSetDelete(bibAFiledataM);
-    }
-}
-
-/***************************************************************/
-
-void initMPINONB ( void )
-{
-  commDefCommColl ( 1 );
-  commSendNodeInfo ();
-  commRecvNodeMap ();
-  commDefCommsIO ();
-
-  bibAFiledataM = listSetNew( destroyAFiledataMPINONB, compareNamesMPINONB );
-  
-  if ( bibAFiledataM == NULL )
-    xabort ( "listSetNew did not succeed" );   
-}
-
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-/* 
-   todo  
-   README: specialRank Pe closes down, when all output files are closed    
-*/
-#ifdef HAVE_CONFIG_H
-#endif
-
-
-#ifdef USE_MPI
-#ifndef _SX
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <aio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-
-extern char * command2charP[6];
-
-extern char *token;
-
-extern double accumSuspend;
-extern double accumWrite;
-
-
-typedef struct
-{
-  struct dBuffer *fb;
-  struct aiocb *ctrlBlks;
-  off_t offset;
-  int currOpIndex;
-  int nextOpIndex;
-  int prefIndex;
-  int activeCollectors;
-  int handle, fileID;
-  char name[];
-} bFiledataPA;
-
-static int
-fileIDTest(void *a, void *fileID)
-{
-  return ((bFiledataPA *)a)->fileID == (int)(intptr_t)fileID;
-}
-
-int nPrefStreams = 4;
-
-/***************************************************************/
-
-static bFiledataPA *
-initBFiledataPA(char *filename, size_t bs, int nc)
-{
-  bFiledataPA *bfd;
-  int i;
-
-  xdebug ( "filename=%s, buffersize=%zu, ncollectors=%d, nPrefetchStreams=%d",
-           filename, bs, nc, nPrefStreams );
-
-  bfd = xmalloc( sizeof (*bfd) + strlen(filename) + 1);
-  strcpy(bfd->name, filename);
-
-  if (( bfd->handle = open ( bfd->name, O_CREAT | O_WRONLY, 0666 )) == -1 )
-    xabort("Failed to open %s", bfd->name);
-
-  dbuffer_init(&(bfd->fb), (size_t)(nPrefStreams * bs));
-
-  bfd->ctrlBlks = xcalloc(nPrefStreams, sizeof (bfd->ctrlBlks[0]));
-
-  for ( i = 0; i < nPrefStreams; i++ )
-    {
-      bfd->ctrlBlks[i].aio_fildes     = bfd->handle;
-      bfd->ctrlBlks[i].aio_buf = bfd->fb->buffer + i * bs;
-      bfd->ctrlBlks[i].aio_reqprio    = 0;
-      bfd->ctrlBlks[i].aio_sigevent.sigev_notify = SIGEV_NONE;   
-    }
-  
-  bfd->nextOpIndex = 0;
-  bfd->prefIndex = 0; 
-  bfd->offset = 0;
-  bfd->activeCollectors = nc;
-
-  xdebug ( "filename=%s, opened file, return", bfd->name );
-
-  return bfd;
-}
-
-/***************************************************************/
-
-static int
-destroyBFiledataPA ( void *v )
-{
-  bFiledataPA *bfd = (bFiledataPA * ) v;
-  const struct aiocb *ccBP[1];
-  int iret = 0;
-  ssize_t ssiret;
-  int nextFinishOp = (bfd->nextOpIndex - bfd->prefIndex + nPrefStreams)
-    % nPrefStreams;
-  double startTime;
-
-  xdebug ( "filename=%s, cleanup and close file", bfd->name );
-
-  /* close file */
-
-  for (; bfd->prefIndex > 0 ; --(bfd->prefIndex))
-    {
-      xdebug("file: %s, prefIndex=%d", bfd->name, (int)bfd->prefIndex);
-      ccBP[0] = ( bfd->ctrlBlks + nextFinishOp );
-
-      if ( ddebug )
-	startTime = MPI_Wtime ();
-
-      do
-	{
-	  iret = aio_suspend ( ccBP, 1, NULL );
-	  if ( iret < 0 && errno != EINTR ) xabort ( "aio_suspend () failed" );
-	}
-      while ( iret != 0 );
-
-      if ( ddebug )
-	accumSuspend += ( MPI_Wtime () - startTime);
-
-      iret = aio_error(bfd->ctrlBlks + nextFinishOp);
-      if (( ssiret = aio_return ( bfd->ctrlBlks + nextFinishOp )) == -1 )
-	xabort("aio_return () failed: %s", strerror(iret));
-
-      nextFinishOp = ( nextFinishOp + 1 ) % nPrefStreams;
-    }
-
-  if ((iret = ftruncate(bfd->handle, bfd->offset)) == -1)
-    xabort("failed to truncate file %s: %s", bfd->name, strerror(errno));
-  if (( iret = close ( bfd->handle )) == -1 )
-    xabort("failed to close %s", bfd->name);
-
-  /* file closed, cleanup */
-
-  dbuffer_cleanup ( &( bfd->fb ));
-
-  free(bfd->ctrlBlks);
-  free(bfd);
-
-  xdebug("%s", "closed file and cleaned up, return");
-
-  return iret;
-}
-
-/***************************************************************/
-
-static bool
-compareNamesBPA(void *v1, void *v2)
-{
-  bFiledataPA *bfd1 = v1, *bfd2 = v2;
-
-  return !strcmp(bfd1->name, bfd2->name);
-}
-
-/***************************************************************/
-
-static void
-writePA(bFiledataPA *bfd, long amount)
-{
-  const struct aiocb *ccBP[1];
-  int iret;
-  double startTime;
-
-  xdebug ( "file %s, in", bfd->name );
-  
-  bfd->ctrlBlks[bfd->currOpIndex].aio_nbytes = amount;
-  bfd->ctrlBlks[bfd->currOpIndex].aio_offset = bfd->offset;
-
-  xdebug ( " before aio_write(), file %s, aio_nbytes=%zu, aio_offset=%zu",
-           bfd->name, bfd->ctrlBlks[bfd->currOpIndex].aio_nbytes,
-           bfd->ctrlBlks[bfd->currOpIndex].aio_offset );
-
-  if ( ddebug ) startTime = MPI_Wtime ();
-
-  iret = aio_write ( bfd->ctrlBlks + bfd->currOpIndex );
-
-  if ( ddebug ) accumWrite += ( MPI_Wtime () - startTime);
-
-  xdebug ( "after aio_write(), file %s, aio_nbytes=%zu, aio_offset=%zu,"
-           "iret=aio_write()=%d",
-           bfd->name, bfd->ctrlBlks[bfd->currOpIndex].aio_nbytes,
-           bfd->ctrlBlks[bfd->currOpIndex].aio_offset, iret );
-   
-  if ( iret == -1 ) 
-    {
-      xabort ( "did not succeed writing buffer" );
-    }
-  else
-    xdebug ( "buffer written to %s",  bfd->name );
-     
-  bfd->offset += ( off_t ) amount;
-  bfd->prefIndex ++;
-
-  if ( bfd->prefIndex >= nPrefStreams ) 
-    {
-      ccBP[0] = ( bfd->ctrlBlks + bfd->nextOpIndex );
-
-      if ( ddebug )
-	startTime = MPI_Wtime ();
-
-      do
-	{
-	  iret = aio_suspend ( ccBP, 1, NULL );
-	  if ( iret < 0 && errno != EINTR )
-	    xabort ( "aio_suspend () failed" );
-	} while ( iret != 0 );
-
-      if ( ddebug )
-	accumSuspend += ( MPI_Wtime () - startTime);
-	      
-      if (( iret = aio_return ( bfd->ctrlBlks + bfd->nextOpIndex )) == -1 ) 
-	xabort ( "aio_return () failed" );
-
-      bfd->prefIndex --;
-    }
-
-  xdebug ( "filename=%s, prefIndex=%d, return", bfd->name, bfd->prefIndex );
-}
-
-/***************************************************************/
-static void
-elemCheck(void *q, void *nm)
-{
-  bFiledataPA *bfd = q;
-  const char *name = nm;
-
-  if (!strcmp(name, bfd->name))
-    xabort("Filename %s has already been inserted\n", name);
-}
-
-/***************************************************************/
-
-void pioWriterAIO(void)
-{
-  bFiledataPA *bfd; 
-  listSet * bibBFiledataPA;
-  long amount, buffersize;
-  char *messageBuffer, *pMB, *filename, *temp;
-  int messagesize, source, tag, id;
-  struct fileOpTag rtag;
-  MPI_Status status;
-  MPI_Comm commNode = commInqCommNode ();
-  int nProcsCollNode = commInqSizeNode () - commInqSizeColl ();
-  bool * sentFinalize, doFinalize;
-
-  if ( nPrefStreams < 1 ) xabort("USAGE: # PREFETCH STREAMS >= 1");
-  xdebug ( "nProcsCollNode=%d on this node", nProcsCollNode );
- 
-  bibBFiledataPA = listSetNew(destroyBFiledataPA, compareNamesBPA);
-  sentFinalize = xmalloc ( nProcsCollNode * sizeof ( sentFinalize ));
-  
-  for ( ;; )
-    {   
-      xmpiStat ( MPI_Probe ( MPI_ANY_SOURCE, MPI_ANY_TAG, commNode, 
-                             &status ), &status );
-
-      source = status.MPI_SOURCE;
-      tag    = status.MPI_TAG;
-      rtag = decodeFileOpTag(tag);
-
-      xmpi ( MPI_Get_count ( &status, MPI_CHAR, &messagesize ));
-
-      xdebug ( "receive message from source=%d, id=%d, command=%d ( %s ), "
-               "messagesize=%d", source, rtag.id, rtag.command,
-               command2charP[rtag.command], messagesize);
-
-      switch (rtag.command)
-	{
-      	case IO_Open_file:
-
-	  messageBuffer = ( char *) xmalloc ( messagesize * 
-                                              sizeof ( messageBuffer[0] ));
-	  pMB = messageBuffer;
-
-	  xmpi ( MPI_Recv ( messageBuffer, messagesize, MPI_CHAR, source, 
-                            tag, commNode, &status ));
-
-	  filename = strtok ( pMB, token );
-	  pMB += ( strlen ( filename ) + 1 );
-	  temp =  strtok ( pMB, token );
-	  buffersize =  strtol ( temp, NULL, 16 );
-	  pMB += ( strlen ( temp ) + 1 );
-	  amount = ( long ) ( messageBuffer + messagesize - pMB );
-
-	  xdebug("command  %s, filename=%s, buffersize=%ld, amount=%ld",
-                 command2charP[rtag.command], filename, buffersize, amount);
-
-          if (!(bfd = listSetGet(bibBFiledataPA, fileIDTest,
-                               (void *)(intptr_t)rtag.id)))
-	    {
-              listSetForeach(bibBFiledataPA, elemCheck, filename);
-	      bfd = initBFiledataPA(filename, buffersize, nProcsCollNode);
-              if ((id = listSetAdd(bibBFiledataPA, bfd)) < 0)
-                xabort("fileID=%d not unique", rtag.id);
-              bfd->fileID = id;
-	    }
-	  else
-	    if (strcmp(filename, bfd->name) != 0)
-              xabort("filename is not consistent, fileID=%d", rtag.id);
-
-	  bfd->currOpIndex = bfd->nextOpIndex;
-	  bfd->nextOpIndex = ( bfd->nextOpIndex + 1 ) % nPrefStreams;
-
-          xassert(amount >= 0);
-	  memcpy((void *)bfd->ctrlBlks[bfd->currOpIndex].aio_buf,
-                 pMB, (size_t)amount);
-
-	  writePA ( bfd, amount );
-
-	  free ( messageBuffer );
-
-	  break;
-
-	case IO_Send_buffer:
-
-          if (!(bfd = listSetGet(bibBFiledataPA, fileIDTest,
-                               (void *)(intptr_t)rtag.id)))
-            xabort("fileID=%d is not in set", rtag.id);
-
-	  amount = messagesize;
-
-	  xdebug("command: %s, id=%d, name=%s",
-                 command2charP[rtag.command], rtag.id, bfd->name );
-
-	  bfd->currOpIndex = bfd->nextOpIndex;
-	  bfd->nextOpIndex = ( bfd->nextOpIndex + 1 ) % nPrefStreams;
-	  
-	  xmpi(MPI_Recv((void *)bfd->ctrlBlks[bfd->currOpIndex].aio_buf,
-                        amount, MPI_CHAR, source, tag, commNode, &status ));
-
-	  writePA ( bfd, amount );
-	  
-	  break;
-
-	case IO_Close_file:
-
-          if (!(bfd = listSetGet(bibBFiledataPA, fileIDTest,
-                               (void *)(intptr_t)rtag.id)))
-            xabort("fileID=%d is not in set", rtag.id);
-
-	  amount = messagesize;
-
-	  xdebug(" command %s, id=%d, name=%s",
-                 command2charP[rtag.command], rtag.id, bfd->name);
-
-	  bfd->currOpIndex = bfd->nextOpIndex;
-
-	  bfd->nextOpIndex = ( bfd->nextOpIndex + 1 ) % nPrefStreams;
-
-	  MPI_Recv((void *)bfd->ctrlBlks[bfd->currOpIndex].aio_buf,
-                   amount, MPI_CHAR, source, tag, commNode, &status);
-
-	  writePA ( bfd, amount );
-
-	  if ( ! --(bfd->activeCollectors))
-	    {
-              xdebug ( "all are finished with file %d, delete node", rtag.id);
-              listSetRemove(bibBFiledataPA, fileIDTest,
-                            (void *)(intptr_t)rtag.id);
-	    }
-          break;
-        case IO_Finalize:
-          {
-            int buffer = CDI_UNDEFID, collID;
-
-            xmpi ( MPI_Recv ( &buffer, 1, MPI_INT, source, tag, commNode, &status ));
-            sentFinalize[source] = true;
-            doFinalize = true;
-            for ( collID = 0; collID < nProcsCollNode; collID++ )
-              if ( !sentFinalize[collID] ) 
-                {
-                  doFinalize = false;
-                  break;
-                }
-            if ( doFinalize )
-              {
-                if (!listSetIsEmpty(bibBFiledataPA))
-                  xabort("Set bibBfiledataP is not empty.");
-                else
-                  {
-                    xdebug("%s", "all files are finished, destroy set,"
-                           " return");
-                    listSetDelete(bibBFiledataPA);
-                  }
-                return;
-              }
-          }
-
-          break;
-        default:
-          xabort ( "COMMAND NOT IMPLEMENTED" );
-	}
-    }
-}
-
-
-
-/***************************************************************/
-
-/***************************************************************/
-
-
-#endif
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-/* 
-   todo 
-   build in control, for consistance of pairs filename / filenumber 
-   ( pioOpenFile member name, recv in tmpbuffer, if(!uniqueName(q,v,n))abort )
-*/
-
-#ifdef HAVE_CONFIG_H
-#endif
-
-#ifdef USE_MPI
-
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <string.h>
-
-
-
-extern char * command2charP[6];
-
-extern long initial_buffersize;
-
-typedef struct
-{
-  struct dBuffer *db1;
-  struct dBuffer *db2;
-  struct dBuffer *db;
-  FILE *fp;
-  IO_Server_command command;
-  int tsID, fileID;
-  char name[];
-} aFiledataPF;
-
-static int
-fileIDTestA(void *a, void *fileID)
-{
-  return ((aFiledataPF *)a)->fileID == (int)(intptr_t)fileID;
-}
-
-typedef struct
-{
-  long offset;
-  bool finished;
-  int fileID;
-  bool nfinished[];
-} bFiledataPF;
-
-static int
-fileIDTestB(void *a, void *fileID)
-{
-  return ((bFiledataPF *)a)->fileID == (int)(intptr_t)fileID;
-}
-
-static bool
-fileIDCmpB(void *a, void *b)
-{
-  return ((bFiledataPF *)a)->fileID == ((bFiledataPF *)b)->fileID;
-}
-
-static listSet *bibAFiledataPF;
-
-/***************************************************************/
-  
-static aFiledataPF *initAFiledataPF ( const char *key, size_t bs)
-{
-  aFiledataPF *afd;
-  size_t len;
-  int iret;
-
-  len = strlen(key);
-  afd = xcalloc(1, sizeof (*afd) + len + 1);
-  strcpy(afd->name, key);
-  afd->tsID = 0;
-
-  /* init output buffer */
-
-  xdebug ( " name=%s, init output buffer",  afd->name );
-   
-  iret = dbuffer_init(&(afd->db1), bs);
-  iret += dbuffer_init(&(afd->db2), bs);
-
-  if ( iret > 0 )
-    xabort("dbuffer_init did not succeed");
-
-  afd->db = afd->db1;
-
-  /* open file */ 
-  xdebug ( "name=%s, open file",  afd->name );
-
-  if ( ( afd->fp = fopen ( afd->name, "w" )) == NULL ) 
-    xabort("Failed to open %s", afd->name);
-
-  afd->command = IO_Open_file;
-  return afd;
-}
-
-/***************************************************************/
-static bFiledataPF *
-initBFiledataPF(int fileID, int nc)
-{
-  bFiledataPF *bfd;
-  size_t bfdSize = sizeof (bFiledataPF) + nc * sizeof (bool);
-  bfd = xcalloc(1, bfdSize);
-  bfd->offset = 0;
-  bfd->finished = false;
-  bfd->fileID = fileID;
-
-  return bfd;
-}
-
-/***************************************************************/
-
-static int
-destroyAFiledataPF(void *v)
-{
-  int iret = 0;
-  aFiledataPF *afd = ( aFiledataPF * ) v;
-
-  /* close file */
-  xdebug("name=%s, close file", afd->name);
-  if ((iret = fclose(afd->fp)) == EOF)
-    xabort("Failed to close %s", afd->name);
-
-  /* file closed, cleanup */
-  xdebug("name=%s, file closed, cleanup ...",  afd->name);
-  dbuffer_cleanup(&(afd->db1));
-  dbuffer_cleanup(&(afd->db2));
-
-  free(afd);
-
-  return iret;
-}
-
-/***************************************************************/
-
-static int
-destroyBFiledataPF(void *v)
-{
-  int iret = 0;
-  bFiledataPF *bfd = (bFiledataPF * ) v;
-  
-  free ( bfd );
-
-  return iret;
-}
-
-/***************************************************************/
-
-static bool
-compareNamesAPF(void *v1, void *v2)
-{
-  aFiledataPF *afd1 = v1, *afd2 = v2;
-
-  return !strcmp(afd1->name, afd2->name);
-}
-
-/***************************************************************/
-
-void fpgPOSIXFPGUARDSENDRECV ( void )
-{
-  int i, source, iret;
-  struct fileOpTag rtag;
-  MPI_Status status;
-  bFiledataPF *bfd; 
-  listSet *bibBFiledataPF;
-  long amount;
-  MPI_Comm commNode = commInqCommNode ();
-  int nProcsCollNode =  commInqSizeNode () - commInqSizeColl ();
-  bool * sentFinalize, doFinalize = false;
-
-  xdebug ( "ncollectors=%d on this node", nProcsCollNode );
-  
-  bibBFiledataPF = listSetNew( destroyBFiledataPF, fileIDCmpB);
-  sentFinalize = xmalloc ( nProcsCollNode * sizeof ( sentFinalize[0] ));
-
-  for ( ;; )
-    {
-      xmpi ( MPI_Probe ( MPI_ANY_SOURCE, MPI_ANY_TAG, commNode, &status ));
-      source = status.MPI_SOURCE;
-      rtag = decodeFileOpTag(status.MPI_TAG);
-      
-      xdebug("receive message from source=%d, id=%d, command=%d ( %s )",
-             source, rtag.id, rtag.command, command2charP[rtag.command]);
-      
-      switch (rtag.command)
-      	{
-      	case IO_Open_file:
-
-          if (!(bfd = listSetGet(bibBFiledataPF, fileIDTestB,
-                                 (void *)(intptr_t)rtag.id)))
-	    {
-	      bfd = initBFiledataPF(rtag.id, nProcsCollNode);
-
-	      if ((iret = listSetAdd(bibBFiledataPF, bfd)) < 0)
-		xabort("fileID=%d not unique", rtag.id);
-              bfd->fileID = iret;
-	    }
-
-          xdebug("id=%d, command=%d ( %s ), send offset=%ld", rtag.id,
-                 rtag.command, command2charP[rtag.command], bfd->offset);
-	  
-	  xmpi ( MPI_Sendrecv ( &( bfd->offset ), 1, MPI_LONG, source,  status.MPI_TAG,
-                                &amount, 1, MPI_LONG, source,  status.MPI_TAG,
-                                commNode, &status ));
-
-	  bfd->offset += amount; 
- 
-          xdebug("id=%d, command=%d ( %s ), recv amount=%ld, set offset=%ld",
-                 rtag.id, rtag.command, command2charP[rtag.command], amount,
-                 bfd->offset);
-
-	  break;
-
-	case IO_Set_fp:
-
-          if (!(bfd = listSetGet(bibBFiledataPF, fileIDTestB,
-                                 (void *)(intptr_t)rtag.id)))
-            xabort("fileId=%d not in set", rtag.id);
-
-          xdebug("id=%d, command=%d ( %s ), send offset=%ld", rtag.id,
-                 rtag.command, command2charP[rtag.command], bfd->offset);
-
-	  xmpi ( MPI_Sendrecv ( &( bfd->offset ), 1, MPI_LONG, source,  status.MPI_TAG,
-                                &amount, 1, MPI_LONG, source,  status.MPI_TAG,
-                                commNode, &status ));
-
-	  bfd->offset += amount;
-
-          xdebug("id=%d, command=%d ( %s ), recv amount=%ld, set offset=%ld",
-                 rtag.id, rtag.command, command2charP[rtag.command], amount,
-                 bfd->offset);
-
-	  break;
-
-	case IO_Close_file:
-
-          if (!(bfd = listSetGet(bibBFiledataPF, fileIDTestB,
-                               (void *)(intptr_t)rtag.id)))
-            xabort("fileId=%d not in set", rtag.id);
-
-          xdebug("id=%d, command=%d ( %s )), send offset=%ld", rtag.id,
-                 rtag.command, command2charP[rtag.command], bfd->offset);
-
-	  xmpi ( MPI_Sendrecv ( &( bfd->offset ), 1, MPI_LONG, source,  status.MPI_TAG,
-                                &amount, 1, MPI_LONG, source,  status.MPI_TAG,
-                                commNode, &status ));
-
-	  bfd->offset += amount;
-
-          xdebug("id=%d, command=%d ( %s ), recv amount=%ld, set offset=%ld",
-                 rtag.id, rtag.command, command2charP[rtag.command], amount,
-                 bfd->offset);
-
-
-	  bfd->nfinished[source] = true;  
-	  bfd->finished          = true;
-	  
-	  for ( i = 0; i < nProcsCollNode; i++ )
-	    if ( !( bfd->nfinished[i] ))
-	      {
-		bfd->finished = false;
-		break;
-	      }
-
-	  if ( bfd->finished )
-            listSetRemove(bibBFiledataPF, fileIDTestB,
-                          (void *)(intptr_t)rtag.id);
-          break;
-        case IO_Finalize:
-          {  
-            int buffer = CDI_UNDEFID, collID; 
-
-            xmpi ( MPI_Recv ( &buffer, 1, MPI_INT, source, status.MPI_TAG,
-                              commNode, &status ));
-            sentFinalize[source] = true;
-            doFinalize = true;
-            for ( collID = 0; collID < nProcsCollNode; collID++ )
-              doFinalize &= sentFinalize[collID];
-            if ( doFinalize )
-              {
-                if (!listSetIsEmpty(bibBFiledataPF))
-                  xabort("set bibBFiledataM not empty");
-                else
-                  {
-                    xdebug("%s", "destroy set");
-                    listSetDelete(bibBFiledataPF);
-                  }
-                return;
-              }
-          }
-          break;
-        default:
-          xabort ( "COMMAND NOT IMPLEMENTED" );
-	}
-    }
-}   
-
-//*******************************************************
-
-static void
-writePF(aFiledataPF *afd)
-{
-  size_t amount, written;
-  long offset;
-  long amountL;
-  int error, tag;
-  MPI_Status status;
-  int specialRank = commInqSpecialRankNode ();
-  MPI_Comm commNode = commInqCommNode ();
-  
-  /* send buffersize, recv offset */
-
-  amount = dbuffer_data_size ( afd->db );
-  amountL = ( long ) amount;
-  int id = afd->fileID;
-  tag = encodeFileOpTag(id, afd->command);
-  
-  xmpi ( MPI_Sendrecv ( &amountL, 1, MPI_LONG, specialRank, tag,
-                        &offset, 1, MPI_LONG, specialRank, tag,
-                        commNode, &status ));
-  xdebug ( "id=%d, command=%d, amount=%zu, send amountL=%ld, recv offset=%ld", 
-           id, afd->command, amount, amountL, offset );
-  
-  /* write buffer */
-  
-  if (( error = fseek ( afd->fp, offset, SEEK_SET )) != 0 )
-    xabort ( "did not succeed seeking fp" );
-
-  if (( written = 
-	fwrite ( afd->db->buffer, sizeof ( char ), amount, afd->fp )) !=
-      amount )
-    xabort("fileId=%d, expect to write %zu byte, written %zu byte",
-           id, amount, written);
- 
-  xdebug("written %zu bytes in file %d with offset %ld",
-         written, id, offset);
-  
-  /* change outputBuffer */
-  
-  dbuffer_reset ( afd->db );
-  
-  if ( afd->db == afd->db1 )
-    {
-      xdebug ( "id=%d, change to buffer 2 ...", id );
-      afd->db =  afd->db2;
-    }
-  else 
-    {
-      xdebug ( "id=%d, change to buffer 1 ...", id );
-      afd->db =  afd->db1;
-    }
-  
-  afd->command = IO_Set_fp;
-}
-
-
-/***************************************************************/
-
-static void
-defTimestepPF(aFiledataPF *afd, int tsID)
-{
-  if ( afd == NULL || tsID < 0 || tsID != afd->tsID + 1 ) 
-    xabort ( " defTimestepPF() didn't succeed." );
-  afd->tsID = tsID;
-}
-
-
-/***************************************************************/
-
-static void
-flushOp(aFiledataPF *a, int tsID)
-{
-  writePF(a);
-  defTimestepPF(a, tsID);
-}
-
-
-size_t fwPOSIXFPGUARDSENDRECV( int fileID, int tsID, const void *buffer, size_t len )
-{
-  int error = 0;
-  int filled = 0;
-  aFiledataPF *afd
-    = listSetGet(bibAFiledataPF, fileIDTestA, (void *)(intptr_t)fileID);
-
-  bool flush = tsID != afd->tsID;
-
-  if (flush)
-    {
-      xdebug("fileID %d, tsID = %d, flush buffer", fileID, tsID);
-      flushOp(afd, tsID);
-      xmpi ( MPI_Barrier ( commInqCommColl ())); 
-    }
-
-  filled = dbuffer_push(afd->db, ( unsigned char * ) buffer, len);
-
-  xdebug ( "fileID = %d, tsID = %d, pushed data on buffer, filled = %d", 
-           fileID, tsID, filled ); 
-
-  if ( filled == 1 ) 
-    {
-      if ( flush )
-	error = filled;
-      else
-	{
-	  writePF(afd);
-     
-	  error = dbuffer_push ( afd->db, ( unsigned char * ) buffer, len );
-	}
-    }
-  
-  if ( error == 1 )
-    xabort("did not succeed filling output buffer, fileID=%d", fileID);
-  
-  return len;
-}
-
-/***************************************************************/
-
-int fcPOSIXFPGUARDSENDRECV ( int id )
-{
-  aFiledataPF *afd;
-  int iret;
-
-  xdebug("write buffer, close file %d and cleanup", id);
-
-  afd = listSetGet(bibAFiledataPF, fileIDTestA, (void *)(intptr_t)id);
-
-  afd->command = IO_Close_file;
-
-  writePF(afd);
-
-  /* remove file element */
-  iret = listSetRemove(bibAFiledataPF, fileIDTestA, (void *)(intptr_t)id);
-  /* make sure the file is closed on all collectors before proceeding */
-  xmpi(MPI_Barrier(commInqCommColl()));
-  return iret;
-}
-
-/***************************************************************/
-static void
-elemCheck(void *q, void *nm)
-{
-  aFiledataPF *afd = q;
-  const char *name = nm;
-
-  if (!strcmp(name, afd->name))
-    xabort("Filename %s has already been added to set\n", name);
-}
-
-int fowPOSIXFPGUARDSENDRECV ( const char *filename )
-{
-  int root = 0, id;
-  aFiledataPF *afd;
-  static long buffersize = 0;
-
-  /* broadcast buffersize to collectors */
-  if (!buffersize)
-    {
-      if (commInqRankColl() == root)
-	{
-          xdebug("name=%s, broadcast buffersize to collectors ...",
-                 filename);
-	  if ( getenv( "BUFSIZE" ) != NULL )
-	    buffersize = atol ( getenv ( "BUFSIZE" ));
-	  if ( buffersize < initial_buffersize )
-	    buffersize = initial_buffersize;
-	}
-      xmpi(MPI_Bcast(&buffersize, 1, MPI_LONG, root, commInqCommColl()));
-    }
-
-  /* init and add file element */
-  listSetForeach(bibAFiledataPF, elemCheck, (void *)filename);
-
-  afd = initAFiledataPF ( filename, buffersize );
-
-  if ((id = listSetAdd(bibAFiledataPF, afd)) < 0)
-    xabort("filename %s not unique", afd->name);
-  afd->fileID = id;
-  xdebug("name=%s, init and add aFiledataPF, return id = %d",
-         filename, id);
-  {
-    long offset, amount = 0L;
-    int tag = encodeFileOpTag(afd->fileID, afd->command);
-    int specialRank = commInqSpecialRankNode ();
-    MPI_Status status;
-    MPI_Comm commNode = commInqCommNode ();
-    xmpi(MPI_Sendrecv(&amount, 1, MPI_LONG, specialRank, tag,
-                      &offset, 1, MPI_LONG, specialRank, tag,
-                      commNode, &status));
-  }
-  afd->command = IO_Set_fp;
-  return id;
-}
-
-/***************************************************************/
-
-void
-finalizePOSIXFPGUARDSENDRECV(void)
-{
-  int buffer = 0, tag = encodeFileOpTag(0, IO_Finalize);
-
-  xmpi(MPI_Send(&buffer, 1, MPI_INT, commInqSpecialRankNode(),
-                tag, commInqCommNode()));
-
-  if (!listSetIsEmpty(bibAFiledataPF))
-    xabort("set bibAFiledataM not empty");
-  else
-    {
-      xdebug("%s", "destroy set");
-      listSetDelete(bibAFiledataPF);
-    }
-}
-
-/***************************************************************/
-
-void initPOSIXFPGUARDSENDRECV ( void )
-{
-  if ( commInqSizeNode () < 2 ) 
-    xabort ( "USAGE: # IO PROCESSES ON A PHYSICAL NODE >= 2" );
-  
-  if ( commInqRankNode () == commInqSpecialRankNode ()) 
-    {
-      commDefCommColl ( 0 );
-      commSendNodeInfo ();
-      commRecvNodeMap ();
-      commDefCommsIO ();
-      fpgPOSIXFPGUARDSENDRECV ();
-    }
-  else
-    {
-      commDefCommColl ( 1 );
-      commSendNodeInfo ();
-      commRecvNodeMap ();
-      commDefCommsIO ();
-      bibAFiledataPF = listSetNew( destroyAFiledataPF, compareNamesAPF );
-    }
-}
-
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
-#endif
-
-#ifdef USE_MPI
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-
-extern char * command2charP[6];
-
-extern char *token;
-
-typedef struct
-{
-  struct dBuffer *fb;
-  FILE *fp;
-  int fileID;
-  int activeCollectors;
-  char name[];
-} bFiledataP;
-
-static int
-fileIDTest(void *a, void *fileID)
-{
-  return ((bFiledataP *)a)->fileID == (int)(intptr_t)fileID;
-}
-
-/***************************************************************/
-
-static bFiledataP *
-initBFiledataP(char *filename, size_t bs, int nc, int fileID)
-{
-  bFiledataP * bfp;
-
-  xdebug ( "filename=%s, buffersize=%lu, ncollectors=%d", filename, bs, nc );
-
-  bfp = xmalloc(sizeof (*bfp) + strlen(filename) + 1);
-  strcpy(bfp->name, filename);
-
-  if (( bfp->fp = fopen ( filename, "w" )) == NULL ) 
-    xabort("Failed to open %s", bfp->name);
-  int fd = fileno(bfp->fp);
-  ftruncate(fd, (off_t)0);
-  dbuffer_init(&bfp->fb, bs);
-
-  bfp->activeCollectors = nc;
-
-  bfp->fileID = fileID;
-
-  xdebug ( "filename=%s, opened file, return", bfp->name );
-
-  return bfp;
-}
-
-/***************************************************************/
-
-static int
-destroyBFiledataP(void *v)
-{
-  int iret = 0;
-  bFiledataP *bfp = ( bFiledataP * ) v;
-
-  xdebug ( "filename=%s, cleanup, in",  bfp->name );
-
-  /* close file */
-  if (( iret = fclose ( bfp->fp )) == EOF )
-    xabort("Failed to close %s", bfp->name);
-
-  /* file closed, cleanup */
-
-  dbuffer_cleanup ( &( bfp->fb ));
-
-  free(bfp);
-
-  xdebug("%s", "cleaned up, return");
-
-  return iret;
-}
-
-/***************************************************************/
-
-static bool
-compareNamesBP(void *v1, void *v2)
-{
-  bFiledataP *bfd1 = v1, *bfd2 = v2;
-
-  return !strcmp(bfd1->name, bfd2->name);
-}
-
-/***************************************************************/
-
-static void
-writeP(bFiledataP *bfd, long amount)
-{
-  long written;
-
-  xdebug ( "filename=%s, amount=%ld, in", bfd->name, amount );
-
-  if (( written = fwrite ( bfd->fb->buffer, 1, amount,
-			   bfd->fp )) != amount )
-    xabort("did not succeed writing buffer in %s", bfd->name);
-
-  xdebug ( "filename=%s, written=%ld, amount=%ld, return",
-           bfd->name, written, amount );
-}
-
-/***************************************************************/
-static void
-elemCheck(void *q, void *nm)
-{
-  bFiledataP *bfd = q;
-  const char *name = nm;
-
-  if (!strcmp(name, bfd->name))
-    xabort("Filename %s has already been added to the set\n", name);
-}
-
-void
-pioWriterStdIO(void)
-{
-  bFiledataP *bfd; 
-  listSet * bibBFiledataP;
-  size_t amount, buffersize;
-  char *messageBuffer = NULL;
-  char *pMB, *filename, *temp;
-  int messagesize, source, tag, id;
-  struct fileOpTag rtag;
-  MPI_Status status;
-  MPI_Comm commNode = commInqCommNode ();
-  int nProcsCollNode = commInqSizeNode () - commInqSizeColl ();
-  bool * sentFinalize, doFinalize;
-
-  xdebug ( "ncollectors=%d on this node", nProcsCollNode );
-
-  bibBFiledataP = listSetNew(destroyBFiledataP, compareNamesBP);
-  sentFinalize = xmalloc ( nProcsCollNode * sizeof ( sentFinalize ));
-  
-  for ( ;; )
-    {  
-        
-      xmpiStat ( MPI_Probe ( MPI_ANY_SOURCE, MPI_ANY_TAG, commNode, 
-                             &status ), &status );
-      
-      
-      source = status.MPI_SOURCE;
-      tag    = status.MPI_TAG;
-      
-      rtag = decodeFileOpTag(tag);
-      
-      xmpi ( MPI_Get_count ( &status, MPI_CHAR, &messagesize ));
-
-      xdebug ( "RECEIVE MESSAGE FROM SOURCE=%d, ID=%d, COMMAND=%d ( %s ),"
-               "MESSAGESIZE=%d", source, rtag.id, rtag.command,
-               command2charP[rtag.command], messagesize);
-
-      switch (rtag.command)
-	{
-      	case IO_Open_file:
-
-	  messageBuffer = xmalloc ( messagesize  * sizeof ( messageBuffer[0] ));
-    	  pMB = messageBuffer;
-
-	  xmpi ( MPI_Recv ( messageBuffer, messagesize, MPI_CHAR, source, 
-                            tag, commNode, &status ));
-
-	  xdebug("%s", "after recv, in loop");
-	  
-	  filename = strtok ( pMB, token );
-	  pMB += ( strlen ( filename ) + 1 );
-	  temp =  strtok ( pMB, token );
-          buffersize =  strtol ( temp, NULL, 16 );
-	  pMB += ( strlen ( temp ) + 1 );
-	  amount = (size_t)(messageBuffer + messagesize - pMB);
-	  
-	  xdebug("command %s, filename=%s, buffersize=%zu, amount=%zu",
-                 command2charP[rtag.command], filename, buffersize, amount);
-	  
-	  
-          if (!(bfd = listSetGet(bibBFiledataP, fileIDTest,
-                               (void *)(intptr_t)rtag.id)))
-	    {
-	      listSetForeach(bibBFiledataP, elemCheck, filename);
-	      bfd = initBFiledataP(filename, buffersize, nProcsCollNode,
-                                   rtag.id);
-	      
-	      if ((id = listSetAdd(bibBFiledataP, bfd)) < 0)
-                xabort("fileID=%d not unique", rtag.id);
-              bfd->fileID = id;
-	    }
-	  else
-	    if (strcmp(filename, bfd->name) != 0)
-              xabort("filename is not consistent, fileID=%d", rtag.id);
-
-	  memcpy(bfd->fb->buffer, pMB, amount);
-
-	  writeP(bfd, amount);
-	  
-	  free ( messageBuffer );
-
-	  break;
-
-	case IO_Send_buffer:
-
-          if (!(bfd = listSetGet(bibBFiledataP, fileIDTest,
-                               (void *)(intptr_t)rtag.id)))
-            xabort("fileID=%d is not in set", rtag.id );
-
-	  amount = messagesize;
-
-	  xdebug("COMMAND %s, ID=%d, NAME=%s", command2charP[rtag.command],
-                 rtag.id, bfd->name);
-	  
-	  xmpi ( MPI_Recv (  bfd->fb->buffer, amount, MPI_CHAR, source, tag, 
-                             commNode, &status ));
-
-	  writeP ( bfd, amount );
-	  
-	  break;
-
-	case IO_Close_file:
-	  
-	  xdebug("COMMAND %s,  FILE%d, SOURCE%d",
-                 command2charP[rtag.command], rtag.id, source);
-
-          if (!(bfd = listSetGet(bibBFiledataP, fileIDTest,
-                               (void *)(intptr_t)rtag.id)))
-            xabort("fileID=%d is not in set", rtag.id);
-
-          amount = messagesize;
-
-	  xdebug("COMMAND %s, ID=%d, NAME=%s, AMOUNT=%zu",
-                 command2charP[rtag.command], rtag.id, bfd->name, amount);
-	  
-	  xmpi(MPI_Recv(bfd->fb->buffer, amount, MPI_CHAR, source, tag,
-                        commNode, &status ));
-
-	  writeP ( bfd, amount );
-
-	  if ( ! --(bfd->activeCollectors))
-	    {
-	      xdebug("all are finished with file %d, delete node", rtag.id);
-	      listSetRemove(bibBFiledataP, fileIDTest,
-                            (void *)(intptr_t)rtag.id);
-	    }
-          break;
-        case IO_Finalize:
-          {
-            int buffer = CDI_UNDEFID, collID;
-
-            xmpi ( MPI_Recv ( &buffer, 1, MPI_INT, source, tag, commNode, &status ));
-            
-            sentFinalize[source] = true;
-            doFinalize = true;
-            
-            for ( collID = 0; collID < nProcsCollNode; collID++ )
-              if ( !sentFinalize[collID] ) 
-                {
-                  doFinalize = false;
-                  break;
-                }
-            
-            if ( doFinalize )
-              {
-                if (!listSetIsEmpty(bibBFiledataP))
-                  xabort("set bibBfiledataP is not empty.");
-                else
-                  {
-                    xdebug("%s", "all files are finished, destroy file set,"
-                           " return");
-                    listSetDelete(bibBFiledataP);
-                  }
-                return;
-              }
-          }
-          break;
-        default:
-          xabort ( "COMMAND NOT IMPLEMENTED" );
-	}
-    }
-}
-
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-#ifdef HAVE_CONFIG_H
-#endif
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-
-#ifdef USE_MPI
-
-struct cons
-{
-  void * val;
-  struct cons * next;
-};
-
-struct listSet {
-  struct cons *head, *tail;
-  valDestroyFunction valDestroy;
-  eqPredicate keyCompare;
-  int count;
-};
-
-listSet *listSetNew( valDestroyFunction vD, eqPredicate kC )
-{
-  listSet *myq;
-
-  myq = xmalloc ( sizeof ( listSet ));
-
-  myq->head = NULL;
-  myq->tail = NULL;
-  myq->valDestroy = vD;
-  myq->keyCompare = kC;
-  myq->count = 0;
-
-  return myq;
-}
-
-void
-listSetDelete(listSet *q)
-{
-  struct cons *curr, *succ;
-
-  if ( q->head )
-    {
-      curr = q->head;
-
-      while ( curr )
-        {
-          succ = curr->next;
-          ( *( q->valDestroy )) ( curr->val );
-          free ( curr );
-          curr = succ;
-        }
-    }
-
-  free ( q );
-
-  return;
-}
-
-int
-listSetAdd(listSet *q, void *v)
-{
-  struct cons *newCons;
-
-  {
-    struct cons *p;
-    for (p = q->head; p; p = p->next)
-      // ensure unique keys
-      if (q->keyCompare(v, p->val))
-        return -1;
-  }
-
-  if ((newCons = malloc(sizeof(struct cons))) == NULL)
-    {
-      perror ( "pio_listSet: listSetAdd (): Not enough memory" );
-      /* FIXME: why not abort? */
-      return 1;
-    }
-
-  newCons->val = v;
-  newCons->next = NULL;
-
-
-  if ( q->tail != NULL)
-    q->tail->next = newCons;
-  else
-    q->head = newCons;
-
-  q->tail = newCons;
-
-  return q->count++;
-}
-
-int
-listSetRemove(listSet *q, int (*predicate)(void *, void *),
-              void *data)
-{
-  struct cons **p;
-
-  for (p = &q->head; *p; p = &(*p)->next)
-    if (predicate((*p)->val, data))
-      {
-        struct cons *rem = *p;
-        if (rem == q->tail) q->tail = NULL;
-        int iret = q->valDestroy(rem->val);
-        *p = rem->next;
-        free(rem);
-        return iret;
-      }
-  return -1;
-}
-
-void *
-listSetGet(listSet *q, int (*predicate)(void *, void *), void *data)
-{
-  struct cons *p;
-  xassert(q && predicate);
-  for (p = q->head; p; p = p->next)
-    if (predicate(p->val, data))
-      return p->val;
-  return NULL;
-}
-
-bool
-listSetIsEmpty(listSet *q)
-{
-  return q->head == NULL;
-}
-
-
-void
-listSetForeach(listSet *q, void (*func)(void *elem, void *data), void *data)
-{
-  struct cons *p;
-  for (p = q->head; p; p = p->next)
-    func(p->val, data);
-}
-
-
-#endif
-/*
- * Local Variables:
- * c-file-style: "Java"
- * c-basic-offset: 2
- * indent-tabs-mode: nil
- * show-trailing-whitespace: t
- * require-trailing-newline: t
- * End:
- */
-   static char cdi_libvers[] = "1.6.2" " of ""Nov  8 2013"" ""15:47:50";
-char *cdiLibraryVersion(void);
-char *cdiLibraryVersion(void)
-{
-  return (cdi_libvers);
-}
-#if defined (HAVE_CF_INTERFACE)
-#undef realloc
-#undef malloc
-#undef calloc
-#undef free
-#undef DOUBLE_PRECISION
-/* cfortran.h  4.3 */
-/* http://www-zeus.desy.de/~burow/cfortran/                   */
-/* Burkhard Burow  burow at desy.de                 1990 - 2001. */
-
-/* 02/12/2002 Uwe Schulzweida : UXP Fortran support           */
-/* 02/05/2003 Uwe Schulzweida : Linux Fortran support on i386 */
-/* 09/09/2005 Uwe Schulzweida : Linux Fortran support on ia64 */
-
-#ifndef __CFORTRAN_LOADED
-#define __CFORTRAN_LOADED
-
-/* 
-   THIS FILE IS PROPERTY OF BURKHARD BUROW. IF YOU ARE USING THIS FILE YOU
-   SHOULD ALSO HAVE ACCESS TO CFORTRAN.DOC WHICH PROVIDES TERMS FOR USING,
-   MODIFYING, COPYING AND DISTRIBUTING THE CFORTRAN.H PACKAGE.
-*/
-
-/* 
-  Avoid symbols already used by compilers and system *.h:
-  __ - OSF1 zukal06 V3.0 347 alpha, cc -c -std1 cfortest.c
-
- */
-
-
-/* First prepare for the C compiler. */
-
-#ifndef ANSI_C_preprocessor /* i.e. user can override. */
-#ifdef __CF__KnR
-#define ANSI_C_preprocessor 0
-#else
-#ifdef __STDC__
-#define ANSI_C_preprocessor 1
-#else
-#define _cfleft             1
-#define _cfright 
-#define _cfleft_cfright     0
-#define ANSI_C_preprocessor _cfleft/**/_cfright
-#endif
-#endif
-#endif
-
-#if ANSI_C_preprocessor
-#define _0(A,B)   A##B
-#define  _(A,B)   _0(A,B)  /* see cat,xcat of K&R ANSI C p. 231 */
-#define _2(A,B)   A##B     /* K&R ANSI C p.230: .. identifier is not replaced */
-#define _3(A,B,C) _(A,_(B,C))
-#else                      /* if it turns up again during rescanning.         */
-#define  _(A,B)   A/**/B
-#define _2(A,B)   A/**/B
-#define _3(A,B,C) A/**/B/**/C
-#endif
-
-#if (defined(vax)&&defined(unix)) || (defined(__vax__)&&defined(__unix__))
-#define VAXUltrix
-#endif
-
-#include <stdio.h>     /* NULL [in all machines stdio.h]                      */
-#include <string.h>    /* strlen, memset, memcpy, memchr.                     */
-#if !( defined(VAXUltrix) || defined(sun) || (defined(apollo)&&!defined(__STDCPP__)) )
-#include <stdlib.h>    /* malloc,free                                         */
-#else
-#include <malloc.h>    /* Had to be removed for DomainOS h105 10.4 sys5.3 425t*/
-#ifdef apollo
-#define __CF__APOLLO67 /* __STDCPP__ is in Apollo 6.8 (i.e. ANSI) and onwards */
-#endif
-#endif
-#include <limits.h>    /* LONG_MAX */
-
-#if !defined(__GNUC__) && !defined(__sun) && (defined(sun)||defined(VAXUltrix)||defined(lynx))
-#define __CF__KnR     /* Sun, LynxOS and VAX Ultrix cc only supports K&R.     */
-                      /* Manually define __CF__KnR for HP if desired/required.*/
-#endif                /*       i.e. We will generate Kernighan and Ritchie C. */
-/* Note that you may define __CF__KnR before #include cfortran.h, in order to
-generate K&R C instead of the default ANSI C. The differences are mainly in the
-function prototypes and declarations. All machines, except the Apollo, work
-with either style. The Apollo's argument promotion rules require ANSI or use of
-the obsolete std_$call which we have not implemented here. Hence on the Apollo,
-only C calling FORTRAN subroutines will work using K&R style.*/
-
-
-/* Remainder of cfortran.h depends on the Fortran compiler. */
-
-#if defined(CLIPPERFortran) || defined(pgiFortran)
-#define f2cFortran
-#endif
-
-/* VAX/VMS does not let us \-split long #if lines. */ 
-/* Split #if into 2 because some HP-UX can't handle long #if */
-#if !(defined(NAGf90Fortran)||defined(f2cFortran)||defined(hpuxFortran)||defined(apolloFortran)||defined(sunFortran)||defined(IBMR2Fortran)||defined(CRAYFortran))
-#if !(defined(mipsFortran)||defined(DECFortran)||defined(vmsFortran)||defined(CONVEXFortran)||defined(PowerStationFortran)||defined(AbsoftUNIXFortran)||defined(AbsoftProFortran)||defined(SXFortran))
-/* If no Fortran compiler is given, we choose one for the machines we know.   */
-#if defined(__linux__) && defined(__i386__)
-#define f2cFortran
-#endif
-#if defined(__linux__) && defined(__ia64__)
-#define f2cFortran
-#endif
-#if defined(__linux__) && defined(__x86_64__)
-#define f2cFortran
-#endif
-#if defined(lynx) || defined(VAXUltrix)
-#define f2cFortran    /* Lynx:      Only support f2c at the moment.
-                         VAXUltrix: f77 behaves like f2c.
-                           Support f2c or f77 with gcc, vcc with f2c. 
-                           f77 with vcc works, missing link magic for f77 I/O.*/
-#endif
-#if defined(__hpux)             /* 921107: Use __hpux instead of __hp9000s300 */
-#define       hpuxFortran       /*         Should also allow hp9000s7/800 use.*/
-#endif
-#if       defined(apollo)
-#define           apolloFortran /* __CF__APOLLO67 also defines some behavior. */
-#endif
-#if          defined(sun) || defined(__sun) 
-#define              sunFortran
-#endif
-#if       defined(_IBMR2)
-#define            IBMR2Fortran
-#endif
-#if        defined(_CRAY)
-#define             CRAYFortran /*       _CRAYT3E also defines some behavior. */
-#endif
-#if        defined(_SX)
-#define               SXFortran
-#endif
-#if        defined(__uxp__)
-#define               UXPFortran
-#endif
-#if         defined(mips) || defined(__mips)
-#define             mipsFortran
-#endif
-#if          defined(vms) || defined(__vms)
-#define              vmsFortran
-#endif
-#if      defined(__alpha) && defined(__unix__)
-#define              DECFortran
-#endif
-#if   defined(__convex__)
-#define           CONVEXFortran
-#endif
-#if   defined(VISUAL_CPLUSPLUS)
-#define     PowerStationFortran
-#endif
-#endif /* ...Fortran */
-#endif /* ...Fortran */
-
-/* Split #if into 2 because some HP-UX can't handle long #if */
-#if !(defined(NAGf90Fortran)||defined(f2cFortran)||defined(hpuxFortran)||defined(apolloFortran)||defined(sunFortran)||defined(IBMR2Fortran)||defined(CRAYFortran))
-#if !(defined(mipsFortran)||defined(DECFortran)||defined(vmsFortran)||defined(CONVEXFortran)||defined(PowerStationFortran)||defined(AbsoftUNIXFortran)||defined(AbsoftProFortran)||defined(SXFortran)||defined(UXPFortran))
-/* If your compiler barfs on ' #error', replace # with the trigraph for #     */
- #error "cfortran.h:  Can't find your environment among:\
-    - MIPS cc and f77 2.0. (e.g. Silicon Graphics, DECstations, ...)     \
-    - IBM AIX XL C and FORTRAN Compiler/6000 Version 01.01.0000.0000     \
-    - VAX   VMS CC 3.1 and FORTRAN 5.4.                                  \
-    - Alpha VMS DEC C 1.3 and DEC FORTRAN 6.0.                           \
-    - Alpha OSF DEC C and DEC Fortran for OSF/1 AXP Version 1.2          \
-    - Apollo DomainOS 10.2 (sys5.3) with f77 10.7 and cc 6.7.            \
-    - CRAY                                                               \
-    - NEC SX-4 SUPER-UX                                                  \
-    - CONVEX                                                             \
-    - Sun                                                                \
-    - PowerStation Fortran with Visual C++                               \
-    - HP9000s300/s700/s800 Latest test with: HP-UX A.08.07 A 9000/730    \
-    - LynxOS: cc or gcc with f2c.                                        \
-    - VAXUltrix: vcc,cc or gcc with f2c. gcc or cc with f77.             \
-    -            f77 with vcc works; but missing link magic for f77 I/O. \
-    -            NO fort. None of gcc, cc or vcc generate required names.\
-    - f2c    : Use #define    f2cFortran, or cc -Df2cFortran             \
-    - NAG f90: Use #define NAGf90Fortran, or cc -DNAGf90Fortran          \
-    - Absoft UNIX F77: Use #define AbsoftUNIXFortran or cc -DAbsoftUNIXFortran \
-    - Absoft Pro Fortran: Use #define AbsoftProFortran \
-    - Portland Group Fortran: Use #define pgiFortran"
-/* Compiler must throw us out at this point! */
-#endif
-#endif
-
-
-#if defined(VAXC) && !defined(__VAXC)
-#define OLD_VAXC
-#pragma nostandard                       /* Prevent %CC-I-PARAMNOTUSED.       */
-#endif
-
-/* Throughout cfortran.h we use: UN = Uppercase Name.  LN = Lowercase Name.   */
+/* Throughout cfortran.h we use: UN = Uppercase Name.  LN = Lowercase Name.   */
 
 #if defined(f2cFortran) || defined(NAGf90Fortran) || defined(DECFortran) || defined(mipsFortran) || defined(apolloFortran) || defined(sunFortran) || defined(CONVEXFortran) || defined(SXFortran) || defined(UXPFortran) || defined(extname)
 #define CFC_(UN,LN)            _(LN,_)      /* Lowercase FORTRAN symbols.     */
@@ -66695,26 +63442,6 @@ string. */
 
 
 #endif	 /* __CFORTRAN_LOADED */
-#ifndef  _CDIFORTRAN_H
-#define  _CDIFORTRAN_H
-
-/*******************************************************************************
- * Character buffer:
- */
-
-#define CBUF_cfINT(N,A,B,X,Y,Z)		STRING_cfINT(N,A,B,X,Y,Z)
-#define CBUF_cfSEP(T,  B)		STRING_cfSEP(T,B)
-#define CBUF_cfN(  T,A)			STRING_cfN(T,A)
-#define CBUF_cfSTR(N,T,A,B,C,D,E)	STRING_cfSTR(N,T,A,B,C,D,E)
-#if defined(vmsFortran)
-#   define CBUF_cfT(M,I,A,B,D)		A->dsc$a_pointer
-#elif defined(CRAYFortran)
-#   define CBUF_cfT(M,I,A,B,D)		_fcdtocp(A)
-#else
-#   define CBUF_cfT(M,I,A,B,D)		A
-#endif
-
-#endif
 #endif
 /* Automatically generated by make_fint.c, don't edit! */
 
@@ -66722,16 +63449,7 @@ string. */
 #  include "config.h"
 #endif
 
-#if USE_MPI
-#  include <mpi.h>
-#  include <yaxt.h>
-#else
-#define MPI_Comm int
-#define MPI_Comm_f2c(c) (c)
-#define MPI_Comm_c2f(c) (c)
-#endif
-
-#if ! defined (_CDI_H)
+#if ! defined (CDI_H_)
 #  include "cdi.h"
 #endif
 
@@ -66741,10 +63459,6 @@ string. */
 #  include "cfortran.h"
 #endif
 
-#if ! defined (_CDIFORTRAN_H)
-#  include "cdiFortran.h"
-#endif
-
 
 /*  Byte order  */
 
@@ -66788,31 +63502,6 @@ string. */
 /*  CALENDAR types  */
 
 
-/*  parallel IO IOMode  */
-
-
-/*  parallel IO routines  */
-
-#ifdef MPI_VERSION /* make_fint keep */
-FCALLSCSUB0 (pioEndDef, PIOENDDEF, pioenddef)
-FCALLSCSUB0 (pioEndTimestepping, PIOENDTIMESTEPPING, pioendtimestepping)
-FCALLSCSUB0 (pioFinalize, PIOFINALIZE, piofinalize)
-static int pioInit_fwrap(int commSuper, int nProcsIO, int IOMode, int * pioNamespace, float partInflate)
-{
-  MPI_Comm v;
-  v = pioInit(MPI_Comm_f2c(commSuper),  nProcsIO,  IOMode,  pioNamespace,  partInflate);
-  return MPI_Comm_c2f(v);
-}
-FCALLSCFUN5 (INT, pioInit_fwrap, PIOINIT, pioinit, INT, INT, INT, PINT, FLOAT)
-FCALLSCSUB0 (pioWriteTimestep, PIOWRITETIMESTEP, piowritetimestep)
-static void streamWriteVarPart_fwrap(int streamID, int varID, const void * data, int nmiss, void * partDesc)
-{
-  streamWriteVarPart( streamID,  varID,  data,  nmiss, (*(Xt_idxlist *)partDesc));
-}
-FCALLSCSUB5 (streamWriteVarPart_fwrap, STREAMWRITEVARPART, streamwritevarpart, INT, INT, PVOID, INT, PVOID)
-#endif /* make_fint keep */
-FCALLSCSUB1 (pioNamespaceSetActive, PIONAMESPACESETACTIVE, pionamespacesetactive, INT)
-
 /*  CDI control routines  */
 
 FCALLSCSUB0 (cdiReset, CDIRESET, cdireset)
@@ -66824,6 +63513,9 @@ FCALLSCFUN1 (INT, cdiHaveFiletype, CDIHAVEFILETYPE, cdihavefiletype, INT)
 FCALLSCSUB1 (cdiDefMissval, CDIDEFMISSVAL, cdidefmissval, DOUBLE)
 FCALLSCFUN0 (DOUBLE, cdiInqMissval, CDIINQMISSVAL, cdiinqmissval)
 FCALLSCSUB2 (cdiDefGlobal, CDIDEFGLOBAL, cdidefglobal, STRING, INT)
+FCALLSCFUN0 (INT, namespaceNew, NAMESPACENEW, namespacenew)
+FCALLSCSUB1 (namespaceSetActive, NAMESPACESETACTIVE, namespacesetactive, INT)
+FCALLSCSUB1 (namespaceDelete, NAMESPACEDELETE, namespacedelete, INT)
 
 /*  CDI converter routines  */
 
@@ -66862,6 +63554,10 @@ FCALLSCSUB2 (streamDefCompLevel, STREAMDEFCOMPLEVEL, streamdefcomplevel, INT, IN
 FCALLSCFUN1 (INT, streamInqCompType, STREAMINQCOMPTYPE, streaminqcomptype, INT)
 FCALLSCFUN1 (INT, streamInqCompLevel, STREAMINQCOMPLEVEL, streaminqcomplevel, INT)
 FCALLSCFUN2 (INT, streamDefTimestep, STREAMDEFTIMESTEP, streamdeftimestep, INT, INT)
+
+/*  query currently set timestep id  */
+
+FCALLSCFUN1 (INT, streamInqCurTimestepID, STREAMINQCURTIMESTEPID, streaminqcurtimestepid, INT)
 FCALLSCFUN2 (INT, streamInqTimestep, STREAMINQTIMESTEP, streaminqtimestep, INT, INT)
 FCALLSCFUN1 (STRING, streamFilename, STREAMFILENAME, streamfilename, INT)
 FCALLSCFUN1 (STRING, streamFilesuffix, STREAMFILESUFFIX, streamfilesuffix, INT)
@@ -66886,7 +63582,6 @@ FCALLSCSUB3 (streamReadRecord, STREAMREADRECORD, streamreadrecord, INT, PDOUBLE,
 FCALLSCSUB3 (streamWriteRecord, STREAMWRITERECORD, streamwriterecord, INT, PDOUBLE, INT)
 FCALLSCSUB3 (streamWriteRecordF, STREAMWRITERECORDF, streamwriterecordf, INT, PFLOAT, INT)
 FCALLSCSUB2 (streamCopyRecord, STREAMCOPYRECORD, streamcopyrecord, INT, INT)
-FCALLSCSUB3 (streamInqGinfo, STREAMINQGINFO, streaminqginfo, INT, PINT, PFLOAT)
 
 /*  VLIST routines  */
 
@@ -67010,10 +63705,10 @@ FCALLSCFUN6 (INT, vlistInqAtt, VLISTINQATT, vlistinqatt, INT, INT, INT, PSTRING,
 FCALLSCFUN3 (INT, vlistDelAtt, VLISTDELATT, vlistdelatt, INT, INT, STRING)
 FCALLSCFUN6 (INT, vlistDefAttInt, VLISTDEFATTINT, vlistdefattint, INT, INT, STRING, INT, INT, PINT)
 FCALLSCFUN6 (INT, vlistDefAttFlt, VLISTDEFATTFLT, vlistdefattflt, INT, INT, STRING, INT, INT, PDOUBLE)
-FCALLSCFUN5 (INT, vlistDefAttTxt, VLISTDEFATTTXT, vlistdefatttxt, INT, INT, STRING, INT, CBUF)
+FCALLSCFUN5 (INT, vlistDefAttTxt, VLISTDEFATTTXT, vlistdefatttxt, INT, INT, STRING, INT, PPSTRING)
 FCALLSCFUN5 (INT, vlistInqAttInt, VLISTINQATTINT, vlistinqattint, INT, INT, STRING, INT, PINT)
 FCALLSCFUN5 (INT, vlistInqAttFlt, VLISTINQATTFLT, vlistinqattflt, INT, INT, STRING, INT, PDOUBLE)
-FCALLSCFUN5 (INT, vlistInqAttTxt, VLISTINQATTTXT, vlistinqatttxt, INT, INT, STRING, INT, CBUF)
+FCALLSCFUN5 (INT, vlistInqAttTxt, VLISTINQATTTXT, vlistinqatttxt, INT, INT, STRING, INT, PPSTRING)
 
 /*  GRID routines  */
 
@@ -67090,8 +63785,8 @@ FCALLSCSUB2 (gridDefPosition, GRIDDEFPOSITION, griddefposition, INT, INT)
 FCALLSCFUN1 (INT, gridInqPosition, GRIDINQPOSITION, gridinqposition, INT)
 FCALLSCSUB2 (gridDefReference, GRIDDEFREFERENCE, griddefreference, INT, STRING)
 FCALLSCFUN2 (INT, gridInqReference, GRIDINQREFERENCE, gridinqreference, INT, PSTRING)
-FCALLSCSUB2 (gridDefUUID, GRIDDEFUUID, griddefuuid, INT, CBUF)
-FCALLSCFUN2 (STRING, gridInqUUID, GRIDINQUUID, gridinquuid, INT, CBUF)
+FCALLSCSUB2 (gridDefUUID, GRIDDEFUUID, griddefuuid, INT, PPSTRING)
+FCALLSCSUB2 (gridInqUUID, GRIDINQUUID, gridinquuid, INT, PPSTRING)
 
 /*  Lambert Conformal Conic grid (GRIB version)  */
 
@@ -67140,8 +63835,8 @@ FCALLSCSUB2 (zaxisDefNlevRef, ZAXISDEFNLEVREF, zaxisdefnlevref, INT, INT)
 FCALLSCFUN1 (INT, zaxisInqNlevRef, ZAXISINQNLEVREF, zaxisinqnlevref, INT)
 FCALLSCSUB2 (zaxisDefNumber, ZAXISDEFNUMBER, zaxisdefnumber, INT, INT)
 FCALLSCFUN1 (INT, zaxisInqNumber, ZAXISINQNUMBER, zaxisinqnumber, INT)
-FCALLSCSUB2 (zaxisDefUUID, ZAXISDEFUUID, zaxisdefuuid, INT, CBUF)
-FCALLSCFUN2 (STRING, zaxisInqUUID, ZAXISINQUUID, zaxisinquuid, INT, CBUF)
+FCALLSCSUB2 (zaxisDefUUID, ZAXISDEFUUID, zaxisdefuuid, INT, PPSTRING)
+FCALLSCSUB2 (zaxisInqUUID, ZAXISINQUUID, zaxisinquuid, INT, PPSTRING)
 FCALLSCSUB2 (zaxisDefName, ZAXISDEFNAME, zaxisdefname, INT, STRING)
 FCALLSCSUB2 (zaxisDefLongname, ZAXISDEFLONGNAME, zaxisdeflongname, INT, STRING)
 FCALLSCSUB2 (zaxisDefUnits, ZAXISDEFUNITS, zaxisdefunits, INT, STRING)
diff --git a/libcdi/src/cdipio.h b/libcdi/src/cdipio.h
new file mode 100644
index 0000000..6d907ff
--- /dev/null
+++ b/libcdi/src/cdipio.h
@@ -0,0 +1,49 @@
+/*
+  CDI PIO C header file
+
+  Include this file in applications to make use of the parallel I/O interfaces
+  of CDI.
+*/
+
+#ifndef  CDIPIO_H_
+#define  CDIPIO_H_
+
+#include <mpi.h>
+
+/* parallel IO IOMode */
+
+#define  PIO_NONE                 0
+#define  PIO_MPI                  1
+#define  PIO_WRITER               2
+#define  PIO_ASYNCH               3
+#define  PIO_FPGUARD              4
+
+#define  PIO_MINIOMODE                  PIO_NONE
+#define  PIO_MAXIOMODE                  PIO_FPGUARD
+#define  PIO_MINIOMODEWITHSPECIALPROCS  PIO_WRITER
+
+/* parallel IO routines */
+#include <yaxt.h>
+
+void     pioEndDef             ( void );
+void     pioEndTimestepping    ( void );
+void     pioFinalize           ( void );
+/* Dummy function to use as argument to pioInit if no actions are
+ * ncecessary after I/O servers initialize communication */
+void cdiPioNoPostCommSetup(void);
+/*      pioInit: initialize I/O server processes and communication */
+MPI_Comm pioInit(MPI_Comm commSuper, int nProcsIO, int IOMode,
+                 int *pioNamespace, float partInflate,
+                 void (*postCommSetupActions)(void));
+void     pioWriteTimestep();
+void     cdiPioRDMAProgress();
+
+void     streamWriteVarPart    (int streamID, int varID,
+                                const void *data, int nmiss,
+                                Xt_idxlist partDesc);
+void     streamWriteScatteredVarPart(int streamID, int varID, const void *data,
+                                     int numBlocks, const int blocklengths[],
+                                     const int displacements[],
+                                     int nmiss, Xt_idxlist partDesc);
+
+#endif
diff --git a/libcdi/src/cdipio.inc b/libcdi/src/cdipio.inc
new file mode 100644
index 0000000..68be71d
--- /dev/null
+++ b/libcdi/src/cdipio.inc
@@ -0,0 +1,71 @@
+! This file was automatically generated, don't edit!
+!
+! Fortran interface for CDI library version 1.6.3
+!
+! Author:
+! -------
+! Uwe Schulzweida, MPI-MET, Hamburg,   January 2014
+!
+
+!
+!  parallel IO IOMode
+!
+      INTEGER    PIO_NONE              
+      PARAMETER (PIO_NONE               =  0)
+      INTEGER    PIO_MPI               
+      PARAMETER (PIO_MPI                =  1)
+      INTEGER    PIO_WRITER            
+      PARAMETER (PIO_WRITER             =  2)
+      INTEGER    PIO_ASYNCH            
+      PARAMETER (PIO_ASYNCH             =  3)
+      INTEGER    PIO_FPGUARD           
+      PARAMETER (PIO_FPGUARD            =  4)
+!
+!  parallel IO routines
+!
+!                     pioEndDef
+      EXTERNAL        pioEndDef
+
+!                     pioEndTimestepping
+      EXTERNAL        pioEndTimestepping
+
+!                     pioFinalize
+      EXTERNAL        pioFinalize
+
+!                     cdiPioNoPostCommSetup
+      EXTERNAL        cdiPioNoPostCommSetup
+
+      INTEGER         pioInit
+!                                    (INTEGER         commSuper,
+!                                     INTEGER         nProcsIO,
+!                                     INTEGER         IOMode,
+!                                     INTEGER         pioNamespace,
+!                                     REAL            partInflate,
+!                                     PROCEDURE       postCommSetupActions)
+      EXTERNAL        pioInit
+
+!                     pioWriteTimestep
+      EXTERNAL        pioWriteTimestep
+
+!                     cdiPioRDMAProgress
+      EXTERNAL        cdiPioRDMAProgress
+
+!                     streamWriteVarPart
+!                                    (INTEGER         streamID,
+!                                     INTEGER         varID,
+!                                     CHOICE          data,
+!                                     INTEGER         nmiss,
+!                                     TYPE(XT_IDXLIST)partDesc)
+      EXTERNAL        streamWriteVarPart
+
+!                     streamWriteScatteredVarPart
+!                                    (INTEGER         streamID,
+!                                     INTEGER         varID,
+!                                     CHOICE          data,
+!                                     INTEGER         numBlocks,
+!                                     INTEGER         blocklengths,
+!                                     INTEGER         displacements,
+!                                     INTEGER         nmiss,
+!                                     TYPE(XT_IDXLIST)partDesc)
+      EXTERNAL        streamWriteScatteredVarPart
+
diff --git a/libcdi/src/cdipioFortran.c b/libcdi/src/cdipioFortran.c
new file mode 100644
index 0000000..ee16cb8
--- /dev/null
+++ b/libcdi/src/cdipioFortran.c
@@ -0,0 +1,54 @@
+/* Automatically generated by make_fint.c, don't edit! */
+
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#if ! defined (CDIPIO_H_)
+#  include "cdipio.h"
+#endif
+
+#if defined (HAVE_CF_INTERFACE)
+
+#if ! defined (__CFORTRAN_LOADED)
+#  include "cfortran.h"
+#endif
+
+#if ! defined (_CDIFORTRAN_H)
+#  include "cdiFortran.h"
+#endif
+
+
+/*  parallel IO IOMode  */
+
+
+/*  parallel IO routines  */
+
+FCALLSCSUB0 (pioEndDef, PIOENDDEF, pioenddef)
+FCALLSCSUB0 (pioEndTimestepping, PIOENDTIMESTEPPING, pioendtimestepping)
+FCALLSCSUB0 (pioFinalize, PIOFINALIZE, piofinalize)
+FCALLSCSUB0 (cdiPioNoPostCommSetup, CDIPIONOPOSTCOMMSETUP, cdipionopostcommsetup)
+
+#undef ROUTINE_5
+#define ROUTINE_5 (void (*)(void))
+static int pioInit_fwrap(int commSuper, int nProcsIO, int IOMode, int *pioNamespace, float partInflate, void (*postCommSetupActions)(void))
+{
+  MPI_Comm v;
+  v = pioInit(MPI_Comm_f2c(commSuper), nProcsIO, IOMode, pioNamespace, partInflate, postCommSetupActions);
+  return MPI_Comm_c2f(v);
+}
+FCALLSCFUN6 (INT, pioInit_fwrap, PIOINIT, pioinit, INT, INT, INT, PINT, FLOAT, ROUTINE)
+FCALLSCSUB0 (pioWriteTimestep, PIOWRITETIMESTEP, piowritetimestep)
+FCALLSCSUB0 (cdiPioRDMAProgress, CDIPIORDMAPROGRESS, cdipiordmaprogress)
+static void streamWriteVarPart_fwrap(int streamID, int varID, const void *data, int nmiss, void *partDesc)
+{
+  streamWriteVarPart(streamID, varID, data, nmiss, (*(Xt_idxlist *)partDesc));
+}
+FCALLSCSUB5 (streamWriteVarPart_fwrap, STREAMWRITEVARPART, streamwritevarpart, INT, INT, PVOID, INT, PVOID)
+static void streamWriteScatteredVarPart_fwrap(int streamID, int varID, const void *data, int numBlocks, int  blocklengths[], int  displacements[], int nmiss, void *partDesc)
+{
+  streamWriteScatteredVarPart(streamID, varID, data, numBlocks, blocklengths, displacements, nmiss, (*(Xt_idxlist *)partDesc));
+}
+FCALLSCSUB8 (streamWriteScatteredVarPart_fwrap, STREAMWRITESCATTEREDVARPART, streamwritescatteredvarpart, INT, INT, PVOID, INT, INTV, INTV, INT, PVOID)
+
+#endif
diff --git a/libcdi/src/cgribex.h b/libcdi/src/cgribex.h
index 58db51b..145b92a 100644
--- a/libcdi/src/cgribex.h
+++ b/libcdi/src/cgribex.h
@@ -246,7 +246,7 @@ int   gribFileSeek(int fileID, long *offset);
 int   gribReadSize(int fileID);
 int   gribVersion(unsigned char *buffer, size_t buffersize);
 
-int   gribGinfo(long recpos, long recsize, unsigned char *gribbuffer, int *intnum, float *fltnum);
+int   gribGinfo(off_t recpos, long recsize, unsigned char *gribbuffer, int *intnum, float *fltnum, off_t *bignum);
 
 double calculate_pfactor(const double* spectralField, long fieldTruncation, long subsetTruncation);
 
diff --git a/libcdi/src/cgribexlib.c b/libcdi/src/cgribexlib.c
index 304cd17..b062405 100644
--- a/libcdi/src/cgribexlib.c
+++ b/libcdi/src/cgribexlib.c
@@ -1,7 +1,7 @@
 
-/* Automatically generated by m214003 at 2013-10-09, do not edit */
+/* Automatically generated by m214003 at 2014-01-08, do not edit */
 
-/* CGRIBEXLIB_VERSION="1.6.2" */
+/* CGRIBEXLIB_VERSION="1.6.3" */
 
 #ifdef _ARCH_PWR6
 #pragma options nostrict
@@ -9547,14 +9547,14 @@ int grib2Sections(unsigned char *gribbuffer, long bufsize, unsigned char **idsp,
 }
 
 
-int gribGinfo(long recpos, long recsize, unsigned char *gribbuffer,
-	      int *intnum, float *fltnum)
+int gribGinfo(off_t recpos, long recsize, unsigned char *gribbuffer,
+	      int *intnum, float *fltnum, off_t *bignum)
 {
   unsigned char *pds, *gds, *bms, *bds;
   unsigned char *bufpointer, *is, *section;
   int gribversion, grib1offset;
   long gribsize = 0;
-  int dpos, bpos = 0;
+  off_t dpos, bpos = 0;
   int bdslen;
   float bsf;
 
@@ -9631,10 +9631,10 @@ int gribGinfo(long recpos, long recsize, unsigned char *gribbuffer,
   if ( bsf > 32767 ) bsf = 32768-bsf;
   bsf = pow(2.0,(double)bsf);
 
-  intnum[0] = dpos;
-  if ( bms ) intnum[1] = bpos;
-  else       intnum[1] = -999;
-  intnum[2] = BDS_NumBits;
+  bignum[0] = dpos;
+  if ( bms ) bignum[1] = bpos;
+  else       bignum[1] = -999;
+  intnum[0] = BDS_NumBits;
 
   /*  fltnum[0] = 1.0; */
   fltnum[0] = pow(10.0, (double)PDS_DecimalScale);
@@ -10839,7 +10839,7 @@ int  gribUnzip(unsigned char *dbuf, long dbufsize, unsigned char *sbuf, long sbu
 
   return (gribLen);
 }
-static const char grb_libvers[] = "1.6.2" " of ""Oct  9 2013"" ""11:03:55";
+static const char grb_libvers[] = "1.6.3" " of ""Jan  8 2014"" ""19:55:18";
 const char *
 cgribexLibraryVersion(void)
 {
diff --git a/libcdi/tests/cksum.c b/libcdi/src/cksum.c
similarity index 72%
rename from libcdi/tests/cksum.c
rename to libcdi/src/cksum.c
index d06b11d..2629cfb 100644
--- a/libcdi/tests/cksum.c
+++ b/libcdi/src/cksum.c
@@ -108,7 +108,63 @@ memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len)
   *state = s;
 }
 
-unsigned long
+#define SWAP_CSUM(BITWIDTH,BYTEWIDTH)                             \
+  do {                                                            \
+  for (size_t i = num_elems; i > 0; --i) {                        \
+    {                                                             \
+      uint##BITWIDTH##_t accum = *(uint##BITWIDTH##_t *)b++;      \
+      for (j = 0; j < BYTEWIDTH; ++j)                             \
+      {                                                           \
+        uint32_t c = (uint32_t)(accum & UCHAR_MAX);               \
+        s = (s << 8) ^ crctab[(s >> 24) ^ c];                     \
+        accum >>= 8;                                              \
+      }                                                           \
+    }                                                             \
+  } while (0)
+
+
+
+/**
+ *  Does endian-swapping prior to checksumming in case platform is big-endian
+ *
+ *  @param elems points to first first element with alignment elem_size
+ *  @param num_elems number of elements to process
+ *  @param elem_size size of each element in bytes
+ */
+void
+memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
+               size_t elem_size)
+{
+#ifdef WORDS_BIGENDIAN
+  register uint32_t c, s = *state;
+  register size_t n = block_len;
+  register unsigned char *b = elems;
+
+  switch (elem_size)
+  {
+  case 1:
+    return memcrc_r(state, elems, num_elems, elem_size);
+  case 2:
+    SWAP_CSUM(16,2);
+    break;
+  case 4:
+    SWAP_CSUM(32,4);
+    break;
+  case 8:
+    SWAP_CSUM(64,8);
+    break;
+  case 16:
+    SWAP_CSUM(64,8);
+    break;
+  }
+  *state = s;
+#else
+  memcrc_r(state, elems, num_elems * elem_size);
+#endif
+}
+
+
+uint32_t
 memcrc_finish(uint32_t *state, off_t total_size)
 {
   register uint32_t c, s = *state;
diff --git a/libcdi/tests/cksum.h b/libcdi/src/cksum.h
similarity index 62%
rename from libcdi/tests/cksum.h
rename to libcdi/src/cksum.h
index 40e17bf..69f404c 100644
--- a/libcdi/tests/cksum.h
+++ b/libcdi/src/cksum.h
@@ -3,11 +3,16 @@
 #endif
 
 #include <inttypes.h>
+#include <sys/types.h>
 
 void
 memcrc_r(uint32_t *state, const unsigned char *block, size_t block_len);
 
-unsigned long
+void
+memcrc_r_eswap(uint32_t *state, const unsigned char *elems, size_t num_elems,
+               size_t elem_size);
+
+uint32_t
 memcrc_finish(uint32_t *state, off_t total_size);
 
 uint32_t
diff --git a/libcdi/src/config.h.in b/libcdi/src/config.h.in
index c161d19..1d6c981 100644
--- a/libcdi/src/config.h.in
+++ b/libcdi/src/config.h.in
@@ -1,5 +1,8 @@
 /* src/config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
 /* Compiler */
 #undef COMPILER
 
@@ -13,6 +16,10 @@
    */
 #undef HAVE_DECL_ISNAN
 
+/* Define to 1 if you have the declaration of `__builtin_ctz', and to 0 if you
+   don't. */
+#undef HAVE_DECL___BUILTIN_CTZ
+
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
@@ -170,6 +177,9 @@
    */
 #undef LT_OBJDIR
 
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
 /* Name of package */
 #undef PACKAGE
 
@@ -210,6 +220,18 @@
 /* Version number of package */
 #undef VERSION
 
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+#  undef WORDS_BIGENDIAN
+# endif
+#endif
+
 /* Number of bits in a file offset, on hosts where this is settable. */
 #undef _FILE_OFFSET_BITS
 
diff --git a/libcdi/src/dmemory.c b/libcdi/src/dmemory.c
index e656fad..90785e1 100644
--- a/libcdi/src/dmemory.c
+++ b/libcdi/src/dmemory.c
@@ -9,6 +9,7 @@
 #include <stdarg.h>
 #include <errno.h>
 
+#include "error.h"
 
 #if ! defined (HAVE_CONFIG_H)
 #if ! defined (HAVE_MALLOC_H)
@@ -530,6 +531,35 @@ void Free(const char *caller, const char *file, int line, void *ptr)
   free(ptr);
 }
 
+void *cdiXmalloc(size_t size, const char *filename, const char *functionname,
+                 int line)
+{
+  void * value = calloc (1, size );
+  if ( value == NULL )
+    cdiAbort(filename, functionname, line, "malloc failed: %s",
+             strerror(errno));
+  return value;
+}
+
+void *cdiXcalloc(size_t nmemb, size_t size, const char *filename,
+                 const char *functionname, int line)
+{
+  void * value = calloc ( nmemb, size );
+  if ( value == NULL )
+    cdiAbort(filename, functionname, line, "calloc failed: %s",
+             strerror(errno) );
+  return value;
+}
+
+void *cdiXrealloc(void *p, size_t size, const char *functionname,
+                  const char *filename, int line)
+{
+  void *value = realloc(p, size);
+  if ( value == NULL )
+    cdiAbort(filename, functionname, line, "realloc failed: %s",
+             strerror(errno));
+  return value;
+}
 
 size_t memTotal(void)
 {
diff --git a/libcdi/src/dmemory.h b/libcdi/src/dmemory.h
index 0ade0cc..73dfaa5 100644
--- a/libcdi/src/dmemory.h
+++ b/libcdi/src/dmemory.h
@@ -42,6 +42,17 @@ extern void    Free   (const char *caller, const char *file, int line, void *ptr
 
 #endif /* DEBUG_MEMORY */
 
+void *cdiXmalloc(size_t, const char *, const char *, int);
+#define xmalloc(size) cdiXmalloc((size), __FILE__, __func__,  __LINE__ )
+
+void *cdiXcalloc(size_t, size_t, const char *, const char *, int);
+#define xcalloc(nmemb,size) cdiXcalloc((nmemb), (size),        \
+                                        __FILE__, __func__, __LINE__)
+
+void *cdiXrealloc(void *, size_t, const char *, const char *, int);
+#define xrealloc(p,size) cdiXrealloc((p), (size),              \
+                                      __FILE__, __func__, __LINE__)
+
 #endif /* _DMEMORY_H */
 /*
  * Local Variables:
diff --git a/libcdi/src/error.c b/libcdi/src/error.c
index 6be3324..4d21a81 100644
--- a/libcdi/src/error.c
+++ b/libcdi/src/error.c
@@ -85,6 +85,9 @@ cdiAbortC_serial(const char *caller, const char *filename,
   exit(EXIT_FAILURE);
 }
 
+typedef void (*cdiWarningFunc)(const char * caller, const char * fmt,
+                               va_list ap);
+
 void Warning_(const char *caller, const char *fmt, ...)
 {
   va_list args;
@@ -93,14 +96,21 @@ void Warning_(const char *caller, const char *fmt, ...)
 
   if ( _Verbose )
     {
-       fprintf(stderr, "Warning (%s) : ", caller);
-      vfprintf(stderr, fmt, args);
-       fprintf(stderr, "\n");
+      cdiWarningFunc cdiWarning_p
+        = (cdiWarningFunc)namespaceSwitchGet(NSSWITCH_WARNING).func;
+      cdiWarning_p(caller, fmt, args);
     }
 
   va_end(args);
 }
 
+void cdiWarning(const char *caller, const char *fmt, va_list ap)
+{
+  fprintf(stderr, "Warning (%s) : ", caller);
+  vfprintf(stderr, fmt, ap);
+  fputc('\n', stderr);
+}
+
 
 void Message_(const char *caller, const char *fmt, ...)
 {
diff --git a/libcdi/src/error.h b/libcdi/src/error.h
index 7a7ee8f..86dc559 100644
--- a/libcdi/src/error.h
+++ b/libcdi/src/error.h
@@ -19,6 +19,8 @@ extern int _Debug;        /* If set to 1, debuggig (default 0)            */
 void SysError_(const char *caller, const char *fmt, ...);
 void    Error_(const char *caller, const char *fmt, ...);
 void  Warning_(const char *caller, const char *fmt, ...);
+/* delegate used by Warning_ unless mode is PIO */
+void cdiWarning(const char *caller, const char *fmt, va_list ap);
 void  Message_(const char *caller, const char *fmt, ...);
 
 #if  defined  WITH_CALLER_NAME
diff --git a/libcdi/src/grid.c b/libcdi/src/grid.c
index a909da0..34ebfa1 100644
--- a/libcdi/src/grid.c
+++ b/libcdi/src/grid.c
@@ -8,10 +8,10 @@
 
 #include "dmemory.h"
 #include "cdi.h"
+#include "cdi_cksum.h"
 #include "cdi_int.h"
 #include "grid.h"
 #include "gaussgrid.h"
-#include "pio_util.h"
 #include "resource_handle.h"
 #include "resource_unpack.h"
 #include "namespace.h"
@@ -129,7 +129,7 @@ void grid_init(grid_t *gridptr)
   gridptr->yunits[0]    = 0;
   gridptr->xstdname[0]  = 0;
   gridptr->ystdname[0]  = 0;
-  gridptr->uuid[0]      = 0;
+  memset(gridptr->uuid, 0, 16);
   gridptr->name         = NULL;
 }
 
@@ -571,7 +571,7 @@ void gridDefXname(int gridID, const char *xname)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning ("%s", "Operation not executed." );
+      Warning ("%s", "Operation not executed." );
       return;
     }
 
@@ -603,7 +603,7 @@ void gridDefXlongname(int gridID, const char *xlongname)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning ("%s", "Operation not executed." );
+      Warning ("%s", "Operation not executed." );
       return;
     }
 
@@ -633,7 +633,7 @@ void gridDefXunits(int gridID, const char *xunits)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -665,7 +665,7 @@ void gridDefYname(int gridID, const char *yname)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -697,7 +697,7 @@ void gridDefYlongname(int gridID, const char *ylongname)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -729,7 +729,7 @@ void gridDefYunits(int gridID, const char *yunits)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -747,8 +747,8 @@ void gridDefYunits(int gridID, const char *yunits)
 
 @Prototype void gridInqXname(int gridID, char *name)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  name     Name of the X-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  name     Name of the X-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -777,8 +777,8 @@ void gridInqXname(int gridID, char *xname)
 
 @Prototype void gridInqXlongname(int gridID, char *longname)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  longname Longname of the X-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  longname Longname of the X-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -807,8 +807,8 @@ void gridInqXlongname(int gridID, char *xlongname)
 
 @Prototype void gridInqXunits(int gridID, char *units)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  units    Units of the X-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  units    Units of the X-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -849,8 +849,8 @@ void gridInqXstdname(int gridID, char *xstdname)
 
 @Prototype void gridInqYname(int gridID, char *name)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  name     Name of the Y-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  name     Name of the Y-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -879,8 +879,8 @@ void gridInqYname(int gridID, char *yname)
 
 @Prototype void gridInqXlongname(int gridID, char *longname)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  longname Longname of the Y-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  longname Longname of the Y-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -909,8 +909,8 @@ void gridInqYlongname(int gridID, char *ylongname)
 
 @Prototype void gridInqYunits(int gridID, char *units)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
-    @Item  units    Units of the Y-axis. The caller must allocate space for the 
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
+    @Item  units    Units of the Y-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
 
@@ -950,7 +950,7 @@ void gridInqYstdname(int gridID, char *ystdname)
 
 @Prototype int gridInqType(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqType} returns the type of a Grid.
@@ -982,7 +982,7 @@ int gridInqType(int gridID)
 
 @Prototype int gridInqSize(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqSize} returns the size of a Grid.
@@ -1066,7 +1066,7 @@ void gridDefTrunc(int gridID, int trunc)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1097,7 +1097,7 @@ void gridDefXsize(int gridID, int xsize)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1138,7 +1138,7 @@ void gridDefPrec(int gridID, int prec)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1176,7 +1176,7 @@ int gridInqPrec(int gridID)
 
 @Prototype int gridInqXsize(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqXsize} returns the number of values of a X-axis.
@@ -1217,7 +1217,7 @@ void gridDefYsize(int gridID, int ysize)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1248,7 +1248,7 @@ void gridDefYsize(int gridID, int ysize)
 
 @Prototype int gridInqYsize(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqYsize} returns the number of values of a Y-axis.
@@ -1290,7 +1290,7 @@ void gridDefNP(int gridID, int np)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning ("%s", "Operation not executed." );
+      Warning ("%s", "Operation not executed." );
       return;
     }
 
@@ -1307,7 +1307,7 @@ void gridDefNP(int gridID, int np)
 
 @Prototype int gridInqNP(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqNP} returns the number of parallels between a pole and the equator
@@ -1345,7 +1345,7 @@ void gridDefRowlon(int gridID, int nrowlon, const int *rowlon)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1414,7 +1414,7 @@ void gridDefMask(int gridID, const int *mask)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1477,7 +1477,7 @@ void gridDefMaskGME(int gridID, const int *mask)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1505,7 +1505,7 @@ void gridDefMaskGME(int gridID, const int *mask)
 
 @Prototype int gridInqXvals(int gridID, double *xvals)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
     @Item  xvals    Pointer to the location into which the X-values are read.
                     The caller must allocate space for the returned values.
 
@@ -1568,7 +1568,7 @@ void gridDefXvals(int gridID, const double *xvals)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1602,7 +1602,7 @@ void gridDefXvals(int gridID, const double *xvals)
 
 @Prototype int gridInqYvals(int gridID, double *yvals)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
     @Item  yvals    Pointer to the location into which the Y-values are read.
                     The caller must allocate space for the returned values.
 
@@ -1663,7 +1663,7 @@ void gridDefYvals(int gridID, const double *yvals)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1854,7 +1854,7 @@ void gridDefXpole(int gridID, double xpole)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1906,7 +1906,7 @@ void gridDefYpole(int gridID, double ypole)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1958,7 +1958,7 @@ void gridDefAngle(int gridID, double angle)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -2007,7 +2007,7 @@ void gridDefGMEnd(int gridID, int nd)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -2055,7 +2055,7 @@ void gridDefGMEni(int gridID, int ni)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -2103,7 +2103,7 @@ void gridDefGMEni2(int gridID, int ni2)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
   gridptr = ( grid_t *) reshGetVal ( gridID, &gridOps );
@@ -2140,7 +2140,7 @@ void gridDefGMEni3(int gridID, int ni3)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -2920,8 +2920,7 @@ int gridGenerate(grid_t grid)
 
 @Prototype int gridDuplicate(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate},
-                    @fref{gridDuplicate} or @fref{vlistInqVarGrid}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridDuplicate} duplicates a horizontal Grid.
@@ -3121,7 +3120,7 @@ void gridDefArea(int gridID, const double *area)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -3192,7 +3191,7 @@ void gridDefNvertex(int gridID, int nvertex)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -3237,7 +3236,7 @@ void gridDefXbounds(int gridID, const double *xbounds)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning ("%s", "Operation not executed.");
+      Warning ("%s", "Operation not executed.");
       return;
     }
 
@@ -3274,7 +3273,7 @@ void gridDefXbounds(int gridID, const double *xbounds)
 
 @Prototype int gridInqXbounds(int gridID, double *xbounds)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
     @Item  xbounds  Pointer to the location into which the X-bounds are read.
                     The caller must allocate space for the returned values.
 
@@ -3352,7 +3351,7 @@ void gridDefYbounds(int gridID, const double *ybounds)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -3389,7 +3388,7 @@ void gridDefYbounds(int gridID, const double *ybounds)
 
 @Prototype int gridInqYbounds(int gridID, double *ybounds)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
     @Item  ybounds  Pointer to the location into which the Y-bounds are read.
                     The caller must allocate space for the returned values.
 
@@ -3914,7 +3913,7 @@ void gridDefLCC(int gridID, double originLon, double originLat, double lonParY,
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -3946,7 +3945,7 @@ void gridDefLCC(int gridID, double originLon, double originLat, double lonParY,
 
 @Prototype void gridInqLCC(int gridID, double *originLon, double *originLat, double *lonParY, double *lat1, double *lat2, double *xinc, double *yinc, int *projflag, int *scanflag)
 @Parameter
-    @Item  gridID    Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID    Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
     @Item  originLon Longitude of the first grid point.
     @Item  originLat Latitude of the first grid point.
     @Item  lonParY   The East longitude of the meridian which is parallel to the Y-axis.
@@ -4000,7 +3999,7 @@ void gridDefLcc2(int gridID, double earth_radius, double lon_0, double lat_0, do
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -4055,7 +4054,7 @@ void gridDefLaea(int gridID, double earth_radius, double lon_0, double lat_0)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -4107,7 +4106,7 @@ void gridDefComplexPacking(int gridID, int lcomplex)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -4153,7 +4152,7 @@ void gridDefNumber(int gridID, const int number)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -4170,7 +4169,7 @@ void gridDefNumber(int gridID, const int number)
 
 @Prototype int gridInqNumber(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqNumber} returns the reference number to an unstructured grid.
@@ -4210,7 +4209,7 @@ void gridDefPosition(int gridID, int position)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -4227,7 +4226,7 @@ void gridDefPosition(int gridID, int position)
 
 @Prototype int gridInqPosition(int gridID)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqPosition} returns the position of grid in the reference file.
@@ -4267,7 +4266,7 @@ void gridDefReference(int gridID, const char *reference)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -4293,7 +4292,7 @@ void gridDefReference(int gridID, const char *reference)
 
 @Prototype char *gridInqReference(int gridID, char *reference)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqReference} returns the reference URI to an unstructured grid.
@@ -4342,7 +4341,7 @@ void gridDefUUID(int gridID, const char *uuid)
 
   if ( reshGetStatus ( gridID, &gridOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -4359,18 +4358,18 @@ void gridDefUUID(int gridID, const char *uuid)
 @Function  gridInqUUID
 @Title     Get the UUID to an unstructured grid
 
- at Prototype char *gridInqUUID(int gridID, char *uuid)
+ at Prototype void gridInqUUID(int gridID, char *uuid)
 @Parameter
-    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate}.
+    @Item  gridID   Grid ID, from a previous call to @fref{gridCreate} or @fref{vlistInqVarGrid}.
 
 @Description
 The function @func{gridInqUUID} returns the UUID to an unstructured grid.
 
 @Result
- at func{gridInqUUID} returns the UUID to an unstructured grid.
+ at func{gridInqUUID} returns the UUID to an unstructured grid to the parameter uuid.
 @EndFunction
 */
-char *gridInqUUID(int gridID, char *uuid)
+void gridInqUUID(int gridID, char *uuid)
 {
   grid_t *gridptr;
 
@@ -4379,8 +4378,6 @@ char *gridInqUUID(int gridID, char *uuid)
   grid_check_ptr(gridID, gridptr);
 
   memcpy(uuid, gridptr->uuid, 16);
-
-  return (uuid);
 }
 
 
@@ -4397,7 +4394,7 @@ gridTxCode ()
 }
 
 enum { gridNint    = 27,
-       gridNdouble = 25,
+       gridNdouble = 24,
        gridNstrings= 8,
        gridHasMaskFlag = 1 << 0,
        gridHasGMEMaskFlag = 1 << 1,
@@ -4434,13 +4431,13 @@ gridGetPackSize(void * voidP, void *context)
   int packBuffSize = 0, count;
 
   packBuffSize += serializeGetSize(gridNint, DATATYPE_INT, context)
-    + serializeGetSize(1, DATATYPE_FLT64, context);
+    + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if (gridP->rowlon)
     {
       xassert(gridP->nrowlon);
       packBuffSize += serializeGetSize(gridP->nrowlon, DATATYPE_INT, context)
-        + serializeGetSize( 1, DATATYPE_FLT64, context);
+        + serializeGetSize( 1, DATATYPE_UINT32, context);
     }
 
   packBuffSize += serializeGetSize(gridNdouble, DATATYPE_FLT64, context);
@@ -4452,7 +4449,8 @@ gridGetPackSize(void * voidP, void *context)
       else
 	count = gridP->xsize;
       xassert(count);
-      packBuffSize += serializeGetSize(count + 1, DATATYPE_FLT64, context);
+      packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->yvals)
@@ -4462,14 +4460,16 @@ gridGetPackSize(void * voidP, void *context)
       else
 	count = gridP->ysize;
       xassert(count);
-      packBuffSize += serializeGetSize(count + 1, DATATYPE_FLT64, context);
+      packBuffSize += serializeGetSize(count, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->area)
     {
       xassert(gridP->size);
       packBuffSize +=
-        serializeGetSize(gridP->size + 1, DATATYPE_FLT64, context);
+        serializeGetSize(gridP->size, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->xbounds)
@@ -4481,7 +4481,8 @@ gridGetPackSize(void * voidP, void *context)
 	count = gridP->xsize;
       xassert(count);
       packBuffSize
-        += serializeGetSize(gridP->nvertex * count + 1, DATATYPE_FLT64, context);
+        += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
+            + serializeGetSize(1, DATATYPE_UINT32, context));
     }
 
   if (gridP->ybounds)
@@ -4493,18 +4494,19 @@ gridGetPackSize(void * voidP, void *context)
 	count = gridP->ysize;
       xassert(count);
       packBuffSize
-        += serializeGetSize(gridP->nvertex * count + 1, DATATYPE_FLT64, context);
+        += (serializeGetSize(gridP->nvertex * count, DATATYPE_FLT64, context)
+            + serializeGetSize(1, DATATYPE_UINT32, context));
     }
 
   packBuffSize +=
     serializeGetSize(gridNstrings * CDI_MAX_NAME , DATATYPE_TXT, context)
-    + serializeGetSize(1, DATATYPE_FLT64, context);
+    + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if (gridP->reference)
     {
       packBuffSize += serializeGetSize(1, DATATYPE_INT, context)
         + serializeGetSize(strlen(gridP->reference) + 1, DATATYPE_TXT, context)
-        + serializeGetSize(1, DATATYPE_FLT64, context);
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->mask)
@@ -4512,14 +4514,14 @@ gridGetPackSize(void * voidP, void *context)
       xassert(gridP->size);
       packBuffSize
         += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
-        + serializeGetSize(1, DATATYPE_FLT64, context);
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   if (gridP->mask_gme)
     {
       xassert(gridP->size);
       packBuffSize += serializeGetSize(gridP->size, DATATYPE_UCHAR, context)
-        + serializeGetSize( 1, DATATYPE_FLT64, context);
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   return packBuffSize;
@@ -4531,8 +4533,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
            int * unpackBufferPos, int nspTarget, void *context)
 {
   grid_t * gridP;
+  uint32_t d;
   int memberMask, size;
-  double d;
   char charBuffer[gridNstrings * CDI_MAX_NAME];
 
   gridInit();
@@ -4544,9 +4546,9 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
     serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                     intBuffer, gridNint, DATATYPE_INT, context);
     serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                    &d, 1, DATATYPE_FLT64, context);
+                    &d, 1, DATATYPE_UINT32, context);
 
-    xassert(xchecksum(DATATYPE_INT, gridNint, intBuffer) == d);
+    xassert(cdiCheckSum(DATATYPE_INT, gridNint, intBuffer) == d);
     xassert(namespaceAdaptKey(intBuffer[0], nspTarget) == gridP->self);
 
     gridP->type          =   intBuffer[1];
@@ -4584,16 +4586,17 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->rowlon, gridP->nrowlon , DATATYPE_INT, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_INT, gridP->nrowlon, gridP->rowlon) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_INT, gridP->nrowlon, gridP->rowlon) == d);
     }
 
   {
     double doubleBuffer[gridNdouble];
     serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                     doubleBuffer, gridNdouble, DATATYPE_FLT64, context);
-    xassert(doubleBuffer[24]
-            == xchecksum(DATATYPE_FLT, gridNdouble, doubleBuffer));
+    serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
+                    &d, 1, DATATYPE_UINT32, context);
+    xassert(d == cdiCheckSum(DATATYPE_FLT, gridNdouble, doubleBuffer));
 
     gridP->xfirst = doubleBuffer[0];
     gridP->yfirst = doubleBuffer[1];
@@ -4632,8 +4635,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->xvals, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, gridP->xvals) == d );
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xvals) == d );
     }
 
   if (memberMask & gridHasYValsFlag)
@@ -4647,8 +4650,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->yvals, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, gridP->yvals ) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->yvals) == d);
     }
 
   if (memberMask & gridHasAreaFlag)
@@ -4658,8 +4661,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->area, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, gridP->area) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->area) == d);
     }
 
   if (memberMask & gridHasXBoundsFlag)
@@ -4674,8 +4677,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->xbounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, gridP->xbounds ) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds) == d);
     }
 
   if (memberMask & gridHasYBoundsFlag)
@@ -4690,16 +4693,16 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
 			  gridP->ybounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, gridP->ybounds ) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds) == d);
     }
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   charBuffer, gridNstrings * CDI_MAX_NAME, DATATYPE_TXT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
+                  &d, 1, DATATYPE_UINT32, context);
 
-  xassert(d == xchecksum(DATATYPE_TXT, gridNstrings * CDI_MAX_NAME, charBuffer));
+  xassert(d == cdiCheckSum(DATATYPE_TXT, gridNstrings * CDI_MAX_NAME, charBuffer));
 
   memcpy ( gridP->xname    , &charBuffer[CDI_MAX_NAME * 0], CDI_MAX_NAME );
   memcpy ( gridP->yname    , &charBuffer[CDI_MAX_NAME * 1], CDI_MAX_NAME );
@@ -4719,8 +4722,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->reference, referenceSize, DATATYPE_TXT, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_TXT, referenceSize, gridP->reference ) == d );
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_TXT, referenceSize, gridP->reference) == d);
     }
 
   if (memberMask & gridHasMaskFlag)
@@ -4730,8 +4733,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->mask, gridP->size, DATATYPE_UCHAR, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_TXT, gridP->size, gridP->mask ) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_UCHAR, gridP->size, gridP->mask) == d);
     }
 
   if (memberMask & gridHasGMEMaskFlag)
@@ -4741,8 +4744,8 @@ gridUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       gridP->mask_gme, gridP->size, DATATYPE_UCHAR, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_TXT, gridP->size, gridP->mask_gme ) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_UCHAR, gridP->size, gridP->mask_gme) == d);
     }
 }
 
@@ -4753,7 +4756,7 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 {
   grid_t   * gridP = ( grid_t * )   voidP;
   int size;
-  double d;
+  uint32_t d;
   char charBuffer[gridNstrings * CDI_MAX_NAME];
 
   {
@@ -4789,8 +4792,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
     serializePack(intBuffer, gridNint, DATATYPE_INT,
                   packBuffer, packBufferSize, packBufferPos, context);
-    d = xchecksum(DATATYPE_INT, gridNint, intBuffer);
-    serializePack(&d, 1, DATATYPE_FLT64,
+    d = cdiCheckSum(DATATYPE_INT, gridNint, intBuffer);
+    serializePack(&d, 1, DATATYPE_UINT32,
                   packBuffer, packBufferSize, packBufferPos, context);
   }
 
@@ -4799,8 +4802,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
       xassert((size = gridP->nrowlon));
       serializePack(gridP->rowlon, size, DATATYPE_INT,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_INT , size, gridP->rowlon);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_INT , size, gridP->rowlon);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -4831,10 +4834,12 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
     doubleBuffer[21] = gridP->xpole;
     doubleBuffer[22] = gridP->ypole;
     doubleBuffer[23] = gridP->angle;
-    doubleBuffer[24] = xchecksum(DATATYPE_FLT, gridNdouble - 1, doubleBuffer);
 
     serializePack(doubleBuffer, gridNdouble, DATATYPE_FLT64,
                   packBuffer, packBufferSize, packBufferPos, context);
+    d = cdiCheckSum(DATATYPE_FLT, gridNdouble, doubleBuffer);
+    serializePack(&d, 1, DATATYPE_UINT32,
+                  packBuffer, packBufferSize, packBufferPos, context);
   }
 
   if (gridP->xvals)
@@ -4847,8 +4852,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(gridP->xvals, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, size, gridP->xvals);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->xvals);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -4861,8 +4866,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
       xassert(size);
       serializePack(gridP->yvals, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, size, gridP->yvals);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->yvals);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -4872,8 +4877,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(gridP->area, gridP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, gridP->size, gridP->area);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, gridP->size, gridP->area);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -4888,8 +4893,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(gridP->xbounds, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, size, gridP->xbounds);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->xbounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -4904,8 +4909,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(gridP->ybounds, size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, size, gridP->ybounds);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, size, gridP->ybounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -4920,8 +4925,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
   serializePack( charBuffer, gridNstrings * CDI_MAX_NAME, DATATYPE_TXT,
 		    packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum(DATATYPE_TXT, gridNstrings * CDI_MAX_NAME, charBuffer);
-  serializePack(&d, 1, DATATYPE_FLT64,
+  d = cdiCheckSum(DATATYPE_TXT, gridNstrings * CDI_MAX_NAME, charBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
                 packBuffer, packBufferSize, packBufferPos, context);
 
   if ( gridP->reference )
@@ -4931,8 +4936,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
                     packBuffer, packBufferSize, packBufferPos, context);
       serializePack(gridP->reference, size, DATATYPE_TXT,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_TXT, size, gridP->reference);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_TXT, size, gridP->reference);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -4941,8 +4946,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
       xassert((size = gridP->size));
       serializePack(gridP->mask, size, DATATYPE_UCHAR,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_TXT, size, gridP->mask);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -4952,8 +4957,8 @@ gridPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(gridP->mask_gme, size, DATATYPE_UCHAR,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_TXT, size, gridP->mask);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_UCHAR, size, gridP->mask_gme);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 }
diff --git a/libcdi/src/institution.c b/libcdi/src/institution.c
index 478571c..ec2f505 100644
--- a/libcdi/src/institution.c
+++ b/libcdi/src/institution.c
@@ -6,7 +6,6 @@
 #include "cdi.h"
 #include "cdi_int.h"
 #include "resource_handle.h"
-#include "pio_util.h"
 #include "resource_handle.h"
 #include "resource_unpack.h"
 #include "namespace.h"
@@ -73,24 +72,25 @@ institute_t * instituteNewEntry ( void )
 static
 void instituteDefaultEntries ( void )
 {
-  cdiResH resH[12];
-  int i;
-
-  resH[0]  = ECMWF   = institutDef( 98,   0, "ECMWF",     "European Centre for Medium-Range Weather Forecasts");
-  resH[1]  = MPIMET  = institutDef( 98, 232, "MPIMET",    "Max-Planck-Institute for Meteorology");
-  resH[2]  =           institutDef( 98, 255, "MPIMET",    "Max-Planck-Institute for Meteorology");
-  resH[3]  =           institutDef( 98, 232, "MPIMET",    "Max-Planck Institute for Meteorology");
-  resH[4]  =           institutDef( 78, 255, "DWD",       "Deutscher Wetterdienst");
-  resH[5]  = MCH     = institutDef(215, 255, "MCH",       "MeteoSwiss");
-  resH[6]  =           institutDef(  7,   0, "NCEP",      "National Centers for Environmental Prediction");
-  resH[7]  =           institutDef(  7,   1, "NCEP",      "National Centers for Environmental Prediction");
-  resH[8]  =           institutDef( 60,   0, "NCAR",      "National Center for Atmospheric Research");
-  resH[9]  =           institutDef( 74,   0, "METOFFICE", "U.K. Met Office");
-  resH[10] =           institutDef( 97,   0, "ESA",       "European Space Agency ");
-  resH[11] =           institutDef( 99,   0, "KNMI",      "Royal Netherlands Meteorological Institute");
+  cdiResH resH[64];
+  int i, n=0;
+
+  resH[n++]  = ECMWF   = institutDef( 98,   0, "ECMWF",     "European Centre for Medium-Range Weather Forecasts");
+  resH[n++]  = MPIMET  = institutDef( 98, 232, "MPIMET",    "Max-Planck-Institute for Meteorology");
+  resH[n++]  =           institutDef( 98, 255, "MPIMET",    "Max-Planck-Institute for Meteorology");
+  resH[n++]  =           institutDef( 98, 232, "MPIMET",    "Max-Planck Institute for Meteorology");
+  resH[n++]  =           institutDef( 78,   0, "DWD",       "Deutscher Wetterdienst");
+  resH[n++]  =           institutDef( 78, 255, "DWD",       "Deutscher Wetterdienst");
+  resH[n++]  = MCH     = institutDef(215, 255, "MCH",       "MeteoSwiss");
+  resH[n++]  =           institutDef(  7,   0, "NCEP",      "National Centers for Environmental Prediction");
+  resH[n++]  =           institutDef(  7,   1, "NCEP",      "National Centers for Environmental Prediction");
+  resH[n++]  =           institutDef( 60,   0, "NCAR",      "National Center for Atmospheric Research");
+  resH[n++]  =           institutDef( 74,   0, "METOFFICE", "U.K. Met Office");
+  resH[n++]  =           institutDef( 97,   0, "ESA",       "European Space Agency");
+  resH[n++]  =           institutDef( 99,   0, "KNMI",      "Royal Netherlands Meteorological Institute");
   /*     (void) institutDef(  0,   0, "IPSL", "IPSL (Institut Pierre Simon Laplace, Paris, France)"); */
 
-  for ( i = 0; i < 12 ; i++ )
+  for ( i = 0; i < n ; i++ )
     reshSetStatus(resH[i], &instituteOps, SUSPENDED);
 }
 
@@ -132,7 +132,7 @@ int instituteCount ( void )
 int instituteCompareKernel ( institute_t *  ip1, institute_t * ip2 )
 {
   int differ = 0;
-  size_t len;
+  size_t len1, len2;
 
   if ( ip1->name )
     {
@@ -143,8 +143,9 @@ int instituteCompareKernel ( institute_t *  ip1, institute_t * ip2 )
         {
           if ( ip2->name )
             {
-              len = strlen(ip2->name);
-              if ( memcmp(ip2->name, ip1->name, len)) differ = 1;
+              len1 = strlen(ip1->name);
+              len2 = strlen(ip2->name);
+              if ( (len1 != len2) || memcmp(ip2->name, ip1->name, len2) ) differ = 1;
             }
         }
     }
@@ -152,8 +153,9 @@ int instituteCompareKernel ( institute_t *  ip1, institute_t * ip2 )
     {
       if ( ip2->longname )
         {
-          len = strlen(ip2->longname);
-          if ( memcmp(ip2->longname, ip1->longname, len)) differ = 1;
+          len1 = strlen(ip1->longname);
+          len2 = strlen(ip2->longname);
+          if ( (len1 < len2) || memcmp(ip2->longname, ip1->longname, len2) ) differ = 1;
         }
     }
   else
diff --git a/libcdi/src/mo_cdi.f90 b/libcdi/src/mo_cdi.f90
index 0468a44..4283635 100644
--- a/libcdi/src/mo_cdi.f90
+++ b/libcdi/src/mo_cdi.f90
@@ -162,11 +162,6 @@ module mo_cdi
       integer :: CALENDAR_365DAYS = 3
       integer :: CALENDAR_366DAYS = 4
       integer :: CALENDAR_NONE = 5
-      integer :: PIO_NONE = 0
-      integer :: PIO_MPI = 1
-      integer :: PIO_WRITER = 2
-      integer :: PIO_ASYNCH = 3
-      integer :: PIO_FPGUARD = 4
 
       interface
         subroutine cdiReset() bind(c,name='cdiReset')
@@ -227,6 +222,26 @@ module mo_cdi
       end interface
   
       interface
+        integer(c_int) function namespaceNew() bind(c,name='namespaceNew')
+          import :: c_int
+       end function namespaceNew
+      end interface
+  
+      interface
+        subroutine namespaceSetActive(namespaceID) bind(c,name='namespaceSetActive')
+          import :: c_int
+          integer(c_int), value :: namespaceID
+       end subroutine namespaceSetActive
+      end interface
+  
+      interface
+        subroutine namespaceDelete(namespaceID) bind(c,name='namespaceDelete')
+          import :: c_int
+          integer(c_int), value :: namespaceID
+       end subroutine namespaceDelete
+      end interface
+  
+      interface
         subroutine cdiParamToString(param,paramstr,maxlen) bind(c,name='cdiParamToString')
           import :: c_int,c_char
           integer(c_int), value :: param
@@ -411,6 +426,13 @@ module mo_cdi
       end interface
   
       interface
+        integer(c_int) function streamInqCurTimestepID(streamID) bind(c,name='streamInqCurTimestepID')
+          import :: c_int
+          integer(c_int), value :: streamID
+       end function streamInqCurTimestepID
+      end interface
+  
+      interface
         integer(c_int) function streamInqTimestep(streamID,tsID) bind(c,name='streamInqTimestep')
           import :: c_int
           integer(c_int), value :: streamID
@@ -556,15 +578,6 @@ module mo_cdi
       end interface
   
       interface
-        subroutine streamInqGinfo(streamID,intnum,fltnum) bind(c,name='streamInqGinfo')
-          import :: c_int,c_float
-          integer(c_int), value :: streamID
-          integer(c_int), intent(out) :: intnum
-          real(c_float), intent(out) :: fltnum
-       end subroutine streamInqGinfo
-      end interface
-  
-      interface
         integer(c_int) function vlistCreate() bind(c,name='vlistCreate')
           import :: c_int
        end function vlistCreate
@@ -2046,11 +2059,11 @@ module mo_cdi
       end interface
   
       interface
-        character(c_char) function gridInqUUID(gridID,uuid_cbuf) bind(c,name='gridInqUUID')
+        subroutine gridInqUUID(gridID,uuid_cbuf) bind(c,name='gridInqUUID')
           import :: c_int,c_char
           integer(c_int), value :: gridID
           character(c_char), dimension(*) :: uuid_cbuf
-       end function gridInqUUID
+       end subroutine gridInqUUID
       end interface
   
       interface
@@ -2370,11 +2383,11 @@ module mo_cdi
       end interface
   
       interface
-        character(c_char) function zaxisInqUUID(zaxisID,uuid_cbuf) bind(c,name='zaxisInqUUID')
+        subroutine zaxisInqUUID(zaxisID,uuid_cbuf) bind(c,name='zaxisInqUUID')
           import :: c_int,c_char
           integer(c_int), value :: zaxisID
           character(c_char), dimension(*) :: uuid_cbuf
-       end function zaxisInqUUID
+       end subroutine zaxisInqUUID
       end interface
   
       interface
@@ -3070,6 +3083,9 @@ module mo_cdi
       public :: cdiDefMissval
       public :: cdiInqMissval
       public :: cdiDefGlobal
+      public :: namespaceNew
+      public :: namespaceSetActive
+      public :: namespaceDelete
       public :: cdiParamToString
       public :: cdiDecodeParam
       public :: cdiEncodeParam
@@ -3093,6 +3109,7 @@ module mo_cdi
       public :: streamInqCompType
       public :: streamInqCompLevel
       public :: streamDefTimestep
+      public :: streamInqCurTimestepID
       public :: streamInqTimestep
       public :: streamFilename
       public :: streamFilesuffix
@@ -3109,7 +3126,6 @@ module mo_cdi
       public :: streamWriteRecord
       public :: streamWriteRecordF
       public :: streamCopyRecord
-      public :: streamInqGinfo
       public :: vlistCreate
       public :: vlistDestroy
       public :: vlistDuplicate
@@ -3574,11 +3590,6 @@ module mo_cdi
       public :: CALENDAR_365DAYS
       public :: CALENDAR_366DAYS
       public :: CALENDAR_NONE
-      public :: PIO_NONE
-      public :: PIO_MPI
-      public :: PIO_WRITER
-      public :: PIO_ASYNCH
-      public :: PIO_FPGUARD
 
 contains
 
diff --git a/libcdi/src/model.c b/libcdi/src/model.c
index 0ca7e99..a907195 100644
--- a/libcdi/src/model.c
+++ b/libcdi/src/model.c
@@ -5,7 +5,6 @@
 #include "dmemory.h"
 #include "cdi.h"
 #include "cdi_int.h"
-#include "pio_util.h"
 #include "resource_handle.h"
 #include "resource_unpack.h"
 #include "namespace.h"
diff --git a/libcdi/src/namespace.c b/libcdi/src/namespace.c
index e156c41..bd62c22 100644
--- a/libcdi/src/namespace.c
+++ b/libcdi/src/namespace.c
@@ -1,10 +1,19 @@
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE 600 /* PTHREAD_MUTEX_RECURSIVE */
+#endif
+
 #include <limits.h>
 #include <stdlib.h>
 #include <stdio.h>
+
 #include "cdi.h"
+#include "dmemory.h"
 #include "namespace.h"
 #include "resource_handle.h"
-#include "pio_util.h"
 #include "serialize.h"
 #include "error.h"
 #include "cdf_int.h"
@@ -26,8 +35,31 @@ static int activeNamespace = 0;
 #define CDI_NETCDF_SWITCHES
 #endif
 
+#if defined (SX)
+static const union namespaceSwitchValue defaultSwitches[NUM_NAMESPACE_SWITCH] = {
+    { .func = (void (*)()) cdiAbortC_serial },
+    { .func = (void (*)()) cdiWarning },
+    { .func = (void (*)()) serializeGetSizeInCore },
+    { .func = (void (*)()) serializePackInCore },
+    { .func = (void (*)()) serializeUnpackInCore },
+    { .func = (void (*)()) fileOpen_serial },
+    { .func = (void (*)()) fileWrite },
+    { .func = (void (*)()) fileClose_serial },
+    { .func = (void (*)()) cdiStreamOpenDefaultDelegate },
+    { .func = (void (*)()) cdiStreamDefVlist_ },
+    { .func = (void (*)()) cdiStreamWriteVar_ },
+    { .func = (void (*)()) cdiStreamwriteVarChunk_ },
+    { .func = (void (*)()) 0 },
+    { .func = (void (*)()) 0 },
+    { .func = (void (*)()) cdiStreamCloseDefaultDelegate },
+    { .func = (void (*)()) cdiStreamDefTimestep_ },
+    { .func = (void (*)()) cdiStreamSync_ },
+    CDI_NETCDF_SWITCHES
+};
+#else
 #define defaultSwitches {                                   \
     { .func = (void (*)()) cdiAbortC_serial },              \
+    { .func = (void (*)()) cdiWarning },                    \
     { .func = (void (*)()) serializeGetSizeInCore },        \
     { .func = (void (*)()) serializePackInCore },           \
     { .func = (void (*)()) serializeUnpackInCore },         \
@@ -38,12 +70,14 @@ static int activeNamespace = 0;
     { .func = (void (*)()) cdiStreamDefVlist_ },            \
     { .func = (void (*)()) cdiStreamWriteVar_ },            \
     { .func = (void (*)()) cdiStreamwriteVarChunk_ },       \
-    { .data = NULL },                                       \
+    { .func = (void (*)()) 0 },                             \
+    { .func = (void (*)()) 0 },                             \
     { .func = (void (*)()) cdiStreamCloseDefaultDelegate }, \
     { .func = (void (*)()) cdiStreamDefTimestep_ }, \
     { .func = (void (*)()) cdiStreamSync_ },                \
     CDI_NETCDF_SWITCHES                        \
     }
+#endif
 
 struct namespace
 {
@@ -51,7 +85,30 @@ struct namespace
   union namespaceSwitchValue switches[NUM_NAMESPACE_SWITCH];
 } initialNamespace = {
   .resStage = STAGE_DEFINITION,
+#if defined (SX)
+  .switches = {
+    { .func = (void (*)()) cdiAbortC_serial },
+    { .func = (void (*)()) cdiWarning },
+    { .func = (void (*)()) serializeGetSizeInCore },
+    { .func = (void (*)()) serializePackInCore },
+    { .func = (void (*)()) serializeUnpackInCore },
+    { .func = (void (*)()) fileOpen_serial },
+    { .func = (void (*)()) fileWrite },
+    { .func = (void (*)()) fileClose_serial },
+    { .func = (void (*)()) cdiStreamOpenDefaultDelegate },
+    { .func = (void (*)()) cdiStreamDefVlist_ },
+    { .func = (void (*)()) cdiStreamWriteVar_ },
+    { .func = (void (*)()) cdiStreamwriteVarChunk_ },
+    { .func = (void (*)()) 0 },
+    { .func = (void (*)()) 0 },
+    { .func = (void (*)()) cdiStreamCloseDefaultDelegate },
+    { .func = (void (*)()) cdiStreamDefTimestep_ },
+    { .func = (void (*)()) cdiStreamSync_ },
+    CDI_NETCDF_SWITCHES
+}
+#else
   .switches = defaultSwitches
+#endif
 };
 
 struct namespace *namespaces = &initialNamespace;
@@ -61,13 +118,28 @@ static int namespacesSize = 1;
 #if  defined  (HAVE_LIBPTHREAD)
 #  include <pthread.h>
 
-static pthread_mutex_t namespaceMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_once_t  namespaceOnce = PTHREAD_ONCE_INIT;
+static pthread_mutex_t namespaceMutex;
+
+static void
+namespaceInitialize(void)
+{
+  pthread_mutexattr_t ma;
+  pthread_mutexattr_init(&ma);
+  pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
+  pthread_mutex_init(&namespaceMutex, &ma);
+  pthread_mutexattr_destroy(&ma);
+}
 
 #  define NAMESPACE_LOCK()         pthread_mutex_lock(&namespaceMutex)
 #  define NAMESPACE_UNLOCK()       pthread_mutex_unlock(&namespaceMutex)
+#  define NAMESPACE_INIT()         pthread_once(&namespaceOnce, \
+                                                namespaceInitialize)
+
 
 #else
 
+#  define NAMESPACE_INIT() do { } while (0)
 #  define NAMESPACE_LOCK()
 #  define NAMESPACE_UNLOCK()
 
@@ -88,25 +160,6 @@ enum {
 };
 
 
-#if 0
-void namespaceShowbits ( int n, char *name )
-{
-  int i;
-  unsigned mask;
-  char bitvalues[intbits + 1];
-
-  mask = 1;
-  for ( i = 0; i < intbits; i++ )
-    {
-      bitvalues[i] = ((unsigned)n & mask) ? '1':'0';
-      mask <<= 1;
-    }
-  bitvalues[intbits] = '\0';
-  fprintf (stdout, "%s: %s\n", name, bitvalues );
-}
-#endif
-
-
 int namespaceIdxEncode ( namespaceTuple_t tin )
 {
   xassert ( tin.nsp < NUM_NAMESPACES && tin.idx < NUM_IDX);
@@ -134,6 +187,7 @@ int
 namespaceNew()
 {
   int newNamespaceID = -1;
+  NAMESPACE_INIT();
   NAMESPACE_LOCK();
   if (namespacesSize > nNamespaces)
     {
@@ -171,9 +225,14 @@ namespaceNew()
   xassert(newNamespaceID >= 0 && newNamespaceID < NUM_NAMESPACES);
   ++nNamespaces;
   namespaces[newNamespaceID].resStage = STAGE_DEFINITION;
+#if defined (SX)
+  memcpy(namespaces[newNamespaceID].switches, defaultSwitches,
+         sizeof (namespaces[newNamespaceID].switches));
+#else
   memcpy(namespaces[newNamespaceID].switches,
          (union namespaceSwitchValue[NUM_NAMESPACE_SWITCH])defaultSwitches,
          sizeof (namespaces[newNamespaceID].switches));
+#endif
   reshListCreate(newNamespaceID);
   NAMESPACE_UNLOCK();
   return newNamespaceID;
@@ -182,6 +241,7 @@ namespaceNew()
 void
 namespaceDelete(int namespaceID)
 {
+  NAMESPACE_INIT();
   NAMESPACE_LOCK();
   xassert(namespaceID < namespacesSize && nNamespaces);
   reshListDestruct(namespaceID);
@@ -190,25 +250,13 @@ namespaceDelete(int namespaceID)
   NAMESPACE_UNLOCK();
 }
 
-void namespaceCleanup ( void )
-{
-  if ( nNamespaces > 1 )
-    {
-      initialNamespace = namespaces[0];
-      free(namespaces);
-      namespaces = &initialNamespace;
-      nNamespaces = 1;
-    }
-}
-
-
 int namespaceGetNumber ()
 {
   return nNamespaces;
 }
 
 
-void pioNamespaceSetActive ( int nId )
+void namespaceSetActive ( int nId )
 {
   xassert(nId < namespacesSize && nId >= 0
           && namespaces[nId].resStage != STAGE_UNUSED);
@@ -284,10 +332,16 @@ union namespaceSwitchValue namespaceSwitchGet(enum namespaceSwitch sw)
 
 void cdiReset(void)
 {
+  NAMESPACE_INIT();
   NAMESPACE_LOCK();
   for (int namespaceID = 0; namespaceID < namespacesSize; ++namespaceID)
-    namespaceDelete(namespaceID);
-  namespaces = &initialNamespace;
+    if (namespaces[namespaceID].resStage != STAGE_UNUSED)
+      namespaceDelete(namespaceID);
+  if (namespaces != &initialNamespace)
+    {
+      free(namespaces);
+      namespaces = &initialNamespace;
+    }
   namespacesSize = 1;
   nNamespaces = 1;
   activeNamespace = 0;
diff --git a/libcdi/src/namespace.h b/libcdi/src/namespace.h
index 00188d8..3834bdd 100644
--- a/libcdi/src/namespace.h
+++ b/libcdi/src/namespace.h
@@ -22,6 +22,7 @@ enum namespaceSwitch
 {
   NSSWITCH_NO_SUCH_SWITCH = -1,
   NSSWITCH_ABORT,
+  NSSWITCH_WARNING,
   NSSWITCH_SERIALIZE_GET_SIZE,
   NSSWITCH_SERIALIZE_PACK,
   NSSWITCH_SERIALIZE_UNPACK,
@@ -33,6 +34,7 @@ enum namespaceSwitch
   NSSWITCH_STREAM_WRITE_VAR_,
   NSSWITCH_STREAM_WRITE_VAR_CHUNK_,
   NSSWITCH_STREAM_WRITE_VAR_PART_,
+  NSSWITCH_STREAM_WRITE_SCATTERED_VAR_PART_,
   NSSWITCH_STREAM_CLOSE_BACKEND,
   NSSWITCH_STREAM_DEF_TIMESTEP_,
   NSSWITCH_STREAM_SYNC,
@@ -58,6 +60,7 @@ int              namespaceNew();
 void             namespaceDelete(int namespaceID);
 void             namespaceCleanup      ( void );
 int              namespaceGetNumber    ( void );
+void namespaceSetActive(int namespaceID);
 int              namespaceGetActive    ( void );
 int              namespaceIdxEncode    ( namespaceTuple_t );
 int              namespaceIdxEncode2   ( int, int );
diff --git a/libcdi/src/pio.c b/libcdi/src/pio.c
index e71200b..3dfc3b0 100644
--- a/libcdi/src/pio.c
+++ b/libcdi/src/pio.c
@@ -14,6 +14,7 @@
 
 #include "pio.h"
 #include "cdi.h"
+#include "cdipio.h"
 #include "pio_comm.h"
 #include "pio_impl.h"
 #include "pio_interface.h"
@@ -142,7 +143,7 @@ int pioFileOpen(const char *filename, const char *mode)
 
 /***************************************************************/
 
-void backendInit ( void )
+void backendInit(void (*postCommSetupActions)(void))
 {
   int IOMode = commInqIOMode ();
 
@@ -159,16 +160,16 @@ void backendInit ( void )
       commDefCommsIO ();
       break;
     case PIO_MPI:
-      initMPINONB ();
+      initMPINONB(postCommSetupActions);
       break;
 #ifndef _SX
     case PIO_ASYNCH:
 #endif
     case PIO_WRITER:
-      pioSendInitialize();
+      pioSendInitialize(postCommSetupActions);
       break;
     case PIO_FPGUARD:
-      initPOSIXFPGUARDSENDRECV ();
+      initPOSIXFPGUARDSENDRECV(postCommSetupActions);
       break;
     }
 }
@@ -201,12 +202,6 @@ void backendCleanup ( void )
 
 /***************************************************************/
 
-void backendFinalize ( void )
-{
-  commDestroy ();
-  MPI_Finalize ();
-  exit ( EXIT_SUCCESS );
-}
 #endif
 /*
  * Local Variables:
diff --git a/libcdi/src/pio.h b/libcdi/src/pio.h
index e7138a7..71dafbc 100644
--- a/libcdi/src/pio.h
+++ b/libcdi/src/pio.h
@@ -12,8 +12,7 @@
 #include "cdi_int.h"
 
 void   backendCleanup  ( void );
-void   backendInit     ( void );
-void   backendFinalize ( void );
+void backendInit(void (*postCommSetupActions)(void));
 int pioFileOpen(const char *filename, const char *mode);
 int    pioFileClose    ( int );
 size_t cdiPioFileWrite(int fileID, const void *restrict buffer, size_t len,
diff --git a/libcdi/src/pio_cdf_int.c b/libcdi/src/pio_cdf_int.c
index 1dcdbe8..2ea90e6 100644
--- a/libcdi/src/pio_cdf_int.c
+++ b/libcdi/src/pio_cdf_int.c
@@ -11,6 +11,7 @@
 
 #include "namespace.h"
 #include "pio.h"
+#include "cdipio.h"
 #include "pio_comm.h"
 #include "pio_cdf_int.h"
 #include "pio_util.h"
diff --git a/libcdi/src/pio_client.c b/libcdi/src/pio_client.c
index 16b8f94..b654d0a 100644
--- a/libcdi/src/pio_client.c
+++ b/libcdi/src/pio_client.c
@@ -10,6 +10,7 @@
 #include "namespace.h"
 #include "taxis.h"
 
+#include "cdipio.h"
 #include "pio.h"
 #include "pio_client.h"
 #include "pio_comm.h"
@@ -18,12 +19,18 @@
 #include "pio_util.h"
 #include "pio_serialize.h"
 
+static void
+nullPackFunc(void *obj, void *buf, int size, int *pos, void *context)
+{
+}
+
+
 static int
 cdiPioClientStreamOpen(const char *filename, const char *filemode,
                        int filetype, stream_t *streamptr,
                        int recordBufIsToBeCreated)
 {
-  union winHeaderEntry header;
+  struct winHeaderEntry header;
   size_t filename_len;
   if ( tolower ( * filemode ) == 'w' )
     {
@@ -35,12 +42,14 @@ cdiPioClientStreamOpen(const char *filename, const char *filemode,
         case STAGE_TIMELOOP:
           filename_len = strlen(filename);
           xassert(filename_len > 0 && filename_len < MAXDATAFILENAME);
-          header.funcCall
-            = (struct funcCallDesc){
-            .funcID = STREAMOPEN,
-            .funcArgs.newFile = { .fnamelen = (int)filename_len,
-                                  .filetype = filetype } };
-          pioBufferFuncCall(header, filename, filename_len + 1);
+          header = (struct winHeaderEntry){
+            .id = STREAMOPEN,
+            .specific.funcArgs.newFile
+            = { .fnamelen = (int)filename_len,
+                .filetype = filetype } };
+          pioBufferFuncCall(header,
+                            &(struct memCpyDataDesc){filename,
+                                filename_len + 1}, memcpyPackFunc);
           xdebug("WROTE FUNCTION CALL IN BUFFER OF WINS:  %s, filenamesz=%zu,"
                  " filename=%s, filetype=%d",
                  funcMap[(-1 - STREAMOPEN)], filename_len + 1, filename,
@@ -61,18 +70,17 @@ cdiPioClientStreamOpen(const char *filename, const char *filemode,
 static void
 cdiPioClientStreamDefVlist_(int streamID, int vlistID)
 {
-  union winHeaderEntry header;
+  struct winHeaderEntry header;
   statusCode nspStatus = namespaceInqResStatus ();
   switch ( nspStatus )
     {
     case STAGE_DEFINITION:
       break;
     case STAGE_TIMELOOP:
-      header.funcCall
-        = (struct funcCallDesc){
-        .funcID = STREAMDEFVLIST,
-        .funcArgs.streamChange = { streamID, vlistID } };
-      pioBufferFuncCall(header, NULL, 0);
+      header = (struct winHeaderEntry){
+        .id = STREAMDEFVLIST,
+        .specific.funcArgs.streamChange = { streamID, vlistID } };
+      pioBufferFuncCall(header, NULL, nullPackFunc);
       xdebug("WROTE FUNCTION CALL IN BUFFER OF WINS:  %s, streamID=%d,"
              " vlistID=%d", funcMap[(-1 - STREAMDEFVLIST)], streamID, vlistID);
       break;
@@ -102,7 +110,8 @@ cdiPioClientStreamWriteVarChunk_(int streamID, int varID, int memtype,
   int size = vlistInqVarSize(vlistID, varID),
     varShape[3];
   unsigned ndims = (unsigned)cdiPioQueryVarDims(varShape, vlistID, varID);
-  Xt_int varShapeXt[3], chunkShape[3] = { 1, 1, 1 }, origin[3] = { 0, 0, 0 };
+  Xt_int varShapeXt[3], origin[3] = { 0, 0, 0 };
+  int chunkShape[3] = { 1, 1, 1 };
   /* FIXME: verify xt_int ranges are good enough */
   for (unsigned i = 0; i < 3; ++i)
     varShapeXt[i] = varShape[i];
@@ -136,6 +145,30 @@ cdiPioClientStreamWriteVarPart(int streamID, int varID, const void *data,
     }
 }
 
+static void
+cdiPioClientStreamWriteScatteredVarPart(int streamID, int varID,
+                                        const void *data,
+                                        int numBlocks, const int blocklengths[],
+                                        const int displacements[],
+                                        int nmiss, Xt_idxlist partDesc)
+{
+  switch (namespaceInqResStatus())
+    {
+    case STAGE_DEFINITION:
+      xabort("DEFINITION STAGE: PARALLEL WRITING NOT POSSIBLE.");
+      break;
+    case STAGE_TIMELOOP:
+      cdiPioBufferPartDataGather(streamID, varID, data, numBlocks,
+                                 blocklengths, displacements, nmiss, partDesc);
+      return;
+    case STAGE_CLEANUP:
+      xabort("CLEANUP STAGE: PARALLEL WRITING NOT POSSIBLE.");
+      break;
+    default:
+      xabort("INTERNAL ERROR");
+    }
+}
+
 #if defined HAVE_LIBNETCDF
 static void
 cdiPioCdfDefTimestepNOP(stream_t *streamptr, int tsID)
@@ -152,18 +185,18 @@ cdiPioClientStreamNOP(stream_t *streamptr)
 static void
 cdiPioClientStreamClose(stream_t *streamptr, int recordBufIsToBeDeleted)
 {
-  union winHeaderEntry header;
+  struct winHeaderEntry header;
   statusCode nspStatus = namespaceInqResStatus ();
   switch ( nspStatus )
     {
     case STAGE_DEFINITION:
       break;
     case STAGE_TIMELOOP:
-      header.funcCall
-        = (struct funcCallDesc){
-        .funcID = STREAMCLOSE,
-        .funcArgs.streamChange = { streamptr->self, CDI_UNDEFID } };
-      pioBufferFuncCall(header, NULL, 0);
+      header = (struct winHeaderEntry){
+        .id = STREAMCLOSE,
+        .specific.funcArgs.streamChange
+        = { streamptr->self, CDI_UNDEFID } };
+      pioBufferFuncCall(header, NULL, nullPackFunc);
       xdebug("WROTE FUNCTION CALL IN BUFFER OF WINS:  %s, streamID=%d",
              funcMap[-1 - STREAMCLOSE], streamptr->self);
       break;
@@ -174,32 +207,31 @@ cdiPioClientStreamClose(stream_t *streamptr, int recordBufIsToBeDeleted)
     }
 }
 
+static void
+cdiPioTaxisPackWrap(void *data, void *buf, int size, int *pos,
+                    void *context)
+{
+  int taxisID = (int)(intptr_t)data;
+  reshPackResource(taxisID, &taxisOps, buf, size, pos, context);
+}
+
 static int
 cdiPioClientStreamDefTimestep_(stream_t *streamptr, int tsID)
 {
-  union winHeaderEntry header;
+  struct winHeaderEntry header;
   statusCode nspStatus = namespaceInqResStatus ();
-  int taxisID, buf_size, position;
-  char *buf;
-  MPI_Comm commCalc;
+  int taxisID;
   switch ( nspStatus )
     {
     case STAGE_DEFINITION:
       break;
     case STAGE_TIMELOOP:
-      position = 0;
       taxisID = vlistInqTaxis(streamptr->vlistID);
-      header.funcCall
-        = (struct funcCallDesc){
-        .funcID = STREAMDEFTIMESTEP,
-        .funcArgs.streamNewTimestep = { streamptr->self, tsID } };
-      commCalc = commInqCommCalc();
-      buf_size = reshResourceGetPackSize(taxisID, &taxisOps, &commCalc);
-      buf = xmalloc((size_t)buf_size);
-      reshPackResource(taxisID, &taxisOps, buf, buf_size, &position,
-                       &commCalc);
-      pioBufferFuncCall(header, buf, buf_size);
-      free(buf);
+      header = (struct winHeaderEntry){
+        .id = STREAMDEFTIMESTEP,
+        .specific.funcArgs.streamNewTimestep = { streamptr->self, tsID } };
+      xassert(sizeof (void *) >= sizeof (int));
+      pioBufferFuncCall(header, (void *)(intptr_t)taxisID, cdiPioTaxisPackWrap);
       break;
     case STAGE_CLEANUP:
       break;
@@ -216,7 +248,7 @@ cdiPioClientSetup(int *pioNamespace_, int *pioNamespace)
   commDefCommsIO ();
   *pioNamespace_ = *pioNamespace = namespaceNew();
   int callerCDINamespace = namespaceGetActive();
-  pioNamespaceSetActive(*pioNamespace_);
+  namespaceSetActive(*pioNamespace_);
   serializeSetMPI();
   namespaceSwitchSet(NSSWITCH_STREAM_OPEN_BACKEND,
                      NSSW_FUNC(cdiPioClientStreamOpen));
@@ -228,6 +260,8 @@ cdiPioClientSetup(int *pioNamespace_, int *pioNamespace)
                      NSSW_FUNC(cdiPioClientStreamWriteVarChunk_));
   namespaceSwitchSet(NSSWITCH_STREAM_WRITE_VAR_PART_,
                      NSSW_FUNC(cdiPioClientStreamWriteVarPart));
+  namespaceSwitchSet(NSSWITCH_STREAM_WRITE_SCATTERED_VAR_PART_,
+                     NSSW_FUNC(cdiPioClientStreamWriteScatteredVarPart));
   namespaceSwitchSet(NSSWITCH_STREAM_CLOSE_BACKEND,
                      NSSW_FUNC(cdiPioClientStreamClose));
   namespaceSwitchSet(NSSWITCH_STREAM_DEF_TIMESTEP_,
@@ -240,7 +274,7 @@ cdiPioClientSetup(int *pioNamespace_, int *pioNamespace)
   namespaceSwitchSet(NSSWITCH_CDF_STREAM_SETUP,
                      NSSW_FUNC(cdiPioClientStreamNOP));
 #endif
-  pioNamespaceSetActive(callerCDINamespace);
+  namespaceSetActive(callerCDINamespace);
 }
 
 
diff --git a/libcdi/src/pio_comm.c b/libcdi/src/pio_comm.c
index 389a2e6..accdfa1 100644
--- a/libcdi/src/pio_comm.c
+++ b/libcdi/src/pio_comm.c
@@ -7,14 +7,15 @@
 
 #include "pio_comm.h"
 #include "cdi.h"
+#include "dmemory.h"
 #include "pio_util.h"
 
 #ifdef USE_MPI
 
+#include "cdipio.h"
+
 typedef struct {
   int IOMode;
-  int maxIOMode;
-  int minIOModeWithSpecialProcs;
   int nProcsIO;
   int nProcsModel;
   int isProcIO;
@@ -57,8 +58,6 @@ static
 void pioInfoInit ( pioInfo_t * p )
 {
   p->IOMode               = CDI_UNDEFID;
-  p->maxIOMode            = CDI_UNDEFID;
-  p->minIOModeWithSpecialProcs = CDI_UNDEFID;
   p->nProcsIO             = CDI_UNDEFID;
   p->nProcsModel          = CDI_UNDEFID;
   p->isProcIO             = CDI_UNDEFID;
@@ -227,16 +226,10 @@ int commInqNProcsModel ( void )
 }
 
 
-void     commDefIOMode  ( int IOMode, int maxIOMode, int minIOModeWithSpecialProcs )
+void     commDefIOMode  ( int IOMode )
 {
-  xassert ( info != NULL &&
-	   IOMode >= 0 &&
-           maxIOMode >= IOMode &&
-           minIOModeWithSpecialProcs > 0 &&
-           minIOModeWithSpecialProcs <= maxIOMode );
+  xassert(info != NULL && IOMode >= PIO_MINIOMODE && IOMode <= PIO_MAXIOMODE );
   info->IOMode = IOMode;
-  info->maxIOMode = maxIOMode;
-  info->minIOModeWithSpecialProcs = minIOModeWithSpecialProcs;
 }
 
 
@@ -344,7 +337,7 @@ void     commDefCommColl  ( int isProcColl )
            info->commNode != MPI_COMM_NULL &&
            info->commColl == MPI_COMM_NULL );
 
-  info->nodeInfo.isProcColl = isProcColl;  
+  info->nodeInfo.isProcColl = isProcColl;
   xmpi ( MPI_Comm_split ( info->commNode, info->nodeInfo.isProcColl, 0, 
                           &info->commColl ));
   xmpi ( MPI_Comm_size ( info->commColl, &info->sizeColl ));
@@ -445,7 +438,7 @@ void commDefCommNode ( void )
                           &info->commNode ));
   xmpi ( MPI_Comm_size ( info->commNode, &info->sizeNode ));
   xmpi ( MPI_Comm_rank ( info->commNode, &info->rankNode ));
-  if ( info->IOMode >= info->minIOModeWithSpecialProcs )
+  if ( info->IOMode >= PIO_MINIOMODEWITHSPECIALPROCS )
     info->specialRankNode = info->sizeNode - 1;
 
   free(sortedHosts);
@@ -794,8 +787,6 @@ void commPrint ( FILE * fp )
   fprintf ( fp, "######## pioinfo PE%d ###########\n", info->rankGlob );
   fprintf ( fp, "#\n" );
   fprintf ( fp, "# IOMode      = %d\n", info->IOMode );
-  fprintf ( fp, "# maxIOMode   = %d\n", info->maxIOMode );
-  fprintf ( fp, "# minIOModeWithSpecialProcs  = %d\n", info->minIOModeWithSpecialProcs );
   fprintf ( fp, "# nProcsIO    = %d\n", info->nProcsIO );
   fprintf ( fp, "# nProcsModel = %d\n", info->nProcsModel );
   fprintf ( fp, "# isProcIO    = %d\n", info->isProcIO );
diff --git a/libcdi/src/pio_comm.h b/libcdi/src/pio_comm.h
index 6e014ec..9fdfc2f 100644
--- a/libcdi/src/pio_comm.h
+++ b/libcdi/src/pio_comm.h
@@ -37,7 +37,7 @@ void     commDefNProcsIO        ( int );
 int      commInqNProcsIO        ( void );
 int      commInqNProcsModel     ( void );
 int      commInqIsProcIO        ( void );
-void     commDefIOMode          ( int, int, int );
+void     commDefIOMode          ( int );
 int      commInqIOMode          ( void );
 
 void     commDefCommPio         ( void );
diff --git a/libcdi/src/pio_impl.h b/libcdi/src/pio_impl.h
index 089f218..0a5e008 100644
--- a/libcdi/src/pio_impl.h
+++ b/libcdi/src/pio_impl.h
@@ -65,7 +65,7 @@ void listSetForeach(listSet *q, elemOp func, void *data);
 int       fowMPINONB ( const char * );
 int       fcMPINONB ( int );
 size_t    fwMPINONB( int, int, const void *, size_t );
-void      initMPINONB ( void );
+void initMPINONB(void (*postCommSetupActions)(void));
 void      finalizeMPINONB ( void );
 
 
@@ -73,7 +73,7 @@ void      finalizeMPINONB ( void );
 int pioSendClose(int);
 int pioSendOpen(const char *);
 size_t pioSendWrite(int, int, const void *, size_t);
-void pioSendInitialize(void);
+void pioSendInitialize(void (*postCommSetupActions)(void));
 void pioSendFinalize(void);
 
 
@@ -87,7 +87,7 @@ void      fpgPOSIXFPGUARDSENDRECV ( void );
 int       fowPOSIXFPGUARDSENDRECV ( const char * );
 int       fcPOSIXFPGUARDSENDRECV ( int );
 size_t    fwPOSIXFPGUARDSENDRECV ( int, int, const void *, size_t );
-void      initPOSIXFPGUARDSENDRECV ( void );
+void      initPOSIXFPGUARDSENDRECV(void (*postCommSetupActions)(void));
 void      finalizePOSIXFPGUARDSENDRECV ( void );
 
 /* pio_posixnonb.c */
diff --git a/libcdi/src/pio_interface.c b/libcdi/src/pio_interface.c
index fbe8791..7f1bb61 100644
--- a/libcdi/src/pio_interface.c
+++ b/libcdi/src/pio_interface.c
@@ -13,6 +13,8 @@
 #endif
 
 #include "cdi.h"
+#include "cdipio.h"
+#include "dmemory.h"
 #include "pio_util.h"
 #include "vlist_var.h"
 
@@ -64,6 +66,15 @@ static int cmp ( const void * va, const void * vb )
   return (( **a < **b ) - ( **a > **b ));
 }
 
+void memcpyPackFunc(void *dataDesc, void *buf, int size, int *pos,
+                    void *context)
+{
+  struct memCpyDataDesc *p = dataDesc;
+  xassert(size >= *pos && (size_t)(size - *pos) >= p->obj_size);
+  memcpy((unsigned char *)buf + *pos, p->obj, p->obj_size);
+  *pos += (int)p->obj_size;
+}
+
 /****************************************************/
 
 static void
@@ -261,7 +272,7 @@ varsMapNDeco(int nNodes, int *nodeSizes)
   for ( i = 0; i < nStreams; i++ )
     streamSizes[i] = streamInqNvars ( * ( resHs + i ));
 
-  nVars = xsum ( nStreams, streamSizes );
+  nVars = sum_int(nStreams, streamSizes);
   varSizes   = xmalloc ( nVars * sizeof ( varSizes[0] ));
   varMapping = xmalloc ( nVars * sizeof ( varMapping[0] ));
 
@@ -372,7 +383,7 @@ modelWinDefBufferSizes(void)
             + sizeof (double) - 1
             /* one header for data record, one for corresponding part
              * descriptor*/
-            + 2 * sizeof (union winHeaderEntry)
+            + 2 * sizeof (struct winHeaderEntry)
             /* FIXME: heuristic for size of packed Xt_idxlist */
             + sizeof (Xt_int) * collIDchunk * 3;
         }
@@ -385,7 +396,7 @@ modelWinDefBufferSizes(void)
           {
             collIndex[collID].numRPCRecords += numRPCFuncs;
             txWin[collID].size +=
-              numRPCFuncs * sizeof (union winHeaderEntry)
+              numRPCFuncs * sizeof (struct winHeaderEntry)
               + MAXDATAFILENAME
               /* data part of streamDefTimestep */
               + (2 * CDI_MAX_NAME + sizeof (taxis_t));
@@ -399,7 +410,7 @@ modelWinDefBufferSizes(void)
       txWin[collID].dictDataUsed = 1;
       txWin[collID].dictRPCUsed = 0;
       /* account for size header */
-      txWin[collID].size += sizeof (union winHeaderEntry);
+      txWin[collID].size += sizeof (struct winHeaderEntry);
       txWin[collID].size = roundUpToMultiple(txWin[collID].size,
                                              PIO_WIN_ALIGN);
       sumWinBufferSize += txWin[collID].size;
@@ -424,13 +435,13 @@ static
 
   xassert ( collID                >= 0         &&
             collID                < nProcsColl &&
-            txWin[collID].buffer     != NULL      &&
             txWin != NULL      &&
+            txWin[collID].buffer     != NULL      &&
             txWin[collID].size >= 0         &&
             txWin[collID].size <= MAXWINBUFFERSIZE);
   memset(txWin[collID].buffer, 0, txWin[collID].size);
   txWin[collID].head = txWin[collID].buffer
-    + txWin[collID].dictSize * sizeof (union winHeaderEntry);
+    + txWin[collID].dictSize * sizeof (struct winHeaderEntry);
   txWin[collID].refuseFuncCall = 0;
   txWin[collID].dictDataUsed = 1;
   txWin[collID].dictRPCUsed = 0;
@@ -452,6 +463,9 @@ void modelWinCreate ( void )
   modelWinDefBufferSizes ();
   ranks[0] = commInqNProcsModel ();
 
+  MPI_Info no_locks_info;
+  xmpi(MPI_Info_create(&no_locks_info));
+  xmpi(MPI_Info_set(no_locks_info, "no_locks", "true"));
   for ( collID = 0; collID < nProcsColl; collID ++ )
     {
       xassert(txWin[collID].size > 0);
@@ -460,14 +474,18 @@ void modelWinCreate ( void )
                          &txWin[collID].buffer));
       xassert ( txWin[collID].buffer != NULL );
       txWin[collID].head = txWin[collID].buffer
-        + txWin[collID].dictSize * sizeof (union winHeaderEntry);
+        + txWin[collID].dictSize * sizeof (struct winHeaderEntry);
       xmpi(MPI_Win_create(txWin[collID].buffer, (MPI_Aint)txWin[collID].size, 1,
-                          MPI_INFO_NULL, commInqCommsIO(collID),
+                          no_locks_info, commInqCommsIO(collID),
                           &txWin[collID].win));
-      xmpi(MPI_Comm_group(commInqCommsIO(collID), &txWin[collID].ioGroup));
-      xmpi(MPI_Group_incl(txWin[collID].ioGroup, 1, ranks,
-                          &txWin[collID].ioGroup ));
+      MPI_Group commGroup;
+      xmpi(MPI_Comm_group(commInqCommsIO(collID), &commGroup));
+      xmpi(MPI_Group_incl(commGroup, 1, ranks, &txWin[collID].ioGroup));
+      xmpi(MPI_Group_free(&commGroup));
     }
+
+  xmpi(MPI_Info_free(&no_locks_info));
+
   xdebug("%s", "RETURN, CREATED MPI_WIN'S");
 }
 
@@ -475,33 +493,37 @@ void modelWinCreate ( void )
 
 static void
 modelWinEnqueue(int collID,
-                union winHeaderEntry header, const void *data, size_t size)
+                struct winHeaderEntry header, const void *data,
+                valPackFunc packFunc)
 {
-  union winHeaderEntry *winDict
-    = (union winHeaderEntry *)txWin[collID].buffer;
+  struct winHeaderEntry *winDict
+    = (struct winHeaderEntry *)txWin[collID].buffer;
   int targetEntry;
-  if (header.dataRecord.streamID > 0)
+  if (header.id > 0 || header.id == PARTDESCMARKER)
+    targetEntry = (txWin[collID].dictDataUsed)++;
+  else
+    targetEntry = txWin[collID].dictSize - ++(txWin[collID].dictRPCUsed);
+  if (header.id > 0)
     {
-      targetEntry = (txWin[collID].dictDataUsed)++;
-      int offset = header.dataRecord.offset
+      int offset = header.offset
         = (int)roundUpToMultiple(txWin[collID].head - txWin[collID].buffer,
                                  sizeof (double));
-      memcpy(txWin[collID].buffer + offset, data, size);
-      txWin[collID].head = txWin[collID].buffer + offset + size;
+      MPI_Comm comm = commInqCommsIO(collID);
+      packFunc((void *)data, txWin[collID].buffer, (int)txWin[collID].size,
+               &offset, &comm);
+      txWin[collID].head = txWin[collID].buffer + offset;
     }
-  else if (header.partDesc.partDescMarker == PARTDESCMARKER)
+  else if (header.id == PARTDESCMARKER)
     {
-      targetEntry = (txWin[collID].dictDataUsed)++;
-      Xt_uid uid = header.partDesc.uid;
+      Xt_uid uid = header.specific.partDesc.uid;
       int offset = -1;
       /* search if same uid entry has already been enqueued */
       for (int entry = 2; entry < targetEntry; entry += 2)
         {
-          xassert(winDict[entry].partDesc.partDescMarker
-                  == PARTDESCMARKER);
-          if (winDict[entry].partDesc.uid == uid)
+          xassert(winDict[entry].id == PARTDESCMARKER);
+          if (winDict[entry].specific.partDesc.uid == uid)
             {
-              offset = winDict[entry].partDesc.offset;
+              offset = winDict[entry].offset;
               break;
             }
         }
@@ -509,46 +531,79 @@ modelWinEnqueue(int collID,
         {
           /* not yet used partition descriptor, serialize at
            * current position */
-          int position = 0;
-          MPI_Comm comm = commInqCommsIO(collID);
-          header.partDesc.offset
+          int position = header.offset
             = (int)(txWin[collID].head - txWin[collID].buffer);
-          size_t size = xt_idxlist_get_pack_size((Xt_idxlist)data, comm);
-          size_t remaining_size = txWin[collID].size
-            - (txWin[collID].head - txWin[collID].buffer);
-          xassert(size <= remaining_size);
-          xt_idxlist_pack((Xt_idxlist)data, txWin[collID].head,
-                          (int)remaining_size, &position, comm);
-          txWin[collID].head += position;
+          MPI_Comm comm = commInqCommsIO(collID);
+          packFunc((void *)data, txWin[collID].buffer, (int)txWin[collID].size,
+                   &position, &comm);
+          txWin[collID].head = txWin[collID].buffer + position;
         }
       else
         /* duplicate entries are copied only once per timestep */
-        header.partDesc.offset = offset;
+        header.offset = offset;
     }
   else
     {
-      targetEntry = txWin[collID].dictSize - ++(txWin[collID].dictRPCUsed);
-      if (header.funcCall.funcID == STREAMOPEN)
-        {
-          header.funcCall.funcArgs.newFile.offset
-            = (int)(txWin[collID].head - txWin[collID].buffer);
-          memcpy(txWin[collID].head, data, size);
-          txWin[collID].head += size;
-        }
-      else if (header.funcCall.funcID == STREAMDEFTIMESTEP)
+      int position = header.offset
+        = (int)(txWin[collID].head - txWin[collID].buffer);
+      MPI_Comm comm = commInqCommsIO(collID);
+      packFunc((void *)data, txWin[collID].buffer, (int)txWin[collID].size,
+               &position, &comm);
+      txWin[collID].head = txWin[collID].buffer + position;
+    }
+  winDict[targetEntry] = header;
+}
+
+static void
+cdiPio_xt_idxlist_pack_wrap(void *data, void *buf, int size, int *pos,
+                            void *context)
+{
+  MPI_Comm comm = *(MPI_Comm *)context;
+  int pack_size = xt_idxlist_get_pack_size((Xt_idxlist)data, comm);
+  xassert(size >= *pos && pack_size <= size - *pos);
+  xt_idxlist_pack((Xt_idxlist)data, (unsigned char *)buf,
+                  size, pos, comm);
+}
+
+static inline void
+collWait(int collID)
+{
+  if (txWin[collID].postSet)
+    {
+      xmpi(MPI_Win_wait(txWin[collID].win));
+      txWin[collID].postSet = 0;
+      modelWinFlushBuffer(collID);
+    }
+}
+
+static inline void
+collProbe(int collID)
+{
+  if (txWin[collID].postSet)
+    {
+      int flag;
+      xmpi(MPI_Win_test(txWin[collID].win, &flag));
+      if (flag)
         {
-          header.funcCall.funcArgs.streamNewTimestep.offset
-            = (int)(txWin[collID].head - txWin[collID].buffer);
-          memcpy(txWin[collID].head, data, size);
-          txWin[collID].head += size;
+          txWin[collID].postSet = 0;
+          modelWinFlushBuffer(collID);
         }
     }
-  winDict[targetEntry] = header;
 }
 
 void
-pioBufferPartData(int streamID, int varID, const double *data,
-                  int nmiss, Xt_idxlist partDesc)
+cdiPioRDMAProgress()
+{
+  int nProcsColl = commInqNProcsColl();
+  for (int collID = 0; collID < nProcsColl; collID++)
+    collProbe(collID);
+}
+
+
+static void
+pioBufferPartData_(int streamID, int varID,
+                   const void *packData, valPackFunc packDataFunc,
+                   int nmiss, Xt_idxlist partDesc)
 {
   int vlistID, collID = CDI_UNDEFID;
 
@@ -558,39 +613,105 @@ pioBufferPartData(int streamID, int varID, const double *data,
             collID         <  commInqNProcsColl () &&
             txWin != NULL);
 
-  if (txWin[collID].postSet)
-    {
-      xmpi(MPI_Win_wait(txWin[collID].win));
-      txWin[collID].postSet = 0;
-      modelWinFlushBuffer ( collID );
-    }
+  collWait(collID);
 
-  Xt_int chunk = xt_idxlist_get_num_indices(partDesc);
-  xassert(chunk <= INT_MAX);
 
-  union winHeaderEntry dataHeader
-    = { .dataRecord = { streamID, varID, -1, nmiss } };
-  modelWinEnqueue(collID, dataHeader, data, chunk * sizeof (data[0]));
+  struct winHeaderEntry dataHeader
+    = { .id = streamID, .specific.dataRecord = { varID, nmiss }, .offset = -1 };
+  modelWinEnqueue(collID, dataHeader, packData, packDataFunc);
   {
-    union winHeaderEntry partHeader
-      = { .partDesc = { .partDescMarker = PARTDESCMARKER,
-                        .uid = xt_idxlist_get_uid(partDesc),
-                        .offset = 0 } };
-    modelWinEnqueue(collID, partHeader, partDesc, 0);
+    struct winHeaderEntry partHeader
+      = { .id = PARTDESCMARKER,
+          .specific.partDesc = { .uid = xt_idxlist_get_uid(partDesc) },
+          .offset = 0 };
+    modelWinEnqueue(collID, partHeader, partDesc, cdiPio_xt_idxlist_pack_wrap);
   }
 
   txWin[collID].refuseFuncCall = 1;
 }
 
+void
+pioBufferPartData(int streamID, int varID, const double *data,
+                  int nmiss, Xt_idxlist partDesc)
+{
+  int chunk = xt_idxlist_get_num_indices(partDesc);
+  xassert(chunk <= INT_MAX);
+  pioBufferPartData_(streamID, varID,
+                     &(struct memCpyDataDesc){data, chunk * sizeof (data[0])},
+                     memcpyPackFunc,
+                     nmiss, partDesc);
+}
+
+struct scatterGatherDesc
+{
+  void *data;
+  const int *blocklengths, *displacements;
+  size_t elemSize;
+  unsigned numBlocks;
+  unsigned numElems;
+};
+
+static void
+scatterGatherPackFunc(void *dataDesc, void *buf, int size, int *pos,
+                      void *context)
+{
+  const struct scatterGatherDesc *p = dataDesc;
+  unsigned numBlocks = p->numBlocks;
+  const int *bls = p->blocklengths, *disps = p->displacements;
+  int pos_ = *pos;
+  unsigned char *dstBuf = buf + pos_, *bufEnd = (unsigned char *)buf + size;
+  size_t elemSize = p->elemSize;
+  const unsigned char *data = p->data;
+  unsigned copyCount = 0, numElems = p->numElems;
+  for (unsigned j = 0; j < numBlocks && copyCount < numElems; ++j)
+    {
+      int bl = bls[j];
+      if (bl + copyCount > numElems)
+        {
+          bl = numElems - copyCount;
+          Warning("%s: %s", "streamWriteScatteredVarPart",
+                  "blocks longer than number of elements in index list!");
+        }
+      if (bl > 0)
+        {
+          size_t bsize = (size_t)bl * elemSize;
+          xassert(dstBuf + bsize <= bufEnd);
+          memcpy(dstBuf, data + elemSize * disps[j], bsize);
+          dstBuf += bsize;
+        }
+    }
+  *pos = (int)(dstBuf - (unsigned char *)buf);
+}
+
+
+void
+cdiPioBufferPartDataGather(int streamID, int varID, const double *data,
+                           int numBlocks, const int blocklengths[],
+                           const int displacements[],
+                           int nmiss, Xt_idxlist partDesc)
+{
+  xassert(numBlocks >= 0);
+  pioBufferPartData_(streamID, varID,
+                     &(struct scatterGatherDesc)
+                     { .data = (void *)data, .blocklengths = blocklengths,
+                       .displacements = displacements,
+                       .elemSize = sizeof (data[0]), .numBlocks = numBlocks,
+                       .numElems
+                         = (unsigned)xt_idxlist_get_num_indices(partDesc) },
+                     scatterGatherPackFunc,
+                     nmiss, partDesc);
+}
+
+
 /************************************************************************/
 
-void pioBufferFuncCall(union winHeaderEntry header,
-                       const void *data, size_t data_len)
+void pioBufferFuncCall(struct winHeaderEntry header,
+                       const void *data, valPackFunc dataPackFunc)
 {
   int rankGlob = commInqRankGlob ();
   int root = commInqRootGlob ();
   int collID, nProcsColl = commInqNProcsColl ();
-  int funcID = header.funcCall.funcID;
+  int funcID = header.id;
 
   xassert(funcID >= MINFUNCID && funcID <= MAXFUNCID);
   xdebug("%s, func: %s", "START", funcMap[(-1 - funcID)]);
@@ -601,16 +722,11 @@ void pioBufferFuncCall(union winHeaderEntry header,
 
   for (collID = 0; collID < nProcsColl; ++collID)
     {
-      if (txWin[collID].postSet)
-        {
-          xmpi(MPI_Win_wait(txWin[collID].win));
-          txWin[collID].postSet = 0;
-          modelWinFlushBuffer ( collID );
-        }
+      collWait(collID);
       xassert(txWin[collID].dictRPCUsed + txWin[collID].dictDataUsed
               < txWin[collID].dictSize);
       xassert(txWin[collID].refuseFuncCall == 0);
-      modelWinEnqueue(collID, header, data, data_len);
+      modelWinEnqueue(collID, header, data, dataPackFunc);
     }
 
   xdebug("%s", "RETURN");
@@ -618,6 +734,12 @@ void pioBufferFuncCall(union winHeaderEntry header,
 
 #endif
 
+
+void
+cdiPioNoPostCommSetup(void)
+{
+}
+
 /*****************************************************************************/
 
 /* pioInit definition must currently compile even in non-MPI configurations */
@@ -644,6 +766,8 @@ void pioBufferFuncCall(union winHeaderEntry header,
   @param partInflate allow for array partitions on comute
   PE that are at most sized \f$ partInflate * \lceil arraySize /
   numComputePEs \rceil \f$
+  @param postSetupActions function which is called by all I/O servers
+  after communicator split
   @return int indicating wether the calling PE is a calcutator (1) or not (0)
 */
 
@@ -654,11 +778,14 @@ static int xtInitByCDI = 0;
 
 MPI_Comm
 pioInit(MPI_Comm commGlob, int nProcsIO, int IOMode,
-        int *pioNamespace, float partInflate)
+        int *pioNamespace, float partInflate,
+        void (*postCommSetupActions)(void))
 {
 #ifdef USE_MPI
   int sizeGlob;
 
+  namespaceSwitchSet(NSSWITCH_WARNING, NSSW_FUNC(cdiPioWarning));
+
   if ( IOMode < PIO_MINIOMODE || IOMode > PIO_MAXIOMODE )
     xabort ( "IOMODE IS NOT VALID." );
 
@@ -668,9 +795,7 @@ pioInit(MPI_Comm commGlob, int nProcsIO, int IOMode,
 #endif
 
   if ((xtInitByCDI = (!xt_initialized() || xt_finalized())))
-    {
-      xt_initialize(commGlob);
-    }
+    xt_initialize(commGlob);
   commInit ();
   commDefCommGlob ( commGlob );
   sizeGlob = commInqSizeGlob ();
@@ -681,7 +806,7 @@ pioInit(MPI_Comm commGlob, int nProcsIO, int IOMode,
            "nProcsIO=%d, sizeGlob=%d\n", nProcsIO, sizeGlob);
 
   commDefNProcsIO ( nProcsIO );
-  commDefIOMode   ( IOMode, PIO_MAXIOMODE, PIO_MINIOMODEWITHSPECIALPROCS );
+  commDefIOMode   ( IOMode );
   commDefCommPio  ();
 
   xassert(partInflate >= 1.0);
@@ -700,12 +825,13 @@ pioInit(MPI_Comm commGlob, int nProcsIO, int IOMode,
       namespaceSwitchSet(NSSWITCH_ABORT, NSSW_FUNC(cdiAbortC_MPI));
       namespaceSwitchSet(NSSWITCH_FILE_OPEN, NSSW_FUNC(pioFileOpen));
       namespaceSwitchSet(NSSWITCH_FILE_CLOSE, NSSW_FUNC(pioFileClose));
-      IOServer ();
+      IOServer(postCommSetupActions);
       namespaceDelete(0);
+      namespaceNew();
       commDestroy ();
-      xt_finalize();
-      MPI_Finalize ();
-      exit ( EXIT_SUCCESS );
+      if (xtInitByCDI)
+        xt_finalize();
+      return MPI_COMM_NULL;
     }
   else
     cdiPioClientSetup(&pioNamespace_, pioNamespace);
@@ -782,6 +908,10 @@ void pioFinalize ( void )
 #ifdef USE_MPI
   int collID, ibuffer = 1111;
   xdebug("%s", "START");
+
+  /* pioNamespace_ is unchanged on I/O servers */
+  if (pioNamespace_ == -1)
+    return;
   namespaceDelete(pioNamespace_);
   for ( collID = 0; collID < commInqNProcsColl (); collID++ )
     {
@@ -802,7 +932,7 @@ void pioFinalize ( void )
 void pioWriteTimestep()
 {
 #ifdef USE_MPI
-  int collID, iAssert = 0;
+  int collID, iAssert = MPI_MODE_NOPUT;
   /* int tokenEnd = END; */
   int rankGlob = commInqRankGlob ();
   int nProcsColl = commInqNProcsColl ();
@@ -821,18 +951,14 @@ void pioWriteTimestep()
 
   for ( collID = 0; collID < nProcsColl; collID++ )
     {
-      if (txWin[collID].postSet)
-        {
-          xmpi(MPI_Win_wait(txWin[collID].win));
-          txWin[collID].postSet = 0;
-          modelWinFlushBuffer ( collID );
-        }
-      union winHeaderEntry header
-        = { .headerSize = { .sizeID = HEADERSIZEMARKER,
-                            .numDataEntries = txWin[collID].dictDataUsed,
-                            .numRPCEntries = txWin[collID].dictRPCUsed } };
-      union winHeaderEntry *winDict
-        = (union winHeaderEntry *)txWin[collID].buffer;
+      collWait(collID);
+      struct winHeaderEntry header
+        = { .id = HEADERSIZEMARKER,
+            .specific.headerSize
+            = { .numDataEntries = txWin[collID].dictDataUsed,
+                .numRPCEntries = txWin[collID].dictRPCUsed } };
+      struct winHeaderEntry *winDict
+        = (struct winHeaderEntry *)txWin[collID].buffer;
       winDict[0] = header;
 
       xmpi(MPI_Win_post(txWin[collID].ioGroup, iAssert, txWin[collID].win));
@@ -851,7 +977,8 @@ streamWriteVarPart(int streamID, int varID, const void *data,
 {
   if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
 
-  check_parg(data);
+  int chunk = xt_idxlist_get_num_indices(partDesc);
+  xassert(chunk == 0 || data);
 
   void (*myStreamWriteVarPart)(int streamID, int varID, const void *data,
                                int nmiss, Xt_idxlist partDesc)
@@ -863,6 +990,34 @@ streamWriteVarPart(int streamID, int varID, const void *data,
 
   myStreamWriteVarPart(streamID, varID, data, nmiss, partDesc);
 }
+
+void
+streamWriteScatteredVarPart(int streamID, int varID, const void *data,
+                            int numBlocks, const int blocklengths[],
+                            const int displacements[],
+                            int nmiss, Xt_idxlist partDesc)
+{
+  if ( CDI_Debug ) Message("streamID = %d varID = %d", streamID, varID);
+
+  int chunk = xt_idxlist_get_num_indices(partDesc);
+  xassert(chunk == 0 || data);
+
+  void (*myStreamWriteScatteredVarPart)(int streamID, int varID,
+                                        const void *data,
+                                        int numBlocks, const int blocklengths[],
+                                        const int displacements[],
+                                        int nmiss, Xt_idxlist partDesc)
+    = (void (*)(int, int, const void *, int, const int[], const int[], int,
+                Xt_idxlist))
+    namespaceSwitchGet(NSSWITCH_STREAM_WRITE_SCATTERED_VAR_PART_).func;
+
+  if (!myStreamWriteScatteredVarPart)
+    xabort("local part writing is unsupported!");
+
+  myStreamWriteScatteredVarPart(streamID, varID, data,
+                                numBlocks, blocklengths, displacements,
+                                nmiss, partDesc);
+}
 #endif
 
 
diff --git a/libcdi/src/pio_interface.h b/libcdi/src/pio_interface.h
index 7d128b9..8801e32 100644
--- a/libcdi/src/pio_interface.h
+++ b/libcdi/src/pio_interface.h
@@ -10,14 +10,29 @@
 #include <mpi.h>
 #include <yaxt.h>
 
+#include "resource_handle.h"
 #include "pio_rpc.h"
 
 void
 pioBufferPartData(int streamID, int varID, const double *data,
                   int nmiss, Xt_idxlist partDesc);
-void pioBufferData (int, int, const double *, int );
-void pioBufferFuncCall(union winHeaderEntry header,
-                       const void *data, size_t data_len);
+void
+cdiPioBufferPartDataGather(int streamID, int varID, const double *data,
+                           int numBlocks, const int blocklengths[],
+                           const int displacements[],
+                           int nmiss, Xt_idxlist partDesc);
+
+void pioBufferFuncCall(struct winHeaderEntry header,
+                       const void *data, valPackFunc dataPackFunc);
+
+
+struct memCpyDataDesc
+{
+  const void *obj;
+  size_t obj_size;
+};
+
+void memcpyPackFunc(void *dataDesc, void *buf, int size, int *pos, void *context);
 
 extern float cdiPIOpartInflate_;
 
diff --git a/libcdi/src/pio_list_set.c b/libcdi/src/pio_list_set.c
index 3b821ae..eb52fe0 100644
--- a/libcdi/src/pio_list_set.c
+++ b/libcdi/src/pio_list_set.c
@@ -9,6 +9,7 @@
 #include <stdarg.h>
 
 #include "cdi.h"
+#include "dmemory.h"
 
 #ifdef USE_MPI
 #include "pio_impl.h"
diff --git a/libcdi/src/pio_mpinonb.c b/libcdi/src/pio_mpinonb.c
index 0b01618..3bb63f4 100644
--- a/libcdi/src/pio_mpinonb.c
+++ b/libcdi/src/pio_mpinonb.c
@@ -11,6 +11,7 @@
 #include <mpi.h>
 
 #include "cdi.h"
+#include "dmemory.h"
 #include "pio.h"
 #include "pio_comm.h"
 #include "pio_impl.h"
@@ -323,13 +324,14 @@ void finalizeMPINONB(void)
 
 /***************************************************************/
 
-void initMPINONB ( void )
+void
+initMPINONB(void (*postCommSetupActions)(void))
 {
   commDefCommColl ( 1 );
   commSendNodeInfo ();
   commRecvNodeMap ();
   commDefCommsIO ();
-
+  postCommSetupActions();
   bibAFiledataM = listSetNew( destroyAFiledataMPINONB, compareNamesMPINONB );
   
   if ( bibAFiledataM == NULL )
diff --git a/libcdi/src/pio_posixasynch.c b/libcdi/src/pio_posixasynch.c
index b5ac645..18a1a73 100644
--- a/libcdi/src/pio_posixasynch.c
+++ b/libcdi/src/pio_posixasynch.c
@@ -10,22 +10,23 @@
 #ifdef USE_MPI
 #ifndef _SX
 
+#include <aio.h>
+#include <errno.h>
+#include <fcntl.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <aio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <fcntl.h>
+#include <unistd.h>
+
+#include <mpi.h>
 
-#include "mpi.h"
 #include "pio.h"
 #include "pio_comm.h"
 #include "pio_impl.h"
 #include "pio_util.h"
+#include "dmemory.h"
 
 extern char * command2charP[6];
 
diff --git a/libcdi/src/pio_posixfpguardsendrecv.c b/libcdi/src/pio_posixfpguardsendrecv.c
index 024fd08..87913de 100644
--- a/libcdi/src/pio_posixfpguardsendrecv.c
+++ b/libcdi/src/pio_posixfpguardsendrecv.c
@@ -15,12 +15,13 @@
 #include <stdbool.h>
 #include <string.h>
 
-#include "mpi.h"
+#include <mpi.h>
+
 #include "pio.h"
 #include "pio_comm.h"
 #include "pio_impl.h"
 #include "pio_util.h"
-
+#include "dmemory.h"
 
 extern char * command2charP[6];
 
@@ -519,27 +520,22 @@ finalizePOSIXFPGUARDSENDRECV(void)
 
 /***************************************************************/
 
-void initPOSIXFPGUARDSENDRECV ( void )
+void
+initPOSIXFPGUARDSENDRECV(void (*postCommSetupActions)(void))
 {
   if ( commInqSizeNode () < 2 ) 
     xabort ( "USAGE: # IO PROCESSES ON A PHYSICAL NODE >= 2" );
-  
-  if ( commInqRankNode () == commInqSpecialRankNode ()) 
-    {
-      commDefCommColl ( 0 );
-      commSendNodeInfo ();
-      commRecvNodeMap ();
-      commDefCommsIO ();
-      fpgPOSIXFPGUARDSENDRECV ();
-    }
+
+  int isCollector = commInqRankNode () != commInqSpecialRankNode ();
+  commDefCommColl(isCollector);
+  commSendNodeInfo ();
+  commRecvNodeMap ();
+  commDefCommsIO ();
+  postCommSetupActions();
+  if (!isCollector)
+    fpgPOSIXFPGUARDSENDRECV ();
   else
-    {
-      commDefCommColl ( 1 );
-      commSendNodeInfo ();
-      commRecvNodeMap ();
-      commDefCommsIO ();
-      bibAFiledataPF = listSetNew( destroyAFiledataPF, compareNamesAPF );
-    }
+    bibAFiledataPF = listSetNew( destroyAFiledataPF, compareNamesAPF );
 }
 
 #endif
diff --git a/libcdi/src/pio_posixnonb.c b/libcdi/src/pio_posixnonb.c
index 216b46f..7ccbc65 100644
--- a/libcdi/src/pio_posixnonb.c
+++ b/libcdi/src/pio_posixnonb.c
@@ -8,13 +8,15 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <mpi.h>
 
-#include "mpi.h"
 #include "pio.h"
 #include "pio_comm.h"
 #include "pio_impl.h"
 #include "pio_util.h"
 
+#include "dmemory.h"
+
 extern char * command2charP[6];
 
 extern char *token;
diff --git a/libcdi/src/pio_record_send.c b/libcdi/src/pio_record_send.c
index 60a6c13..d633bed 100644
--- a/libcdi/src/pio_record_send.c
+++ b/libcdi/src/pio_record_send.c
@@ -7,9 +7,11 @@
 #include <inttypes.h>
 #include <stdlib.h>
 
+#include "cdipio.h"
 #include "pio_comm.h"
 #include "pio_impl.h"
 #include "pio_util.h"
+#include "dmemory.h"
 
 extern char *command2charP[];
 extern double accumWait;
@@ -319,36 +321,30 @@ pioSendFinalize(void)
 }
 
 void
-pioSendInitialize(void)
+pioSendInitialize(void (*postCommSetupActions)(void))
 {
   if (commInqSizeNode() < 2)
     xabort ( "USAGE: # IO PROCESSES ON A PHYSICAL NODE >= 2" );
 
 
-  if ( commInqRankNode () == commInqSpecialRankNode ())
-    {
-      commDefCommColl ( 0 );
-      commSendNodeInfo ();
-      commRecvNodeMap ();
-      commDefCommsIO ();
-      switch ( commInqIOMode ())
-        {
-        case PIO_WRITER:
-          pioWriterStdIO();
-          break;
-        case PIO_ASYNCH:
-          pioWriterAIO();
-          break;
-        }
-    }
+  int isCollector = commInqRankNode () != commInqSpecialRankNode ();
+  commDefCommColl(isCollector);
+  commSendNodeInfo();
+  commRecvNodeMap();
+  commDefCommsIO();
+  postCommSetupActions();
+  if (!isCollector)
+    switch ( commInqIOMode ())
+      {
+      case PIO_WRITER:
+        pioWriterStdIO();
+        break;
+      case PIO_ASYNCH:
+        pioWriterAIO();
+        break;
+      }
   else
-    {
-      commDefCommColl ( 1 );
-      commSendNodeInfo ();
-      commRecvNodeMap ();
-      commDefCommsIO ();
-      bibRemoteFileBuf = listSetNew(destroyRemoteFileBuf, compareNames);
-    }
+    bibRemoteFileBuf = listSetNew(destroyRemoteFileBuf, compareNames);
 }
 
 #endif
diff --git a/libcdi/src/pio_rpc.h b/libcdi/src/pio_rpc.h
index f02caae..69c6c63 100644
--- a/libcdi/src/pio_rpc.h
+++ b/libcdi/src/pio_rpc.h
@@ -37,48 +37,48 @@ extern const char * const funcMap[numRPCFuncs];
 
 struct headerSize
 {
-  int sizeID, numDataEntries, numRPCEntries;
+  int numDataEntries, numRPCEntries;
 };
 
 struct dataRecord
 {
-  int streamID, varID, offset, nmiss;
+  int varID, nmiss;
 };
 
-struct funcCallDesc
+union funcArgs
 {
-  int funcID;
-  union
+  struct
+  {
+    int streamID, vlistID;
+  } streamChange;
+  struct
+  {
+    int streamID, tsID;
+  } streamNewTimestep;
+  struct
   {
-    struct
-    {
-      int streamID, vlistID;
-    } streamChange;
-    struct
-    {
-      int streamID, tsID, offset;
-    } streamNewTimestep;
-    struct
-    {
-      int fnamelen, offset, filetype;
-    } newFile;
-  } funcArgs;
+    int fnamelen, filetype;
+  } newFile;
 };
 
 /* Describes offset and ID of serialized partition descriptor.
  * partDescMarker == PARTDESCMARKER, always. */
 struct partDescRecord
 {
-  int partDescMarker, offset;
   Xt_uid uid;
 };
 
-union winHeaderEntry
+struct winHeaderEntry
 {
-  struct headerSize headerSize;
-  struct dataRecord dataRecord;
-  struct funcCallDesc funcCall;
-  struct partDescRecord partDesc;
+  int id;
+  union
+  {
+    struct headerSize headerSize;
+    struct dataRecord dataRecord;
+    union funcArgs funcArgs;
+    struct partDescRecord partDesc;
+  }  specific;
+  int offset;
 };
 
 /* round size to next multiple of factor */
diff --git a/libcdi/src/pio_serialize.c b/libcdi/src/pio_serialize.c
index 8296d7b..4f13678 100644
--- a/libcdi/src/pio_serialize.c
+++ b/libcdi/src/pio_serialize.c
@@ -4,6 +4,8 @@
 
 #ifdef USE_MPI
 
+#include <inttypes.h>
+
 #include <mpi.h>
 
 #include "cdi.h"
@@ -21,9 +23,11 @@ static struct
 #define CDI_DT_MATCH_NEEDED 1
   { DATATYPE_INT8, MPI_SIGNED_CHAR },
   { DATATYPE_INT16, MPI_SHORT },
+  { DATATYPE_UINT32, MPI_INT },
 #else
   { DATATYPE_INT8, MPI_INT8_T },
   { DATATYPE_INT16, MPI_INT16_T },
+  { DATATYPE_UINT32, MPI_UINT32_T },
 #endif
   { DATATYPE_INT, MPI_INT },
   { DATATYPE_FLT64, MPI_DOUBLE },
@@ -56,12 +60,15 @@ static inline void
 }
 
 static void
-  setupDtDict()
+setupDtDict()
 {
   dtDictFixMPIType(lookupDt(DATATYPE_INT8), MPI_TYPECLASS_INTEGER,
                    (int)sizeof (int8_t));
-  dtDictFixMPIType(lookupDt(DATATYPE_INT8), MPI_TYPECLASS_INTEGER,
+  dtDictFixMPIType(lookupDt(DATATYPE_INT16), MPI_TYPECLASS_INTEGER,
                    (int)sizeof (int16_t));
+  dtDictFixMPIType(lookupDt(DATATYPE_UINT32), MPI_TYPECLASS_INTEGER,
+                   (int)sizeof (uint32_t));
+  dtDictMatchComplete = 1;
 }
 #endif
 
diff --git a/libcdi/src/pio_server.c b/libcdi/src/pio_server.c
index 0e1e0ac..3487109 100644
--- a/libcdi/src/pio_server.c
+++ b/libcdi/src/pio_server.c
@@ -21,6 +21,8 @@
 #include <yaxt.h>
 
 #include "cdi.h"
+#include "cdipio.h"
+#include "dmemory.h"
 #include "namespace.h"
 #include "taxis.h"
 #include "pio.h"
@@ -118,7 +120,7 @@ collDefBufferSizes()
                     + sizeof (double) - 1
                     /* one header for data record, one for
                      * corresponding part descriptor*/
-                    + 2 * sizeof (union winHeaderEntry)
+                    + 2 * sizeof (struct winHeaderEntry)
                     /* FIXME: heuristic for size of packed Xt_idxlist */
                     + sizeof (Xt_int) * decoChunk * 3;
                   rxWin[modelID].dictSize += 2;
@@ -127,7 +129,7 @@ collDefBufferSizes()
         }
       // space required for the 3 function calls streamOpen, streamDefVlist, streamClose 
       // once per stream and timestep for all collprocs only on the modelproc root
-      rxWin[root].size += numRPCFuncs * sizeof (union winHeaderEntry)
+      rxWin[root].size += numRPCFuncs * sizeof (struct winHeaderEntry)
         /* serialized filename */
         + MAXDATAFILENAME
         /* data part of streamDefTimestep */
@@ -140,7 +142,7 @@ collDefBufferSizes()
     {
       /* account for size header */
       rxWin[modelID].dictSize += 1;
-      rxWin[modelID].size += sizeof (union winHeaderEntry);
+      rxWin[modelID].size += sizeof (struct winHeaderEntry);
       rxWin[modelID].size = roundUpToMultiple(rxWin[modelID].size,
                                               PIO_WIN_ALIGN);
       sumGetBufferSizes += (size_t)rxWin[modelID].size;
@@ -151,16 +153,18 @@ collDefBufferSizes()
 
  /************************************************************************/
 
-static 
- void serverWinCreate ()
-{ 
+static void
+serverWinCreate(void)
+{
   int ranks[1], modelID;
   MPI_Comm commCalc = commInqCommCalc ();
   MPI_Group groupCalc;
   int nProcsModel = commInqNProcsModel ();
+  MPI_Info no_locks_info;
+  xmpi(MPI_Info_create(&no_locks_info));
+  xmpi(MPI_Info_set(no_locks_info, "no_locks", "true"));
 
-  xmpi ( MPI_Win_create ( MPI_BOTTOM, 0, 1, MPI_INFO_NULL,
-                          commCalc, &getWin ));
+  xmpi(MPI_Win_create(MPI_BOTTOM, 0, 1, no_locks_info, commCalc, &getWin));
 
   /* target group */
   ranks[0] = nProcsModel;
@@ -177,16 +181,19 @@ static
       rxWin[modelID].buffer = rxWin[0].buffer + ofs;
     }
 
+  xmpi(MPI_Info_free(&no_locks_info));
+
   xdebug("%s", "created mpi_win, allocated getBuffer");
 }
 
 /************************************************************************/
 
 static void
-readFuncCall(struct funcCallDesc *header)
+readFuncCall(struct winHeaderEntry *header)
 {
   int root = commInqRootGlob ();
-  int funcID = header->funcID;
+  int funcID = header->id;
+  union funcArgs *funcArgs = &(header->specific.funcArgs);
 
   xassert(funcID >= MINFUNCID && funcID <= MAXFUNCID);
   switch ( funcID )
@@ -194,7 +201,7 @@ readFuncCall(struct funcCallDesc *header)
     case STREAMCLOSE:
       {
         int streamID
-          = namespaceAdaptKey2(header->funcArgs.streamChange.streamID);
+          = namespaceAdaptKey2(funcArgs->streamChange.streamID);
         streamClose(streamID);
         xdebug("READ FUNCTION CALL FROM WIN:  %s, streamID=%d,"
                " closed stream",
@@ -203,13 +210,12 @@ readFuncCall(struct funcCallDesc *header)
       break;
     case STREAMOPEN:
       {
-        size_t filenamesz = header->funcArgs.newFile.fnamelen;
+        size_t filenamesz = funcArgs->newFile.fnamelen;
         xassert ( filenamesz > 0 && filenamesz < MAXDATAFILENAME );
         const char *filename
-          = (const char *)(rxWin[root].buffer
-                           + header->funcArgs.newFile.offset);
+          = (const char *)(rxWin[root].buffer + header->offset);
         xassert(filename[filenamesz] == '\0');
-        int filetype = header->funcArgs.newFile.filetype;
+        int filetype = funcArgs->newFile.filetype;
         int streamID = streamOpenWrite(filename, filetype);
         xassert(streamID != CDI_ELIBNAVAIL);
         xdebug("READ FUNCTION CALL FROM WIN:  %s, filenamesz=%zu,"
@@ -221,8 +227,8 @@ readFuncCall(struct funcCallDesc *header)
     case STREAMDEFVLIST:
       {
         int streamID
-          = namespaceAdaptKey2(header->funcArgs.streamChange.streamID);
-        int vlistID = namespaceAdaptKey2(header->funcArgs.streamChange.vlistID);
+          = namespaceAdaptKey2(funcArgs->streamChange.streamID);
+        int vlistID = namespaceAdaptKey2(funcArgs->streamChange.vlistID);
         streamDefVlist(streamID, vlistID);
         xdebug("READ FUNCTION CALL FROM WIN:  %s, streamID=%d,"
                " vlistID=%d, called streamDefVlist ().",
@@ -232,14 +238,12 @@ readFuncCall(struct funcCallDesc *header)
     case STREAMDEFTIMESTEP:
       {
         MPI_Comm commCalc = commInqCommCalc ();
-        int streamID = header->funcArgs.streamNewTimestep.streamID;
+        int streamID = funcArgs->streamNewTimestep.streamID;
         int nspTarget = namespaceResHDecode(streamID).nsp;
         streamID = namespaceAdaptKey2(streamID);
-        int tsID
-          = header->funcArgs.streamNewTimestep.tsID;
         int oldTaxisID
           = vlistInqTaxis(streamInqVlist(streamID));
-        int position = header->funcArgs.streamNewTimestep.offset;
+        int position = header->offset;
         int changedTaxisID
           = taxisUnpack((char *)rxWin[root].buffer, (int)rxWin[root].size,
                         &position, nspTarget, &commCalc, 0);
@@ -247,7 +251,7 @@ readFuncCall(struct funcCallDesc *header)
         taxis_t *changedTaxisPtr = taxisPtr(changedTaxisID);
         ptaxisCopy(oldTaxisPtr, changedTaxisPtr);
         taxisDestroy(changedTaxisID);
-        streamDefTimestep(streamID, tsID);
+        streamDefTimestep(streamID, funcArgs->streamNewTimestep.tsID);
       }
       break;
     default:
@@ -270,10 +274,10 @@ gatherArray(int root, int nProcsModel, int headerIdx,
             int vlistID,
             double *gatherBuf, int *nmiss)
 {
-  union winHeaderEntry *winDict
-    = (union winHeaderEntry *)rxWin[root].buffer;
-  int streamID = winDict[headerIdx].dataRecord.streamID;
-  int varID = winDict[headerIdx].dataRecord.varID;
+  struct winHeaderEntry *winDict
+    = (struct winHeaderEntry *)rxWin[root].buffer;
+  int streamID = winDict[headerIdx].id;
+  int varID = winDict[headerIdx].specific.dataRecord.varID;
   int varShape[3] = { 0, 0, 0 };
   cdiPioQueryVarDims(varShape, vlistID, varID);
   Xt_int varShapeXt[3];
@@ -281,40 +285,43 @@ gatherArray(int root, int nProcsModel, int headerIdx,
   for (unsigned i = 0; i < 3; ++i)
     varShapeXt[i] = varShape[i];
   int varSize = varShape[0] * varShape[1] * varShape[2];
-  int *partOfs = xmalloc(2 * varSize * sizeof (partOfs[0])),
-    *gatherOfs = partOfs + varSize;
+  struct Xt_offset_ext *partExts
+    = xmalloc(nProcsModel * sizeof (partExts[0]));
   Xt_idxlist *part = xmalloc(nProcsModel * sizeof (part[0]));
   MPI_Comm commCalc = commInqCommCalc();
   {
-    int nmiss_ = 0, partOfsOfs = 0;
+    int nmiss_ = 0;
     for (int modelID = 0; modelID < nProcsModel; modelID++)
       {
         struct dataRecord *dataHeader
-          = &((union winHeaderEntry *)
-              rxWin[modelID].buffer)[headerIdx].dataRecord;
-        struct partDescRecord *partHeader
-          = &((union winHeaderEntry *)
-              rxWin[modelID].buffer)[headerIdx + 1].partDesc;
-        int position = partHeader->offset;
-        xassert(namespaceAdaptKey2(dataHeader->streamID) == streamID
+          = &((struct winHeaderEntry *)
+              rxWin[modelID].buffer)[headerIdx].specific.dataRecord;
+        int position =
+          ((struct winHeaderEntry *)rxWin[modelID].buffer)[headerIdx + 1].offset;
+        xassert(namespaceAdaptKey2(((struct winHeaderEntry *)
+                                    rxWin[modelID].buffer)[headerIdx].id)
+                == streamID
                 && dataHeader->varID == varID
-                && partHeader->partDescMarker == PARTDESCMARKER
+                && ((struct winHeaderEntry *)
+                    rxWin[modelID].buffer)[headerIdx + 1].id == PARTDESCMARKER
                 && position > 0
                 && ((size_t)position
-                    >= sizeof (union winHeaderEntry) * rxWin[modelID].dictSize)
+                    >= sizeof (struct winHeaderEntry) * rxWin[modelID].dictSize)
                 && ((size_t)position < rxWin[modelID].size));
         part[modelID] = xt_idxlist_unpack(rxWin[modelID].buffer,
                                           (int)rxWin[modelID].size,
                                           &position, commCalc);
-        Xt_int partSize = xt_idxlist_get_num_indices(part[modelID]);
-        size_t charOfs = (rxWin[modelID].buffer + dataHeader->offset)
+        int partSize = xt_idxlist_get_num_indices(part[modelID]);
+        size_t charOfs = (rxWin[modelID].buffer
+                          + ((struct winHeaderEntry *)
+                             rxWin[modelID].buffer)[headerIdx].offset)
           - rxWin[0].buffer;
         xassert(charOfs % sizeof (double) == 0
                 && charOfs / sizeof (double) + partSize <= INT_MAX);
         int elemOfs = charOfs / sizeof (double);
-        for (int i = 0; i < (int)partSize; ++i)
-          partOfs[partOfsOfs + i] = elemOfs + i;
-        partOfsOfs += partSize;
+        partExts[modelID].start = elemOfs;
+        partExts[modelID].size = partSize;
+        partExts[modelID].stride = 1;
         nmiss_ += dataHeader->nmiss;
       }
     *nmiss = nmiss_;
@@ -329,18 +336,18 @@ gatherArray(int root, int nProcsModel, int headerIdx,
       = xt_idxsection_new(0, 3, varShapeXt, varShapeXt, origin);
     struct Xt_com_list full = { .list = dstList, .rank = 0 };
     gatherXmap = xt_xmap_intersection_new(1, &full, 1, &full, srcList, dstList,
-                                        MPI_COMM_SELF);
+                                          MPI_COMM_SELF);
     xt_idxlist_delete(dstList);
   }
   xt_idxlist_delete(srcList);
-  for (int i = 0; i < varSize; ++i)
-    gatherOfs[i] = i;
 
+  struct Xt_offset_ext gatherExt = { .start = 0, .size = varSize, .stride = 1 };
   Xt_redist gatherRedist
-    = xt_redist_p2p_off_new(gatherXmap, partOfs, gatherOfs, MPI_DOUBLE);
+    = xt_redist_p2p_ext_new(gatherXmap, nProcsModel, partExts, 1, &gatherExt,
+                            MPI_DOUBLE);
   xt_xmap_delete(gatherXmap);
   xt_redist_s_exchange1(gatherRedist, rxWin[0].buffer, gatherBuf);
-  free(partOfs);
+  free(partExts);
   xt_redist_delete(gatherRedist);
 }
 
@@ -463,6 +470,193 @@ cdiPioServerCdfDefVars(stream_t *streamptr)
 
 #endif
 
+struct streamMapping {
+  int streamID, filetype;
+  int firstHeaderIdx, lastHeaderIdx;
+  int numVars, *varMap;
+};
+
+struct streamMap
+{
+  struct streamMapping *entries;
+  int numEntries;
+};
+
+static int
+smCmpStreamID(const void *a_, const void *b_)
+{
+  const struct streamMapping *a = a_, *b = b_;
+  int streamIDa = a->streamID, streamIDb = b->streamID;
+  return (streamIDa > streamIDb) - (streamIDa < streamIDb);
+}
+
+static inline int
+inventorizeStream(struct streamMapping *streamMap, int numStreamIDs,
+                  int *sizeStreamMap_, int streamID, int headerIdx)
+{
+  int sizeStreamMap = *sizeStreamMap_;
+  if (numStreamIDs < sizeStreamMap) ; else
+    {
+      streamMap = xrealloc(streamMap,
+                           (sizeStreamMap *= 2)
+                           * sizeof (streamMap[0]));
+      *sizeStreamMap_ = sizeStreamMap;
+    }
+  streamMap[numStreamIDs].streamID = streamID;
+  streamMap[numStreamIDs].firstHeaderIdx = headerIdx;
+  streamMap[numStreamIDs].lastHeaderIdx = headerIdx;
+  streamMap[numStreamIDs].numVars = -1;
+  int filetype = streamInqFiletype(streamID);
+  streamMap[numStreamIDs].filetype = filetype;
+  if (filetype == FILETYPE_NC || filetype == FILETYPE_NC2
+      || filetype == FILETYPE_NC4)
+    {
+      int vlistID = streamInqVlist(streamID);
+      int nvars = vlistNvars(vlistID);
+      streamMap[numStreamIDs].numVars = nvars;
+      streamMap[numStreamIDs].varMap
+        = xmalloc(sizeof (streamMap[numStreamIDs].varMap[0])
+                  * nvars);
+      for (int i = 0; i < nvars; ++i)
+        streamMap[numStreamIDs].varMap[i] = -1;
+    }
+  return numStreamIDs + 1;
+}
+
+static inline int
+streamIsInList(struct streamMapping *streamMap, int numStreamIDs,
+               int streamIDQuery)
+{
+  int p = 0;
+  for (int i = 0; i < numStreamIDs; ++i)
+    p |= streamMap[i].streamID == streamIDQuery;
+  return p;
+}
+
+static struct streamMap
+buildStreamMap(struct winHeaderEntry *winDict)
+{
+  int streamIDOld = CDI_UNDEFID;
+  int oldStreamIdx = CDI_UNDEFID;
+  int filetype = CDI_UNDEFID;
+  int sizeStreamMap = 16;
+  struct streamMapping *streamMap
+    = xmalloc(sizeStreamMap * sizeof (streamMap[0]));
+  int numDataEntries = winDict[0].specific.headerSize.numDataEntries;
+  int numStreamIDs = 0;
+  /* find streams written on this process */
+  for (int headerIdx = 1; headerIdx < numDataEntries; headerIdx += 2)
+    {
+      int streamID
+        = winDict[headerIdx].id
+        = namespaceAdaptKey2(winDict[headerIdx].id);
+      xassert(streamID > 0);
+      if (streamID != streamIDOld)
+        {
+          for (int i = numStreamIDs - 1; i >= 0; --i)
+            if ((streamIDOld = streamMap[i].streamID) == streamID)
+              {
+                oldStreamIdx = i;
+                goto streamIDInventorized;
+              }
+          oldStreamIdx = numStreamIDs;
+          streamIDOld = streamID;
+          numStreamIDs = inventorizeStream(streamMap, numStreamIDs,
+                                           &sizeStreamMap, streamID, headerIdx);
+        }
+      streamIDInventorized:
+      filetype = streamMap[oldStreamIdx].filetype;
+      streamMap[oldStreamIdx].lastHeaderIdx = headerIdx;
+      if (filetype == FILETYPE_NC || filetype == FILETYPE_NC2
+          || filetype == FILETYPE_NC4)
+        {
+          int varID = winDict[headerIdx].specific.dataRecord.varID;
+          streamMap[oldStreamIdx].varMap[varID] = headerIdx;
+        }
+    }
+  /* join with list of streams written to in total */
+  {
+    int *streamIDs, *streamIsWritten;
+    int numTotalStreamIDs = streamSize();
+    streamIDs = xmalloc(2 * sizeof (streamIDs[0]) * (size_t)numTotalStreamIDs);
+    streamGetIndexList(numTotalStreamIDs, streamIDs);
+    streamIsWritten = streamIDs + numTotalStreamIDs;
+    for (int i = 0; i < numTotalStreamIDs; ++i)
+      streamIsWritten[i] = streamIsInList(streamMap, numStreamIDs,
+                                          streamIDs[i]);
+    /* Find what streams are written to at all on any process */
+    xmpi(MPI_Allreduce(MPI_IN_PLACE, streamIsWritten, numTotalStreamIDs,
+                       MPI_INT, MPI_BOR, commInqCommColl()));
+    /* append streams written to on other tasks to mapping */
+    for (int i = 0; i < numTotalStreamIDs; ++i)
+      if (streamIsWritten[i] && !streamIsInList(streamMap, numStreamIDs,
+                                                streamIDs[i]))
+        numStreamIDs = inventorizeStream(streamMap, numStreamIDs,
+                                         &sizeStreamMap, streamIDs[i], -1);
+
+    free(streamIDs);
+  }
+  /* sort written streams by streamID */
+  streamMap = xrealloc(streamMap, sizeof (streamMap[0]) * numStreamIDs);
+  qsort(streamMap, numStreamIDs, sizeof (streamMap[0]), smCmpStreamID);
+  return (struct streamMap){ .entries = streamMap, .numEntries = numStreamIDs };
+}
+
+static void
+writeGribStream(struct winHeaderEntry *winDict, struct streamMapping *mapping,
+                double **data_, int *currentDataBufSize, int root,
+                int nProcsModel)
+{
+  int streamID = mapping->streamID;
+  int headerIdx, lastHeaderIdx = mapping->lastHeaderIdx;
+  int vlistID = streamInqVlist(streamID);
+  if (lastHeaderIdx < 0)
+    {
+      /* write zero bytes to trigger synchronization code in fileWrite */
+      cdiPioFileWrite(streamInqFileID(streamID), NULL, 0,
+                      streamInqCurTimestepID(streamID));
+    }
+  else
+    for (headerIdx = mapping->firstHeaderIdx;
+         headerIdx <= lastHeaderIdx;
+         headerIdx += 2)
+      if (streamID == winDict[headerIdx].id)
+        {
+          int varID = winDict[headerIdx].specific.dataRecord.varID;
+          int size = vlistInqVarSize(vlistID, varID);
+          int nmiss;
+          resizeVarGatherBuf(vlistID, varID, data_, currentDataBufSize);
+          double *data = *data_;
+          gatherArray(root, nProcsModel, headerIdx,
+                      vlistID, data, &nmiss);
+          streamWriteVar(streamID, varID, data, nmiss);
+          if ( ddebug > 2 )
+            {
+              char text[1024];
+              sprintf(text, "streamID=%d, var[%d], size=%d",
+                      streamID, varID, size);
+              xprintArray(text, data, size, DATATYPE_FLT);
+            }
+        }
+}
+
+#ifdef HAVE_NETCDF4
+static void
+buildWrittenVars(struct streamMapping *mapping, int **varIsWritten_,
+                 int myCollRank, MPI_Comm collComm)
+{
+  int nvars = mapping->numVars;
+  int *varMap = mapping->varMap;
+  int *varIsWritten = *varIsWritten_
+    = xrealloc(*varIsWritten_, sizeof (*varIsWritten) * nvars);
+  for (int varID = 0; varID < nvars; ++varID)
+    varIsWritten[varID] = ((varMap[varID] != -1)
+                           ?myCollRank+1 : 0);
+  xmpi(MPI_Allreduce(MPI_IN_PLACE, varIsWritten, nvars,
+                     MPI_INT, MPI_BOR, collComm));
+}
+#endif
+
 static void readGetBuffers()
 {
   int nProcsModel = commInqNProcsModel ();
@@ -473,129 +667,49 @@ static void readGetBuffers()
 #endif
   xdebug("%s", "START");
 
-  union winHeaderEntry *winDict
-    = (union winHeaderEntry *)rxWin[root].buffer;
-  xassert(winDict[0].headerSize.sizeID == HEADERSIZEMARKER);
+  struct winHeaderEntry *winDict
+    = (struct winHeaderEntry *)rxWin[root].buffer;
+  xassert(winDict[0].id == HEADERSIZEMARKER);
   {
     int dictSize = rxWin[root].dictSize,
-      firstNonRPCEntry = dictSize - winDict[0].headerSize.numRPCEntries - 1,
+      firstNonRPCEntry = dictSize - winDict[0].specific.headerSize.numRPCEntries - 1,
       headerIdx,
       numFuncCalls = 0;
     for (headerIdx = dictSize - 1;
          headerIdx > firstNonRPCEntry;
          --headerIdx)
       {
-        struct funcCallDesc *header
-          = &(winDict[headerIdx].funcCall);
-        xassert(header->funcID >= MINFUNCID
-                && header->funcID <= MAXFUNCID);
+        xassert(winDict[headerIdx].id >= MINFUNCID
+                && winDict[headerIdx].id <= MAXFUNCID);
         ++numFuncCalls;
-        readFuncCall(header);
+        readFuncCall(winDict + headerIdx);
       }
-    xassert(numFuncCalls == winDict[0].headerSize.numRPCEntries);
+    xassert(numFuncCalls == winDict[0].specific.headerSize.numRPCEntries);
   }
   /* build list of streams, data was transferred for */
   {
-    int numDataEntries = winDict[0].headerSize.numDataEntries;
-    int streamIdx;
-    struct {
-      int streamID, filetype;
-      int firstHeaderIdx, lastHeaderIdx;
-      int numVars, *varMap;
-    } *streamMap;
-    int numStreamIDs = 0, sizeStreamMap = 16;
-    streamMap = xmalloc(sizeStreamMap * sizeof (streamMap[0]));
-    int streamIDOld = CDI_UNDEFID;
-    int oldStreamIdx = CDI_UNDEFID;
-    int filetype = CDI_UNDEFID;
-    for (int headerIdx = 1; headerIdx < numDataEntries; headerIdx += 2)
-      {
-        int streamID
-          = winDict[headerIdx].dataRecord.streamID
-          = namespaceAdaptKey2(winDict[headerIdx].dataRecord.streamID);
-        xassert(streamID > 0);
-        if (streamID != streamIDOld)
-          {
-            for (int i = numStreamIDs - 1; i >= 0; --i)
-              if ((streamIDOld = streamMap[i].streamID) == streamID)
-                {
-                  filetype = streamMap[i].filetype;
-                  oldStreamIdx = i;
-                  goto streamIDInventorized;
-                }
-            if (numStreamIDs < sizeStreamMap) ; else
-              streamMap = xrealloc(streamMap,
-                                   (sizeStreamMap *= 2)
-                                   * sizeof (streamMap[0]));
-            streamMap[numStreamIDs].streamID = streamID;
-            streamMap[numStreamIDs].firstHeaderIdx = headerIdx;
-            streamMap[numStreamIDs].numVars = -1;
-            oldStreamIdx = numStreamIDs;
-            streamIDOld = streamID;
-            filetype = streamInqFiletype(streamID);
-            streamMap[numStreamIDs].filetype = filetype;
-            if (filetype == FILETYPE_NC || filetype == FILETYPE_NC2
-                || filetype == FILETYPE_NC4)
-              {
-                int vlistID = streamInqVlist(streamID);
-                int nvars = vlistNvars(vlistID);
-                streamMap[numStreamIDs].numVars = nvars;
-                streamMap[numStreamIDs].varMap
-                  = xmalloc(sizeof (streamMap[numStreamIDs].varMap[0])
-                            * nvars);
-                for (int i = 0; i < nvars; ++i)
-                  streamMap[numStreamIDs].varMap[i] = -1;
-              }
-            ++numStreamIDs;
-          }
-        streamIDInventorized:
-        streamMap[oldStreamIdx].lastHeaderIdx = headerIdx;
-        if (filetype == FILETYPE_NC || filetype == FILETYPE_NC2
-                || filetype == FILETYPE_NC4)
-          {
-            int varID = winDict[headerIdx].dataRecord.varID;
-            streamMap[oldStreamIdx].varMap[varID] = headerIdx;
-          }
-      }
+    struct streamMap map = buildStreamMap(winDict);
     double *data = NULL;
+#ifdef HAVE_NETCDF4
+    int *varIsWritten = NULL;
+#endif
 #if defined (HAVE_PARALLEL_NC4)
     double *writeBuf = NULL;
 #endif
     int currentDataBufSize = 0;
-    for (streamIdx = 0; streamIdx < numStreamIDs; ++streamIdx)
+    for (int streamIdx = 0; streamIdx < map.numEntries; ++streamIdx)
       {
-        int streamID = streamMap[streamIdx].streamID;
+        int streamID = map.entries[streamIdx].streamID;
         int vlistID = streamInqVlist(streamID);
-        int fileType = streamMap[streamIdx].filetype;
+        int filetype = map.entries[streamIdx].filetype;
 
-        switch (fileType)
+        switch (filetype)
           {
           case FILETYPE_GRB:
           case FILETYPE_GRB2:
-            {
-              int headerIdx, lastHeaderIdx = streamMap[streamIdx].lastHeaderIdx;
-              for (headerIdx = streamMap[streamIdx].firstHeaderIdx;
-                   headerIdx <= lastHeaderIdx;
-                   headerIdx += 2)
-                if (streamID == winDict[headerIdx].dataRecord.streamID)
-                  {
-                    int varID = winDict[headerIdx].dataRecord.varID;
-                    int size = vlistInqVarSize(vlistID, varID);
-                    int nmiss;
-                    resizeVarGatherBuf(vlistID, varID, &data,
-                                       &currentDataBufSize);
-                    gatherArray(root, nProcsModel, headerIdx,
-                                vlistID, data, &nmiss);
-                    streamWriteVar(streamID, varID, data, nmiss);
-                    if ( ddebug > 2 )
-                      {
-                        char text[1024];
-                        sprintf(text, "streamID=%d, var[%d], size=%d",
-                                streamID, varID, size);
-                        xprintArray(text, data, size, DATATYPE_FLT);
-                      }
-                  }
-            }
+            writeGribStream(winDict, map.entries + streamIdx,
+                            &data, &currentDataBufSize,
+                            root, nProcsModel);
             break;
 #ifdef HAVE_NETCDF4
           case FILETYPE_NC:
@@ -604,14 +718,10 @@ static void readGetBuffers()
 #ifdef HAVE_PARALLEL_NC4
             /* HAVE_PARALLE_NC4 implies having ScalES-PPM and yaxt */
             {
-              int nvars = streamMap[streamIdx].numVars;
-              int *varMap = streamMap[streamIdx].varMap;
-              int *varIsWritten = xmalloc(sizeof (varIsWritten[0]) * nvars);
-              for (int varID = 0; varID < nvars; ++varID)
-                varIsWritten[varID] = ((varMap[varID] != -1)
-                                       ?myCollRank+1 : 0);
-              xmpi(MPI_Allreduce(MPI_IN_PLACE, varIsWritten, nvars,
-                                 MPI_INT, MPI_BOR, collComm));
+              int nvars = map.entries[streamIdx].numVars;
+              int *varMap = map.entries[streamIdx].varMap;
+              buildWrittenVars(map.entries + streamIdx, &varIsWritten,
+                               myCollRank, collComm);
               for (int varID = 0; varID < nvars; ++varID)
                 if (varIsWritten[varID])
                   {
@@ -702,14 +812,10 @@ static void readGetBuffers()
              * which has data for which variable (var owner)
              * three cases need to be distinguished */
             {
-              int nvars = streamMap[streamIdx].numVars;
-              int *varMap = streamMap[streamIdx].varMap;
-              int *varIsWritten = xmalloc(sizeof (varIsWritten[0]) * nvars);
-              for (int varID = 0; varID < nvars; ++varID)
-                varIsWritten[varID] = ((varMap[varID] != -1)
-                                       ?myCollRank+1 : 0);
-              xmpi(MPI_Allreduce(MPI_IN_PLACE, varIsWritten, nvars,
-                                 MPI_INT, MPI_BOR, collComm));
+              int nvars = map.entries[streamIdx].numVars;
+              int *varMap = map.entries[streamIdx].varMap;
+              buildWrittenVars(map.entries + streamIdx, &varIsWritten,
+                               myCollRank, collComm);
               int writerRank;
               if ((writerRank = cdiPioSerialOpenFileMap(streamID))
                   == myCollRank)
@@ -785,7 +891,13 @@ static void readGetBuffers()
             xabort("unhandled filetype in parallel I/O.");
           }
       }
-    free(streamMap);
+#ifdef HAVE_NETCDF4
+    free(varIsWritten);
+#ifdef HAVE_PARALLEL_NC4
+    free(writeBuf);
+#endif
+#endif
+    free(map.entries);
     free(data);
   }
   xdebug("%s", "RETURN");
@@ -822,13 +934,14 @@ void getTimeStepData()
 
   xdebug("%s", "START");
 
+  for ( modelID = 0; modelID < nProcsModel; modelID++ )
+    clearModelWinBuffer(modelID);
   // todo put in correct lbs and ubs
   xmpi(MPI_Win_start(groupModel, 0, getWin));
   xmpi(MPI_Win_get_attr(getWin, MPI_WIN_BASE, &getWinBaseAddr, &attrFound));
   xassert(attrFound);
   for ( modelID = 0; modelID < nProcsModel; modelID++ )
     {
-      clearModelWinBuffer(modelID);
       xdebug("modelID=%d, nProcsModel=%d, rxWin[%d].size=%zu,"
              " getWin=%p, sizeof(int)=%u",
              modelID, nProcsModel, modelID, rxWin[modelID].size,
@@ -932,7 +1045,7 @@ cdiPioCdfDefTimestep(stream_t *streamptr, int tsID)
   @return
 */
 
-void IOServer ()
+void IOServer(void (*postCommSetupActions)(void))
 {
   int source, tag, size, nProcsModel=commInqNProcsModel();
   static int nfinished = 0;
@@ -942,9 +1055,9 @@ void IOServer ()
 
   xdebug("%s", "START");
 
-  backendInit ();
-  if ( commInqRankNode () == commInqSpecialRankNode ()) 
-    backendFinalize ();
+  backendInit(postCommSetupActions);
+  if (commInqRankNode() == commInqSpecialRankNode())
+    return;
   commCalc = commInqCommCalc ();
 #ifdef HAVE_PARALLEL_NC4
   cdiPioEnableNetCDFParAccess();
@@ -1003,6 +1116,9 @@ void IOServer ()
               }
               backendCleanup();
               serverWinCleanup();
+#ifdef HAVE_PARALLEL_NC4
+              free(pioPrimes);
+#endif
               /* listDestroy(); */
               xdebug("%s", "RETURN");
               return;
diff --git a/libcdi/src/pio_server.h b/libcdi/src/pio_server.h
index 396ef9b..e7bf111 100644
--- a/libcdi/src/pio_server.h
+++ b/libcdi/src/pio_server.h
@@ -9,7 +9,7 @@
 
 #include <mpi.h>
 
-void IOServer ();
+void IOServer(void (*postCommSetupActions)(void));
 
 #endif
 
diff --git a/libcdi/src/pio_util.c b/libcdi/src/pio_util.c
index 394765a..36ad8f2 100644
--- a/libcdi/src/pio_util.c
+++ b/libcdi/src/pio_util.c
@@ -10,6 +10,7 @@
 
 #include "pio_util.h"
 #include "cdi.h"
+#include "dmemory.h"
 
 #ifdef USE_MPI
 static
@@ -42,39 +43,18 @@ cdiAbortC_MPI(const char *caller, const char *filename,
   exit(EXIT_FAILURE);
   va_end(ap);
 }
-#endif
-
-/*****************************************************************************/
 
-void * pcdiXmalloc ( size_t size, const char *filename, const char *functionname,
-		     int line )
+void cdiPioWarning(const char *caller, const char *fmt, va_list ap)
 {
-  void * value = calloc (1, size );
-  if ( value == NULL )
-    cdiAbort(filename, functionname, line, "malloc failed: %s",
-             strerror(errno));
-  return value;
+  int rank = getMPICommWorldRank();
+  fprintf(stderr, "pe%d: Warning (%s) : ", rank, caller);
+  vfprintf(stderr, fmt, ap);
+  fputc('\n', stderr);
 }
 
-void * pcdiXcalloc ( size_t nmemb, size_t size, const char *filename,
-		     const char *functionname, int line )
-{
-  void * value = calloc ( nmemb, size );
-  if ( value == NULL )
-    cdiAbort(filename, functionname, line, "calloc failed: %s",
-             strerror(errno) );
-  return value;
-}
+#endif
 
-void * pcdiXrealloc ( void *p, size_t size, const char *functionname,
-		      const char *filename, int line )
-{
-  void * value = realloc ( p, size );
-  if ( value == NULL )
-    cdiAbort(filename, functionname, line, "realloc failed: %s",
-             strerror(errno));
-  return value;
-}
+/*****************************************************************************/
 
 /***************************************************************/
 
@@ -193,47 +173,6 @@ void pcdiDebugMsg2 ( const char *filename, const char *functionname, int line,
 
 /****************************************************/
 
-
-int xmaxInt ( int a, int b )
-{
-  return a >= b ? a : b;
-}
-
-
-/****************************************************/
-
-
-int xminInt ( int a, int b )
-{
-  return a <= b ? a : b;
-}
-
-
-/****************************************************/
-
-
-int xsum ( int n, int * argarray )
-{
-  int i, sum = 0;
-
-  for ( i = 0; i < n; i++ )
-    sum += * ( argarray + i );
-
-  return sum;
-}
-
-
-/****************************************************/
-
-
-double xchecksum ( int type, int count, void * buffer )
-{
-  return 0.0;
-}
-
-
-/****************************************************/
-
 void printArray ( const char * cdiPioDebugString, char * ps, const void * array, int n,
                   int datatype, const char * funname, const char * filename, int line )
 {
diff --git a/libcdi/src/pio_util.h b/libcdi/src/pio_util.h
index 5c74227..c06f5b3 100644
--- a/libcdi/src/pio_util.h
+++ b/libcdi/src/pio_util.h
@@ -26,6 +26,9 @@ cdiAbortC_MPI(const char * caller, const char * filename,
               const char *functionname, int line,
               const char * errorString, va_list ap)
   __attribute__((noreturn));
+
+void cdiPioWarning(const char *caller, const char *fmt, va_list ap);
+
 #endif
 
 #ifdef USE_MPI
@@ -84,34 +87,6 @@ getMPICommWorldRank()
   }
 #endif
 
-#ifdef USE_MPI
-#define xwarning(fmt, ...)						\
-  if ( ddebug ){							\
-    int rank = getMPICommWorldRank();                                   \
-    fprintf ( stderr, "WARNING: pe%d in %s, %s, line %d: " fmt "\n",	\
-              rank,  __func__, __FILE__,  __LINE__,			\
-              __VA_ARGS__ );						\
-  }
-#else
-#define xwarning(fmt, ...)					\
-  if ( ddebug ){                                                \
-    fprintf ( stderr, "WARNING: %s, %s, line %d: " fmt "\n",    \
-              __func__, __FILE__,  __LINE__,                    \
-              __VA_ARGS__ );                                 \
-  }
-#endif
-
-void * pcdiXmalloc ( size_t, const char *, const char *, int );
-#define xmalloc(size) pcdiXmalloc ( size, __FILE__, __func__,  __LINE__ )
-
-void * pcdiXcalloc ( size_t, size_t, const char *, const char *, int );
-#define xcalloc(nmemb,size) pcdiXcalloc(nmemb, size,            \
-                                        __FILE__, __func__, __LINE__)
-
-void * pcdiXrealloc ( void *, size_t, const char *, const char *, int );
-#define xrealloc(p,size) pcdiXrealloc(p, size,            \
-                                      __FILE__, __func__, __LINE__)
-
 void pcdiXMPI(int iret, const char *, int);
 #define xmpi(ret) do {                                  \
     int tmpIRet = (ret);                                   \
@@ -140,12 +115,16 @@ void pcdiDebugMsg2 ( const char *filename, const char *functionname, int line, \
 #define xdebugMsg2(tag,source,text) \
   if ( ddebug ) pcdiDebugMsg ( __FILE__, __func__,  __LINE__, tag, source, text )
 
-int xmaxInt ( int, int );
-int xminInt ( int, int );
-int xsum ( int, int * );
+static inline int
+sum_int(size_t n, int *a)
+{
+  int sum = 0;
+  for (size_t i = 0; i < n; ++i)
+    sum += a[i];
+  return sum;
+}
+
 
-double xchecksum ( int, int, void * );
- 
 void printArray ( const char *, char *, const void *, int, int, const char *, const char *, int );
 #define xprintArray(ps,array,n,datatype)                                \
   if ( ddebug )                                                         \
diff --git a/libcdi/src/pkgconfig/cdipio.pc.in b/libcdi/src/pkgconfig/cdipio.pc.in
new file mode 100644
index 0000000..27a8c17
--- /dev/null
+++ b/libcdi/src/pkgconfig/cdipio.pc.in
@@ -0,0 +1,48 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+cflags=-I at includedir@
+fcflags=@FPP_INCOPT@@includedir@ @CDI_F90_INTERFACE_FCFLAGS@
+libs=-L at libdir@ -lcdipio @PPM_CORE_LIBS@ @YAXT_LIBS@ -lcdi @GRIB_API_LIBS@ @JASPER_LIBS@ @NETCDF_LIBS@ @HDF5_LIBS@ @SZLIB_LIBS@ @ZLIB_LIBS@ @THREADS_LIBS@
+threads_libs=@THREADS_LIBS@
+threads_cflags=@THREADS_INCLUDE@
+zlib_cflags=@ZLIB_INCLUDE@
+zlib_libs=@ZLIB_LIBS@
+szlib_cflags=@SZLIB_INCLUDE@
+szlib_libs=@SZLIB_LIBS@
+hdf5_root=@HDF5_ROOT@
+hdf5_cflags=@HDF5_INCLUDE@
+hdf5_libs=@HDF5_LIBS@
+netcdf_root=@NETCDF_ROOT@
+netcdf_cflags=@NETCDF_INCLUDE@
+netcdf_libs=@NETCDF_LIBS@
+jasper_libs=@JASPER_LIBS@
+grib_api_cflags=@GRIB_API_INCLUDE@
+grib_api_libs=@GRIB_API_LIBS@
+cdipio_build_cc=@CC@
+cdipio_build_cflags=@CFLAGS@
+cdipio_build_cppflags=@CPPFLAGS@
+cdipio_build_ldflags=@LDFLAGS@
+cdipio_build_libs=@LIBS@
+cdipio_build_fc=@FC@
+cdipio_build_fcflags=@FCFLAGS@
+cdipio_build_f77=@F77@
+cdipio_build_fflags=@FFLAGS@
+cdipio_build_cxx=@CXX@
+cdipio_build_cxxflags=@CXXFLAGS@
+cdipio_build_enable_grib=@ENABLE_GRIB@
+cdipio_build_enable_cgribex=@ENABLE_CGRIBEX@
+cdipio_build_enable_service=@ENABLE_SERVICE@
+cdipio_build_enable_extra=@ENABLE_EXTRA@
+cdipio_build_enable_ieg=@ENABLE_IEG@
+
+Name: @PACKAGE_NAME at pio
+Description: CDI-PIO is the MPI-parallel layer of CDI
+URL: @PACKAGE_URL@
+Version: @VERSION@
+Requires: 
+Libs: ${libs}
+Cflags: ${cflags}
+FCflags: ${fcflags}
+
diff --git a/libcdi/src/resource_handle.c b/libcdi/src/resource_handle.c
index 0b68864..9771253 100644
--- a/libcdi/src/resource_handle.c
+++ b/libcdi/src/resource_handle.c
@@ -9,8 +9,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#include "dmemory.h"
 #include "resource_handle.h"
-#include "pio_util.h"
 #include "namespace.h"
 #include "serialize.h"
 #include "cdi.h"
@@ -120,10 +120,11 @@ reshListCreate(int namespaceID)
 void
 reshListDestruct(int namespaceID)
 {
+  LIST_INIT();
   LIST_LOCK();
   xassert(resHList && namespaceID >= 0 && namespaceID < resHListSize);
   int callerNamespaceID = namespaceGetActive();
-  pioNamespaceSetActive(namespaceID);
+  namespaceSetActive(namespaceID);
   if (resHList[namespaceID].resources)
     {
       for ( int j = 0; j < resHList[namespaceID].size; j++ )
@@ -136,7 +137,7 @@ reshListDestruct(int namespaceID)
       reshListClearEntry(namespaceID);
     }
   if (resHList[callerNamespaceID].resources)
-    pioNamespaceSetActive(callerNamespaceID);
+    namespaceSetActive(callerNamespaceID);
   LIST_UNLOCK();
 }
 
@@ -149,6 +150,7 @@ static void listDestroy ( void )
       namespaceDelete(i);
   free(resHList);
   resHList = NULL;
+  cdiReset();
   LIST_UNLOCK();
 }
 
@@ -591,65 +593,47 @@ void reshUnlock ()
 
 int reshListCompare ( int nsp0, int nsp1 )
 {
-  int valCompare = 0;
-  int i;
-
-
   LIST_INIT();
   LIST_LOCK();
 
-  xassert(resHListSize > xmaxInt ( nsp0, nsp1 ) &&
-          xminInt ( nsp0, nsp1 ) >= 0 );
+  xassert(resHListSize > nsp0 && resHListSize > nsp1 &&
+          nsp0 >= 0 && nsp1 >= 0);
 
-  for ( i = 0; i < resHList[nsp0].size; i++ )
+  int valCompare = 0;
+  int i, listSizeMin = (resHList[nsp0].size <= resHList[nsp1].size)
+    ? resHList[nsp0].size : resHList[nsp1].size;
+  listElem_t *resources0 = resHList[nsp0].resources,
+    *resources1 = resHList[nsp1].resources;
+  for (i = 0; i < listSizeMin; i++)
     {
-      listElem_t *listElem0 = resHList[nsp0].resources + i,
-        *listElem1 = resHList[nsp1].resources + i;
-      if ( listElem0->val )
-	{
-	  if ( i >= resHList[nsp1].size )
-	    {
-              valCompare = 1;
-	      xdebug("%s %d", "namespace active length mismatch at resource",
-                     i);
-	      break;
-	    }
-
-	  if ( !listElem1->val )
-	    {
-              valCompare = 1;
-	      xdebug("%s %d", "namespace occupation mismatch at resource", i);
-              break;
-	    }
-
-	  if ( listElem0->ops != listElem1->ops || listElem0->ops == NULL )
-	    {
-              valCompare = 1;
-	      xdebug("%s %d", "resource type mismatch at resource", i);
-              break;
-	    }
-
-	  valCompare = listElem0->ops->valCompare(listElem0->val,
-                                                  listElem1->val);
-          if (valCompare)
-            break;
-	}
-      else if ( listElem1->val )
+      int occupied0 = resources0[i].val != NULL,
+        occupied1 = resources1[i].val != NULL;
+      /* occupation mismatch ? */
+      int diff = occupied0 ^ occupied1;
+      valCompare |= (diff << cdiResHListOccupationMismatch);
+      if (!diff && occupied0)
         {
-          valCompare = 1;
-          xdebug("namespace 1 has value at empty place %d of namespace 0",
-                 i);
-          break;
+          /* both occupied, do resource types match? */
+          diff = (resources0[i].ops != resources1[i].ops
+                  || resources0[i].ops == NULL);
+          valCompare |= (diff << cdiResHListResourceTypeMismatch);
+          if (!diff)
+            {
+              /* types match, does content match also? */
+              diff = resources0[i].ops->valCompare(resources0[i].val,
+                                                   resources1[i].val);
+              valCompare |= (diff << cdiResHListResourceContentMismatch);
+            }
         }
     }
-
-  if (!valCompare)
-    {
-      for ( ; i < resHList[nsp1].size; i++ )
-        valCompare = valCompare || resHList[nsp1].resources[i].val != NULL;
-      if (valCompare)
-        xdebug("%s", "extra elements in second namespace");
-    }
+  /* find resources in nsp 0 beyond end of nsp 1 */
+  for (int j = listSizeMin; j < resHList[nsp0].size; ++j)
+    valCompare |= ((resources0[j].val != NULL)
+                   << cdiResHListOccupationMismatch);
+  /* find resources in nsp 1 beyond end of nsp 0 */
+  for (; i < resHList[nsp1].size; ++i)
+    valCompare |= ((resources1[i].val != NULL)
+                   << cdiResHListOccupationMismatch);
 
   LIST_UNLOCK();
 
@@ -673,7 +657,7 @@ void reshListPrint(FILE *fp)
 
   for ( i = 0; i < namespaceGetNumber (); i++ )
     {
-      pioNamespaceSetActive ( i );
+      namespaceSetActive ( i );
 
       fprintf ( fp, "\n" );
       fprintf ( fp, "##################################\n" );
@@ -697,7 +681,7 @@ void reshListPrint(FILE *fp)
   fprintf ( fp, "#\n#  end global resource list" \
             "\n#\n##########################################\n\n" );
 
-  pioNamespaceSetActive ( temp );
+  namespaceSetActive ( temp );
 }
 
 
diff --git a/libcdi/src/resource_handle.h b/libcdi/src/resource_handle.h
index b93b6c2..9ac3e7a 100644
--- a/libcdi/src/resource_handle.h
+++ b/libcdi/src/resource_handle.h
@@ -71,6 +71,13 @@ int    reshGetStatus ( cdiResH, resOps * );
 
 void   reshLock   ( void );
 void   reshUnlock ( void );
+
+enum reshListMismatch {
+  cdiResHListOccupationMismatch,
+  cdiResHListResourceTypeMismatch,
+  cdiResHListResourceContentMismatch,
+};
+
 int reshListCompare(int nsp0, int nsp1);
 void reshListPrint(FILE *fp);
 
diff --git a/libcdi/src/resource_unpack.c b/libcdi/src/resource_unpack.c
index 1e44ece..f054eaa 100644
--- a/libcdi/src/resource_unpack.c
+++ b/libcdi/src/resource_unpack.c
@@ -3,7 +3,7 @@
 #endif
 
 #include "cdi.h"
-#include "pio_util.h"
+#include "dmemory.h"
 #include "institution.h"
 #include "model.h"
 #include "cdi_int.h"
diff --git a/libcdi/src/serialize.c b/libcdi/src/serialize.c
index f1125df..c608434 100644
--- a/libcdi/src/serialize.c
+++ b/libcdi/src/serialize.c
@@ -1,10 +1,11 @@
 #include <inttypes.h>
 #include <limits.h>
+#include <string.h>
 
 #include "cdi.h"
+#include "error.h"
 #include "serialize.h"
 #include "namespace.h"
-#include "pio_util.h"
 
 int
 serializeGetSize(int count, int datatype, void *context)
@@ -49,9 +50,13 @@ serializeGetSizeInCore(int count, int datatype, void *context)
   case DATATYPE_INT16:
     elemSize = sizeof (int16_t);
     break;
+  case DATATYPE_UINT32:
+    elemSize = sizeof (uint32_t);
+    break;
   case DATATYPE_INT:
     elemSize = sizeof (int);
     break;
+  case DATATYPE_FLT:
   case DATATYPE_FLT64:
     elemSize = sizeof (double);
     break;
diff --git a/libcdi/src/serialize.h b/libcdi/src/serialize.h
index b7fcb64..b9f5f4e 100644
--- a/libcdi/src/serialize.h
+++ b/libcdi/src/serialize.h
@@ -5,8 +5,6 @@
 #ifndef SERIALIZE_H
 #define SERIALIZE_H
 
-#include "cdi.h"
-
 /*
  * Generic interfaces for (de-)marshalling
  */
diff --git a/libcdi/src/stream.c b/libcdi/src/stream.c
index e014244..7b3609d 100644
--- a/libcdi/src/stream.c
+++ b/libcdi/src/stream.c
@@ -4,10 +4,11 @@
 
 #include <ctype.h>
 
-#include "dmemory.h"
 #include "cdi.h"
 #include "cdi_int.h"
 #include "cdf.h"
+#include "dmemory.h"
+#include "error.h"
 #include "stream_grb.h"
 #include "stream_cdf.h"
 #include "stream_srv.h"
@@ -22,12 +23,8 @@
 #include "ieg.h"
 #include "vlist.h"
 #include "resource_handle.h"
-#include "pio_util.h"
 
 #include "namespace.h"
-#include "pio_interface.h"
-#include "pio_rpc.h"
-#include "pio_comm.h"
 
 #include <string.h>
 
@@ -454,7 +451,7 @@ void streamDefByteorder(int streamID, int byteorder)
 
   if ( reshGetStatus ( streamID, &streamOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -750,10 +747,11 @@ int streamOpen(const char *filename, const char *filemode, int filetype)
 
   {
     int (*streamOpenDelegate)(const char *filename, const char *filemode,
-                              int filetype, stream_t *streamptr)
-      = (int (*)(const char *, const char *, int, stream_t *))
+                              int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
+      = (int (*)(const char *, const char *, int, stream_t *, int))
       namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
-    fileID = streamOpenDelegate(filename, filemode, filetype, streamptr);
+
+    fileID = streamOpenDelegate(filename, filemode, filetype, streamptr, 1);
   }
 
   if (fileID < 0)
@@ -798,51 +796,45 @@ static int streamOpenA(const char *filename, const char *filemode, int filetype)
   int fileID = CDI_UNDEFID;
   int streamID = CDI_ESYSTEM;
   int status;
-  Record *record = NULL;
   stream_t *streamptr = stream_new_entry();
+  vlist_t *vlistptr;
 
   if ( CDI_Debug )
-    Message("Open %s mode %c file %s", strfiletype(filetype), (int) *filemode, filename);
+    Message("Open %s file (mode=%c); filename: %s", strfiletype(filetype), (int) *filemode, filename);
+  if ( CDI_Debug ) printf("streamOpenA: %s\n", filename); // seg fault without this line on thunder/squall with "cdo cat x y"
 
   if ( ! filename || ! filemode || filetype < 0 ) return (CDI_EINVAL);
 
   {
     int (*streamOpenDelegate)(const char *filename, const char *filemode,
-                              int filetype, stream_t *streamptr)
-      = (int (*)(const char *, const char *, int, stream_t *))
+                              int filetype, stream_t *streamptr, int recordBufIsToBeCreated)
+      = (int (*)(const char *, const char *, int, stream_t *, int))
       namespaceSwitchGet(NSSWITCH_STREAM_OPEN_BACKEND).func;
-    fileID = streamOpenDelegate(filename, "r", filetype, streamptr);
+
+    fileID = streamOpenDelegate(filename, "r", filetype, streamptr, 1);
   }
 
-  if (fileID == CDI_UNDEFID || fileID == CDI_ELIBNAVAIL
-      || fileID == CDI_ESYSTEM )
-    {
-      streamID = fileID;
-      return (streamID);
-    }
-  else
-    {
-      vlist_t *vlistptr;
-      streamID = streamptr->self;
+  if ( fileID == CDI_UNDEFID || fileID == CDI_ELIBNAVAIL || fileID == CDI_ESYSTEM ) return (fileID);
 
-      streamptr->record   = record;
-      streamptr->filetype = filetype;
-      streamptr->filemode = tolower(*filemode);
-      streamptr->filename = strdupx(filename);
-      streamptr->fileID   = fileID;
+  streamID = streamptr->self;
 
-      streamptr->vlistID = vlistCreate();
-      /* cdiReadByteorder(streamID); */
-      status = cdiInqContents(streamptr);
-      if ( status < 0 ) return (status);
-      vlistptr = vlist_to_pointer(streamptr->vlistID);
-      vlistptr->ntsteps = cdiInqTimeSize(streamID);
-    }
+  streamptr->filetype = filetype;
+  streamptr->filemode = tolower(*filemode);
+  streamptr->filename = strdupx(filename);
+  streamptr->fileID   = fileID;
+
+  streamptr->vlistID = vlistCreate();
+  /* cdiReadByteorder(streamID); */
+  status = cdiInqContents(streamptr);
+  if ( status < 0 ) return (status);
+  vlistptr = vlist_to_pointer(streamptr->vlistID);
+  vlistptr->ntsteps = cdiInqTimeSize(streamID);
 
   {
     void (*streamCloseDelegate)(stream_t *streamptr, int recordBufIsToBeDeleted)
       = (void (*)(stream_t *, int))
       namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
+
     streamCloseDelegate(streamptr, 0);
   }
 
@@ -908,7 +900,7 @@ static int streamOpenA(const char *filename, const char *filemode, int filetype)
   if ( fileID == CDI_UNDEFID )
     streamID = CDI_UNDEFID;
   else
-    streamptr->fileID   = fileID;
+    streamptr->fileID = fileID;
 
   return (streamID);
 }
@@ -1128,7 +1120,7 @@ cdiStreamCloseDefaultDelegate(stream_t *streamptr, int recordBufIsToBeDeleted)
 #endif
       default:
         {
-          Error("%s support not compiled in!", strfiletype(filetype));
+          Error("%s support not compiled in (fileID = %d)!", strfiletype(filetype), fileID);
           break;
         }
       }
@@ -1167,15 +1159,15 @@ void streamClose(int streamID)
     = (void (*)(stream_t *, int))
     namespaceSwitchGet(NSSWITCH_STREAM_CLOSE_BACKEND).func;
 
-  streamCloseDelegate(streamptr, 1);
+  if ( streamptr->filetype != -1 ) streamCloseDelegate(streamptr, 1);
 
   if ( streamptr->record )
-      {
-	  if ( streamptr->record->buffer )
-              free(streamptr->record->buffer);
+    {
+      if ( streamptr->record->buffer )
+        free(streamptr->record->buffer);
 
-	  free(streamptr->record);
-      }
+      free(streamptr->record);
+    }
 
   streamptr->filetype = 0;
   if ( streamptr->filename ) free(streamptr->filename);
@@ -1383,6 +1375,13 @@ int streamDefTimestep(int streamID, int tsID)
   return myStreamDefTimestep_(streamptr, tsID);
 }
 
+int streamInqCurTimestepID(int streamID)
+{
+  stream_t *streamptr = stream_to_pointer(streamID);
+  return streamptr->curTsID;
+}
+
+
 /*
 @Function  streamInqTimestep
 @Title     Get time step
@@ -1620,7 +1619,8 @@ cdiStreamWriteVar_(int streamID, int varID, int memtype, const void *data,
 
   stream_check_ptr(__func__, streamptr);
 
-  // streamDefineTaxis(streamID);
+  // check taxis
+  if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
 
   filetype = streamptr->filetype;
 
@@ -1803,6 +1803,9 @@ void stream_write_var_slice(int streamID, int varID, int levelID, int memtype, c
 
   stream_check_ptr(__func__, streamptr);
 
+  // check taxis
+  if ( streamptr->curTsID == CDI_UNDEFID ) streamDefTimestep(streamID, 0);
+
   filetype = streamptr->filetype;
 
   switch (filetype)
@@ -2228,7 +2231,7 @@ void streamDefCompType(int streamID, int comptype)
 
   if ( reshGetStatus ( streamID, &streamOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -2246,7 +2249,7 @@ void streamDefCompLevel(int streamID, int complevel)
 
   if ( reshGetStatus ( streamID, &streamOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
diff --git a/libcdi/src/stream_cdf.c b/libcdi/src/stream_cdf.c
index 73f74ee..43d23c4 100644
--- a/libcdi/src/stream_cdf.c
+++ b/libcdi/src/stream_cdf.c
@@ -1955,6 +1955,26 @@ void cdfDefGridUUID(stream_t *streamptr, int gridID)
 }
 
 static
+void cdfDefZaxisUUID(stream_t *streamptr, int zaxisID)
+{
+  char uuidOfVGrid[17];
+  zaxisInqUUID(zaxisID, uuidOfVGrid);
+
+  if ( uuidOfVGrid[0] != 0 )
+    {
+      char uuidOfVGridStr[37];
+      uuid2str(uuidOfVGrid, uuidOfVGridStr);
+      if ( uuidOfVGridStr[0] != 0 && strlen(uuidOfVGridStr) == 36 )
+        {
+          int fileID  = streamptr->fileID;
+          if ( streamptr->ncmode == 2 ) cdf_redef(fileID);
+          cdf_put_att_text(fileID, NC_GLOBAL, "uuidOfVGrid", 36, uuidOfVGridStr);
+          if ( streamptr->ncmode == 2 ) cdf_enddef(fileID);
+        }
+    }
+}
+
+static
 void cdfDefUnstructured(stream_t *streamptr, int gridID)
 {
   char xunits[CDI_MAX_NAME];
@@ -2324,6 +2344,9 @@ void cdfDefZaxis(stream_t *streamptr, int zaxisID)
 
       if ( ilevel ) sprintf(&axisname[strlen(axisname)], "_%1d", ilevel+1);
 
+      if ( type == ZAXIS_REFERENCE )
+	cdfDefZaxisUUID(streamptr, zaxisID);
+
       if ( type == ZAXIS_HYBRID || type == ZAXIS_HYBRID_HALF )
         {
           if ( type == ZAXIS_HYBRID )
@@ -3716,6 +3739,55 @@ void cdf_write_var_chunk(stream_t *streamptr, int varID, int memtype,
 }
 #endif
 
+static
+int set_validrange(long gridsize, double *data, double missval, double validmin, double validmax)
+{
+  long i;
+  int nmiss = 0;
+  /*
+  for ( i = 0; i < gridsize; i++, data++ )
+    {
+      if ( IS_NOT_EQUAL(validmin, VALIDMISS) && (*data) < validmin ) *data = missval;
+      if ( IS_NOT_EQUAL(validmax, VALIDMISS) && (*data) > validmax ) *data = missval;
+      if ( DBL_IS_EQUAL((*data), missval) ) nmiss++;
+    }
+  */
+  // 21/01/2014 Florian Prill: SX-9 vectorization
+
+  if ( IS_NOT_EQUAL(validmin, VALIDMISS) && !IS_NOT_EQUAL(validmax, VALIDMISS) )
+    {
+      for ( i = 0; i < gridsize; i++, data++ )
+        {
+          if ( (*data) < validmin )  { (*data) = missval; nmiss++; }
+          else if ( DBL_IS_EQUAL((*data), missval) )  nmiss++;
+        } // i
+    }
+  else if ( IS_NOT_EQUAL(validmax, VALIDMISS) && !IS_NOT_EQUAL(validmin, VALIDMISS))
+    {
+      for ( i = 0; i < gridsize; i++, data++ )
+        {
+          if ( (*data) > validmax )  { (*data) = missval; nmiss++; }
+          else if ( DBL_IS_EQUAL((*data), missval) )  nmiss++;
+        } // i
+    }
+  else if ( IS_NOT_EQUAL(validmin, VALIDMISS) && IS_NOT_EQUAL(validmax, VALIDMISS))
+    {
+      for ( i = 0; i < gridsize; i++, data++ )
+        {
+          if      ( (*data) < validmin )  { (*data) = missval; nmiss++; }
+          else if ( (*data) > validmax )  { (*data) = missval; nmiss++; }
+          else if ( DBL_IS_EQUAL((*data), missval) )  nmiss++;
+        } // i
+    }
+  else
+    {
+      for ( i = 0; i < gridsize; i++, data++ )
+        if ( DBL_IS_EQUAL((*data), missval) ) nmiss++;
+    }
+
+  return (nmiss);
+}
+
 
 int cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data, int *nmiss)
 {
@@ -3875,15 +3947,15 @@ int cdfReadVarSliceDP(stream_t *streamptr, int varID, int levelID, double *data,
       lvalidrange = vlistInqVarValidrange(vlistID, varID, validrange);
       // printf("readvarslice: validrange %d %g %g\n", lvalidrange, validrange[0], validrange[1]);
       if ( lvalidrange )
-        for ( i = 0; i < gridsize; i++ )
-          {
-            if ( IS_NOT_EQUAL(validrange[0], VALIDMISS) && data[i] < validrange[0] ) data[i] = missval;
-            if ( IS_NOT_EQUAL(validrange[1], VALIDMISS) && data[i] > validrange[1] ) data[i] = missval;
-          }
-
-      // printf("XXX %31.0f %31.0f %31.0f %31.0f\n", missval, (float)data[0]);
-      for ( i = 0; i < gridsize; i++ )
-        if ( DBL_IS_EQUAL(data[i], missval) ) *nmiss += 1;
+        {
+          *nmiss = set_validrange(gridsize, data, missval, validrange[0], validrange[1]);
+        }
+      else
+        {
+          double *data_ptr = data; 
+          for ( i = 0; i < gridsize; i++, data_ptr++ )
+            if ( DBL_IS_EQUAL((*data_ptr), missval) ) (*nmiss)++;
+        }
     }
 
   addoffset    = vlistInqVarAddoffset(vlistID, varID);
@@ -5595,8 +5667,7 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 		{
 		  if ( ncvars[xvarid].ndims != ncvars[yvarid].ndims )
 		    {
-		      Warning("Inconsistent grid structure for variable %s!",
-			      ncvars[ncvarid].name);
+		      Warning("Inconsistent grid structure for variable %s!", ncvars[ncvarid].name);
 		      ncvars[ncvarid].xvarid = UNDEFID;
 		      ncvars[ncvarid].yvarid = UNDEFID;
 		      xvarid = UNDEFID;
@@ -5772,7 +5843,7 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 
 	      if      ( (int) ysize == 0 ) size = xsize;
 	      else if ( (int) xsize == 0 ) size = ysize;
-	      else if ( ncvars[ncvarid].gridtype == GRID_UNSTRUCTURED ) size = xsize; 
+	      else if ( ncvars[ncvarid].gridtype == GRID_UNSTRUCTURED ) size = xsize;
 	      else                         size = xsize*ysize;
 	    }
 
@@ -5986,6 +6057,46 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 		}
 	    }
 
+          if ( grid.type == GRID_UNSTRUCTURED )
+            {
+              int zdimid = UNDEFID;
+              int xdimidx = -1, ydimidx = -1;
+
+              for ( i = 0; i < ndims; i++ )
+                {
+                  if      ( ncvars[ncvarid].dimtype[i] == X_AXIS ) xdimidx = i;
+                  else if ( ncvars[ncvarid].dimtype[i] == Y_AXIS ) ydimidx = i;
+                  else if ( ncvars[ncvarid].dimtype[i] == Z_AXIS ) zdimid = ncvars[ncvarid].dimids[i];
+                }
+
+              if ( xdimid != UNDEFID && ydimid != UNDEFID && zdimid == UNDEFID )
+                {
+                  if ( grid.xsize > grid.ysize && grid.ysize < 1000 )
+                    {
+                      ncvars[ncvarid].dimtype[ydimidx] = Z_AXIS;
+                      ydimid = UNDEFID;
+                      grid.size  = grid.xsize;
+                      grid.ysize = 0;
+                    }
+                  else if ( grid.ysize > grid.xsize && grid.xsize < 1000 )
+                    {
+                      ncvars[ncvarid].dimtype[xdimidx] = Z_AXIS;
+                      xdimid = ydimid;
+                      ydimid = UNDEFID;
+                      grid.size  = grid.ysize;
+                      grid.xsize = grid.ysize;
+                      grid.ysize = 0;
+                    }
+                }
+
+              if ( grid.size != grid.xsize )
+                {
+                  Warning("Unsupported array structure, skipped variable %s!", ncvars[ncvarid].name);
+                  ncvars[ncvarid].isvar = -1;
+                  continue;
+                }
+            }
+
 #if defined (PROJECTION_TEST)
 	  if ( proj.type == GRID_PROJECTION )
 	    {
@@ -6025,10 +6136,16 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 
           if ( grid.type == GRID_UNSTRUCTURED )
             {
-              if ( ncvars[ncvarid].position > 0 ) gridDefPosition(ncvars[ncvarid].gridID, ncvars[ncvarid].position);
+              if ( CDI_Debug)
+                {
+                  if ( grid.number != UNDEFID ) printf("number : %d\n", grid.number);
+                  if ( ncvars[ncvarid].position > 0 ) printf("position : %d\n", ncvars[ncvarid].position);
+                  if ( gridfile[0] != 0 ) printf("gridfile: %s\n", gridfile);
+                  if ( uuidOfHGrid[0] != 0 ) printf("uuidOfHGrid: defined\n");
+                }
 
+              if ( ncvars[ncvarid].position > 0 ) gridDefPosition(ncvars[ncvarid].gridID, ncvars[ncvarid].position);
               if ( gridfile[0] != 0 ) gridDefReference(ncvars[ncvarid].gridID, gridfile);
-
               if ( uuidOfHGrid[0] != 0 ) gridDefUUID(ncvars[ncvarid].gridID, uuidOfHGrid);
             }
 
@@ -6060,26 +6177,43 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 	  streamptr->xdimID[gridindex] = xdimid;
 	  streamptr->ydimID[gridindex] = ydimid;
 
-	  grid_free(&grid);
-	  grid_free(&proj);
-
 	  if ( CDI_Debug )
 	    Message("gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid, ncvars[ncvarid].name);
 
 	  for ( ncvarid2 = ncvarid+1; ncvarid2 < nvars; ncvarid2++ )
 	    if ( ncvars[ncvarid2].isvar == TRUE && ncvars[ncvarid2].gridID == UNDEFID )
 	      {
-		int xdimid2 = -1, ydimid2 = -1;
-		ndims = ncvars[ncvarid2].ndims;
-		for ( i = 0; i < ndims; i++ )
+		int xdimid2 = UNDEFID, ydimid2 = UNDEFID, zdimid2 = UNDEFID;
+                int xdimidx = -1, ydimidx = -1;
+		int ndims2 = ncvars[ncvarid2].ndims;
+
+		for ( i = 0; i < ndims2; i++ )
 		  {
 		    if ( ncvars[ncvarid2].dimtype[i] == X_AXIS )
-		      xdimid2 = ncvars[ncvarid2].dimids[i];
+		      { xdimid2 = ncvars[ncvarid2].dimids[i]; xdimidx = i; }
 		    else if ( ncvars[ncvarid2].dimtype[i] == Y_AXIS )
-		      ydimid2 = ncvars[ncvarid2].dimids[i];
+		      { ydimid2 = ncvars[ncvarid2].dimids[i]; ydimidx = i; }
+		    else if ( ncvars[ncvarid2].dimtype[i] == Z_AXIS )
+		      { zdimid2 = ncvars[ncvarid2].dimids[i]; }
 		  }
 
-		if ( xdimid == xdimid2 &&
+                if ( ncvars[ncvarid2].gridtype == UNDEFID && grid.type == GRID_UNSTRUCTURED )
+                  {
+                    if ( xdimid == xdimid2 && ydimid2 != UNDEFID && zdimid2 == UNDEFID )
+                      {
+                        ncvars[ncvarid2].dimtype[ydimidx] = Z_AXIS;
+                        ydimid2 = UNDEFID;
+                      }
+
+                    if ( xdimid == ydimid2 && xdimid2 != UNDEFID && zdimid2 == UNDEFID )
+                      {
+                        ncvars[ncvarid2].dimtype[xdimidx] = Z_AXIS;
+                        xdimid2 = ydimid2;
+                        ydimid2 = UNDEFID;
+                      }
+                  }
+
+                if ( xdimid == xdimid2 &&
 		    (ydimid == ydimid2 || (xdimid == ydimid && ydimid2 == UNDEFID)) )
 		  {
 		    int same_grid = TRUE;
@@ -6098,13 +6232,15 @@ void define_all_grids(stream_t *streamptr, int vlistID, ncdim_t *ncdims, int nva
 		    if ( same_grid )
 		      {
 			if ( CDI_Debug )
-			  Message("Same gridID %d %d %s",
-				  ncvars[ncvarid].gridID, ncvarid2, ncvars[ncvarid2].name);
+			  Message("Same gridID %d %d %s", ncvars[ncvarid].gridID, ncvarid2, ncvars[ncvarid2].name);
 			ncvars[ncvarid2].gridID = ncvars[ncvarid].gridID;
 			ncvars[ncvarid2].chunktype = ncvars[ncvarid].chunktype;
 		      }
 		  }
 	      }
+
+	  grid_free(&grid);
+	  grid_free(&proj);
 	}
     }
 }
diff --git a/libcdi/src/stream_cgribex.c b/libcdi/src/stream_cgribex.c
index b11a01d..b252d6f 100644
--- a/libcdi/src/stream_cgribex.c
+++ b/libcdi/src/stream_cgribex.c
@@ -1403,7 +1403,7 @@ int cgribexDecode(unsigned char *gribbuffer, int gribsize, double *data, int gri
 
       *nmiss = 0;
       for ( i = 0; i < gridsize; i++ )
-        if ( (abs(data[i]-undef_pds) < undef_eps) || IS_EQUAL(data[i],FSEC3_MissVal) ) {
+        if ( (fabs(data[i]-undef_pds) < undef_eps) || IS_EQUAL(data[i],FSEC3_MissVal) ) {
           data[i] = missval;
           (*nmiss)++;
         }
@@ -1566,13 +1566,15 @@ int cgribexDefDateTime(int *isec1, int timeunit, int date, int time)
 static
 void cgribexDefTime(int *isec1, int vdate, int vtime, int tsteptype, int numavg, int taxisID)
 {
-  int timetype = -1;
+  int timetype = TAXIS_ABSOLUTE;
   int timerange = 0;
-  int timeunit;
-
-  if ( taxisID != -1 ) timetype = taxisInqType(taxisID);
+  int timeunit = TUNIT_HOUR;
 
-  timeunit = taxisInqTunit(taxisID);
+  if ( taxisID != -1 ) 
+    {
+      timetype = taxisInqType(taxisID);
+      timeunit = taxisInqTunit(taxisID);
+    }
 
   if ( timetype == TAXIS_RELATIVE )
     {
@@ -1637,8 +1639,8 @@ static
 void cgribexDefGrid(int *isec1, int *isec2, int *isec4, int gridID)
 {
   int gridtype;
-  int lcurvi = FALSE;
-  static short lwarn = TRUE;
+  bool lcurvi = false;
+  static bool lwarning = true;
 
   memset(isec2, 0, 16*sizeof(int));
 
@@ -1659,7 +1661,7 @@ void cgribexDefGrid(int *isec1, int *isec2, int *isec4, int gridID)
       if ( (ysize ==  32 || ysize ==  48 || ysize ==  64 ||
 	    ysize ==  96 || ysize == 160 || ysize == 192 ||
 	    ysize == 240 || ysize == 320 || ysize == 384 ||
-	    ysize == 480 || ysize == 768 ) && 
+	    ysize == 480 || ysize == 768 ) &&
 	   (xsize == 2*ysize || xsize == 1) )
 	{
 	  gridtype = GRID_GAUSSIAN;
@@ -1678,13 +1680,13 @@ void cgribexDefGrid(int *isec1, int *isec2, int *isec4, int gridID)
     }
   else if ( gridtype == GRID_CURVILINEAR )
     {
-      if ( lwarn && gridInqSize(gridID) > 1 )
+      if ( lwarning && gridInqSize(gridID) > 1 )
 	{
-	  lwarn = FALSE;
+	  lwarning = false;
 	  Warning("Curvilinear grids are unsupported in GRIB1! Created wrong GDS!");
 	}
       gridtype = GRID_LONLAT;
-      lcurvi = TRUE;
+      lcurvi = true;
     }
 
   ISEC2_Reduced  = FALSE;
@@ -1888,8 +1890,8 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
 {
   double level;
   int ilevel, zaxistype, ltype;
-  static int warning = 1;
-  static int vct_warning = 1;
+  static bool lwarning = true;
+  static bool lwarning_vct = true;
 
   zaxistype = zaxisInqType(zaxisID);
   ltype = zaxisInqLtype(zaxisID);
@@ -1983,18 +1985,18 @@ void cgribexDefLevel(int *isec1, int *isec2, double *fsec2, int zaxisID, int lev
 	  }
 
 	vctsize = zaxisInqVctSize(zaxisID);
-	if ( vctsize == 0 && warning )
+	if ( vctsize == 0 && lwarning )
 	  {
 	    Warning("VCT missing. ( param = %d, zaxisID = %d )", ISEC1_Parameter, zaxisID);
-	    warning = 0;
+	    lwarning = false;
 	  }
 	if ( vctsize > 255 )
 	  {
 	    ISEC2_NumVCP = 0;
-	    if ( vct_warning )
+	    if ( lwarning_vct )
 	      {
 		Warning("VCT size of %d is too large (maximum is 255). Set to 0!", vctsize);
-		vct_warning = 0;
+		lwarning_vct = false;
 	      }
 	  }
 	else
diff --git a/libcdi/src/stream_grb.c b/libcdi/src/stream_grb.c
index 873859a..5af130d 100644
--- a/libcdi/src/stream_grb.c
+++ b/libcdi/src/stream_grb.c
@@ -728,7 +728,7 @@ int grb_write_record(stream_t * streamptr, int memtype, const void *data, int nm
 }
 
 
-void streamInqGinfo(int streamID, int *intnum, float *fltnum)
+void streamInqGinfo(int streamID, int *intnum, float *fltnum, off_t *bignum)
 {
   int recID, vrecID, tsID;
   int filetype;
@@ -758,7 +758,7 @@ void streamInqGinfo(int streamID, int *intnum, float *fltnum)
       if ( zip > 0 )
 	Error("Compressed GRIB records unsupported!");
       else
-	gribGinfo(recpos, gribbuffersize, (unsigned char *) gribbuffer, intnum, fltnum);
+	gribGinfo(recpos, gribbuffersize, (unsigned char *) gribbuffer, intnum, fltnum, bignum);
     }
 }
 /*
diff --git a/libcdi/src/stream_gribapi.c b/libcdi/src/stream_gribapi.c
index aa0c37d..8065d70 100644
--- a/libcdi/src/stream_gribapi.c
+++ b/libcdi/src/stream_gribapi.c
@@ -957,7 +957,7 @@ void gribapiAddRecord(stream_t * streamptr, int param, grib_handle *gh,
       if ( linitial_field )
 	{
 	  if ( grib_get_double(gh, cdiAdditionalGRIBKeys[i], &dval) == 0 )
-            varDefOptGribInt(varID, dval, cdiAdditionalGRIBKeys[i]);
+            varDefOptGribDbl(varID, dval, cdiAdditionalGRIBKeys[i]);
 	}
       /* note: if the key is not defined, we do not throw an error! */
     }
@@ -2601,7 +2601,8 @@ void gribapiDefGrid(int editionNumber, grib_handle *gh, int gridID, int ljpeg, i
 	    GRIB_CHECK(grib_set_long(gh, "numberOfGridUsed", number), 0);
 	    GRIB_CHECK(grib_set_long(gh, "numberOfGridInReference", position), 0);
             len = 16;
-	    if (grib_set_bytes(gh, "uuidOfHGrid", (unsigned char *) gridInqUUID(gridID, uuid), &len) != 0)
+            gridInqUUID(gridID, uuid);
+	    if (grib_set_bytes(gh, "uuidOfHGrid", (unsigned char *) uuid, &len) != 0)
 	      Warning("Can't write UUID!");
 	  }
 
@@ -2896,7 +2897,8 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
                 GRIB_CHECK(grib_set_long(gh, "nlev", zaxisInqNlevRef(zaxisID)), 0);
                 GRIB_CHECK(grib_set_long(gh, "numberOfVGridUsed", number), 0);
                 len = 16;
-                if (grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) zaxisInqUUID(zaxisID, uuid), &len) != 0)
+                zaxisInqUUID(zaxisID, uuid);
+                if (grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) uuid, &len) != 0)
                   Warning("Can't write UUID!");
                 GRIB_CHECK(grib_set_long(gh, "topLevel", (long) dlevel1), 0);
                 GRIB_CHECK(grib_set_long(gh, "bottomLevel", (long) dlevel2), 0);
@@ -2914,7 +2916,8 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int param, int zaxisID,
                 GRIB_CHECK(grib_set_long(gh, "nlev", zaxisInqNlevRef(zaxisID)), 0);
                 GRIB_CHECK(grib_set_long(gh, "numberOfVGridUsed", number), 0);
                 len = 16;
-                if (grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) zaxisInqUUID(zaxisID, uuid), &len) != 0)
+                zaxisInqUUID(zaxisID, uuid);
+                if (grib_set_bytes(gh, "uuidOfVGrid", (unsigned char *) uuid, &len) != 0)
                   Warning("Can't write UUID!");
                 GRIB_CHECK(grib_set_double(gh, "level", level), 0);
               }
@@ -3044,13 +3047,25 @@ size_t gribapiEncode(int varID, int levelID, int vlistID, int gridID, int zaxisI
     int i;
     for (i=0; i<vlistptr->vars[varID].opt_grib_dbl_nentries; i++)
       {
-	GRIB_CHECK(grib_set_double(gh, vlistptr->vars[varID].opt_grib_dbl_keyword[i],
-				   vlistptr->vars[varID].opt_grib_dbl_val[i]), 0);
+	int ret = grib_set_double(gh, vlistptr->vars[varID].opt_grib_dbl_keyword[i],
+                                  vlistptr->vars[varID].opt_grib_dbl_val[i]);
+	if (ret != 0) {
+	    fprintf(stderr, "key \"%s\"  :   value = %g\n",
+                    vlistptr->vars[varID].opt_grib_dbl_keyword[i],
+		    vlistptr->vars[varID].opt_grib_dbl_val[i]);
+	}
+	GRIB_CHECK(ret, 0);
       }
     for (i=0; i<vlistptr->vars[varID].opt_grib_int_nentries; i++)
       {
-	GRIB_CHECK(grib_set_long(gh, vlistptr->vars[varID].opt_grib_int_keyword[i],
-				 vlistptr->vars[varID].opt_grib_int_val[i]), 0);
+	int ret = grib_set_long(gh, vlistptr->vars[varID].opt_grib_int_keyword[i],
+	                        vlistptr->vars[varID].opt_grib_int_val[i]);
+	if (ret != 0) {
+	    fprintf(stderr, "key \"%s\"  :   value = %d\n",
+		    vlistptr->vars[varID].opt_grib_int_keyword[i],
+		    vlistptr->vars[varID].opt_grib_int_val[i]);
+	}
+	GRIB_CHECK(ret, 0);
       }
   }
 
diff --git a/libcdi/src/taxis.c b/libcdi/src/taxis.c
index 0b49566..aca5593 100644
--- a/libcdi/src/taxis.c
+++ b/libcdi/src/taxis.c
@@ -7,10 +7,11 @@
 #include "dmemory.h"
 
 #include "cdi.h"
+#include "error.h"
 #include "taxis.h"
+#include "cdi_cksum.h"
 #include "cdi_int.h"
 #include "calendar.h"
-#include "pio_util.h"
 #include "namespace.h"
 #include "serialize.h"
 #include "resource_handle.h"
@@ -294,7 +295,7 @@ void taxisDefType(int taxisID, int type)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -375,7 +376,7 @@ void taxisDefRdate(int taxisID, int rdate)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -406,7 +407,7 @@ void taxisDefRtime(int taxisID, int rtime)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -439,7 +440,7 @@ void taxisDefCalendar(int taxisID, int calendar)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -457,7 +458,7 @@ void taxisDefTunit(int taxisID, int unit)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -475,7 +476,7 @@ void taxisDefNumavg(int taxisID, int numavg)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -520,7 +521,7 @@ void taxisDeleteBounds(int taxisID)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -609,7 +610,7 @@ void taxisDefVdateBounds(int taxisID, int vdate_lb, int vdate_ub)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -670,7 +671,7 @@ void taxisDefVtimeBounds(int taxisID, int vtime_lb, int vtime_ub)
 
   if ( reshGetStatus ( taxisID, &taxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1310,7 +1311,7 @@ taxisGetPackSize(void *p, void *context)
   taxis_t *taxisptr = p;
   int packBufferSize
     = serializeGetSize(taxisNint, DATATYPE_INT, context)
-    + serializeGetSize(1, DATATYPE_FLT64, context)
+    + serializeGetSize(1, DATATYPE_UINT32, context)
     + (taxisptr->name ?
        serializeGetSize(strlen(taxisptr->name), DATATYPE_TXT, context) : 0)
     + (taxisptr->longname ?
@@ -1325,14 +1326,14 @@ taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
 {
   taxis_t * taxisP;
   int intBuffer[taxisNint];
-  double d;
+  uint32_t d;
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   intBuffer, taxisNint, DATATYPE_INT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
+                  &d, 1, DATATYPE_UINT32, context);
 
-  xassert(xchecksum(DATATYPE_INT, taxisNint, intBuffer) == d);
+  xassert(cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer) == d);
 
   taxisInit();
 
@@ -1387,7 +1388,7 @@ taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferP
 {
   taxis_t *taxisP = (taxis_t *)voidP;
   int intBuffer[taxisNint];
-  double d;
+  uint32_t d;
 
   intBuffer[0]  = taxisP->self;
   intBuffer[1]  = taxisP->used;
@@ -1406,11 +1407,12 @@ taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferP
   intBuffer[14] = taxisP->vtime_ub;
   intBuffer[15] = taxisP->name ? strlen(taxisP->name) : 0;
   intBuffer[16] = taxisP->longname ? strlen(taxisP->longname) : 0;
+  intBuffer[17] = taxisP->climatology;
 
   serializePack(intBuffer, taxisNint, DATATYPE_INT,
                 packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum(DATATYPE_INT, taxisNint, intBuffer);
-  serializePack(&d, 1, DATATYPE_FLT64,
+  d = cdiCheckSum(DATATYPE_INT, taxisNint, intBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
                 packBuffer, packBufferSize, packBufferPos, context);
   if (taxisP->name)
     serializePack(taxisP->name, intBuffer[15], DATATYPE_TXT,
@@ -1419,7 +1421,6 @@ taxisPack(void * voidP, void * packBuffer, int packBufferSize, int * packBufferP
     serializePack(taxisP->longname, intBuffer[16], DATATYPE_TXT,
                   packBuffer, packBufferSize, packBufferPos, context);
 
-  intBuffer[17] = taxisP->climatology;
 }
 
 /*
diff --git a/libcdi/src/taxis.h b/libcdi/src/taxis.h
index 72ec845..1018782 100644
--- a/libcdi/src/taxis.h
+++ b/libcdi/src/taxis.h
@@ -37,7 +37,9 @@ double  cdiEncodeTimeval(int date, int time, taxis_t *taxis);
 void    timeval2vtime(double timevalue, taxis_t *taxis, int *vdate, int *vtime);
 double  vtime2timeval(int vdate, int vtime, taxis_t *taxis);
 
+#if !defined (SX)
 extern resOps taxisOps;
+#endif
 
 int
 taxisUnpack(char * unpackBuffer, int unpackBufferSize, int * unpackBufferPos,
diff --git a/libcdi/src/varscan.c b/libcdi/src/varscan.c
index 8c0f407..40e0e0c 100644
--- a/libcdi/src/varscan.c
+++ b/libcdi/src/varscan.c
@@ -380,11 +380,11 @@ int dblcmp(const void *s1, const void *s2)
 }
 */
 static
-int cmpLevelTable(const void *s1, const void *s2)
+int cmpLevelTable(const void* s1, const void* s2)
 {
   int cmp = 0;
-  leveltable_t *x = (leveltable_t *) s1;
-  leveltable_t *y = (leveltable_t *) s2;
+  const leveltable_t* x = s1;
+  const leveltable_t* y = s2;
   /*
   printf("%g %g  %d %d\n", x->leve11, y->level1, x, y);
   */
@@ -394,6 +394,21 @@ int cmpLevelTable(const void *s1, const void *s2)
   return (cmp);
 }
 
+static
+int cmpLevelTableInv(const void* s1, const void* s2)
+{
+  int cmp = 0;
+  const leveltable_t* x = s1;
+  const leveltable_t* y = s2;
+  /*
+  printf("%g %g  %d %d\n", x->leve11, y->level1, x, y);
+  */
+  if      ( x->level1 < y->level1 ) cmp =  1;
+  else if ( x->level1 > y->level1 ) cmp = -1;
+
+  return (cmp);
+}
+
 
 typedef struct
 {
@@ -405,11 +420,11 @@ param_t;
 
 
 static
-int cmpparam(const void *s1, const void *s2)
+int cmpparam(const void* s1, const void* s2)
 {
   int cmp = 0;
-  param_t *x = (param_t *) s1;
-  param_t *y = (param_t *) s2;
+  const param_t* x = s1;
+  const param_t* y = s2;
 
   if      ( x->param > y->param ) cmp =  1;
   else if ( x->param < y->param ) cmp = -1;
@@ -419,11 +434,11 @@ int cmpparam(const void *s1, const void *s2)
 
 
 static
-int cmpltype(const void *s1, const void *s2)
+int cmpltype(const void* s1, const void* s2)
 {
   int cmp = 0;
-  param_t *x = (param_t *) s1;
-  param_t *y = (param_t *) s2;
+  const param_t* x = s1;
+  const param_t* y = s2;
 
   if      ( x->ltype > y->ltype ) cmp =  1;
   else if ( x->ltype < y->ltype ) cmp = -1;
@@ -523,39 +538,47 @@ void cdi_generate_vars(stream_t *streamptr)
 
       if ( nlevels > 1 )
 	{
-	  int linc = FALSE, ldec = FALSE;
-	  /* check increasing of levels */
-	  for ( levelID = 1; levelID < nlevels; levelID++ )
-	    if ( dlevels[levelID] < dlevels[levelID-1] ) break;
-
-	  if ( levelID == nlevels ) linc = TRUE;
-
-	  if ( linc == FALSE )
-	    {
-	      /* check decreasing of levels */
-	      for ( levelID = 1; levelID < nlevels; levelID++ )
-		if ( dlevels[levelID] > dlevels[levelID-1] ) break;
-
-	      if ( levelID == nlevels ) ldec = TRUE;
+          bool linc = true, ldec = true, lsort = false;
+          for ( levelID = 1; levelID < nlevels; levelID++ )
+            {
+              /* check increasing of levels */
+              linc &= (dlevels[levelID] > dlevels[levelID-1]);
+              /* check decreasing of levels */
+              ldec &= (dlevels[levelID] < dlevels[levelID-1]);
+            }
+          /*
+           * always sort pressure z-axis to ensure
+           * vartable[varid].levelTable[levelID1].level1 < vartable[varid].levelTable[levelID2].level1 <=> levelID1 > levelID2
+           * unless already sorted in decreasing order
+           */
+          if ( !ldec && zaxistype == ZAXIS_PRESSURE )
+            {
+              qsort(vartable[varid].levelTable, (size_t)nlevels, sizeof(leveltable_t), cmpLevelTableInv);
+              lsort = true;
+            }
+          /*
+           * always sort hybrid and depth-below-land z-axis to ensure
+           * vartable[varid].levelTable[levelID1].level1 < vartable[varid].levelTable[levelID2].level1 <=> levelID1 < levelID2
+           * unless already sorted in increasing order
+           */
+          else if ( (!linc && !ldec) ||
+                    zaxistype == ZAXIS_HYBRID ||
+                    zaxistype == ZAXIS_DEPTH_BELOW_LAND )
+            {
+              qsort(vartable[varid].levelTable, (size_t)nlevels, sizeof(leveltable_t), cmpLevelTable);
+              lsort = true;
+            }
 
-	      if ( ldec == FALSE ||
-		   zaxistype == ZAXIS_HYBRID ||
-		   zaxistype == ZAXIS_DEPTH_BELOW_LAND )
-		{
-		  /*
-		  qsort(dlevels, nlevels, sizeof(double), dblcmp);
-		  */
-		  qsort(vartable[varid].levelTable, nlevels, sizeof(leveltable_t), cmpLevelTable);
-
-		  if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
-		    for ( levelID = 0; levelID < nlevels; levelID++ )
-		      dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
-					  level_sf*vartable[varid].levelTable[levelID].level2)/2.;
-		  else
-		    for ( levelID = 0; levelID < nlevels; levelID++ )
-		      dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
-		}
-	    }
+          if ( lsort )
+            {
+              if ( lbounds && zaxistype != ZAXIS_HYBRID && zaxistype != ZAXIS_HYBRID_HALF )
+                for ( levelID = 0; levelID < nlevels; levelID++ )
+                  dlevels[levelID] = (level_sf*vartable[varid].levelTable[levelID].level1 +
+                                      level_sf*vartable[varid].levelTable[levelID].level2)/2.;
+              else
+                for ( levelID = 0; levelID < nlevels; levelID++ )
+                  dlevels[levelID] = level_sf*vartable[varid].levelTable[levelID].level1;
+            }
 	}
 
       if ( lbounds )
@@ -566,7 +589,7 @@ void cdi_generate_vars(stream_t *streamptr)
 	  dlevels2 = (double *) malloc(nlevels*sizeof(double));
 	  for ( levelID = 0; levelID < nlevels; levelID++ )
 	    dlevels2[levelID] = level_sf*vartable[varid].levelTable[levelID].level2;
-	}
+        }
 
       char *unitptr = cdiUnitNamePtr(vartable[varid].level_unit);
       zaxisID = varDefZaxis(vlistID, zaxistype, nlevels, dlevels, lbounds, dlevels1, dlevels2,
diff --git a/libcdi/src/vlist.c b/libcdi/src/vlist.c
index 3cbebbf..5252b7c 100644
--- a/libcdi/src/vlist.c
+++ b/libcdi/src/vlist.c
@@ -5,15 +5,14 @@
 #include "dmemory.h"
 #include "cdi.h"
 #include "cdi_int.h"
+#include "error.h"
 #include "vlist.h"
 #include "zaxis.h"
 #include "varscan.h"
 #include "namespace.h"
-#include "pio_util.h"
 #include "resource_handle.h"
 #include "vlist_var.h"
 #include "vlist_att.h"
-#include "pio_rpc.h"
 
 #include "resource_unpack.h"
 #include "serialize.h"
@@ -250,7 +249,7 @@ vlist_delete(vlist_t *vlistptr)
 
 @Prototype void vlistDestroy(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
 
 @EndFunction
 */
@@ -269,8 +268,8 @@ void vlistDestroy(int vlistID)
 
 @Prototype void vlistCopy(int vlistID2, int vlistID1)
 @Parameter
-    @Item  vlistID2  Target variable list ID
-    @Item  vlistID1  Source variable list ID
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
 
 @Description
 The function @func{vlistCopy} copies all entries from vlistID1 to vlistID2.
@@ -294,7 +293,7 @@ void vlistCopy(int vlistID2, int vlistID1)
   if ( vlistptr1->vars )
     {
       int nvars = vlistptr1->nvars;
-      int nlevs, varID;
+      int varID;
 
       //vlistptr2->varsAllocated = nvars;
       vlistptr2->vars = (var_t *) malloc(vlistptr2->varsAllocated*sizeof(var_t));
@@ -345,10 +344,13 @@ void vlistCopy(int vlistID2, int vlistID1)
 	  vlistptr2->vars[varID].atts.nelems = 0;
 	  vlistCopyVarAtts(vlistID1, varID, vlistID2, varID);
 
-          nlevs = vlistptr1->vars[varID].nlevs;
-          vlistptr2->vars[varID].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
-          memcpy(vlistptr2->vars[varID].levinfo,
-                 vlistptr1->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
+          if ( vlistptr1->vars[varID].levinfo )
+            {
+              int nlevs = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
+              vlistptr2->vars[varID].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
+              memcpy(vlistptr2->vars[varID].levinfo,
+                     vlistptr1->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
+            }
 	}
     }
 }
@@ -359,7 +361,7 @@ void vlistCopy(int vlistID2, int vlistID1)
 
 @Prototype int vlistDuplicate(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
 @Description
 The function @func{vlistDuplicate} duplicates the variable list from vlistID1.
@@ -396,9 +398,13 @@ void vlistClearFlag(int vlistID)
   for ( varID = 0; varID < vlistptr->nvars; varID++ )
     {
       vlistptr->vars[varID].flag = FALSE;
-      for ( levID = 0; levID < vlistptr->vars[varID].nlevs; levID++ )
+      if ( vlistptr->vars[varID].levinfo )
         {
-          vlistptr->vars[varID].levinfo[levID].flag = FALSE;
+          int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
+          for ( levID = 0; levID < nlevs; levID++ )
+            {
+              vlistptr->vars[varID].levinfo[levID].flag = FALSE;
+            }
         }
     }
 }
@@ -491,8 +497,8 @@ int vlist_generate_zaxis(int vlistID, int zaxistype, int nlevels, double *levels
 
 @Prototype void vlistCopyFlag(int vlistID2, int vlistID1)
 @Parameter
-    @Item  vlistID2  Target variable list ID
-    @Item  vlistID1  Source variable list ID
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
 
 @Description
 The function @func{vlistCopyFlag} copies all entries with a flag from vlistID1 to vlistID2.
@@ -593,10 +599,11 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 	    vlistptr2->vars[varID2].atts.nelems = 0;
 	    vlistCopyVarAtts(vlistID1, varID, vlistID2, varID2);
 
-	    nlevs  = vlistptr1->vars[varID].nlevs;
+	    nlevs  = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
 	    nlevs2 = 0;
-	    for ( levID = 0; levID < nlevs; levID++ )
-	      if ( vlistptr1->vars[varID].levinfo[levID].flag ) nlevs2++;
+            if ( vlistptr1->vars[varID].levinfo )
+              for ( levID = 0; levID < nlevs; levID++ )
+                if ( vlistptr1->vars[varID].levinfo[levID].flag ) nlevs2++;
 
 	    vlistptr2->vars[varID2].levinfo = (levinfo_t *) malloc(nlevs2*sizeof(levinfo_t));
 
@@ -613,6 +620,8 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 		zaxisID = vlistptr1->vars[varID].zaxisID;
 		levels = (double *) malloc(nlevs2*sizeof(double));
 		levID2 = 0;
+                if (!vlistptr1->vars[varID].levinfo)
+                  cdiVlistCreateVarLevInfo(vlistptr1, varID);
 		for ( levID = 0; levID < nlevs; ++levID )
 		  if ( vlistptr1->vars[varID].levinfo[levID].flag )
 		    {
@@ -668,7 +677,6 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 
 		zaxisID = zaxisID2;
 		vlistptr2->vars[varID2].zaxisID = zaxisID2;
-		vlistptr2->vars[varID2].nlevs   = nlevs2;
 	      }
 
 	    for ( levID = 0; levID < nlevs2; levID++ )
@@ -717,8 +725,8 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
 
 @Prototype void vlistCat(int vlistID2, int vlistID1)
 @Parameter
-    @Item  vlistID2  Target variable list ID
-    @Item  vlistID1  Source variable list ID
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
 
 @Description
 Concatenate the variable list vlistID1 at the end of vlistID2.
@@ -779,9 +787,12 @@ void vlistCat(int vlistID2, int vlistID1)
       if ( vlistptr1->vars[varID].units )
         vlistptr2->vars[varID2].units = strdupx(vlistptr1->vars[varID].units);
 
-      nlevs = vlistptr1->vars[varID].nlevs;
-      vlistptr2->vars[varID2].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
-      memcpy(vlistptr2->vars[varID2].levinfo, vlistptr1->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
+      nlevs = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
+      if (vlistptr1->vars[varID].levinfo)
+        {
+          vlistptr2->vars[varID2].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
+          memcpy(vlistptr2->vars[varID2].levinfo, vlistptr1->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
+        }
 
       if ( vlistptr1->vars[varID].ensdata )
         {
@@ -844,8 +855,8 @@ void vlistCat(int vlistID2, int vlistID1)
 
 @Prototype void vlistMerge(int vlistID2, int vlistID1)
 @Parameter
-    @Item  vlistID2  Target variable list ID
-    @Item  vlistID1  Source variable list ID
+    @Item  vlistID2  Target variable list ID.
+    @Item  vlistID1  Source variable list ID.
 
 @Description
 Merge the variable list vlistID1 to the variable list vlistID2.
@@ -898,21 +909,24 @@ void vlistMerge(int vlistID2, int vlistID1)
           vlistptr1->vars[varID].mvarID = varID;
           vlistptr2->vars[varID].mvarID = varID;
 
-          nlevs1 = vlistptr1->vars[varID].nlevs;
-          nlevs2 = vlistptr2->vars[varID].nlevs;
+          nlevs1 = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
+          nlevs2 = zaxisInqSize(vlistptr2->vars[varID].zaxisID);
 
           nlevs = nlevs1 + nlevs2;
 
-          vlistptr2->vars[varID].nlevs = nlevs;
           /*
           fprintf(stderr, "var %d %d %d %d %d\n", varID, nlevs1, nlevs2, nlevs, sizeof(levinfo_t));
           */
-          vlistptr2->vars[varID].levinfo =
-            (levinfo_t *) realloc(vlistptr2->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
-
-	  memcpy(vlistptr2->vars[varID].levinfo+nlevs2,
-		 vlistptr1->vars[varID].levinfo, nlevs1*sizeof(levinfo_t));
+          if (vlistptr1->vars[varID].levinfo)
+            {
+              vlistptr2->vars[varID].levinfo =
+                xrealloc(vlistptr2->vars[varID].levinfo, nlevs*sizeof(levinfo_t));
 
+              memcpy(vlistptr2->vars[varID].levinfo+nlevs2,
+                     vlistptr1->vars[varID].levinfo, nlevs1*sizeof(levinfo_t));
+            }
+          else
+            cdiVlistCreateVarLevInfo(vlistptr1, varID);
 	  for ( levID = 0; levID < nlevs1; levID++ )
 	    {
 	      vlistptr1->vars[varID].levinfo[levID].mlevelID = nlevs2 + levID;
@@ -929,8 +943,8 @@ void vlistMerge(int vlistID2, int vlistID1)
           zaxisID1 = vlistptr1->vars[varID].zaxisID;
           zaxisID2 = vlistptr2->vars[varID].zaxisID;
           /*
-          nlevs1 = vlistptr1->vars[varID].nlevs;
-          nlevs2 = vlistptr2->vars[varID].nlevs;
+          nlevs1 = zaxisInqSize(vlistptr1->vars[varID].zaxisID);
+          nlevs2 = zaxisInqSize(vlistptr2->vars[varID].zaxisID);
           */
           nlevs1 = zaxisInqSize(zaxisID1);
           nlevs2 = zaxisInqSize(zaxisID2);
@@ -981,7 +995,7 @@ void vlistMerge(int vlistID2, int vlistID1)
 
 @Prototype int vlistNvars(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
 @Description
 The function @func{vlistNvars} returns the number of variables in the variable list vlistID.
@@ -1013,7 +1027,7 @@ int vlistNrecs(int vlistID)
   vlist_check_ptr(__func__, vlistptr);
 
   for ( varID = 0; varID < vlistptr->nvars; varID++ )
-    nrecs +=  vlistptr->vars[varID].nlevs;
+    nrecs +=  zaxisInqSize(vlistptr->vars[varID].zaxisID);
 
   return (nrecs);
 }
@@ -1058,7 +1072,7 @@ int vlistNumber(int vlistID)
 
 @Prototype int vlistNgrids(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
 @Description
 The function @func{vlistNgrids} returns the number of grids in the variable list vlistID.
@@ -1085,7 +1099,7 @@ int vlistNgrids(int vlistID)
 
 @Prototype int vlistNzaxis(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
 @Description
 The function @func{vlistNzaxis} returns the number of zaxis in the variable list vlistID.
@@ -1117,7 +1131,7 @@ void vlistDefNtsteps(int vlistID, int nts)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1166,7 +1180,7 @@ vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
 
   if ( nvars > 0 )
     {
-      fprintf(fp, " varID param    gridID zaxisID tsteptype nlevel flag "
+      fprintf(fp, " varID param    gridID zaxisID tsteptype flag "
               " name     longname iorank\n");
       for ( varID = 0; varID < nvars; varID++ )
         {
@@ -1174,7 +1188,6 @@ vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
           gridID   = vlistptr->vars[varID].gridID;
           zaxisID  = vlistptr->vars[varID].zaxisID;
 	  tsteptype= vlistptr->vars[varID].tsteptype;
-          nlevs    = vlistptr->vars[varID].nlevs;
           name     = vlistptr->vars[varID].name;
           longname = vlistptr->vars[varID].longname;
           units    = vlistptr->vars[varID].units;
@@ -1182,9 +1195,9 @@ vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
           iorank   = vlistptr->vars[varID].iorank;
 
           cdiParamToString(param, paramstr, sizeof(paramstr));
-          fprintf(fp, "%6d %-8s %6d %6d %6d %6d %5d %-8s"
+          fprintf(fp, "%6d %-8s %6d %6d %6d %5d %-8s"
                   " %s %6d",
-                  varID, paramstr, gridID, zaxisID, tsteptype, nlevs, flag,
+                  varID, paramstr, gridID, zaxisID, tsteptype, flag,
                   name ? name : "", longname ? longname : "",
                   iorank);
 
@@ -1196,18 +1209,24 @@ vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
       fprintf(fp, " varID  levID fvarID flevID mvarID mlevID  index  dtype  flag  level\n");
       for ( varID = 0; varID < nvars; varID++ )
         {
-          nlevs    = vlistptr->vars[varID].nlevs;
           zaxisID  = vlistptr->vars[varID].zaxisID;
+          nlevs    = zaxisInqSize(zaxisID);
           fvarID   = vlistptr->vars[varID].fvarID;
           mvarID   = vlistptr->vars[varID].mvarID;
           dtype    = vlistptr->vars[varID].datatype;
           for ( levID = 0; levID < nlevs; levID++ )
             {
-              flevID = vlistptr->vars[varID].levinfo[levID].flevelID;
-              mlevID = vlistptr->vars[varID].levinfo[levID].mlevelID;
-              index  = vlistptr->vars[varID].levinfo[levID].index;
-              flag   = vlistptr->vars[varID].levinfo[levID].flag;
+              levinfo_t li;
+              if (vlistptr->vars[varID].levinfo)
+                li = vlistptr->vars[varID].levinfo[levID];
+              else
+                li = DEFAULT_LEVINFO(levID);
+              flevID = li.flevelID;
+              mlevID = li.mlevelID;
+              index  = li.index;
+              flag   = li.flag;
               level  = zaxisInqLevel(zaxisID, levID);
+
               fprintf(fp, "%6d %6d %6d %6d %6d %6d %6d %6d %5d  %.9g\n",
                       varID, levID, fvarID, flevID, mvarID, mlevID, index,
                       dtype, flag, level);
@@ -1218,7 +1237,7 @@ vlistPrintKernel(vlist_t *vlistptr, FILE * fp )
       fprintf(fp, " varID  size iorank\n");
       for ( varID = 0; varID < nvars; varID++ )
         fprintf(fp, "%3d %8d %6d\n", varID,
-                vlistptr->vars[varID].nlevs
+                zaxisInqSize(vlistptr->vars[varID].zaxisID)
                 * gridInqSize(vlistptr->vars[varID].gridID),
                 vlistptr->vars[varID].iorank);
     }
@@ -1242,8 +1261,8 @@ void vlistPrint(int vlistID)
 
 @Prototype void vlistDefTaxis(int vlistID, int taxisID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
-    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  taxisID  Time axis ID, from a previous call to @fref{taxisCreate}.
 
 @Description
 The function @func{vlistDefTaxis} defines the time axis of a variable list.
@@ -1260,7 +1279,7 @@ void vlistDefTaxis(int vlistID, int taxisID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1273,7 +1292,7 @@ void vlistDefTaxis(int vlistID, int taxisID)
 
 @Prototype int vlistInqTaxis(int vlistID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
 
 @Description
 The function @func{vlistInqTaxis} returns the time axis of a variable list.
@@ -1305,7 +1324,7 @@ void  vlistDefTable(int vlistID, int tableID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1335,9 +1354,7 @@ void vlistDefInstitut(int vlistID, int instID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
-
-      xdebug("%s", "");
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1383,7 +1400,7 @@ void vlistDefModel(int vlistID, int modelID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1487,7 +1504,7 @@ void vlistChangeGridIndex(int vlistID, int index, int gridID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1513,7 +1530,7 @@ void vlistChangeGrid(int vlistID, int gridID1, int gridID2)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1580,7 +1597,7 @@ void vlistChangeZaxisIndex(int vlistID, int index, int zaxisID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1594,19 +1611,14 @@ void vlistChangeZaxisIndex(int vlistID, int index, int zaxisID)
         vlistptr->vars[varID].zaxisID = zaxisID;
 
         nlevs = zaxisInqSize(zaxisID);
-        if ( nlevs != vlistptr->vars[varID].nlevs )
+        if ( vlistptr->vars[varID].levinfo
+             && nlevs != zaxisInqSize(zaxisIDold) )
           {
-            vlistptr->vars[varID].nlevs   = nlevs;
             vlistptr->vars[varID].levinfo = (levinfo_t *) realloc(vlistptr->vars[varID].levinfo,
                                                                      nlevs*sizeof(levinfo_t));
 
             for ( levID = 0; levID < nlevs; levID++ )
-              {
-                vlistptr->vars[varID].levinfo[levID].flevelID = levID;
-                vlistptr->vars[varID].levinfo[levID].mlevelID = levID;
-                vlistptr->vars[varID].levinfo[levID].index    = -1;
-                vlistptr->vars[varID].levinfo[levID].flag     = FALSE;
-              }
+              vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO(levID);
           }
       }
 }
@@ -1616,7 +1628,7 @@ void vlistChangeZaxis(int vlistID, int zaxisID1, int zaxisID2)
 {
   int varID, nvars;
   int index, nzaxis;
-  int nlevs, levID;
+  int nlevs1 = zaxisInqSize(zaxisID1), nlevs2 = zaxisInqSize(zaxisID2), levID;
   vlist_t *vlistptr;
 
   vlistptr = vlist_to_pointer(vlistID);
@@ -1625,7 +1637,7 @@ void vlistChangeZaxis(int vlistID, int zaxisID1, int zaxisID2)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1645,20 +1657,14 @@ void vlistChangeZaxis(int vlistID, int zaxisID1, int zaxisID2)
       {
         vlistptr->vars[varID].zaxisID = zaxisID2;
 
-        nlevs = zaxisInqSize(zaxisID2);
-        if ( nlevs != vlistptr->vars[varID].nlevs )
+        if ( vlistptr->vars[varID].levinfo && nlevs2 != nlevs1 )
           {
-            vlistptr->vars[varID].nlevs   = nlevs;
-            vlistptr->vars[varID].levinfo = (levinfo_t *) realloc(vlistptr->vars[varID].levinfo,
-                                                                     nlevs*sizeof(levinfo_t));
+            vlistptr->vars[varID].levinfo
+              = realloc(vlistptr->vars[varID].levinfo,
+                        nlevs2 * sizeof(levinfo_t));
 
-            for ( levID = 0; levID < nlevs; levID++ )
-              {
-                vlistptr->vars[varID].levinfo[levID].flevelID = levID;
-                vlistptr->vars[varID].levinfo[levID].mlevelID = levID;
-                vlistptr->vars[varID].levinfo[levID].index    = -1;
-                vlistptr->vars[varID].levinfo[levID].flag     = FALSE;
-              }
+            for ( levID = 0; levID < nlevs2; levID++ )
+              vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO(levID);
           }
       }
 }
@@ -1703,7 +1709,7 @@ int  vlistGetSizeP ( void * vlistptr, void *context)
   txsize = serializeGetSize(vlist_nints, DATATYPE_INT, context);
   txsize += vlistAttsGetSize(p, CDI_GLOBAL, context);
   for ( varID = 0; varID <  p->nvars; varID++ )
-    txsize += vlistVarGetSize(p, varID, context);
+    txsize += vlistVarGetPackSize(p, varID, context);
   return txsize;
 }
 
@@ -1736,10 +1742,11 @@ void vlistUnpack(char * buf, int size, int *position, int nspTarget, void *conte
   serializeUnpack(buf, size, position, tempbuf, vlist_nints, DATATYPE_INT, context);
   newvlist = vlistCreate();
   /* xassert(newvlist == tempbuf[0]); */
-  vlistDefTaxis ( newvlist, namespaceAdaptKey ( tempbuf[3], nspTarget ));
-  vlistDefTable(newvlist, tempbuf[4]);
-  vlistDefInstitut ( newvlist, namespaceAdaptKey ( tempbuf[5], nspTarget ));
-  vlistDefModel ( newvlist, namespaceAdaptKey ( tempbuf[6], nspTarget ));
+  vlist_t *p = vlist_to_pointer(newvlist);
+  p->taxisID = namespaceAdaptKey(tempbuf[3], nspTarget);
+  p->tableID = tempbuf[4];
+  p->instID = namespaceAdaptKey(tempbuf[5], nspTarget);
+  p->modelID = namespaceAdaptKey(tempbuf[6], nspTarget);
   vlistAttsUnpack(newvlist, CDI_GLOBAL, buf, size, position, context);
   for ( varID = 0; varID < tempbuf[1]; varID++ )
     vlistVarUnpack(newvlist, buf, size, position, nspTarget, context);
diff --git a/libcdi/src/vlist.h b/libcdi/src/vlist.h
index 9c4dadc..cbc38b4 100644
--- a/libcdi/src/vlist.h
+++ b/libcdi/src/vlist.h
@@ -47,6 +47,8 @@ typedef struct
 }
 levinfo_t;
 
+#define DEFAULT_LEVINFO(levID) \
+  (levinfo_t){ .flag = 0, .index = -1, .flevelID = levID, .mlevelID = levID}
 
 typedef struct
 {
@@ -67,7 +69,6 @@ ensinfo_t;
 typedef struct
 {
   int         flag;
-  int         nlevs;
   int         isUsed;
   int         mvarID;
   int         fvarID;
diff --git a/libcdi/src/vlist_att.c b/libcdi/src/vlist_att.c
index a63fe11..6643992 100644
--- a/libcdi/src/vlist_att.c
+++ b/libcdi/src/vlist_att.c
@@ -11,7 +11,7 @@
 #include "cdi.h"
 #include "cdi_int.h"
 #include "vlist.h"
-#include "pio_util.h"
+#include "error.h"
 #include "serialize.h"
 
 static
@@ -105,7 +105,7 @@ void fill_att(cdi_att_t *attp, int indtype, int exdtype, size_t nelems, size_t x
 
 @Prototype int vlistInqNatts(int vlistID, int varID, int *nattsp)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
     @Item  nattsp   Pointer to location for returned number of variable attributes.
 
@@ -136,7 +136,7 @@ int vlistInqNatts(int vlistID, int varID, int *nattsp)
 
 @Prototype int vlistInqAtt(int vlistID, int varID, int attnum, char *name, int *typep, int *lenp)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
     @Item  attnum   Attribute number (from 0 to natts-1).
     @Item  name     Pointer to the location for the returned attribute name. The caller must allocate space for the 
@@ -389,7 +389,7 @@ int vlistDefAttTxt(int vlistID, int varID, const char *name, int len, const char
 
 @Prototype int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
     @Item  name     Attribute name.
     @Item  mlen     Number of allocated values provided for the attribute.
@@ -411,7 +411,7 @@ int vlistInqAttInt(int vlistID, int varID, const char *name, int mlen, int *ip)
 
 @Prototype int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *dp)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
     @Item  name     Attribute name.
     @Item  mlen     Number of allocated values provided for the attribute.
@@ -433,7 +433,7 @@ int vlistInqAttFlt(int vlistID, int varID, const char *name, int mlen, double *d
 
 @Prototype int vlistInqAttTxt(int vlistID, int varID, const char *name, int mlen, char *tp)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier, or @func{CDI_GLOBAL} for a global attribute.
     @Item  name     Attribute name.
     @Item  mlen     Number of allocated values provided for the attribute.
diff --git a/libcdi/src/vlist_var.c b/libcdi/src/vlist_var.c
index 3583b77..cbb0949 100644
--- a/libcdi/src/vlist_var.c
+++ b/libcdi/src/vlist_var.c
@@ -13,7 +13,7 @@
 #include "vlist_att.h"
 #include "namespace.h"
 #include "serialize.h"
-#include "pio_util.h"
+#include "error.h"
 
 extern resOps vlist_ops;
 
@@ -32,6 +32,7 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].tsteptype     = TSTEP_INSTANT;
   vlistptr->vars[varID].timave        = 0;
   vlistptr->vars[varID].timaccu       = 0;
+  vlistptr->vars[varID].typeOfGeneratingProcess = 0;
   vlistptr->vars[varID].chunktype     = cdiChunkType;
   vlistptr->vars[varID].xyz           = 0;
   vlistptr->vars[varID].gridID        = CDI_UNDEFID;
@@ -48,7 +49,6 @@ void vlistvarInitEntry(int vlistID, int varID)
   vlistptr->vars[varID].stdname       = NULL;
   vlistptr->vars[varID].units         = NULL;
   vlistptr->vars[varID].extra         = NULL;
-  vlistptr->vars[varID].nlevs         = 0;
   vlistptr->vars[varID].levinfo       = NULL;
   vlistptr->vars[varID].comptype      = COMPRESS_NONE;
   vlistptr->vars[varID].complevel     = 1;
@@ -200,15 +200,13 @@ vlistDestroy(vlistID);
 int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
 {
   int varID;
-  int nlevs;
-  int levID;
   int index;
   vlist_t *vlistptr;
 
   vlistptr = vlist_to_pointer(vlistID);
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return CDI_UNDEFID;
     }
 
@@ -229,20 +227,6 @@ int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
       vlistptr->vars[varID].tsteptype = TSTEP_INSTANT;
     }
 
-  nlevs = zaxisInqSize(zaxisID);
-
-  vlistptr->vars[varID].levinfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
-
-  for ( levID = 0; levID < nlevs; levID++ )
-    {
-      vlistptr->vars[varID].levinfo[levID].flag     = 0;
-      vlistptr->vars[varID].levinfo[levID].index    = -1;
-      vlistptr->vars[varID].levinfo[levID].flevelID = levID;
-      vlistptr->vars[varID].levinfo[levID].mlevelID = levID;
-    }
-
-  vlistptr->vars[varID].nlevs = nlevs;
-
   for ( index = 0; index < vlistptr->ngrids; index++ )
     if ( gridID == vlistptr->gridIDs[index] ) break;
 
@@ -272,6 +256,20 @@ int vlistDefVar(int vlistID, int gridID, int zaxisID, int tsteptype)
   return (varID);
 }
 
+void
+cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID)
+{
+  xassert(varID >= 0 && varID < vlistptr->nvars
+          && vlistptr->vars[varID].levinfo == NULL);
+  int zaxisID = vlistptr->vars[varID].zaxisID;
+  int nlevs = zaxisInqSize(zaxisID);
+
+  vlistptr->vars[varID].levinfo = malloc(nlevs * sizeof(levinfo_t));
+
+  for (int levID = 0; levID < nlevs; levID++ )
+      vlistptr->vars[varID].levinfo[levID] = DEFAULT_LEVINFO(levID);
+}
+
 /*
 @Function  vlistDefVarParam
 @Title     Define the parameter number of a Variable
@@ -297,7 +295,7 @@ void vlistDefVarParam(int vlistID, int varID, int param)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -330,14 +328,14 @@ void vlistDefVarCode(int vlistID, int varID, int code)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
   param = vlistptr->vars[varID].param;
 
   cdiDecodeParam(param, &pnum, &pcat, &pdis);
-  
+
   vlistptr->vars[varID].param = cdiEncodeParam(code, pcat, pdis);
 }
 
@@ -363,7 +361,7 @@ void vlistInqVar(int vlistID, int varID, int *gridID, int *zaxisID, int *tstepty
 
 @Prototype int vlistInqVarGrid(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -391,7 +389,7 @@ int vlistInqVarGrid(int vlistID, int varID)
 
 @Prototype int vlistInqVarZaxis(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -419,7 +417,7 @@ int vlistInqVarZaxis(int vlistID, int varID)
 
 @Prototype int vlistInqVarParam(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -450,7 +448,7 @@ int vlistInqVarParam(int vlistID, int varID)
 
 @Prototype int vlistInqVarCode(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -537,7 +535,7 @@ const char *vlistInqVarUnitsPtr(int vlistID, int varID)
 
 @Prototype void vlistInqVarName(int vlistID, int varID, char *name)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
     @Item  name     Returned variable name. The caller must allocate space for the 
                     returned string. The maximum possible length, in characters, of
@@ -591,7 +589,7 @@ void vlistInqVarName(int vlistID, int varID, char *name)
 
 @Prototype void vlistInqVarLongname(int vlistID, int varID, char *longname)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
     @Item  longname Long name of the variable. The caller must allocate space for the 
                     returned string. The maximum possible length, in characters, of
@@ -643,7 +641,7 @@ void vlistInqVarLongname(int vlistID, int varID, char *longname)
 
 @Prototype void vlistInqVarStdname(int vlistID, int varID, char *stdname)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
     @Item  stdname  Standard name of the variable. The caller must allocate space for the 
                     returned string. The maximum possible length, in characters, of
@@ -682,7 +680,7 @@ void vlistInqVarStdname(int vlistID, int varID, char *stdname)
 
 @Prototype void vlistInqVarUnits(int vlistID, int varID, char *units)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
     @Item  units    Units of the variable. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
@@ -774,7 +772,7 @@ int vlistInqVarSize(int vlistID, int varID)
 
 @Prototype int vlistInqVarDatatype(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -844,7 +842,7 @@ void vlistDefVarDatatype(int vlistID, int varID, int datatype)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -871,7 +869,7 @@ void vlistDefVarInstitut(int vlistID, int varID, int instID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -895,7 +893,7 @@ void vlistDefVarModel(int vlistID, int varID, int modelID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -921,7 +919,7 @@ void vlistDefVarTable(int vlistID, int varID, int tableID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -976,7 +974,7 @@ void vlistDefVarName(int vlistID, int varID, const char *name)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1017,7 +1015,7 @@ void vlistDefVarLongname(int vlistID, int varID, const char *longname)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1058,7 +1056,7 @@ void vlistDefVarStdname(int vlistID, int varID, const char *stdname)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1099,7 +1097,7 @@ void vlistDefVarUnits(int vlistID, int varID, const char *units)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1125,7 +1123,7 @@ void vlistDefVarUnits(int vlistID, int varID, const char *units)
 
 @Prototype double vlistInqVarMissval(int vlistID, int varID)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
 
 @Description
@@ -1195,7 +1193,7 @@ void vlistDefVarExtra(int vlistID, int varID, const char *extra)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1221,7 +1219,7 @@ void vlistDefVarExtra(int vlistID, int varID, const char *extra)
 
 @Prototype void vlistInqVarExtra(int vlistID, int varID, char *extra)
 @Parameter
-    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate}.
+    @Item  vlistID  Variable list ID, from a previous call to @fref{vlistCreate} or @fref{streamInqVlist}.
     @Item  varID    Variable identifier.
     @Item  extra    Returned variable extra information. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
@@ -1291,7 +1289,7 @@ double vlistInqVarScalefactor(int vlistID, int varID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return 1.0;
     }
 
@@ -1320,7 +1318,7 @@ void vlistDefVarScalefactor(int vlistID, int varID, double scalefactor)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed." );
+      Warning("%s", "Operation not executed." );
       return;
     }
 
@@ -1338,7 +1336,7 @@ void vlistDefVarAddoffset(int vlistID, int varID, double addoffset)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1356,7 +1354,7 @@ void vlistDefVarTsteptype(int vlistID, int varID, int tsteptype)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1382,7 +1380,7 @@ void vlistDefVarTimave(int vlistID, int varID, int timave)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1408,7 +1406,7 @@ void vlistDefVarTimaccu(int vlistID, int varID, int timaccu)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1434,7 +1432,7 @@ void vlistDefVarTypeOfGeneratingProcess(int vlistID, int varID, int typeOfGenera
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1526,14 +1524,33 @@ void vlistDefFlag(int vlistID, int varID, int levID, int flag)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  vlistptr->vars[varID].flag = flag;
+  levinfo_t li = DEFAULT_LEVINFO(levID);
+  if (vlistptr->vars[varID].levinfo)
+    ;
+  else if (flag != li.flag)
+    cdiVlistCreateVarLevInfo(vlistptr, varID);
+  else
+    return;
+
   vlistptr->vars[varID].levinfo[levID].flag = flag;
+
+  vlistptr->vars[varID].flag = 0;
+
+  int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
+  for ( int levelID = 0; levelID < nlevs; levelID++ )
+    {
+      if ( vlistptr->vars[varID].levinfo[levelID].flag )
+        {
+          vlistptr->vars[varID].flag = 1;
+          break;
+        }
+    }
 }
 
 
@@ -1543,7 +1560,13 @@ int vlistInqFlag(int vlistID, int varID, int levID)
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  return (vlistptr->vars[varID].levinfo[levID].flag);
+  if (vlistptr->vars[varID].levinfo)
+    return (vlistptr->vars[varID].levinfo[levID].flag);
+  else
+    {
+      levinfo_t li = DEFAULT_LEVINFO(levID);
+      return li.flag;
+    }
 }
 
 
@@ -1565,7 +1588,7 @@ int vlistFindVar(int vlistID, int fvarID)
       Message("varID not found for fvarID %d in vlistID %d!", fvarID, vlistID);
     }
 
-  return (varID);  
+  return (varID);
 }
 
 
@@ -1581,12 +1604,13 @@ int vlistFindLevel(int vlistID, int fvarID, int flevelID)
 
   if ( varID != -1 )
     {
-      for ( levelID = 0; levelID < vlistptr->vars[varID].nlevs; levelID++ )
+      int nlevs = zaxisInqSize(vlistptr->vars[varID].zaxisID);
+      for ( levelID = 0; levelID < nlevs; levelID++ )
 	{
 	  if ( vlistptr->vars[varID].levinfo[levelID].flevelID == flevelID ) break;
 	}
 
-      if ( levelID == vlistptr->vars[varID].nlevs )
+      if ( levelID == nlevs )
 	{
 	  levelID = -1;
 	  Message("levelID not found for fvarID %d and levelID %d in vlistID %d!",
@@ -1594,7 +1618,7 @@ int vlistFindLevel(int vlistID, int fvarID, int flevelID)
 	}
     }
 
-  return (levelID);  
+  return (levelID);
 }
 
 
@@ -1604,7 +1628,7 @@ int vlistMergedVar(int vlistID, int varID)
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  return (vlistptr->vars[varID].mvarID);  
+  return (vlistptr->vars[varID].mvarID);
 }
 
 
@@ -1614,7 +1638,13 @@ int vlistMergedLevel(int vlistID, int varID, int levelID)
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  return (vlistptr->vars[varID].levinfo[levelID].mlevelID);  
+  if (vlistptr->vars[varID].levinfo)
+    return vlistptr->vars[varID].levinfo[levelID].mlevelID;
+  else
+    {
+      levinfo_t li = DEFAULT_LEVINFO(levelID);
+      return li.mlevelID;
+    }
 }
 
 
@@ -1624,13 +1654,20 @@ void vlistDefIndex(int vlistID, int varID, int levelID, int index)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  vlistptr->vars[varID].levinfo[levelID].index = index;  
+  levinfo_t li = DEFAULT_LEVINFO(levelID);
+  if (vlistptr->vars[varID].levinfo)
+    ;
+  else if (index != li.index)
+    cdiVlistCreateVarLevInfo(vlistptr, varID);
+  else
+    return;
+  vlistptr->vars[varID].levinfo[levelID].index = index;
 }
 
 
@@ -1640,7 +1677,13 @@ int vlistInqIndex(int vlistID, int varID, int levelID)
 
   vlistptr = vlist_to_pointer(vlistID);
 
-  return (vlistptr->vars[varID].levinfo[levelID].index);  
+  if (vlistptr->vars[varID].levinfo)
+    return (vlistptr->vars[varID].levinfo[levelID].index);
+  else
+    {
+      levinfo_t li = DEFAULT_LEVINFO(levelID);
+      return li.index;
+    }
 }
 
 
@@ -1652,7 +1695,7 @@ void vlistChangeVarZaxis(int vlistID, int varID, int zaxisID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1702,7 +1745,7 @@ void vlistChangeVarGrid(int vlistID, int varID, int gridID)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1750,7 +1793,7 @@ void vlistDefVarCompType(int vlistID, int varID, int comptype)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1776,7 +1819,7 @@ void vlistDefVarCompLevel(int vlistID, int varID, int complevel)
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -2053,7 +2096,7 @@ void     vlistDefVarIOrank   ( int vlistID, int varID, int iorank )
 
   if ( reshGetStatus ( vlistID, &vlist_ops ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -2078,7 +2121,7 @@ enum {
   vlistvar_ndbls = 3,
 };
 
-int vlistVarGetSize(vlist_t *p, int varID, void *context)
+int vlistVarGetPackSize(vlist_t *p, int varID, void *context)
 {
   var_t *var = p->vars + varID;
   int varsize = serializeGetSize(vlistvar_nints, DATATYPE_INT, context)
@@ -2091,7 +2134,8 @@ int vlistVarGetSize(vlist_t *p, int varID, void *context)
     varsize += serializeGetSize(strlen(var->stdname), DATATYPE_TXT, context);
   if (var->units)
     varsize += serializeGetSize(strlen(var->units), DATATYPE_TXT, context);
-  varsize += serializeGetSize(4 * var->nlevs, DATATYPE_INT, context);
+  varsize += serializeGetSize(4 * zaxisInqSize(var->zaxisID),
+                              DATATYPE_INT, context);
   varsize += vlistAttsGetSize(p, varID, context);
   return varsize;
 }
@@ -2101,7 +2145,7 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
 {
   double dtempbuf[vlistvar_ndbls];
   var_t *var = p->vars + varID;
-  int tempbuf[vlistvar_nints], namesz, longnamesz, stdnamesz, unitssz, i;
+  int tempbuf[vlistvar_nints], namesz, longnamesz, stdnamesz, unitssz;
 
   tempbuf[0] = var->flag;
   tempbuf[1] = var->gridID;
@@ -2121,7 +2165,8 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
   tempbuf[15] = var->missvalused;
   tempbuf[16] = var->comptype;
   tempbuf[17] = var->complevel;
-  tempbuf[18] = var->nlevs;
+  int nlevs = var->levinfo ? zaxisInqSize(var->zaxisID) : 0;
+  tempbuf[18] = nlevs;
   tempbuf[19] = var->iorank;
   dtempbuf[0] = var->missval;
   dtempbuf[1] = var->scalefactor;
@@ -2141,18 +2186,19 @@ void vlistVarPack(vlist_t *p, int varID, char * buf, int size, int *position,
   if (unitssz)
     serializePack(var->units, unitssz, DATATYPE_TXT,
                   buf, size, position, context);
-  {
-    int levbuf[var->nlevs][4];
-    for (i = 0; i < var->nlevs; ++i)
+  if (nlevs)
     {
-      levbuf[i][0] = var->levinfo[i].flag;
-      levbuf[i][1] = var->levinfo[i].index;
-      levbuf[i][2] = var->levinfo[i].mlevelID;
-      levbuf[i][3] = var->levinfo[i].flevelID;
+      int levbuf[nlevs][4];
+      for (int levID = 0; levID < nlevs; ++levID)
+        {
+          levbuf[levID][0] = var->levinfo[levID].flag;
+          levbuf[levID][1] = var->levinfo[levID].index;
+          levbuf[levID][2] = var->levinfo[levID].mlevelID;
+          levbuf[levID][3] = var->levinfo[levID].flevelID;
+        }
+      serializePack(levbuf, nlevs * 4, DATATYPE_INT,
+                    buf, size, position, context);
     }
-    serializePack(levbuf, var->nlevs * 4, DATATYPE_INT,
-                  buf, size, position, context);
-  }
   vlistAttsPack(p, varID, buf, size, position, context);
 }
 
@@ -2170,6 +2216,7 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
   int tempbuf[vlistvar_nints];
   int newvar;
   char *varname = NULL;
+  vlist_t *vlistptr = vlist_to_pointer(vlistID);
   serializeUnpack(buf, size, position,
                   tempbuf, vlistvar_nints, DATATYPE_INT, context);
   serializeUnpack(buf, size, position,
@@ -2227,25 +2274,27 @@ void vlistVarUnpack(int vlistID, char * buf, int size, int *position,
   vlistDefVarAddoffset(vlistID, newvar, dtempbuf[2]);
   vlistDefVarCompType(vlistID, newvar, tempbuf[16]);
   vlistDefVarCompLevel(vlistID, newvar, tempbuf[17]);
-  {
-    int levbuf[tempbuf[18]][4];
-    var_t *var = vlist_to_pointer(vlistID)->vars + newvar;
-    int nlevs=tempbuf[18], i, flagSetLev = 0;
-    xassert(nlevs == var->nlevs);
-    serializeUnpack(buf, size, position,
-                    levbuf, nlevs * 4, DATATYPE_INT, context);
-    for (i = 0; i < nlevs; ++i)
-    {
-      vlistDefFlag(vlistID, newvar, i, levbuf[i][0]);
-      vlistDefIndex(vlistID, newvar, i, levbuf[i][1]);
-      // FIXME: these lack an accessor function
-      var->levinfo[i].mlevelID = levbuf[i][2];
-      var->levinfo[i].flevelID = levbuf[i][3];
-      if (levbuf[i][0] == tempbuf[0])
-        flagSetLev = i;
+  int nlevs = tempbuf[18];
+  if (nlevs)
+    {
+      int levbuf[nlevs][4];
+      var_t *var = vlistptr->vars + newvar;
+      int i, flagSetLev = 0;
+      cdiVlistCreateVarLevInfo(vlistptr, newvar);
+      serializeUnpack(buf, size, position,
+                      levbuf, nlevs * 4, DATATYPE_INT, context);
+      for (i = 0; i < nlevs; ++i)
+        {
+          vlistDefFlag(vlistID, newvar, i, levbuf[i][0]);
+          vlistDefIndex(vlistID, newvar, i, levbuf[i][1]);
+          // FIXME: these lack an accessor function
+          var->levinfo[i].mlevelID = levbuf[i][2];
+          var->levinfo[i].flevelID = levbuf[i][3];
+          if (levbuf[i][0] == tempbuf[0])
+            flagSetLev = i;
+        }
+      vlistDefFlag(vlistID, newvar, flagSetLev, levbuf[flagSetLev][0]);
     }
-    vlistDefFlag(vlistID, newvar, flagSetLev, levbuf[flagSetLev][0]);
-  }
   vlistDefVarIOrank(vlistID, newvar, tempbuf[19]);
   vlistAttsUnpack(vlistID, newvar, buf, size, position, context);
 }
diff --git a/libcdi/src/vlist_var.h b/libcdi/src/vlist_var.h
index 96f0b44..32968d7 100644
--- a/libcdi/src/vlist_var.h
+++ b/libcdi/src/vlist_var.h
@@ -9,10 +9,7 @@
 #include "vlist.h"
 #endif
 
-int  vlistInqVarDecoChunk ( int, int, int );
-int  vlistInqVarDecoOff   ( int, int, int );
-
-int  vlistVarGetSize(vlist_t *p, int varID, void *context);
+int  vlistVarGetPackSize(vlist_t *p, int varID, void *context);
 void vlistVarPack(vlist_t *p, int varID,
                   char * buffer, int bufferSize, int * pos, void *context);
 void vlistVarUnpack(int vlistID,
@@ -20,6 +17,8 @@ void vlistVarUnpack(int vlistID,
 void vlistDefVarIOrank    ( int, int, int );
 int  vlistInqVarIOrank    ( int, int );
 
+void cdiVlistCreateVarLevInfo(vlist_t *vlistptr, int varID);
+
 #endif
 /*
  * Local Variables:
diff --git a/libcdi/src/zaxis.c b/libcdi/src/zaxis.c
index 353d31d..ec498ce 100644
--- a/libcdi/src/zaxis.c
+++ b/libcdi/src/zaxis.c
@@ -9,8 +9,8 @@
 #include "dmemory.h"
 
 #include "cdi.h"
+#include "cdi_cksum.h"
 #include "cdi_int.h"
-#include "pio_util.h"
 #include "resource_handle.h"
 #include "resource_unpack.h"
 #include "varscan.h"
@@ -342,7 +342,7 @@ void zaxisDefName(int zaxisID, const char *name)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -374,7 +374,7 @@ void zaxisDefLongname(int zaxisID, const char *longname)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -406,7 +406,7 @@ void zaxisDefUnits(int zaxisID, const char *units)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -424,7 +424,7 @@ void zaxisDefUnits(int zaxisID, const char *units)
 
 @Prototype void zaxisInqName(int zaxisID, char *name)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
     @Item  name     Name of the Z-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
@@ -454,7 +454,7 @@ void zaxisInqName(int zaxisID, char *name)
 
 @Prototype void zaxisInqLongname(int zaxisID, char *longname)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
     @Item  longname Longname of the Z-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
@@ -484,7 +484,7 @@ void zaxisInqLongname(int zaxisID, char *longname)
 
 @Prototype void zaxisInqUnits(int zaxisID, char *units)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
     @Item  units    Units of the Z-axis. The caller must allocate space for the
                     returned string. The maximum possible length, in characters, of
                     the string is given by the predefined constant @func{CDI_MAX_NAME}.
@@ -527,7 +527,7 @@ void zaxisDefPrec(int zaxisID, int prec)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -557,7 +557,7 @@ void zaxisDefPositive(int zaxisID, int positive)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -587,7 +587,7 @@ void zaxisDefLtype(int zaxisID, int ltype)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -633,7 +633,7 @@ void zaxisDefLevels(int zaxisID, const double *levels)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -670,7 +670,7 @@ void zaxisDefLevel(int zaxisID, int levelID, double level)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -689,7 +689,7 @@ void zaxisDefNlevRef(int zaxisID, const int nhlev)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -735,7 +735,7 @@ void zaxisDefNumber(int zaxisID, const int number)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -752,7 +752,7 @@ void zaxisDefNumber(int zaxisID, const int number)
 
 @Prototype int zaxisInqNumber(int zaxisID)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
 
 @Description
 The function @func{zaxisInqNumber} returns the reference number to a generalized Z-axis.
@@ -795,7 +795,7 @@ void zaxisDefUUID(int zaxisID, const char *uuid)
 
     if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -812,18 +812,18 @@ void zaxisDefUUID(int zaxisID, const char *uuid)
 @Function  zaxisInqUUID
 @Title     Get the uuid to a generalized Z-axis
 
- at Prototype char *zaxisInqUUID(int zaxisID, char *uuid)
+ at Prototype void zaxisInqUUID(int zaxisID, char *uuid)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
 
 @Description
 The function @func{zaxisInqUUID} returns the UUID to a generalized Z-axis.
 
 @Result
- at func{zaxisInqUUID} returns the UUID to a generalized Z-axis.
+ at func{zaxisInqUUID} returns the UUID to a generalized Z-axis to the parameter uuid.
 @EndFunction
 */
-char *zaxisInqUUID(int zaxisID, char *uuid)
+void zaxisInqUUID(int zaxisID, char *uuid)
 {
   zaxis_t *zaxisptr;
 
@@ -832,8 +832,6 @@ char *zaxisInqUUID(int zaxisID, char *uuid)
   zaxis_check_ptr(zaxisID, zaxisptr);
 
   memcpy(uuid, zaxisptr->uuid, 16);
-
-  return (uuid);
 }
 
 /*
@@ -842,7 +840,7 @@ char *zaxisInqUUID(int zaxisID, char *uuid)
 
 @Prototype double zaxisInqLevel(int zaxisID, int levelID)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
     @Item  levelID  Level index (range: 0 to nlevel-1).
 
 @Description
@@ -918,7 +916,7 @@ const double *zaxisInqLevelsPtr(int zaxisID)
 
 @Prototype void zaxisInqLevels(int zaxisID, double *levels)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
     @Item  levels   Pointer to the location into which the levels are read.
                     The caller must allocate space for the returned values.
 
@@ -1040,7 +1038,7 @@ int zaxisInqLevelID(int zaxisID, double level)
 
 @Prototype int zaxisInqType(int zaxisID)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}.
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
 
 @Description
 The function @func{zaxisInqType} returns the type of a Z-axis.
@@ -1076,7 +1074,7 @@ int zaxisInqType(int zaxisID)
 
 @Prototype int zaxisInqSize(int zaxisID)
 @Parameter
-    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate}
+    @Item  zaxisID  Z-axis ID, from a previous call to @fref{zaxisCreate} or @fref{vlistInqVarZaxis}.
 
 @Description
 The function @func{zaxisInqSize} returns the size of a Z-axis.
@@ -1154,7 +1152,7 @@ void zaxisDefVct(int zaxisID, int size, const double *vct)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1217,7 +1215,7 @@ void zaxisDefLbounds(int zaxisID, const double *lbounds)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1245,7 +1243,7 @@ void zaxisDefUbounds(int zaxisID, const double *ubounds)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1273,7 +1271,7 @@ void zaxisDefWeights(int zaxisID, const double *weights)
 
   if ( reshGetStatus ( zaxisID, &zaxisOps ) == CLOSED )
     {
-      xwarning("%s", "Operation not executed.");
+      Warning("%s", "Operation not executed.");
       return;
     }
 
@@ -1648,31 +1646,36 @@ zaxisGetPackSize(void * voidP, void *context)
 {
   zaxis_t * zaxisP = ( zaxis_t * ) voidP;
   int packBufferSize = serializeGetSize(zaxisNint, DATATYPE_INT, context)
-    + serializeGetSize(1, DATATYPE_FLT64, context);
+    + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if (zaxisP->vals || zaxisP->lbounds || zaxisP->ubounds || zaxisP->weights)
     xassert(zaxisP->size);
 
   if ( zaxisP->vals )
-    packBufferSize += serializeGetSize( zaxisP->size + 1, DATATYPE_FLT64, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->lbounds )
-    packBufferSize += serializeGetSize(zaxisP->size + 1, DATATYPE_FLT64, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->ubounds )
-    packBufferSize += serializeGetSize(zaxisP->size + 1, DATATYPE_FLT64, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->weights )
-    packBufferSize += serializeGetSize(zaxisP->size + 1, DATATYPE_FLT64, context);
+    packBufferSize += serializeGetSize(zaxisP->size, DATATYPE_FLT64, context)
+      + serializeGetSize(1, DATATYPE_UINT32, context);
 
   if ( zaxisP->vct )
     {
       xassert ( zaxisP->vctsize );
-      packBufferSize += serializeGetSize(zaxisP->vctsize + 1, DATATYPE_FLT64, context);
+      packBufferSize += serializeGetSize(zaxisP->vctsize, DATATYPE_FLT64, context)
+        + serializeGetSize(1, DATATYPE_UINT32, context);
     }
 
   packBufferSize += serializeGetSize(zaxisNstrings * CDI_MAX_NAME, DATATYPE_TXT, context)
-    + serializeGetSize(1, DATATYPE_FLT64, context)
+    + serializeGetSize(1, DATATYPE_UINT32, context)
     + serializeGetSize(1, DATATYPE_UCHAR, context);
   return packBufferSize;
 }
@@ -1684,15 +1687,15 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
 {
   zaxis_t * zaxisP;
   int intBuffer[zaxisNint], memberMask;
-  double d;
+  uint32_t d;
   char charBuffer[zaxisNstrings * CDI_MAX_NAME];
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   intBuffer, zaxisNint, DATATYPE_INT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
+                  &d, 1, DATATYPE_UINT32, context);
 
-  xassert ( xchecksum ( DATATYPE_INT, zaxisNint, intBuffer ) == d );
+  xassert(cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer) == d);
 
   zaxisInit ();
 
@@ -1718,8 +1721,8 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       zaxisP->vals, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, zaxisP->vals) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->vals) == d);
     }
 
   if (memberMask & lbounds)
@@ -1731,8 +1734,8 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       zaxisP->lbounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, zaxisP->lbounds) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->lbounds) == d);
     }
 
   if (memberMask & ubounds)
@@ -1744,8 +1747,8 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       zaxisP->ubounds, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, zaxisP->ubounds) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->ubounds) == d);
     }
 
   if (memberMask & weights)
@@ -1757,8 +1760,8 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       zaxisP->weights, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, zaxisP->weights) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT, size, zaxisP->weights) == d);
     }
 
   if ( memberMask & vct )
@@ -1770,16 +1773,16 @@ zaxisUnpack(char * unpackBuffer, int unpackBufferSize,
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                       zaxisP->vct, size, DATATYPE_FLT64, context);
       serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                      &d, 1, DATATYPE_FLT64, context);
-      xassert(xchecksum(DATATYPE_FLT, size, zaxisP->vct) == d);
+                      &d, 1, DATATYPE_UINT32, context);
+      xassert(cdiCheckSum(DATATYPE_FLT64, size, zaxisP->vct) == d);
     }
 
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
                   charBuffer, zaxisNstrings * CDI_MAX_NAME, DATATYPE_TXT, context);
   serializeUnpack(unpackBuffer, unpackBufferSize, unpackBufferPos,
-                  &d, 1, DATATYPE_FLT64, context);
+                  &d, 1, DATATYPE_UINT32, context);
 
-  xassert(d == xchecksum(DATATYPE_TXT, zaxisNstrings * CDI_MAX_NAME, charBuffer));
+  xassert(d == cdiCheckSum(DATATYPE_TXT, zaxisNstrings * CDI_MAX_NAME, charBuffer));
 
   memcpy ( zaxisP->name,     &charBuffer[CDI_MAX_NAME * 0], CDI_MAX_NAME );
   memcpy ( zaxisP->longname, &charBuffer[CDI_MAX_NAME * 1], CDI_MAX_NAME );
@@ -1796,7 +1799,7 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 {
   zaxis_t   * zaxisP = ( zaxis_t * ) voidP;
   int intBuffer[zaxisNint];
-  double d;
+  uint32_t d;
   char charBuffer[zaxisNstrings * CDI_MAX_NAME];
 
   intBuffer[0]  = zaxisP->self;
@@ -1810,8 +1813,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 
   serializePack(intBuffer, zaxisNint, DATATYPE_INT,
                 packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum ( DATATYPE_INT, zaxisNint, intBuffer );
-  serializePack(&d, 1, DATATYPE_FLT64,
+  d = cdiCheckSum(DATATYPE_INT, zaxisNint, intBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
                 packBuffer, packBufferSize, packBufferPos, context);
 
 
@@ -1820,8 +1823,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
       xassert(zaxisP->size);
       serializePack(zaxisP->vals, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, zaxisP->size, zaxisP->vals );
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->vals );
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -1830,8 +1833,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
       xassert(zaxisP->size);
       serializePack(zaxisP->lbounds, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, zaxisP->size, zaxisP->lbounds);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->lbounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -1841,8 +1844,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(zaxisP->ubounds, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, zaxisP->size, zaxisP->ubounds);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->ubounds);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -1852,8 +1855,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(zaxisP->weights, zaxisP->size, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, zaxisP->size, zaxisP->weights);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT, zaxisP->size, zaxisP->weights);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -1863,8 +1866,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 
       serializePack(zaxisP->vct, zaxisP->vctsize, DATATYPE_FLT64,
                     packBuffer, packBufferSize, packBufferPos, context);
-      d = xchecksum(DATATYPE_FLT, zaxisP->vctsize, zaxisP->vct);
-      serializePack(&d, 1, DATATYPE_FLT64,
+      d = cdiCheckSum(DATATYPE_FLT64, zaxisP->vctsize, zaxisP->vct);
+      serializePack(&d, 1, DATATYPE_UINT32,
                     packBuffer, packBufferSize, packBufferPos, context);
     }
 
@@ -1875,8 +1878,8 @@ zaxisPack(void * voidP, void * packBuffer, int packBufferSize,
 
   serializePack(charBuffer, zaxisNstrings * CDI_MAX_NAME, DATATYPE_TXT,
                 packBuffer, packBufferSize, packBufferPos, context);
-  d = xchecksum(DATATYPE_TXT, zaxisNstrings * CDI_MAX_NAME, charBuffer);
-  serializePack(&d, 1, DATATYPE_FLT64,
+  d = cdiCheckSum(DATATYPE_TXT, zaxisNstrings * CDI_MAX_NAME, charBuffer);
+  serializePack(&d, 1, DATATYPE_UINT32,
                 packBuffer, packBufferSize, packBufferPos, context);
 
   serializePack(&zaxisP->positive, 1, DATATYPE_UCHAR,
diff --git a/libcdi/tests/Makefile.am b/libcdi/tests/Makefile.am
index 316c9f4..afa834b 100644
--- a/libcdi/tests/Makefile.am
+++ b/libcdi/tests/Makefile.am
@@ -1,32 +1,50 @@
 ## Process this file with automake to produce Makefile.in
 #
-TESTS = test_grib.sh cksum_verify \
+#TESTS = test_grib.sh
+TESTS = cksum_verify \
 	test_cksum_grib test_cksum_nc test_cksum_extra \
 	test_cksum_service test_cksum_nc2 test_cksum_nc4 test_cksum_ieg \
 	test_chunk_cksum \
 	pio_write_run pio_cksum_mpinonb pio_cksum_fpguard \
 	pio_cksum_asynch pio_cksum_writer pio_cksum_cdf \
-	test_resource_copy
+	test_resource_copy pio_write_deco2d_run
 check_PROGRAMS = cksum_verify test_grib cksum_write cksum_read pio_write \
-	test_resource_copy cksum_write_chunk
+	test_resource_copy cksum_write_chunk pio_write_deco2d
+
 #
 test_grib_SOURCES = test_grib.c
-cksum_verify_SOURCES = cksum_verify.c cksum.c cksum.h
-cksum_write_SOURCES = cksum_write.c cksum.c cksum.h
-cksum_write_chunk_SOURCES = cksum_write_chunk.c cksum.c cksum.h
+cksum_verify_SOURCES = cksum_verify.c
+cksum_write_SOURCES = cksum_write.c
+cksum_write_chunk_SOURCES = cksum_write_chunk.c
 cksum_read_SOURCES = cksum_read.c \
 	var_cksum.c var_cksum.h \
 	stream_cksum.c stream_cksum.h \
-	cksum.c cksum.h \
 	ensure_array_size.h ensure_array_size.c
-pio_write_SOURCES = pio_write.c cksum.h cksum.c
-test_resource_copy_SOURCES = test_resource_copy.c
+pio_write_SOURCES = pio_write.c pio_write.h simple_model.c \
+	simple_model_helper.h simple_model_helper.c
+pio_write_deco2d_SOURCES = pio_write.c pio_write.h deco2d_model.c \
+	simple_model_helper.h simple_model_helper.c
+test_resource_copy_SOURCES = test_resource_copy.c \
+	$(top_srcdir)/src/resource_unpack.c
+test_resource_copy_mpi_SOURCES = test_resource_copy.c
 #
-AM_CFLAGS = $(YAXT_CFLAGS)
+AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS)
+if USE_MPI
+pio_write_LDADD = ../src/libcdipio.la
+pio_write_deco2d_LDADD = ../src/libcdipio.la
+TESTS +=  test_resource_copy_mpi_run
+check_PROGRAMS += test_resource_copy_mpi
+test_resource_copy_mpi_LDADD = ../src/libcdipio.la
+test_resource_copy_mpi_CFLAGS = $(AM_CFLAGS) $(CFLAGS) -DMPI_MARSHALLING
+else
+pio_write_LDADD = $(LDADD)
+pio_write_deco2d_LDADD = $(LDADD)
+endif
+
 LDADD = ../src/libcdi.la -lm
 INCLUDES   = -I$(top_srcdir)/src
 #
-EXTRA_DIST = $(TESTS)
+# EXTRA_DIST = $(TESTS)
 #
 CLEANFILES  = `ls *~ *.grb *.nc *.srv *.ext example_*.cksum`
 #
diff --git a/libcdi/tests/Makefile.in b/libcdi/tests/Makefile.in
index 605e3f0..b35a251 100644
--- a/libcdi/tests/Makefile.in
+++ b/libcdi/tests/Makefile.in
@@ -50,24 +50,29 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-TESTS = test_grib.sh cksum_verify$(EXEEXT) test_cksum_grib \
-	test_cksum_nc test_cksum_extra test_cksum_service \
-	test_cksum_nc2 test_cksum_nc4 test_cksum_ieg test_chunk_cksum \
-	pio_write_run pio_cksum_mpinonb pio_cksum_fpguard \
-	pio_cksum_asynch pio_cksum_writer pio_cksum_cdf \
-	test_resource_copy$(EXEEXT)
+TESTS = cksum_verify$(EXEEXT) test_cksum_grib test_cksum_nc \
+	test_cksum_extra test_cksum_service test_cksum_nc2 \
+	test_cksum_nc4 test_cksum_ieg test_chunk_cksum pio_write_run \
+	pio_cksum_mpinonb pio_cksum_fpguard pio_cksum_asynch \
+	pio_cksum_writer pio_cksum_cdf test_resource_copy$(EXEEXT) \
+	pio_write_deco2d_run $(am__append_1)
 check_PROGRAMS = cksum_verify$(EXEEXT) test_grib$(EXEEXT) \
 	cksum_write$(EXEEXT) cksum_read$(EXEEXT) pio_write$(EXEEXT) \
-	test_resource_copy$(EXEEXT) cksum_write_chunk$(EXEEXT)
+	test_resource_copy$(EXEEXT) cksum_write_chunk$(EXEEXT) \
+	pio_write_deco2d$(EXEEXT) $(am__EXEEXT_1)
+ at USE_MPI_TRUE@am__append_1 = test_resource_copy_mpi_run
+ at USE_MPI_TRUE@am__append_2 = test_resource_copy_mpi
 subdir = tests
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(srcdir)/pio_cksum_asynch.in $(srcdir)/pio_cksum_cdf.in \
 	$(srcdir)/pio_cksum_fpguard.in $(srcdir)/pio_cksum_mpinonb.in \
-	$(srcdir)/pio_cksum_writer.in $(srcdir)/pio_write_run.in \
+	$(srcdir)/pio_cksum_writer.in \
+	$(srcdir)/pio_write_deco2d_run.in $(srcdir)/pio_write_run.in \
 	$(srcdir)/test_chunk_cksum.in $(srcdir)/test_cksum_extra.in \
 	$(srcdir)/test_cksum_grib.in $(srcdir)/test_cksum_ieg.in \
 	$(srcdir)/test_cksum_nc.in $(srcdir)/test_cksum_nc2.in \
-	$(srcdir)/test_cksum_nc4.in $(srcdir)/test_cksum_service.in
+	$(srcdir)/test_cksum_nc4.in $(srcdir)/test_cksum_service.in \
+	$(srcdir)/test_resource_copy_mpi_run.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/acx_assert_lang_is_fortran_variant.m4 \
@@ -78,7 +83,7 @@ am__aclocal_m4_deps =  \
 	$(top_srcdir)/m4/asx_unset.m4 $(top_srcdir)/m4/ax_pthread.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/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
 	$(top_srcdir)/m4/starlink_fpp.m4 $(top_srcdir)/acinclude.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -88,40 +93,57 @@ CONFIG_HEADER = $(top_builddir)/src/config.h
 CONFIG_CLEAN_FILES = test_cksum_grib test_cksum_nc test_cksum_nc2 \
 	test_cksum_nc4 test_cksum_extra test_cksum_service \
 	test_cksum_ieg test_chunk_cksum pio_write_run \
-	pio_cksum_mpinonb pio_cksum_fpguard pio_cksum_asynch \
-	pio_cksum_writer pio_cksum_cdf
+	pio_write_deco2d_run pio_cksum_mpinonb pio_cksum_fpguard \
+	pio_cksum_asynch pio_cksum_writer pio_cksum_cdf \
+	test_resource_copy_mpi_run
 CONFIG_CLEAN_VPATH_FILES =
+ at USE_MPI_TRUE@am__EXEEXT_1 = test_resource_copy_mpi$(EXEEXT)
 am_cksum_read_OBJECTS = cksum_read.$(OBJEXT) var_cksum.$(OBJEXT) \
-	stream_cksum.$(OBJEXT) cksum.$(OBJEXT) \
-	ensure_array_size.$(OBJEXT)
+	stream_cksum.$(OBJEXT) ensure_array_size.$(OBJEXT)
 cksum_read_OBJECTS = $(am_cksum_read_OBJECTS)
 cksum_read_LDADD = $(LDADD)
 cksum_read_DEPENDENCIES = ../src/libcdi.la
-am_cksum_verify_OBJECTS = cksum_verify.$(OBJEXT) cksum.$(OBJEXT)
+am_cksum_verify_OBJECTS = cksum_verify.$(OBJEXT)
 cksum_verify_OBJECTS = $(am_cksum_verify_OBJECTS)
 cksum_verify_LDADD = $(LDADD)
 cksum_verify_DEPENDENCIES = ../src/libcdi.la
-am_cksum_write_OBJECTS = cksum_write.$(OBJEXT) cksum.$(OBJEXT)
+am_cksum_write_OBJECTS = cksum_write.$(OBJEXT)
 cksum_write_OBJECTS = $(am_cksum_write_OBJECTS)
 cksum_write_LDADD = $(LDADD)
 cksum_write_DEPENDENCIES = ../src/libcdi.la
-am_cksum_write_chunk_OBJECTS = cksum_write_chunk.$(OBJEXT) \
-	cksum.$(OBJEXT)
+am_cksum_write_chunk_OBJECTS = cksum_write_chunk.$(OBJEXT)
 cksum_write_chunk_OBJECTS = $(am_cksum_write_chunk_OBJECTS)
 cksum_write_chunk_LDADD = $(LDADD)
 cksum_write_chunk_DEPENDENCIES = ../src/libcdi.la
-am_pio_write_OBJECTS = pio_write.$(OBJEXT) cksum.$(OBJEXT)
+am_pio_write_OBJECTS = pio_write.$(OBJEXT) simple_model.$(OBJEXT) \
+	simple_model_helper.$(OBJEXT)
 pio_write_OBJECTS = $(am_pio_write_OBJECTS)
-pio_write_LDADD = $(LDADD)
-pio_write_DEPENDENCIES = ../src/libcdi.la
+am__DEPENDENCIES_1 = ../src/libcdi.la
+ at USE_MPI_FALSE@pio_write_DEPENDENCIES = $(am__DEPENDENCIES_1)
+ at USE_MPI_TRUE@pio_write_DEPENDENCIES = ../src/libcdipio.la
+am_pio_write_deco2d_OBJECTS = pio_write.$(OBJEXT) \
+	deco2d_model.$(OBJEXT) simple_model_helper.$(OBJEXT)
+pio_write_deco2d_OBJECTS = $(am_pio_write_deco2d_OBJECTS)
+ at USE_MPI_FALSE@pio_write_deco2d_DEPENDENCIES = $(am__DEPENDENCIES_1)
+ at USE_MPI_TRUE@pio_write_deco2d_DEPENDENCIES = ../src/libcdipio.la
 am_test_grib_OBJECTS = test_grib.$(OBJEXT)
 test_grib_OBJECTS = $(am_test_grib_OBJECTS)
 test_grib_LDADD = $(LDADD)
 test_grib_DEPENDENCIES = ../src/libcdi.la
-am_test_resource_copy_OBJECTS = test_resource_copy.$(OBJEXT)
+am_test_resource_copy_OBJECTS = test_resource_copy.$(OBJEXT) \
+	resource_unpack.$(OBJEXT)
 test_resource_copy_OBJECTS = $(am_test_resource_copy_OBJECTS)
 test_resource_copy_LDADD = $(LDADD)
 test_resource_copy_DEPENDENCIES = ../src/libcdi.la
+am_test_resource_copy_mpi_OBJECTS =  \
+	test_resource_copy_mpi-test_resource_copy.$(OBJEXT)
+test_resource_copy_mpi_OBJECTS = $(am_test_resource_copy_mpi_OBJECTS)
+ at USE_MPI_TRUE@test_resource_copy_mpi_DEPENDENCIES =  \
+ at USE_MPI_TRUE@	../src/libcdipio.la
+test_resource_copy_mpi_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(test_resource_copy_mpi_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
 DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)/src
 depcomp = $(SHELL) $(top_srcdir)/config/depcomp
 am__depfiles_maybe = depfiles
@@ -137,12 +159,14 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
 	$(LDFLAGS) -o $@
 SOURCES = $(cksum_read_SOURCES) $(cksum_verify_SOURCES) \
 	$(cksum_write_SOURCES) $(cksum_write_chunk_SOURCES) \
-	$(pio_write_SOURCES) $(test_grib_SOURCES) \
-	$(test_resource_copy_SOURCES)
+	$(pio_write_SOURCES) $(pio_write_deco2d_SOURCES) \
+	$(test_grib_SOURCES) $(test_resource_copy_SOURCES) \
+	$(test_resource_copy_mpi_SOURCES)
 DIST_SOURCES = $(cksum_read_SOURCES) $(cksum_verify_SOURCES) \
 	$(cksum_write_SOURCES) $(cksum_write_chunk_SOURCES) \
-	$(pio_write_SOURCES) $(test_grib_SOURCES) \
-	$(test_resource_copy_SOURCES)
+	$(pio_write_SOURCES) $(pio_write_deco2d_SOURCES) \
+	$(test_grib_SOURCES) $(test_resource_copy_SOURCES) \
+	$(test_resource_copy_mpi_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -174,13 +198,6 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
-BUILD_CC = @BUILD_CC@
-BUILD_CFLAGS = @BUILD_CFLAGS@
-BUILD_CXX = @BUILD_CXX@
-BUILD_F77 = @BUILD_F77@
-BUILD_FC = @BUILD_FC@
-BUILD_FCFLAGS = @BUILD_FCFLAGS@
-BUILD_LDFLAGS = @BUILD_LDFLAGS@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CDI_F90_INTERFACE_FCFLAGS = @CDI_F90_INTERFACE_FCFLAGS@
@@ -358,25 +375,39 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
+
 #
 test_grib_SOURCES = test_grib.c
-cksum_verify_SOURCES = cksum_verify.c cksum.c cksum.h
-cksum_write_SOURCES = cksum_write.c cksum.c cksum.h
-cksum_write_chunk_SOURCES = cksum_write_chunk.c cksum.c cksum.h
+cksum_verify_SOURCES = cksum_verify.c
+cksum_write_SOURCES = cksum_write.c
+cksum_write_chunk_SOURCES = cksum_write_chunk.c
 cksum_read_SOURCES = cksum_read.c \
 	var_cksum.c var_cksum.h \
 	stream_cksum.c stream_cksum.h \
-	cksum.c cksum.h \
 	ensure_array_size.h ensure_array_size.c
 
-pio_write_SOURCES = pio_write.c cksum.h cksum.c
-test_resource_copy_SOURCES = test_resource_copy.c
+pio_write_SOURCES = pio_write.c pio_write.h simple_model.c \
+	simple_model_helper.h simple_model_helper.c
+
+pio_write_deco2d_SOURCES = pio_write.c pio_write.h deco2d_model.c \
+	simple_model_helper.h simple_model_helper.c
+
+test_resource_copy_SOURCES = test_resource_copy.c \
+	$(top_srcdir)/src/resource_unpack.c
+
+test_resource_copy_mpi_SOURCES = test_resource_copy.c
 #
-AM_CFLAGS = $(YAXT_CFLAGS)
+AM_CFLAGS = $(PPM_CORE_CFLAGS) $(YAXT_CFLAGS)
+ at USE_MPI_FALSE@pio_write_LDADD = $(LDADD)
+ at USE_MPI_TRUE@pio_write_LDADD = ../src/libcdipio.la
+ at USE_MPI_FALSE@pio_write_deco2d_LDADD = $(LDADD)
+ at USE_MPI_TRUE@pio_write_deco2d_LDADD = ../src/libcdipio.la
+ at USE_MPI_TRUE@test_resource_copy_mpi_LDADD = ../src/libcdipio.la
+ at USE_MPI_TRUE@test_resource_copy_mpi_CFLAGS = $(AM_CFLAGS) $(CFLAGS) -DMPI_MARSHALLING
 LDADD = ../src/libcdi.la -lm
 INCLUDES = -I$(top_srcdir)/src
 #
-EXTRA_DIST = $(TESTS)
+# EXTRA_DIST = $(TESTS)
 #
 CLEANFILES = `ls *~ *.grb *.nc *.srv *.ext example_*.cksum`
 #
@@ -433,6 +464,8 @@ test_chunk_cksum: $(top_builddir)/config.status $(srcdir)/test_chunk_cksum.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 pio_write_run: $(top_builddir)/config.status $(srcdir)/pio_write_run.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+pio_write_deco2d_run: $(top_builddir)/config.status $(srcdir)/pio_write_deco2d_run.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 pio_cksum_mpinonb: $(top_builddir)/config.status $(srcdir)/pio_cksum_mpinonb.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 pio_cksum_fpguard: $(top_builddir)/config.status $(srcdir)/pio_cksum_fpguard.in
@@ -443,6 +476,8 @@ pio_cksum_writer: $(top_builddir)/config.status $(srcdir)/pio_cksum_writer.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 pio_cksum_cdf: $(top_builddir)/config.status $(srcdir)/pio_cksum_cdf.in
 	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+test_resource_copy_mpi_run: $(top_builddir)/config.status $(srcdir)/test_resource_copy_mpi_run.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 
 clean-checkPROGRAMS:
 	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
@@ -467,12 +502,18 @@ cksum_write_chunk$(EXEEXT): $(cksum_write_chunk_OBJECTS) $(cksum_write_chunk_DEP
 pio_write$(EXEEXT): $(pio_write_OBJECTS) $(pio_write_DEPENDENCIES) $(EXTRA_pio_write_DEPENDENCIES) 
 	@rm -f pio_write$(EXEEXT)
 	$(LINK) $(pio_write_OBJECTS) $(pio_write_LDADD) $(LIBS)
+pio_write_deco2d$(EXEEXT): $(pio_write_deco2d_OBJECTS) $(pio_write_deco2d_DEPENDENCIES) $(EXTRA_pio_write_deco2d_DEPENDENCIES) 
+	@rm -f pio_write_deco2d$(EXEEXT)
+	$(LINK) $(pio_write_deco2d_OBJECTS) $(pio_write_deco2d_LDADD) $(LIBS)
 test_grib$(EXEEXT): $(test_grib_OBJECTS) $(test_grib_DEPENDENCIES) $(EXTRA_test_grib_DEPENDENCIES) 
 	@rm -f test_grib$(EXEEXT)
 	$(LINK) $(test_grib_OBJECTS) $(test_grib_LDADD) $(LIBS)
 test_resource_copy$(EXEEXT): $(test_resource_copy_OBJECTS) $(test_resource_copy_DEPENDENCIES) $(EXTRA_test_resource_copy_DEPENDENCIES) 
 	@rm -f test_resource_copy$(EXEEXT)
 	$(LINK) $(test_resource_copy_OBJECTS) $(test_resource_copy_LDADD) $(LIBS)
+test_resource_copy_mpi$(EXEEXT): $(test_resource_copy_mpi_OBJECTS) $(test_resource_copy_mpi_DEPENDENCIES) $(EXTRA_test_resource_copy_mpi_DEPENDENCIES) 
+	@rm -f test_resource_copy_mpi$(EXEEXT)
+	$(test_resource_copy_mpi_LINK) $(test_resource_copy_mpi_OBJECTS) $(test_resource_copy_mpi_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -480,16 +521,20 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cksum.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cksum_read.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cksum_verify.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cksum_write.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cksum_write_chunk.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/deco2d_model.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ensure_array_size.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pio_write.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/resource_unpack.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/simple_model.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/simple_model_helper.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/stream_cksum.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_grib.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_resource_copy.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/test_resource_copy_mpi-test_resource_copy.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/var_cksum.Po at am__quote@
 
 .c.o:
@@ -513,6 +558,34 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
 
+resource_unpack.o: $(top_srcdir)/src/resource_unpack.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT resource_unpack.o -MD -MP -MF $(DEPDIR)/resource_unpack.Tpo -c -o resource_unpack.o `test -f '$(top_srcdir)/src/resource_unpack.c' || echo '$(srcdir)/'`$(top_srcdir)/src/resource_unpack.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/resource_unpack.Tpo $(DEPDIR)/resource_unpack.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/src/resource_unpack.c' object='resource_unpack.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o resource_unpack.o `test -f '$(top_srcdir)/src/resource_unpack.c' || echo '$(srcdir)/'`$(top_srcdir)/src/resource_unpack.c
+
+resource_unpack.obj: $(top_srcdir)/src/resource_unpack.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT resource_unpack.obj -MD -MP -MF $(DEPDIR)/resource_unpack.Tpo -c -o resource_unpack.obj `if test -f '$(top_srcdir)/src/resource_unpack.c'; then $(CYGPATH_W) '$(top_srcdir)/src/resource_unpack.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/resource_unpack.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/resource_unpack.Tpo $(DEPDIR)/resource_unpack.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$(top_srcdir)/src/resource_unpack.c' object='resource_unpack.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o resource_unpack.obj `if test -f '$(top_srcdir)/src/resource_unpack.c'; then $(CYGPATH_W) '$(top_srcdir)/src/resource_unpack.c'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/resource_unpack.c'; fi`
+
+test_resource_copy_mpi-test_resource_copy.o: test_resource_copy.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resource_copy_mpi_CFLAGS) $(CFLAGS) -MT test_resource_copy_mpi-test_resource_copy.o -MD -MP -MF $(DEPDIR)/test_resource_copy_mpi-test_resource_copy.Tpo -c -o test_resource_copy_mpi-test_resource_copy.o `test -f 'test_resource_copy.c' || echo '$(srcdir)/'`test_resource_copy.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/test_resource_copy_mpi-test_resource_copy.Tpo $(DEPDIR)/test_resource_copy_mpi-test_resource_copy.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='test_resource_copy.c' object='test_resource_copy_mpi-test_resource_copy.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resource_copy_mpi_CFLAGS) $(CFLAGS) -c -o test_resource_copy_mpi-test_resource_copy.o `test -f 'test_resource_copy.c' || echo '$(srcdir)/'`test_resource_copy.c
+
+test_resource_copy_mpi-test_resource_copy.obj: test_resource_copy.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resource_copy_mpi_CFLAGS) $(CFLAGS) -MT test_resource_copy_mpi-test_resource_copy.obj -MD -MP -MF $(DEPDIR)/test_resource_copy_mpi-test_resource_copy.Tpo -c -o test_resource_copy_mpi-test_resource_copy.obj `if test -f 'test_resource_copy.c'; then $(CYGPATH_W) 'test_resource_copy.c'; else $(CYGPATH_W) '$(srcdir)/test_resource_copy.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/test_resource_copy_mpi-test_resource_copy.Tpo $(DEPDIR)/test_resource_copy_mpi-test_resource_copy.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='test_resource_copy.c' object='test_resource_copy_mpi-test_resource_copy.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resource_copy_mpi_CFLAGS) $(CFLAGS) -c -o test_resource_copy_mpi-test_resource_copy.obj `if test -f 'test_resource_copy.c'; then $(CYGPATH_W) 'test_resource_copy.c'; else $(CYGPATH_W) '$(srcdir)/test_resource_copy.c'; fi`
+
 mostlyclean-libtool:
 	-rm -f *.lo
 
diff --git a/libcdi/tests/cksum_verify b/libcdi/tests/cksum_verify
deleted file mode 100755
index 3805fd2..0000000
Binary files a/libcdi/tests/cksum_verify and /dev/null differ
diff --git a/libcdi/tests/deco2d_model.c b/libcdi/tests/deco2d_model.c
new file mode 100644
index 0000000..ffa239d
--- /dev/null
+++ b/libcdi/tests/deco2d_model.c
@@ -0,0 +1,496 @@
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#ifdef USE_MPI
+#include <mpi.h>
+#include <yaxt.h>
+#else
+typedef int MPI_Comm;
+#endif
+
+#include "cdi.h"
+#ifdef USE_MPI
+#include "cdipio.h"
+#include "pio_util.h"
+#ifdef HAVE_PPM_CORE
+#include <ppm/ppm_uniform_partition.h>
+#include <core/ppm_combinatorics.h>
+#endif
+#endif
+
+#include "cksum.h"
+#include "dmemory.h"
+#include "error.h"
+#include "pio_write.h"
+
+#include "simple_model_helper.h"
+
+enum {
+  ntfiles     = 2,
+  nproma = 16,
+};
+
+static void
+modelRegionCompute(double region[], int nlev, int nlat, int nlon,
+                   const int chunkStart[3], const int chunkSize[3],
+                   int tsID, const double lons[], const double lats[],
+                   double mscale, double mrscale)
+{
+  unsigned is = (unsigned)chunkStart[0],
+    js = (unsigned)chunkStart[1],
+    ks = (unsigned)chunkStart[2],
+    m = (unsigned)chunkSize[0],
+    n = (unsigned)chunkSize[1],
+    o = (unsigned)chunkSize[2],
+    jstride = (unsigned)chunkSize[0],
+    kstride = ((jstride * (unsigned)chunkSize[1] + nproma - 1)/nproma)*nproma;
+
+  for (unsigned k = 0; k < o; ++k)
+    for (unsigned j = 0; j < n; ++j)
+      for (unsigned i = 0; i < m; ++i)
+        region[k * kstride + j * jstride + i]
+          = sign_flat(round((cos(2.0 * M_PI * (lons[(i + is + tsID)%nlon]
+                                               - lons[0])
+                                 / (lons[nlon-1] - lons[0]))
+                             * sin(2.0 * M_PI * (lats[(j + js + k + ks)%nlat]
+                                                 - lats[0])
+                                   / (lats[nlat-1] - lats[0]))
+                             ) * mscale)) * mrscale;
+}
+
+#ifdef USE_MPI
+static void
+findPartition2D(int npart[2], int num_parts);
+#endif
+
+void
+modelRun(struct model_config setup, MPI_Comm comm)
+{
+  static const char * const fname_prefix        = "example";
+
+  struct
+  {
+    size_t size;
+    int nlev, zaxisID, id, code;
+    uint32_t checksum_state;
+#if USE_MPI
+    int chunkSize[2], start[2];
+    Xt_idxlist partDesc;
+    Xt_redist redist4gather;
+#endif
+  } *varDesc;
+  int gridID, taxisID, vlistID, streamID, tsID, tfID = 0;
+  int i, nmiss = 0;
+  double *lons, *lats, *levs;
+  double *var = NULL, *varslice = NULL;
+  double mscale, mrscale;
+  time_t current_time;
+  int vdate = 19850101, vtime = 120000;
+  int rank = 0;
+  char filename[1024];
+  int nlon = setup.nlon, nlat = setup.nlat;
+  int nVars = setup.nvars;
+  size_t varslice_size = 0;
+#if USE_MPI
+  int comm_size = 1;
+  int npart[2], rank_coord[2];
+  int *blk_displ, *blk_lens;
+#endif
+
+#if USE_MPI
+  xmpi ( MPI_Comm_rank ( comm, &rank ));
+  xmpi ( MPI_Comm_size ( comm, &comm_size ));
+#endif
+
+  if (rank == 0 && setup.compute_checksum)
+    {
+      var = xmalloc((size_t)nlon * (size_t)nlat
+                    * (size_t)setup.max_nlev * sizeof(var[0]));
+    }
+
+#if USE_MPI
+  if (comm_size == 1)
+    {
+      npart[0] = 1;
+      npart[1] = 1;
+      rank_coord[0] = 0;
+      rank_coord[1] = 0;
+    }
+  else
+    {
+      findPartition2D(npart, comm_size);
+      rank_coord[0] = rank % npart[0],
+        rank_coord[1] = rank / npart[0];
+    }
+  blk_displ = xmalloc(setup.max_nlev * sizeof (blk_displ[0]) * 2);
+  blk_lens = blk_displ + setup.max_nlev;
+#endif
+
+  var_scale(setup.datatype, &mscale, &mrscale);
+
+  gridID = gridCreate ( GRID_LONLAT, nlon*nlat );
+  gridDefXsize ( gridID, nlon );
+  gridDefYsize ( gridID, nlat );
+  lons = xmalloc(nlon * sizeof (lons[0]));
+  for (i = 0; i < nlon; ++i)
+    lons[i] = ((double)(i * 360))/nlon;
+  lats = xmalloc(nlat * sizeof (lats[0]));
+  for (i = 0; i < nlat; ++i)
+    lats[i] = ((double)(i * 180))/nlat - 90.0;
+  gridDefXvals ( gridID, lons );
+  gridDefYvals ( gridID, lats );
+
+  levs = xmalloc(setup.max_nlev * sizeof (levs[0]));
+  for (i = 0; i < setup.max_nlev; ++i)
+    levs[i] = 101300.0
+      - 3940.3 * (exp(1.3579 * (double)(i)/(setup.max_nlev - 1)) - 1.0);
+
+  vlistID = vlistCreate ();
+
+  varDesc = xmalloc(nVars * sizeof (varDesc[0]));
+  for (int varIdx = 0; varIdx < nVars; varIdx++ )
+    {
+      int varLevs = random()%4;
+      switch (varLevs)
+        {
+        case 1:
+          varLevs = setup.max_nlev / 3;
+          break;
+        case 2:
+          varLevs = setup.max_nlev >= 11 ? 11 : setup.max_nlev / 2;
+          break;
+        case 3:
+          varLevs = setup.max_nlev - 1;
+          break;
+        }
+      ++varLevs;
+      varDesc[varIdx].nlev = varLevs;
+      for (size_t i = 0; i < varIdx; ++i)
+        if (varDesc[i].nlev == varLevs)
+          {
+            varDesc[varIdx].zaxisID = varDesc[i].zaxisID;
+            goto zaxisIDset;
+          }
+      varDesc[varIdx].zaxisID
+        = zaxisCreate(ZAXIS_PRESSURE, varDesc[varIdx].nlev);
+      zaxisDefLevels(varDesc[varIdx].zaxisID, levs);
+      zaxisIDset:
+      varDesc[varIdx].id = vlistDefVar(vlistID, gridID, varDesc[varIdx].zaxisID,
+                                       TIME_VARIABLE);
+      varDesc[varIdx].size = nlon * nlat * varDesc[varIdx].nlev;
+#ifdef USE_MPI
+      {
+        int start[2], chunkSize[3], varSize[2] = { nlon, nlat };
+        for (size_t i = 0; i < 2; ++i)
+          {
+            struct PPM_extent range
+              = PPM_uniform_partition((struct PPM_extent){ 0, varSize[i] },
+                                      npart[i], rank_coord[i]);
+            start[i] = range.first;
+            chunkSize[i] = range.size;
+            fprintf(stderr, "%d: start[%zu]=%d, chunkSize[%zu] = %d\n", rank,
+                    i, start[i], i, chunkSize[i]);
+            varDesc[varIdx].start[i] = range.first;
+            varDesc[varIdx].chunkSize[i] = range.size;
+          }
+        Xt_int varSizeXt[3] = { (Xt_int)nlon, (Xt_int)nlat, (Xt_int)varLevs };
+        chunkSize[2] = varLevs;
+        Xt_int varStartXt[3] = { start[0], start[1], 0 };
+        for (int i = 0; i < varIdx; ++i)
+          if (varDesc[i].nlev == varLevs)
+            {
+              varDesc[varIdx].redist4gather = varDesc[i].redist4gather;
+              varDesc[varIdx].partDesc = varDesc[i].partDesc;
+              goto gatherRedistSet;
+            }
+        Xt_idxlist part_idxlist
+          = xt_idxsection_new(0, (varLevs > 1 ? 3 : 2), varSizeXt,
+                              chunkSize, varStartXt),
+          gather_idxlist;
+        varDesc[varIdx].partDesc = part_idxlist;
+        if (setup.compute_checksum)
+          {
+            if (rank == 0)
+              {
+                gather_idxlist
+                  = xt_idxstripes_new(&(struct Xt_stripe){.start = 0,
+                        .stride = 1, .nstrides = varDesc[varIdx].size }, 1);
+              }
+            else
+              gather_idxlist = xt_idxempty_new();
+            Xt_xmap xmap4gather
+              = xt_xmap_all2all_new(part_idxlist, gather_idxlist, comm);
+            xt_idxlist_delete(gather_idxlist);
+            struct Xt_offset_ext *src_blocks = xmalloc(varLevs
+                                                       * sizeof (*src_blocks));
+            struct Xt_offset_ext dst_block = { .start = 0,
+                                               .size = nlon * nlat * varLevs,
+                                               .stride = 1 };
+            size_t levStride
+              = (((size_t)chunkSize[0] * (size_t)chunkSize[1] + nproma - 1)
+                 / nproma) * nproma;
+            for (size_t i = 0; i < (size_t)varLevs; ++i)
+              src_blocks[i] = (struct Xt_offset_ext)
+                { .start = (int)i * levStride,
+                  .size = chunkSize[0] * chunkSize[1],
+                  .stride = 1 };
+            varDesc[varIdx].redist4gather
+              = xt_redist_p2p_ext_new(xmap4gather,
+                                      varLevs, src_blocks, 1, &dst_block,
+                                      MPI_DOUBLE);
+            free(src_blocks);
+            xt_xmap_delete(xmap4gather);
+          }
+        gatherRedistSet: ;
+      }
+#endif
+      varDesc[varIdx].code = 129 + varIdx;
+      vlistDefVarCode(vlistID, varDesc[varIdx].id, varDesc[varIdx].code);
+      vlistDefVarDatatype(vlistID, varDesc[varIdx].id, setup.datatype);
+    }
+
+  taxisID = taxisCreate ( TAXIS_ABSOLUTE );
+  vlistDefTaxis ( vlistID, taxisID );
+
+  sprintf ( &filename[0], "%s_%d.%s", fname_prefix, tfID, setup.suffix );
+  streamID = streamOpenWrite ( filename, setup.filetype );
+  xassert ( streamID >= 0 );
+  streamDefVlist ( streamID, vlistID);
+
+#ifdef USE_MPI
+  pioEndDef ();
+#endif
+
+  for ( tfID = 0; tfID < ntfiles; tfID++ )
+    {
+      for (int varIdx = 0; varIdx < nVars; ++varIdx)
+        varDesc[varIdx].checksum_state = 0;
+      if ( tfID > 0 )
+	{
+	  streamClose ( streamID );
+	  sprintf ( &filename[0], "%s_%d.%s", fname_prefix, tfID, setup.suffix );
+	  streamID = streamOpenWrite ( filename, setup.filetype );
+	  xassert ( streamID >= 0 );
+	  streamDefVlist ( streamID, vlistID );
+	}
+      vdate = 19850101;
+      vtime = 120000;
+      current_time = cditime2time_t(vdate, vtime);
+      for ( tsID = 0; tsID < setup.nts; tsID++ )
+	{
+          time_t2cditime(current_time, &vdate, &vtime);
+	  taxisDefVdate ( taxisID, vdate );
+	  taxisDefVtime ( taxisID, vtime );
+	  streamDefTimestep ( streamID, tsID );
+	  for (int varID = 0; varID < nVars; ++varID)
+	    {
+              size_t varLevs = (size_t)varDesc[varID].nlev;
+#ifdef USE_MPI
+              int start[3] = { varDesc[varID].start[0],
+                               varDesc[varID].start[1],
+                               0 };
+              int chunk[3] = { varDesc[varID].chunkSize[0],
+                               varDesc[varID].chunkSize[1],
+                               (int)varLevs };
+#else
+              int chunk[3] = { nlon, nlat, (int)varLevs };
+              int start[3] = { 0, 0, 0 };
+#endif
+              size_t chunkSize
+                = (((size_t)chunk[0] * (size_t)chunk[1] + (size_t)(nproma - 1))
+                   / (size_t)nproma) * (size_t)nproma * varLevs;
+              if (varslice_size < chunkSize)
+                {
+                  varslice = xrealloc(varslice, chunkSize * sizeof (var[0]));
+                  varslice_size = chunkSize;
+                }
+              modelRegionCompute(varslice, (int)varLevs, nlat, nlon,
+                                 start, chunk, tsID, lons, lats,
+                                 mscale, mrscale);
+              if (setup.compute_checksum)
+                {
+#if USE_MPI
+                  xt_redist_s_exchange1(varDesc[varID].redist4gather,
+                                        varslice, var);
+                  size_t layerSize = (size_t)(chunk[0] * chunk[1]);
+                  size_t nblk = (layerSize + nproma - 1)/nproma - 1;
+                  size_t npromz = layerSize - nblk * nproma;
+                  for (size_t k = 0; k < varLevs; ++k)
+                    {
+                      blk_displ[k] = k * (nblk + 1) * nproma;
+                      blk_lens[k] = layerSize;
+                    }
+#else
+                  size_t layerSize = (size_t)(chunk[0] * chunk[1]);
+                  size_t nblk = (layerSize + nproma - 1)/nproma - 1;
+                  size_t npromz = layerSize - nblk * nproma;
+                  for (size_t k = 0; k < varLevs; ++k)
+                    {
+                      for (size_t j = 0; j < nblk; ++j)
+                        for (size_t i = 0; i < nproma; ++i)
+                          var[k * layerSize + j * nproma + i] =
+                            varslice[k * (nblk + 1) * nproma + j * nproma + i];
+                      for (size_t i = 0; i < npromz; ++i)
+                        var[k * layerSize + nblk * nproma + i] =
+                          varslice[k * (nblk + 1) * nproma + nblk * nproma + i];
+                    }
+#endif
+                }
+              if (rank == 0 && setup.compute_checksum)
+                {
+                  memcrc_r(&varDesc[varID].checksum_state,
+                           (const unsigned char *)var,
+                           varDesc[varID].size * sizeof (var[0]));
+                }
+
+#ifdef USE_MPI
+	      streamWriteScatteredVarPart(streamID, varDesc[varID].id,
+                                          varslice,
+                                          (int)varLevs, blk_lens, blk_displ,
+                                          nmiss, varDesc[varID].partDesc);
+#else
+	      streamWriteVar(streamID, varDesc[varID].id, var, nmiss);
+#endif
+	    }
+          current_time += 86400;
+#ifdef USE_MPI
+	  pioWriteTimestep ( tsID, vdate, vtime );
+#endif
+	}
+      if (rank == 0 && setup.compute_checksum)
+        {
+          FILE *tablefp;
+          {
+            sprintf(filename, "%s_%d.cksum", fname_prefix, tfID);
+            if (!(tablefp = fopen(filename, "w")))
+              {
+                perror("failed to open table file");
+                exit(EXIT_FAILURE);
+              }
+            for (i = 0; i < nVars; ++i)
+              {
+                uint32_t cksum;
+                int code;
+                cksum = memcrc_finish(&varDesc[i].checksum_state,
+                                      (off_t)varDesc[i].size
+                                      * sizeof (var[0]) * setup.nts);
+                code = vlistInqVarCode(vlistID, varDesc[i].id);
+                if (fprintf(tablefp, "%08lx %d\n", (unsigned long)cksum,
+                            code) < 0)
+                  {
+                    perror("failed to write table file");
+                    exit(EXIT_FAILURE);
+                  }
+              }
+            fclose(tablefp);
+          }
+        }
+    }
+  free(varslice);
+#ifdef USE_MPI
+  pioEndTimestepping ();
+#endif
+  streamClose ( streamID );
+  vlistDestroy ( vlistID );
+  taxisDestroy ( taxisID );
+  for (int varID = 0; varID < nVars; varID++ )
+    {
+      int zID = varDesc[varID].zaxisID;
+      if (zID != CDI_UNDEFID)
+        {
+          zaxisDestroy(zID);
+#if USE_MPI
+          xt_idxlist_delete(varDesc[varID].partDesc);
+          xt_redist_delete(varDesc[varID].redist4gather);
+#endif
+          for (int j = varID + 1; j < nVars; ++j)
+            if (zID == varDesc[j].zaxisID)
+              varDesc[j].zaxisID = CDI_UNDEFID;
+        }
+    }
+  gridDestroy ( gridID );
+  free(var);
+#if USE_MPI
+  free(blk_displ);
+#endif
+  free(varDesc);
+  free(levs);
+  free(lats);
+  free(lons);
+}
+
+#ifdef USE_MPI
+static void
+findPartition2D(int npart[2], int num_parts)
+{
+  const uint64_t rscale = 256;
+  uint32_t *factors = NULL;
+  xassert(num_parts > 0);
+  int numFactors
+    = PPM_prime_factorization_32((uint32_t)num_parts, &factors);
+  /* try to distribute prime factors on dimensions to get
+   * approx. 2 times as many parts in x dim than y dim */
+  const uint64_t optimumRatio = rscale * 2;
+  npart[0] = num_parts, npart[1] = 1;
+  uint_fast32_t npart_attempt[2];
+  uint64_t bestRatio = (uint64_t)num_parts * rscale,
+    bestDiff = llabs((long long)(bestRatio - optimumRatio));
+  /* test all assignments of factors to dimensions, starting with
+   * only one assigned to x dim (omitting 0 because that would
+   * always give npart[1] > npart[0] */
+  for (int assign2X = 1; assign2X <= numFactors; ++assign2X)
+    {
+      uint_fast32_t pattern = (1 << assign2X) - 1,
+        lastPattern = pattern << (numFactors - assign2X);
+      do {
+        npart_attempt[0] = 1;
+        npart_attempt[1] = 1;
+        /* loop over all factors */
+        for (uint_fast32_t i = 0; i < numFactors; ++i)
+          {
+            uint_fast32_t dim_idx = (pattern >> i) & 1;
+            npart_attempt[dim_idx] *= factors[i];
+          }
+        uint64_t ratio = ((uint64_t)npart_attempt[0] * rscale)
+          / (uint64_t)npart_attempt[1];
+        uint64_t diff = llabs(ratio - optimumRatio);
+        if (diff < bestDiff)
+          {
+            npart[0] = (int)npart_attempt[0];
+            npart[1] = (int)npart_attempt[1];
+            bestDiff = diff;
+            bestRatio = ratio;
+          }
+        {
+          uint_fast32_t t;
+#if HAVE_DECL___BUILTIN_CTZ
+          t = pattern | (pattern - 1);
+          pattern = (t + 1)
+            | (((~t & -~t) - 1) >> (__builtin_ctz(pattern) + 1));
+#else
+          t = (pattern | (pattern - 1)) + 1;
+          pattern = t | ((((t & -t) / (pattern & -pattern)) >> 1) - 1);
+#endif
+        }
+      } while (pattern <= lastPattern);
+    }
+  free(factors);
+}
+#endif
+
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
diff --git a/libcdi/tests/ensure_array_size.c b/libcdi/tests/ensure_array_size.c
index 0b03f15..2eb1b5b 100644
--- a/libcdi/tests/ensure_array_size.c
+++ b/libcdi/tests/ensure_array_size.c
@@ -1,7 +1,7 @@
 #include <stdlib.h>
 
 #include "ensure_array_size.h"
-#include "pio_util.h"
+#include "error.h"
 
 void
 realloc_array(void **array, size_t elem_size, size_t *curr_array_size,
diff --git a/libcdi/tests/pio_cksum_asynch b/libcdi/tests/pio_cksum_asynch
deleted file mode 100755
index ff00756..0000000
--- a/libcdi/tests/pio_cksum_asynch
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/sh
-pio_write_args="-p PIO_ASYNCH -w 3"
-mpi_task_num=7
-LOG=pio_cksum_asynch.log
-if [ "" = yes ]; then
-  . ./pio_write_run
-else
-  exit 77
-fi
diff --git a/libcdi/tests/pio_cksum_cdf b/libcdi/tests/pio_cksum_cdf
deleted file mode 100755
index 1f28a45..0000000
--- a/libcdi/tests/pio_cksum_cdf
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /bin/sh
-pio_write_args="-f nc4 -w 3"
-mpi_task_num=7
-LOG=pio_cksum_cdf.log
-suffix=nc4
-if [ "" = yes -a "yes" = yes ]; then
-  . ./pio_write_run
-else
-  exit 77
-fi
diff --git a/libcdi/tests/pio_cksum_fpguard b/libcdi/tests/pio_cksum_fpguard
deleted file mode 100755
index cfac274..0000000
--- a/libcdi/tests/pio_cksum_fpguard
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/sh
-pio_write_args="-p PIO_FPGUARD -w 3"
-mpi_task_num=6
-LOG=pio_cksum_fpguard.log
-if [ "" = yes ]; then
-  . ./pio_write_run
-else
-  exit 77
-fi
diff --git a/libcdi/tests/pio_cksum_mpinonb b/libcdi/tests/pio_cksum_mpinonb
deleted file mode 100755
index 38dfeef..0000000
--- a/libcdi/tests/pio_cksum_mpinonb
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/sh
-pio_write_args="-p PIO_MPI -w 2"
-mpi_task_num=4
-LOG=pio_cksum_mpinonb.log
-if [ "" = yes ]; then
-  . ./pio_write_run
-else
-  exit 77
-fi
diff --git a/libcdi/tests/pio_cksum_writer b/libcdi/tests/pio_cksum_writer
deleted file mode 100755
index 0a3c44a..0000000
--- a/libcdi/tests/pio_cksum_writer
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/sh
-pio_write_args="-p PIO_WRITER -w 4"
-mpi_task_num=8
-LOG=pio_cksum_writer.log
-if [ "" = yes ]; then
-  . ./pio_write_run
-else
-  exit 77
-fi
diff --git a/libcdi/tests/pio_write.c b/libcdi/tests/pio_write.c
index 32ce947..74524a5 100644
--- a/libcdi/tests/pio_write.c
+++ b/libcdi/tests/pio_write.c
@@ -5,11 +5,10 @@
 #include <errno.h>
 #include <inttypes.h>
 #include <limits.h>
-#include <math.h>
 #include <stdbool.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <time.h>
 #include <unistd.h>
 
 #ifdef USE_MPI
@@ -20,312 +19,26 @@ typedef int MPI_Comm;
 #endif
 
 #include "cdi.h"
+#include "dmemory.h"
+#include "pio_write.h"
+#ifdef USE_MPI
+#include "cdipio.h"
 #include "pio_util.h"
-#include "cksum.h"
+#endif
 
-struct model_config
-{
-  int nlon, nlat, nts, max_nlev;
-  int filetype, datatype;
-  bool compute_checksum;
-  const char *suffix;
-};
+void
+modelRun(struct model_config setup, MPI_Comm comm);
 
-struct model_config default_setup
-  = { .nlon = 12, .nts = 3, .nlat = 6,
+static const struct model_config default_setup
+  = { .nlon = 12, .nts = 3, .nlat = 6, .nvars = 5,
       .filetype = FILETYPE_GRB, .datatype = DATATYPE_PACK24,
       .compute_checksum = 1,
       .suffix = "grb",
       .max_nlev = 5,
 };
 
-static void
-var_scale(int datatype, double *mscale, double *mrscale);
-
-static inline double
-sign_flat(double v)
-{
-  if (v == 0.0)
-    return 0.0;
-  return v;
-}
-
-enum {
-  ntfiles     = 2,
-  nVars       = 5,
-};
-
-static time_t
-cditime2time_t(int date, int timeofday);
-static void
-time_t2cditime(time_t t, int *date, int *timeofday);
-
-
-static void
-modelRegionCompute(double region[], size_t offset, size_t len,
-                   int nlev, int nlat, int nlon,
-                   int tsID, const double lons[], const double lats[],
-                   double mscale, double mrscale)
-{
-  size_t local_pos;
-  for (local_pos = 0; local_pos < len; ++local_pos)
-    {
-      size_t global_pos = offset + local_pos;
-      int k = global_pos / (nlon * nlat);
-      int j = (global_pos % (nlon * nlat))/ nlon;
-      int i = global_pos % nlon;
-      region[local_pos]
-        = sign_flat(round((cos(2.0 * M_PI * (lons[(i + tsID)%nlon] - lons[0])
-                               / (lons[nlon-1] - lons[0]))
-                           * sin(2.0 * M_PI * (lats[(j + k)%nlat] - lats[0])
-                                 / (lats[nlat-1] - lats[0]))
-                           ) * mscale)) * mrscale;
-    }
-}
-
 #ifdef USE_MPI
-static int
-uniform_partition_start(int set_interval[2], int nparts, int part_idx);
-#endif
-
-static void
-modelRun(struct model_config setup, MPI_Comm comm)
-{
-
-  static int nlev_scale[nVars]    = {0,0,1,1,1};
-  static int varCodes[nVars] = {129, 130, 131, 132, 133};
-  static char * name        = "example";
-
-  int gridID, zaxisID[nVars], taxisID;
-  int vlistID, varIDs[nVars], streamID, tsID, tfID = 0;
-  int i, nmiss = 0;
-  double *lons, *lats;
-  double *var = NULL, *varslice = NULL;
-  double mscale, mrscale;
-  time_t current_time;
-  int vdate = 19850101, vtime = 120000;
-  int rank = 0;
-  char filename[1024];
-  int nlon = setup.nlon, nlat = setup.nlat;
-  uint32_t checksum_state[nVars];
-  size_t varSize[nVars], varslice_size = 0;
-  int *nlev;
-  double *levs;
-#if USE_MPI
-  int *chunks = NULL, *displs = NULL, comm_size = 1;
-  struct var1DDeco {
-    int chunkSize, start;
-    Xt_idxlist partDesc;
-  } varDeco[nVars];
-#endif
-
-#if USE_MPI
-  xmpi ( MPI_Comm_rank ( comm, &rank ));
-  xmpi ( MPI_Comm_size ( comm, &comm_size ));
-  if (rank == 0 && setup.compute_checksum)
-    {
-      chunks = xmalloc(comm_size * sizeof (chunks[0]));
-      displs = xmalloc(comm_size * sizeof (displs[0]));
-      var = xmalloc((size_t)nlon * (size_t)nlat
-                    * (size_t)setup.max_nlev * sizeof(var[0]));
-    }
-#endif
-
-  var_scale(setup.datatype, &mscale, &mrscale);
-
-  gridID = gridCreate ( GRID_LONLAT, nlon*nlat );
-  gridDefXsize ( gridID, nlon );
-  gridDefYsize ( gridID, nlat );
-  lons = xmalloc(nlon * sizeof (lons[0]));
-  for (i = 0; i < nlon; ++i)
-    lons[i] = ((double)(i * 360))/nlon;
-  lats = xmalloc(nlat * sizeof (lats[0]));
-  for (i = 0; i < nlat; ++i)
-    lats[i] = ((double)(i * 180))/nlat - 90.0;
-  gridDefXvals ( gridID, lons );
-  gridDefYvals ( gridID, lats );
-
-  levs = xmalloc(setup.max_nlev * sizeof (levs[0]));
-  for (i = 0; i < setup.max_nlev; ++i)
-    levs[i] = 101300.0
-      - 3940.3 * (exp(1.3579 * (double)(i)/(setup.max_nlev - 1)) - 1.0);
-
-  nlev = xmalloc(nVars * sizeof (nlev[0]));
-  for ( i = 0; i < nVars; i++ )
-    {
-      nlev[i] = nlev_scale[i] * (setup.max_nlev - 1) + 1;
-      zaxisID[i] = zaxisCreate ( ZAXIS_PRESSURE, nlev[i] );
-      zaxisDefLevels ( zaxisID[i], levs );
-    }
-
-  vlistID = vlistCreate ();
-
-  for ( i = 0; i < nVars; i++ )
-    {
-      varIDs[i] = vlistDefVar ( vlistID, gridID, zaxisID[i], TIME_VARIABLE );
-      varSize[i] = nlon * nlat * nlev[i];
-#ifdef USE_MPI
-      {
-         int start = uniform_partition_start((int [2]){ 0, varSize[i] - 1 },
-                                             comm_size, rank),
-           chunkSize = uniform_partition_start((int [2]){ 0, varSize[i] - 1 },
-                                               comm_size, rank + 1) - start;
-         fprintf(stderr, "%d: start=%d, chunkSize = %d\n", rank,
-                 start, chunkSize);
-         Xt_idxlist idxlist
-           = xt_idxstripes_new(&(struct Xt_stripe){ .start = start,
-                   .nstrides = chunkSize, .stride = 1 }, 1);
-         varDeco[i] = (struct var1DDeco){
-           .start = start,
-           .chunkSize = chunkSize,
-           .partDesc = idxlist
-         };
-      }
-#endif
-      vlistDefVarCode(vlistID, varIDs[i], varCodes[i]);
-      vlistDefVarDatatype(vlistID, varIDs[i], setup.datatype);
-    }
-
-  taxisID = taxisCreate ( TAXIS_ABSOLUTE );
-  vlistDefTaxis ( vlistID, taxisID );
-
-  sprintf ( &filename[0], "%s_%d.%s", name, tfID, setup.suffix );
-  streamID = streamOpenWrite ( filename, setup.filetype );
-  xassert ( streamID >= 0 );
-  streamDefVlist ( streamID, vlistID);
-
-#ifdef USE_MPI
-  pioEndDef ();
-#endif
-
-  for ( tfID = 0; tfID < ntfiles; tfID++ )
-    {
-      memset(checksum_state, 0, sizeof(checksum_state));
-      if ( tfID > 0 )
-	{
-	  streamClose ( streamID );
-	  sprintf ( &filename[0], "%s_%d.%s", name, tfID, setup.suffix );
-	  streamID = streamOpenWrite ( filename, setup.filetype );
-	  xassert ( streamID >= 0 );
-	  streamDefVlist ( streamID, vlistID );
-	}
-      vdate = 19850101;
-      vtime = 120000;
-      current_time = cditime2time_t(vdate, vtime);
-      for ( tsID = 0; tsID < setup.nts; tsID++ )
-	{
-          time_t2cditime(current_time, &vdate, &vtime);
-	  taxisDefVdate ( taxisID, vdate );
-	  taxisDefVtime ( taxisID, vtime );
-	  streamDefTimestep ( streamID, tsID );
-	  for (int varID = 0; varID < nVars; ++varID)
-	    {
-#ifdef USE_MPI
-              int start = varDeco[varID].start;
-              int chunk = varDeco[varID].chunkSize;
-#else
-              int chunk = varSize[varID];
-              int start = 0;
-#endif
-              if (varslice_size < chunk)
-                {
-                  varslice = xrealloc(varslice, chunk * sizeof (var[0]));
-                  varslice_size = chunk;
-                }
-              modelRegionCompute(varslice, start, chunk,
-                                 nlev[varID], nlat, nlon,
-                                 tsID, lons, lats,
-                                 mscale, mrscale);
-              if (setup.compute_checksum)
-                {
-#if USE_MPI
-                  xmpi(MPI_Gather(&chunk, 1, MPI_INT,
-                                  chunks, 1, MPI_INT, 0, comm));
-                  if (rank == 0)
-                    {
-                      displs[0] = 0;
-                      for (i = 1; i < comm_size; ++i)
-                        displs[i] = displs[i - 1] + chunks[i - 1];
-                    }
-                  xmpi(MPI_Gatherv(varslice, chunk, MPI_DOUBLE,
-                                   var, chunks, displs, MPI_DOUBLE, 0, comm));
-#else
-                  var = varslice;
-#endif
-                }
-              if (rank == 0 && setup.compute_checksum)
-                {
-                  memcrc_r(&checksum_state[varID], (const unsigned char *)var,
-                           varSize[varID] * sizeof (var[0]));
-                }
-
-#ifdef USE_MPI
-	      streamWriteVarPart(streamID, varIDs[varID], varslice, nmiss,
-                                 varDeco[varID].partDesc);
-#else
-	      streamWriteVar(streamID, varIDs[varID], varslice, nmiss);
-#endif
-	      start = CDI_UNDEFID;
-	      chunk = CDI_UNDEFID;
-	    }
-          current_time += 86400;
-#ifdef USE_MPI
-	  pioWriteTimestep ( tsID, vdate, vtime );
-#endif
-	}
-      if (rank == 0 && setup.compute_checksum)
-        {
-          FILE *tablefp;
-          {
-            sprintf(filename, "%s_%d.cksum", name, tfID);
-            if (!(tablefp = fopen(filename, "w")))
-              {
-                perror("failed to open table file");
-                exit(EXIT_FAILURE);
-              }
-            for (i = 0; i < nVars; ++i)
-              {
-                uint32_t cksum;
-                int code;
-                cksum = memcrc_finish(&checksum_state[i],
-                                      (off_t)varSize[i]
-                                      * sizeof (var[0]) * setup.nts);
-                code = vlistInqVarCode(vlistID, varIDs[i]);
-                if (fprintf(tablefp, "%08lx %d\n", (unsigned long)cksum,
-                            code) < 0)
-                  {
-                    perror("failed to write table file");
-                    exit(EXIT_FAILURE);
-                  }
-              }
-            fclose(tablefp);
-          }
-        }
-    }
-  free(varslice);
-#ifdef USE_MPI
-  pioEndTimestepping ();
-#endif
-  streamClose ( streamID );
-  vlistDestroy ( vlistID );
-  taxisDestroy ( taxisID );
-  for ( i = 0; i < nVars; i++ )
-    zaxisDestroy ( zaxisID[i] );
-  gridDestroy ( gridID );
-#if USE_MPI
-  for (int varID = 0; varID < nVars; ++varID)
-    xt_idxlist_delete(varDeco[varID].partDesc);
-  free(displs);
-  free(chunks);
-  free(var);
-#endif
-  free(nlev);
-  free(levs);
-  free(lats);
-  free(lons);
-}
-
-struct {
+static const struct {
   char *text;
   int mode;
 } mode_map[] = {
@@ -334,6 +47,7 @@ struct {
   { "PIO_ASYNCH", PIO_ASYNCH },
   { "PIO_WRITER", PIO_WRITER }
 };
+#endif
 
 static const struct {
   char suffix[4];
@@ -366,39 +80,7 @@ parse_intarg(const char msg[])
   return (int)temp;
 }
 
-static void
-var_scale(int datatype, double *mscale, double *mrscale)
-{
-  int mant_bits;
-  switch (datatype)
-    {
-    case DATATYPE_PACK8:
-      mant_bits = 7;
-      break;
-    case DATATYPE_PACK16:
-      mant_bits = 15;
-      break;
-    case DATATYPE_PACK24:
-      mant_bits = 23;
-      break;
-    case DATATYPE_FLT32:
-      mant_bits = 24;
-      break;
-    case DATATYPE_FLT64:
-      mant_bits = 53;
-      break;
-    case DATATYPE_INT8:
-    case DATATYPE_INT16:
-    case DATATYPE_INT32:
-    default:
-      fprintf(stderr, "Unexpected or unusable content format: %d\n",
-              datatype);
-      exit(EXIT_FAILURE);
-    }
-  *mscale = INT64_C(1) << mant_bits;
-  *mrscale = 1.0 / *mscale;
-}
-
+#ifdef USE_MPI
 static inline int
 search_iomode_str(const char *modestr)
 {
@@ -413,6 +95,7 @@ search_iomode_str(const char *modestr)
       }
   return retval;
 }
+#endif
 
 int main (int argc, char *argv[])
 {
@@ -436,7 +119,7 @@ int main (int argc, char *argv[])
 
   {
     int opt;
-    while ((opt = getopt(argc, argv, "f:m:n:z:t:c"
+    while ((opt = getopt(argc, argv, "f:m:n:z:t:y:c"
 #ifdef USE_MPI
                          "p:w:"
 #endif
@@ -485,6 +168,21 @@ int main (int argc, char *argv[])
       case 'n':
         setup.nlat = parse_intarg("error parsing number of latitudes");
         break;
+      case 'y':
+        setup.nvars = parse_intarg("error parsing number of variables");
+        if (setup.nvars < 1)
+          {
+            fputs("number of levels must be greater than zero!\n",
+                  stderr);
+            exit(EXIT_FAILURE);
+          }
+        if (setup.nvars > 127)
+          {
+            fputs("number of variables must not exceed 127!\n",
+                  stderr);
+            exit(EXIT_FAILURE);
+          }
+        break;
       case 'z':
         setup.max_nlev = parse_intarg("error parsing number of levels");
         if (setup.max_nlev < 1)
@@ -502,7 +200,7 @@ int main (int argc, char *argv[])
         break;
       default: /* '?' */
         fprintf(stderr, "Usage: %s "
-                "[-m nlon] [-n nlat] [-z nlev] [-t nts]"
+                "[-m nlon] [-n nlat] [-z nlev] [-t nts] [-y num_vars]"
 #ifdef USE_MPI
                 " [-p PIO_MODE] [-w NIOSERVERS] [-c]"
 #endif
@@ -514,15 +212,19 @@ int main (int argc, char *argv[])
 
 #ifdef USE_MPI
   int pioNamespace;
-  commModel = pioInit(commGlob, nProcsIO, IOMode, &pioNamespace, 1.0);
-  pioNamespaceSetActive(pioNamespace);
+  commModel = pioInit(commGlob, nProcsIO, IOMode, &pioNamespace, 1.0,
+                      cdiPioNoPostCommSetup);
+  if (commModel != MPI_COMM_NULL)
+    {
+      namespaceSetActive(pioNamespace);
 #else
-  commModel = -1;
+      commModel = -1;
 #endif
 
-  modelRun (setup, commModel);
+      modelRun (setup, commModel);
 
 #ifdef USE_MPI
+    }
   pioFinalize ();
   xt_finalize();
   MPI_Finalize ();
@@ -530,48 +232,7 @@ int main (int argc, char *argv[])
   return 0;
 }
 
-static time_t
-cditime2time_t(int date, int timeofday)
-{
-  struct tm t_s;
-  time_t t;
-  t_s.tm_year = date / 10000;
-  t_s.tm_mon = (date - t_s.tm_year * 10000)/100;
-  t_s.tm_mday = date % 100;
-  t_s.tm_year -= 1900;
-  t_s.tm_hour = timeofday/10000;
-  t_s.tm_min = (timeofday%10000)/100;
-  t_s.tm_sec = timeofday%100;
-  t_s.tm_isdst = 0;
-  t = mktime(&t_s);
-  /* 
-   * fprintf(stderr, "converted %d,%d to %s to %lld.\n", date, timeofday,
-   *         asctime(&t_s), (long long)t);
-   */
-  return t;
-}
 
-static void
-time_t2cditime(time_t t, int *date, int *timeofday)
-{
-  struct tm *t_s;
-  t_s = localtime(&t);
-  /* fprintf(stderr, "converted %lld to %s.\n", (long long)t, asctime(t_s)); */
-  *date = (t_s->tm_year + 1900) * 10000 + t_s->tm_mon * 100 + t_s->tm_mday;
-  *timeofday = t_s->tm_hour * 10000 + t_s->tm_min * 100 + t_s->tm_sec;
-}
-
-#ifdef USE_MPI
-static int
-uniform_partition_start(int set_interval[2], int nparts, int part_idx)
-{
-  int part_offset
-    = (((long long)set_interval[1] - (long long)set_interval[0] + 1LL)
-       * (long long)part_idx) / (long long)nparts;
-  int start = set_interval[0] + part_offset;
-  return start;
-}
-#endif
 /*
  * Local Variables:
  * c-file-style: "Java"
diff --git a/libcdi/tests/pio_write.h b/libcdi/tests/pio_write.h
new file mode 100644
index 0000000..66b3762
--- /dev/null
+++ b/libcdi/tests/pio_write.h
@@ -0,0 +1,18 @@
+#ifndef PIO_WRITE_H
+#define PIO_WRITE_H
+
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#include <stdbool.h>
+
+struct model_config
+{
+  int nlon, nlat, nts, max_nlev, nvars;
+  int filetype, datatype;
+  bool compute_checksum;
+  const char *suffix;
+};
+
+#endif
diff --git a/libcdi/tests/pio_write_run b/libcdi/tests/pio_write_deco2d_run.in
old mode 100755
new mode 100644
similarity index 55%
rename from libcdi/tests/pio_write_run
rename to libcdi/tests/pio_write_deco2d_run.in
index 11ba2d2..d0d9162
--- a/libcdi/tests/pio_write_run
+++ b/libcdi/tests/pio_write_deco2d_run.in
@@ -1,11 +1,11 @@
-#! /bin/sh
+#! @SHELL@
 set -e
-LOG="${LOG-pio_write.log}"
-mpi_task_num="${mpi_task_num-4}"
+LOG="${LOG-pio_write_deco2d.log}"
+mpi_task_num="${mpi_task_num-6}"
 suffix="${suffix-grb}"
 exec 5>&1 6>&2 >"$LOG" 2>&1
-../libtool --mode=execute /Users/m214003/cdt/work/cdo/build/gcc/libcdi/util/serialrun -n ${mpi_task_num} \
-  ${tool_wrap} ./pio_write ${pio_write_args}
+../libtool --mode=execute @MPI_LAUNCH@ -n ${mpi_task_num} \
+  ${tool_wrap} ./pio_write_deco2d ${pio_write_args}
 exec 2>&6 1>&5 5>&- 6>&-
 ../libtool --mode=execute \
   ${tool_wrap} ./cksum_read example_0.${suffix} example_0.cksum
diff --git a/libcdi/tests/simple_model.c b/libcdi/tests/simple_model.c
new file mode 100644
index 0000000..ccaed23
--- /dev/null
+++ b/libcdi/tests/simple_model.c
@@ -0,0 +1,333 @@
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#ifdef USE_MPI
+#include <mpi.h>
+#include <yaxt.h>
+#else
+typedef int MPI_Comm;
+#endif
+
+#include "cdi.h"
+#ifdef USE_MPI
+#include "cdipio.h"
+#include "pio_util.h"
+#ifdef HAVE_PPM_CORE
+#include <ppm/ppm_uniform_partition.h>
+#endif
+#endif
+
+#include "cksum.h"
+#include "dmemory.h"
+#include "error.h"
+#include "pio_write.h"
+
+#include "simple_model_helper.h"
+
+enum {
+  ntfiles     = 2,
+};
+
+
+static void
+modelRegionCompute(double region[], size_t offset, size_t len,
+                   int nlev, int nlat, int nlon,
+                   int tsID, const double lons[], const double lats[],
+                   double mscale, double mrscale)
+{
+  size_t local_pos;
+  for (local_pos = 0; local_pos < len; ++local_pos)
+    {
+      size_t global_pos = offset + local_pos;
+      int k = global_pos / (nlon * nlat);
+      int j = (global_pos % (nlon * nlat))/ nlon;
+      int i = global_pos % nlon;
+      region[local_pos]
+        = sign_flat(round((cos(2.0 * M_PI * (lons[(i + tsID)%nlon] - lons[0])
+                               / (lons[nlon-1] - lons[0]))
+                           * sin(2.0 * M_PI * (lats[(j + k)%nlat] - lats[0])
+                                 / (lats[nlat-1] - lats[0]))
+                           ) * mscale)) * mrscale;
+    }
+}
+
+void
+modelRun(struct model_config setup, MPI_Comm comm)
+{
+  static const char * const fname_prefix        = "example";
+
+  struct
+  {
+    size_t size;
+    int nlev, zaxisID, id, code;
+    uint32_t checksum_state;
+#if USE_MPI
+    int chunkSize, start;
+    Xt_idxlist partDesc;
+#endif
+  } *varDesc;
+  int gridID, taxisID, vlistID, streamID, tsID, tfID = 0;
+  int i, nmiss = 0;
+  double *lons, *lats, *levs;
+  double *var = NULL, *varslice = NULL;
+  double mscale, mrscale;
+  time_t current_time;
+  int vdate = 19850101, vtime = 120000;
+  int rank = 0;
+  char filename[1024];
+  int nlon = setup.nlon, nlat = setup.nlat;
+  int nVars = setup.nvars;
+  size_t varslice_size = 0;
+#if USE_MPI
+  int *chunks = NULL, *displs = NULL, comm_size = 1;
+#endif
+
+#if USE_MPI
+  xmpi ( MPI_Comm_rank ( comm, &rank ));
+  xmpi ( MPI_Comm_size ( comm, &comm_size ));
+  if (rank == 0 && setup.compute_checksum)
+    {
+      chunks = xmalloc(comm_size * sizeof (chunks[0]));
+      displs = xmalloc(comm_size * sizeof (displs[0]));
+      var = xmalloc((size_t)nlon * (size_t)nlat
+                    * (size_t)setup.max_nlev * sizeof(var[0]));
+    }
+#endif
+
+  var_scale(setup.datatype, &mscale, &mrscale);
+
+  gridID = gridCreate ( GRID_LONLAT, nlon*nlat );
+  gridDefXsize ( gridID, nlon );
+  gridDefYsize ( gridID, nlat );
+  lons = xmalloc(nlon * sizeof (lons[0]));
+  for (i = 0; i < nlon; ++i)
+    lons[i] = ((double)(i * 360))/nlon;
+  lats = xmalloc(nlat * sizeof (lats[0]));
+  for (i = 0; i < nlat; ++i)
+    lats[i] = ((double)(i * 180))/nlat - 90.0;
+  gridDefXvals ( gridID, lons );
+  gridDefYvals ( gridID, lats );
+
+  levs = xmalloc(setup.max_nlev * sizeof (levs[0]));
+  for (i = 0; i < setup.max_nlev; ++i)
+    levs[i] = 101300.0
+      - 3940.3 * (exp(1.3579 * (double)(i)/(setup.max_nlev - 1)) - 1.0);
+
+  vlistID = vlistCreate ();
+
+  varDesc = xmalloc(nVars * sizeof (varDesc[0]));
+  for (int varIdx = 0; varIdx < nVars; varIdx++ )
+    {
+      int varLevs = random()%4;
+      switch (varLevs)
+        {
+        case 1:
+          varLevs = setup.max_nlev / 3;
+          break;
+        case 2:
+          varLevs = setup.max_nlev >= 11 ? 11 : setup.max_nlev / 2;
+          break;
+        case 3:
+          varLevs = setup.max_nlev - 1;
+          break;
+        }
+      ++varLevs;
+      varDesc[varIdx].nlev = varLevs;
+      for (i = 0; i < varIdx; ++i)
+        if (varDesc[i].nlev == varLevs)
+          {
+            varDesc[varIdx].zaxisID = varDesc[i].zaxisID;
+            goto zaxisIDset;
+          }
+      varDesc[varIdx].zaxisID
+        = zaxisCreate(ZAXIS_PRESSURE, varDesc[varIdx].nlev);
+      zaxisDefLevels(varDesc[varIdx].zaxisID, levs);
+      zaxisIDset:
+      varDesc[varIdx].id = vlistDefVar(vlistID, gridID, varDesc[varIdx].zaxisID,
+                                       TIME_VARIABLE);
+      varDesc[varIdx].size = nlon * nlat * varDesc[varIdx].nlev;
+#ifdef USE_MPI
+      {
+        struct PPM_extent range
+          = PPM_uniform_partition((struct PPM_extent){ 0,
+                (int32_t)varDesc[varIdx].size }, comm_size, rank);
+        int start = range.first;
+        int chunkSize = range.size;
+         fprintf(stderr, "%d: start=%d, chunkSize = %d\n", rank,
+                 start, chunkSize);
+         Xt_idxlist idxlist
+           = xt_idxstripes_new(&(struct Xt_stripe){ .start = start,
+                 .nstrides = chunkSize, .stride = 1 }, 1);
+         varDesc[varIdx].start = start;
+         varDesc[varIdx].chunkSize = chunkSize;
+         varDesc[varIdx].partDesc = idxlist;
+      }
+#endif
+      varDesc[varIdx].code = 129 + varIdx;
+      vlistDefVarCode(vlistID, varDesc[varIdx].id, varDesc[varIdx].code);
+      vlistDefVarDatatype(vlistID, varDesc[varIdx].id, setup.datatype);
+    }
+
+  taxisID = taxisCreate ( TAXIS_ABSOLUTE );
+  vlistDefTaxis ( vlistID, taxisID );
+
+  sprintf ( &filename[0], "%s_%d.%s", fname_prefix, tfID, setup.suffix );
+  streamID = streamOpenWrite ( filename, setup.filetype );
+  xassert ( streamID >= 0 );
+  streamDefVlist ( streamID, vlistID);
+
+#ifdef USE_MPI
+  pioEndDef ();
+#endif
+
+  for ( tfID = 0; tfID < ntfiles; tfID++ )
+    {
+      for (int varIdx = 0; varIdx < nVars; ++varIdx)
+        varDesc[varIdx].checksum_state = 0;
+      if ( tfID > 0 )
+	{
+	  streamClose ( streamID );
+	  sprintf ( &filename[0], "%s_%d.%s", fname_prefix, tfID, setup.suffix );
+	  streamID = streamOpenWrite ( filename, setup.filetype );
+	  xassert ( streamID >= 0 );
+	  streamDefVlist ( streamID, vlistID );
+	}
+      vdate = 19850101;
+      vtime = 120000;
+      current_time = cditime2time_t(vdate, vtime);
+      for ( tsID = 0; tsID < setup.nts; tsID++ )
+	{
+          time_t2cditime(current_time, &vdate, &vtime);
+	  taxisDefVdate ( taxisID, vdate );
+	  taxisDefVtime ( taxisID, vtime );
+	  streamDefTimestep ( streamID, tsID );
+	  for (int varID = 0; varID < nVars; ++varID)
+	    {
+#ifdef USE_MPI
+              int start = varDesc[varID].start;
+              int chunk = varDesc[varID].chunkSize;
+#else
+              int chunk = varDesc[varID].size;
+              int start = 0;
+#endif
+              if (varslice_size < chunk)
+                {
+                  varslice = xrealloc(varslice, chunk * sizeof (var[0]));
+                  varslice_size = chunk;
+                }
+              modelRegionCompute(varslice, start, chunk,
+                                 varDesc[varID].nlev, nlat, nlon,
+                                 tsID, lons, lats,
+                                 mscale, mrscale);
+              if (setup.compute_checksum)
+                {
+#if USE_MPI
+                  xmpi(MPI_Gather(&chunk, 1, MPI_INT,
+                                  chunks, 1, MPI_INT, 0, comm));
+                  if (rank == 0)
+                    {
+                      displs[0] = 0;
+                      for (i = 1; i < comm_size; ++i)
+                        displs[i] = displs[i - 1] + chunks[i - 1];
+                    }
+                  xmpi(MPI_Gatherv(varslice, chunk, MPI_DOUBLE,
+                                   var, chunks, displs, MPI_DOUBLE, 0, comm));
+#else
+                  var = varslice;
+#endif
+                }
+              if (rank == 0 && setup.compute_checksum)
+                {
+                  memcrc_r(&varDesc[varID].checksum_state,
+                           (const unsigned char *)var,
+                           varDesc[varID].size * sizeof (var[0]));
+                }
+
+#ifdef USE_MPI
+	      streamWriteVarPart(streamID, varDesc[varID].id, varslice, nmiss,
+                                 varDesc[varID].partDesc);
+#else
+	      streamWriteVar(streamID, varDesc[varID].id, varslice, nmiss);
+#endif
+	    }
+          current_time += 86400;
+#ifdef USE_MPI
+	  pioWriteTimestep ( tsID, vdate, vtime );
+#endif
+	}
+      if (rank == 0 && setup.compute_checksum)
+        {
+          FILE *tablefp;
+          {
+            sprintf(filename, "%s_%d.cksum", fname_prefix, tfID);
+            if (!(tablefp = fopen(filename, "w")))
+              {
+                perror("failed to open table file");
+                exit(EXIT_FAILURE);
+              }
+            for (i = 0; i < nVars; ++i)
+              {
+                uint32_t cksum;
+                int code;
+                cksum = memcrc_finish(&varDesc[i].checksum_state,
+                                      (off_t)varDesc[i].size
+                                      * sizeof (var[0]) * setup.nts);
+                code = vlistInqVarCode(vlistID, varDesc[i].id);
+                if (fprintf(tablefp, "%08lx %d\n", (unsigned long)cksum,
+                            code) < 0)
+                  {
+                    perror("failed to write table file");
+                    exit(EXIT_FAILURE);
+                  }
+              }
+            fclose(tablefp);
+          }
+        }
+    }
+  free(varslice);
+#ifdef USE_MPI
+  pioEndTimestepping ();
+#endif
+  streamClose ( streamID );
+  vlistDestroy ( vlistID );
+  taxisDestroy ( taxisID );
+  for ( i = 0; i < nVars; i++ )
+    {
+      int zID = varDesc[i].zaxisID;
+      if (zID != CDI_UNDEFID)
+        {
+          zaxisDestroy(zID);
+          for (int j = i + 1; j < nVars; ++j)
+            if (zID == varDesc[j].zaxisID)
+              varDesc[j].zaxisID = CDI_UNDEFID;
+        }
+    }
+  gridDestroy ( gridID );
+#if USE_MPI
+  for (int varID = 0; varID < nVars; ++varID)
+    xt_idxlist_delete(varDesc[varID].partDesc);
+  free(displs);
+  free(chunks);
+  free(var);
+#endif
+  free(varDesc);
+  free(levs);
+  free(lats);
+  free(lons);
+}
+
+/*
+ * Local Variables:
+ * c-file-style: "Java"
+ * c-basic-offset: 2
+ * indent-tabs-mode: nil
+ * show-trailing-whitespace: t
+ * require-trailing-newline: t
+ * End:
+ */
diff --git a/libcdi/tests/simple_model_helper.c b/libcdi/tests/simple_model_helper.c
new file mode 100644
index 0000000..9e92d1b
--- /dev/null
+++ b/libcdi/tests/simple_model_helper.c
@@ -0,0 +1,135 @@
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "cdi.h"
+#include "dmemory.h"
+
+#include "simple_model_helper.h"
+
+void
+var_scale(int datatype, double *mscale, double *mrscale)
+{
+  int mant_bits;
+  switch (datatype)
+    {
+    case DATATYPE_PACK8:
+      mant_bits = 7;
+      break;
+    case DATATYPE_PACK16:
+      mant_bits = 15;
+      break;
+    case DATATYPE_PACK24:
+      mant_bits = 23;
+      break;
+    case DATATYPE_FLT32:
+      mant_bits = 24;
+      break;
+    case DATATYPE_FLT64:
+      mant_bits = 53;
+      break;
+    case DATATYPE_INT8:
+    case DATATYPE_INT16:
+    case DATATYPE_INT32:
+    default:
+      fprintf(stderr, "Unexpected or unusable content format: %d\n",
+              datatype);
+      exit(EXIT_FAILURE);
+    }
+  *mscale = INT64_C(1) << mant_bits;
+  *mrscale = 1.0 / *mscale;
+}
+
+/**
+ * Compute UNIX epoch-based time_t from CDI's decimal encoding of date.
+ */
+time_t
+cditime2time_t(int date, int timeofday)
+{
+  struct tm t_s;
+  time_t t;
+  t_s.tm_year = date / 10000;
+  t_s.tm_mon = (date - t_s.tm_year * 10000)/100;
+  t_s.tm_mday = date % 100;
+  t_s.tm_year -= 1900;
+  t_s.tm_hour = timeofday/10000;
+  t_s.tm_min = (timeofday%10000)/100;
+  t_s.tm_sec = timeofday%100;
+  t_s.tm_isdst = 0;
+  t = mktime(&t_s);
+  return t;
+}
+
+/**
+ * Build decimal encoding of date from UNIX epoch-based time_t.
+ */
+void
+time_t2cditime(time_t t, int *date, int *timeofday)
+{
+  struct tm *t_s;
+  t_s = localtime(&t);
+  *date = (t_s->tm_year + 1900) * 10000 + t_s->tm_mon * 100 + t_s->tm_mday;
+  *timeofday = t_s->tm_hour * 10000 + t_s->tm_min * 100 + t_s->tm_sec;
+}
+
+#if defined USE_MPI && ! defined HAVE_PPM_CORE
+
+static int32_t
+uniform_partition_start(struct PPM_extent set_interval, int nparts,
+                        int part_idx);
+
+struct PPM_extent
+PPM_uniform_partition(struct PPM_extent set_interval, int nparts,
+                      int part_idx)
+{
+  struct PPM_extent range;
+  range.first = uniform_partition_start(set_interval, nparts, part_idx);
+  range.size = uniform_partition_start(set_interval, nparts, part_idx + 1)
+    - range.first;
+  return range;
+}
+
+static int32_t
+uniform_partition_start(struct PPM_extent set_interval, int nparts,
+                        int part_idx)
+{
+  int32_t part_offset
+    = ((int64_t)set_interval.size * (int64_t)part_idx) / (int64_t)nparts;
+  int32_t start = set_interval.first + part_offset;
+  return start;
+}
+
+int
+PPM_prime_factorization_32(uint32_t n, uint32_t **factors)
+{
+  if (n <= 1) return 0;
+  uint32_t * restrict pfactors = xrealloc(*factors, 32 * sizeof (pfactors[0]));
+  size_t numFactors = 0;
+  uint32_t unfactored = n;
+  while (!(unfactored & 1))
+  {
+    pfactors[numFactors] = 2;
+    ++numFactors;
+    unfactored >>= 1;
+  }
+  uint32_t divisor = 3;
+  while (unfactored > 1)
+  {
+    while (unfactored % divisor == 0)
+    {
+      unfactored /= divisor;
+      pfactors[numFactors] = divisor;
+      ++numFactors;
+    }
+    divisor += 1;
+  }
+  *factors = pfactors;
+  return numFactors;
+}
+
+#endif
+
diff --git a/libcdi/tests/simple_model_helper.h b/libcdi/tests/simple_model_helper.h
new file mode 100644
index 0000000..d74c215
--- /dev/null
+++ b/libcdi/tests/simple_model_helper.h
@@ -0,0 +1,42 @@
+#ifndef SIMPLE_MODEL_HELPER_H
+#define SIMPLE_MODEL_HELPER_H
+
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <time.h>
+
+void
+var_scale(int datatype, double *mscale, double *mrscale);
+
+static inline double
+sign_flat(double v)
+{
+  if (v == 0.0)
+    return 0.0;
+  return v;
+}
+
+time_t
+cditime2time_t(int date, int timeofday);
+void
+time_t2cditime(time_t t, int *date, int *timeofday);
+
+#if defined (USE_MPI) && ! defined(HAVE_PPM_CORE)
+struct PPM_extent
+{
+  int32_t first, size;
+};
+
+struct PPM_extent
+PPM_uniform_partition(struct PPM_extent set_interval, int nparts,
+                      int part_idx);
+
+int
+PPM_prime_factorization_32(uint32_t n, uint32_t **factors);
+
+#endif
+
+#endif
diff --git a/libcdi/tests/stream_cksum.c b/libcdi/tests/stream_cksum.c
index 6b970c5..0ee33d5 100644
--- a/libcdi/tests/stream_cksum.c
+++ b/libcdi/tests/stream_cksum.c
@@ -1,8 +1,9 @@
+#include <stdio.h>
+
 #include "cdi.h"
 #include "cksum.h"
 #include "stream_cksum.h"
-#include "pio_util.h"
-
+#include "dmemory.h"
 
 struct cksum_table *
 cksum_stream(const char *fname, size_t *table_len)
diff --git a/libcdi/tests/test_chunk_cksum b/libcdi/tests/test_chunk_cksum
deleted file mode 100755
index 7265822..0000000
--- a/libcdi/tests/test_chunk_cksum
+++ /dev/null
@@ -1,14 +0,0 @@
-#! /bin/sh
-
-set -e
-format=nc
-if [ yes = yes ]; then
-  exec >test_chunk_cksum_$format.log 2>&1
-  ./cksum_write_chunk -m 17
-  ./cksum_read example.$format
-  \rm example.cksum example.$format
-  \rm test_chunk_cksum_$format.log
-else
-  # skip tests for unsupported formats
-  exit 77
-fi
diff --git a/libcdi/tests/test_cksum_extra b/libcdi/tests/test_cksum_extra
deleted file mode 100755
index 01e827c..0000000
--- a/libcdi/tests/test_cksum_extra
+++ /dev/null
@@ -1,14 +0,0 @@
-#! /bin/sh
-
-set -e
-format=ext
-if [ yes = yes ]; then
-  exec >test_cksum_$format.log 2>&1
-  ./cksum_write -f $format
-  ./cksum_read example.$format
-  \rm example.cksum example.$format
-  \rm test_cksum_$format.log
-else
-  # skip tests for unsupported formats
-  exit 77
-fi
diff --git a/libcdi/tests/test_cksum_grib b/libcdi/tests/test_cksum_grib
deleted file mode 100755
index 2374062..0000000
--- a/libcdi/tests/test_cksum_grib
+++ /dev/null
@@ -1,14 +0,0 @@
-#! /bin/sh
-
-set -e
-format=grb
-if [ yes = yes ]; then
-  exec >test_cksum_$format.log 2>&1
-  ./cksum_write -f $format
-  ./cksum_read example.$format
-  \rm example.cksum example.$format
-  \rm test_cksum_$format.log
-else
-  # skip tests for unsupported formats
-  exit 77
-fi
diff --git a/libcdi/tests/test_cksum_ieg b/libcdi/tests/test_cksum_ieg
deleted file mode 100755
index 766b082..0000000
--- a/libcdi/tests/test_cksum_ieg
+++ /dev/null
@@ -1,14 +0,0 @@
-#! /bin/sh
-
-set -e
-format=ieg
-if [ yes = yes ]; then
-  exec >test_cksum_$format.log 2>&1
-  ./cksum_write -f $format
-  ./cksum_read example.$format
-  \rm example.cksum example.$format
-  \rm test_cksum_$format.log
-else
-  # skip tests for unsupported formats
-  exit 77
-fi
diff --git a/libcdi/tests/test_cksum_nc b/libcdi/tests/test_cksum_nc
deleted file mode 100755
index e9849a2..0000000
--- a/libcdi/tests/test_cksum_nc
+++ /dev/null
@@ -1,14 +0,0 @@
-#! /bin/sh
-
-set -e
-format=nc
-if [ yes = yes ]; then
-  exec >test_cksum_$format.log 2>&1
-  ./cksum_write -f $format
-  ./cksum_read example.$format
-  \rm example.cksum example.$format
-  \rm test_cksum_$format.log
-else
-  # skip tests for unsupported formats
-  exit 77
-fi
diff --git a/libcdi/tests/test_cksum_nc2 b/libcdi/tests/test_cksum_nc2
deleted file mode 100755
index e7d07e2..0000000
--- a/libcdi/tests/test_cksum_nc2
+++ /dev/null
@@ -1,14 +0,0 @@
-#! /bin/sh
-
-set -e
-format=nc2
-if [ yes = yes ]; then
-  exec >test_cksum_$format.log 2>&1
-  ./cksum_write -f $format
-  ./cksum_read example.$format
-  \rm example.cksum example.$format
-  \rm test_cksum_$format.log
-else
-  # skip tests for unsupported formats
-  exit 77
-fi
diff --git a/libcdi/tests/test_cksum_nc4 b/libcdi/tests/test_cksum_nc4
deleted file mode 100755
index 75bb567..0000000
--- a/libcdi/tests/test_cksum_nc4
+++ /dev/null
@@ -1,14 +0,0 @@
-#! /bin/sh
-
-set -e
-format=nc4
-if [ yes = yes ]; then
-  exec >test_cksum_$format.log 2>&1
-  ./cksum_write -f $format
-  ./cksum_read example.$format
-  \rm example.cksum example.$format
-  \rm test_cksum_$format.log
-else
-  # skip tests for unsupported formats
-  exit 77
-fi
diff --git a/libcdi/tests/test_cksum_service b/libcdi/tests/test_cksum_service
deleted file mode 100755
index 2c05b55..0000000
--- a/libcdi/tests/test_cksum_service
+++ /dev/null
@@ -1,14 +0,0 @@
-#! /bin/sh
-
-set -e
-format=svc
-if [ yes = yes ]; then
-  exec >test_cksum_$format.log 2>&1
-  ./cksum_write -f $format
-  ./cksum_read example.$format
-  \rm example.cksum example.$format
-  \rm test_cksum_$format.log
-else
-  # skip tests for unsupported formats
-  exit 77
-fi
diff --git a/libcdi/tests/test_grib.sh b/libcdi/tests/test_grib.sh
deleted file mode 100755
index c66111b..0000000
--- a/libcdi/tests/test_grib.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /bin/sh
-
-TEST=test_grib
-
-./${TEST}
-
-result=$?
-
-exit $result
diff --git a/libcdi/tests/test_resource_copy b/libcdi/tests/test_resource_copy
deleted file mode 100755
index 7a4e255..0000000
Binary files a/libcdi/tests/test_resource_copy and /dev/null differ
diff --git a/libcdi/tests/test_resource_copy.c b/libcdi/tests/test_resource_copy.c
index 6bd227a..03f972c 100644
--- a/libcdi/tests/test_resource_copy.c
+++ b/libcdi/tests/test_resource_copy.c
@@ -3,21 +3,26 @@
 #endif
 
 #include <stdio.h>
+#include <string.h>
 
-#ifdef USE_MPI
-#include <mpi.h>
 #include "cdi.h"
-#include "pio_util.h"
+#include "dmemory.h"
+#include "error.h"
 #include "resource_handle.h"
 #include "resource_unpack.h"
+
+#ifdef MPI_MARSHALLING
+#include <mpi.h>
+#include "cdipio.h"
 #include "pio_serialize.h"
+#include "pio_util.h"
+#else
+typedef int MPI_Comm;
+#endif
 
 extern void   arrayDestroy          ( void );
 
 enum {
-  IOMode           = PIO_NONE,
-  nProcsIO         = 1,
-  nNamespaces      = 2,
   DOUBLE_PRECISION = 8,
   nlon             = 12,
   nlat             = 6,
@@ -173,16 +178,18 @@ int defineModel ( int instID )
   return modelID;
 }
 
-int modelRun ( MPI_Comm comm )
+static int destNamespace;
+
+int modelRun(MPI_Comm comm)
 {
   int gridID, zaxisID, taxisID, instID, modelID, vlistID, streamID;
 
   char * recvBuffer, * sendBuffer;
   int bufferSize, differ;
 
-  pioNamespaceSetActive ( 0 );
-  if (IOMode != PIO_NONE)
-    serializeSetMPI();
+#ifdef MPI_MARSHALLING
+  serializeSetMPI();
+#endif
 
   gridID  = defineGrid      ();
   zaxisID = defineZaxis     ();
@@ -196,49 +203,41 @@ int modelRun ( MPI_Comm comm )
 
   reshPackBufferCreate ( &sendBuffer, &bufferSize, &comm );
   recvBuffer = xmalloc(bufferSize);
+#ifdef MPI_MARSHALLING
   xmpi(MPI_Sendrecv(sendBuffer, bufferSize, MPI_PACKED, 0, 0,
                     recvBuffer, bufferSize, MPI_PACKED, 0, 0,
                     MPI_COMM_SELF, MPI_STATUS_IGNORE));
-  pioNamespaceSetActive ( 1 );
+#else
+  memcpy(recvBuffer, sendBuffer, bufferSize);
+#endif
+  namespaceSetActive(destNamespace);
   reshUnpackResources(recvBuffer, bufferSize, &comm);
-  free ( recvBuffer );
-  reshPackBufferDestroy ( &sendBuffer );
+  free(recvBuffer);
+  reshPackBufferDestroy(&sendBuffer);
 
   differ = reshListCompare ( 0, 1 );
 
-  pioNamespaceSetActive ( 0 );
+  namespaceSetActive(0);
   streamClose(streamID);
   return differ;
 }
 
-#endif
-
 int main (int argc, char *argv[])
 {
   int exitCode = 77;
-#ifdef USE_MPI
-  int sizeGlob, pioNamespace;
-  MPI_Comm commGlob, commModel;
-
+  MPI_Comm commModel;
+#ifdef MPI_MARSHALLING
   MPI_Init(&argc, &argv);
-  xmpi ( MPI_Comm_dup ( MPI_COMM_WORLD, &commGlob ));
-  xmpi ( MPI_Comm_set_errhandler ( commGlob, MPI_ERRORS_RETURN ));
-  xmpi ( MPI_Comm_size ( commGlob, &sizeGlob ));
-
-  if ( sizeGlob != 1 )
-      xabort ( "test transition of resource array only with 1 PE." );
-
-  if ( nProcsIO != 1 )
-    xabort ( "bad distribution of tasks on PEs" );
-
-  commModel = pioInit(commGlob, nProcsIO, IOMode, &pioNamespace, 1.0f);
-  pioNamespaceSetActive(pioNamespace);
+  commModel = MPI_COMM_WORLD;
+#else
+  commModel = 0;
+#endif
+  destNamespace = namespaceNew();
 
   exitCode = modelRun(commModel);
 
+#ifdef MPI_MARSHALLING
   xmpi(MPI_Finalize());
-#else
-  printf ( "Use MPI for this testprogram.\n" );
 #endif
 
   return exitCode;
diff --git a/libcdi/tests/test_resource_copy_mpi_run.in b/libcdi/tests/test_resource_copy_mpi_run.in
new file mode 100644
index 0000000..e9f1602
--- /dev/null
+++ b/libcdi/tests/test_resource_copy_mpi_run.in
@@ -0,0 +1,5 @@
+#! @SHELL@
+set -e
+mpi_task_num="${mpi_task_num-1}"
+../libtool --mode=execute @MPI_LAUNCH@ -n ${mpi_task_num} \
+  ./test_resource_copy_mpi
diff --git a/libcdi/util/xlfpreproc-wrapper b/libcdi/util/xlfpreproc-wrapper
index fe0ad8b..33a132b 100755
--- a/libcdi/util/xlfpreproc-wrapper
+++ b/libcdi/util/xlfpreproc-wrapper
@@ -11,19 +11,32 @@
 # Maintainer: Thomas Jahns <jahns at dkrz.de>
 # URL: http://
 #
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+# Redistribution and use in source and binary forms, with or without
+# modification, are  permitted provided that the following conditions are
+# met:
+#
+# Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 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.
+#
+# Neither the name of the DKRZ GmbH 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
+# 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.
 #
 # Commentary:
 #
diff --git a/src/Adisit.c b/src/Adisit.c
index 64b071d..dfcbdb6 100644
--- a/src/Adisit.c
+++ b/src/Adisit.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -256,7 +256,7 @@ void *Adisit(void *argument)
   if ( nlevel1 != nlevel2 ) cdoAbort("temperature and salinity have different number of levels!");
   nlevel = nlevel1;
 
-  pressure = (double *) malloc(nlevel*sizeof(double));
+  pressure = malloc(nlevel*sizeof(double));
   zaxisInqLevels(zaxisID, pressure);
 
   if ( pin >= 0 ) 
@@ -274,9 +274,9 @@ void *Adisit(void *argument)
   field_init(&tho);
   field_init(&sao);
   field_init(&tis);
-  tho.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
-  sao.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
-  tis.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
+  tho.ptr = malloc(gridsize*nlevel*sizeof(double));
+  sao.ptr = malloc(gridsize*nlevel*sizeof(double));
+  tis.ptr = malloc(gridsize*nlevel*sizeof(double));
 
   tho.nmiss = 0;
   sao.nmiss = 0;
diff --git a/src/Arith.c b/src/Arith.c
index 05903a6..15d1588 100644
--- a/src/Arith.c
+++ b/src/Arith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -150,12 +150,12 @@ void *Arith(void *argument)
 
   field_init(&field1);
   field_init(&field2);
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field2.ptr = malloc(gridsize*sizeof(double));
   if ( filltype == FILL_VAR || filltype == FILL_VARTS )
     {
-      vardata2 = (double *) malloc(gridsize*nlevels2*sizeof(double));
-      varnmiss2 = (int *) malloc(nlevels2*sizeof(int));
+      vardata2 = malloc(gridsize*nlevels2*sizeof(double));
+      varnmiss2 = malloc(nlevels2*sizeof(int));
     }
 
   if ( cdoVerbose ) cdoPrint("Number of timesteps: file1 %d, file2 %d", ntsteps1, ntsteps2);
@@ -183,14 +183,14 @@ void *Arith(void *argument)
       if ( filltype == FILL_TS )
 	{
 	  nvars  = vlistNvars(vlistIDx2);
-	  vardata  = (double **) malloc(nvars*sizeof(double *));
-	  varnmiss = (int **) malloc(nvars*sizeof(int *));
+	  vardata  = malloc(nvars*sizeof(double *));
+	  varnmiss = malloc(nvars*sizeof(int *));
 	  for ( varID = 0; varID < nvars; varID++ )
 	    {
 	      gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID));
 	      nlev     = zaxisInqSize(vlistInqVarZaxis(vlistIDx2, varID));
-	      vardata[varID]  = (double *) malloc(nlev*gridsize*sizeof(double));
-	      varnmiss[varID] = (int *) malloc(nlev*sizeof(int));
+	      vardata[varID]  = malloc(nlev*gridsize*sizeof(double));
+	      varnmiss[varID] = malloc(nlev*sizeof(int));
 	    }
 	}
     }
diff --git a/src/Arithc.c b/src/Arithc.c
index 0371156..14abb29 100644
--- a/src/Arithc.c
+++ b/src/Arithc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -36,7 +36,7 @@ int *fill_vars(int vlistID)
 {
   int varID;
   int nvars = vlistNvars(vlistID);
-  int *vars = (int *) malloc(nvars*sizeof(int));
+  int *vars = malloc(nvars*sizeof(int));
 
   if ( cdoNumVarnames )
     {
@@ -117,7 +117,7 @@ void *Arithc(void *argument)
   gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field);
-  field.ptr    = (double *) malloc(gridsize*sizeof(double));
+  field.ptr    = malloc(gridsize*sizeof(double));
   field.weight = NULL;
 
   tsID = 0;
diff --git a/src/Arithdays.c b/src/Arithdays.c
index 37a55bf..b68c9d7 100644
--- a/src/Arithdays.c
+++ b/src/Arithdays.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -116,7 +116,7 @@ void *Arithdays(void *argument)
   gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field);
-  field.ptr    = (double *) malloc(gridsize*sizeof(double));
+  field.ptr    = malloc(gridsize*sizeof(double));
   field.weight = NULL;
 
   tsID = 0;
diff --git a/src/Arithlat.c b/src/Arithlat.c
index 45a88f7..d717da4 100644
--- a/src/Arithlat.c
+++ b/src/Arithlat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -71,7 +71,7 @@ void *Arithlat(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
@@ -118,7 +118,7 @@ void *Arithlat(void *argument)
 
 	      gridsize = gridInqSize(gridID);
 
-	      scale = (double *) realloc(scale, gridsize*sizeof(double));
+	      scale = realloc(scale, gridsize*sizeof(double));
 	      gridInqYvals(gridID, scale);
 
 	      /* Convert lat/lon units if required */
diff --git a/src/CDIread.c b/src/CDIread.c
index fbfd3ce..66192d7 100644
--- a/src/CDIread.c
+++ b/src/CDIread.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -64,26 +64,6 @@ const char *datatypestr(int datatype)
 }
 
 static
-off_t filesize(const char *filename)
-{
-  FILE *fp;
-  off_t pos = 0;
-
-  fp = fopen(filename, "r");
-  if ( fp == NULL )
-    {
-      fprintf(stderr, "Open failed on %s\n", filename);
-    }
-  else
-    {
-      fseek(fp, 0L, SEEK_END);
-      pos = ftello(fp);
-    }
-  
-  return pos;
-}
-
-static
 void print_stat(const char *sinfo, int memtype, int datatype, int filetype, off_t nvalues, double data_size, double file_size, double tw)
 {
   nvalues /= 1000000;
@@ -160,8 +140,8 @@ void *CDIread(void *argument)
 	  
       gridsize = vlistGridsizeMax(vlistID);
       
-      if ( darray == NULL ) darray = (double *) malloc(gridsize*sizeof(double));
-      if ( farray == NULL && memtype == MEMTYPE_FLOAT ) farray = (float *) malloc(gridsize*sizeof(float));
+      if ( darray == NULL ) darray = malloc(gridsize*sizeof(double));
+      if ( farray == NULL && memtype == MEMTYPE_FLOAT ) farray = malloc(gridsize*sizeof(float));
 
       t0 = timer_val(timer_read);
 
diff --git a/src/CDItest.c b/src/CDItest.c
index 84f8f67..173f310 100644
--- a/src/CDItest.c
+++ b/src/CDItest.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -75,7 +75,7 @@ void *CDItest(void *argument)
       streamDefVlist(streamID2, vlistID2);
 
       gridsize = vlistGridsizeMax(vlistID1);
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
 
       tsID1 = 0;
       tsID2 = 0;
diff --git a/src/CDIwrite.c b/src/CDIwrite.c
index cd8dffd..70f7148 100644
--- a/src/CDIwrite.c
+++ b/src/CDIwrite.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -64,32 +64,6 @@ const char *datatypestr(int datatype)
 }
 
 static
-off_t filesize(const char *filename)
-{
-  FILE *fp;
-  off_t pos = 0;
-
-  if ( filename[0] == '(' && filename[1] == 'p' )
-    {
-    }
-  else
-    {
-      fp = fopen(filename, "r");
-      if ( fp == NULL )
-	{
-	  fprintf(stderr, "Open failed on %s\n", filename);
-	}
-      else
-	{
-	  fseek(fp, 0L, SEEK_END);
-	  pos = ftello(fp);
-	}
-    }
-  
-  return pos;
-}
-
-static
 void print_stat(const char *sinfo, int memtype, int datatype, int filetype, off_t nvalues, double data_size, double file_size, double tw)
 {
   double rout;
@@ -192,19 +166,19 @@ void *CDIwrite(void *argument)
       cdoPrint("nvars      : %d", nvars);
     } 
 
-  vars = (double ***) malloc(nvars*sizeof(double **));
+  vars = malloc(nvars*sizeof(double **));
   for ( varID = 0; varID < nvars; varID++ )
     {
-      vars[varID] = (double **) malloc(nlevs*sizeof(double *));
+      vars[varID] = malloc(nlevs*sizeof(double *));
       for ( levelID = 0; levelID < nlevs; levelID++ )
 	{
-	  vars[varID][levelID] = (double *) malloc(gridsize*sizeof(double));
+	  vars[varID][levelID] = malloc(gridsize*sizeof(double));
 	  for ( i = 0; i < gridsize; ++i )
 	    vars[varID][levelID][i] = varID + rand()/(RAND_MAX+1.0);
 	}
     }
 
-  if ( memtype == MEMTYPE_FLOAT ) farray = (float *) malloc(gridsize*sizeof(float));
+  if ( memtype == MEMTYPE_FLOAT ) farray = malloc(gridsize*sizeof(float));
 
   vlistID = vlistCreate();
 
diff --git a/src/Cat.c b/src/Cat.c
index 5440bad..d65d4d3 100644
--- a/src/Cat.c
+++ b/src/Cat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -106,7 +106,7 @@ void *Cat(void *argument)
 	  if ( ! lcopy )
 	    {
 	      gridsize = vlistGridsizeMax(vlistID1);
-	      array = (double *) malloc(gridsize*sizeof(double));
+	      array = malloc(gridsize*sizeof(double));
 	    }
 	}
       else
diff --git a/src/Change.c b/src/Change.c
index 4b81e11..8ecc8ae 100644
--- a/src/Change.c
+++ b/src/Change.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -204,8 +204,8 @@ void *Change(void *argument)
 	{
 	  zaxisID1 = vlistZaxis(vlistID2, index);
 	  nlevs = zaxisInqSize(zaxisID1);
-	  levels = (double *) malloc(nlevs*sizeof(double));
-	  newlevels = (double *) malloc(nlevs*sizeof(double));
+	  levels = malloc(nlevs*sizeof(double));
+	  newlevels = malloc(nlevs*sizeof(double));
 	  zaxisInqLevels(zaxisID1, levels);
 
 	  for ( k = 0; k < nlevs; k++ ) newlevels[k] = levels[k];
@@ -255,7 +255,7 @@ void *Change(void *argument)
 
       zaxisID1 = vlistInqVarZaxis(vlistID2, varID);
       nlevs = zaxisInqSize(zaxisID1);
-      levels = (double *) malloc(nlevs*sizeof(double));
+      levels = malloc(nlevs*sizeof(double));
       zaxisInqLevels(zaxisID1, levels);
       nfound = 0;
       for ( k = 0; k < nlevs; k++ )
@@ -317,7 +317,7 @@ void *Change(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = vlistGridsizeMax(vlistID2);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID1 = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID1)) )
diff --git a/src/Change_e5slm.c b/src/Change_e5slm.c
index c313d1c..6d04d74 100644
--- a/src/Change_e5slm.c
+++ b/src/Change_e5slm.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -75,9 +75,9 @@ void *Change_e5slm(void *argument)
 
   gridsize = gridInqSize(vlistInqVarGrid(vlistIDslm, 0));
 
-  array = (double *) malloc(gridsize*sizeof(double));
-  cland = (double *) malloc(gridsize*sizeof(double));
-  lsea  = (short *)  malloc(gridsize*sizeof(short));
+  array = malloc(gridsize*sizeof(double));
+  cland = malloc(gridsize*sizeof(double));
+  lsea  = malloc(gridsize*sizeof(short));
 
   streamInqTimestep(streamIDslm, 0);
 
@@ -102,7 +102,7 @@ void *Change_e5slm(void *argument)
 
 
   nvars = vlistNvars(vlistID1);
-  codes = (short *) malloc(nvars*sizeof(short));
+  codes = malloc(nvars*sizeof(short));
 
   for ( varID = 0; varID < nvars; ++varID )
     {
diff --git a/src/Cloudlayer.c b/src/Cloudlayer.c
index 19be733..e78f70d 100644
--- a/src/Cloudlayer.c
+++ b/src/Cloudlayer.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -234,13 +234,13 @@ void *Cloudlayer(void *argument)
   nlevel = zaxisInqSize(zaxisID);
   nhlev  = nlevel+1;
 
-  aclcac = (double *) malloc(gridsize*nlevel*sizeof(double));
+  aclcac = malloc(gridsize*nlevel*sizeof(double));
   for ( varID = 0; varID < nvars2; ++varID )
-    cloud[varID] = (double *) malloc(gridsize*sizeof(double));
+    cloud[varID] = malloc(gridsize*sizeof(double));
 
   if ( zaxisInqType(zaxisID) == ZAXIS_PRESSURE )
     {
-      plevs = (double *) malloc(nlevel*sizeof(double));
+      plevs = malloc(nlevel*sizeof(double));
       zaxisInqLevels(zaxisID, plevs);
       if ( plevs[0] > plevs[nlevel-1] )
 	{
@@ -281,11 +281,11 @@ void *Cloudlayer(void *argument)
 	{
 	  double *vct;
 
-	  vct = (double *) malloc(nvct*sizeof(double));
+	  vct = malloc(nvct*sizeof(double));
 	  zaxisInqVct(zaxisID, vct);
 
 	  nlevs = nlevel + 1;
-	  plevs = (double *) malloc(nlevs*sizeof(double));
+	  plevs = malloc(nlevs*sizeof(double));
 	  vct2plev(vct, plevs, nlevs);
 	  free(vct);
 
diff --git a/src/Command.c b/src/Command.c
index 4dd81c7..f29b4cc 100644
--- a/src/Command.c
+++ b/src/Command.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -302,10 +302,10 @@ void command_init()
   taxisID = vlistInqTaxis(gl_vlistID);
 
   gridsize = vlistGridsizeMax(gl_vlistID);
-  gl_data = (double *) malloc(gridsize*sizeof(double));
+  gl_data = malloc(gridsize*sizeof(double));
 
   gl_nvars = vlistNvars(gl_vlistID);
-  all_vars = (vars_t *) malloc(gl_nvars*sizeof(vars_t));
+  all_vars = malloc(gl_nvars*sizeof(vars_t));
 
   for ( varID = 0; varID < gl_nvars; ++varID )
     {
diff --git a/src/Comp.c b/src/Comp.c
index 23078a8..cb9e5c4 100644
--- a/src/Comp.c
+++ b/src/Comp.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -112,9 +112,9 @@ void *Comp(void *argument)
 
   gridsize = vlistGridsizeMax(vlistIDx1);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
-  array3 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
+  array3 = malloc(gridsize*sizeof(double));
 
   arrayx1 = array1;
   arrayx2 = array2;
@@ -143,12 +143,12 @@ void *Comp(void *argument)
       if ( filltype == FILL_TS )
 	{
 	  nvars  = vlistNvars(vlistIDx2);
-	  vardata  = (double **) malloc(nvars*sizeof(double *));
+	  vardata  = malloc(nvars*sizeof(double *));
 	  for ( varID = 0; varID < nvars; varID++ )
 	    {
 	      gridsize = gridInqSize(vlistInqVarGrid(vlistIDx2, varID));
 	      nlev     = zaxisInqSize(vlistInqVarZaxis(vlistIDx2, varID));
-	      vardata[varID]  = (double *) malloc(nlev*gridsize*sizeof(double));
+	      vardata[varID]  = malloc(nlev*gridsize*sizeof(double));
 	    }
 	}
     }
diff --git a/src/Compc.c b/src/Compc.c
index 4b8744a..b48bf4e 100644
--- a/src/Compc.c
+++ b/src/Compc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -78,8 +78,8 @@ void *Compc(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
 
   streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
diff --git a/src/Complextorect.c b/src/Complextorect.c
index 20e3caf..e319501 100644
--- a/src/Complextorect.c
+++ b/src/Complextorect.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -74,9 +74,9 @@ void *Complextorect(void *argument)
   streamDefVlist(streamID3, vlistID3);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array1 = (double *) malloc(2*gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
-  array3 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(2*gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
+  array3 = malloc(gridsize*sizeof(double));
       
   tsID  = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Cond.c b/src/Cond.c
index 0484f4e..a69518f 100644
--- a/src/Cond.c
+++ b/src/Cond.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -95,9 +95,9 @@ void *Cond(void *argument)
   if ( filltype == FILL_REC && gridsize != gridInqSize(vlistGrid(vlistID1, 0)) )
     cdoAbort("Stream1 >%s< has wrong gridsize!", cdoStreamName(0)->args);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
-  array3 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
+  array3 = malloc(gridsize*sizeof(double));
 
   if ( cdoVerbose )
     cdoPrint("Number of timesteps: file1 %d, file2 %d", ntsteps1, ntsteps2);
@@ -110,14 +110,14 @@ void *Cond(void *argument)
 	  cdoPrint("Filling up stream1 >%s< by copying the first timestep.", cdoStreamName(0)->args);
 
 	  nvars  = vlistNvars(vlistID1);
-	  vardata1  = (double **) malloc(nvars*sizeof(double *));
-	  varnmiss1 = (int **) malloc(nvars*sizeof(int *));
+	  vardata1  = malloc(nvars*sizeof(double *));
+	  varnmiss1 = malloc(nvars*sizeof(int *));
 	  for ( varID = 0; varID < nvars; varID++ )
 	    {
 	      gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	      nlev     = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	      vardata1[varID]  = (double *) malloc(nlev*gridsize*sizeof(double));
-	      varnmiss1[varID] = (int *) malloc(nlev*sizeof(int));
+	      vardata1[varID]  = malloc(nlev*gridsize*sizeof(double));
+	      varnmiss1[varID] = malloc(nlev*sizeof(int));
 	    }
 	}
     }
diff --git a/src/Cond2.c b/src/Cond2.c
index 4b8c744..a1aa53c 100644
--- a/src/Cond2.c
+++ b/src/Cond2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -98,10 +98,10 @@ void *Cond2(void *argument)
   if ( filltype == FILL_REC && gridsize != gridInqSize(vlistGrid(vlistID1, 0)) )
     cdoAbort("Stream1 >%s< has wrong gridsize!", cdoStreamName(0)->args);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
-  array3 = (double *) malloc(gridsize*sizeof(double));
-  array4 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
+  array3 = malloc(gridsize*sizeof(double));
+  array4 = malloc(gridsize*sizeof(double));
 
   if ( cdoVerbose )
     cdoPrint("Number of timesteps: file1 %d, file2 %d, file3 %d",
@@ -115,14 +115,14 @@ void *Cond2(void *argument)
 	  cdoPrint("Filling up stream1 >%s< by copying the first timestep.", cdoStreamName(0)->args);
 
 	  nvars  = vlistNvars(vlistID1);
-	  vardata1  = (double **) malloc(nvars*sizeof(double *));
-	  varnmiss1 = (int **) malloc(nvars*sizeof(int *));
+	  vardata1  = malloc(nvars*sizeof(double *));
+	  varnmiss1 = malloc(nvars*sizeof(int *));
 	  for ( varID = 0; varID < nvars; varID++ )
 	    {
 	      gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	      nlev     = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	      vardata1[varID]  = (double *) malloc(nlev*gridsize*sizeof(double));
-	      varnmiss1[varID] = (int *) malloc(nlev*sizeof(int));
+	      vardata1[varID]  = malloc(nlev*gridsize*sizeof(double));
+	      varnmiss1[varID] = malloc(nlev*sizeof(int));
 	    }
 	}
     }
diff --git a/src/Condc.c b/src/Condc.c
index b1ae7fe..e1c76bf 100644
--- a/src/Condc.c
+++ b/src/Condc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -69,8 +69,8 @@ void *Condc(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
 
   streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
diff --git a/src/Consecstat.c b/src/Consecstat.c
index a882eb5..5548806 100644
--- a/src/Consecstat.c
+++ b/src/Consecstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -152,7 +152,7 @@ void *Consecstat (void *argument)
   vlistDefTaxis(ovlistID, otaxisID);
 
   field_init(&field);
-  field.ptr = (double *) malloc(vlistGridsizeMax(ovlistID)*sizeof(double));
+  field.ptr = malloc(vlistGridsizeMax(ovlistID)*sizeof(double));
 
   nvars     = vlistNvars(ivlistID);
   vars      = field_calloc(ivlistID, FIELD_PTR);
diff --git a/src/Copy.c b/src/Copy.c
index ba81f82..4571b0f 100644
--- a/src/Copy.c
+++ b/src/Copy.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -102,11 +102,11 @@ void *Copy(void *argument)
 	  streamDefVlist(streamID2, vlistID2);
 
 	  gridsize = vlistGridsizeMax(vlistID1);
-	  array = (double *) malloc(gridsize*sizeof(double));
+	  array = malloc(gridsize*sizeof(double));
 	  if ( cdoParIO )
 	    {
 	      fprintf(stderr, "Parallel reading enabled!\n");
-	      parIO.array = (double *) malloc(gridsize*sizeof(double));
+	      parIO.array = malloc(gridsize*sizeof(double));
 	      parIO.array_size = gridsize;
 	    }
 	}
diff --git a/src/Deltime.c b/src/Deltime.c
index ca5c490..3f34e40 100644
--- a/src/Deltime.c
+++ b/src/Deltime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -100,7 +100,7 @@ void *Deltime(void *argument)
   if ( ! lcopy )
     {
       gridsize = vlistGridsizeMax(vlistID1);
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
       
   nfound = 0;
diff --git a/src/Derivepar.c b/src/Derivepar.c
index b80e54e..cb74f44 100644
--- a/src/Derivepar.c
+++ b/src/Derivepar.c
@@ -27,6 +27,7 @@
 #include "cdo_int.h"
 #include "pstream.h"
 #include "vinterp.h"
+#include "stdnametable.h"
 
 #define  C_RKBOL         (1.380658e-23)     /* Boltzmann constant in J/K   */
 #define  C_RNAVO         (6.0221367e+23)    /* Avogadro constant in 1/mol  */
@@ -145,7 +146,7 @@ void minmaxval(long nvals, double *array, int *imiss, double *minval, double *ma
 
 void *Derivepar(void *argument)
 {
-  int GEOPOTHEIGHT;
+  int GEOPOTHEIGHT, SEALEVELPRESSURE;
   int operatorID;
   int mode;
   enum {ECHAM_MODE, WMO_MODE};
@@ -161,11 +162,12 @@ void *Derivepar(void *argument)
   int ngrids, gridID = -1, zaxisID;
   int nlevel;
   int nvct;
+  int surfaceID = -1;
   int geopID = -1, tempID = -1, humID = -1, psID = -1, lnpsID = -1, presID = -1;
   // int clwcID = -1, ciwcID = -1;
   int code, param;
   char paramstr[32];
-  char varname[CDI_MAX_NAME];
+  char varname[CDI_MAX_NAME], stdname[CDI_MAX_NAME];
   double *single2;
   int taxisID1, taxisID2;
   int lhavevct;
@@ -174,17 +176,20 @@ void *Derivepar(void *argument)
   double *geop = NULL, *ps = NULL, *temp = NULL, *hum = NULL;
   // double *lwater = NULL, *iwater = NULL;
   double *geopotheight = NULL;
+  double *sealevelpressure = NULL;
   int nmiss, nmissout = 0;
   int ltq = FALSE;
   double *array = NULL;
   double *half_press = NULL;
+  double *full_press = NULL;
   double minval, maxval;
   int instNum, tableNum;
   int useTable;
 
   cdoInitialize(argument);
 
-  GEOPOTHEIGHT = cdoOperatorAdd("geopotheight",   0, 0, NULL);
+  GEOPOTHEIGHT     = cdoOperatorAdd("geopotheight",   0, 0, NULL);
+  SEALEVELPRESSURE = cdoOperatorAdd("sealevelpressure",   0, 0, NULL);
 
   operatorID = cdoOperatorID();
 
@@ -249,7 +254,7 @@ void *Derivepar(void *argument)
                       if ( cdoVerbose )
                         cdoPrint("lhavevct=TRUE  zaxisIDh = %d, nhlevf   = %d", zaxisIDh, nlevel);
  
-		      vct = (double *) malloc(nvct*sizeof(double));
+		      vct = malloc(nvct*sizeof(double));
 		      zaxisInqVct(zaxisID, vct);
 
 		      if ( cdoVerbose )
@@ -333,24 +338,24 @@ void *Derivepar(void *argument)
       if ( cdoVerbose )
 	cdoPrint("Mode = %d  Center = %d  Param = %s", mode, instNum, paramstr);
 
-      if ( code <= 0 )
+      if ( code <= 0 || code == 255 )
 	{
 	  vlistInqVarName(vlistID1, varID, varname);
-
 	  strtolower(varname);
 
-	  if ( nlevel == 1 )
-	    {
-	      if      ( strcmp(varname, "geosp")   == 0 ) code = 129;
-	      else if ( strcmp(varname, "aps")     == 0 ) code = 134;
-	      else if ( strcmp(varname, "ps")      == 0 ) code = 134;
-	      else if ( strcmp(varname, "lsp")     == 0 ) code = 152;
-	    }
+	  vlistInqVarStdname(vlistID1, varID, stdname);
+	  strtolower(stdname);
+
+	  code = echamcode_from_stdname(stdname);
 
-	  if ( nlevel == nhlevf )
+	  if ( code < 0 )
 	    {
-	      if      ( strcmp(varname, "t")       == 0 ) code = 130;
-	      else if ( strcmp(varname, "q")       == 0 ) code = 133;
+	      if      ( geopID == -1  && strcmp(varname, "geosp")   == 0 ) code = 129;
+	      else if ( psID   == -1  && strcmp(varname, "aps")     == 0 ) code = 134;
+	      else if ( psID   == -1  && strcmp(varname, "ps")      == 0 ) code = 134;
+	      else if ( lnpsID == -1  && strcmp(varname, "lsp")     == 0 ) code = 152;
+	      else if ( tempID == -1  && strcmp(varname, "t")       == 0 ) code = 130;
+	      else if ( humID  == -1  && strcmp(varname, "q")       == 0 ) code = 133;
 	      // else if ( strcmp(varname, "clwc")    == 0 ) code = 246;
 	      // else if ( strcmp(varname, "ciwc")    == 0 ) code = 247;
 	    }
@@ -364,6 +369,8 @@ void *Derivepar(void *argument)
       // else if ( code == 246 ) clwcID    = varID;
       // else if ( code == 247 ) ciwcID    = varID;
 
+      if ( operatorID == SEALEVELPRESSURE ) humID = -1;
+
       if ( gridInqType(gridID) == GRID_SPECTRAL && zaxisInqType(zaxisID) == ZAXIS_HYBRID )
 	cdoAbort("Spectral data on model level unsupported!");
 
@@ -371,30 +378,42 @@ void *Derivepar(void *argument)
 	cdoAbort("Spectral data unsupported!");
     }
 
-  if ( tempID == -1 ) cdoAbort("Temperature not found!");
+  if ( tempID == -1 ) cdoAbort("Air temperature not found!");
 
-  array  = (double *) malloc(ngp*sizeof(double));
+  array  = malloc(ngp*sizeof(double));
 
-  geop   = (double *) malloc(ngp*sizeof(double));
-  ps     = (double *) malloc(ngp*sizeof(double));
+  geop   = malloc(ngp*sizeof(double));
+  ps     = malloc(ngp*sizeof(double));
 
-  temp   = (double *) malloc(ngp*nhlevf*sizeof(double));
+  temp   = malloc(ngp*nhlevf*sizeof(double));
 
-  if ( humID == -1 )
-    cdoWarning("Humidity not found - using algorithm without humidity!");
-  else
-    hum    = (double *) malloc(ngp*nhlevf*sizeof(double));
+  // lwater = malloc(ngp*nhlevf*sizeof(double));
+  // iwater = malloc(ngp*nhlevf*sizeof(double));
 
-  // lwater = (double *) malloc(ngp*nhlevf*sizeof(double));
-  // iwater = (double *) malloc(ngp*nhlevf*sizeof(double));
+  half_press   = malloc(ngp*(nhlevf+1)*sizeof(double));
 
-  half_press   = (double *) malloc(ngp*(nhlevf+1)*sizeof(double));
-  geopotheight = (double *) malloc(ngp*(nhlevf+1)*sizeof(double));
+  if ( operatorID == GEOPOTHEIGHT )
+    {
+      if ( humID == -1 )
+	cdoWarning("%s not found - using algorithm without %s!", var_stdname(specific_humidity), var_stdname(specific_humidity));
+      else
+	hum    = malloc(ngp*nhlevf*sizeof(double));
+
+      geopotheight = malloc(ngp*(nhlevf+1)*sizeof(double));
+    }
+  
+  if ( operatorID == SEALEVELPRESSURE )
+    {
+      full_press   = malloc(ngp*nhlevf*sizeof(double));
+
+      surfaceID = zaxisFromName("surface");
+      sealevelpressure = malloc(ngp*sizeof(double));
+    }
 
   if ( zaxisIDh != -1 && geopID == -1 )
     {
       if ( ltq )
-	cdoWarning("Orography (surf. geopotential) not found - using zero orography!");
+	cdoWarning("%s not found - using zero %s!", var_stdname(surface_geopotential), var_stdname(surface_geopotential));
 
       memset(geop, 0, ngp*sizeof(double));
     }
@@ -404,18 +423,33 @@ void *Derivepar(void *argument)
     {
       presID = psID;
       if ( psID != -1 )
-	cdoWarning("LOG surface pressure (lsp) not found - using surface pressure (asp)!");
+	cdoWarning("LOG(%s) not found - using %s!", var_stdname(surface_air_pressure), var_stdname(surface_air_pressure));
       else
-	cdoAbort("Surface pressure not found!");
+	cdoAbort("%s not found!", var_stdname(surface_air_pressure));
     }
 
 
   vlistID2 = vlistCreate();
-  varID = vlistDefVar(vlistID2, gridID, zaxisIDh, TSTEP_INSTANT);
-  vlistDefVarParam(vlistID2, varID, cdiEncodeParam(156, 128, 255));
-  vlistDefVarName(vlistID2, varID, "geopotheight");
-  vlistDefVarStdname(vlistID2, varID, "geopotental_height");
-  vlistDefVarUnits(vlistID2, varID, "m");
+
+  int var_id = -1;
+
+  if ( operatorID == GEOPOTHEIGHT )
+    {
+      var_id = geopotential_height;
+      varID  = vlistDefVar(vlistID2, gridID, zaxisIDh, TSTEP_INSTANT);
+    }
+  else if ( operatorID == SEALEVELPRESSURE )
+    {
+      var_id = air_pressure_at_sea_level;
+      varID  = vlistDefVar(vlistID2, gridID, surfaceID, TSTEP_INSTANT);
+    }
+  else
+    cdoAbort("Internal problem, invalid operatorID: %d!", operatorID);
+  
+  vlistDefVarParam(vlistID2, varID, cdiEncodeParam(var_echamcode(var_id), 128, 255));
+  vlistDefVarName(vlistID2, varID, var_name(var_id));
+  vlistDefVarStdname(vlistID2, varID, var_stdname(var_id));
+  vlistDefVarUnits(vlistID2, varID, var_units(var_id));
 
   taxisID1 = vlistInqTaxis(vlistID1);
   taxisID2 = taxisDuplicate(taxisID1);
@@ -513,19 +547,33 @@ void *Derivepar(void *argument)
 	    }
 	}
 
-      presh(NULL, half_press, vct, ps, nhlevf, ngp);
+      if ( operatorID == GEOPOTHEIGHT )
+	{
+	  presh(NULL, half_press, vct, ps, nhlevf, ngp);
+	  
+	  memcpy(geopotheight+ngp*nhlevf, geop, ngp*sizeof(double));
+	  MakeGeopotHeight(geopotheight, temp, hum, half_press, ngp, nhlevf);
+
+	  nmissout = 0;
+	  varID = 0;
+	  nlevel = nhlevf;
+	  for ( levelID = 0; levelID < nlevel; levelID++ )
+	    {
+	      streamDefRecord(streamID2, varID, levelID);
+	      streamWriteRecord(streamID2, geopotheight+levelID*ngp, nmissout);
+	    }
+	}
+      else if ( operatorID == SEALEVELPRESSURE )
+	{
+	  presh(full_press, half_press, vct, ps, nhlevf, ngp);
 
-      memcpy(geopotheight+ngp*nhlevf, geop, ngp*sizeof(double));
-      MakeGeopotHeight(geopotheight, temp, hum, half_press, ngp, nhlevf);
+	  extra_P(sealevelpressure, half_press+ngp*(nhlevf), full_press+ngp*(nhlevf-1), geop, temp+ngp*(nhlevf-1), ngp);
 
-      nmissout = 0;
-      varID = 0;
-      nlevel = nhlevf;
-      for ( levelID = 0; levelID < nlevel; levelID++ )
-	{
-	  streamDefRecord(streamID2, varID, levelID);
-	  streamWriteRecord(streamID2, geopotheight+levelID*ngp, nmissout);
+	  streamDefRecord(streamID2, 0, 0);
+	  streamWriteRecord(streamID2, sealevelpressure, 0);
 	}
+      else
+	cdoAbort("Internal error");
 
       tsID++;
     }
@@ -538,9 +586,11 @@ void *Derivepar(void *argument)
   free(ps);
   free(geop);
   free(temp);
-  free(geopotheight);
+  if ( geopotheight ) free(geopotheight);
+  if ( sealevelpressure ) free(sealevelpressure);
   if ( hum ) free(hum);
 
+  if ( full_press ) free(full_press);
   if ( half_press ) free(half_press);
 
   free(array);
diff --git a/src/Detrend.c b/src/Detrend.c
index 7d4969d..8cbe0f5 100644
--- a/src/Detrend.c
+++ b/src/Detrend.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -139,8 +139,8 @@ void *Detrend(void *argument)
       if ( tsID >= nalloc )
 	{
 	  nalloc += NALLOC_INC;
-	  dtinfo = (dtinfo_t *) realloc(dtinfo, nalloc*sizeof(dtinfo_t));
-	  vars   = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
+	  dtinfo = realloc(dtinfo, nalloc*sizeof(dtinfo_t));
+	  vars   = realloc(vars, nalloc*sizeof(field_t **));
 	}
 
       taxisInqDTinfo(taxisID1, &dtinfo[tsID]);
@@ -152,7 +152,7 @@ void *Detrend(void *argument)
 	  streamInqRecord(streamID1, &varID, &levelID);
 	  gridID   = vlistInqVarGrid(vlistID1, varID);
 	  gridsize = gridInqSize(gridID);
-	  vars[tsID][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+	  vars[tsID][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 	  streamReadRecord(streamID1, vars[tsID][varID][levelID].ptr, &nmiss);
 	  vars[tsID][varID][levelID].nmiss = nmiss;
 	}
@@ -162,11 +162,11 @@ void *Detrend(void *argument)
 
   nts = tsID;
 
-  mem = (memory_t *) malloc(ompNumThreads*sizeof(memory_t));
+  mem = malloc(ompNumThreads*sizeof(memory_t));
   for ( i = 0; i < ompNumThreads; i++ )
     {
-      mem[i].array1 = (double *) malloc(nts*sizeof(double));
-      mem[i].array2 = (double *) malloc(nts*sizeof(double));
+      mem[i].array1 = malloc(nts*sizeof(double));
+      mem[i].array2 = malloc(nts*sizeof(double));
     }
 
   for ( varID = 0; varID < nvars; varID++ )
diff --git a/src/Diff.c b/src/Diff.c
index f9e34c1..cbf21f1 100644
--- a/src/Diff.c
+++ b/src/Diff.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -76,8 +76,8 @@ void *Diff(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
 
   indg = 0;
   tsID = 0;
@@ -161,9 +161,9 @@ void *Diff(void *argument)
 
 		      fprintf(stdout, ": S Z  Max_Absdiff Max_Reldiff");
 
-		      if ( operatorID == DIFFN )
+		      if ( operatorID == DIFFN || operatorID == DIFF2 )
 			fprintf(stdout, " : Parameter name");
-		      else if ( operatorID == DIFF || operatorID == DIFF2 || operatorID == DIFFP )
+		      else if ( operatorID == DIFF || operatorID == DIFFP )
 			fprintf(stdout, " : Parameter ID");
 		      else if ( operatorID == DIFFC )
 			fprintf(stdout, " : Code number");
diff --git a/src/Duplicate.c b/src/Duplicate.c
index fd33ba1..42abc1f 100644
--- a/src/Duplicate.c
+++ b/src/Duplicate.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -86,9 +86,9 @@ void *Duplicate(void *argument)
       if ( tsID >= nalloc )
 	{
 	  nalloc += NALLOC_INC;
-	  vdate = (int *) realloc(vdate, nalloc*sizeof(int));
-	  vtime = (int *) realloc(vtime, nalloc*sizeof(int));
-	  vars  = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
+	  vdate = realloc(vdate, nalloc*sizeof(int));
+	  vtime = realloc(vtime, nalloc*sizeof(int));
+	  vars  = realloc(vars, nalloc*sizeof(field_t **));
 	}
 
       vdate[tsID] = taxisInqVdate(taxisID1);
@@ -101,7 +101,7 @@ void *Duplicate(void *argument)
 	  streamInqRecord(streamID1, &varID, &levelID);
 	  gridID   = vlistInqVarGrid(vlistID1, varID);
 	  gridsize = gridInqSize(gridID);
-	  vars[tsID][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+	  vars[tsID][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 	  streamReadRecord(streamID1, vars[tsID][varID][levelID].ptr, &nmiss);
 	  vars[tsID][varID][levelID].nmiss = nmiss;
 	}
diff --git a/src/EOFs.c b/src/EOFs.c
index f9348db..507bd0f 100644
--- a/src/EOFs.c
+++ b/src/EOFs.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -36,6 +36,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
+#include "grid.h"
 #include "statistic.h"
 
 enum T_EIGEN_MODE {JACOBI, DANIELSON_LANCZOS};
@@ -143,7 +144,7 @@ void *EOFs(void * argument)
   nvars       = vlistNvars(vlistID1);
   nrecs       = vlistNrecs(vlistID1);
 
-  weight      = (double*) malloc(gridsize*sizeof(double));
+  weight      = malloc(gridsize*sizeof(double));
   if ( WEIGHTS )
     gridWeights(gridID1, &weight[0]);
   else
@@ -236,11 +237,11 @@ void *EOFs(void * argument)
   if ( cdoTimer ) timer_start(timer_alloc);
 
   /* allocation of temporary fields and output structures */
-  in           = (double    *) malloc(gridsize*sizeof(double));
-  datafields   = (double ****) malloc(nvars*sizeof(double ***));
-  datacounts   = (int     ***) malloc(nvars*sizeof(int **));
-  eigenvectors = (double ****) malloc(nvars*sizeof(double ***));
-  eigenvalues  = (double ****) malloc(nvars*sizeof(double ***));
+  in           = malloc(gridsize*sizeof(double));
+  datafields   = malloc(nvars*sizeof(double ***));
+  datacounts   = malloc(nvars*sizeof(int **));
+  eigenvectors = malloc(nvars*sizeof(double ***));
+  eigenvalues  = malloc(nvars*sizeof(double ***));
 
   for ( varID = 0; varID < nvars; ++varID )
     {
@@ -249,22 +250,22 @@ void *EOFs(void * argument)
       nlevs               = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
       missval             = vlistInqVarMissval(vlistID1, varID);
 
-      datafields[varID]   = (double ***) malloc(nlevs*sizeof(double **));
-      datacounts[varID]   = (int **)     malloc(nlevs*sizeof(int* ));
-      eigenvectors[varID] = (double ***) malloc(nlevs*sizeof(double **));
-      eigenvalues[varID]  = (double ***) malloc(nlevs*sizeof(double **));
+      datafields[varID]   = malloc(nlevs*sizeof(double **));
+      datacounts[varID]   = malloc(nlevs*sizeof(int* ));
+      eigenvectors[varID] = malloc(nlevs*sizeof(double **));
+      eigenvalues[varID]  = malloc(nlevs*sizeof(double **));
 
       for ( levelID = 0; levelID < nlevs; ++levelID )
         {
           if ( grid_space )
             {
-              datafields[varID][levelID]            = (double **) malloc(1*sizeof(double *));
+              datafields[varID][levelID]            = malloc(1*sizeof(double *));
               //datafields[varID][levelID][0].grid    = gridID1;
               //datafields[varID][levelID][0].nmiss   = 0;
               //datafields[varID][levelID][0].missval = missval;
-              datafields[varID][levelID][0]     = (double *) malloc(gridsize*gridsize*sizeof(double));
+              datafields[varID][levelID][0]     = malloc(gridsize*gridsize*sizeof(double));
 
-              datacounts[varID][levelID]            = (int *) malloc(gridsize*gridsize*sizeof(int));
+              datacounts[varID][levelID]            = malloc(gridsize*gridsize*sizeof(int));
 	      for ( i = 0; i<gridsize*gridsize; i++ )
 		{
 		  datacounts[varID][levelID][i] = 0;
@@ -273,34 +274,34 @@ void *EOFs(void * argument)
 	    }
           else if ( time_space )
             {
-              datafields[varID][levelID] = (double **) malloc(nts*sizeof(double *));
+              datafields[varID][levelID] = malloc(nts*sizeof(double *));
               for ( tsID = 0; tsID < nts; tsID++ )
                 {
                   //datafields[varID][levelID][tsID].grid    = gridID1;
                   //datafields[varID][levelID][tsID].nmiss   = 0;
                   //datafields[varID][levelID][tsID].missval = missval;
-                  datafields[varID][levelID][tsID]    = (double *) malloc(gridsize*sizeof(double));
+                  datafields[varID][levelID][tsID]    = malloc(gridsize*sizeof(double));
                   for ( i = 0; i < gridsize; ++i )
                     datafields[varID][levelID][tsID][i] = 0;
                 }
-              datacounts[varID][levelID] = (int *) malloc(gridsize*sizeof(int));	      
+              datacounts[varID][levelID] = malloc(gridsize*sizeof(int));	      
 	      for(i=0;i<gridsize;i++)
 		datacounts[varID][levelID][i] = 0;
             }
 
-          eigenvectors[varID][levelID] = (double **) malloc(n_eig*sizeof(double *));
-          eigenvalues[varID][levelID]  = (double **) malloc(n*sizeof(double *));
+          eigenvectors[varID][levelID] = malloc(n_eig*sizeof(double *));
+          eigenvalues[varID][levelID]  = malloc(n*sizeof(double *));
 
           for ( i = 0; i < n; i++ )
             {
               if ( i < n_eig )
                 {
-                  eigenvectors[varID][levelID][i] = (double *) malloc(gridsize*sizeof(double));
+                  eigenvectors[varID][levelID][i] = malloc(gridsize*sizeof(double));
                   for ( ii = 0; ii < gridsize; ++ii )
                     eigenvectors[varID][levelID][i][ii] = missval;
                 }
 
-              eigenvalues[varID][levelID][i] = (double *) malloc(1*sizeof(double));
+              eigenvalues[varID][levelID][i] = malloc(1*sizeof(double));
               eigenvalues[varID][levelID][i][0]  = missval;
             }
         }
@@ -399,8 +400,8 @@ void *EOFs(void * argument)
         }
 
   /*
-  pack = (int *) malloc(gridsize*sizeof(int)); //TODO
-  miss = (int *) malloc(gridsize*sizeof(int));
+  pack = malloc(gridsize*sizeof(int)); //TODO
+  miss = malloc(gridsize*sizeof(int));
   */
 
   if ( cdoTimer ) timer_stop(timer_read);
@@ -435,8 +436,8 @@ void *EOFs(void * argument)
 
           if ( grid_space )
             {
-	      pack = (int *) malloc(gridsize*sizeof(int));
-	      miss = (int *) malloc(gridsize*sizeof(int));
+	      pack = malloc(gridsize*sizeof(int));
+	      miss = malloc(gridsize*sizeof(int));
 
               for ( i1 = 0; i1 < gridsize; i1++ )
                 {
@@ -452,10 +453,10 @@ void *EOFs(void * argument)
 	      n = npack;
 	      if ( npack )
 		{
-		  cov = (double **) malloc(npack*sizeof(double *));
+		  cov = malloc(npack*sizeof(double *));
 		  for (i1 = 0; i1 < npack; i1++ )
-		    cov[i1] = (double*) malloc(npack*sizeof(double));
-		  eigv = (double *) malloc(npack*sizeof(double));
+		    cov[i1] = malloc(npack*sizeof(double));
+		  eigv = malloc(npack*sizeof(double));
 		}
 
               for (i1 = 0; i1 < npack; i1++)
@@ -470,8 +471,8 @@ void *EOFs(void * argument)
             {
               sum_w = 0;
 
-	      pack = (int *) malloc ( gridsize * sizeof(int) );
-	      miss = (int *) malloc ( gridsize * sizeof(int) );
+	      pack = malloc ( gridsize * sizeof(int) );
+	      miss = malloc ( gridsize * sizeof(int) );
 
               for ( i = 0; i < gridsize ; i++ )
                 {
@@ -486,10 +487,10 @@ void *EOFs(void * argument)
 	      if ( cdoVerbose )
 		cdoPrint("allocating cov with %i x %i elements | npack=%i",nts,nts,npack);
 
-              cov = (double **) malloc (nts*sizeof(double*));
+              cov = malloc (nts*sizeof(double*));
               for ( j1 = 0; j1 < nts; j1++)
-                cov[j1] = (double*) malloc(nts*sizeof(double));
-	      eigv = (double *) malloc (nts*sizeof(double));
+                cov[j1] = malloc(nts*sizeof(double));
+	      eigv = malloc (nts*sizeof(double));
 
 #if defined(_OPENMP)
 #pragma omp parallel for private(j1,j2,i,sum, df1p, df2p) default(shared) schedule(dynamic)
diff --git a/src/EcaIndices.c b/src/EcaIndices.c
index 10b1b18..03a651b 100755
--- a/src/EcaIndices.c
+++ b/src/EcaIndices.c
@@ -74,10 +74,16 @@
 static const char CFD_NAME[]         = "consecutive_frost_days_index_per_time_period";
 static const char CFD_LONGNAME[]     = "Consecutive frost days index is the greatest number of consecutive frost days in a given time period. Frost days is the number of days where minimum of temperature is below 0 degree Celsius. The time period should be defined by the bounds of the time coordinate.";
 static const char CFD_UNITS[]        = "No.";
+static const char CFD_NAME2[]        = "number_of_cfd_periods_with_more_than_5days_per_time_period";
+static const char CFD_LONGNAME2[]    = "Number of cfd periods in given time period with more than 5 days. The time period should be defined by the bounds of the time coordinate.";
+static const char CFD_UNITS2[]       = "No.";
 
 static const char CSU_NAME[]         = "consecutive_summer_days_index_per_time_period";
 static const char CSU_LONGNAME[]     = "Consecutive summer days index is the greatest number of consecutive summer days in a given time period. Summer days is the number of days where maximum of temperature is above 25 degree Celsius. The time period should be defined by the bounds of the time coordinate.";
 static const char CSU_UNITS[]        = "No.";
+static const char CSU_NAME2[]        = "number_of_csu_periods_with_more_than_5days_per_time_period";
+static const char CSU_LONGNAME2[]    = "Number of csu periods in given time period with more than 5 days. The time period should be defined by the bounds of the time coordinate.";
+static const char CSU_UNITS2[]       = "No.";
 
 static const char CWDI_NAME[]        = "cold_wave_duration_index_wrt_mean_of_reference_period";
 static const char CWDI_LONGNAME[]    = "This is the number of days per time period where in intervals of at least %d consecutive days the daily minimum temperature is more than %1.0f degrees below a reference value. The reference value is calculated  as the mean of minimum temperatures of a five day window centred on each calendar day of a given 30 year climate reference period. The time period should be defined by the bounds of the time coordinate.";
@@ -286,8 +292,13 @@ void *EcaCfd(void *argument)
   request.var1.mulc     = 0.0;
   request.var1.addc     = 0.0;
   request.var1.epilog   = NONE;
+  request.var2.name     = CFD_NAME2;
+  request.var2.longname = CFD_LONGNAME2;
+  request.var2.units    = CFD_UNITS2;
+  request.var2.h1       = farseleqc;
+  request.var2.h1arg    = 6;
   request.var2.h2       = NULL;
-  request.var2.h3       = NULL;
+  request.var2.h3       = farnum;
    
   eca1(&request);
   cdoFinish();
@@ -316,8 +327,13 @@ void *EcaCsu(void *argument)
   request.var1.mulc     = 0.0;
   request.var1.addc     = 0.0;
   request.var1.epilog   = NONE;
+  request.var2.name     = CSU_NAME2;
+  request.var2.longname = CSU_LONGNAME2;
+  request.var2.units    = CSU_UNITS2;
+  request.var2.h1       = farseleqc;
+  request.var2.h1arg    = 6;
   request.var2.h2       = NULL;
-  request.var2.h3       = NULL;
+  request.var2.h3       = farnum;
   
   eca1(&request);
   cdoFinish();
@@ -339,7 +355,7 @@ void *EcaCwdi(void *argument)
   if ( operatorArgc() > 0 ) argN = atoi(operatorArgv()[0]);
   if ( operatorArgc() > 1 ) argT = atof(operatorArgv()[1]);
   
-  longname = (char *) malloc(strlen(CWDI_LONGNAME) + 80);
+  longname = malloc(strlen(CWDI_LONGNAME) + 80);
   sprintf(longname, CWDI_LONGNAME, argN, argT);
 
   request.var1.name     = CWDI_NAME;
@@ -380,7 +396,7 @@ void *EcaCwfi(void *argument)
 
   if ( operatorArgc() > 0 ) argN = atoi(operatorArgv()[0]);
 
-  longname = (char *) malloc(strlen(CWFI_LONGNAME) + 40);
+  longname = malloc(strlen(CWFI_LONGNAME) + 40);
   sprintf(longname, CWFI_LONGNAME, argN);
 
   request.var1.name     = CWFI_NAME;
@@ -482,7 +498,7 @@ void *EcaGsl(void *argument)
   if ( operatorArgc() > 1 ) argT = atof(operatorArgv()[1]);
   if ( operatorArgc() > 2 ) minLandFraction = atof(operatorArgv()[2]);
 
-  longname = (char *) malloc(strlen(GSL_LONGNAME) + 160);
+  longname = malloc(strlen(GSL_LONGNAME) + 160);
   sprintf(longname, GSL_LONGNAME, argN, argT, argN, argT);
   
   request.name      = GSL_NAME;
@@ -560,7 +576,7 @@ void *EcaHwdi(void *argument)
   if ( operatorArgc() > 0 ) argN = atoi(operatorArgv()[0]);
   if ( operatorArgc() > 1 ) argT = atof(operatorArgv()[1]);
   
-  longname = (char *) malloc(strlen(HWDI_LONGNAME) + 80);
+  longname = malloc(strlen(HWDI_LONGNAME) + 80);
   sprintf(longname, HWDI_LONGNAME, argN, argT);
   
   request.var1.name     = HWDI_NAME;
@@ -601,7 +617,7 @@ void *EcaHwfi(void *argument)
 
   if ( operatorArgc() > 0 ) argN = atoi(operatorArgv()[0]);
 
-  longname = (char *) malloc(strlen(HWFI_LONGNAME) + 40);
+  longname = malloc(strlen(HWFI_LONGNAME) + 40);
   sprintf(longname, HWFI_LONGNAME, argN);
 
   request.var1.name     = HWFI_NAME;
@@ -667,7 +683,7 @@ void *EcaSu(void *argument)
   cdoOperatorAdd("eca_su", 0, 31, NULL);
 
   if ( operatorArgc() > 0 ) argT = atof(operatorArgv()[0]);
-  longname = (char *) malloc(strlen(SU_LONGNAME) + 40);
+  longname = malloc(strlen(SU_LONGNAME) + 40);
   sprintf(longname, SU_LONGNAME, argT);
 
   request.var1.name     = SU_NAME;
@@ -802,7 +818,7 @@ void *EcaTr(void *argument)
   cdoOperatorAdd("eca_tr", 0, 31, NULL);
 
   if ( operatorArgc() > 0 ) argT = atof(operatorArgv()[0]);
-  longname = (char *) malloc(strlen(TR_LONGNAME) + 40);
+  longname = malloc(strlen(TR_LONGNAME) + 40);
   sprintf(longname, TR_LONGNAME, argT);
  
   request.var1.name     = TR_NAME;
@@ -1311,7 +1327,7 @@ void *EcaRx5day(void *argument)
   cdoInitialize(argument);
   if ( operatorArgc() > 0 ) argX = atof(operatorArgv()[0]);
   
-  longname = (char *) malloc(strlen(RX5DAY_LONGNAME2) + 40);
+  longname = malloc(strlen(RX5DAY_LONGNAME2) + 40);
   sprintf(longname, RX5DAY_LONGNAME2, argX);
   
   cdoOperatorAdd("eca_rx5day", 0, 31, NULL);
@@ -1415,7 +1431,7 @@ void *Strwin(void *argument)
   if ( operatorArgc() > 0 )
     maxWind = atof(operatorArgv()[0]);
 
-  longname = (char *) malloc(strlen(STRWIN_LONGNAME) + 40);
+  longname = malloc(strlen(STRWIN_LONGNAME) + 40);
   sprintf(longname, STRWIN_LONGNAME, maxWind);
          
   request.var1.name     = STRWIN_NAME;
diff --git a/src/Echam5ini.c b/src/Echam5ini.c
index a1394cf..6dff491 100644
--- a/src/Echam5ini.c
+++ b/src/Echam5ini.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -89,7 +89,7 @@ void inivar(VAR *var, int gridtype, int zaxistype, int code, const char *name,
 static
 void inivars_ml(VAR **vars)
 {
-  *vars = (VAR *) malloc((nvars_ml+1)*sizeof(VAR));
+  *vars = malloc((nvars_ml+1)*sizeof(VAR));
 
   inivar(&(*vars)[0], GRID_GAUSSIAN, ZAXIS_HYBRID,  133, "Q",   "specific humidity", "kg/kg");
   inivar(&(*vars)[1], GRID_SPECTRAL, ZAXIS_HYBRID,  138, "SVO", "vorticity", "1/s");
@@ -170,15 +170,15 @@ int import_e5ml(const char *filename, VAR **vars)
   zaxisIDsfc = zaxisCreate(ZAXIS_SURFACE, 1);
   zaxisIDml  = zaxisCreate(ZAXIS_HYBRID, nlev);
 
-  levs = (double *) malloc(nlev*sizeof(double));
+  levs = malloc(nlev*sizeof(double));
   for ( i = 0; i < nlev; i++ ) levs[i] = i+1;
   zaxisDefLevels(zaxisIDml, levs);
   free(levs);
 
   /* read variables */
 
-  xvals = (double *) malloc(nlon*sizeof(double));
-  yvals = (double *) malloc(nlat*sizeof(double));
+  xvals = malloc(nlon*sizeof(double));
+  yvals = malloc(nlat*sizeof(double));
 
   nce(nc_inq_varid(nc_file_id, "lon", &nc_var_id));
   nce(nc_get_var_double(nc_file_id, nc_var_id, xvals));
@@ -192,7 +192,7 @@ int import_e5ml(const char *filename, VAR **vars)
   free(xvals);
   free(yvals);
 
-  vct   = (double *) malloc(nvct*sizeof(double));
+  vct   = malloc(nvct*sizeof(double));
 
   nce(nc_inq_varid(nc_file_id, "vct_a", &nc_var_id));
   nce(nc_get_var_double(nc_file_id, nc_var_id, vct));
@@ -225,7 +225,7 @@ int import_e5ml(const char *filename, VAR **vars)
       (*vars)[iv].gridsize  = nvals;
       (*vars)[iv].nlev      = nlev;
 
-      (*vars)[iv].ptr = (double *) malloc(nlev*nvals*sizeof(double));
+      (*vars)[iv].ptr = malloc(nlev*nvals*sizeof(double));
       
       for ( i = 0; i < nlev; i++ )
 	{
@@ -255,7 +255,7 @@ int import_e5ml(const char *filename, VAR **vars)
   start[0] = 0;    start[1] = 0;  start[2] = nlev;
   count[0] = nsp;  count[1] = 2;  count[2] = 1;
 
-  (*vars)[nvars_ml].ptr = (double *) malloc(nsp*2*sizeof(double));
+  (*vars)[nvars_ml].ptr = malloc(nsp*2*sizeof(double));
 
   nce(nc_inq_varid(nc_file_id, "STP", &nc_var_id));
   nce(nc_get_vara_double(nc_file_id, nc_var_id, start, count, (*vars)[nvars_ml].ptr));
@@ -449,8 +449,8 @@ void export_e5ml(const char *filename, VAR *vars, int nvars, int vdate, int vtim
 
   /* define gaussian grid */
 
-  xvals = (double *) malloc(nlon*sizeof(double));
-  yvals = (double *) malloc(nlat*sizeof(double));
+  xvals = malloc(nlon*sizeof(double));
+  yvals = malloc(nlat*sizeof(double));
 
   gridInqXvals(gridIDgp, xvals);
   gridInqYvals(gridIDgp, yvals);
@@ -484,7 +484,7 @@ void export_e5ml(const char *filename, VAR *vars, int nvars, int vdate, int vtim
 
   nvct = nvclev*2;
 
-  /* vct   = (double *) malloc(nvct*sizeof(double)); */
+  /* vct   = malloc(nvct*sizeof(double)); */
 
   vct = zaxisInqVctPtr(zaxisIDml);
 
@@ -631,7 +631,7 @@ void read_gg3d(int nc_file_id, const char *name, VAR *var, int gridID, int zaxis
   var->gridsize  = gridsize;
   var->nlev      = nlev;
 
-  var->ptr = (double *) malloc(nlev*gridsize*sizeof(double));
+  var->ptr = malloc(nlev*gridsize*sizeof(double));
   
   for ( i = 0; i < nlev; i++ )
     {
@@ -668,7 +668,7 @@ void read_fc4d(int nc_file_id, const char *name, VAR *var, int gridID, int zaxis
   var->gridsize  = nfc;
   var->nlev      = nlev;
 
-  var->ptr = (double *) malloc(nlev*nfc*sizeof(double));
+  var->ptr = malloc(nlev*nfc*sizeof(double));
   
   for ( i = 0; i < nlev; i++ )
     {
@@ -794,8 +794,8 @@ int import_e5res(const char *filename, VAR **vars, ATTS *atts)
   gridDefXsize(gridIDgp, nlon);
   gridDefYsize(gridIDgp, nlat);
 
-  xvals = (double *) malloc(nlon*sizeof(double));
-  yvals = (double *) malloc(nlat*sizeof(double));
+  xvals = malloc(nlon*sizeof(double));
+  yvals = malloc(nlat*sizeof(double));
 
   nce(nc_inq_varid(nc_file_id, "lon", &nc_var_id));
   nce(nc_get_var_double(nc_file_id, nc_var_id, xvals));
@@ -829,7 +829,7 @@ int import_e5res(const char *filename, VAR **vars, ATTS *atts)
   nlev = belowsurface;
   zaxisIDbsfc = zaxisCreate(ZAXIS_DEPTH_BELOW_LAND, nlev);
 
-  levs = (double *) malloc(nlev*sizeof(double));
+  levs = malloc(nlev*sizeof(double));
   for ( i = 0; i < nlev; i++ ) levs[i] = 0;
   zaxisDefLevels(zaxisIDbsfc, levs);
   free(levs);
@@ -840,7 +840,7 @@ int import_e5res(const char *filename, VAR **vars, ATTS *atts)
   nlev = n2;
   zaxisIDn2 = zaxisCreate(ZAXIS_GENERIC, nlev);
 
-  levs = (double *) malloc(nlev*sizeof(double));
+  levs = malloc(nlev*sizeof(double));
   for ( i = 0; i < nlev; i++ ) levs[i] = 0;
   zaxisDefLevels(zaxisIDn2, levs);
   free(levs);
@@ -850,7 +850,7 @@ int import_e5res(const char *filename, VAR **vars, ATTS *atts)
   nlev = lev;
   nvct = nvclev*2;
 
-  vct   = (double *) malloc(nvct*sizeof(double));
+  vct   = malloc(nvct*sizeof(double));
 
   nce(nc_inq_varid(nc_file_id, "vct_a", &nc_var_id));
   nce(nc_get_var_double(nc_file_id, nc_var_id, vct));
@@ -862,7 +862,7 @@ int import_e5res(const char *filename, VAR **vars, ATTS *atts)
 
   zaxisIDml  = zaxisCreate(ZAXIS_HYBRID, nlev);
 
-  levs = (double *) malloc(nlev*sizeof(double));
+  levs = malloc(nlev*sizeof(double));
   for ( i = 0; i < nlev; i++ ) levs[i] = i+1;
   zaxisDefLevels(zaxisIDml, levs);
   free(levs);
@@ -873,7 +873,7 @@ int import_e5res(const char *filename, VAR **vars, ATTS *atts)
 
   zaxisIDmlh  = zaxisCreate(ZAXIS_HYBRID_HALF, nlevp1);
 
-  levs = (double *) malloc(nlevp1*sizeof(double));
+  levs = malloc(nlevp1*sizeof(double));
   for ( i = 0; i < nlevp1; i++ ) levs[i] = i;
   zaxisDefLevels(zaxisIDmlh, levs);
   free(levs);
@@ -930,7 +930,7 @@ int import_e5res(const char *filename, VAR **vars, ATTS *atts)
 	}
     }
 
-  *vars = (VAR *) malloc(max_vars*sizeof(VAR));
+  *vars = malloc(max_vars*sizeof(VAR));
 
   varid = 0;
   for ( ncvarid = 0; ncvarid < nvars; ncvarid++ )
@@ -1002,7 +1002,7 @@ int import_e5res(const char *filename, VAR **vars, ATTS *atts)
 	      (*vars)[varid].gridsize  = nvals;
 	      (*vars)[varid].nlev      = 1;
 
-	      (*vars)[varid].ptr = (double *) malloc(nvals*sizeof(double));
+	      (*vars)[varid].ptr = malloc(nvals*sizeof(double));
 
 	      nce(nc_inq_varid(nc_file_id, name, &nc_var_id));
 	      nce(nc_get_var_double(nc_file_id, nc_var_id, (*vars)[varid].ptr));
@@ -1020,7 +1020,7 @@ int import_e5res(const char *filename, VAR **vars, ATTS *atts)
 	      (*vars)[varid].gridsize  = nvals;
 	      (*vars)[varid].nlev      = nlev;
 
-	      (*vars)[varid].ptr = (double *) malloc(nvals*nlev*sizeof(double));
+	      (*vars)[varid].ptr = malloc(nvals*nlev*sizeof(double));
 
 	      for ( i = 0; i < nlev; i++ )
 		{
@@ -1369,8 +1369,8 @@ void export_e5res(const char *filename, VAR *vars, int nvars)
   nlon = lon;
   nlat = lat;
 
-  xvals = (double *) malloc(nlon*sizeof(double));
-  yvals = (double *) malloc(nlat*sizeof(double));
+  xvals = malloc(nlon*sizeof(double));
+  yvals = malloc(nlat*sizeof(double));
 
   gridInqXvals(gridIDgp, xvals);
   gridInqYvals(gridIDgp, yvals);
@@ -1394,7 +1394,7 @@ void export_e5res(const char *filename, VAR *vars, int nvars)
   nlev = lev;
   nvct = nvclev*2;
 
-  /* vct   = (double *) malloc(nvct*sizeof(double)); */
+  /* vct   = malloc(nvct*sizeof(double)); */
 
   vct = zaxisInqVctPtr(zaxisIDml);
 
@@ -1530,7 +1530,7 @@ void *Echam5ini(void *argument)
 
       nvars = vlistNvars(vlistID1);
 
-      vars = (VAR *) malloc(nvars*sizeof(VAR));
+      vars = malloc(nvars*sizeof(VAR));
 
       for ( varID = 0; varID < nvars; ++varID )
 	{
@@ -1581,7 +1581,7 @@ void *Echam5ini(void *argument)
 	  vars[varID].gridsize  = gridsize;
 	  vars[varID].nlev      = nlev;
 
-	  vars[varID].ptr = (double *) malloc(nlev*gridsize*sizeof(double));
+	  vars[varID].ptr = malloc(nlev*gridsize*sizeof(double));
 	}
 
       nrecs = streamInqTimestep(streamID1, 0);
diff --git a/src/Enlarge.c b/src/Enlarge.c
index a65ae6d..fb5ece5 100644
--- a/src/Enlarge.c
+++ b/src/Enlarge.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -77,8 +77,8 @@ void *Enlarge(void *argument)
 
   streamDefVlist(streamID2, vlistID2);
 
-  array1 = (double *) malloc(gridsize2*sizeof(double));
-  array2 = (double *) malloc(gridsize2*sizeof(double));
+  array1 = malloc(gridsize2*sizeof(double));
+  array2 = malloc(gridsize2*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Enlargegrid.c b/src/Enlargegrid.c
index b8645d2..c541a83 100644
--- a/src/Enlargegrid.c
+++ b/src/Enlargegrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -69,13 +69,13 @@ void gen_index(int gridID1, int gridID2, int *index)
       if ( ! (gridInqXvals(gridID2, NULL) && gridInqYvals(gridID2, NULL)) )
 	cdoAbort("Grid 2 has no values!");
 
-      xvals1 = (double *) malloc(nlon1*sizeof(double));
-      yvals1 = (double *) malloc(nlat1*sizeof(double));
-      xvals2 = (double *) malloc(nlon2*sizeof(double));
-      yvals2 = (double *) malloc(nlat2*sizeof(double));
+      xvals1 = malloc(nlon1*sizeof(double));
+      yvals1 = malloc(nlat1*sizeof(double));
+      xvals2 = malloc(nlon2*sizeof(double));
+      yvals2 = malloc(nlat2*sizeof(double));
 
-      xindex = (int *) malloc(nlon2*sizeof(int));
-      yindex = (int *) malloc(nlat2*sizeof(int));
+      xindex = malloc(nlon2*sizeof(int));
+      yindex = malloc(nlat2*sizeof(int));
 
       gridInqXvals(gridID1, xvals1);
       gridInqYvals(gridID1, yvals1);
@@ -209,9 +209,9 @@ void *Enlargegrid(void *argument)
   gridsize1 = gridInqSize(gridID1);
   gridsize2 = gridInqSize(gridID2);
 
-  array1 = (double *) malloc(gridsize1*sizeof(double));
-  array2 = (double *) malloc(gridsize2*sizeof(double));
-  gindex = (int *) malloc(gridsize1*sizeof(int));
+  array1 = malloc(gridsize1*sizeof(double));
+  array2 = malloc(gridsize2*sizeof(double));
+  gindex = malloc(gridsize1*sizeof(int));
 
   gen_index(gridID2, gridID1, gindex);
 
diff --git a/src/Ensstat.c b/src/Ensstat.c
index c68d591..a95cfe7 100644
--- a/src/Ensstat.c
+++ b/src/Ensstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -108,15 +108,15 @@ void *Ensstat(void *argument)
       if ( !userFileOverwrite(ofilename) )
 	cdoAbort("Outputfile %s already exists!", ofilename);
 
-  ef = (ens_file_t *) malloc(nfiles*sizeof(ens_file_t));
+  ef = malloc(nfiles*sizeof(ens_file_t));
 
-  field = (field_t *) malloc(ompNumThreads*sizeof(field_t));
+  field = malloc(ompNumThreads*sizeof(field_t));
   for ( i = 0; i < ompNumThreads; i++ )
     {
       field_init(&field[i]);
       field[i].size   = nfiles;
-      field[i].ptr    = (double *) malloc(nfiles*sizeof(double));
-      field[i].weight = (double *) malloc(nfiles*sizeof(double));
+      field[i].ptr    = malloc(nfiles*sizeof(double));
+      field[i].weight = malloc(nfiles*sizeof(double));
       for ( fileID = 0; fileID < nfiles; fileID++ )
 	field[i].weight[fileID] = 1;
     }
@@ -148,9 +148,9 @@ void *Ensstat(void *argument)
   gridsize = vlistGridsizeMax(vlistID1);
 
   for ( fileID = 0; fileID < nfiles; fileID++ )
-    ef[fileID].array = (double *) malloc(gridsize*sizeof(double));
+    ef[fileID].array = malloc(gridsize*sizeof(double));
 
-  array2 = (double *) malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   do
diff --git a/src/Ensstat3.c b/src/Ensstat3.c
index 0d3534c..6f16560 100644
--- a/src/Ensstat3.c
+++ b/src/Ensstat3.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -57,7 +57,7 @@ void *Ensstat3(void *argument)
   int operatorID;
   int operfunc, datafunc;
   int i,j;
-  int nvars,nbins, nrecs = 0, nrecs0, nmiss, nens, nfiles;;
+  int nvars,nbins, nrecs = 0, nrecs0, nmiss, nens, nfiles;
   int cum;
   int chksum;                  // for check of histogram population 
   int levelID, varID, recID, tsID, binID = 0;
@@ -121,7 +121,7 @@ void *Ensstat3(void *argument)
       if ( !userFileOverwrite(ofilename) )
 	cdoAbort("Outputfile %s already exists!", ofilename);
 
-  ef = (ens_file_t *) malloc(nfiles*sizeof(ens_file_t));
+  ef = malloc(nfiles*sizeof(ens_file_t));
 
   /* *************************************************** */
   /* should each thread be allocating memory locally???? */
@@ -129,17 +129,17 @@ void *Ensstat3(void *argument)
   /* --> #pragma omp parallel for ...                    */
   /* *************************************************** */
 #if defined(_OPENMP)
-  field = (field_t *) malloc(omp_get_max_threads()*sizeof(field_t));
+  field = malloc(omp_get_max_threads()*sizeof(field_t));
   for ( i = 0; i < omp_get_max_threads(); i++ )
 #else
-  field = (field_t *) malloc(1*sizeof(field_t));
+  field = malloc(1*sizeof(field_t));
   for ( i = 0; i < 1; i++ )
 #endif
     {
       field_init(&field[i]);
       field[i].size   = nfiles;
-      field[i].ptr    = (double *) malloc(nfiles*sizeof(double));
-      field[i].weight = (double *) malloc(nfiles*sizeof(double));
+      field[i].ptr    = malloc(nfiles*sizeof(double));
+      field[i].weight = malloc(nfiles*sizeof(double));
       for ( fileID = 0; fileID < nfiles; fileID++ )
 	field[i].weight[fileID] = 1;
     }
@@ -161,9 +161,9 @@ void *Ensstat3(void *argument)
   vlistID1 = ef[0].vlistID;
   vlistID2 = vlistCreate();
   nvars = vlistNvars(vlistID1);
-  varID2 = (int *) malloc(nvars*sizeof(int));
+  varID2 = malloc(nvars*sizeof(int));
 
-  levs = (double*) calloc (nfiles, sizeof(double) );
+  levs = calloc (nfiles, sizeof(double) );
   zaxisID2 = zaxisCreate(ZAXIS_GENERIC, nfiles);
   for ( i=0; i<nfiles; i++ )
     levs[i] = i;
@@ -217,37 +217,37 @@ void *Ensstat3(void *argument)
   gridsize = vlistGridsizeMax(vlistID1);
 
   for ( fileID = 0; fileID < nfiles; fileID++ )
-    ef[fileID].array = (double *) malloc(gridsize*sizeof(double));
+    ef[fileID].array = malloc(gridsize*sizeof(double));
 
   if ( operfunc == func_rank && datafunc == SPACE ) 
     { /*need to memorize data for entire grid before writing          */
-      array2 = (int **) malloc((nfiles+1)*sizeof(int*));
+      array2 = malloc((nfiles+1)*sizeof(int*));
       for ( binID=0; binID<nfiles; binID++ ) 
-	array2[binID] = (int*) calloc ( gridsize, sizeof(int) );
+	array2[binID] = calloc ( gridsize, sizeof(int) );
     }
   else if ( operfunc == func_rank )
     {  /* can process data separately for each timestep and only need */
        /* to cumulate values over the grid                            */
-      array2    = (int**) malloc ( (nfiles+1)*sizeof(int *));
+      array2    = malloc ( (nfiles+1)*sizeof(int *));
       for ( binID=0; binID<nfiles; binID++ )
-	array2[binID] = (int *) calloc ( 1, sizeof(int) );
+	array2[binID] = calloc ( 1, sizeof(int) );
     }
 
   if ( operfunc == func_roc ) {
-    ctg_tab = (int **)    malloc ((nbins+1)*sizeof(int*) );
-    hist =    (int *)     malloc ( nbins*sizeof(int) );
-    uThresh = (double *)  malloc ( nbins*sizeof(double) );
-    lThresh = (double *)  malloc ( nbins*sizeof(double) );
-    roc     = (double **) malloc ((nbins+1)*sizeof(double*) );
+    ctg_tab = malloc ((nbins+1)*sizeof(int*) );
+    hist =    malloc ( nbins*sizeof(int) );
+    uThresh = malloc ( nbins*sizeof(double) );
+    lThresh = malloc ( nbins*sizeof(double) );
+    roc     = malloc ((nbins+1)*sizeof(double*) );
     
     for  ( i=0; i<nbins; i++ ) {
-      ctg_tab[i] = (int *) calloc ( 4,sizeof(int) );
-      roc[i]     = (double*)calloc( 2,sizeof(double));
+      ctg_tab[i] = calloc ( 4,sizeof(int) );
+      roc[i]     = calloc( 2,sizeof(double));
       uThresh[i] = ((double)i+1)/nbins;
       lThresh[i] = (double)i/nbins;
     }
-    ctg_tab[nbins] = (int *)   calloc (4,sizeof(int));
-    roc[nbins]     = (double*) calloc (2,sizeof(double));
+    ctg_tab[nbins] = calloc (4,sizeof(int));
+    roc[nbins]     = calloc (2,sizeof(double));
   }
   
   
@@ -451,7 +451,7 @@ void *Ensstat3(void *argument)
       int osize = gridsize;
 
       if ( datafunc == TIME ) osize = 1;
-      tmpdoub = (double *) malloc(osize*sizeof(double));
+      tmpdoub = malloc(osize*sizeof(double));
 
       for ( binID = 0; binID < nfiles; binID++ )
 	{
diff --git a/src/Ensval.c b/src/Ensval.c
index 7ea7619..d4607ae 100644
--- a/src/Ensval.c
+++ b/src/Ensval.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -118,31 +118,31 @@ void *Ensval(void *argument)
   }
 
   // allocate array to hold results 
-  r = (double *) malloc ( nostreams*sizeof(double) );
+  r = malloc ( nostreams*sizeof(double) );
   
 
   // one stream for each value of the decomposition
-  streamID2 = (int *) malloc ( nostreams*sizeof(int) );
-  vlistID2 = (int *) malloc ( nostreams*sizeof(int) );
-  taxisID2 = (int *) malloc ( nostreams*sizeof(int) );
-  zaxisID2 = (int *) malloc ( nostreams*sizeof(int) );
+  streamID2 = malloc ( nostreams*sizeof(int) );
+  vlistID2 = malloc ( nostreams*sizeof(int) );
+  taxisID2 = malloc ( nostreams*sizeof(int) );
+  zaxisID2 = malloc ( nostreams*sizeof(int) );
 
-  val = (double *) calloc ( nfiles,sizeof(double) );
+  val = calloc ( nfiles,sizeof(double) );
   
   if ( operfunc == CRPS ) {
-    alpha=(double *) calloc ( nens+1,sizeof(double) );
-    beta =(double *) calloc ( nens+1,sizeof(double) );
-    alpha_weights=(double *) calloc ( nens+1,sizeof(double) );
-    beta_weights =(double *) calloc ( nens+1,sizeof(double) );
+    alpha=calloc ( nens+1,sizeof(double) );
+    beta =calloc ( nens+1,sizeof(double) );
+    alpha_weights=calloc ( nens+1,sizeof(double) );
+    beta_weights =calloc ( nens+1,sizeof(double) );
   }
   else if ( operfunc == BRS ) {
-    brs_g = (double *) calloc ( nens+1,sizeof(double) );
-    brs_o = (double *) calloc ( nens+1,sizeof(double) );
+    brs_g = calloc ( nens+1,sizeof(double) );
+    brs_o = calloc ( nens+1,sizeof(double) );
   }
   if ( cdoVerbose )
     cdoPrint("Ensemble over %d files (Ensstat5).", nfiles-1);
 
-  ef = (ens_file_t *) malloc(nfiles*sizeof(ens_file_t));
+  ef = malloc(nfiles*sizeof(ens_file_t));
   
   for ( fileID = 0; fileID < nfiles; fileID++ )
     {
@@ -203,7 +203,7 @@ void *Ensval(void *argument)
       break;
     }
 
-    ofilename = (char *) calloc(namelen, sizeof(char));
+    ofilename = calloc(namelen, sizeof(char));
 
     sprintf(ofilename, "%s.%s%s", ofilebase, type_suffix, file_suffix);
     // fprintf(stderr, "StreamID %i: %s\n", stream, ofilename);
@@ -270,11 +270,11 @@ void *Ensval(void *argument)
 		  missval  = vlistInqVarMissval(vlistID1, varID);
 		  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));//vlistGridsizeMax(vlistID1);
 		  if ( weights ) free(weights); 
-		  weights=(double*) malloc (gridsize*sizeof(double));
+		  weights=malloc (gridsize*sizeof(double));
 		}
 
 	      if (ef[fileID].array ) free(ef[fileID].array);
-	      ef[fileID].array = (double *) malloc(gridsize*sizeof(double));
+	      ef[fileID].array = malloc(gridsize*sizeof(double));
 
 	      streamID = ef[fileID].streamID;
 	      streamReadRecord(streamID, ef[fileID].array, &nmiss);
diff --git a/src/Eof3d.c b/src/Eof3d.c
index dffb4ad..4a31789 100644
--- a/src/Eof3d.c
+++ b/src/Eof3d.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -36,6 +36,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
+#include "grid.h"
 #include "statistic.h"
 
 
@@ -144,7 +145,7 @@ void *EOF3d(void * argument)
   nvars       = vlistNvars(vlistID1);
   nrecs       = vlistNrecs(vlistID1);
   taxisID1    = vlistInqTaxis(vlistID1);
-  weight      = (double*) malloc(gridsize*sizeof(double));
+  weight      = malloc(gridsize*sizeof(double));
   if ( WEIGHTS )
       gridWeights(gridID1, &weight[0]);
   else
@@ -160,9 +161,9 @@ void *EOF3d(void * argument)
   gridID2     = gridCreate(GRID_LONLAT, 1);
   gridDefXsize(gridID2, 1);
   gridDefYsize(gridID2, 1);
-  xvals       = (double*) malloc(1*sizeof(double));
-  yvals       = (double*) malloc(1*sizeof(double));
-  zvals       = (double*) malloc(1*sizeof(double));
+  xvals       = malloc(1*sizeof(double));
+  yvals       = malloc(1*sizeof(double));
+  zvals       = malloc(1*sizeof(double));
   xvals[0]    = 0;
   yvals[0]    = 0;
   zvals[0]    = 0;
@@ -179,7 +180,7 @@ void *EOF3d(void * argument)
   taxisDefRtime(taxisID2, 0);
   vlistDefTaxis(vlistID2, taxisID2);
 
-  varID2 = (int *) malloc (nvars*sizeof(int));
+  varID2 = malloc (nvars*sizeof(int));
   for ( varID=0; varID<nvars; varID++ )
     varID2[varID] = vlistDefVar(vlistID2, gridID2, zaxisID2, TSTEP_INSTANT);
   ngrids      = vlistNgrids(vlistID2);
@@ -242,11 +243,11 @@ void *EOF3d(void * argument)
   if ( cdoTimer ) timer_start(timer_alloc);
 
   /* allocation of temporary fields and output structures */
-  in.ptr       = (double *)   malloc(gridsize*sizeof(double));
-  datafields   = (field_t **) malloc(nvars*sizeof(field_t*));
-  datacounts   = (int     **) malloc(nvars*sizeof(int *));
-  eigenvectors = (field_t **) malloc(nvars*sizeof(field_t*));
-  eigenvalues  = (field_t **) malloc(nvars*sizeof(field_t*));
+  in.ptr       = malloc(gridsize*sizeof(double));
+  datafields   = malloc(nvars*sizeof(field_t*));
+  datacounts   = malloc(nvars*sizeof(int *));
+  eigenvectors = malloc(nvars*sizeof(field_t*));
+  eigenvalues  = malloc(nvars*sizeof(field_t*));
 
   for ( varID = 0; varID < nvars; ++varID )
     {
@@ -256,26 +257,26 @@ void *EOF3d(void * argument)
       temp_size           = gridsize * nlevs;
       missval             = vlistInqVarMissval(vlistID1, varID);
 
-      datafields[varID]   = (field_t *) malloc(nlevs*sizeof(field_t*));
-      datacounts[varID]   = (int *)     malloc(nlevs*sizeof(int* ));
-      eigenvectors[varID] = (field_t *) malloc(nlevs*sizeof(field_t*));
+      datafields[varID]   = malloc(nlevs*sizeof(field_t*));
+      datacounts[varID]   = malloc(nlevs*sizeof(int* ));
+      eigenvectors[varID] = malloc(nlevs*sizeof(field_t*));
 
-      datafields[varID] = (field_t *) malloc(nts*sizeof(field_t));
+      datafields[varID] = malloc(nts*sizeof(field_t));
       for ( tsID = 0; tsID < nts; tsID++ )
 	{
 	  datafields[varID][tsID].grid    = gridID1;
 	  datafields[varID][tsID].nmiss   = 0;
 	  datafields[varID][tsID].missval = missval;
-	  datafields[varID][tsID].ptr     = (double *) malloc(temp_size*sizeof(double));
+	  datafields[varID][tsID].ptr     = malloc(temp_size*sizeof(double));
 	  for ( i = 0; i < temp_size; ++i )
 	    datafields[varID][tsID].ptr[i] = 0;
 	}
-      datacounts[varID] = (int *) malloc(temp_size*sizeof(int));	      
+      datacounts[varID] = malloc(temp_size*sizeof(int));	      
       for(i=0;i<temp_size;i++)
 	datacounts[varID][i] = 0;
       
-      eigenvectors[varID] = (field_t *) malloc(n_eig*sizeof(field_t));
-      eigenvalues[varID]  = (field_t *) malloc(nts*sizeof(field_t));
+      eigenvectors[varID] = malloc(n_eig*sizeof(field_t));
+      eigenvalues[varID]  = malloc(nts*sizeof(field_t));
 
       for ( i = 0; i < n; i++ )
 	{
@@ -284,7 +285,7 @@ void *EOF3d(void * argument)
 	      eigenvectors[varID][i].grid    = gridID2;
 	      eigenvectors[varID][i].nmiss   = 0;
 	      eigenvectors[varID][i].missval = missval;
-	      eigenvectors[varID][i].ptr     = (double *) malloc(temp_size*sizeof(double));
+	      eigenvectors[varID][i].ptr     = malloc(temp_size*sizeof(double));
 	      for ( i2 = 0; i2 < temp_size; ++i2 )
 		eigenvectors[varID][i].ptr[i2] = missval;
 	    }
@@ -292,7 +293,7 @@ void *EOF3d(void * argument)
 	  eigenvalues[varID][i].grid    = gridID3;
 	  eigenvalues[varID][i].nmiss   = 0;
 	  eigenvalues[varID][i].missval = missval;
-	  eigenvalues[varID][i].ptr     = (double *) malloc(1*sizeof(double));
+	  eigenvalues[varID][i].ptr     = malloc(1*sizeof(double));
 	  eigenvalues[varID][i].ptr[0]  = missval;
 	}
     }
@@ -354,8 +355,8 @@ void *EOF3d(void * argument)
   if ( cdoVerbose ) 
     cdoPrint("Read data for %i variables",nvars);
   
-  pack = (int *) malloc(temp_size*sizeof(int)); //TODO
-  miss = (int *) malloc(temp_size*sizeof(int));
+  pack = malloc(temp_size*sizeof(int)); //TODO
+  miss = malloc(temp_size*sizeof(int));
 
   if ( cdoTimer ) timer_stop(timer_read);
 
@@ -396,10 +397,10 @@ void *EOF3d(void * argument)
       }
 
 	  
-      cov = (double **) malloc (nts*sizeof(double*));
+      cov = malloc (nts*sizeof(double*));
       for ( j1 = 0; j1 < nts; j1++)
-	cov[j1] = (double*) malloc(nts*sizeof(double));
-      eigv = (double *) malloc(n*sizeof(double));
+	cov[j1] = malloc(nts*sizeof(double));
+      eigv = malloc(n*sizeof(double));
 
       if ( cdoVerbose )  {
 	cdoPrint("varID %i allocated eigv and cov with nts=%i and n=%i",varID,nts,n);
diff --git a/src/Eofcoeff.c b/src/Eofcoeff.c
index 7596d0a..631a435 100644
--- a/src/Eofcoeff.c
+++ b/src/Eofcoeff.c
@@ -2,7 +2,7 @@
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.
  
- Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+ Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
  See COPYING file for copying and redistribution conditions.
  
  This program is free software; you can redistribute it and/or modify
@@ -26,6 +26,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
+#include "grid.h"
 
 
 // NO MISSING VALUE SUPPORT ADDED SO FAR
@@ -84,7 +85,7 @@ void *Eofcoeff(void * argument)
   nvars = vlistNvars(vlistID1)==vlistNvars(vlistID2) ? vlistNvars(vlistID1) : -1;
   nrecs = vlistNrecs(vlistID1); 
   nlevs = zaxisInqSize(vlistInqVarZaxis(vlistID1, 0));
-  w = (double*)malloc(gridsize*sizeof(double));
+  w = malloc(gridsize*sizeof(double));
   gridWeights(gridID2, &w[0]);
   
   
@@ -101,9 +102,9 @@ void *Eofcoeff(void * argument)
   filesuffix[0] = 0;
   cdoGenFileSuffix(filesuffix, sizeof(filesuffix), streamInqFiletype(streamID1), vlistID1, refname);
   
-  eof = (field_t ***) malloc (nvars * sizeof(field_t**) );
+  eof = malloc (nvars * sizeof(field_t**) );
   for ( varID=0; varID<nvars; varID++)
-    eof[varID] = (field_t **) malloc(nlevs*sizeof(field_t*));
+    eof[varID] = malloc(nlevs*sizeof(field_t*));
   reached_eof=0;
   eofID = 0;
   while ( 1 )       
@@ -119,13 +120,13 @@ void *Eofcoeff(void * argument)
          streamInqRecord(streamID1, &varID, &levelID);
          missval1 = vlistInqVarMissval(vlistID1, varID);
          if ( eofID == 0 )
-           eof[varID][levelID] = (field_t*) malloc (1*sizeof(field_t));
+           eof[varID][levelID] = malloc (1*sizeof(field_t));
          else
-           eof[varID][levelID] = (field_t*) realloc (eof[varID][levelID], (eofID+1)*sizeof(field_t));
+           eof[varID][levelID] = realloc (eof[varID][levelID], (eofID+1)*sizeof(field_t));
          eof[varID][levelID][eofID].grid   = gridID1;
          eof[varID][levelID][eofID].nmiss  = 0;
          eof[varID][levelID][eofID].missval= missval1;
-         eof[varID][levelID][eofID].ptr    = (double*)malloc(gridsize*sizeof(double));
+         eof[varID][levelID][eofID].ptr    = malloc(gridsize*sizeof(double));
          memset(&eof[varID][levelID][eofID].ptr[0], missval1, gridsize*sizeof(double));
          if ( varID >= nvars )
            cdoAbort("Internal error - too high varID");
@@ -144,8 +145,8 @@ void *Eofcoeff(void * argument)
   gridID3 = gridCreate(GRID_LONLAT, 1);
   gridDefXsize(gridID3, 1);
   gridDefYsize(gridID3, 1);
-  xvals=(double*)malloc(1*sizeof(double));
-  yvals=(double*)malloc(1*sizeof(double));
+  xvals=malloc(1*sizeof(double));
+  yvals=malloc(1*sizeof(double));
   xvals[0]=0;
   yvals[0]=0;
   gridDefXvals(gridID3, xvals);
@@ -163,7 +164,7 @@ void *Eofcoeff(void * argument)
     vlistDefVarTsteptype(vlistID3, varID, TSTEP_INSTANT);
   
   // open streams for eofcoeff output
-  streamIDs = (int *) malloc (neof*sizeof(int)); 
+  streamIDs = malloc (neof*sizeof(int)); 
   eofID = 0;
   for ( eofID = 0; eofID < neof; eofID++)
     {
@@ -186,11 +187,11 @@ void *Eofcoeff(void * argument)
     }
   
   // ALLOCATE temporary fields for data read and write
-  in.ptr = (double*) malloc(gridsize*sizeof(double));
+  in.ptr = malloc(gridsize*sizeof(double));
   in.grid = gridID1;  
   out.missval = missval1;
   out.nmiss = 0;
-  out.ptr = (double *) malloc (1*sizeof(double));
+  out.ptr = malloc (1*sizeof(double));
  
   // 
   reached_eof=0;
diff --git a/src/Eofcoeff3d.c b/src/Eofcoeff3d.c
index 3049311..78e2aee 100644
--- a/src/Eofcoeff3d.c
+++ b/src/Eofcoeff3d.c
@@ -2,7 +2,7 @@
  This file is part of CDO. CDO is a collection of Operators to
  manipulate and analyse Climate model Data.
  
- Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+ Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
  See COPYING file for copying and redistribution conditions.
  
  This program is free software; you can redistribute it and/or modify
@@ -26,6 +26,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
+#include "grid.h"
 
 
 // NO MISSING VALUE SUPPORT ADDED SO FAR
@@ -84,7 +85,7 @@ void *Eofcoeff3d(void * argument)
   nvars = vlistNvars(vlistID1)==vlistNvars(vlistID2) ? vlistNvars(vlistID1) : -1;
   nrecs = vlistNrecs(vlistID1); 
   nlevs = zaxisInqSize(vlistInqVarZaxis(vlistID1, 0));
-  w = (double*)malloc(gridsize*sizeof(double));
+  w = malloc(gridsize*sizeof(double));
   gridWeights(gridID2, &w[0]);
   
   
@@ -99,9 +100,9 @@ void *Eofcoeff3d(void * argument)
   filesuffix[0] = 0;
   cdoGenFileSuffix(filesuffix, sizeof(filesuffix), streamInqFiletype(streamID1), vlistID1, refname);
  
-  eof = (field_t ***) malloc (nvars * sizeof(field_t**) );
+  eof = malloc (nvars * sizeof(field_t**) );
   for ( varID=0; varID<nvars; varID++)
-    eof[varID] = (field_t **) malloc(nlevs*sizeof(field_t*));
+    eof[varID] = malloc(nlevs*sizeof(field_t*));
   reached_eof=0;
   eofID = 0;
   while ( 1 )       
@@ -117,13 +118,13 @@ void *Eofcoeff3d(void * argument)
          streamInqRecord(streamID1, &varID, &levelID);
          missval1 = vlistInqVarMissval(vlistID1, varID);
          if ( eofID == 0 )
-           eof[varID][levelID] = (field_t*) malloc (1*sizeof(field_t));
+           eof[varID][levelID] = malloc (1*sizeof(field_t));
          else
-           eof[varID][levelID] = (field_t*) realloc (eof[varID][levelID], (eofID+1)*sizeof(field_t));
+           eof[varID][levelID] = realloc (eof[varID][levelID], (eofID+1)*sizeof(field_t));
          eof[varID][levelID][eofID].grid   = gridID1;
          eof[varID][levelID][eofID].nmiss  = 0;
          eof[varID][levelID][eofID].missval= missval1;
-         eof[varID][levelID][eofID].ptr    = (double*)malloc(gridsize*sizeof(double));
+         eof[varID][levelID][eofID].ptr    = malloc(gridsize*sizeof(double));
          memset(&eof[varID][levelID][eofID].ptr[0], missval1, gridsize*sizeof(double));
 
          if ( varID >= nvars )
@@ -143,14 +144,14 @@ void *Eofcoeff3d(void * argument)
   gridID3 = gridCreate(GRID_LONLAT, 1);
   gridDefXsize(gridID3, 1);
   gridDefYsize(gridID3, 1);
-  xvals=(double*)malloc(1*sizeof(double));
-  yvals=(double*)malloc(1*sizeof(double));
+  xvals=malloc(1*sizeof(double));
+  yvals=malloc(1*sizeof(double));
   xvals[0]=0;
   yvals[0]=0;
   gridDefXvals(gridID3, xvals);
   gridDefYvals(gridID3, yvals);
   
-  zvals = (double *) malloc ( 1* sizeof(double ) );
+  zvals = malloc ( 1* sizeof(double ) );
   zvals[0] = 0.;
   zaxisID3 = zaxisCreate(ZAXIS_GENERIC,1);
   zaxisDefLevels(zaxisID3,zvals);
@@ -159,12 +160,12 @@ void *Eofcoeff3d(void * argument)
   
   vlistID3 = vlistCreate();
   vlistDefTaxis(vlistID3,taxisID3);
-  varID3 = (int *) malloc ( nvars * sizeof(int) );
+  varID3 = malloc ( nvars * sizeof(int) );
   for ( varID=0; varID<nvars; varID++ )
     varID3[varID] = vlistDefVar(vlistID3, gridID3, zaxisID3, TSTEP_INSTANT);
   
   // open streams for eofcoeff output
-  streamIDs = (int *) malloc (neof*sizeof(int)); 
+  streamIDs = malloc (neof*sizeof(int)); 
   eofID = 0;
   for ( eofID = 0; eofID < neof; eofID++)
     {
@@ -186,15 +187,15 @@ void *Eofcoeff3d(void * argument)
     }
   
   // ALLOCATE temporary fields for data read and write
-  in.ptr = (double*) malloc(gridsize*sizeof(double));
+  in.ptr = malloc(gridsize*sizeof(double));
   in.grid = gridID1;  
-  out = (field_t **) malloc (nvars*sizeof(field_t*));
+  out = malloc (nvars*sizeof(field_t*));
   for ( varID = 0; varID < nvars; varID++ ) {
-    out[varID] = (field_t*) malloc ( neof * sizeof(field_t) );
+    out[varID] = malloc ( neof * sizeof(field_t) );
     for ( eofID=0; eofID<neof; eofID++ ) {
       out[varID][eofID].missval = missval1;
       out[varID][eofID].nmiss = 0;
-      out[varID][eofID].ptr = (double *) malloc (1*sizeof(double));
+      out[varID][eofID].ptr = malloc (1*sizeof(double));
     }
   }
 
diff --git a/src/Exprf.c b/src/Exprf.c
index 32c228e..338a601 100644
--- a/src/Exprf.c
+++ b/src/Exprf.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -83,7 +83,7 @@ void *Expr(void *argument)
       size_t slen;
 
       slen = strlen(operatorArgv()[0]);
-      exprs = (char *) malloc(slen+2);
+      exprs = malloc(slen+2);
       strcpy(exprs, operatorArgv()[0]);
       if ( exprs[slen-1] != ';' )
 	{
@@ -106,7 +106,7 @@ void *Expr(void *argument)
       if ( stat(exprf, &filestat) != 0 ) cdoAbort("Stat failed on %s", exprf);
 
       fsize = (size_t) filestat.st_size;
-      exprs = (char *) malloc(fsize+1);
+      exprs = malloc(fsize+1);
 
       while ( (ichar = fgetc(fp)) != EOF ) exprs[ipos++] = ichar;
 
@@ -136,6 +136,7 @@ void *Expr(void *argument)
   parse_arg.vlistID2 = vlistID2;
   parse_arg.nvars1   = 0;
   parse_arg.debug    = 0;
+  if ( cdoVerbose ) parse_arg.debug    = 1;
   parse_arg.gridID2  = -1;
   parse_arg.zaxisID2 = -1;
   parse_arg.tsteptype2  = -1;
@@ -165,8 +166,8 @@ void *Expr(void *argument)
 
   streamDefVlist(streamID2, vlistID2);
 
-  parse_arg.vardata1 = (double **) malloc(nvars*sizeof(double*));
-  parse_arg.vardata2 = (double **) malloc(nvars2*sizeof(double*));
+  parse_arg.vardata1 = malloc(nvars*sizeof(double*));
+  parse_arg.vardata2 = malloc(nvars2*sizeof(double*));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
@@ -177,7 +178,7 @@ void *Expr(void *argument)
       gridsize = gridInqSize(gridID);
       nlevel   = zaxisInqSize(zaxisID);
       if ( parse_arg.var_needed[varID] )
-	parse_arg.vardata1[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+	parse_arg.vardata1[varID] = malloc(gridsize*nlevel*sizeof(double));
       else
 	parse_arg.vardata1[varID] = NULL;
     }
@@ -189,11 +190,11 @@ void *Expr(void *argument)
 
       gridsize = gridInqSize(gridID);
       nlevel   = zaxisInqSize(zaxisID);
-      parse_arg.vardata2[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+      parse_arg.vardata2[varID] = malloc(gridsize*nlevel*sizeof(double));
     }
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/FC.c b/src/FC.c
index 3eab604..dee9661 100644
--- a/src/FC.c
+++ b/src/FC.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -230,7 +230,7 @@ void *FC(void *argument)
   // printf("nfc %d, ntr %d, nlat %d, nlon %d\n", nfc, ntr, nlat, nlon);
 
   nvars = vlistNvars(vlistID2);
-  vars  = (int *) malloc(nvars*sizeof(int));
+  vars  = malloc(nvars*sizeof(int));
   for ( varID = 0; varID < nvars; varID++ )
     {
       if ( gridID1 == vlistInqVarGrid(vlistID1, varID) )
@@ -246,12 +246,12 @@ void *FC(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array1 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
 
   if ( gridID2 != -1 )
     {
       gridsize = gridInqSize(gridID2);
-      array2 = (double *) malloc(gridsize*sizeof(double));
+      array2 = malloc(gridsize*sizeof(double));
     }
 
   tsID = 0;
diff --git a/src/Filedes.c b/src/Filedes.c
index fa5bb9b..37119b5 100644
--- a/src/Filedes.c
+++ b/src/Filedes.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Fillmiss.c b/src/Fillmiss.c
index 3dc5a93..d650cd6 100644
--- a/src/Fillmiss.c
+++ b/src/Fillmiss.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -56,8 +56,8 @@ void fillmiss(field_t *field1, field_t *field2, int nfill)
   if ( !(gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN ) )
     cdoAbort("Unsupported grid type: %s!", gridNamePtr(gridtype));
 
-  matrix1 = (double **) malloc(ny * sizeof(double *));
-  matrix2 = (double **) malloc(ny * sizeof(double *));
+  matrix1 = malloc(ny * sizeof(double *));
+  matrix2 = malloc(ny * sizeof(double *));
 
   for ( j = 0; j < ny; j++ )
     {
@@ -165,8 +165,8 @@ void fillmiss_one_step(field_t *field1, field_t *field2, int maxfill)
   nx  = gridInqXsize(gridID);
   ny  = gridInqYsize(gridID);
 
-  matrix1 = (double **) malloc(ny * sizeof(double *));
-  matrix2 = (double **) malloc(ny * sizeof(double *));
+  matrix1 = malloc(ny * sizeof(double *));
+  matrix2 = malloc(ny * sizeof(double *));
 
   for ( j = 0; j < ny; j++ ) { matrix1[j] = array1 + j*nx; matrix2[j] = array2 + j*nx; }
 
@@ -342,8 +342,8 @@ void *Fillmiss(void *argument)
 
   field_init(&field1);
   field_init(&field2);
-  field1.ptr   = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr   = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr   = malloc(gridsize*sizeof(double));
+  field2.ptr   = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Filter.c b/src/Filter.c
index c78fb17..9415a30 100644
--- a/src/Filter.c
+++ b/src/Filter.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -243,8 +243,8 @@ void *Filter(void *argument)
       if ( tsID >= nalloc )
         {
           nalloc += NALLOC_INC;
-	  dtinfo = (dtinfo_t *)  realloc(dtinfo, nalloc*sizeof(dtinfo_t));
-          vars   = (field_t ***) realloc(vars,   nalloc*sizeof(field_t **));
+	  dtinfo = realloc(dtinfo, nalloc*sizeof(dtinfo_t));
+          vars   = realloc(vars,   nalloc*sizeof(field_t **));
         }
                        
       taxisInqDTinfo(taxisID1, &dtinfo[tsID]);
@@ -256,7 +256,7 @@ void *Filter(void *argument)
           streamInqRecord(streamID1, &varID, &levelID);
           gridID   = vlistInqVarGrid(vlistID1, varID);
           gridsize = gridInqSize(gridID);
-          vars[tsID][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+          vars[tsID][varID][levelID].ptr = malloc(gridsize*sizeof(double));
           streamReadRecord(streamID1, vars[tsID][varID][levelID].ptr, &nmiss);
           vars[tsID][varID][levelID].nmiss = nmiss;
           if ( nmiss ) cdoAbort("Missing value support for operators in module Filter not added yet");
@@ -312,8 +312,8 @@ void *Filter(void *argument)
 #if defined( HAVE_LIBFFTW3 ) 
   nts2 = nts;
 
-  out_fft = (fftw_complex *) malloc ( nts * sizeof(fftw_complex) );
-  in_fft  = (fftw_complex *) malloc ( nts * sizeof(fftw_complex) );
+  out_fft = malloc ( nts * sizeof(fftw_complex) );
+  in_fft  = malloc ( nts * sizeof(fftw_complex) );
 
   p_T2S = fftw_plan_dft_1d(nts,in_fft,out_fft,  1, FFTW_ESTIMATE);
   p_S2T = fftw_plan_dft_1d(nts,out_fft,in_fft, -1, FFTW_ESTIMATE);
@@ -326,11 +326,11 @@ void *Filter(void *argument)
   nts2 |= nts2 >> 16; /* handle 32 bit numbers */
   nts2++;
 
-  array1 = (double *) malloc(nts2*sizeof(double));
-  array2 = (double *) malloc(nts2*sizeof(double));
+  array1 = malloc(nts2*sizeof(double));
+  array2 = malloc(nts2*sizeof(double));
 #endif
 
-  fmasc  = (int *) calloc(nts2, sizeof(int));
+  fmasc  = calloc(nts2, sizeof(int));
    
   for ( tsID = 0; tsID < nts; tsID++ ) array2[tsID] = 0;
 
diff --git a/src/Fldrms.c b/src/Fldrms.c
index 2a874c0..2520818 100644
--- a/src/Fldrms.c
+++ b/src/Fldrms.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -25,6 +25,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
+#include "grid.h"
 
 
 void *Fldrms(void *argument)
@@ -100,12 +101,12 @@ void *Fldrms(void *argument)
   field_init(&field3);
 
   lim = vlistGridsizeMax(vlistID1);
-  field1.ptr    = (double *) malloc(lim*sizeof(double));
+  field1.ptr    = malloc(lim*sizeof(double));
   field1.weight = NULL;
   if ( needWeights )
-    field1.weight = (double *) malloc(lim*sizeof(double));
+    field1.weight = malloc(lim*sizeof(double));
 
-  field2.ptr    = (double *) malloc(lim*sizeof(double));
+  field2.ptr    = malloc(lim*sizeof(double));
   field2.weight = NULL;
 
   field3.ptr  = &sglval;
diff --git a/src/Fldstat.c b/src/Fldstat.c
index aa31707..ea60ddd 100644
--- a/src/Fldstat.c
+++ b/src/Fldstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -35,6 +35,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
+#include "grid.h"
 
 static
 void print_location_LL(int operfunc, int vlistID, int varID, int levelID, int gridID, double sglval, double *fieldptr,
@@ -164,10 +165,10 @@ void *Fldstat(void *argument)
   field_init(&field);
 
   lim = vlistGridsizeMax(vlistID1);
-  field.ptr    = (double *) malloc(lim*sizeof(double));
+  field.ptr    = malloc(lim*sizeof(double));
   field.weight = NULL;
   if ( needWeights )
-    field.weight = (double *) malloc(lim*sizeof(double));
+    field.weight = malloc(lim*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Fldstat2.c b/src/Fldstat2.c
index b0a3bcf..ec4b478 100644
--- a/src/Fldstat2.c
+++ b/src/Fldstat2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -26,6 +26,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
+#include "grid.h"
 
 
 /* routine corr copied from PINGO */
@@ -155,11 +156,11 @@ void *Fldstat2(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
   weight = NULL;
   if ( needWeights )
-    weight = (double *) malloc(gridsize*sizeof(double));
+    weight = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Fourier.c b/src/Fourier.c
index 19b5ac8..5437fd4 100644
--- a/src/Fourier.c
+++ b/src/Fourier.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -83,9 +83,9 @@ void *Fourier(void *argument)
       if ( tsID >= nalloc )
 	{
 	  nalloc += NALLOC_INC;
-	  vdate = (int *) realloc(vdate, nalloc*sizeof(int));
-	  vtime = (int *) realloc(vtime, nalloc*sizeof(int));
-	  vars  = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
+	  vdate = realloc(vdate, nalloc*sizeof(int));
+	  vtime = realloc(vtime, nalloc*sizeof(int));
+	  vars  = realloc(vars, nalloc*sizeof(field_t **));
 	}
 
       vdate[tsID] = taxisInqVdate(taxisID1);
@@ -98,7 +98,7 @@ void *Fourier(void *argument)
 	  streamInqRecord(streamID1, &varID, &levelID);
 	  gridID   = vlistInqVarGrid(vlistID1, varID);
 	  gridsize = gridInqSize(gridID);
-	  vars[tsID][varID][levelID].ptr = (double *) malloc(2*gridsize*sizeof(double));
+	  vars[tsID][varID][levelID].ptr = malloc(2*gridsize*sizeof(double));
 	  streamReadRecord(streamID1, vars[tsID][varID][levelID].ptr, &nmiss);
 	  vars[tsID][varID][levelID].nmiss = nmiss;
 	}
@@ -110,15 +110,15 @@ void *Fourier(void *argument)
 
   for ( bit = nts; !(bit & 1); bit >>= 1 );
 
-  mem = (memory_t *) malloc(ompNumThreads*sizeof(memory_t));
+  mem = malloc(ompNumThreads*sizeof(memory_t));
   for ( i = 0; i < ompNumThreads; i++ )
     {
-      mem[i].real = (double *) malloc(nts*sizeof(double));
-      mem[i].imag = (double *) malloc(nts*sizeof(double));
+      mem[i].real = malloc(nts*sizeof(double));
+      mem[i].imag = malloc(nts*sizeof(double));
       if ( bit != 1 )
 	{
-	  mem[i].work_r = (double *) malloc(nts*sizeof(double));
-	  mem[i].work_i = (double *) malloc(nts*sizeof(double));
+	  mem[i].work_r = malloc(nts*sizeof(double));
+	  mem[i].work_i = malloc(nts*sizeof(double));
 	}
     }
 
diff --git a/src/Gather.c b/src/Gather.c
index 65c0681..6ae3b6d 100644
--- a/src/Gather.c
+++ b/src/Gather.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -42,8 +42,8 @@ static
 int cmpx(const void *s1, const void *s2)
 {
   int cmp = 0;
-  xyinfo_t *xy1 = (xyinfo_t *) s1;
-  xyinfo_t *xy2 = (xyinfo_t *) s2;
+  const xyinfo_t *xy1 = s1;
+  const xyinfo_t *xy2 = s2;
 
   if      ( xy1->x < xy2->x ) cmp = -1;
   else if ( xy1->x > xy2->x ) cmp =  1;
@@ -55,8 +55,8 @@ static
 int cmpxy_lt(const void *s1, const void *s2)
 {
   int cmp = 0;
-  xyinfo_t *xy1 = (xyinfo_t *) s1;
-  xyinfo_t *xy2 = (xyinfo_t *) s2;
+  const xyinfo_t *xy1 = s1;
+  const xyinfo_t *xy2 = s2;
 
   if      ( xy1->y < xy2->y || (!(fabs(xy1->y - xy2->y) > 0) && xy1->x < xy2->x) ) cmp = -1;
   else if ( xy1->y > xy2->y || (!(fabs(xy1->y - xy2->y) > 0) && xy1->x > xy2->x) ) cmp =  1;
@@ -68,8 +68,8 @@ static
 int cmpxy_gt(const void *s1, const void *s2)
 {
   int cmp = 0;
-  xyinfo_t *xy1 = (xyinfo_t *) s1;
-  xyinfo_t *xy2 = (xyinfo_t *) s2;
+  const xyinfo_t *xy1 = s1;
+  const xyinfo_t *xy2 = s2;
 
   if      ( xy1->y > xy2->y || (!(fabs(xy1->y - xy2->y) > 0) && xy1->x < xy2->x) ) cmp = -1;
   else if ( xy1->y < xy2->y || (!(fabs(xy1->y - xy2->y) > 0) && xy1->x > xy2->x) ) cmp =  1;
@@ -99,11 +99,11 @@ int genGrid(int nfiles, ens_file_t *ef, int **gridindex, int igrid)
   if ( gridtype == GRID_GENERIC && gridInqXsize(gridID) == 0 && gridInqYsize(gridID) == 0 )
     return (gridID2);
 
-  xsize = (int *) malloc(nfiles*sizeof(int));
-  ysize = (int *) malloc(nfiles*sizeof(int));
-  xyinfo = (xyinfo_t *) malloc(nfiles*sizeof(xyinfo_t));
-  xvals = (double **) malloc(nfiles*sizeof(double));
-  yvals = (double **) malloc(nfiles*sizeof(double));
+  xsize = malloc(nfiles*sizeof(int));
+  ysize = malloc(nfiles*sizeof(int));
+  xyinfo = malloc(nfiles*sizeof(xyinfo_t));
+  xvals = malloc(nfiles*sizeof(double));
+  yvals = malloc(nfiles*sizeof(double));
 
   for ( fileID = 0; fileID < nfiles; fileID++ )
     {
@@ -121,8 +121,8 @@ int genGrid(int nfiles, ens_file_t *ef, int **gridindex, int igrid)
       if ( xsize != gridInqXsize(gridID) ) cdoAbort("xsize differ!");
       if ( ysize != gridInqYsize(gridID) ) cdoAbort("ysize differ!");
       */
-      xvals[fileID] = (double *) malloc(xsize[fileID]*sizeof(double));
-      yvals[fileID] = (double *) malloc(ysize[fileID]*sizeof(double));
+      xvals[fileID] = malloc(xsize[fileID]*sizeof(double));
+      yvals[fileID] = malloc(ysize[fileID]*sizeof(double));
       gridInqXvals(gridID, xvals[fileID]);
       gridInqYvals(gridID, yvals[fileID]);
 
@@ -172,11 +172,11 @@ int genGrid(int nfiles, ens_file_t *ef, int **gridindex, int igrid)
   for ( j = 0; j < ny; ++j ) ysize2 += ysize[xyinfo[j*nx].id];
   if ( cdoVerbose ) cdoPrint("xsize2 %d  ysize2 %d", xsize2, ysize2);
 
-  xvals2 = (double *) malloc(xsize2*sizeof(double));
-  yvals2 = (double *) malloc(ysize2*sizeof(double));
+  xvals2 = malloc(xsize2*sizeof(double));
+  yvals2 = malloc(ysize2*sizeof(double));
 
-  xoff = (int *) malloc((nx+1)*sizeof(int));
-  yoff = (int *) malloc((ny+1)*sizeof(int));
+  xoff = malloc((nx+1)*sizeof(int));
+  yoff = malloc((ny+1)*sizeof(int));
 
   xoff[0] = 0;
   for ( i = 0; i < nx; ++i )
@@ -297,7 +297,7 @@ void *Gather(void *argument)
       if ( !userFileOverwrite(ofilename) )
 	cdoAbort("Outputfile %s already exists!", ofilename);
 
-  ef = (ens_file_t *) malloc(nfiles*sizeof(ens_file_t));
+  ef = malloc(nfiles*sizeof(ens_file_t));
 
   for ( fileID = 0; fileID < nfiles; fileID++ )
     {
@@ -310,7 +310,7 @@ void *Gather(void *argument)
     }
 
   nvars = vlistNvars(ef[0].vlistID);
-  vars  = (int *) malloc(nvars*sizeof(int));
+  vars  = malloc(nvars*sizeof(int));
   for ( varID = 0; varID < nvars; varID++ ) vars[varID] = FALSE;
 
   /* check that the contents is always the same */
@@ -332,13 +332,13 @@ void *Gather(void *argument)
   gridsize = gridsizemax;
 
   for ( fileID = 0; fileID < nfiles; fileID++ )
-    ef[fileID].array = (double *) malloc(gridsizemax*sizeof(double));
+    ef[fileID].array = malloc(gridsizemax*sizeof(double));
 
   ngrids = vlistNgrids(ef[0].vlistID);
-  gridIDs = (int *) malloc(ngrids*sizeof(int));
-  gridindex = (int **) malloc(nfiles*sizeof(int *));
+  gridIDs = malloc(ngrids*sizeof(int));
+  gridindex = malloc(nfiles*sizeof(int *));
   for ( fileID = 0; fileID < nfiles; fileID++ )
-    gridindex[fileID] = (int *) malloc(gridsizemax*sizeof(int));
+    gridindex[fileID] = malloc(gridsizemax*sizeof(int));
 
   int ginit = FALSE;
   for ( i = 0; i < ngrids; ++i )
@@ -387,7 +387,7 @@ void *Gather(void *argument)
       
   streamDefVlist(streamID2, vlistID2);
 	  
-  array2 = (double *) malloc(gridsize2*sizeof(double));
+  array2 = malloc(gridsize2*sizeof(double));
 
   tsID = 0;
   do
diff --git a/src/Gengrid.c b/src/Gengrid.c
index fc3d6ff..47dd83a 100644
--- a/src/Gengrid.c
+++ b/src/Gengrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -62,9 +62,9 @@ void *Gengrid(void *argument)
   xsize = gridInqXsize(gridID1);
   ysize = gridInqYsize(gridID1);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
-  array3 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
+  array3 = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   nrecs = streamInqTimestep(streamID1, tsID);
diff --git a/src/Gradsdes.c b/src/Gradsdes.c
index c06e577..169ff52 100644
--- a/src/Gradsdes.c
+++ b/src/Gradsdes.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -18,8 +18,7 @@
 /*
    This module contains the following operators:
 
-      Gradsdes   gradsdes1       GrADS data descriptor file (version 1 map)
-      Gradsdes   gradsdes2       GrADS data descriptor file (version 2 map)
+      Gradsdes   gradsdes       GrADS data descriptor file
 */
 
 
@@ -75,6 +74,10 @@ struct gaindx {
   int   *intpnt;    /* Pointer to int index values    */
   float *fltpnt;    /* Pointer to float index values  */
 };
+struct gaindxb {
+  int    bignum;    /* Number of off_t values */	       
+  off_t *bigpnt;    /* Pointer to off_t values */
+};
 
 
 /* Byte swap requested number of 4 byte elements */
@@ -226,7 +229,9 @@ void dumpmap()
   unsigned char mrec[512];
   int swpflg = 0;
   int i;
+  int nrecords = 0;
   struct gaindx indx;
+  struct gaindxb indxb;
   size_t nbytes;
   FILE *mapfp;
 
@@ -234,6 +239,8 @@ void dumpmap()
   indx.hfpnt = NULL;
   indx.intpnt = NULL;
   indx.fltpnt = NULL;
+  indxb.bigpnt = NULL;
+  indxb.bignum = 0;
 
   mapfp = fopen(cdoStreamName(0)->args, "r");
   if ( mapfp == NULL ) cdoAbort("Open failed on %s", cdoStreamName(0)->args);
@@ -243,9 +250,12 @@ void dumpmap()
   fseek(mapfp, 1, 0);
   nbytes = fread(&vermap, sizeof(unsigned char), 1, mapfp);
 
+  if ( vermap == 0 ) vermap = 1;
+
+  printf("gribmap version = %d\n", vermap);
+
   if ( vermap == 2 )
     {
-      printf("gribmap version = %d\n", vermap);
       fseek(mapfp, 2, 0);
 
       nbytes = fread(mrec, sizeof(unsigned char), 4, mapfp);
@@ -264,7 +274,7 @@ void dumpmap()
 
       if ( indx.hinum > 0 )
 	{
-	  indx.hipnt = (int *) malloc(sizeof(int)*indx.hinum);
+	  indx.hipnt = malloc(sizeof(int)*indx.hinum);
 	  for ( i = 0; i < indx.hinum; i++ )
 	    {
 	      nbytes = fread(mrec, sizeof(unsigned char), 4, mapfp);
@@ -273,12 +283,12 @@ void dumpmap()
 	}
       if ( indx.hfnum > 0 )
 	{
-	  indx.hfpnt = (float *) malloc(sizeof(float)*indx.hfnum);
+	  indx.hfpnt = malloc(sizeof(float)*indx.hfnum);
 	  nbytes = fread (indx.hfpnt,sizeof(float),indx.hfnum,mapfp);
 	}
       if ( indx.intnum > 0 )
 	{
-	  indx.intpnt = (int *) malloc(sizeof(int)*indx.intnum);
+	  indx.intpnt = malloc(sizeof(int)*indx.intnum);
 	  for ( i = 0; i < indx.intnum; i++ )
 	    {
 	      nbytes = fread(mrec, sizeof(unsigned char), 4, mapfp);
@@ -288,7 +298,7 @@ void dumpmap()
 	}
       if ( indx.fltnum > 0 )
 	{
-	  indx.fltpnt = (float *) malloc(sizeof(float)*indx.fltnum);
+	  indx.fltpnt = malloc(sizeof(float)*indx.fltnum);
 	  for ( i = 0; i < indx.fltnum; i++ )
 	    {
 	      nbytes = fread(urec, sizeof(unsigned char), 4, mapfp);
@@ -300,34 +310,47 @@ void dumpmap()
     {
       fseek(mapfp, 0, 0);
       nbytes = fread (&indx, sizeof(struct gaindx), 1, mapfp);
+
       if ( indx.type>>24 > 0 ) swpflg = 1;
       if ( swpflg ) printf("swap endian!\n");
       if ( swpflg ) gabswp((float *)&indx.type, 5);
       
       if ( indx.hinum > 0 )
 	{
-	  indx.hipnt = (int *) malloc(sizeof(int)*indx.hinum);
+	  indx.hipnt = malloc(sizeof(int)*indx.hinum);
 	  nbytes = fread (indx.hipnt, sizeof(int), indx.hinum, mapfp);
 	  if ( swpflg ) gabswp((float *)(indx.hipnt),indx.hinum);
 	}
       if ( indx.hfnum > 0 )
 	{
-	  indx.hfpnt = (float *) malloc(sizeof(float)*indx.hfnum);
+	  indx.hfpnt = malloc(sizeof(float)*indx.hfnum);
 	  nbytes = fread (indx.hfpnt,sizeof(float),indx.hfnum,mapfp);
 	  if ( swpflg ) gabswp(indx.hfpnt,indx.hfnum);
 	}
+
       if ( indx.intnum > 0 )
 	{
-	  indx.intpnt = (int *) malloc(sizeof(int)*indx.intnum);
+	  indx.intpnt = malloc(sizeof(int)*indx.intnum);
 	  nbytes = fread (indx.intpnt,sizeof(int),indx.intnum,mapfp);
 	  if ( swpflg ) gabswp((float *)(indx.intpnt),indx.intnum);
 	}
       if ( indx.fltnum > 0 )
 	{
-	  indx.fltpnt = (float *) malloc(sizeof(float)*indx.fltnum);
+	  indx.fltpnt = malloc(sizeof(float)*indx.fltnum);
 	  nbytes = fread (indx.fltpnt,sizeof(float),indx.fltnum,mapfp);
 	  if ( swpflg ) gabswp(indx.fltpnt,indx.fltnum);
 	}
+
+      if ( indx.hipnt[0] == 4 )
+	{
+	  indxb.bignum = indx.hipnt[4];
+	  if ( indxb.bignum > 0 )
+	    {
+	      indxb.bigpnt = malloc(sizeof(off_t)*indxb.bignum);
+	      nbytes = fread (indxb.bigpnt,sizeof(off_t),indxb.bignum,mapfp);
+	      if ( swpflg ) gabswp(indxb.bigpnt,indxb.bignum);
+	    }
+	}
     }
 
   fclose(mapfp);
@@ -342,6 +365,9 @@ void dumpmap()
     printf("%3d %g\n", i+1, indx.hfpnt[i]);
   
   printf("\n");
+
+  nrecords = indx.hipnt[1]*indx.hipnt[2];
+
   if ( indx.intnum == indx.fltnum )
     {
       printf("num: %d\n", indx.intnum);
@@ -350,6 +376,14 @@ void dumpmap()
 	       indx.intpnt[i*3], indx.intpnt[i*3+1], indx.intpnt[i*3+2],
 	       indx.fltpnt[i*3], indx.fltpnt[i*3+1], indx.fltpnt[i*3+2]);
     }
+  else if ( indx.intnum == nrecords && indx.fltnum == nrecords*3 && indxb.bignum == nrecords*2 )
+    {
+      printf("nrecords: %d\n", nrecords);
+      for ( i = 0; i < nrecords; i++ )
+	printf("%3d %8zd %6zd %4d %8g %10g %8g\n", i+1,
+	       (size_t)indxb.bigpnt[i*2], (size_t)indxb.bigpnt[i*2+1], indx.intpnt[i],
+	       indx.fltpnt[i*3], indx.fltpnt[i*3+1], indx.fltpnt[i*3+2]);
+    }
   else
     {
       printf("intnum: %d\n", indx.intnum);
@@ -360,6 +394,11 @@ void dumpmap()
       printf("fltnum: %d\n", indx.fltnum);
       for ( i = 0; i < indx.fltnum; i++ )
 	printf("%3d %g\n", i+1, indx.fltpnt[i]);
+
+      printf("\n");
+      printf("bignum: %d\n", indxb.bignum);
+      for ( i = 0; i < indxb.bignum; i++ )
+	printf("%3d %zd\n", i+1, (size_t)indxb.bigpnt[i]);
     }
 }
 
@@ -392,12 +431,12 @@ void ctl_xydef(FILE *gdp, int gridID, int *yrev)
 
       gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
 		 &projflag, &scanflag);
-      fprintf(gdp, "PDEF %d %d lcc %g %g 1 1 %g %g %g %g %g\n", 
+      fprintf(gdp, "PDEF %d %d LCCR %g %g 1 1 %g %g %g %g %g\n", 
 	      xsize, ysize, originLat, originLon, lat1, lat2, lonParY, xincm, yincm);
 
       gridID = gridToCurvilinear(gridID, 0);
-      xvals = (double *) malloc(xsize*ysize*sizeof(double));
-      yvals = (double *) malloc(xsize*ysize*sizeof(double));
+      xvals = malloc(xsize*ysize*sizeof(double));
+      yvals = malloc(xsize*ysize*sizeof(double));
       gridInqXvals(gridID, xvals);
       gridInqYvals(gridID, yvals);
       for ( i = 0; i < xsize*ysize; ++i )
@@ -438,7 +477,7 @@ void ctl_xydef(FILE *gdp, int gridID, int *yrev)
       xinc   = gridInqXinc(gridID);
       if ( IS_EQUAL(xinc, 0) && gridInqXvals(gridID, NULL) )
 	{
-	  xvals = (double *) malloc(xsize*sizeof(double));
+	  xvals = malloc(xsize*sizeof(double));
 	  gridInqXvals(gridID, xvals);
 	  fprintf(gdp ,"XDEF %d LEVELS ", xsize);
 	  j = 0;
@@ -474,7 +513,7 @@ void ctl_xydef(FILE *gdp, int gridID, int *yrev)
 
       if ( IS_EQUAL(yinc, 0) && gridInqYvals(gridID, NULL) )
 	{
-	  yvals = (double *) malloc(ysize*sizeof(double));
+	  yvals = malloc(ysize*sizeof(double));
 	  gridInqYvals(gridID, yvals);
 	  fprintf(gdp ,"YDEF %d LEVELS ", ysize);
 	  j = 0;
@@ -550,7 +589,7 @@ void ctl_zdef(FILE *gdp, int vlistID, int *zrev)
 	}
     }
 
-  levels = (double *) malloc(nlevmax*sizeof(double));
+  levels = malloc(nlevmax*sizeof(double));
   zaxisInqLevels(zaxisIDmax, levels);
   if ( zaxisInqType(zaxisIDmax) == ZAXIS_PRESSURE ) lplev = TRUE;
   level0 = levels[0];
@@ -748,30 +787,46 @@ void ctl_vars(FILE *gdp, int filetype, int vlistID, int nvarsout, int *vars)
 }
 
 static
-void write_map_grib1(const char *ctlfile, int map_version, int nrecords, int *intnum, float *fltnum)
+void write_map_grib1(const char *ctlfile, int map_version, int nrecords, int *intnum, float *fltnum, off_t *bignum)
 {
   int i;
   struct gaindx indx;
+  struct gaindxb indxb;
   FILE *mapfp;
-  int hinum[4];
+  int hinum[5];
+
+  memset(&indx, 0, sizeof(struct gaindx));
 
   mapfp = fopen(ctlfile, "w");
   if ( mapfp == NULL ) cdoAbort("Open failed on %s", ctlfile);
 
-  indx.type   = 1;  /* GRIB type */
-  indx.hinum  = 4;
+  indx.type   = map_version;
   indx.hfnum  = 0;
-  indx.intnum = 3 * nrecords;
+  if ( map_version == 4 )
+    {
+      indx.hinum  = 5;
+      indx.intnum = nrecords;
+      indxb.bignum = 2 * nrecords;
+    }
+  else
+    {
+      indx.hinum  = 4;
+      indx.intnum = 3 * nrecords;
+      indxb.bignum = 0;
+    }
   indx.fltnum = 3 * nrecords;
+
   indx.hipnt  = NULL;
   indx.hfpnt  = NULL;
   indx.intpnt = NULL;
   indx.fltpnt = NULL;
+  indxb.bigpnt = NULL;
 
-  hinum[0] = 1;
+  hinum[0] = map_version;
   hinum[1] = 1;
   hinum[2] = nrecords;
   hinum[3] = 255;
+  hinum[4] = indxb.bignum;
 
   if ( map_version == 2 )
     {
@@ -782,22 +837,22 @@ void write_map_grib1(const char *ctlfile, int map_version, int nrecords, int *in
       
       /* calculate the size of the ver==1 index file */
       
-      nb = 2 + (4*4) +  /* version in byte 2, then 4 ints with number of each data type */
-	indx.hinum*sizeof(int)+
-	indx.hfnum*sizeof(int)+
-	indx.intnum*sizeof(int)+
-	indx.fltnum*sizeof(float) ;
+      nb = 2 + (indx.hinum*4) +  /* version in byte 2, then 4 ints with number of each data type */
+	indx.hinum*sizeof(int) +
+	indx.hfnum*sizeof(int) +
+	indx.intnum*sizeof(int) +
+	indx.fltnum*sizeof(float);
       
       /* add additional info */
       
       nb += 7;      /* base time (+ sec)  for compatibility with earlier version 2 maps */
       nb += 8*4;    /* grvals for time <-> grid conversion */
       
-      map = (unsigned char *) malloc(nb);
+      map = malloc(nb);
       
       bcnt = 0;
       Put1Byte(map, bcnt, 0);
-      Put1Byte(map, bcnt, 2); /* version 2 */
+      Put1Byte(map, bcnt, map_version);
       
       Put4Byte(map, bcnt, indx.hinum);
       Put4Byte(map, bcnt, indx.hfnum);
@@ -819,9 +874,13 @@ void write_map_grib1(const char *ctlfile, int map_version, int nrecords, int *in
 	/* blank for now */
       }
       
-      for ( i = 0; i < indx.intnum; i++ )
-	PutInt(map, bcnt, intnum[i]);
-      
+      for ( i = 0; i < nrecords; i++ )
+	{
+	  PutInt(map, bcnt, (int) bignum[i*2]);
+	  PutInt(map, bcnt, (int) bignum[i*2+1]);
+	  PutInt(map, bcnt, intnum[i]);
+	}
+
       for ( i = 0; i < indx.fltnum; i++)
 	{
 	  fdum= fltnum[i];
@@ -841,15 +900,33 @@ void write_map_grib1(const char *ctlfile, int map_version, int nrecords, int *in
 	}
       
       fwrite(map, 1, bcnt, mapfp);
-	  
+
       free(map);
     }
   else
     {
       fwrite(&indx, sizeof(struct gaindx), 1, mapfp);
-      fwrite(hinum, sizeof(int), 4, mapfp);
-      fwrite(intnum, sizeof(int), 3*nrecords, mapfp);
-      fwrite(fltnum, sizeof(float), 3*nrecords, mapfp);
+      if ( indx.hinum > 0 )  fwrite(hinum, sizeof(int), indx.hinum, mapfp);
+      if ( map_version == 1 )
+	{
+	  int *intnumbuf;
+	  intnumbuf = malloc(indx.intnum*sizeof(int));
+	  for ( i = 0; i < nrecords; i++ )
+	    {
+	      intnumbuf[i*3+0] = (int) bignum[i*2];
+	      intnumbuf[i*3+1] = (int) bignum[i*2+1];
+	      intnumbuf[i*3+2] = intnum[i];
+	    }
+	  if ( indx.intnum > 0 ) fwrite(intnumbuf, sizeof(int), indx.intnum, mapfp);
+	  free(intnumbuf);
+	  if ( indx.fltnum > 0 ) fwrite(fltnum, sizeof(float), indx.fltnum, mapfp);
+	}
+      else
+	{
+	  if ( indx.intnum  > 0 ) fwrite(intnum, sizeof(int), indx.intnum, mapfp);
+	  if ( indx.fltnum  > 0 ) fwrite(fltnum, sizeof(float), indx.fltnum, mapfp);
+	  if ( indxb.bignum > 0 ) fwrite(bignum, sizeof(off_t), indxb.bignum, mapfp);
+	}
     }
   
   fclose(mapfp);
@@ -858,7 +935,7 @@ void write_map_grib1(const char *ctlfile, int map_version, int nrecords, int *in
 
 void *Gradsdes(void *argument)
 {
-  int GRADSDES2, DUMPMAP;
+  int GRADSDES, DUMPMAP;
   int operatorID;
   int streamID = 0;
   int gridID = -1;
@@ -896,7 +973,7 @@ void *Gradsdes(void *argument)
   long checksize = 0;
   int nmiss;
   int prec;
-  int map_version = 1;
+  int map_version = 2;
   int nrecsout = 0;
   int maxrecs = 0;
   int monavg = -1;
@@ -904,19 +981,17 @@ void *Gradsdes(void *argument)
   int *recoffset = NULL;
   int *intnum = NULL;
   float *fltnum = NULL;
+  off_t *bignum = NULL;
   double *array = NULL;
   const char *cmons[]={"jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"};
       
   cdoInitialize(argument);
 
-              cdoOperatorAdd("gradsdes1", 0, 0, NULL);
-  GRADSDES2 = cdoOperatorAdd("gradsdes2", 0, 0, NULL);
+  GRADSDES  = cdoOperatorAdd("gradsdes",  0, 0, NULL);
   DUMPMAP   = cdoOperatorAdd("dumpmap",   0, 0, NULL);
 
   operatorID = cdoOperatorID();
 
-  if ( operatorID == GRADSDES2 ) map_version = 2;
-
   if ( cdoStreamName(0)->args[0] == '-' )
     cdoAbort("This operator does not work with pipes!");
 
@@ -927,6 +1002,26 @@ void *Gradsdes(void *argument)
       goto END_LABEL;
     }
 
+  if ( operatorArgc() > 1 ) cdoAbort("Too many arguments!");
+
+  if ( operatorArgc() == 1 )
+    {
+      map_version = atoi(operatorArgv()[0]);
+      if ( map_version != 1 && map_version != 2 && map_version != 4 )
+	cdoAbort("map_version=%d unsupported!", map_version);
+    }
+  else
+    {
+      if ( filesize(cdoStreamName(0)->args) > 2147483647L ) map_version = 4;
+    }
+
+  if ( cdoVerbose ) cdoPrint("GrADS GRIB map version: %d", map_version);
+
+  if ( map_version == 4 && sizeof(off_t) != 8 )
+    cdoAbort("GrADS GRIB map version %d requires size of off_t to be 8! The size of off_t is %ld.",
+	     map_version, sizeof(off_t));
+ 
+
   streamID = streamOpenRead(cdoStreamName(0));
 
   vlistID = streamInqVlist(streamID);
@@ -965,12 +1060,11 @@ void *Gradsdes(void *argument)
     }
 
   if ( index == ngrids )
-    cdoAbort("No Lon/Lat, Gaussian or Lambert grid found (%s data unsupported)!",
-	     gridNamePtr(gridtype));
+    cdoAbort("No Lon/Lat, Gaussian or Lambert grid found (%s data unsupported)!", gridNamePtr(gridtype));
 
   /* select all variables with used gridID */
-  vars = (int *) malloc(nvars*sizeof(int));
-  recoffset = (int *) malloc(nvars*sizeof(int));
+  vars = malloc(nvars*sizeof(int));
+  recoffset = malloc(nvars*sizeof(int));
   nvarsout = 0;
   nrecsout = 0;
   for ( varID = 0; varID < nvars; varID++ )
@@ -1089,7 +1183,7 @@ void *Gradsdes(void *argument)
 	}
 
       gridsize = vlistGridsizeMax(vlistID);
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
   else if ( filetype == FILETYPE_NC )
     {
@@ -1203,8 +1297,9 @@ void *Gradsdes(void *argument)
 	  if ( nrecords >= maxrecs )
 	    {
 	      maxrecs = nrecords;
-	      intnum = (int *) realloc(intnum, 3*maxrecs*sizeof(int));
-	      fltnum = (float *) realloc(fltnum, 3*maxrecs*sizeof(float));
+	      intnum = realloc(intnum, 1*maxrecs*sizeof(int));
+	      fltnum = realloc(fltnum, 3*maxrecs*sizeof(float));
+	      bignum = realloc(bignum, 2*maxrecs*sizeof(off_t));
 	    }
 
 	  for ( recID = 0; recID < nrecs; recID++ )
@@ -1214,16 +1309,19 @@ void *Gradsdes(void *argument)
 		{
 		  streamReadRecord(streamID, array, &nmiss);
 
-		  index = 3*(tsID*nrecsout + recoffset[varID] + levelID);
+		  index = (tsID*nrecsout + recoffset[varID] + levelID);
 	      
-		  streamInqGinfo(streamID, &intnum[index], &fltnum[index]);
+		  streamInqGinfo(streamID, &intnum[index], &fltnum[index*3], &bignum[index*2]);
 
-		  checksize = (long)intnum[index] + (long)gridsize*intnum[index+2]/8;
-		  if ( checksize < 0L || checksize > 2147483647L )
+		  if ( map_version != 4 )
 		    {
-		      nrecords -= nrecsout;
-		      cdoWarning("GRIB file too large for GrADS! Only the first %d time steps (2GB) are processed.", tsID);
-		      goto LABEL_STOP;
+		      checksize = (long)bignum[index*2] + (long)gridsize*intnum[index]/8;
+		      if ( checksize < 0L || checksize > 2147483647L )
+			{
+			  nrecords -= nrecsout;
+			  cdoWarning("File size limit reached for GrADS GRIB map_version=%d! Only the first %d time steps (2GB) are processed.", map_version, tsID);
+			  goto LABEL_STOP;
+			}
 		    }
 		}
 	    }
@@ -1286,7 +1384,7 @@ void *Gradsdes(void *argument)
   /* INDEX file */
   if ( filetype == FILETYPE_GRB )
     {
-      write_map_grib1(ctlfile, map_version, nrecords, intnum, fltnum);
+      write_map_grib1(ctlfile, map_version, nrecords, intnum, fltnum, bignum);
     }
 
 
diff --git a/src/Gridboxstat.c b/src/Gridboxstat.c
index 1f7f3fc..bf933cc 100644
--- a/src/Gridboxstat.c
+++ b/src/Gridboxstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -103,19 +103,19 @@ int genBoxGrid(int gridID1, int xinc, int yinc)
       if ( gridInqXbounds(gridID1, NULL) && gridInqYbounds(gridID1, NULL) )
         gridHasBounds = TRUE;
 
-      xvals1 = (double *) malloc(nlon1*sizeof(double));
-      yvals1 = (double *) malloc(nlat1*sizeof(double));
-      xvals2 = (double *) malloc(nlon2*sizeof(double));
-      yvals2 = (double *) malloc(nlat2*sizeof(double));
+      xvals1 = malloc(nlon1*sizeof(double));
+      yvals1 = malloc(nlat1*sizeof(double));
+      xvals2 = malloc(nlon2*sizeof(double));
+      yvals2 = malloc(nlat2*sizeof(double));
       gridInqXvals(gridID1, xvals1);
       gridInqYvals(gridID1, yvals1);
 
       if ( gridHasBounds )
         {
-          grid1_corner_lon = (double *) malloc(2*nlon1*sizeof(double));
-          grid1_corner_lat = (double *) malloc(2*nlat1*sizeof(double));
-          grid2_corner_lon = (double *) malloc(2*nlon2*sizeof(double));
-          grid2_corner_lat = (double *) malloc(2*nlat2*sizeof(double));
+          grid1_corner_lon = malloc(2*nlon1*sizeof(double));
+          grid1_corner_lat = malloc(2*nlat1*sizeof(double));
+          grid2_corner_lon = malloc(2*nlon2*sizeof(double));
+          grid2_corner_lat = malloc(2*nlat2*sizeof(double));
           gridInqXbounds(gridID1, grid1_corner_lon);
           gridInqYbounds(gridID1, grid1_corner_lat);
         }
@@ -177,10 +177,10 @@ int genBoxGrid(int gridID1, int xinc, int yinc)
       if ( gridInqXbounds(gridID1, NULL) && gridInqYbounds(gridID1, NULL) )
         gridHasBounds = TRUE;
       
-      xvals1 = (double *) malloc(nlon1*nlat1*sizeof(double));
-      yvals1 = (double *) malloc(nlon1*nlat1*sizeof(double));
-      xvals2 = (double *) malloc(nlon2*nlat2*sizeof(double));
-      yvals2 = (double *) malloc(nlon2*nlat2*sizeof(double));
+      xvals1 = malloc(nlon1*nlat1*sizeof(double));
+      yvals1 = malloc(nlon1*nlat1*sizeof(double));
+      xvals2 = malloc(nlon2*nlat2*sizeof(double));
+      yvals2 = malloc(nlon2*nlat2*sizeof(double));
       gridInqXvals(gridID1, xvals1);
       gridInqYvals(gridID1, yvals1);
 
@@ -195,10 +195,10 @@ int genBoxGrid(int gridID1, int xinc, int yinc)
       
       if ( gridHasBounds )
         {
-          grid1_corner_lon = (double *) malloc(4*nlon1*nlat1*sizeof(double));
-          grid1_corner_lat = (double *) malloc(4*nlon1*nlat1*sizeof(double));
-          grid2_corner_lon = (double *) malloc(4*nlon2*nlat2*sizeof(double));
-          grid2_corner_lat = (double *) malloc(4*nlon2*nlat2*sizeof(double));
+          grid1_corner_lon = malloc(4*nlon1*nlat1*sizeof(double));
+          grid1_corner_lat = malloc(4*nlon1*nlat1*sizeof(double));
+          grid2_corner_lon = malloc(4*nlon2*nlat2*sizeof(double));
+          grid2_corner_lat = malloc(4*nlon2*nlat2*sizeof(double));
           gridInqXbounds(gridID1, grid1_corner_lon);
           gridInqYbounds(gridID1, grid1_corner_lat);
 
@@ -545,14 +545,14 @@ void gridboxstat(field_t *field1, field_t *field2, int xinc, int yinc, int statf
   if ( field1->weight ) useWeight = TRUE;
 
   gridsize      = xinc*yinc;
-  field = (field_t *) malloc(ompNumThreads*sizeof(field_t));
+  field = malloc(ompNumThreads*sizeof(field_t));
   for ( i = 0; i < ompNumThreads; i++ )
     {
       field[i].size    = gridsize;
-      field[i].ptr     = (double *) malloc(gridsize*sizeof(double));
+      field[i].ptr     = malloc(gridsize*sizeof(double));
       field[i].weight  = NULL;
       if ( useWeight )
-	field[i].weight  = (double *) malloc(gridsize*sizeof(double));
+	field[i].weight  = malloc(gridsize*sizeof(double));
       field[i].missval = field1->missval;
       field[i].nmiss   = 0;
     }
@@ -700,13 +700,13 @@ void *Gridboxstat(void *argument)
   field_init(&field2);
 
   gridsize1 = gridInqSize(gridID1);
-  field1.ptr    = (double *) malloc(gridsize1*sizeof(double));
+  field1.ptr    = malloc(gridsize1*sizeof(double));
   field1.weight = NULL;
   if ( needWeights )
-    field1.weight = (double *) malloc(gridsize1*sizeof(double));
+    field1.weight = malloc(gridsize1*sizeof(double));
 
   gridsize2 = gridInqSize(gridID2);
-  field2.ptr    = (double *) malloc(gridsize2*sizeof(double));
+  field2.ptr    = malloc(gridsize2*sizeof(double));
   field2.weight = NULL;
 
   tsID = 0;
diff --git a/src/Gridcell.c b/src/Gridcell.c
index 2d0f0bb..c12ef39 100644
--- a/src/Gridcell.c
+++ b/src/Gridcell.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -137,7 +137,7 @@ void *Gridcell(void *argument)
 
 
   gridsize = gridInqSize(gridID);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
 
   if ( operatorID == GRIDAREA )
@@ -185,7 +185,7 @@ void *Gridcell(void *argument)
   else if ( operatorID == GRIDMASK )
     {
       int *mask;
-      mask = (int *) malloc(gridsize*sizeof(int));
+      mask = malloc(gridsize*sizeof(int));
       if ( gridInqMask(gridID, NULL) )
 	{
 	  gridInqMask(gridID, mask);
@@ -218,8 +218,8 @@ void *Gridcell(void *argument)
 	  xsize = gridInqXsize(gridID);
 	  ysize = gridInqYsize(gridID);
 
-	  xv = (double *) malloc(gridsize*sizeof(double));
-	  yv = (double *) malloc(gridsize*sizeof(double));
+	  xv = malloc(gridsize*sizeof(double));
+	  yv = malloc(gridsize*sizeof(double));
 
 	  gridInqXvals(gridID, xv);
 	  gridInqYvals(gridID, yv);
diff --git a/src/Harmonic.c b/src/Harmonic.c
index 1236ed7..c57667c 100644
--- a/src/Harmonic.c
+++ b/src/Harmonic.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -80,7 +80,7 @@ void *Harmonic(void *argument)
   filesuffix[0] = 0;
   cdoGenFileSuffix(filesuffix, sizeof(filesuffix), streamInqFiletype(streamID1), vlistID1, refname);
 
-  streamIDs = (int*) malloc(n_out*sizeof(int));
+  streamIDs = malloc(n_out*sizeof(int));
 
   strcpy(filename, cdoStreamName(1)->args);
   nchars = strlen(filename);
@@ -102,35 +102,35 @@ void *Harmonic(void *argument)
 
   nvars = vlistNvars(vlistID1);
 
-  out  = (double ***) malloc(n_out*sizeof(double **));
-  work = (double ***) malloc(2*n_out*sizeof(double **));
+  out  = malloc(n_out*sizeof(double **));
+  work = malloc(2*n_out*sizeof(double **));
 
   for ( j = 0; j < n_out; ++j )
     {
-      out[j] = (double **) malloc(nvars*sizeof(double *));
+      out[j] = malloc(nvars*sizeof(double *));
       for ( varID = 0; varID < nvars; ++varID )
 	{
 	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	  nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	  out[j][varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+	  out[j][varID] = malloc(gridsize*nlevel*sizeof(double));
 	}
     }
 
   for ( j = 0; j < n_out*2; ++j )
     {
-      work[j] = (double **) malloc(nvars*sizeof(double *));
+      work[j] = malloc(nvars*sizeof(double *));
       for ( varID = 0; varID < nvars; ++varID )
 	{
 	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	  nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-	  work[j][varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+	  work[j][varID] = malloc(gridsize*nlevel*sizeof(double));
 	  memset(work[j][varID], 0, gridsize*nlevel*sizeof(double));
 	}
     }
 
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Hi.c b/src/Hi.c
index 103fe3d..f882037 100755
--- a/src/Hi.c
+++ b/src/Hi.c
@@ -123,9 +123,9 @@ void *Hi(void *argument)
   field_init(&field1);
   field_init(&field2);
   field_init(&field3);
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr = (double *) malloc(gridsize*sizeof(double));
-  field3.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field2.ptr = malloc(gridsize*sizeof(double));
+  field3.ptr = malloc(gridsize*sizeof(double));
 
   if ( cdoVerbose )
     cdoPrint("Number of timesteps: file1 %d, file2 %d, file3 %d",
diff --git a/src/Histogram.c b/src/Histogram.c
index 2179c14..3bc7ddb 100644
--- a/src/Histogram.c
+++ b/src/Histogram.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -82,7 +82,7 @@ void *Histogram(void *argument)
 
   /* create zaxis for output bins */
   zaxisID2 = zaxisCreate(ZAXIS_GENERIC, nbins);
-  bins = (double *) malloc(nbins*sizeof(double));
+  bins = malloc(nbins*sizeof(double));
   /* for ( i = 0; i < nbins; i++ ) bins[i] = (fltarr[i]+fltarr[i+1])/2; */
   for ( i = 0; i < nbins; i++ ) bins[i] = fltarr[i];
   zaxisDefLevels(zaxisID2, bins);
@@ -112,22 +112,22 @@ void *Histogram(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   nvars = vlistNvars(vlistID2);
-  vardata   = (double **) malloc(nvars*sizeof(double *));
-  varcount  = (double **) malloc(nvars*sizeof(double *));
-  vartcount = (double **) malloc(nvars*sizeof(double *));
+  vardata   = malloc(nvars*sizeof(double *));
+  varcount  = malloc(nvars*sizeof(double *));
+  vartcount = malloc(nvars*sizeof(double *));
   for ( varID = 0; varID < nvars; varID++ )
     {
       gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
-      vardata[varID]  = (double *) malloc(nbins*gridsize*sizeof(double));
-      varcount[varID] = (double *) malloc(nbins*gridsize*sizeof(double));
-      vartcount[varID] = (double *) malloc(gridsize*sizeof(double));
+      vardata[varID]  = malloc(nbins*gridsize*sizeof(double));
+      varcount[varID] = malloc(nbins*gridsize*sizeof(double));
+      vartcount[varID] = malloc(gridsize*sizeof(double));
       memset(vardata[varID], 0, nbins*gridsize*sizeof(double));
       memset(varcount[varID], 0, nbins*gridsize*sizeof(double));
       memset(vartcount[varID], 0, gridsize*sizeof(double));
     }
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID1 = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID1)) )
diff --git a/src/Importamsr.c b/src/Importamsr.c
index e428a39..ce4a38d 100644
--- a/src/Importamsr.c
+++ b/src/Importamsr.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -121,7 +121,7 @@ void read_amsr(FILE *fp, int vlistID, int nvars, double *data[], int *nmiss)
   for ( varID = 0; varID < nvars; ++varID )
     {
       gridsize = gridInqSize(vlistInqVarGrid(vlistID, varID));
-      amsr_data = (unsigned char *) realloc(amsr_data, gridsize);
+      amsr_data = realloc(amsr_data, gridsize);
       size = fread(amsr_data, 1, gridsize, fp);
       if ( (int)size != gridsize ) cdoAbort("Read error!");
 
@@ -228,7 +228,7 @@ void *Importamsr(void *argument)
   if ( fsize == 12441600 )
     {
       nvars = 6;
-      for ( i = 0; i < nvars; ++i ) data[i] = (double *) malloc(gridsize*sizeof(double));
+      for ( i = 0; i < nvars; ++i ) data[i] = malloc(gridsize*sizeof(double));
 
       init_amsr_day(vlistID, gridID, zaxisID, nvars);
 
@@ -253,7 +253,7 @@ void *Importamsr(void *argument)
   else if ( fsize == 5184000 )
     {
       nvars = 5;
-      for ( i = 0; i < nvars; ++i ) data[i] = (double *) malloc(gridsize*sizeof(double));
+      for ( i = 0; i < nvars; ++i ) data[i] = malloc(gridsize*sizeof(double));
 
       init_amsr_averaged(vlistID, gridID, zaxisID, nvars);
 
diff --git a/src/Importbinary.c b/src/Importbinary.c
index ff07af0..d63ae83 100644
--- a/src/Importbinary.c
+++ b/src/Importbinary.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -25,6 +25,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
+#include "grid.h"
 
 #include "gradsdeslib.h"
 
@@ -85,8 +86,8 @@ int y_is_gauss(double *gridyvals, int ysize)
   if ( ysize > 2 )
     {
       double *yvals, *yw;
-      yvals = (double *) malloc(ysize*sizeof(double));
-      yw    = (double *) malloc(ysize*sizeof(double));
+      yvals = malloc(ysize*sizeof(double));
+      yw    = malloc(ysize*sizeof(double));
       gaussaw(yvals, yw, ysize);
       free(yw);
       for ( i = 0; i < (int) ysize; i++ )
@@ -125,8 +126,8 @@ int define_grid(dsets_t *pfi)
   nx = pfi->dnum[0];
   ny = pfi->dnum[1];
 
-  xvals = (double *) malloc(nx*sizeof(double));
-  yvals = (double *) malloc(ny*sizeof(double));
+  xvals = malloc(nx*sizeof(double));
+  yvals = malloc(ny*sizeof(double));
 
   get_dim_vals(pfi, xvals, nx, 0);
   get_dim_vals(pfi, yvals, ny, 1);
@@ -163,7 +164,7 @@ int define_level(dsets_t *pfi, int nlev)
     {
       double *zvals = NULL;
 
-      zvals = (double *) malloc(nz*sizeof(double));
+      zvals = malloc(nz*sizeof(double));
 
       get_dim_vals(pfi, zvals, nz, 2);
 
@@ -251,10 +252,10 @@ void *Importbinary(void *argument)
 
   vlistID = vlistCreate();
 
-  var_zaxisID = (int *) malloc(nvars*sizeof(int));
-  recVarID    = (int *) malloc(nrecs*sizeof(int));
-  recLevelID  = (int *) malloc(nrecs*sizeof(int));
-  var_dfrm    = (int *) malloc(nrecs*sizeof(int));
+  var_zaxisID = malloc(nvars*sizeof(int));
+  recVarID    = malloc(nrecs*sizeof(int));
+  recLevelID  = malloc(nrecs*sizeof(int));
+  var_dfrm    = malloc(nrecs*sizeof(int));
 
   recID = 0;
   for ( ivar = 0; ivar < nvars; ++ivar )
@@ -365,9 +366,9 @@ void *Importbinary(void *argument)
 
   //recsize = pfi.gsiz*4;
   recsize = pfi.gsiz*8;
-  rec = (char *) malloc(recsize);
+  rec = malloc(recsize);
 
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   /*
   if (pfi.tmplat)
diff --git a/src/Importcmsaf.c b/src/Importcmsaf.c
index 18c455f..959912a 100644
--- a/src/Importcmsaf.c
+++ b/src/Importcmsaf.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -177,10 +177,10 @@ int defLonLatGrid(int nx, int ny, double c0, double lts, double re)
       return(-1);
     }
 
-  xvals = (double *) malloc(nx*sizeof(double));
-  yvals = (double *) malloc(ny*sizeof(double));
-  xbounds = (double *) malloc(nx*2*sizeof(double));
-  ybounds = (double *) malloc(nx*2*sizeof(double));
+  xvals = malloc(nx*sizeof(double));
+  yvals = malloc(ny*sizeof(double));
+  xbounds = malloc(nx*2*sizeof(double));
+  ybounds = malloc(nx*2*sizeof(double));
 
   for ( i = 0; i < nx; ++i )
     {
@@ -231,8 +231,8 @@ int defSinusoidalGrid(int nx, int ny, double xmin, double xmax, double ymin, dou
   int i;
   double *xvals, *yvals;
 
-  xvals = (double *) malloc(nx*sizeof(double));
-  yvals = (double *) malloc(ny*sizeof(double));
+  xvals = malloc(nx*sizeof(double));
+  yvals = malloc(ny*sizeof(double));
 
   for ( i = 0; i < nx; ++i )
     {
@@ -266,8 +266,8 @@ int defLaeaGrid(int nx, int ny, double xmin, double xmax, double ymin, double ym
   int i;
   double *xvals, *yvals;
 
-  xvals = (double *) malloc(nx*sizeof(double));
-  yvals = (double *) malloc(ny*sizeof(double));
+  xvals = malloc(nx*sizeof(double));
+  yvals = malloc(ny*sizeof(double));
 
   for ( i = 0; i < nx; ++i )
     {
@@ -1061,7 +1061,7 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
       
       offset = gridsize*(nz-1);
       array  = ((datasets_t *) opdata)->obj[nset].array;
-      array  = (double *) realloc(array, gridsize*nz*nt*sizeof(double));
+      array  = realloc(array, gridsize*nz*nt*sizeof(double));
       ((datasets_t *) opdata)->obj[nset].array    = array;
       array  = array+offset;
 
@@ -1071,7 +1071,7 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
 	    {
 	      float *farray;
 	      int i;
-	      farray = (float *) malloc(gridsize*nt*sizeof(float));
+	      farray = malloc(gridsize*nt*sizeof(float));
 	      status = H5Dread(dset_id, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, farray);
 	      if ( status < 0 )
 		cdoAbort("Reading of NATIVE_FLOAT variable %s failed!", varname);
@@ -1088,7 +1088,7 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
       else
 	{
 	  int *iarray, i;
-	  iarray = (int *) malloc(gridsize*nt*sizeof(int));
+	  iarray = malloc(gridsize*nt*sizeof(int));
 	  status = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, iarray);
 	  if ( status < 0 )
 	    cdoAbort("Reading of NATIVE_INT variable %s failed!", varname);
@@ -1120,7 +1120,7 @@ void read_dataset(hid_t loc_id, const char *name, void *opdata)
 
       if ( nz == 1 ) ((datasets_t *) opdata)->nsets++;
 
-      mask = (short *) malloc(gridsize*nt*sizeof(short));
+      mask = malloc(gridsize*nt*sizeof(short));
       memset(mask, 0, gridsize*nt*sizeof(short));
 
       nmiss  = 0;
@@ -1457,7 +1457,7 @@ void *Importcmsaf(void *argument)
 
   if ( nt > 1 )
     {
-      vtimes = (int *) malloc(nt*sizeof(int));
+      vtimes = malloc(nt*sizeof(int));
       
       for ( i = 0; i < nt; ++i ) vtimes[i] = i*10000 + 45*100;
 
@@ -1513,7 +1513,7 @@ void *Importcmsaf(void *argument)
   else
     {
       double *levels;
-      levels = (double *) malloc(nz*sizeof(double));
+      levels = malloc(nz*sizeof(double));
       for ( i = 0; i < nz; ++i ) levels[i] = i+1;
       zaxisID = zaxisCreate(ZAXIS_GENERIC, nz);
       zaxisDefLevels(zaxisID, levels);
diff --git a/src/Importobs.c b/src/Importobs.c
index 8eca2f9..4fb495a 100644
--- a/src/Importobs.c
+++ b/src/Importobs.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -147,8 +147,8 @@ void *Importobs(void *argument)
 
   // printf("gridsize=%d, xsize=%d, ysize=%d\n", gridsize, xsize, ysize);
 
-  xvals = (double *) malloc(gridsize*sizeof(double));
-  yvals = (double *) malloc(gridsize*sizeof(double));
+  xvals = malloc(gridsize*sizeof(double));
+  yvals = malloc(gridsize*sizeof(double));
 
   gridInqXvals(gridID, xvals);
   gridInqYvals(gridID, yvals);
@@ -178,7 +178,7 @@ void *Importobs(void *argument)
   vlistDefTaxis(vlistID, taxisID);
 
     {
-      for ( i = 0; i < nvars; ++i ) data[i] = (double *) malloc(gridsize*sizeof(double));
+      for ( i = 0; i < nvars; ++i ) data[i] = malloc(gridsize*sizeof(double));
 
       init_vars(vlistID, gridID, zaxisID, nvars);
 
diff --git a/src/Info.c b/src/Info.c
index 9dffd93..c32141a 100644
--- a/src/Info.c
+++ b/src/Info.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -266,7 +266,7 @@ void *Info(void *argument)
       gridsize = vlistGridsizeMax(vlistID);
       if ( vlistNumber(vlistID) != CDI_REAL ) gridsize *= 2;
 
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
 
       indg = 0;
       tsID = 0;
diff --git a/src/Input.c b/src/Input.c
index 49d89e2..b861c47 100644
--- a/src/Input.c
+++ b/src/Input.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -121,7 +121,7 @@ void *Input(void *argument)
 	  time     = 0;
 	  
 	  if ( nrecs == 0 )
-	    array = (double *) malloc(gridsize*sizeof(double));
+	    array = malloc(gridsize*sizeof(double));
 	  
 	  cdoPrint("Enter all %d elements of record %d!", gridsize, nrecs+1);
 	  
@@ -164,7 +164,7 @@ void *Input(void *argument)
 	      if ( gridsize < 0 )
 		cdoAbort("Gridsize must not be negative!", gridsize);
 
-	      array = (double *) malloc(gridsize*sizeof(double));
+	      array = malloc(gridsize*sizeof(double));
 
 	      gridID = gridCreate(GRID_GENERIC, gridsize);
 	    }
@@ -211,7 +211,7 @@ void *Input(void *argument)
 	      if ( gridsize < 0 )
 		cdoAbort("Gridsize must not be negative!", gridsize);
 
-	      array = (double *) malloc(gridsize*sizeof(double));
+	      array = malloc(gridsize*sizeof(double));
 
 	      gridID = gridCreate(GRID_GENERIC, gridsize);
 	      gridDefXsize(gridID, nlon);
diff --git a/src/Intgrid.c b/src/Intgrid.c
index be07400..92e7aa9 100644
--- a/src/Intgrid.c
+++ b/src/Intgrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -53,10 +53,10 @@ int genThinoutGrid(int gridID1, int xinc, int yinc)
 
   if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_LONLAT )
     {
-      xvals1 = (double *) malloc(nlon1*sizeof(double));
-      yvals1 = (double *) malloc(nlat1*sizeof(double));
-      xvals2 = (double *) malloc(nlon2*sizeof(double));
-      yvals2 = (double *) malloc(nlat2*sizeof(double));
+      xvals1 = malloc(nlon1*sizeof(double));
+      yvals1 = malloc(nlat1*sizeof(double));
+      xvals2 = malloc(nlon2*sizeof(double));
+      yvals2 = malloc(nlat2*sizeof(double));
       gridInqXvals(gridID1, xvals1);
       gridInqYvals(gridID1, yvals1);
 
@@ -112,19 +112,19 @@ int genBoxavgGrid(int gridID1, int xinc, int yinc)
 
   if ( gridtype == GRID_GAUSSIAN || gridtype == GRID_LONLAT )
     {
-      xvals1 = (double *) malloc(nlon1*sizeof(double));
-      yvals1 = (double *) malloc(nlat1*sizeof(double));
-      xvals2 = (double *) malloc(nlon2*sizeof(double));
-      yvals2 = (double *) malloc(nlat2*sizeof(double));
+      xvals1 = malloc(nlon1*sizeof(double));
+      yvals1 = malloc(nlat1*sizeof(double));
+      xvals2 = malloc(nlon2*sizeof(double));
+      yvals2 = malloc(nlat2*sizeof(double));
       gridInqXvals(gridID1, xvals1);
       gridInqYvals(gridID1, yvals1);
 
       if ( gridInqYbounds(gridID1, NULL) && gridInqXbounds(gridID1, NULL) )
 	{
-	  grid1_corner_lon = (double *) malloc(2*nlon1*sizeof(double));
-	  grid1_corner_lat = (double *) malloc(2*nlat1*sizeof(double));
-	  grid2_corner_lon = (double *) malloc(2*nlon2*sizeof(double));
-	  grid2_corner_lat = (double *) malloc(2*nlat2*sizeof(double));
+	  grid1_corner_lon = malloc(2*nlon1*sizeof(double));
+	  grid1_corner_lat = malloc(2*nlat1*sizeof(double));
+	  grid2_corner_lon = malloc(2*nlon2*sizeof(double));
+	  grid2_corner_lat = malloc(2*nlat2*sizeof(double));
 	  gridInqXbounds(gridID1, grid1_corner_lon);
 	  gridInqYbounds(gridID1, grid1_corner_lat);
 	}
@@ -204,13 +204,13 @@ void boxavg(field_t *field1, field_t *field2, int xinc, int yinc)
   nlon2 = gridInqXsize(gridID2);
   nlat2 = gridInqYsize(gridID2);
 
-  xfield1 = (double **) malloc(nlat1*sizeof(double *));
+  xfield1 = malloc(nlat1*sizeof(double *));
 
   for ( ilat = 0; ilat < nlat1; ilat++ )
     xfield1[ilat] = array1 + ilat*nlon1;
 
 
-  xfield2 = (double **) malloc(nlat2 * sizeof(double *));
+  xfield2 = malloc(nlat2 * sizeof(double *));
 
   for ( ilat = 0; ilat < nlat2; ilat++ )
     xfield2[ilat] = array2 + ilat*nlon2;
@@ -272,12 +272,12 @@ void thinout(field_t *field1, field_t *field2, int xinc, int yinc)
   nlon2 = gridInqXsize(gridID2);
   nlat2 = gridInqYsize(gridID2);
 
-  xfield1 = (double **) malloc(nlat1*sizeof(double *));
+  xfield1 = malloc(nlat1*sizeof(double *));
 
   for ( ilat = 0; ilat < nlat1; ilat++ )
     xfield1[ilat] = array1 + ilat*nlon1;
 
-  xfield2 = (double **) malloc(nlat2*sizeof(double *));
+  xfield2 = malloc(nlat2*sizeof(double *));
 
   for ( ilat = 0; ilat < nlat2; ilat++ )
     xfield2[ilat] = array2 + ilat*nlon2;
@@ -408,10 +408,10 @@ void *Intgrid(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array1   = (double *) malloc(gridsize*sizeof(double));
+  array1   = malloc(gridsize*sizeof(double));
 
   gridsize = gridInqSize(gridID2);
-  array2   = (double *) malloc(gridsize*sizeof(double));
+  array2   = malloc(gridsize*sizeof(double));
 
   field_init(&field1);
   field_init(&field2);
diff --git a/src/Intgridtraj.c b/src/Intgridtraj.c
index 1507d84..2143888 100644
--- a/src/Intgridtraj.c
+++ b/src/Intgridtraj.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -100,21 +100,21 @@ void *Intgridtraj(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
-  vardata1 = (double **) malloc(nvars*sizeof(double*));
-  vardata2 = (double **) malloc(nvars*sizeof(double*));
+  vardata1 = malloc(nvars*sizeof(double*));
+  vardata2 = malloc(nvars*sizeof(double*));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
       gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
       nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      vardata1[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
-      vardata2[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+      vardata1[varID] = malloc(gridsize*nlevel*sizeof(double));
+      vardata2[varID] = malloc(gridsize*nlevel*sizeof(double));
     }
 
   gridID2 = gridCreate(GRID_TRAJECTORY, 1);
diff --git a/src/Intlevel.c b/src/Intlevel.c
index eaae403..6d890d4 100644
--- a/src/Intlevel.c
+++ b/src/Intlevel.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -231,7 +231,7 @@ void *Intlevel(void *argument)
   if ( i == nzaxis ) cdoAbort("No processable variable found!");
 
   nlev1 = nlevel;
-  lev1  = (double *) malloc((nlev1+2)*sizeof(double));
+  lev1  = malloc((nlev1+2)*sizeof(double));
   zaxisInqLevels(zaxisID1, lev1+1);
 
   lup = FALSE;
@@ -273,10 +273,10 @@ void *Intlevel(void *argument)
 
   if ( cdoVerbose ) for ( i = 0; i < nlev1+2; ++i ) printf("lev1 %d: %g\n", i, lev1[i]);
 
-  lev_idx1 = (int *) malloc(nlev2*sizeof(int));
-  lev_idx2 = (int *) malloc(nlev2*sizeof(int));
-  lev_wgt1 = (double *) malloc(nlev2*sizeof(double));
-  lev_wgt2 = (double *) malloc(nlev2*sizeof(double));
+  lev_idx1 = malloc(nlev2*sizeof(int));
+  lev_idx2 = malloc(nlev2*sizeof(int));
+  lev_wgt1 = malloc(nlev2*sizeof(double));
+  lev_wgt2 = malloc(nlev2*sizeof(double));
 
   gen_weights(expol, nlev1+2, lev1, nlev2, lev2, lev_idx1, lev_idx2, lev_wgt1, lev_wgt2);
 
@@ -307,11 +307,11 @@ void *Intlevel(void *argument)
 
   nvars = vlistNvars(vlistID1);
 
-  vars      = (int *) malloc(nvars*sizeof(int));
-  vardata1  = (double **) malloc(nvars*sizeof(double*));
-  vardata2  = (double **) malloc(nvars*sizeof(double*));
-  varnmiss  = (int **) malloc(nvars*sizeof(int*));
-  varinterp = (int *) malloc(nvars*sizeof(int));
+  vars      = malloc(nvars*sizeof(int));
+  vardata1  = malloc(nvars*sizeof(double*));
+  vardata2  = malloc(nvars*sizeof(double*));
+  varnmiss  = malloc(nvars*sizeof(int*));
+  varinterp = malloc(nvars*sizeof(int));
 
   maxlev   = nlev1 > nlev2 ? nlev1 : nlev2;
 
@@ -322,20 +322,20 @@ void *Intlevel(void *argument)
       gridsize = gridInqSize(gridID);
       nlevel   = zaxisInqSize(zaxisID);
 
-      vardata1[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+      vardata1[varID] = malloc(gridsize*nlevel*sizeof(double));
 
       if ( zaxisID == zaxisID1 )
 	{
 	  varinterp[varID] = TRUE;
-	  vardata2[varID]  = (double *) malloc(gridsize*nlev2*sizeof(double));
-	  varnmiss[varID]  = (int *) malloc(maxlev*sizeof(int));
+	  vardata2[varID]  = malloc(gridsize*nlev2*sizeof(double));
+	  varnmiss[varID]  = malloc(maxlev*sizeof(int));
 	  memset(varnmiss[varID], 0, maxlev*sizeof(int));
 	}
       else
 	{
 	  varinterp[varID] = FALSE;
 	  vardata2[varID]  = vardata1[varID];
-	  varnmiss[varID]  = (int *) malloc(nlevel*sizeof(int));
+	  varnmiss[varID]  = malloc(nlevel*sizeof(int));
 	}
     }
 
diff --git a/src/Intlevel3d.c b/src/Intlevel3d.c
index 36f34fc..04d6b4e 100644
--- a/src/Intlevel3d.c
+++ b/src/Intlevel3d.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -266,12 +266,12 @@ void *Intlevel3d(void *argument)
 
     nlonIn  = gridInqXsize(gridID);
     nlatIn  = gridInqYsize(gridID);
-    lonIn   = (double *) malloc(nlonIn*sizeof(double));
-    latIn   = (double *) malloc(nlatIn*sizeof(double));
+    lonIn   = malloc(nlonIn*sizeof(double));
+    latIn   = malloc(nlatIn*sizeof(double));
     gridInqXvals(gridID, lonIn);
     gridInqYvals(gridID, latIn);
 
-    zlevels_in = (double *) malloc(gridsize*(nlevel+2)*sizeof(double*));
+    zlevels_in = malloc(gridsize*(nlevel+2)*sizeof(double*));
     nlevi      = nlevel;   /* number of input levels for later use */
     gridsizei  = gridsize; /* horizontal gridsize of input z coordinate */
     nrecs      = streamInqTimestep(streamID0, 0);
@@ -302,12 +302,12 @@ void *Intlevel3d(void *argument)
 
     nlonOut = gridInqXsize(gridID);
     nlatOut = gridInqYsize(gridID);
-    lonOut  = (double *) malloc(nlonOut*sizeof(double));
-    latOut  = (double *) malloc(nlatOut*sizeof(double));
+    lonOut  = malloc(nlonOut*sizeof(double));
+    latOut  = malloc(nlatOut*sizeof(double));
     gridInqXvals(gridID, lonOut);
     gridInqYvals(gridID, latOut);
 
-    zlevels_out = (double *) malloc(gridsize*nlevel*sizeof(double));
+    zlevels_out = malloc(gridsize*nlevel*sizeof(double));
     nlevo       = nlevel;  /* number of output levels for later use */
     gridsizeo   = gridsize;/* horizontal gridsize of output z coordinate */
     nrecs       = streamInqTimestep(streamID2, 0);
@@ -427,10 +427,10 @@ void *Intlevel3d(void *argument)
   /*
    * Create weights for later interpolation - assumption: input vertical correct is constant in time
    */
-  lev_idx1 = (int *)    malloc(nlevo*gridSize*sizeof(int));
-  lev_idx2 = (int *)    malloc(nlevo*gridSize*sizeof(int));
-  lev_wgt1 = (double *) malloc(nlevo*gridSize*sizeof(double));
-  lev_wgt2 = (double *) malloc(nlevo*gridSize*sizeof(double));
+  lev_idx1 = malloc(nlevo*gridSize*sizeof(int));
+  lev_idx2 = malloc(nlevo*gridSize*sizeof(int));
+  lev_wgt1 = malloc(nlevo*gridSize*sizeof(double));
+  lev_wgt2 = malloc(nlevo*gridSize*sizeof(double));
 
   gen_weights3d(expol, nlevi+2, gridSize, zlevels_in, nlevo, zlevels_out, lev_idx1, lev_idx2, lev_wgt1, lev_wgt2);
 
@@ -438,7 +438,7 @@ void *Intlevel3d(void *argument)
    * Copy z-axis information to output z-axis
    */
   zaxisID3 = zaxisCreate(zaxisInqType(zaxisID1), nlevo);
-  lev2 = (double *) malloc(nlevo*sizeof(double));
+  lev2 = malloc(nlevo*sizeof(double));
   /* fill values with its indices */
   for (i=0;i<nlevo;i++)
     lev2[i] = (double) i;
@@ -470,11 +470,11 @@ void *Intlevel3d(void *argument)
 
   maxlev   = nlevi > nlevo ? nlevi : nlevo;
   nvars     = vlistNvars(vlistID1);
-  vars      = (int *)     malloc(nvars*sizeof(int));
-  vardata1  = (double **) malloc(nvars*sizeof(double*)); /* input                                         */
-  vardata2  = (double **) malloc(nvars*sizeof(double*)); /* output                                        */
-  varnmiss  = (int **)    malloc(nvars*sizeof(int*));    /* can for missing values of arbitrary variables */
-  varinterp = (int *)     malloc(nvars*sizeof(int));     /* marker for variables to be interpolated       */
+  vars      = malloc(nvars*sizeof(int));
+  vardata1  = malloc(nvars*sizeof(double*)); /* input                                         */
+  vardata2  = malloc(nvars*sizeof(double*)); /* output                                        */
+  varnmiss  = malloc(nvars*sizeof(int*));    /* can for missing values of arbitrary variables */
+  varinterp = malloc(nvars*sizeof(int));     /* marker for variables to be interpolated       */
 
   /* by default no variable should be interpolated */
   for (i = 0; i < nvars;i++)
@@ -489,7 +489,7 @@ void *Intlevel3d(void *argument)
 
       vlistInqVarName(vlistID1, varID, varname);
 
-      vardata1[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+      vardata1[varID] = malloc(gridsize*nlevel*sizeof(double));
 
       /*  variabls for interpolation:
        *  * have the required vertical axis, i.e. the correct number of levels (nlevi)
@@ -500,8 +500,8 @@ void *Intlevel3d(void *argument)
         {
           nlonIn  = gridInqXsize(gridID);
           nlatIn  = gridInqYsize(gridID);
-          lonIn   = (double *) malloc(nlonIn*sizeof(double));
-          latIn   = (double *) malloc(nlatIn*sizeof(double));
+          lonIn   = malloc(nlonIn*sizeof(double));
+          latIn   = malloc(nlatIn*sizeof(double));
           gridInqXvals(gridID, lonIn);
           gridInqYvals(gridID, latIn);
 
@@ -512,14 +512,14 @@ void *Intlevel3d(void *argument)
             {
               varinterp[varID] = FALSE;
               vardata2[varID]  = vardata1[varID];
-              varnmiss[varID]  = (int *) malloc(nlevel*sizeof(int));
+              varnmiss[varID]  = malloc(nlevel*sizeof(int));
               if ( cdoVerbose ) cdoPrint("Ignore variable %s with %d levels\n",varname,nlevel);
             }
           else
             {
               varinterp[varID] = TRUE;
-              vardata2[varID]  = (double *) malloc(gridsize*nlevo*sizeof(double));
-              varnmiss[varID]  = (int *) malloc(maxlev*sizeof(int));
+              vardata2[varID]  = malloc(gridsize*nlevo*sizeof(double));
+              varnmiss[varID]  = malloc(maxlev*sizeof(int));
               memset(varnmiss[varID], 0, maxlev*sizeof(int));
             }
         }
@@ -527,7 +527,7 @@ void *Intlevel3d(void *argument)
         {
           varinterp[varID] = FALSE;
           vardata2[varID]  = vardata1[varID];
-          varnmiss[varID]  = (int *) malloc(nlevel*sizeof(int));
+          varnmiss[varID]  = malloc(nlevel*sizeof(int));
           if ( cdoVerbose ) cdoPrint("Ignore variable %s with %d levels\n",varname,nlevel);
         }
       }
diff --git a/src/Intntime.c b/src/Intntime.c
index b1356fa..0837d9d 100644
--- a/src/Intntime.c
+++ b/src/Intntime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -68,25 +68,25 @@ void *Intntime(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
-  nmiss1   = (int **) malloc(nvars*sizeof(int *));
-  nmiss2   = (int **) malloc(nvars*sizeof(int *));
-  vardata1 = (double **) malloc(nvars*sizeof(double *));
-  vardata2 = (double **) malloc(nvars*sizeof(double *));
+  nmiss1   = malloc(nvars*sizeof(int *));
+  nmiss2   = malloc(nvars*sizeof(int *));
+  vardata1 = malloc(nvars*sizeof(double *));
+  vardata2 = malloc(nvars*sizeof(double *));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
       gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
       nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      nmiss1[varID]   = (int *) malloc(nlevel*sizeof(int));
-      nmiss2[varID]   = (int *) malloc(nlevel*sizeof(int));
-      vardata1[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
-      vardata2[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+      nmiss1[varID]   = malloc(nlevel*sizeof(int));
+      nmiss2[varID]   = malloc(nlevel*sizeof(int));
+      vardata1[varID] = malloc(gridsize*nlevel*sizeof(double));
+      vardata2[varID] = malloc(gridsize*nlevel*sizeof(double));
     }
 
   taxisID1 = vlistInqTaxis(vlistID1);
diff --git a/src/Inttime.c b/src/Inttime.c
index 5d3b978..8cf4472 100644
--- a/src/Inttime.c
+++ b/src/Inttime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -92,7 +92,8 @@ void *Inttime(void *argument)
   if ( operatorArgc() == 3 )
     {
       const char *timeunits = operatorArgv()[2];
-      incperiod = (int)strtol(timeunits, NULL, 10);;
+      incperiod = (int)strtol(timeunits, NULL, 10);
+      if ( timeunits[0] == '-' || timeunits[0] == '+' ) timeunits++;
       while ( isdigit((int) *timeunits) ) timeunits++;
 
       get_tunits(timeunits, &incperiod, &incunit, &tunit);
@@ -110,25 +111,25 @@ void *Inttime(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
-  nmiss1   = (int **) malloc(nvars*sizeof(int *));
-  nmiss2   = (int **) malloc(nvars*sizeof(int *));
-  vardata1 = (double **) malloc(nvars*sizeof(double *));
-  vardata2 = (double **) malloc(nvars*sizeof(double *));
+  nmiss1   = malloc(nvars*sizeof(int *));
+  nmiss2   = malloc(nvars*sizeof(int *));
+  vardata1 = malloc(nvars*sizeof(double *));
+  vardata2 = malloc(nvars*sizeof(double *));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
       gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
       nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      nmiss1[varID]   = (int *) malloc(nlevel*sizeof(int));
-      nmiss2[varID]   = (int *) malloc(nlevel*sizeof(int));
-      vardata1[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
-      vardata2[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+      nmiss1[varID]   = malloc(nlevel*sizeof(int));
+      nmiss2[varID]   = malloc(nlevel*sizeof(int));
+      vardata1[varID] = malloc(gridsize*nlevel*sizeof(double));
+      vardata2[varID] = malloc(gridsize*nlevel*sizeof(double));
     }
 
   taxisID1 = vlistInqTaxis(vlistID1);
diff --git a/src/Intyear.c b/src/Intyear.c
index 22b6198..ea58b71 100644
--- a/src/Intyear.c
+++ b/src/Intyear.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -60,7 +60,7 @@ void *Intyear(void *argument)
 
   iyears = (int *) listArrayPtr(ilist);
 
-  streamIDs = (int *) malloc(nyears*sizeof(int));
+  streamIDs = malloc(nyears*sizeof(int));
 
   streamID1 = streamOpenRead(cdoStreamName(0));
   streamID2 = streamOpenRead(cdoStreamName(1));
@@ -72,9 +72,9 @@ void *Intyear(void *argument)
   vlistCompare(vlistID1, vlistID2, CMP_ALL);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
-  array3 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
+  array3 = malloc(gridsize*sizeof(double));
 
   taxisID1 = vlistInqTaxis(vlistID1);
   taxisID2 = vlistInqTaxis(vlistID2);
diff --git a/src/Invert.c b/src/Invert.c
index 534bad4..6566cd2 100644
--- a/src/Invert.c
+++ b/src/Invert.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -66,8 +66,8 @@ void invertLonDes(int vlistID)
 	  else
             size = nlon;
 
-	  xv1 = (double *) malloc(size*sizeof(double));
-	  xv2 = (double *) malloc(size*sizeof(double));
+	  xv1 = malloc(size*sizeof(double));
+	  xv2 = malloc(size*sizeof(double));
 
 	  gridInqXvals(gridID1, xv1);
 
@@ -101,8 +101,8 @@ void invertLonDes(int vlistID)
 	  else
             size = nv*nlon;
 
-	  xb1 = (double *) malloc(size*sizeof(double));
-	  xb2 = (double *) malloc(size*sizeof(double));
+	  xb1 = malloc(size*sizeof(double));
+	  xb2 = malloc(size*sizeof(double));
 
 	  gridInqXbounds(gridID1, xb1);
 
@@ -165,8 +165,8 @@ void invertLatDes(int vlistID)
 	  else
             size = nlat;
 
-	  yv1 = (double *) malloc(size*sizeof(double));
-	  yv2 = (double *) malloc(size*sizeof(double));
+	  yv1 = malloc(size*sizeof(double));
+	  yv2 = malloc(size*sizeof(double));
 
 
 	  if ( gridtype == GRID_CURVILINEAR )
@@ -213,8 +213,8 @@ void invertLatDes(int vlistID)
 	  else
             size = nv*nlat;
 
-	  yb1 = (double *) malloc(size*sizeof(double));
-	  yb2 = (double *) malloc(size*sizeof(double));
+	  yb1 = malloc(size*sizeof(double));
+	  yb2 = malloc(size*sizeof(double));
 
 	  gridInqYbounds(gridID1, yb1);
 
@@ -256,8 +256,8 @@ void invertLonData(double *array1, double *array2, int gridID1)
 
   if ( nlat > 0 )
     {
-      field1 = (double **) malloc(nlat*sizeof(double *));
-      field2 = (double **) malloc(nlat*sizeof(double *));
+      field1 = malloc(nlat*sizeof(double *));
+      field2 = malloc(nlat*sizeof(double *));
   
       for ( ilat = 0; ilat < nlat; ilat++ )
 	{
@@ -290,8 +290,8 @@ void invertLatData(double *array1, double *array2, int gridID1)
 
   if ( nlat > 0 )
     {
-      field1 = (double **) malloc(nlat*sizeof(double *));
-      field2 = (double **) malloc(nlat*sizeof(double *));
+      field1 = malloc(nlat*sizeof(double *));
+      field2 = malloc(nlat*sizeof(double *));
   
       for ( ilat = 0; ilat < nlat; ilat++ )
 	{
@@ -366,8 +366,8 @@ void *Invert(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Invertlev.c b/src/Invertlev.c
index c645f1f..3dacd13 100644
--- a/src/Invertlev.c
+++ b/src/Invertlev.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -55,8 +55,8 @@ void invertLevDes(int vlistID)
       /* if ( zaxisInqLevels(zaxisID1, NULL) ) */
 	{
 
-	  yv1 = (double *) malloc(nlev*sizeof(double));
-	  yv2 = (double *) malloc(nlev*sizeof(double));
+	  yv1 = malloc(nlev*sizeof(double));
+	  yv2 = malloc(nlev*sizeof(double));
 
 	  zaxisInqLevels(zaxisID1, yv1);
 	  for ( ilev = 0; ilev < nlev; ++ilev ) yv2[nlev-ilev-1] = yv1[ilev];
@@ -68,8 +68,8 @@ void invertLevDes(int vlistID)
 
       if ( zaxisInqLbounds(zaxisID1, NULL) && zaxisInqUbounds(zaxisID1, NULL) )
 	{
-	  yb1 = (double *) malloc(nlev*sizeof(double));
-	  yb2 = (double *) malloc(nlev*sizeof(double));
+	  yb1 = malloc(nlev*sizeof(double));
+	  yb2 = malloc(nlev*sizeof(double));
 
 	  zaxisInqLbounds(zaxisID1, yb1);
 	  for ( ilev = 0; ilev < nlev; ++ilev ) yb2[nlev-ilev-1] = yb1[ilev];
@@ -137,12 +137,12 @@ void *Invertlev(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   nvars = vlistNvars(vlistID1);
 
-  vardata  = (double **) malloc(nvars*sizeof(double*));
-  varnmiss = (int **) malloc(nvars*sizeof(int*));
+  vardata  = malloc(nvars*sizeof(double*));
+  varnmiss = malloc(nvars*sizeof(int*));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
@@ -160,8 +160,8 @@ void *Invertlev(void *argument)
       else
 	{
 	  linvert = TRUE;
-	  vardata[varID]  = (double *) malloc(gridsize*nlev*sizeof(double));
-	  varnmiss[varID] = (int *) malloc(nlev*sizeof(int));
+	  vardata[varID]  = malloc(gridsize*nlev*sizeof(double));
+	  varnmiss[varID] = malloc(nlev*sizeof(int));
 	}
     }
 
diff --git a/src/Isosurface.c b/src/Isosurface.c
index 0713b54..ef81b0d 100644
--- a/src/Isosurface.c
+++ b/src/Isosurface.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -135,7 +135,7 @@ void *Isosurface(void *argument)
   if ( i == nzaxis ) cdoAbort("No processable variable found!");
 
   nlev1 = nlevel;
-  lev1  = (double *) malloc((nlev1)*sizeof(double));
+  lev1  = malloc((nlev1)*sizeof(double));
   zaxisInqLevels(zaxisID1, lev1);
 
   zaxisIDsfc = zaxisCreate(ZAXIS_SURFACE, 1);
@@ -150,13 +150,13 @@ void *Isosurface(void *argument)
   gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   nvars = vlistNvars(vlistID1);
 
-  liso  =     (int *) malloc(nvars*sizeof(int));
-  vars  =     (int *) malloc(nvars*sizeof(int));
-  vars1 = (field_t *) malloc(nvars*sizeof(field_t));
+  liso  =     malloc(nvars*sizeof(int));
+  vars  =     malloc(nvars*sizeof(int));
+  vars1 = malloc(nvars*sizeof(field_t));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
@@ -176,7 +176,7 @@ void *Isosurface(void *argument)
       vars1[varID].zaxis   = zaxisID;
       vars1[varID].nmiss   = 0;
       vars1[varID].missval = missval;
-      vars1[varID].ptr     = (double *) malloc(gridsize*nlevel*sizeof(double));
+      vars1[varID].ptr     = malloc(gridsize*nlevel*sizeof(double));
     }
 
   tsID = 0;
diff --git a/src/Kvl.c b/src/Kvl.c
index 11fce76..26cb43f 100644
--- a/src/Kvl.c
+++ b/src/Kvl.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Log.c b/src/Log.c
index 6ba50ed..c320abb 100644
--- a/src/Log.c
+++ b/src/Log.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Maggraph.c b/src/Maggraph.c
index b2262a3..8a8ff7d 100644
--- a/src/Maggraph.c
+++ b/src/Maggraph.c
@@ -256,20 +256,20 @@ void maggraph(const char *plotfile, const char *varname,const char *varunits, lo
   if ( stat == TRUE )
     {
 	/* if all files are of same number of steps, only one date_time_str array is being used */
-        date_time_str[0] = (char **)malloc( ntime_steps*sizeof(char *) ); 
+        date_time_str[0] = malloc( ntime_steps*sizeof(char *) ); 
 	
-	date_time   = (double *) malloc( ntime_steps*sizeof(double) );
-	mean_val    = (double *) malloc( ntime_steps*sizeof(double) );
-	std_dev_val = (double *) malloc( ntime_steps*sizeof(double) );
-	spread_min  = (double *) malloc( ntime_steps*sizeof(double) );
-	spread_max  = (double *) malloc( ntime_steps*sizeof(double) );
+	date_time   = malloc( ntime_steps*sizeof(double) );
+	mean_val    = malloc( ntime_steps*sizeof(double) );
+	std_dev_val = malloc( ntime_steps*sizeof(double) );
+	spread_min  = malloc( ntime_steps*sizeof(double) );
+	spread_max  = malloc( ntime_steps*sizeof(double) );
 	
 	for ( tsID = 0; tsID < ntime_steps; ++tsID )
 	  {
 	    date_time[tsID] = tsID+1;
 	    date2str(vdate[0][tsID], vdatestr, sizeof(vdatestr));
 	    time2str(vtime[0][tsID], vtimestr, sizeof(vtimestr));
-	    date_time_str[0][tsID] = (char *)malloc(256);
+	    date_time_str[0][tsID] = malloc(256);
 	    sprintf(date_time_str[0][tsID], "%s %s", vdatestr, vtimestr);
 	    mean_val[tsID] = 0.;
 	    std_dev_val[tsID] = 0.;
@@ -358,8 +358,8 @@ void maggraph(const char *plotfile, const char *varname,const char *varunits, lo
 	{
 	  if ( DBG )
 	    fprintf(stderr,"FILE  %ld\n", fileID );
-	  date_time             = (double *) malloc( nts[fileID]*sizeof(double) );
-	  date_time_str[fileID] = (char **)malloc( nts[fileID]*sizeof(char *) );
+	  date_time             = malloc( nts[fileID]*sizeof(double) );
+	  date_time_str[fileID] = malloc( nts[fileID]*sizeof(char *) );
 	  
 	  for ( tsID = 0; tsID <  nts[fileID]; ++tsID )
 	    {
@@ -367,7 +367,7 @@ void maggraph(const char *plotfile, const char *varname,const char *varunits, lo
 	      date2str(vdate[fileID][tsID], vdatestr, sizeof(vdatestr));
 	      time2str(vtime[fileID][tsID], vtimestr, sizeof(vtimestr));
 	      
-	      date_time_str[fileID][tsID] = (char *)malloc(256);
+	      date_time_str[fileID][tsID] = malloc(256);
 	      sprintf(date_time_str[fileID][tsID], "%s %s", vdatestr, vtimestr);
 	      if ( DBG )
 		fprintf( stderr,"%s %s %s\n", vdatestr, vtimestr, date_time_str[fileID][tsID] );
@@ -668,7 +668,7 @@ void maggraph(const char *plotfile, const char *varname,const char *varunits, lo
     }
   
   
-  lines[0] = (char *)malloc(1024);
+  lines[0] = malloc(1024);
   /* To be obtained from Meta Data */
   /*sprintf( lines[0],"%s","ExpID : " );*/ 
   /*sprintf( lines[0],"%sxxxx  Variable : %s[%s]",lines[0], varname, varunits );*/
@@ -824,10 +824,10 @@ void *Maggraph(void *argument)
        fprintf( stderr," files %s\n",ofilename );
     }
 	
-  datatab = (double **) malloc(nfiles*sizeof(double *));
-  vdate   = (int **) malloc(nfiles*sizeof(int *));
-  vtime   = (int **) malloc(nfiles*sizeof(int *));
-  nts     = (long *) malloc(nfiles*sizeof(long));
+  datatab = malloc(nfiles*sizeof(double *));
+  vdate   = malloc(nfiles*sizeof(int *));
+  vtime   = malloc(nfiles*sizeof(int *));
+  nts     = malloc(nfiles*sizeof(long));
   
   for ( fileID = 0; fileID < nfiles; fileID++ )
     {
@@ -876,9 +876,9 @@ void *Maggraph(void *argument)
 	  if ( tsID == 0 )
 	    {
 	      nts_alloc += NINC_ALLOC;
-	      datatab[ fileID ] = (double *) malloc( nts_alloc*sizeof(double) );
-	      vdate[ fileID ]   = (int *) malloc(  nts_alloc*sizeof(int) );
-	      vtime[ fileID ]   = (int *) malloc(  nts_alloc*sizeof(int) );
+	      datatab[ fileID ] = malloc( nts_alloc*sizeof(double) );
+	      vdate[ fileID ]   = malloc(  nts_alloc*sizeof(int) );
+	      vtime[ fileID ]   = malloc(  nts_alloc*sizeof(int) );
 	    }
 		
 	  nts[ fileID ]++;
@@ -886,9 +886,9 @@ void *Maggraph(void *argument)
 	  if ( nts[ fileID ] > nts_alloc )
 	    {
 	      nts_alloc += NINC_ALLOC;
-	      datatab[ fileID ] = (double *) realloc(datatab[fileID], nts_alloc*sizeof(double));
-	      vdate[ fileID ]   = (int *) realloc(vdate[fileID], nts_alloc*sizeof(int));
-	      vtime[ fileID ]   = (int *) realloc(vtime[fileID], nts_alloc*sizeof(int));
+	      datatab[ fileID ] = realloc(datatab[fileID], nts_alloc*sizeof(double));
+	      vdate[ fileID ]   = realloc(vdate[fileID], nts_alloc*sizeof(int));
+	      vtime[ fileID ]   = realloc(vtime[fileID], nts_alloc*sizeof(int));
 	    }
 	  
 	  streamInqRecord( streamID, &varID, &levelID );
diff --git a/src/Magplot.c b/src/Magplot.c
index a8ac8d0..9875333 100644
--- a/src/Magplot.c
+++ b/src/Magplot.c
@@ -549,9 +549,9 @@ void *Magplot(void *argument)
   nlat     = gridInqYsize(gridID);
   nlev     = zaxisInqSize(zaxisID);
 
-  array           = (double *) malloc(gridsize*sizeof(double));
-  grid_center_lat = (double *) malloc(gridsize*sizeof(double));
-  grid_center_lon = (double *) malloc(gridsize*sizeof(double));
+  array           = malloc(gridsize*sizeof(double));
+  grid_center_lat = malloc(gridsize*sizeof(double));
+  grid_center_lon = malloc(gridsize*sizeof(double));
 
   gridInqYvals(gridID, grid_center_lat);
   gridInqXvals(gridID, grid_center_lon);
@@ -931,7 +931,7 @@ void VerifyPlotParameters( int num_param, char **param_names, int opID )
 			  if( syntax == TRUE )
 			    {
 	                       NUM_LEVELS = split_str_count;
-	                       LEV_LIST = ( double *) malloc( sizeof( double ) * split_str_count );
+	                       LEV_LIST = malloc( sizeof( double ) * split_str_count );
 			       for( k = 0; k < split_str_count; k++ )
 		                 {
 		                    LEV_LIST[k] = atof( split_str1[k] );
diff --git a/src/Magvector.c b/src/Magvector.c
index 8f2c02a..1395ec0 100644
--- a/src/Magvector.c
+++ b/src/Magvector.c
@@ -291,10 +291,10 @@ void *Magvector(void *argument)
   nlat     = gridInqYsize(gridID);
   nlev     = zaxisInqSize(zaxisID);
 
-  uarray          = (double *) malloc(gridsize*sizeof(double));
-  varray          = (double *) malloc(gridsize*sizeof(double));
-  grid_center_lat = (double *) malloc(gridsize*sizeof(double));
-  grid_center_lon = (double *) malloc(gridsize*sizeof(double));
+  uarray          = malloc(gridsize*sizeof(double));
+  varray          = malloc(gridsize*sizeof(double));
+  grid_center_lat = malloc(gridsize*sizeof(double));
+  grid_center_lon = malloc(gridsize*sizeof(double));
 
   gridInqYvals(gridID, grid_center_lat);
   gridInqXvals(gridID, grid_center_lon);
diff --git a/src/Makefile.am b/src/Makefile.am
index 5d846c0..b627bec 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -270,6 +270,9 @@ cdo_SOURCES += Adisit.c        \
                remaplib.c      \
                remapsort.c     \
                remap_scrip_io.c \
+               remap_search_latbins.c \
+               stdnametable.c  \
+               stdnametable.h  \
                specspace.c     \
                specspace.h     \
                statistic.c     \
@@ -284,6 +287,23 @@ cdo_SOURCES += Adisit.c        \
                vinterp.h       \
                zaxis.c
 
+cdo_SOURCES += clipping/clipping.c           \
+               clipping/clipping.h           \
+               clipping/area.c               \
+               clipping/area.h               \
+               clipping/ensure_array_size.c  \
+               clipping/ensure_array_size.h  \
+               clipping/geometry_tools.c     \
+               clipping/geometry.h           \
+               clipping/grid.h               \
+               clipping/points.h             \
+               clipping/dep_list.h           \
+               clipping/grid_cell.c          \
+               clipping/grid_cell.h          \
+               clipping/intersection.c       \
+               clipping/utils.c              \
+               clipping/utils.h 
+
 if ENABLE_MAGICS
 cdo_SOURCES += Magplot.c       \
                Magvector.c     \
diff --git a/src/Makefile.in b/src/Makefile.in
index ee1ee48..70e7a09 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -134,14 +134,20 @@ am__cdo_SOURCES_DIST = cdo.c Adisit.c Arith.c Arithc.c Arithdays.c \
 	percentiles.h pipe.c pipe.h printinfo.h process.c process.h \
 	pstream.c pstream.h pstream_int.h pthread_debug.c \
 	pthread_debug.h readline.c realtime.c remap.h remaplib.c \
-	remapsort.c remap_scrip_io.c specspace.c specspace.h \
+	remapsort.c remap_scrip_io.c remap_search_latbins.c \
+	stdnametable.c stdnametable.h specspace.c specspace.h \
 	statistic.c statistic.h table.c timebase.h timer.c userlog.c \
-	util.c util.h vinterp.c vinterp.h zaxis.c Magplot.c \
-	Magvector.c Maggraph.c template_parser.h template_parser.c \
-	results_template_parser.h results_template_parser.c \
-	magics_template_parser.h magics_template_parser.c \
-	StringUtilities.h StringUtilities.c CdoMagicsMapper.h \
-	CdoMagicsMapper.c
+	util.c util.h vinterp.c vinterp.h zaxis.c clipping/clipping.c \
+	clipping/clipping.h clipping/area.c clipping/area.h \
+	clipping/ensure_array_size.c clipping/ensure_array_size.h \
+	clipping/geometry_tools.c clipping/geometry.h clipping/grid.h \
+	clipping/points.h clipping/dep_list.h clipping/grid_cell.c \
+	clipping/grid_cell.h clipping/intersection.c clipping/utils.c \
+	clipping/utils.h Magplot.c Magvector.c Maggraph.c \
+	template_parser.h template_parser.c results_template_parser.h \
+	results_template_parser.c magics_template_parser.h \
+	magics_template_parser.c StringUtilities.h StringUtilities.c \
+	CdoMagicsMapper.h CdoMagicsMapper.c
 @ENABLE_MAGICS_TRUE at am__objects_1 = cdo-Magplot.$(OBJEXT) \
 @ENABLE_MAGICS_TRUE@	cdo-Magvector.$(OBJEXT) \
 @ENABLE_MAGICS_TRUE@	cdo-Maggraph.$(OBJEXT) \
@@ -257,10 +263,14 @@ am_cdo_OBJECTS = cdo-cdo.$(OBJEXT) cdo-Adisit.$(OBJEXT) \
 	cdo-pthread_debug.$(OBJEXT) cdo-readline.$(OBJEXT) \
 	cdo-realtime.$(OBJEXT) cdo-remaplib.$(OBJEXT) \
 	cdo-remapsort.$(OBJEXT) cdo-remap_scrip_io.$(OBJEXT) \
+	cdo-remap_search_latbins.$(OBJEXT) cdo-stdnametable.$(OBJEXT) \
 	cdo-specspace.$(OBJEXT) cdo-statistic.$(OBJEXT) \
 	cdo-table.$(OBJEXT) cdo-timer.$(OBJEXT) cdo-userlog.$(OBJEXT) \
 	cdo-util.$(OBJEXT) cdo-vinterp.$(OBJEXT) cdo-zaxis.$(OBJEXT) \
-	$(am__objects_1)
+	cdo-clipping.$(OBJEXT) cdo-area.$(OBJEXT) \
+	cdo-ensure_array_size.$(OBJEXT) cdo-geometry_tools.$(OBJEXT) \
+	cdo-grid_cell.$(OBJEXT) cdo-intersection.$(OBJEXT) \
+	cdo-utils.$(OBJEXT) $(am__objects_1)
 cdo_OBJECTS = $(am_cdo_OBJECTS)
 cdo_DEPENDENCIES = $(top_builddir)/libcdi/src/libcdi.la
 cdo_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
@@ -507,9 +517,16 @@ cdo_SOURCES = cdo.c Adisit.c Arith.c Arithc.c Arithdays.c Arithlat.c \
 	pipe.c pipe.h printinfo.h process.c process.h pstream.c \
 	pstream.h pstream_int.h pthread_debug.c pthread_debug.h \
 	readline.c realtime.c remap.h remaplib.c remapsort.c \
-	remap_scrip_io.c specspace.c specspace.h statistic.c \
-	statistic.h table.c timebase.h timer.c userlog.c util.c util.h \
-	vinterp.c vinterp.h zaxis.c $(am__append_1)
+	remap_scrip_io.c remap_search_latbins.c stdnametable.c \
+	stdnametable.h specspace.c specspace.h statistic.c statistic.h \
+	table.c timebase.h timer.c userlog.c util.c util.h vinterp.c \
+	vinterp.h zaxis.c clipping/clipping.c clipping/clipping.h \
+	clipping/area.c clipping/area.h clipping/ensure_array_size.c \
+	clipping/ensure_array_size.h clipping/geometry_tools.c \
+	clipping/geometry.h clipping/grid.h clipping/points.h \
+	clipping/dep_list.h clipping/grid_cell.c clipping/grid_cell.h \
+	clipping/intersection.c clipping/utils.c clipping/utils.h \
+	$(am__append_1)
 cdo_CPPFLAGS = -I$(top_srcdir)/libcdi/src
 cdo_LDADD = $(top_builddir)/libcdi/src/libcdi.la
 cdo_LDFLAGS = $(am__append_2)
@@ -820,13 +837,16 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Yseaspctl.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Yseasstat.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-Zonstat.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-area.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-cdo.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-cdo_pthread.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-cdo_vlist.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-clipping.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-color.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-commandline.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-ecacore.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-ecautil.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-ensure_array_size.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-exception.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-expr.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-expr_lex.Po at am__quote@
@@ -839,9 +859,11 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-fieldmer.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-fieldzon.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-fouriertrans.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-geometry_tools.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-gradsdeslib.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-grid.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-grid_area.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-grid_cell.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-grid_gme.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-grid_lcc.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-grid_rot.Po at am__quote@
@@ -853,6 +875,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-history.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-institution.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-interpol.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-intersection.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-job.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-juldate.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-kvlist.Po at am__quote@
@@ -873,16 +896,19 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-readline.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-realtime.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remap_scrip_io.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remap_search_latbins.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remaplib.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-remapsort.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-results_template_parser.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-specspace.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-statistic.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-stdnametable.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-table.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-template_parser.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-timer.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-userlog.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-util.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-utils.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-vinterp.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdo-zaxis.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/cdotest-cdotest.Po at am__quote@
@@ -4128,6 +4154,34 @@ cdo-remap_scrip_io.obj: remap_scrip_io.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_scrip_io.obj `if test -f 'remap_scrip_io.c'; then $(CYGPATH_W) 'remap_scrip_io.c'; else $(CYGPATH_W) '$(srcdir)/remap_scrip_io.c'; fi`
 
+cdo-remap_search_latbins.o: remap_search_latbins.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_search_latbins.o -MD -MP -MF $(DEPDIR)/cdo-remap_search_latbins.Tpo -c -o cdo-remap_search_latbins.o `test -f 'remap_search_latbins.c' || echo '$(srcdir)/'`remap_search_latbins.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-remap_search_latbins.Tpo $(DEPDIR)/cdo-remap_search_latbins.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='remap_search_latbins.c' object='cdo-remap_search_latbins.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_search_latbins.o `test -f 'remap_search_latbins.c' || echo '$(srcdir)/'`remap_search_latbins.c
+
+cdo-remap_search_latbins.obj: remap_search_latbins.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-remap_search_latbins.obj -MD -MP -MF $(DEPDIR)/cdo-remap_search_latbins.Tpo -c -o cdo-remap_search_latbins.obj `if test -f 'remap_search_latbins.c'; then $(CYGPATH_W) 'remap_search_latbins.c'; else $(CYGPATH_W) '$(srcdir)/remap_search_latbins.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-remap_search_latbins.Tpo $(DEPDIR)/cdo-remap_search_latbins.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='remap_search_latbins.c' object='cdo-remap_search_latbins.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-remap_search_latbins.obj `if test -f 'remap_search_latbins.c'; then $(CYGPATH_W) 'remap_search_latbins.c'; else $(CYGPATH_W) '$(srcdir)/remap_search_latbins.c'; fi`
+
+cdo-stdnametable.o: stdnametable.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-stdnametable.o -MD -MP -MF $(DEPDIR)/cdo-stdnametable.Tpo -c -o cdo-stdnametable.o `test -f 'stdnametable.c' || echo '$(srcdir)/'`stdnametable.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-stdnametable.Tpo $(DEPDIR)/cdo-stdnametable.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stdnametable.c' object='cdo-stdnametable.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-stdnametable.o `test -f 'stdnametable.c' || echo '$(srcdir)/'`stdnametable.c
+
+cdo-stdnametable.obj: stdnametable.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-stdnametable.obj -MD -MP -MF $(DEPDIR)/cdo-stdnametable.Tpo -c -o cdo-stdnametable.obj `if test -f 'stdnametable.c'; then $(CYGPATH_W) 'stdnametable.c'; else $(CYGPATH_W) '$(srcdir)/stdnametable.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-stdnametable.Tpo $(DEPDIR)/cdo-stdnametable.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stdnametable.c' object='cdo-stdnametable.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-stdnametable.obj `if test -f 'stdnametable.c'; then $(CYGPATH_W) 'stdnametable.c'; else $(CYGPATH_W) '$(srcdir)/stdnametable.c'; fi`
+
 cdo-specspace.o: specspace.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-specspace.o -MD -MP -MF $(DEPDIR)/cdo-specspace.Tpo -c -o cdo-specspace.o `test -f 'specspace.c' || echo '$(srcdir)/'`specspace.c
 @am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-specspace.Tpo $(DEPDIR)/cdo-specspace.Po
@@ -4233,6 +4287,104 @@ cdo-zaxis.obj: zaxis.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-zaxis.obj `if test -f 'zaxis.c'; then $(CYGPATH_W) 'zaxis.c'; else $(CYGPATH_W) '$(srcdir)/zaxis.c'; fi`
 
+cdo-clipping.o: clipping/clipping.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-clipping.o -MD -MP -MF $(DEPDIR)/cdo-clipping.Tpo -c -o cdo-clipping.o `test -f 'clipping/clipping.c' || echo '$(srcdir)/'`clipping/clipping.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-clipping.Tpo $(DEPDIR)/cdo-clipping.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/clipping.c' object='cdo-clipping.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-clipping.o `test -f 'clipping/clipping.c' || echo '$(srcdir)/'`clipping/clipping.c
+
+cdo-clipping.obj: clipping/clipping.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-clipping.obj -MD -MP -MF $(DEPDIR)/cdo-clipping.Tpo -c -o cdo-clipping.obj `if test -f 'clipping/clipping.c'; then $(CYGPATH_W) 'clipping/clipping.c'; else $(CYGPATH_W) '$(srcdir)/clipping/clipping.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-clipping.Tpo $(DEPDIR)/cdo-clipping.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/clipping.c' object='cdo-clipping.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-clipping.obj `if test -f 'clipping/clipping.c'; then $(CYGPATH_W) 'clipping/clipping.c'; else $(CYGPATH_W) '$(srcdir)/clipping/clipping.c'; fi`
+
+cdo-area.o: clipping/area.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-area.o -MD -MP -MF $(DEPDIR)/cdo-area.Tpo -c -o cdo-area.o `test -f 'clipping/area.c' || echo '$(srcdir)/'`clipping/area.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-area.Tpo $(DEPDIR)/cdo-area.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/area.c' object='cdo-area.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-area.o `test -f 'clipping/area.c' || echo '$(srcdir)/'`clipping/area.c
+
+cdo-area.obj: clipping/area.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-area.obj -MD -MP -MF $(DEPDIR)/cdo-area.Tpo -c -o cdo-area.obj `if test -f 'clipping/area.c'; then $(CYGPATH_W) 'clipping/area.c'; else $(CYGPATH_W) '$(srcdir)/clipping/area.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-area.Tpo $(DEPDIR)/cdo-area.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/area.c' object='cdo-area.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-area.obj `if test -f 'clipping/area.c'; then $(CYGPATH_W) 'clipping/area.c'; else $(CYGPATH_W) '$(srcdir)/clipping/area.c'; fi`
+
+cdo-ensure_array_size.o: clipping/ensure_array_size.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-ensure_array_size.o -MD -MP -MF $(DEPDIR)/cdo-ensure_array_size.Tpo -c -o cdo-ensure_array_size.o `test -f 'clipping/ensure_array_size.c' || echo '$(srcdir)/'`clipping/ensure_array_size.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-ensure_array_size.Tpo $(DEPDIR)/cdo-ensure_array_size.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/ensure_array_size.c' object='cdo-ensure_array_size.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-ensure_array_size.o `test -f 'clipping/ensure_array_size.c' || echo '$(srcdir)/'`clipping/ensure_array_size.c
+
+cdo-ensure_array_size.obj: clipping/ensure_array_size.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-ensure_array_size.obj -MD -MP -MF $(DEPDIR)/cdo-ensure_array_size.Tpo -c -o cdo-ensure_array_size.obj `if test -f 'clipping/ensure_array_size.c'; then $(CYGPATH_W) 'clipping/ensure_array_size.c'; else $(CYGPATH_W) '$(srcdir)/clipping/ensure_array_size.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-ensure_array_size.Tpo $(DEPDIR)/cdo-ensure_array_size.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/ensure_array_size.c' object='cdo-ensure_array_size.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-ensure_array_size.obj `if test -f 'clipping/ensure_array_size.c'; then $(CYGPATH_W) 'clipping/ensure_array_size.c'; else $(CYGPATH_W) '$(srcdir)/clipping/ensure_array_size.c'; fi`
+
+cdo-geometry_tools.o: clipping/geometry_tools.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-geometry_tools.o -MD -MP -MF $(DEPDIR)/cdo-geometry_tools.Tpo -c -o cdo-geometry_tools.o `test -f 'clipping/geometry_tools.c' || echo '$(srcdir)/'`clipping/geometry_tools.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-geometry_tools.Tpo $(DEPDIR)/cdo-geometry_tools.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/geometry_tools.c' object='cdo-geometry_tools.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-geometry_tools.o `test -f 'clipping/geometry_tools.c' || echo '$(srcdir)/'`clipping/geometry_tools.c
+
+cdo-geometry_tools.obj: clipping/geometry_tools.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-geometry_tools.obj -MD -MP -MF $(DEPDIR)/cdo-geometry_tools.Tpo -c -o cdo-geometry_tools.obj `if test -f 'clipping/geometry_tools.c'; then $(CYGPATH_W) 'clipping/geometry_tools.c'; else $(CYGPATH_W) '$(srcdir)/clipping/geometry_tools.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-geometry_tools.Tpo $(DEPDIR)/cdo-geometry_tools.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/geometry_tools.c' object='cdo-geometry_tools.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-geometry_tools.obj `if test -f 'clipping/geometry_tools.c'; then $(CYGPATH_W) 'clipping/geometry_tools.c'; else $(CYGPATH_W) '$(srcdir)/clipping/geometry_tools.c'; fi`
+
+cdo-grid_cell.o: clipping/grid_cell.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid_cell.o -MD -MP -MF $(DEPDIR)/cdo-grid_cell.Tpo -c -o cdo-grid_cell.o `test -f 'clipping/grid_cell.c' || echo '$(srcdir)/'`clipping/grid_cell.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-grid_cell.Tpo $(DEPDIR)/cdo-grid_cell.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/grid_cell.c' object='cdo-grid_cell.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid_cell.o `test -f 'clipping/grid_cell.c' || echo '$(srcdir)/'`clipping/grid_cell.c
+
+cdo-grid_cell.obj: clipping/grid_cell.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-grid_cell.obj -MD -MP -MF $(DEPDIR)/cdo-grid_cell.Tpo -c -o cdo-grid_cell.obj `if test -f 'clipping/grid_cell.c'; then $(CYGPATH_W) 'clipping/grid_cell.c'; else $(CYGPATH_W) '$(srcdir)/clipping/grid_cell.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-grid_cell.Tpo $(DEPDIR)/cdo-grid_cell.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/grid_cell.c' object='cdo-grid_cell.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-grid_cell.obj `if test -f 'clipping/grid_cell.c'; then $(CYGPATH_W) 'clipping/grid_cell.c'; else $(CYGPATH_W) '$(srcdir)/clipping/grid_cell.c'; fi`
+
+cdo-intersection.o: clipping/intersection.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-intersection.o -MD -MP -MF $(DEPDIR)/cdo-intersection.Tpo -c -o cdo-intersection.o `test -f 'clipping/intersection.c' || echo '$(srcdir)/'`clipping/intersection.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-intersection.Tpo $(DEPDIR)/cdo-intersection.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/intersection.c' object='cdo-intersection.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-intersection.o `test -f 'clipping/intersection.c' || echo '$(srcdir)/'`clipping/intersection.c
+
+cdo-intersection.obj: clipping/intersection.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-intersection.obj -MD -MP -MF $(DEPDIR)/cdo-intersection.Tpo -c -o cdo-intersection.obj `if test -f 'clipping/intersection.c'; then $(CYGPATH_W) 'clipping/intersection.c'; else $(CYGPATH_W) '$(srcdir)/clipping/intersection.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-intersection.Tpo $(DEPDIR)/cdo-intersection.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/intersection.c' object='cdo-intersection.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-intersection.obj `if test -f 'clipping/intersection.c'; then $(CYGPATH_W) 'clipping/intersection.c'; else $(CYGPATH_W) '$(srcdir)/clipping/intersection.c'; fi`
+
+cdo-utils.o: clipping/utils.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-utils.o -MD -MP -MF $(DEPDIR)/cdo-utils.Tpo -c -o cdo-utils.o `test -f 'clipping/utils.c' || echo '$(srcdir)/'`clipping/utils.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-utils.Tpo $(DEPDIR)/cdo-utils.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/utils.c' object='cdo-utils.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-utils.o `test -f 'clipping/utils.c' || echo '$(srcdir)/'`clipping/utils.c
+
+cdo-utils.obj: clipping/utils.c
+ at am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-utils.obj -MD -MP -MF $(DEPDIR)/cdo-utils.Tpo -c -o cdo-utils.obj `if test -f 'clipping/utils.c'; then $(CYGPATH_W) 'clipping/utils.c'; else $(CYGPATH_W) '$(srcdir)/clipping/utils.c'; fi`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-utils.Tpo $(DEPDIR)/cdo-utils.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='clipping/utils.c' object='cdo-utils.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o cdo-utils.obj `if test -f 'clipping/utils.c'; then $(CYGPATH_W) 'clipping/utils.c'; else $(CYGPATH_W) '$(srcdir)/clipping/utils.c'; fi`
+
 cdo-Magplot.o: Magplot.c
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(cdo_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cdo-Magplot.o -MD -MP -MF $(DEPDIR)/cdo-Magplot.Tpo -c -o cdo-Magplot.o `test -f 'Magplot.c' || echo '$(srcdir)/'`Magplot.c
 @am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/cdo-Magplot.Tpo $(DEPDIR)/cdo-Magplot.Po
diff --git a/src/Maskbox.c b/src/Maskbox.c
index 963e3fa..f2034e6 100644
--- a/src/Maskbox.c
+++ b/src/Maskbox.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -145,8 +145,8 @@ void maskregion(int *mask, int gridID, double *xcoords, double *ycoords, int nof
   nlon = gridInqXsize(gridID);
   nlat = gridInqYsize(gridID);
 
-  xvals = (double *) malloc(nlon*sizeof(double));
-  yvals = (double *) malloc(nlat*sizeof(double));
+  xvals = malloc(nlon*sizeof(double));
+  yvals = malloc(nlat*sizeof(double));
 
   gridInqXvals(gridID, xvals);
   gridInqYvals(gridID, yvals);  
@@ -304,7 +304,7 @@ void *Maskbox(void *argument)
   vlistDefTaxis(vlistID2, taxisID2);
 
   nvars = vlistNvars(vlistID1);
-  vars  = (int *) malloc(nvars*sizeof(int));
+  vars  = malloc(nvars*sizeof(int));
   for ( varID = 0; varID < nvars; varID++ )
     {
       if ( gridID == vlistInqVarGrid(vlistID1, varID) )
@@ -318,8 +318,8 @@ void *Maskbox(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = gridInqSize(gridID);
-  array = ( double  * ) malloc ( gridsize*sizeof(double) );
-  mask  = ( int * )     malloc ( gridsize*sizeof(int) );
+  array = malloc ( gridsize*sizeof(double) );
+  mask  = malloc ( gridsize*sizeof(int) );
   for( i=0;  i < gridsize; i++) mask[i] = 1;
  
   if ( operatorID == MASKLONLATBOX )
@@ -334,8 +334,8 @@ void *Maskbox(void *argument)
     }
   if ( operatorID == MASKREGION )
     {
-      xcoords = (double *) malloc( MAX_VALS*sizeof(double) );
-      ycoords = (double *) malloc( MAX_VALS*sizeof(double) );
+      xcoords = malloc( MAX_VALS*sizeof(double) );
+      ycoords = malloc( MAX_VALS*sizeof(double) );
       nfiles = operatorArgc();
      
       for ( i2 = 0; i2 < nfiles; i2++ )
diff --git a/src/Mastrfu.c b/src/Mastrfu.c
index ccff3bd..35fa006 100644
--- a/src/Mastrfu.c
+++ b/src/Mastrfu.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -42,12 +42,12 @@ void mastrfu(int gridID, int zaxisID, double *array1, double *array2, int nmiss,
 
   nlat = gridInqSize(gridID);
   nlev = zaxisInqSize(zaxisID);
-  phi    = (double *) malloc(nlat*sizeof(double));
-  dummy  = (double *) malloc(nlat*sizeof(double));
-  cosphi = (double *) malloc(nlat*sizeof(double));
-  plevel = (double *) malloc(nlev*sizeof(double));
-  field1 = (double **) malloc(nlev*sizeof(double*));
-  field2 = (double **) malloc(nlev*sizeof(double*));
+  phi    = malloc(nlat*sizeof(double));
+  dummy  = malloc(nlat*sizeof(double));
+  cosphi = malloc(nlat*sizeof(double));
+  plevel = malloc(nlev*sizeof(double));
+  field1 = malloc(nlev*sizeof(double*));
+  field2 = malloc(nlev*sizeof(double*));
 
   zaxisInqLevels(zaxisID, plevel);
 
@@ -167,8 +167,8 @@ void *Mastrfu(void *argument)
 
   streamDefVlist(streamID2, vlistID2);
 
-  array1 = (double *) malloc(gridsize*nlev*sizeof(double));
-  array2 = (double *) malloc(gridsize*nlev*sizeof(double));
+  array1 = malloc(gridsize*nlev*sizeof(double));
+  array2 = malloc(gridsize*nlev*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Math.c b/src/Math.c
index 11f69b0..2b7e8e0 100644
--- a/src/Math.c
+++ b/src/Math.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -98,8 +98,8 @@ void *Math(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
 
   streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
diff --git a/src/Merge.c b/src/Merge.c
index 629874c..9005a02 100644
--- a/src/Merge.c
+++ b/src/Merge.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -62,7 +62,7 @@ void checkDupEntry(int vlistID1, int vlistID2, const char *filename)
       if ( nlev1 > mlev1 )
 	{
 	  mlev1 = nlev1;
-	  lev1 = (double *) realloc(lev1, mlev1*sizeof(double));
+	  lev1 = realloc(lev1, mlev1*sizeof(double));
 	}
       zaxisInqLevels(zaxisID1, lev1);
 
@@ -81,7 +81,7 @@ void checkDupEntry(int vlistID1, int vlistID2, const char *filename)
 	      if ( nlev2 > mlev2 )
 		{
 		  mlev2 = nlev2;
-		  lev2 = (double *) realloc(lev2, mlev2*sizeof(double));
+		  lev2 = realloc(lev2, mlev2*sizeof(double));
 		}
 	      zaxisInqLevels(zaxisID2, lev2);
 
@@ -168,8 +168,8 @@ void *Merge(void *argument)
       if ( !userFileOverwrite(ofilename) )
 	cdoAbort("Outputfile %s already exists!", ofilename);
 
-  streamIDs = (int *) malloc(nmerge*sizeof(int));
-  vlistIDs  = (int *) malloc(nmerge*sizeof(int));
+  streamIDs = malloc(nmerge*sizeof(int));
+  vlistIDs  = malloc(nmerge*sizeof(int));
 
   for ( index = 0; index < nmerge; index++ )
     {
@@ -208,7 +208,7 @@ void *Merge(void *argument)
   if ( ! lcopy )
     {
       gridsize = vlistGridsizeMax(vlistID2);
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   tsID = 0;
diff --git a/src/Mergegrid.c b/src/Mergegrid.c
index 7716bb8..0b2199d 100644
--- a/src/Mergegrid.c
+++ b/src/Mergegrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -71,13 +71,13 @@ void gen_index(int gridID1, int gridID2, int *index)
       if ( ! (gridInqXvals(gridID2, NULL) && gridInqYvals(gridID2, NULL)) )
 	cdoAbort("Grid 2 has no values!");
 
-      xvals1 = (double *) malloc(nlon1*sizeof(double));
-      yvals1 = (double *) malloc(nlat1*sizeof(double));
-      xvals2 = (double *) malloc(nlon2*sizeof(double));
-      yvals2 = (double *) malloc(nlat2*sizeof(double));
+      xvals1 = malloc(nlon1*sizeof(double));
+      yvals1 = malloc(nlat1*sizeof(double));
+      xvals2 = malloc(nlon2*sizeof(double));
+      yvals2 = malloc(nlat2*sizeof(double));
 
-      xindex = (int *) malloc(nlon2*sizeof(int));
-      yindex = (int *) malloc(nlat2*sizeof(int));
+      xindex = malloc(nlon2*sizeof(int));
+      yindex = malloc(nlat2*sizeof(int));
 
       gridInqXvals(gridID1, xvals1);
       gridInqYvals(gridID1, yvals1);
@@ -220,9 +220,9 @@ void *Mergegrid(void *argument)
   gridsize1 = gridInqSize(gridID1);
   gridsize2 = gridInqSize(gridID2);
 
-  array1 = (double *) malloc(gridsize1*sizeof(double));
-  array2 = (double *) malloc(gridsize2*sizeof(double));
-  gindex = (int *) malloc(gridsize2*sizeof(int));
+  array1 = malloc(gridsize1*sizeof(double));
+  array2 = malloc(gridsize2*sizeof(double));
+  gindex = malloc(gridsize2*sizeof(int));
 
   gen_index(gridID1, gridID2, gindex);
 
diff --git a/src/Mergetime.c b/src/Mergetime.c
index be49041..0c75ccf 100644
--- a/src/Mergetime.c
+++ b/src/Mergetime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -80,7 +80,7 @@ void *Mergetime(void *argument)
 
   nfiles = cdoStreamCnt() - 1;
 
-  sf = (sfile_t *) malloc(nfiles*sizeof(sfile_t));
+  sf = malloc(nfiles*sizeof(sfile_t));
 
   for ( fileID = 0; fileID < nfiles; fileID++ )
     {
@@ -130,7 +130,7 @@ void *Mergetime(void *argument)
   if ( ! lcopy )
     {
       gridsize = vlistGridsizeMax(sf[0].vlistID);
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   while ( TRUE )
diff --git a/src/Merstat.c b/src/Merstat.c
index aad2472..e043f59 100644
--- a/src/Merstat.c
+++ b/src/Merstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -133,12 +133,12 @@ void *Merstat(void *argument)
   field_init(&field2);
 
   lim = vlistGridsizeMax(vlistID1);
-  field1.ptr    = (double *) malloc(lim*sizeof(double));
+  field1.ptr    = malloc(lim*sizeof(double));
   field1.weight = NULL;
   if ( needWeights )
-    field1.weight = (double *) malloc(lim*sizeof(double));
+    field1.weight = malloc(lim*sizeof(double));
 
-  field2.ptr  = (double *) malloc(nlonmax*sizeof(double));
+  field2.ptr  = malloc(nlonmax*sizeof(double));
   field2.grid = gridID2;
 
   tsID = 0;
diff --git a/src/Monarith.c b/src/Monarith.c
index 4db6c00..75bab6e 100644
--- a/src/Monarith.c
+++ b/src/Monarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -72,8 +72,8 @@ void *Monarith(void *argument)
   field_init(&field1);
   field_init(&field2);
 
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field2.ptr = malloc(gridsize*sizeof(double));
 
   taxisID1 = vlistInqTaxis(vlistID1);
   taxisID2 = vlistInqTaxis(vlistID2);
@@ -86,15 +86,15 @@ void *Monarith(void *argument)
 
   nvars  = vlistNvars(vlistID2);
 
-  vardata2  = (double **) malloc(nvars*sizeof(double *));
-  varnmiss2 = (int **) malloc(nvars*sizeof(int *));
+  vardata2  = malloc(nvars*sizeof(double *));
+  varnmiss2 = malloc(nvars*sizeof(int *));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
       gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
       nlev     = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
-      vardata2[varID]  = (double *) malloc(nlev*gridsize*sizeof(double));
-      varnmiss2[varID] = (int *) malloc(nlev*sizeof(int));
+      vardata2[varID]  = malloc(nlev*gridsize*sizeof(double));
+      varnmiss2[varID] = malloc(nlev*sizeof(int));
     }
 
   tsID  = 0;
diff --git a/src/Mrotuv.c b/src/Mrotuv.c
index a526473..adc0cf0 100644
--- a/src/Mrotuv.c
+++ b/src/Mrotuv.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -261,12 +261,12 @@ void *Mrotuv(void *argument)
   nlon    = gridInqXsize(gridID1);
   nlat    = gridInqYsize(gridID1);
 
-  grid1x  = (double *) malloc(gridsize*sizeof(double));
-  grid1y  = (double *) malloc(gridsize*sizeof(double));
-  gridux  = (double *) malloc(gridsize*sizeof(double));
-  griduy  = (double *) malloc(gridsize*sizeof(double));
-  gridvx  = (double *) malloc(gridsize*sizeof(double));
-  gridvy  = (double *) malloc(gridsize*sizeof(double));
+  grid1x  = malloc(gridsize*sizeof(double));
+  grid1y  = malloc(gridsize*sizeof(double));
+  gridux  = malloc(gridsize*sizeof(double));
+  griduy  = malloc(gridsize*sizeof(double));
+  gridvx  = malloc(gridsize*sizeof(double));
+  gridvy  = malloc(gridsize*sizeof(double));
 
   gridsizex = (nlon+2)*nlat;
 
@@ -331,19 +331,19 @@ void *Mrotuv(void *argument)
   missval1 = vlistInqVarMissval(vlistID1, uid);
   missval2 = vlistInqVarMissval(vlistID1, vid);
 
-  ufield  = (double *) malloc(gridsize*sizeof(double));
-  vfield  = (double *) malloc(gridsize*sizeof(double));
+  ufield  = malloc(gridsize*sizeof(double));
+  vfield  = malloc(gridsize*sizeof(double));
 
-  urfield  = (double **) malloc(nlevs*sizeof(double*));
-  vrfield  = (double **) malloc(nlevs*sizeof(double*));
+  urfield  = malloc(nlevs*sizeof(double*));
+  vrfield  = malloc(nlevs*sizeof(double*));
   for ( lid = 0; lid < nlevs; lid++ )
     {
-      urfield[lid] = (double *) malloc(gridsize*sizeof(double));
-      vrfield[lid] = (double *) malloc(gridsize*sizeof(double));
+      urfield[lid] = malloc(gridsize*sizeof(double));
+      vrfield[lid] = malloc(gridsize*sizeof(double));
     }
 
-  uhelp   = (double *) malloc(gridsizex*sizeof(double));
-  vhelp   = (double *) malloc(gridsizex*sizeof(double));
+  uhelp   = malloc(gridsizex*sizeof(double));
+  vhelp   = malloc(gridsizex*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Mrotuvb.c b/src/Mrotuvb.c
index fde6cd2..565d1a7 100644
--- a/src/Mrotuvb.c
+++ b/src/Mrotuvb.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -162,8 +162,8 @@ void uv_to_p_grid(int nlon, int nlat, double *grid1x, double *grid1y,
   double *gxhelp, *gyhelp;
 
   gridsizex = (nlon+2)*nlat;
-  gxhelp  = (double *) malloc(gridsizex*sizeof(double));
-  gyhelp  = (double *) malloc(gridsizex*sizeof(double));
+  gxhelp  = malloc(gridsizex*sizeof(double));
+  gyhelp  = malloc(gridsizex*sizeof(double));
 
   /* load to a help field */
   for ( j = 0; j < nlat; j++ )
@@ -323,12 +323,12 @@ void *Mrotuvb(void *argument)
   nlon    = gridInqXsize(gridID1);
   nlat    = gridInqYsize(gridID1);
 
-  grid1x  = (double *) malloc(gridsize*sizeof(double));
-  grid1y  = (double *) malloc(gridsize*sizeof(double));
-  grid2x  = (double *) malloc(gridsize*sizeof(double));
-  grid2y  = (double *) malloc(gridsize*sizeof(double));
-  grid3x  = (double *) malloc(gridsize*sizeof(double));
-  grid3y  = (double *) malloc(gridsize*sizeof(double));
+  grid1x  = malloc(gridsize*sizeof(double));
+  grid1y  = malloc(gridsize*sizeof(double));
+  grid2x  = malloc(gridsize*sizeof(double));
+  grid2y  = malloc(gridsize*sizeof(double));
+  grid3x  = malloc(gridsize*sizeof(double));
+  grid3y  = malloc(gridsize*sizeof(double));
 
   gridInqXvals(gridID1, grid1x);
   gridInqYvals(gridID1, grid1y);
@@ -407,16 +407,16 @@ void *Mrotuvb(void *argument)
   missval1 = vlistInqVarMissval(vlistID1, 0);
   missval2 = vlistInqVarMissval(vlistID2, 0);
 
-  ufield  = (double *) malloc(gridsize*sizeof(double));
-  vfield  = (double *) malloc(gridsize*sizeof(double));
-  urfield = (double *) malloc(gridsize*sizeof(double));
-  vrfield = (double *) malloc(gridsize*sizeof(double));
+  ufield  = malloc(gridsize*sizeof(double));
+  vfield  = malloc(gridsize*sizeof(double));
+  urfield = malloc(gridsize*sizeof(double));
+  vrfield = malloc(gridsize*sizeof(double));
 
   if ( gpint )
     {
       int gridsizex = (nlon+2)*nlat;
-      uhelp   = (double *) malloc(gridsizex*sizeof(double));
-      vhelp   = (double *) malloc(gridsizex*sizeof(double));
+      uhelp   = malloc(gridsizex*sizeof(double));
+      vhelp   = malloc(gridsizex*sizeof(double));
     }
 
   tsID = 0;
diff --git a/src/Ninfo.c b/src/Ninfo.c
index 7983f66..04a670d 100644
--- a/src/Ninfo.c
+++ b/src/Ninfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Nmltest.c b/src/Nmltest.c
index 05499d9..f70fd73 100644
--- a/src/Nmltest.c
+++ b/src/Nmltest.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Output.c b/src/Output.c
index 878a23d..6cf1017 100644
--- a/src/Output.c
+++ b/src/Output.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -112,7 +112,7 @@ void *Output(void *argument)
 	for ( i = 0; i < npar; i++ )
 	  printf("key %d = %s\n", i+1, parnames[i]);
 
-      keys = (int *) malloc(npar*sizeof(int));
+      keys = malloc(npar*sizeof(int));
       nkeys = 0;
       nKeys = sizeof(Keynames)/sizeof(char *);
       for ( i = 0; i < npar; i++ )
@@ -156,7 +156,7 @@ void *Output(void *argument)
       gridsize = gridInqSize(gridID);
       gridtype = gridInqType(gridID);
 
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
 
       if ( operatorID == OUTPUTFLD || operatorID == OUTPUTXYZ || operatorID == OUTPUTTAB )
 	{
@@ -167,8 +167,8 @@ void *Output(void *argument)
 
 	  gridtype = gridInqType(gridID);
 
-	  grid_center_lon = (double *) malloc(gridsize*sizeof(double));
-	  grid_center_lat = (double *) malloc(gridsize*sizeof(double));
+	  grid_center_lon = malloc(gridsize*sizeof(double));
+	  grid_center_lat = malloc(gridsize*sizeof(double));
 	  gridInqXvals(gridID, grid_center_lon);
 	  gridInqYvals(gridID, grid_center_lat);
 
diff --git a/src/Outputgmt.c b/src/Outputgmt.c
index 399469a..4a39f53 100644
--- a/src/Outputgmt.c
+++ b/src/Outputgmt.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -163,7 +163,7 @@ void verify_grid(int gridtype, int gridsize, int ncorner,
   double lon_bounds[MAX_CORNERS], lat_bounds[MAX_CORNERS];
   double area, sumarea;
 
-  alone_cell = (int *) malloc(gridsize*ncorner*sizeof(int));
+  alone_cell = malloc(gridsize*ncorner*sizeof(int));
 
   check_corners = 0; /* don't execute corner checking (last loop) */
   nout = 0;
@@ -671,7 +671,7 @@ void *Outputgmt(void *argument)
 
   if ( gridInqMaskGME(gridID, NULL) )
     {
-      grid_mask = (int *) malloc(gridsize*sizeof(int));
+      grid_mask = malloc(gridsize*sizeof(int));
       gridInqMaskGME(gridID, grid_mask);
     }
 
@@ -709,8 +709,8 @@ void *Outputgmt(void *argument)
 
   grid_is_circular = gridIsCircular(gridID);
 
-  grid_center_lat = (double *) malloc(gridsize*sizeof(double));
-  grid_center_lon = (double *) malloc(gridsize*sizeof(double));
+  grid_center_lat = malloc(gridsize*sizeof(double));
+  grid_center_lon = malloc(gridsize*sizeof(double));
 
   gridInqYvals(gridID, grid_center_lat);
   gridInqXvals(gridID, grid_center_lon);
@@ -731,8 +731,8 @@ void *Outputgmt(void *argument)
 
       gridsize2 = nlat*(nlon+1);
 
-      grid_center_lat2 = (double *) malloc(gridsize2*sizeof(double));
-      grid_center_lon2 = (double *) malloc(gridsize2*sizeof(double));
+      grid_center_lat2 = malloc(gridsize2*sizeof(double));
+      grid_center_lon2 = malloc(gridsize2*sizeof(double));
 
       make_cyclic(grid_center_lat, grid_center_lat2, nlon, nlat);
       make_cyclic(grid_center_lon, grid_center_lon2, nlon, nlat);
@@ -748,9 +748,9 @@ void *Outputgmt(void *argument)
       plat = grid_center_lat2;
     }
 
-  zaxis_center_lev = (double *) malloc(nlev*sizeof(double));
-  zaxis_lower_lev  = (double *) malloc(nlev*sizeof(double));
-  zaxis_upper_lev  = (double *) malloc(nlev*sizeof(double));
+  zaxis_center_lev = malloc(nlev*sizeof(double));
+  zaxis_lower_lev  = malloc(nlev*sizeof(double));
+  zaxis_upper_lev  = malloc(nlev*sizeof(double));
 
   zaxisInqLevels(zaxisID, zaxis_center_lev);
 
@@ -758,8 +758,8 @@ void *Outputgmt(void *argument)
     {
       if ( gridcorners == 0 ) cdoAbort("grid corner missing!");
       nalloc = gridcorners*gridsize;
-      grid_corner_lat = (double *) realloc(grid_corner_lat, nalloc*sizeof(double));
-      grid_corner_lon = (double *) realloc(grid_corner_lon, nalloc*sizeof(double));
+      grid_corner_lat = realloc(grid_corner_lat, nalloc*sizeof(double));
+      grid_corner_lon = realloc(grid_corner_lon, nalloc*sizeof(double));
 
       if ( gridInqYbounds(gridID, NULL) && gridInqXbounds(gridID, NULL) )
 	{
@@ -770,8 +770,12 @@ void *Outputgmt(void *argument)
 	{
 	  if ( lgrid_gen_bounds )
 	    {
-	      if ( ! lzon ) genXbounds(nlon, nlat, grid_center_lon, grid_corner_lon, 0);
-	      if ( ! lmer ) genYbounds(nlon, nlat, grid_center_lat, grid_corner_lat);
+	      char xunitstr[CDI_MAX_NAME];
+	      char yunitstr[CDI_MAX_NAME];
+	      gridInqXunits(gridID, xunitstr);
+	      gridInqYunits(gridID, yunitstr);
+	      if ( ! lzon ) grid_cell_center_to_bounds_X2D(xunitstr, nlon, nlat, grid_center_lon, grid_corner_lon, 0);
+	      if ( ! lmer ) grid_cell_center_to_bounds_Y2D(yunitstr, nlon, nlat, grid_center_lat, grid_corner_lat);
 	    }
 	  else
 	    cdoAbort("Grid corner missing!");
@@ -804,21 +808,21 @@ void *Outputgmt(void *argument)
 	}
     }
 
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
   parray = array;
 						
   if ( operatorID == OUTPUTCENTER2 && grid_is_circular )
     {
-      array2 = (double *) malloc(nlat*(nlon+1)*sizeof(double));
+      array2 = malloc(nlat*(nlon+1)*sizeof(double));
       parray = array2;
     }
 
   if ( operatorID == OUTPUTVECTOR )
     {
-      uf    = (double *) malloc(gridsize*sizeof(double));
-      vf    = (double *) malloc(gridsize*sizeof(double));
-      alpha = (double *) malloc(gridsize*sizeof(double));
-      auv   = (double *) malloc(gridsize*sizeof(double));
+      uf    = malloc(gridsize*sizeof(double));
+      vf    = malloc(gridsize*sizeof(double));
+      alpha = malloc(gridsize*sizeof(double));
+      auv   = malloc(gridsize*sizeof(double));
     }
 
   if ( operatorID == GRIDVERIFY )
diff --git a/src/Pack.c b/src/Pack.c
index b4c299a..856e6fd 100644
--- a/src/Pack.c
+++ b/src/Pack.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -116,8 +116,8 @@ void *Pack(void *argument)
       if ( tsID >= nalloc )
 	{
 	  nalloc += NALLOC_INC;
-	  dtinfo = (dtinfo_t *) realloc(dtinfo, nalloc*sizeof(dtinfo_t));
-	  vars   = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
+	  dtinfo = realloc(dtinfo, nalloc*sizeof(dtinfo_t));
+	  vars   = realloc(vars, nalloc*sizeof(field_t **));
 	}
 
       taxisInqDTinfo(taxisID1, &dtinfo[tsID]);
@@ -129,7 +129,7 @@ void *Pack(void *argument)
 	  streamInqRecord(streamID1, &varID, &levelID);
 	  gridID   = vlistInqVarGrid(vlistID1, varID);
 	  gridsize = gridInqSize(gridID);
-	  vars[tsID][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+	  vars[tsID][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 	  streamReadRecord(streamID1, vars[tsID][varID][levelID].ptr, &nmiss);
 	  vars[tsID][varID][levelID].nmiss = nmiss;
 	}
diff --git a/src/Pinfo.c b/src/Pinfo.c
index b08cefc..113a1ab 100644
--- a/src/Pinfo.c
+++ b/src/Pinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -74,8 +74,8 @@ void *Pinfo(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
 
   indg = 0;
   tsID = 0;
diff --git a/src/Pressure.c b/src/Pressure.c
index 414554f..8db8a3a 100644
--- a/src/Pressure.c
+++ b/src/Pressure.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -31,6 +31,7 @@
 #include "pstream.h"
 #include "vinterp.h"
 #include "list.h"
+#include "stdnametable.h"
 
 
 void *Pressure(void *argument)
@@ -115,7 +116,7 @@ void *Pressure(void *argument)
 	{
 	  double *level;
 	  int l;
-	  level = (double *) malloc(nlevel*sizeof(double));
+	  level = malloc(nlevel*sizeof(double));
 	  zaxisInqLevels(zaxisID, level);
 	  for ( l = 0; l < nlevel; l++ )
 	    {
@@ -139,7 +140,7 @@ void *Pressure(void *argument)
 		  nhlevf   = nhlev;
 		  nhlevh   = nhlevf + 1;
 	      
-		  vct = (double *) malloc(nvct*sizeof(double));
+		  vct = malloc(nvct*sizeof(double));
 		  zaxisInqVct(zaxisID, vct);
 		}
 	    }
@@ -153,7 +154,7 @@ void *Pressure(void *argument)
 		  nhlevf   = nhlev - 1;
 		  nhlevh   = nhlev;
 	      
-		  vct = (double *) malloc(nvct*sizeof(double));
+		  vct = malloc(nvct*sizeof(double));
 		  zaxisInqVct(zaxisID, vct);
 		}
 	    }
@@ -165,7 +166,7 @@ void *Pressure(void *argument)
 		  int voff = 4;
 		  double *rvct = NULL;
 
-		  rvct = (double *) malloc(nvct*sizeof(double));
+		  rvct = malloc(nvct*sizeof(double));
 		  zaxisInqVct(zaxisID,rvct);
 
 		  if ( (int)(rvct[0]+0.5) == 100000 && rvct[voff] < rvct[voff+1] )
@@ -177,7 +178,7 @@ void *Pressure(void *argument)
 		      nhlevh   = nhlev + 1;
 
 		      vctsize = 2*nhlevh;
-		      vct = (double *) malloc(vctsize*sizeof(double));
+		      vct = malloc(vctsize*sizeof(double));
 
 		      /* calculate VCT for LM */
 
@@ -212,10 +213,10 @@ void *Pressure(void *argument)
 
   if ( zaxisIDh != -1 && ngp > 0 )
     {
-      ps_prog    = (double *) malloc(ngp*sizeof(double));
-      deltap     = (double *) malloc(ngp*nhlevf*sizeof(double));
-      full_press = (double *) malloc(ngp*nhlevf*sizeof(double));
-      half_press = (double *) malloc(ngp*nhlevh*sizeof(double));
+      ps_prog    = malloc(ngp*sizeof(double));
+      deltap     = malloc(ngp*nhlevf*sizeof(double));
+      full_press = malloc(ngp*nhlevf*sizeof(double));
+      half_press = malloc(ngp*nhlevh*sizeof(double));
     }
   else
     cdoAbort("No data on hybrid model level found!");
@@ -228,7 +229,7 @@ void *Pressure(void *argument)
   {
     double *level;
     int l;
-    level = (double *) malloc(nhlevh*sizeof(double));
+    level = malloc(nhlevh*sizeof(double));
     for ( l = 0; l < nhlevh; l++ ) level[l] = l+1;
     zaxisDefLevels(zaxisIDp, level);
     free(level);
@@ -334,7 +335,7 @@ void *Pressure(void *argument)
       if ( gridInqType(gridID) == GRID_SPECTRAL )
 	{
 	  lnpsID = -1;
-	  cdoWarning("Spectral LOG surface pressure not supported - using surface pressure!");
+	  cdoWarning("Spectral LOG(%s) not supported - using %s!", var_stdname(surface_air_pressure), var_stdname(surface_air_pressure));
 	}
     }
 
@@ -342,22 +343,21 @@ void *Pressure(void *argument)
     {
       pvarID = psID;
       if ( psID == -1 )
-	cdoAbort("Surface pressure not found!");
+	cdoAbort("%s not found!", var_stdname(surface_air_pressure));
     }
 
   gridID = vlistInqVarGrid(vlistID1, pvarID);
   if ( gridInqType(gridID) == GRID_SPECTRAL )
-    cdoAbort("Surface pressure on spectral representation not supported!");
+    cdoAbort("%s on spectral representation not supported!", var_stdname(surface_air_pressure));
 
   gridsize = gridInqSize(gridID);
-  pdata = (double *) malloc(gridsize*sizeof(double));
+  pdata = malloc(gridsize*sizeof(double));
 
 
   vlistID2 = vlistCreate();
   varID = vlistDefVar(vlistID2, gridID, zaxisIDp, TSTEP_INSTANT);
   vlistDefVarCode(vlistID2, varID, 1);
   vlistDefVarName(vlistID2, varID, "pressure");
-  vlistDefVarLongname(vlistID2, varID, "Air pressure");
   vlistDefVarStdname(vlistID2, varID, "air_pressure");
   vlistDefVarUnits(vlistID2, varID, "Pa");
 
diff --git a/src/Regres.c b/src/Regres.c
index 7b8c9a3..31dff3e 100644
--- a/src/Regres.c
+++ b/src/Regres.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -70,15 +70,15 @@ void *Regres(void *argument)
 
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field1);
   field_init(&field2);
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field2.ptr = malloc(gridsize*sizeof(double));
 
   for ( w = 0; w < nwork; w++ )
     work[w] = field_calloc(vlistID1, FIELD_PTR);
diff --git a/src/Remap.c b/src/Remap.c
index 766fb83..2f57a09 100644
--- a/src/Remap.c
+++ b/src/Remap.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -44,15 +44,20 @@
 
 
 enum {REMAPCON, REMAPCON2, REMAPBIL, REMAPBIC, REMAPDIS, REMAPNN, REMAPLAF, REMAPSUM,
-      GENCON, GENCON2, GENBIL, GENBIC, GENDIS, GENNN, GENLAF, REMAPXXX};
+      GENCON, GENCON2, GENBIL, GENBIC, GENDIS, GENNN, GENLAF, REMAPXXX, REMAPCONS, GENCONS};
 
 enum {HEAP_SORT, MERGE_SORT};
 
 static
-void get_map_type(int operfunc, int *map_type, int *submap_type, int *remap_order)
+void get_map_type(int operfunc, int *map_type, int *submap_type, int *num_neighbors, int *remap_order)
 {
   switch ( operfunc )
     {
+    case REMAPCONS:
+    case GENCONS:
+      *map_type = MAP_TYPE_CONSPHERE;
+      *remap_order = 1;
+      break;
     case REMAPCON:
     case GENCON:
       *map_type = MAP_TYPE_CONSERV;
@@ -83,10 +88,12 @@ void get_map_type(int operfunc, int *map_type, int *submap_type, int *remap_orde
     case REMAPDIS:
     case GENDIS:
       *map_type = MAP_TYPE_DISTWGT;
+      *num_neighbors = 4;
       break;
     case REMAPNN:
     case GENNN:
-      *map_type = MAP_TYPE_DISTWGT1;
+      *map_type = MAP_TYPE_DISTWGT;
+      *num_neighbors = 1;
       break;
     default:
       cdoAbort("Unknown mapping method");
@@ -95,7 +102,7 @@ void get_map_type(int operfunc, int *map_type, int *submap_type, int *remap_orde
 }
 
 static
-int maptype2operfunc(int map_type, int submap_type, int remap_order)
+int maptype2operfunc(int map_type, int submap_type, int num_neighbors, int remap_order)
 {
   int operfunc = -1;
 
@@ -120,6 +127,11 @@ int maptype2operfunc(int map_type, int submap_type, int remap_order)
 	    }
 	}
     }
+  else if ( map_type == MAP_TYPE_CONSPHERE )
+    {
+      operfunc = REMAPCONS;
+      cdoPrint("Using remapcons");
+    }
   else if ( map_type == MAP_TYPE_BILINEAR )
     {
       operfunc = REMAPBIL;
@@ -132,13 +144,16 @@ int maptype2operfunc(int map_type, int submap_type, int remap_order)
     }
   else if ( map_type == MAP_TYPE_DISTWGT )
     {
-      operfunc = REMAPDIS;
-      cdoPrint("Using remapdis");
-    }
-  else if ( map_type == MAP_TYPE_DISTWGT1 )
-    {
-      operfunc = REMAPNN;
-      cdoPrint("Using remapnn");
+      if ( num_neighbors == 1 )
+	{
+	  operfunc = REMAPNN;
+	  cdoPrint("Using remapnn");
+	}
+      else
+	{
+	  operfunc = REMAPDIS;
+	  cdoPrint("Using remapdis");
+	}
     }
   else
     cdoAbort("Unsupported mapping method (map_type = %d)", map_type);
@@ -149,7 +164,6 @@ int maptype2operfunc(int map_type, int submap_type, int remap_order)
 double remap_threshhold = 2;
 int remap_test = 0;
 int remap_order = 1;
-int remap_restrict_type = RESTRICT_LATITUDE;
 int remap_store_link_fast = TRUE;
 int remap_non_global = FALSE;
 int remap_num_srch_bins = 180;
@@ -186,7 +200,7 @@ void get_remap_env(void)
       ival = atoi(envstr);
       if ( ival > 0 )
 	{
-	  remap_set_max_iter(ival);
+	  remap_set_int(REMAP_MAX_ITER, ival);
 	  if ( cdoVerbose )
 	    cdoPrint("Set REMAP_MAX_ITER to %d", ival);
 	}
@@ -243,21 +257,6 @@ void get_remap_env(void)
 	}
     }
 
-  envstr = getenv("REMAP_RESTRICT_TYPE");
-  if ( envstr )
-    {
-      if      ( strcmp(envstr, "latitude") == 0 ) remap_restrict_type = RESTRICT_LATITUDE;
-      else if ( strcmp(envstr, "latlon")   == 0 ) remap_restrict_type = RESTRICT_LATLON;
-
-      if ( cdoVerbose )
-	{
-	  if      ( remap_restrict_type == RESTRICT_LATITUDE )
-	    cdoPrint("Set REMAP_RESTRICT_TYPE to latitude");
-	  else if ( remap_restrict_type == RESTRICT_LATLON )
-	    cdoPrint("Set REMAP_RESTRICT_TYPE to latlon");
-	}
-    }
-
   envstr = getenv("REMAP_THRESHHOLD");
   if ( envstr )
     {
@@ -271,6 +270,8 @@ void get_remap_env(void)
 	}
     }
 
+  remap_set_threshhold(remap_threshhold);
+
   envstr = getenv("REMAP_AREA_MIN");
   if ( envstr )
     {
@@ -324,6 +325,8 @@ void get_remap_env(void)
 	}
     }
 
+  remap_set_int(REMAP_STORE_LINK_FAST, remap_store_link_fast);
+
   envstr = getenv("REMAP_EXTRAPOLATE");
   if ( envstr )
     {
@@ -403,6 +406,7 @@ void *Remap(void *argument)
   int norm_opt = NORM_OPT_NONE;
   int map_type = -1;
   int submap_type = SUBMAP_TYPE_NONE;
+  int num_neighbors = 4;
   int need_gradiants = FALSE;
   int non_global;
   int grid1sizemax;
@@ -430,27 +434,31 @@ void *Remap(void *argument)
 
   cdoInitialize(argument);
 
-  cdoOperatorAdd("remapcon",    REMAPCON,    0, NULL);
-  cdoOperatorAdd("remapcon2",   REMAPCON2,   0, NULL);
-  cdoOperatorAdd("remapbil",    REMAPBIL,    0, NULL);
-  cdoOperatorAdd("remapbic",    REMAPBIC,    0, NULL);
-  cdoOperatorAdd("remapdis",    REMAPDIS,    0, NULL);
-  cdoOperatorAdd("remapnn",     REMAPNN,     0, NULL);
-  cdoOperatorAdd("remaplaf",    REMAPLAF,    0, NULL);
-  cdoOperatorAdd("remapsum",    REMAPSUM,    0, NULL);
-  cdoOperatorAdd("gencon",      GENCON,      1, NULL);
-  cdoOperatorAdd("gencon2",     GENCON2,     1, NULL);
-  cdoOperatorAdd("genbil",      GENBIL,      1, NULL);
-  cdoOperatorAdd("genbic",      GENBIC,      1, NULL);
-  cdoOperatorAdd("gendis",      GENDIS,      1, NULL);
-  cdoOperatorAdd("gennn",       GENNN,       1, NULL);
-  cdoOperatorAdd("genlaf",      GENLAF,      1, NULL);
-  cdoOperatorAdd("remap",       REMAPXXX,    0, NULL);
-
-  operatorID = cdoOperatorID();
-  operfunc   = cdoOperatorF1(operatorID);
+  cdoOperatorAdd("remapcon",     REMAPCON,     0, NULL);
+  cdoOperatorAdd("remapcon2",    REMAPCON2,    0, NULL);
+  cdoOperatorAdd("remapbil",     REMAPBIL,     0, NULL);
+  cdoOperatorAdd("remapbic",     REMAPBIC,     0, NULL);
+  cdoOperatorAdd("remapdis",     REMAPDIS,     0, NULL);
+  cdoOperatorAdd("remapnn",      REMAPNN,      0, NULL);
+  cdoOperatorAdd("remaplaf",     REMAPLAF,     0, NULL);
+  cdoOperatorAdd("remapsum",     REMAPSUM,     0, NULL);
+  cdoOperatorAdd("gencon",       GENCON,       1, NULL);
+  cdoOperatorAdd("gencon2",      GENCON2,      1, NULL);
+  cdoOperatorAdd("genbil",       GENBIL,       1, NULL);
+  cdoOperatorAdd("genbic",       GENBIC,       1, NULL);
+  cdoOperatorAdd("gendis",       GENDIS,       1, NULL);
+  cdoOperatorAdd("gennn",        GENNN,        1, NULL);
+  cdoOperatorAdd("genlaf",       GENLAF,       1, NULL);
+  cdoOperatorAdd("remap",        REMAPXXX,     0, NULL);
+  cdoOperatorAdd("remapcons",    REMAPCONS,    0, NULL);
+  cdoOperatorAdd("gencons",      GENCONS,      1, NULL);
+
+  operatorID   = cdoOperatorID();
+  operfunc     = cdoOperatorF1(operatorID);
   lwrite_remap = cdoOperatorF2(operatorID);
 
+  remap_set_int(REMAP_WRITE_REMAP, lwrite_remap);
+
   if ( operfunc == REMAPDIS || operfunc == GENDIS ||
        operfunc == REMAPNN  || operfunc == GENNN )
     remap_extrapolate = TRUE;
@@ -489,7 +497,7 @@ void *Remap(void *argument)
   vlistDefTaxis(vlistID2, taxisID2);
 
   ngrids = vlistNgrids(vlistID1);
-  remapgrids = (short *) malloc(ngrids*sizeof(short));
+  remapgrids = malloc(ngrids*sizeof(short));
   for ( index = 0; index < ngrids; index++ )
     {
       remapgrids[index] = TRUE;
@@ -546,7 +554,7 @@ void *Remap(void *argument)
         cdoPrint("Set max_remaps to %d", max_remaps);
     }
 
-  remaps = (remap_t *) malloc(max_remaps*sizeof(remap_t));
+  remaps = malloc(max_remaps*sizeof(remap_t));
   for ( r = 0; r < max_remaps; r++ )
     {
       remaps[r].gridID   = -1;
@@ -558,23 +566,20 @@ void *Remap(void *argument)
     {
       int gridsize2;
 
-      read_remap_scrip(remap_file, gridID1, gridID2, &map_type, &submap_type, 
-		       &remap_order, &remaps[0].grid, &remaps[0].vars);
+      read_remap_scrip(remap_file, gridID1, gridID2, &map_type, &submap_type, &num_neighbors,
+		       &remap_order, &remaps[0].src_grid, &remaps[0].tgt_grid, &remaps[0].vars);
       nremaps = 1;
-      gridsize = remaps[0].grid.grid1_size;
+      gridsize = remaps[0].src_grid.size;
       remaps[0].gridID = gridID1;
       remaps[0].gridsize = gridInqSize(gridID1);
       remaps[0].nmiss = 0;
 
-      if ( map_type == MAP_TYPE_DISTWGT || map_type == MAP_TYPE_DISTWGT1 )
-	{
-	  if ( !lextrapolate ) remap_extrapolate = TRUE;
-	}
+      if ( map_type == MAP_TYPE_DISTWGT && !lextrapolate ) remap_extrapolate = TRUE;
+      if ( gridIsCircular(gridID1)      && !lextrapolate ) remap_extrapolate = TRUE;
 
-      if ( gridIsCircular(gridID1) && !lextrapolate ) remap_extrapolate = TRUE;
       non_global = remap_non_global || !gridIsCircular(gridID1);
       if ( !remap_extrapolate && gridInqSize(gridID1) > 1 &&
-	   (map_type == MAP_TYPE_DISTWGT || map_type == MAP_TYPE_DISTWGT1) &&
+	   map_type == MAP_TYPE_DISTWGT &&
 	   ((gridInqType(gridID1) == GRID_LONLAT && gridIsRotated(gridID1)) ||
 	    (gridInqType(gridID1) == GRID_LONLAT && non_global) ||
 	    (gridInqType(gridID1) == GRID_LCC) ||
@@ -583,18 +588,18 @@ void *Remap(void *argument)
 	    (gridInqType(gridID1) == GRID_CURVILINEAR && non_global)) )
 	{
 	  remaps[0].gridsize += 4*(gridInqXsize(gridID1)+2) + 4*(gridInqYsize(gridID1)+2);
-	  remaps[0].grid.non_global = TRUE;
+	  remaps[0].src_grid.non_global = TRUE;
 	}
 
-      if ( gridInqType(gridID1) == GRID_GME ) gridsize = remaps[0].grid.grid1_nvgp;
+      if ( gridInqType(gridID1) == GRID_GME ) gridsize = remaps[0].src_grid.nvgp;
 
       if ( gridsize != remaps[0].gridsize )
 	cdoAbort("Size of source grid and weights from %s differ!", remap_file);
 
-      if ( gridInqType(gridID1) == GRID_GME ) gridsize = remaps[0].grid.grid1_size;
+      if ( gridInqType(gridID1) == GRID_GME ) gridsize = remaps[0].src_grid.size;
 
       for ( i = 0; i < gridsize; i++ )
-        if ( remaps[0].grid.grid1_mask[i] == FALSE )
+        if ( remaps[0].src_grid.mask[i] == FALSE )
           remaps[0].nmiss++;
 
       gridsize2 = gridInqSize(gridID2);
@@ -602,29 +607,28 @@ void *Remap(void *argument)
 	{
 	  int gridID2_gme;
 	  int isize = 0;
-	  remaps[0].grid.grid2_nvgp = gridInqSize(gridID2);
-	  remaps[0].grid.grid2_vgpm = (int *) realloc(remaps[0].grid.grid2_vgpm,
-						      gridInqSize(gridID2)*sizeof(int));
+	  remaps[0].tgt_grid.nvgp = gridInqSize(gridID2);
+	  remaps[0].tgt_grid.vgpm = realloc(remaps[0].tgt_grid.vgpm, gridInqSize(gridID2)*sizeof(int));
 	  gridID2_gme = gridToUnstructured(gridID2, 1);
-	  gridInqMaskGME(gridID2_gme, remaps[0].grid.grid2_vgpm);
+	  gridInqMaskGME(gridID2_gme, remaps[0].tgt_grid.vgpm);
 	  for ( i = 0; i < gridsize2; ++i )
-	    if ( remaps[0].grid.grid2_vgpm[i] ) isize++;
+	    if ( remaps[0].tgt_grid.vgpm[i] ) isize++;
 	  gridsize2 = isize;
 	}
       /*
-      printf("grid2 %d %d %d\n", gridsize2, remaps[0].grid.grid2_nvgp, remaps[0].grid.grid2_size);
+      printf("grid2 %d %d %d\n", gridsize2, remaps[0].tgt_grid.nvgp, remaps[0].tgt_grid.size);
       */
-      if ( remaps[0].grid.grid2_size != gridsize2 )
+      if ( remaps[0].tgt_grid.size != gridsize2 )
 	cdoAbort("Size of target grid and weights from %s differ!", remap_file);
 
-      operfunc = maptype2operfunc(map_type, submap_type, remap_order);
+      operfunc = maptype2operfunc(map_type, submap_type, num_neighbors, remap_order);
 
       if ( remap_test ) reorder_links(&remaps[0].vars);
     }
 
-  get_map_type(operfunc, &map_type, &submap_type, &remap_order);
+  get_map_type(operfunc, &map_type, &submap_type, &num_neighbors, &remap_order);
 
-  if ( map_type == MAP_TYPE_CONSERV )
+  if ( map_type == MAP_TYPE_CONSERV ||map_type == MAP_TYPE_CONSPHERE )
     {
       norm_opt = NORM_OPT_FRACAREA;
 
@@ -666,16 +670,16 @@ void *Remap(void *argument)
 
   if ( need_gradiants )
     {
-      grad1_lat    = (double *) malloc(grid1sizemax*sizeof(double));
-      grad1_lon    = (double *) malloc(grid1sizemax*sizeof(double));
-      grad1_latlon = (double *) malloc(grid1sizemax*sizeof(double));
+      grad1_lat    = malloc(grid1sizemax*sizeof(double));
+      grad1_lon    = malloc(grid1sizemax*sizeof(double));
+      grad1_latlon = malloc(grid1sizemax*sizeof(double));
     }
 
-  array1 = (double *) malloc(grid1sizemax*sizeof(double));
-  imask  = (int *) malloc(grid1sizemax*sizeof(int));
+  array1 = malloc(grid1sizemax*sizeof(double));
+  imask  = malloc(grid1sizemax*sizeof(int));
 
   gridsize = gridInqSize(gridID2);
-  array2   = (double *) malloc(gridsize*sizeof(double));
+  array2   = malloc(gridsize*sizeof(double));
 
   if ( ! lwrite_remap )
     {
@@ -710,7 +714,7 @@ void *Remap(void *argument)
 		}
 	    }
 
-	  if ( map_type != MAP_TYPE_CONSERV && 
+	  if ( map_type != MAP_TYPE_CONSERV && map_type != MAP_TYPE_CONSPHERE && 
 	       gridInqType(gridID1) == GRID_GME && gridInqType(gridID2) == GRID_GME )
 	    cdoAbort("Only conservative remapping is available to remap between GME grids!");
 	  /*
@@ -723,7 +727,7 @@ void *Remap(void *argument)
 	  if ( gridIsCircular(gridID1) && !lextrapolate ) remap_extrapolate = TRUE;
 	  non_global = remap_non_global || !gridIsCircular(gridID1);
 	  if ( !remap_extrapolate && gridInqSize(gridID1) > 1 &&
-	       (map_type == MAP_TYPE_DISTWGT || map_type == MAP_TYPE_DISTWGT1) &&
+	       map_type == MAP_TYPE_DISTWGT  &&
 	       ((gridInqType(gridID1) == GRID_LONLAT && gridIsRotated(gridID1)) ||
 		(gridInqType(gridID1) == GRID_LONLAT && non_global) ||
 		(gridInqType(gridID1) == GRID_LCC) ||
@@ -739,14 +743,14 @@ void *Remap(void *argument)
 	      if ( gridsize_new > grid1sizemax )
 		{
 		  grid1sizemax = gridsize_new;
-		  array1 = (double *) realloc(array1, grid1sizemax*sizeof(double));
-		  imask  = (int *) realloc(imask, grid1sizemax*sizeof(int));
+		  array1 = realloc(array1, grid1sizemax*sizeof(double));
+		  imask  = realloc(imask, grid1sizemax*sizeof(int));
 
 		  if ( need_gradiants )
 		    {
-		      grad1_lat    = (double *) realloc(grad1_lat, grid1sizemax*sizeof(double));
-		      grad1_lon    = (double *) realloc(grad1_lon, grid1sizemax*sizeof(double));
-		      grad1_latlon = (double *) realloc(grad1_latlon, grid1sizemax*sizeof(double));
+		      grad1_lat    = realloc(grad1_lat, grid1sizemax*sizeof(double));
+		      grad1_lon    = realloc(grad1_lon, grid1sizemax*sizeof(double));
+		      grad1_latlon = realloc(grad1_latlon, grid1sizemax*sizeof(double));
 		    }
 		}
 	      
@@ -777,7 +781,7 @@ void *Remap(void *argument)
 	    {
 	      if ( gridID1 == remaps[r].gridID && nmiss1 == remaps[r].nmiss )
 		{
-		  if ( memcmp(imask, remaps[r].grid.grid1_mask, remaps[r].grid.grid1_size*sizeof(int)) == 0 )
+		  if ( memcmp(imask, remaps[r].src_grid.mask, remaps[r].src_grid.size*sizeof(int)) == 0 )
 		    break;
 		}	      
 	    }
@@ -799,10 +803,10 @@ void *Remap(void *argument)
 	      if ( remaps[r].gridID != gridID1 )
 		{
 		  if ( gridIsCircular(gridID1) && !lextrapolate ) remap_extrapolate = TRUE;
-		  remaps[r].grid.non_global = FALSE;
+		  remaps[r].src_grid.non_global = FALSE;
 		  non_global = remap_non_global || !gridIsCircular(gridID1);
 		  if ( !remap_extrapolate && gridInqSize(gridID1) > 1 &&
-		       (map_type == MAP_TYPE_DISTWGT || map_type == MAP_TYPE_DISTWGT1) &&
+		       map_type == MAP_TYPE_DISTWGT &&
 		       ((gridInqType(gridID1) == GRID_LONLAT && gridIsRotated(gridID1)) ||
 			(gridInqType(gridID1) == GRID_LONLAT && non_global) ||
 			(gridInqType(gridID1) == GRID_LCC) ||
@@ -810,15 +814,15 @@ void *Remap(void *argument)
 			(gridInqType(gridID1) == GRID_SINUSOIDAL) ||
 			(gridInqType(gridID1) == GRID_CURVILINEAR && non_global)) )
 		    {
-		      remaps[r].grid.non_global = TRUE;
+		      remaps[r].src_grid.non_global = TRUE;
 		    }
 		  /*
-		    remaps[r].grid.luse_grid1_area = FALSE;
-		    remaps[r].grid.luse_grid2_area = FALSE;
+		    remaps[r].src_grid.luse_cell_area = FALSE;
+		    remaps[r].tgt_grid.luse_cell_area = FALSE;
 		  */
 		  if ( gridInqType(gridID1) != GRID_UNSTRUCTURED && lremap_num_srch_bins == FALSE )
 		    {
-		      if ( !remap_extrapolate && (map_type == MAP_TYPE_DISTWGT || map_type == MAP_TYPE_DISTWGT1) )
+		      if ( !remap_extrapolate && map_type == MAP_TYPE_DISTWGT )
 			{
 			  remap_num_srch_bins = 1;
 			}
@@ -832,10 +836,7 @@ void *Remap(void *argument)
 			}
 		    }
 
-		  remaps[r].grid.threshhold    = remap_threshhold;
-		  remaps[r].grid.restrict_type = remap_restrict_type;
-		  remaps[r].grid.num_srch_bins = remap_num_srch_bins;
-		  remaps[r].grid.pinit = FALSE;
+		  remap_set_int(REMAP_NUM_SRCH_BINS, remap_num_srch_bins);
 
 		  remaps[r].vars.norm_opt = norm_opt;
 		  remaps[r].vars.pinit = FALSE;
@@ -846,10 +847,8 @@ void *Remap(void *argument)
 
 		  /* initialize grid information for both grids */
 		  if ( cdoTimer ) timer_start(timer_remap_init);
-		  remapGridInit(map_type, remap_extrapolate, gridID1, gridID2, &remaps[r].grid);
+		  remap_grids_init(map_type, remap_extrapolate, gridID1, &remaps[r].src_grid, gridID2, &remaps[r].tgt_grid);
 		  if ( cdoTimer ) timer_stop(timer_remap_init);
-
-		  remaps[r].grid.store_link_fast = remap_store_link_fast;
 		}
 
 	      remaps[r].gridID = gridID1;
@@ -859,52 +858,55 @@ void *Remap(void *argument)
 		{
 		  j = 0;
 		  for ( i = 0; i < gridsize; i++ )
-		    if ( remaps[r].grid.grid1_vgpm[i] ) imask[j++] = imask[i];
+		    if ( remaps[r].src_grid.vgpm[i] ) imask[j++] = imask[i];
 		}
 
-	      memcpy(remaps[r].grid.grid1_mask, imask, remaps[r].grid.grid1_size*sizeof(int));
+	      memcpy(remaps[r].src_grid.mask, imask, remaps[r].src_grid.size*sizeof(int));
 
-	      if ( map_type == MAP_TYPE_CONSERV )
+	      if ( map_type == MAP_TYPE_CONSERV || map_type == MAP_TYPE_CONSPHERE )
 		{
-		  memset(remaps[r].grid.grid1_area, 0, remaps[r].grid.grid1_size*sizeof(double));
-		  memset(remaps[r].grid.grid1_frac, 0, remaps[r].grid.grid1_size*sizeof(double));
-		  memset(remaps[r].grid.grid2_area, 0, remaps[r].grid.grid2_size*sizeof(double));
+		  memset(remaps[r].src_grid.cell_area, 0, remaps[r].src_grid.size*sizeof(double));
+		  memset(remaps[r].src_grid.cell_frac, 0, remaps[r].src_grid.size*sizeof(double));
+		  memset(remaps[r].tgt_grid.cell_area, 0, remaps[r].tgt_grid.size*sizeof(double));
 		}
-	      memset(remaps[r].grid.grid2_frac, 0, remaps[r].grid.grid2_size*sizeof(double));
+	      memset(remaps[r].tgt_grid.cell_frac, 0, remaps[r].tgt_grid.size*sizeof(double));
 
 	      /* initialize some remapping variables */
 	      if ( cdoTimer ) timer_start(timer_remap_init);
-	      remapVarsInit(map_type, &remaps[r].grid, &remaps[r].vars);
+	      remap_vars_init(map_type, remaps[r].src_grid.size, remaps[r].tgt_grid.size, &remaps[r].vars);
 	      if ( cdoTimer ) timer_stop(timer_remap_init);
 
-	      if      ( map_type == MAP_TYPE_CONSERV  ) remap_conserv(&remaps[r].grid, &remaps[r].vars);
-	      else if ( map_type == MAP_TYPE_BILINEAR ) remap_bilin(&remaps[r].grid, &remaps[r].vars);
-	      else if ( map_type == MAP_TYPE_BICUBIC  ) remap_bicub(&remaps[r].grid, &remaps[r].vars);
-	      else if ( map_type == MAP_TYPE_DISTWGT  ) remap_distwgt(&remaps[r].grid, &remaps[r].vars);
-	      else if ( map_type == MAP_TYPE_DISTWGT1 ) remap_distwgt1(&remaps[r].grid, &remaps[r].vars);
+	      if      ( map_type == MAP_TYPE_CONSERV   ) remap_conserv(&remaps[r].src_grid, &remaps[r].tgt_grid, &remaps[r].vars);
+	      else if ( map_type == MAP_TYPE_BILINEAR  ) remap_bilin(&remaps[r].src_grid, &remaps[r].tgt_grid, &remaps[r].vars);
+	      else if ( map_type == MAP_TYPE_BICUBIC   ) remap_bicub(&remaps[r].src_grid, &remaps[r].tgt_grid, &remaps[r].vars);
+	      else if ( map_type == MAP_TYPE_DISTWGT   ) remap_distwgt(num_neighbors, &remaps[r].src_grid, &remaps[r].tgt_grid, &remaps[r].vars);
+	      else if ( map_type == MAP_TYPE_CONSPHERE ) remap_consphere(&remaps[r].src_grid, &remaps[r].tgt_grid, &remaps[r].vars);
 
 	      if ( remaps[r].vars.num_links != remaps[r].vars.max_links )
 		resize_remap_vars(&remaps[r].vars, remaps[r].vars.num_links-remaps[r].vars.max_links);
 
-	      if ( cdoTimer ) timer_start(timer_remap_sort);
-	      if ( sort_mode == MERGE_SORT )
-		{ /* 
-		  ** use a combination of the old sort_add and a split and merge approach.
-                  ** The chunk size is determined by MERGE_SORT_LIMIT_SIZE in remaplib.c. 
-		  ** OpenMP parallelism is supported
-		  */   
-		  sort_iter(remaps[r].vars.num_links, remaps[r].vars.num_wts,
-			    remaps[r].vars.grid2_add, remaps[r].vars.grid1_add,
-			    remaps[r].vars.wts, ompNumThreads);
-		}
-	      else
-		{ /* use a pure heap sort without any support of parallelism */
-		  sort_add(remaps[r].vars.num_links, remaps[r].vars.num_wts,
-			   remaps[r].vars.grid2_add, remaps[r].vars.grid1_add,
-			   remaps[r].vars.wts);
+	      if ( remaps[r].vars.sort_add )
+		{
+		  if ( cdoTimer ) timer_start(timer_remap_sort);
+		  if ( sort_mode == MERGE_SORT )
+		    { /* 
+		      ** use a combination of the old sort_add and a split and merge approach.
+		      ** The chunk size is determined by MERGE_SORT_LIMIT_SIZE in remaplib.c. 
+		      ** OpenMP parallelism is supported
+		      */   
+		      sort_iter(remaps[r].vars.num_links, remaps[r].vars.num_wts,
+				remaps[r].vars.tgt_grid_add, remaps[r].vars.src_grid_add,
+				remaps[r].vars.wts, ompNumThreads);
+		    }
+		  else
+		    { /* use a pure heap sort without any support of parallelism */
+		      sort_add(remaps[r].vars.num_links, remaps[r].vars.num_wts,
+			       remaps[r].vars.tgt_grid_add, remaps[r].vars.src_grid_add,
+			       remaps[r].vars.wts);
+		    }
+		  if ( cdoTimer ) timer_stop(timer_remap_sort);
 		}
-	      if ( cdoTimer ) timer_stop(timer_remap_sort);
-	      	      
+
 	      if ( lwrite_remap ) goto WRITE_REMAP;
 
 	      if ( remap_test ) reorder_links(&remaps[r].vars);
@@ -914,32 +916,32 @@ void *Remap(void *argument)
 	    {
 	      j = 0;
 	      for ( i = 0; i < gridsize; i++ )
-		if ( remaps[r].grid.grid1_vgpm[i] ) array1[j++] = array1[i];
+		if ( remaps[r].src_grid.vgpm[i] ) array1[j++] = array1[i];
 	    }
 	  
 	  if ( need_gradiants )
 	    {
-	      if ( remaps[r].grid.grid1_rank != 2 && remap_order == 2 )
+	      if ( remaps[r].src_grid.rank != 2 && remap_order == 2 )
 		cdoAbort("Second order remapping is only available for 2D grids!");
 
-	      remap_gradients(remaps[r].grid, array1, grad1_lat, grad1_lon, grad1_latlon);
+	      remap_gradients(remaps[r].src_grid, array1, grad1_lat, grad1_lon, grad1_latlon);
 	    }
 
 	  if ( operfunc == REMAPLAF )
 	    remap_laf(array2, missval, gridInqSize(gridID2), remaps[r].vars.num_links, remaps[r].vars.wts,
-		  remaps[r].vars.num_wts, remaps[r].vars.grid2_add, remaps[r].vars.grid1_add, array1);
+		  remaps[r].vars.num_wts, remaps[r].vars.tgt_grid_add, remaps[r].vars.src_grid_add, array1);
 	  else if ( operfunc == REMAPSUM )
 	    remap_sum(array2, missval, gridInqSize(gridID2), remaps[r].vars.num_links, remaps[r].vars.wts,
-		  remaps[r].vars.num_wts, remaps[r].vars.grid2_add, remaps[r].vars.grid1_add, array1);
+		  remaps[r].vars.num_wts, remaps[r].vars.tgt_grid_add, remaps[r].vars.src_grid_add, array1);
 	  else
 	    remap(array2, missval, gridInqSize(gridID2), remaps[r].vars.num_links, remaps[r].vars.wts,
-		  remaps[r].vars.num_wts, remaps[r].vars.grid2_add, remaps[r].vars.grid1_add,
+		  remaps[r].vars.num_wts, remaps[r].vars.tgt_grid_add, remaps[r].vars.src_grid_add,
 		  array1, grad1_lat, grad1_lon, grad1_latlon, remaps[r].vars.links);
 
 	  gridsize2 = gridInqSize(gridID2);
 
 	  /* used only to check the result of remapcon */
-	  if ( operfunc == REMAPCON || operfunc == REMAPCON2 )
+	  if ( operfunc == REMAPCON || operfunc == REMAPCON2|| operfunc == REMAPCONS )
 	    {
 	      double grid2_err;
 
@@ -947,7 +949,7 @@ void *Remap(void *argument)
 		{
 		  for ( i = 0; i < gridsize2; i++ )
 		    {
-		      grid2_err = remaps[r].grid.grid2_frac[i]*remaps[r].grid.grid2_area[i];
+		      grid2_err = remaps[r].tgt_grid.cell_frac[i]*remaps[r].tgt_grid.cell_area[i];
 		      if ( fabs(grid2_err) > 0 )
 			array2[i] = array2[i]/grid2_err;
 		      else
@@ -958,8 +960,8 @@ void *Remap(void *argument)
 		{
 		  for ( i = 0; i < gridsize2; i++ )
 		    {
-		      if ( fabs(remaps[r].grid.grid2_frac[i]) > 0 )
-			array2[i] = array2[i]/remaps[r].grid.grid2_frac[i];
+		      if ( fabs(remaps[r].tgt_grid.cell_frac[i]) > 0 )
+			array2[i] = array2[i]/remaps[r].tgt_grid.cell_frac[i];
 		      else
 			array2[i] = missval;
 		    }
@@ -969,50 +971,50 @@ void *Remap(void *argument)
 		{
 		  for ( i = 0; i < gridsize2; i++ )
 		    {
-		      //printf("%d %g %g\n", i, remaps[r].grid.grid2_frac[i], remaps[r].grid.grid2_area[i]);
-		      if ( remaps[r].grid.grid2_frac[i] < remap_area_min ) array2[i] = missval;
+		      //printf("%d %g %g\n", i, remaps[r].tgt_grid.cell_frac[i], remaps[r].tgt_grid.cell_area[i]);
+		      if ( remaps[r].tgt_grid.cell_frac[i] < remap_area_min ) array2[i] = missval;
 		    }
 		}
 	    }
 
 	  if ( operfunc == REMAPSUM )
-	  {
-	    double array1sum = 0;
-	    double array2sum = 0;
+	    {
+	      double array1sum = 0;
+	      double array2sum = 0;
    
-	    for ( i = 0; i < gridsize; i++ )
-	      printf("1 %d %g %g %g %g\n", i, array1[i], remaps[r].grid.grid1_frac[i], remaps[r].grid.grid1_area[i],remaps[r].grid.grid1_frac[i]);
-	    for ( i = 0; i < gridsize; i++ )
-	      array1sum += remaps[r].grid.grid1_area[i];
+	      for ( i = 0; i < gridsize; i++ )
+		printf("1 %d %g %g %g %g\n", i, array1[i], remaps[r].src_grid.cell_frac[i], remaps[r].src_grid.cell_area[i],remaps[r].src_grid.cell_frac[i]);
+	      for ( i = 0; i < gridsize; i++ )
+		array1sum += remaps[r].src_grid.cell_area[i];
 
-	    for ( i = 0; i < gridsize2; i++ )
-	      printf("2 %d %g %g %g %g\n", i, array2[i], remaps[r].grid.grid2_frac[i],remaps[r].grid.grid2_area[i],remaps[r].grid.grid2_frac[i]);
-	    for ( i = 0; i < gridsize2; i++ )
-	      array2sum += remaps[r].grid.grid2_area[i];
+	      for ( i = 0; i < gridsize2; i++ )
+		printf("2 %d %g %g %g %g\n", i, array2[i], remaps[r].tgt_grid.cell_frac[i],remaps[r].tgt_grid.cell_area[i],remaps[r].tgt_grid.cell_frac[i]);
+	      for ( i = 0; i < gridsize2; i++ )
+		array2sum += remaps[r].tgt_grid.cell_area[i];
 
-	    printf("array1sum %g, array2sum %g\n", array1sum, array2sum);
-	  }
+	      printf("array1sum %g, array2sum %g\n", array1sum, array2sum);
+	    }
 
 	  vlistInqVarName(vlistID1, varID, varname);
-	  if ( operfunc == REMAPCON || operfunc == REMAPCON2 )
+	  if ( operfunc == REMAPCON || operfunc == REMAPCON2 || operfunc == REMAPCONS )
 	    if ( strcmp(varname, "gridbox_area") == 0 )
 	      {
-		scale_gridbox_area(gridsize, array1, gridsize2, array2, remaps[r].grid.grid2_area);
+		scale_gridbox_area(gridsize, array1, gridsize2, array2, remaps[r].tgt_grid.cell_area);
 	      }
 
 	  /* calculate some statistics */
 	  if ( cdoVerbose )
-	    remap_stat(remap_order, remaps[r].grid, remaps[r].vars, array1, array2, missval);
+	    remap_stat(remap_order, remaps[r].src_grid, remaps[r].tgt_grid, remaps[r].vars, array1, array2, missval);
 
 	  if ( gridInqType(gridID2) == GRID_GME )
 	    {
 	      int ni, nd;
  	      ni = gridInqGMEni(gridID2);
 	      nd = gridInqGMEnd(gridID2);
-	      j = remaps[r].grid.grid2_size;
+	      j = remaps[r].tgt_grid.size;
 
 	      for ( i = gridsize2-1; i >=0 ; i-- )
-		if ( remaps[r].grid.grid2_vgpm[i] ) array2[i] = array2[--j];
+		if ( remaps[r].tgt_grid.vgpm[i] ) array2[i] = array2[--j];
 
 	      gme_grid_restore(array2, ni, nd);
 	    }
@@ -1034,7 +1036,8 @@ void *Remap(void *argument)
   WRITE_REMAP:
  
   if ( lwrite_remap ) 
-    write_remap_scrip(cdoStreamName(1)->args, map_type, submap_type, remap_order, remaps[r].grid, remaps[r].vars);
+    write_remap_scrip(cdoStreamName(1)->args, map_type, submap_type, num_neighbors, remap_order,
+		      remaps[r].src_grid, remaps[r].tgt_grid, remaps[r].vars);
 
   streamClose(streamID1);
 
@@ -1050,7 +1053,8 @@ void *Remap(void *argument)
   for ( r = 0; r < nremaps; r++ )
     {
       remapVarsFree(&remaps[r].vars);
-      remapGridFree(&remaps[r].grid);
+      remapGridFree(&remaps[r].src_grid);
+      remapGridFree(&remaps[r].tgt_grid);
     }
 
   if ( remaps ) free(remaps);
diff --git a/src/Remapeta.c b/src/Remapeta.c
index 880f1c5..f8039b3 100644
--- a/src/Remapeta.c
+++ b/src/Remapeta.c
@@ -28,6 +28,7 @@
 #include "pstream.h"
 #include "vinterp.h"
 #include "list.h"
+#include "stdnametable.h"
 #include "hetaeta.h"
 
 
@@ -110,7 +111,7 @@ double *vctFromFile(const char *filename, int *nvct)
   fp = fopen(filename, "r");
   if ( fp == NULL ) { perror(filename); exit(EXIT_FAILURE); }
 
-  vct2 = (double *) malloc(maxvct*sizeof(double));
+  vct2 = malloc(maxvct*sizeof(double));
 
   while ( readline(fp, line, 1024) )
     {
@@ -140,7 +141,7 @@ double *vctFromFile(const char *filename, int *nvct)
   for ( i = 0; i < nlevh2+1; ++i )
     vct2[i+nvct2/2] = vct2[i+maxvct/2];
   
-  vct2 = (double *) realloc(vct2, nvct2*sizeof(double));
+  vct2 = realloc(vct2, nvct2*sizeof(double));
 
   *nvct = nvct2;
 
@@ -274,14 +275,14 @@ void *Remapeta(void *argument)
       gridID  = vlistInqVarGrid(vlistID1, varID);
       nfis2gp = gridInqSize(gridID);
 
-      fis2 = (double *) malloc(nfis2gp*sizeof(double));
+      fis2 = malloc(nfis2gp*sizeof(double));
 
       streamReadRecord(streamID1, fis2, &nmiss);
 
       if ( nmiss )
 	{
 	  missval = vlistInqVarMissval(vlistID1, varID);
-	  imiss = (int *) malloc (nfis2gp*sizeof(int));
+	  imiss = malloc (nfis2gp*sizeof(int));
 	  for ( i = 0; i < nfis2gp; ++i )
 	    {
 	      if ( DBL_IS_EQUAL(fis2[i], missval) )
@@ -293,13 +294,13 @@ void *Remapeta(void *argument)
 	  nmissout = nmiss;
 	}
 
-      /* check range of geop */
+      /* check range of surface_geopotential */
       minmaxval(nfis2gp, fis2, imiss, &minval, &maxval);
       if ( minval < MIN_FIS || maxval > MAX_FIS )
-	cdoWarning("Orography out of range (min=%g max=%g)!", minval, maxval);
+	cdoWarning("%s out of range (min=%g max=%g)!", var_stdname(surface_geopotential), minval, maxval);
 
       if ( minval < -1.e10 || maxval > 1.e10 )
-	cdoAbort("Orography out of range!");
+	cdoAbort("%s out of range!", var_stdname(surface_geopotential));
 
       streamClose(streamID1); 
     }
@@ -340,7 +341,7 @@ void *Remapeta(void *argument)
     }
 
   zaxisID2 = zaxisCreate(ZAXIS_HYBRID, nhlevf2);
-  lev2 = (double *) malloc(nhlevf2*sizeof(double));
+  lev2 = malloc(nhlevf2*sizeof(double));
   for ( i = 0; i < nhlevf2; ++i ) lev2[i] = i+1;
   zaxisDefLevels(zaxisID2, lev2);
   free(lev2);
@@ -380,7 +381,7 @@ void *Remapeta(void *argument)
                       if ( cdoVerbose )
                         cdoPrint("lhavevct=TRUE  zaxisIDh = %d, nhlevf1   = %d", zaxisIDh, nlevel);
  
-		      vct1 = (double *) malloc(nvct1*sizeof(double));
+		      vct1 = malloc(nvct1*sizeof(double));
 		      zaxisInqVct(zaxisID, vct1);
 		      
 		      vlistChangeZaxisIndex(vlistID2, i, zaxisID2);
@@ -496,57 +497,57 @@ void *Remapeta(void *argument)
   */
   if ( operatorID == REMAPETAS || operatorID == REMAPETAZ)
     {
-      sum1 = (double *) malloc(ngp*sizeof(double));
-      sum2 = (double *) malloc(ngp*sizeof(double));
+      sum1 = malloc(ngp*sizeof(double));
+      sum2 = malloc(ngp*sizeof(double));
     }
 
   if ( operatorID == REMAPETAZ )
     {
-      deltap1 = (double *) malloc(ngp*nhlevf1*sizeof(double));
-      deltap2 = (double *) malloc(ngp*nhlevf2*sizeof(double));
-      half_press1 = (double *) malloc(ngp*(nhlevf1+1)*sizeof(double));
-      half_press2 = (double *) malloc(ngp*(nhlevf2+1)*sizeof(double));
+      deltap1 = malloc(ngp*nhlevf1*sizeof(double));
+      deltap2 = malloc(ngp*nhlevf2*sizeof(double));
+      half_press1 = malloc(ngp*(nhlevf1+1)*sizeof(double));
+      half_press2 = malloc(ngp*(nhlevf2+1)*sizeof(double));
     }
 
-  array = (double *) malloc(ngp*sizeof(double));
+  array = malloc(ngp*sizeof(double));
 
-  fis1  = (double *) malloc(ngp*sizeof(double));
-  ps1   = (double *) malloc(ngp*sizeof(double));
+  fis1  = malloc(ngp*sizeof(double));
+  ps1   = malloc(ngp*sizeof(double));
 
-  if ( lfis2 == FALSE ) fis2  = (double *) malloc(ngp*sizeof(double));
+  if ( lfis2 == FALSE ) fis2  = malloc(ngp*sizeof(double));
   if ( lfis2 == TRUE && ngp != nfis2gp ) cdoAbort("Orographies have different grid size!");
 
-  ps2   = (double *) malloc(ngp*sizeof(double));
+  ps2   = malloc(ngp*sizeof(double));
 
   if ( ltq )
     {
-      tscor = (double *) malloc(ngp*sizeof(double));
-      pscor = (double *) malloc(ngp*sizeof(double));
-      secor = (double *) malloc(ngp*sizeof(double));
+      tscor = malloc(ngp*sizeof(double));
+      pscor = malloc(ngp*sizeof(double));
+      secor = malloc(ngp*sizeof(double));
 
-      t1    = (double *) malloc(ngp*nhlevf1*sizeof(double));
-      q1    = (double *) malloc(ngp*nhlevf1*sizeof(double));
+      t1    = malloc(ngp*nhlevf1*sizeof(double));
+      q1    = malloc(ngp*nhlevf1*sizeof(double));
 
-      t2    = (double *) malloc(ngp*nhlevf2*sizeof(double));
-      q2    = (double *) malloc(ngp*nhlevf2*sizeof(double));
+      t2    = malloc(ngp*nhlevf2*sizeof(double));
+      q2    = malloc(ngp*nhlevf2*sizeof(double));
     }
 
   if ( nvars3D )
     {
-      vars1  = (double **) malloc(nvars*sizeof(double));
-      vars2  = (double **) malloc(nvars*sizeof(double));
+      vars1  = malloc(nvars*sizeof(double));
+      vars2  = malloc(nvars*sizeof(double));
 
       for ( varID = 0; varID < nvars3D; ++varID )
 	{
-	  vars1[varID] = (double *) malloc(ngp*nhlevf1*sizeof(double));
-	  vars2[varID] = (double *) malloc(ngp*nhlevf2*sizeof(double));
+	  vars1[varID] = malloc(ngp*nhlevf1*sizeof(double));
+	  vars2[varID] = malloc(ngp*nhlevf2*sizeof(double));
 	}
     }
 
   if ( zaxisIDh != -1 && geopID == -1 )
     {
       if ( ltq )
-	cdoWarning("Orography (surf. geopotential) not found - using zero orography!");
+	cdoWarning("%s not found - using zero %s!", var_stdname(surface_geopotential), var_stdname(surface_geopotential));
 
       memset(fis1, 0, ngp*sizeof(double));
     }
@@ -556,9 +557,9 @@ void *Remapeta(void *argument)
     {
       presID = psID;
       if ( psID != -1 )
-	cdoWarning("LOG surface pressure (lsp) not found - using surface pressure (asp)!");
+	cdoWarning("LOG(%s) not found - using %s!", var_stdname(surface_air_pressure), var_stdname(surface_air_pressure));
       else
-	cdoAbort("Surface pressure not found!");
+	cdoAbort("%s not found!", var_stdname(surface_air_pressure));
     }
 
   if ( cdoVerbose ) cdoPrint("nvars3D = %d   ltq = %d", nvars3D, ltq);
diff --git a/src/Replace.c b/src/Replace.c
index 833d6a3..dacb7a9 100644
--- a/src/Replace.c
+++ b/src/Replace.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -127,9 +127,9 @@ void *Replace(void *argument)
 
   if ( nchvars )
     {
-      vardata2  = (double **) malloc(nchvars*sizeof(double *));
-      varnmiss2 = (int **) malloc(nchvars*sizeof(int *));
-      varlevel  = (int **) malloc(nchvars*sizeof(int *));
+      vardata2  = malloc(nchvars*sizeof(double *));
+      varnmiss2 = malloc(nchvars*sizeof(int *));
+      varlevel  = malloc(nchvars*sizeof(int *));
       for ( idx = 0; idx < nchvars; idx++ )
 	{
 	  varID1 = varlist1[idx];
@@ -137,17 +137,17 @@ void *Replace(void *argument)
 	  nlevel1  = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID1));
 	  nlevel2  = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID2));
 	  gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID2));
-	  vardata2[idx]  = (double *) malloc(nlevel2*gridsize*sizeof(double));
-	  varnmiss2[idx] = (int *) malloc(nlevel2*sizeof(int));
-	  varlevel[idx] = (int *) malloc(nlevel1*sizeof(int));
+	  vardata2[idx]  = malloc(nlevel2*gridsize*sizeof(double));
+	  varnmiss2[idx] = malloc(nlevel2*sizeof(int));
+	  varlevel[idx] = malloc(nlevel1*sizeof(int));
 	  /*
 	  for ( levelID = 0; levelID < nlevel1; levelID++ )
 	    varlevel[idx][levelID] = levelID;
 	  */
 	  if ( nlevel2 <= nlevel1 )
 	    {
-	      double *level1 = (double *) malloc(nlevel1*sizeof(double));
-	      double *level2 = (double *) malloc(nlevel2*sizeof(double));
+	      double *level1 = malloc(nlevel1*sizeof(double));
+	      double *level2 = malloc(nlevel2*sizeof(double));
 	      zaxisInqLevels(vlistInqVarZaxis(vlistID1, varID1), level1);
 	      zaxisInqLevels(vlistInqVarZaxis(vlistID2, varID2), level2);
 
@@ -181,7 +181,7 @@ void *Replace(void *argument)
   streamDefVlist(streamID3, vlistID3);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   nts2 = vlistNtsteps(vlistID2);
 
diff --git a/src/Replacevalues.c b/src/Replacevalues.c
index 349fb7c..0712c7a 100644
--- a/src/Replacevalues.c
+++ b/src/Replacevalues.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -112,7 +112,7 @@ void *Replacevalues(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Rhopot.c b/src/Rhopot.c
index 9121f2d..3d622b6 100644
--- a/src/Rhopot.c
+++ b/src/Rhopot.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -246,7 +246,7 @@ void *Rhopot(void *argument)
   if ( nlevel1 != nlevel2 ) cdoAbort("temperature and salinity have different number of levels!");
   nlevel = nlevel1;
 
-  pressure = (double *) malloc(nlevel*sizeof(double));
+  pressure = malloc(nlevel*sizeof(double));
   zaxisInqLevels(zaxisID, pressure);
 
   if ( pin >= 0 ) 
@@ -264,9 +264,9 @@ void *Rhopot(void *argument)
   field_init(&to);
   field_init(&sao);
   field_init(&rho);
-  to.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
-  sao.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
-  rho.ptr = (double *) malloc(gridsize*nlevel*sizeof(double));
+  to.ptr = malloc(gridsize*nlevel*sizeof(double));
+  sao.ptr = malloc(gridsize*nlevel*sizeof(double));
+  rho.ptr = malloc(gridsize*nlevel*sizeof(double));
 
   to.nmiss = 0;
   sao.nmiss = 0;
diff --git a/src/Rotuv.c b/src/Rotuv.c
index 3d0eb0c..87324c2 100644
--- a/src/Rotuv.c
+++ b/src/Rotuv.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -46,8 +46,8 @@ void rot_uv_back(int gridID, double *us, double *vs)
   ypole = gridInqYpole(gridID);
   angle = gridInqAngle(gridID);
 
-  xvals = (double *) malloc(nlon*sizeof(double));
-  yvals = (double *) malloc(nlat*sizeof(double));
+  xvals = malloc(nlon*sizeof(double));
+  yvals = malloc(nlat*sizeof(double));
 
   gridInqXvals(gridID, xvals);
   gridInqYvals(gridID, yvals);
@@ -137,11 +137,11 @@ void *Rotuv(void *argument)
   nvars = vlistNvars(vlistID1);
   nrecs = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecs*sizeof(int));
-  recLevelID = (int *) malloc(nrecs*sizeof(int));
+  recVarID   = malloc(nrecs*sizeof(int));
+  recLevelID = malloc(nrecs*sizeof(int));
 
-  varnmiss   = (int **) malloc(nvars*sizeof(int *));
-  vardata    = (double **) malloc(nvars*sizeof(double *));
+  varnmiss   = malloc(nvars*sizeof(int *));
+  vardata    = malloc(nvars*sizeof(double *));
 
   for ( i = 0; i < nch; i++ ) lfound[i] = FALSE;
 
@@ -176,8 +176,8 @@ void *Rotuv(void *argument)
 
       gridsize = gridInqSize(gridID);
       nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      varnmiss[varID] = (int *)    malloc(nlevel*sizeof(int));
-      vardata[varID]  = (double *) malloc(gridsize*nlevel*sizeof(double));
+      varnmiss[varID] = malloc(nlevel*sizeof(int));
+      vardata[varID]  = malloc(gridsize*nlevel*sizeof(double));
     }
 
   taxisID1 = vlistInqTaxis(vlistID1);
diff --git a/src/Runpctl.c b/src/Runpctl.c
index 86e2164..25b2b48 100644
--- a/src/Runpctl.c
+++ b/src/Runpctl.c
@@ -82,12 +82,12 @@ void *Runpctl(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
-  dtinfo = (dtinfo_t *) malloc((ndates+1)*sizeof(dtinfo_t));
-  vars1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
-  array = (double *) malloc(ndates*sizeof(double));
+  dtinfo = malloc((ndates+1)*sizeof(dtinfo_t));
+  vars1 = malloc((ndates+1)*sizeof(field_t **));
+  array = malloc(ndates*sizeof(double));
   
   for ( its = 0; its < ndates; its++ )
     {
diff --git a/src/Runstat.c b/src/Runstat.c
index 8c99d3a..38fee38 100644
--- a/src/Runstat.c
+++ b/src/Runstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -227,15 +227,15 @@ void *Runstat(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
-  dtinfo = (dtinfo_t *) malloc((ndates+1)*sizeof(dtinfo_t));
-  vars1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
+  dtinfo = malloc((ndates+1)*sizeof(dtinfo_t));
+  vars1 = malloc((ndates+1)*sizeof(field_t **));
   if ( !runstat_nomiss )
-    samp1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
+    samp1 = malloc((ndates+1)*sizeof(field_t **));
   if ( lvarstd )
-    vars2 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
+    vars2 = malloc((ndates+1)*sizeof(field_t **));
 
   for ( its = 0; its < ndates; its++ )
     {
@@ -247,7 +247,7 @@ void *Runstat(void *argument)
     }
 
   gridsizemax = vlistGridsizeMax(vlistID1);
-  imask = (int *) malloc(gridsizemax*sizeof(int));
+  imask = malloc(gridsizemax*sizeof(int));
 
   for ( tsID = 0; tsID < ndates; tsID++ )
     {
diff --git a/src/SSOpar.c b/src/SSOpar.c
index edc8cdc..16cf885 100644
--- a/src/SSOpar.c
+++ b/src/SSOpar.c
@@ -42,10 +42,10 @@ void data_treat(double *zdata, double *xdata, double *ydata, long nx, long ny)
   int *iscale = NULL;
   long i, j;
 
-  zwork = (double *) malloc(3*nx*ny*sizeof(double));
-  xwork = (double *) malloc(3*nx*sizeof(double));
-  xscale = (double *) malloc(ny*sizeof(double));
-  iscale = (int *) malloc(ny*sizeof(int));
+  zwork = malloc(3*nx*ny*sizeof(double));
+  xwork = malloc(3*nx*sizeof(double));
+  xscale = malloc(ny*sizeof(double));
+  iscale = malloc(ny*sizeof(int));
 
   double pi2 = 2*acos(-1.);
   for ( i = 0; i < nx; ++i )
@@ -784,7 +784,7 @@ void *SSOpar(void *argument)
                       if ( cdoVerbose )
                         cdoPrint("lhavevct=TRUE  zaxisIDh = %d, nhlevf   = %d", zaxisIDh, nlevel);
  
-		      vct = (double *) malloc(nvct*sizeof(double));
+		      vct = malloc(nvct*sizeof(double));
 		      zaxisInqVct(zaxisID, vct);
 
 		      if ( cdoVerbose )
@@ -866,18 +866,18 @@ void *SSOpar(void *argument)
 
   if ( tempID == -1 ) cdoAbort("Temperature not found!");
 
-  array  = (double *) malloc(ngp*sizeof(double));
+  array  = malloc(ngp*sizeof(double));
 
-  geop   = (double *) malloc(ngp*sizeof(double));
-  ps     = (double *) malloc(ngp*sizeof(double));
+  geop   = malloc(ngp*sizeof(double));
+  ps     = malloc(ngp*sizeof(double));
 
-  temp   = (double *) malloc(ngp*nhlevf*sizeof(double));
-  hum    = (double *) malloc(ngp*nhlevf*sizeof(double));
-  lwater = (double *) malloc(ngp*nhlevf*sizeof(double));
-  iwater = (double *) malloc(ngp*nhlevf*sizeof(double));
+  temp   = malloc(ngp*nhlevf*sizeof(double));
+  hum    = malloc(ngp*nhlevf*sizeof(double));
+  lwater = malloc(ngp*nhlevf*sizeof(double));
+  iwater = malloc(ngp*nhlevf*sizeof(double));
 
-  half_press   = (double *) malloc(ngp*(nhlevf+1)*sizeof(double));
-  geopotheight = (double *) malloc(ngp*(nhlevf+1)*sizeof(double));
+  half_press   = malloc(ngp*(nhlevf+1)*sizeof(double));
+  geopotheight = malloc(ngp*(nhlevf+1)*sizeof(double));
 
   if ( zaxisIDh != -1 && geopID == -1 )
     {
@@ -902,7 +902,7 @@ void *SSOpar(void *argument)
   varID = vlistDefVar(vlistID2, gridID, zaxisIDh, TSTEP_INSTANT);
   vlistDefVarParam(vlistID2, varID, cdiEncodeParam(156, 128, 255));
   vlistDefVarName(vlistID2, varID, "geopotheight");
-  vlistDefVarStdname(vlistID2, varID, "geopotental_height");
+  vlistDefVarStdname(vlistID2, varID, "geopotential_height");
   vlistDefVarUnits(vlistID2, varID, "m");
 
   taxisID1 = vlistInqTaxis(vlistID1);
diff --git a/src/Scatter.c b/src/Scatter.c
index 9230aab..8ab95a8 100644
--- a/src/Scatter.c
+++ b/src/Scatter.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -41,11 +41,11 @@ void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, i
   nx = gridInqXsize(gridID1);
   ny = gridInqYsize(gridID1);
 
-  xvals = (double *) malloc(nx*sizeof(double));
-  yvals = (double *) malloc(ny*sizeof(double));
+  xvals = malloc(nx*sizeof(double));
+  yvals = malloc(ny*sizeof(double));
 
-  xlsize = (int *) malloc(nxblocks*sizeof(int));
-  ylsize = (int *) malloc(nyblocks*sizeof(int));
+  xlsize = malloc(nxblocks*sizeof(int));
+  ylsize = malloc(nyblocks*sizeof(int));
 
   gridInqXvals(gridID1, xvals);
   gridInqYvals(gridID1, yvals);
@@ -65,7 +65,7 @@ void genGrids(int gridID1, int *gridIDs, int nxvals, int nyvals, int nxblocks, i
 	offset = iy*nyvals*nx + ix*nxvals;
 
 	gridsize2 = xlsize[ix]*ylsize[iy];
-	gridindex[index] = (int *) malloc(gridsize2*sizeof(int));
+	gridindex[index] = malloc(gridsize2*sizeof(int));
 
 	gridsize2 = 0;
         // printf("iy %d, ix %d offset %d\n", iy, ix,  offset);
@@ -207,19 +207,19 @@ void *Scatter(void *argument)
   nsplit = nxblocks*nyblocks;
   if ( nsplit > MAX_BLOCKS ) cdoAbort("Too many blocks (max = %d)!", MAX_BLOCKS);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
 
-  vlistIDs  = (int *) malloc(nsplit*sizeof(int));
-  streamIDs = (int *) malloc(nsplit*sizeof(int));
+  vlistIDs  = malloc(nsplit*sizeof(int));
+  streamIDs = malloc(nsplit*sizeof(int));
 
-  grids = (sgrid_t *) malloc(ngrids*sizeof(sgrid_t));
+  grids = malloc(ngrids*sizeof(sgrid_t));
   for ( i = 0; i < ngrids; i++ )
     {  
       gridID1 = vlistGrid(vlistID1, i);
       grids[i].gridID    = vlistGrid(vlistID1, i);
-      grids[i].gridIDs   = (int *) malloc(nsplit*sizeof(int));
-      grids[i].gridsize  = (int *) malloc(nsplit*sizeof(int));
-      grids[i].gridindex = (int **) malloc(nsplit*sizeof(int*));
+      grids[i].gridIDs   = malloc(nsplit*sizeof(int));
+      grids[i].gridsize  = malloc(nsplit*sizeof(int));
+      grids[i].gridindex = malloc(nsplit*sizeof(int*));
 
       for ( index = 0; index < nsplit; index++ ) grids[i].gridindex[index] = NULL;
     }
@@ -246,7 +246,7 @@ void *Scatter(void *argument)
   for ( index = 0; index < nsplit; index++ )
     if ( grids[0].gridsize[index] > gridsize2max ) gridsize2max = grids[0].gridsize[index];
 
-  array2 = (double *) malloc(gridsize2max*sizeof(double));
+  array2 = malloc(gridsize2max*sizeof(double));
 
   strcpy(filename, cdoStreamName(1)->args);
   nchars = strlen(filename);
diff --git a/src/Seascount.c b/src/Seascount.c
index 028c352..8581896 100644
--- a/src/Seascount.c
+++ b/src/Seascount.c
@@ -71,14 +71,14 @@ void *Seascount(void *argument)
 
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
 
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   vars1 = field_malloc(vlistID1, FIELD_PTR);
 
diff --git a/src/Seaspctl.c b/src/Seaspctl.c
index 4c139bc..b8de942 100644
--- a/src/Seaspctl.c
+++ b/src/Seaspctl.c
@@ -95,14 +95,14 @@ void *Seaspctl(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords * sizeof(int));
-  recLevelID = (int *) malloc(nrecords * sizeof(int));
+  recVarID   = malloc(nrecords * sizeof(int));
+  recLevelID = malloc(nrecords * sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
-  vars1 = (field_t **) malloc(nvars * sizeof(field_t *));
+  vars1 = malloc(nvars * sizeof(field_t *));
   hset = hsetCreate(nvars);
 
   for ( varID = 0; varID < nvars; varID++ )
@@ -112,7 +112,7 @@ void *Seaspctl(void *argument)
       nlevels   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
       missval  = vlistInqVarMissval(vlistID1, varID);
 
-      vars1[varID] = (field_t *) malloc(nlevels * sizeof(field_t));
+      vars1[varID] = malloc(nlevels * sizeof(field_t));
       hsetCreateVarLevels(hset, varID, nlevels, gridID);
 
       for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -120,7 +120,7 @@ void *Seaspctl(void *argument)
 	  vars1[varID][levelID].grid    = gridID;
 	  vars1[varID][levelID].nmiss   = 0;
 	  vars1[varID][levelID].missval = missval;
-	  vars1[varID][levelID].ptr     = (double *) malloc(gridsize * sizeof(double));
+	  vars1[varID][levelID].ptr     = malloc(gridsize * sizeof(double));
 	}
     }
 
diff --git a/src/Seasstat.c b/src/Seasstat.c
index 58b4b8d..a715848 100644
--- a/src/Seasstat.c
+++ b/src/Seasstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -94,13 +94,13 @@ void *Seasstat(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   vars1 = field_malloc(vlistID1, FIELD_PTR);
   samp1 = field_malloc(vlistID1, FIELD_NONE);
@@ -178,7 +178,7 @@ void *Seasstat(void *argument)
 		  if ( nmiss > 0 || samp1[varID][levelID].ptr )
 		    {
 		      if ( samp1[varID][levelID].ptr == NULL )
-			samp1[varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+			samp1[varID][levelID].ptr = malloc(gridsize*sizeof(double));
 
 		      for ( i = 0; i < gridsize; i++ )
 			if ( DBL_IS_EQUAL(vars1[varID][levelID].ptr[i],
@@ -198,7 +198,7 @@ void *Seasstat(void *argument)
 		    {
 		      if ( samp1[varID][levelID].ptr == NULL )
 			{
-			  samp1[varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+			  samp1[varID][levelID].ptr = malloc(gridsize*sizeof(double));
 			  for ( i = 0; i < gridsize; i++ )
 			    samp1[varID][levelID].ptr[i] = nsets;
 			}
diff --git a/src/Selbox.c b/src/Selbox.c
index 9119f58..272d407 100644
--- a/src/Selbox.c
+++ b/src/Selbox.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -117,18 +117,18 @@ int gengrid(int gridID1, int lat1, int lat2, int lon11, int lon12, int lon21, in
     {
       if ( lxvals && lyvals )
 	{
-	  xvals1 = (double *) malloc(nlon1*nlat1*sizeof(double));
-	  yvals1 = (double *) malloc(nlon1*nlat1*sizeof(double));
-	  xvals2 = (double *) malloc(nlon2*nlat2*sizeof(double));
-	  yvals2 = (double *) malloc(nlon2*nlat2*sizeof(double));
+	  xvals1 = malloc(nlon1*nlat1*sizeof(double));
+	  yvals1 = malloc(nlon1*nlat1*sizeof(double));
+	  xvals2 = malloc(nlon2*nlat2*sizeof(double));
+	  yvals2 = malloc(nlon2*nlat2*sizeof(double));
 	}
     }
   else
     {
-      if ( lxvals ) xvals1 = (double *) malloc(nlon1*sizeof(double));
-      if ( lyvals ) yvals1 = (double *) malloc(nlat1*sizeof(double));
-      if ( lxvals ) xvals2 = (double *) malloc(nlon2*sizeof(double));
-      if ( lyvals ) yvals2 = (double *) malloc(nlat2*sizeof(double));
+      if ( lxvals ) xvals1 = malloc(nlon1*sizeof(double));
+      if ( lyvals ) yvals1 = malloc(nlat1*sizeof(double));
+      if ( lxvals ) xvals2 = malloc(nlon2*sizeof(double));
+      if ( lyvals ) yvals2 = malloc(nlat2*sizeof(double));
     }
 
   pxvals2 = xvals2;
@@ -181,17 +181,17 @@ int gengrid(int gridID1, int lat1, int lat2, int lon11, int lon12, int lon21, in
     {
       if ( gridtype == GRID_CURVILINEAR )
 	{
-	  xbounds1 = (double *) malloc(4*nlon1*nlat1*sizeof(double));
-	  ybounds1 = (double *) malloc(4*nlon1*nlat1*sizeof(double));
-	  xbounds2 = (double *) malloc(4*nlon2*nlat2*sizeof(double));
-	  ybounds2 = (double *) malloc(4*nlon2*nlat2*sizeof(double));
+	  xbounds1 = malloc(4*nlon1*nlat1*sizeof(double));
+	  ybounds1 = malloc(4*nlon1*nlat1*sizeof(double));
+	  xbounds2 = malloc(4*nlon2*nlat2*sizeof(double));
+	  ybounds2 = malloc(4*nlon2*nlat2*sizeof(double));
 	}
       else
 	{
-	  xbounds1 = (double *) malloc(2*nlon1*sizeof(double));
-	  ybounds1 = (double *) malloc(2*nlat1*sizeof(double));
-	  xbounds2 = (double *) malloc(2*nlon2*sizeof(double));
-	  ybounds2 = (double *) malloc(2*nlat2*sizeof(double));
+	  xbounds1 = malloc(2*nlon1*sizeof(double));
+	  ybounds1 = malloc(2*nlat1*sizeof(double));
+	  xbounds2 = malloc(2*nlon2*sizeof(double));
+	  ybounds2 = malloc(2*nlat2*sizeof(double));
 	}
 
       pxbounds2 = xbounds2;
@@ -284,10 +284,10 @@ int gengridcell(int gridID1, int gridsize2, int *cellidx)
 
   if ( gridInqXvals(gridID1, NULL) && gridInqYvals(gridID1, NULL) )
     {
-      xvals1 = (double *) malloc(gridsize1*sizeof(double));
-      yvals1 = (double *) malloc(gridsize1*sizeof(double));
-      xvals2 = (double *) malloc(gridsize2*sizeof(double));
-      yvals2 = (double *) malloc(gridsize2*sizeof(double));
+      xvals1 = malloc(gridsize1*sizeof(double));
+      yvals1 = malloc(gridsize1*sizeof(double));
+      xvals2 = malloc(gridsize2*sizeof(double));
+      yvals2 = malloc(gridsize2*sizeof(double));
 
       gridInqXvals(gridID1, xvals1);
       gridInqYvals(gridID1, yvals1);
@@ -314,10 +314,10 @@ int gengridcell(int gridID1, int gridsize2, int *cellidx)
     {
       nv = gridInqNvertex(gridID1);
 
-      xbounds1 = (double *) malloc(nv*gridsize1*sizeof(double));
-      ybounds1 = (double *) malloc(nv*gridsize1*sizeof(double));
-      xbounds2 = (double *) malloc(nv*gridsize2*sizeof(double));
-      ybounds2 = (double *) malloc(nv*gridsize2*sizeof(double));
+      xbounds1 = malloc(nv*gridsize1*sizeof(double));
+      ybounds1 = malloc(nv*gridsize1*sizeof(double));
+      xbounds2 = malloc(nv*gridsize2*sizeof(double));
+      ybounds2 = malloc(nv*gridsize2*sizeof(double));
 
       gridInqXbounds(gridID1, xbounds1);
       gridInqYbounds(gridID1, ybounds1);
@@ -444,13 +444,13 @@ void genlonlatbox(int argc_offset, int gridID1, int *lat1, int *lat2, int *lon11
 
   if ( gridtype == GRID_CURVILINEAR )
     {
-      xvals1 = (double *) malloc(nlon1*nlat1*sizeof(double));
-      yvals1 = (double *) malloc(nlon1*nlat1*sizeof(double));
+      xvals1 = malloc(nlon1*nlat1*sizeof(double));
+      yvals1 = malloc(nlon1*nlat1*sizeof(double));
     }
   else
     {
-      xvals1 = (double *) malloc(nlon1*sizeof(double));
-      yvals1 = (double *) malloc(nlat1*sizeof(double));
+      xvals1 = malloc(nlon1*sizeof(double));
+      yvals1 = malloc(nlat1*sizeof(double));
     }
 
   gridInqXvals(gridID1, xvals1);
@@ -611,8 +611,8 @@ int gencellgrid(int gridID1, int *gridsize2, int **cellidx)
 
   if ( gridtype != GRID_UNSTRUCTURED ) cdoAbort("Internal problem, wrong grid type!");
 
-  xvals1 = (double *) malloc(gridsize1*sizeof(double));
-  yvals1 = (double *) malloc(gridsize1*sizeof(double));
+  xvals1 = malloc(gridsize1*sizeof(double));
+  yvals1 = malloc(gridsize1*sizeof(double));
 
   gridInqXvals(gridID1, xvals1);
   gridInqYvals(gridID1, yvals1);
@@ -645,7 +645,7 @@ int gencellgrid(int gridID1, int *gridsize2, int **cellidx)
 	    if ( nvals > maxcell )
 	      {
 		maxcell += cellinc;
-		*cellidx = (int *) realloc(*cellidx, maxcell*sizeof(int));
+		*cellidx = realloc(*cellidx, maxcell*sizeof(int));
 	      }
 	    (*cellidx)[nvals-1] = i;
 	  }
@@ -859,11 +859,11 @@ void *Selbox(void *argument)
   vlistDefTaxis(vlistID2, taxisID2);
 
   nvars = vlistNvars(vlistID1);
-  vars  = (int *) malloc(nvars*sizeof(int));
+  vars  = malloc(nvars*sizeof(int));
   for ( varID = 0; varID < nvars; varID++ ) vars[varID] = FALSE;
 
   ngrids = vlistNgrids(vlistID1);
-  sbox = (sbox_t *) malloc(ngrids*sizeof(sbox_t));
+  sbox = malloc(ngrids*sizeof(sbox_t));
 
   for ( index = 0; index < ngrids; index++ )
     {
@@ -925,11 +925,11 @@ void *Selbox(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-  array1 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
 
   gridsize2 = vlistGridsizeMax(vlistID2);
   if ( vlistNumber(vlistID2) != CDI_REAL ) gridsize2 *= 2;
-  array2 = (double *) malloc(gridsize2*sizeof(double));
+  array2 = malloc(gridsize2*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Select.c b/src/Select.c
index d0e6b85..7138843 100644
--- a/src/Select.c
+++ b/src/Select.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -130,7 +130,7 @@ pml_t *pmlNew(const char *name)
 {
   pml_t *pml;
 
-  pml = (pml_t *) malloc(sizeof(pml_t));
+  pml = malloc(sizeof(pml_t));
 
   pml_init(pml, name);
 
@@ -196,7 +196,7 @@ int pmlAdd(pml_t *pml, const char *name, int type, int dis, void *ptr, size_t si
       return (-1);
     }
 
-  pml_entry = (pml_entry_t *) malloc(sizeof(pml_entry_t));
+  pml_entry = malloc(sizeof(pml_entry_t));
 
   pml_entry->name = strdup(name);
   pml_entry->len  = strlen(name);
@@ -328,7 +328,7 @@ int pmlRead(pml_t *pml, int argc, char **argv)
       bufsize += len+1;
     }
 
-  parbuf = (char *) malloc(bufsize*sizeof(char));
+  parbuf = malloc(bufsize*sizeof(char));
   memset(parbuf, 0, bufsize*sizeof(char));
 
   istart = 0;
@@ -463,7 +463,7 @@ void *Select(void *argument)
   int operatorID;
   int streamID1, streamID2 = CDI_UNDEFID;
   int tsID1, tsID2, nrecs;
-  int nvars, nlevs;
+  int nvars, nvars2, nlevs;
   int zaxisID, levID;
   int varID2, levelID2;
   int recID, varID, levelID;
@@ -589,9 +589,11 @@ void *Select(void *argument)
 
       if ( indf == 0 )
 	{
+	  // vlistID0 = vlistDuplicate(vlistID1);
+
 	  vlistClearFlag(vlistID1);
 	  nvars = vlistNvars(vlistID1);
-	  vars  = (int *) malloc(nvars*sizeof(int));
+	  vars  = malloc(nvars*sizeof(int));
 
 	  if ( operatorID == DELETE )
 	    {
@@ -744,7 +746,7 @@ void *Select(void *argument)
 		}
 	    }
 
-	  // if ( cdoVerbose ) vlistPrint(vlistID1);
+	  //if ( cdoVerbose ) vlistPrint(vlistID1);
 
 	  vlistID0 = vlistDuplicate(vlistID1);
 	  for ( varID = 0; varID < nvars; varID++ )
@@ -755,16 +757,18 @@ void *Select(void *argument)
 		vlistDefFlag(vlistID0, varID, levID, vlistInqFlag(vlistID1, varID, levID));
 	    }
 
-	  // if ( cdoVerbose ) vlistPrint(vlistID0);
+	  //if ( cdoVerbose ) vlistPrint(vlistID0);
 
 	  vlistID2 = vlistCreate();
-	  vlistCopyFlag(vlistID2, vlistID1);
+	  vlistCopyFlag(vlistID2, vlistID0);
+
+	  //if ( cdoVerbose ) vlistPrint(vlistID2);
+
+	  nvars2 = vlistNvars(vlistID2);
 
-	  // if ( cdoVerbose ) vlistPrint(vlistID2);
-	  nvars = vlistNvars(vlistID2);
-	  for ( varID = 0; varID < nvars; ++varID )
+	  for ( varID = 0; varID < nvars2; ++varID )
 	    if ( vlistInqVarTsteptype(vlistID2, varID) != TSTEP_CONSTANT ) break;
-	  if ( varID == nvars ) vlistDefNtsteps(vlistID2, 0);
+	  if ( varID == nvars2 ) vlistDefNtsteps(vlistID2, 0);
 
 	  taxisID2 = taxisDuplicate(taxisID1);
 	  vlistDefTaxis(vlistID2, taxisID2);
@@ -773,15 +777,15 @@ void *Select(void *argument)
 
 	  if ( ntsteps == 1 )
 	    {
-	      for ( varID = 0; varID < nvars; ++varID )
+	      for ( varID = 0; varID < nvars2; ++varID )
 		if ( vlistInqVarTsteptype(vlistID1, varID) != TSTEP_CONSTANT ) break;
 	      
-	      if ( varID == nvars ) ntsteps = 0;
+	      if ( varID == nvars2 ) ntsteps = 0;
 	    }
 
 	  if ( ntsteps == 0 && nfiles > 1 )
 	    {	      
-	      for ( varID = 0; varID < nvars; ++varID )
+	      for ( varID = 0; varID < nvars2; ++varID )
 		vlistDefVarTsteptype(vlistID2, varID, TSTEP_INSTANT);
 	    }
 
@@ -789,7 +793,7 @@ void *Select(void *argument)
 	    {
 	      gridsize = vlistGridsizeMax(vlistID1);
 	      if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-	      array = (double *) malloc(gridsize*sizeof(double));
+	      array = malloc(gridsize*sizeof(double));
 	    }
 	}
       else
@@ -798,6 +802,12 @@ void *Select(void *argument)
 	}
 
 
+      if ( nvars2 == 0 )
+	{
+	  cdoWarning("No resulting variables available!");
+	  goto END_LABEL;
+	}
+
       tsID1 = 0;
       while ( (nrecs = streamInqTimestep(streamID1, tsID1)) )
 	{
@@ -884,6 +894,8 @@ void *Select(void *argument)
       streamClose(streamID1);
     }
 
+ END_LABEL:
+
   PAR_CHECK_INT_FLAG(timestep_of_year);
   PAR_CHECK_INT_FLAG(timestep);
   PAR_CHECK_INT_FLAG(year);
diff --git a/src/Seloperator.c b/src/Seloperator.c
index 5800303..e48ec04 100644
--- a/src/Seloperator.c
+++ b/src/Seloperator.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -107,7 +107,7 @@ void *Seloperator(void *argument)
   if ( ! lcopy )
     {
       gridsize = vlistGridsizeMax(vlistID1);
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   tsID = 0;
diff --git a/src/Selrec.c b/src/Selrec.c
index 1c3f3ec..025c9e8 100644
--- a/src/Selrec.c
+++ b/src/Selrec.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Seltime.c b/src/Seltime.c
index c761301..9d7c0da 100644
--- a/src/Seltime.c
+++ b/src/Seltime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -301,7 +301,7 @@ void *Seltime(void *argument)
 
   if ( nsel )
     {
-      selfound = (int *) malloc(nsel*sizeof(int));
+      selfound = malloc(nsel*sizeof(int));
       for ( i = 0; i < nsel; i++ ) selfound[i] = FALSE;
     }
 
@@ -330,7 +330,7 @@ void *Seltime(void *argument)
     {
       gridsize = vlistGridsizeMax(vlistID1);
       if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   nvars = vlistNvars(vlistID1);
@@ -344,15 +344,15 @@ void *Seltime(void *argument)
     {
       if ( lnts1 )
 	{
-	  vdate_list = (int *) malloc(nts1*sizeof(int));
-	  vtime_list = (int *) malloc(nts1*sizeof(int));
+	  vdate_list = malloc(nts1*sizeof(int));
+	  vtime_list = malloc(nts1*sizeof(int));
 	}
       else
 	{
 	  nts1 = 1;
 	}
 
-      vars  = (field_t ***) malloc(nts1*sizeof(field_t **));
+      vars  = malloc(nts1*sizeof(field_t **));
 
       for ( tsID = 0; tsID < nts1; tsID++ )
 	{
@@ -368,7 +368,7 @@ void *Seltime(void *argument)
 		  
 		  for ( levelID = 0; levelID < nlevel; levelID++ )
 		    {
-		      vars[tsID][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+		      vars[tsID][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 		    }
 		}
 	    }
diff --git a/src/Selvar.c b/src/Selvar.c
index ba2a4dd..ed5b90f 100644
--- a/src/Selvar.c
+++ b/src/Selvar.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -150,7 +150,7 @@ void *Selvar(void *argument)
 
   if ( nsel )
     {
-      selfound = (int *) malloc(nsel*sizeof(int));
+      selfound = malloc(nsel*sizeof(int));
       for ( i = 0; i < nsel; i++ ) selfound[i] = FALSE;
     }
 
@@ -407,7 +407,7 @@ void *Selvar(void *argument)
     {
       gridsize = vlistGridsizeMax(vlistID1);
       if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   tsID = 0;
diff --git a/src/Set.c b/src/Set.c
index 421be8e..2067698 100644
--- a/src/Set.c
+++ b/src/Set.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -147,7 +147,7 @@ void *Set(void *argument)
 	  zaxisID1 = vlistZaxis(vlistID2, index);
 	  zaxisID2 = zaxisDuplicate(zaxisID1);
 	  nlevs = zaxisInqSize(zaxisID2);
-	  levels = (double *) malloc(nlevs*sizeof(double));
+	  levels = malloc(nlevs*sizeof(double));
 	  zaxisInqLevels(zaxisID2, levels);
 	  levels[0] = newlevel;
 	  zaxisDefLevels(zaxisID2, levels);
@@ -178,7 +178,7 @@ void *Set(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID1 = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID1)) )
diff --git a/src/Setbox.c b/src/Setbox.c
index 9e4627b..327fc49 100644
--- a/src/Setbox.c
+++ b/src/Setbox.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -125,7 +125,7 @@ void *Setbox(void *argument)
   vlistDefTaxis(vlistID2, taxisID2);
 
   nvars = vlistNvars(vlistID1);
-  vars  = (int *) malloc(nvars*sizeof(int));
+  vars  = malloc(nvars*sizeof(int));
   for ( varID = 0; varID < nvars; varID++ )
     {
       if ( gridID == vlistInqVarGrid(vlistID1, varID) )
@@ -139,7 +139,7 @@ void *Setbox(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = gridInqSize(gridID);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Setgatt.c b/src/Setgatt.c
index fd5d5d3..ffc7d87 100644
--- a/src/Setgatt.c
+++ b/src/Setgatt.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -121,7 +121,7 @@ void *Setgatt(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Setgrid.c b/src/Setgrid.c
index 9801a35..6aae60e 100644
--- a/src/Setgrid.c
+++ b/src/Setgrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -113,7 +113,7 @@ void *Setgrid(void *argument)
 
       gridID = vlistInqVarGrid(vlistID, varID);
       areasize = gridInqSize(gridID);
-      areaweight = (double *) malloc(areasize*sizeof(double));
+      areaweight = malloc(areasize*sizeof(double));
   
       streamReadRecord(streamID, areaweight, &nmiss);
 
@@ -157,7 +157,7 @@ void *Setgrid(void *argument)
       missval  = vlistInqVarMissval(vlistID, varID);
       gridID   = vlistInqVarGrid(vlistID, varID);
       masksize = gridInqSize(gridID);
-      gridmask = (double *) malloc(masksize*sizeof(double));
+      gridmask = malloc(masksize*sizeof(double));
   
       streamReadRecord(streamID, gridmask, &nmiss);
 
@@ -275,7 +275,7 @@ void *Setgrid(void *argument)
 		  if ( ligme )
 		    {
 		      grid2_nvgp = gridInqSize(gridID2);
-		      grid2_vgpm = (int *) malloc(grid2_nvgp*sizeof(int));
+		      grid2_vgpm = malloc(grid2_nvgp*sizeof(int));
 		      gridInqMaskGME(gridID2, grid2_vgpm);
 		      gridCompress(gridID2);
 		    }
@@ -322,7 +322,7 @@ void *Setgrid(void *argument)
 	  if ( gridsize == masksize )
 	    {
 	      int *mask;
-	      mask = (int *) malloc(masksize*sizeof(int));
+	      mask = malloc(masksize*sizeof(int));
 	      for ( i = 0; i < masksize; i++ )
 		{
 		  if ( gridmask[i] < 0 || gridmask[i] > 255 )
@@ -358,7 +358,7 @@ void *Setgrid(void *argument)
     gridsize = vlistGridsizeMax(vlistID1);
 
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Sethalo.c b/src/Sethalo.c
index 33401fc..ac895c5 100644
--- a/src/Sethalo.c
+++ b/src/Sethalo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -75,10 +75,10 @@ int gentpngrid(int gridID1)
     {
       if ( gridtype == GRID_CURVILINEAR )
 	{
-	  xvals1 = (double *) malloc(nlon1*nlat1*sizeof(double));
-	  yvals1 = (double *) malloc(nlon1*nlat1*sizeof(double));
-	  xvals2 = (double *) malloc(nlon2*nlat2*sizeof(double));
-	  yvals2 = (double *) malloc(nlon2*nlat2*sizeof(double));
+	  xvals1 = malloc(nlon1*nlat1*sizeof(double));
+	  yvals1 = malloc(nlon1*nlat1*sizeof(double));
+	  xvals2 = malloc(nlon2*nlat2*sizeof(double));
+	  yvals2 = malloc(nlon2*nlat2*sizeof(double));
 
 	  gridInqXvals(gridID1, xvals1);
 	  gridInqYvals(gridID1, yvals1);
@@ -115,10 +115,10 @@ int gentpngrid(int gridID1)
     {
       if ( gridtype == GRID_CURVILINEAR )
 	{
-	  xbounds1 = (double *) malloc(4*nlon1*nlat1*sizeof(double));
-	  ybounds1 = (double *) malloc(4*nlon1*nlat1*sizeof(double));
-	  xbounds2 = (double *) malloc(4*nlon2*nlat2*sizeof(double));
-	  ybounds2 = (double *) malloc(4*nlon2*nlat2*sizeof(double));
+	  xbounds1 = malloc(4*nlon1*nlat1*sizeof(double));
+	  ybounds1 = malloc(4*nlon1*nlat1*sizeof(double));
+	  xbounds2 = malloc(4*nlon2*nlat2*sizeof(double));
+	  ybounds2 = malloc(4*nlon2*nlat2*sizeof(double));
 
 	  gridInqXbounds(gridID1, xbounds1);
 	  gridInqYbounds(gridID1, ybounds1);
@@ -238,17 +238,17 @@ int gengrid(int gridID1, int lhalo, int rhalo)
     {
       if ( gridtype == GRID_CURVILINEAR )
 	{
-	  xvals1 = (double *) malloc(nlon1*nlat1*sizeof(double));
-	  yvals1 = (double *) malloc(nlon1*nlat1*sizeof(double));
-	  xvals2 = (double *) malloc(nlon2*nlat2*sizeof(double));
-	  yvals2 = (double *) malloc(nlon2*nlat2*sizeof(double));
+	  xvals1 = malloc(nlon1*nlat1*sizeof(double));
+	  yvals1 = malloc(nlon1*nlat1*sizeof(double));
+	  xvals2 = malloc(nlon2*nlat2*sizeof(double));
+	  yvals2 = malloc(nlon2*nlat2*sizeof(double));
 	}
       else
 	{
-	  xvals1 = (double *) malloc(nlon1*sizeof(double));
-	  yvals1 = (double *) malloc(nlat1*sizeof(double));
-	  xvals2 = (double *) malloc(nlon2*sizeof(double));
-	  yvals2 = (double *) malloc(nlat2*sizeof(double));
+	  xvals1 = malloc(nlon1*sizeof(double));
+	  yvals1 = malloc(nlat1*sizeof(double));
+	  xvals2 = malloc(nlon2*sizeof(double));
+	  yvals2 = malloc(nlat2*sizeof(double));
 	}
 
       pxvals2 = xvals2;
@@ -305,17 +305,17 @@ int gengrid(int gridID1, int lhalo, int rhalo)
     {
       if ( gridtype == GRID_CURVILINEAR )
 	{
-	  xbounds1 = (double *) malloc(4*nlon1*nlat1*sizeof(double));
-	  ybounds1 = (double *) malloc(4*nlon1*nlat1*sizeof(double));
-	  xbounds2 = (double *) malloc(4*nlon2*nlat2*sizeof(double));
-	  ybounds2 = (double *) malloc(4*nlon2*nlat2*sizeof(double));
+	  xbounds1 = malloc(4*nlon1*nlat1*sizeof(double));
+	  ybounds1 = malloc(4*nlon1*nlat1*sizeof(double));
+	  xbounds2 = malloc(4*nlon2*nlat2*sizeof(double));
+	  ybounds2 = malloc(4*nlon2*nlat2*sizeof(double));
 	}
       else
 	{
-	  xbounds1 = (double *) malloc(2*nlon1*sizeof(double));
-	  ybounds1 = (double *) malloc(2*nlat1*sizeof(double));
-	  xbounds2 = (double *) malloc(2*nlon2*sizeof(double));
-	  ybounds2 = (double *) malloc(2*nlat2*sizeof(double));
+	  xbounds1 = malloc(2*nlon1*sizeof(double));
+	  ybounds1 = malloc(2*nlat1*sizeof(double));
+	  xbounds2 = malloc(2*nlon2*sizeof(double));
+	  ybounds2 = malloc(2*nlat2*sizeof(double));
 	}
 
       pxbounds2 = xbounds2;
@@ -547,7 +547,7 @@ void *Sethalo(void *argument)
     }
 
   nvars = vlistNvars(vlistID1);
-  vars  = (int *) malloc(nvars*sizeof(int));
+  vars  = malloc(nvars*sizeof(int));
   for ( varID = 0; varID < nvars; varID++ )
     {
       if ( gridID1 == vlistInqVarGrid(vlistID1, varID) )
@@ -561,10 +561,10 @@ void *Sethalo(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = gridInqSize(gridID1);
-  array1 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
 
   gridsize2 = gridInqSize(gridID2);
-  array2 = (double *) malloc(gridsize2*sizeof(double));
+  array2 = malloc(gridsize2*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Setmiss.c b/src/Setmiss.c
index 39738e9..e57083b 100644
--- a/src/Setmiss.c
+++ b/src/Setmiss.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -132,7 +132,7 @@ void *Setmiss(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Setpartab.c b/src/Setpartab.c
index e11e946..e093dc2 100644
--- a/src/Setpartab.c
+++ b/src/Setpartab.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -631,7 +631,7 @@ void *Setpartab(void *argument)
 	{
 	  fseek(fp, 0L, SEEK_END);
 	  fsize = (size_t) ftell(fp);
-	  parbuf = (char *) malloc(fsize+1);
+	  parbuf = malloc(fsize+1);
 	  fseek(fp, 0L, SEEK_SET);
 	  nbytes = fread(parbuf, fsize, 1, fp);
 	  parbuf[fsize] = 0;
@@ -661,7 +661,7 @@ void *Setpartab(void *argument)
   /* vlistPrint(vlistID2);*/
 
   nvars = vlistNvars(vlistID2);
-  vars = (var_t *) malloc(nvars*sizeof(var_t));
+  vars = malloc(nvars*sizeof(var_t));
   memset(vars, 0, nvars*sizeof(var_t));
 
   if ( tableformat == 0 )
@@ -721,7 +721,7 @@ void *Setpartab(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID1 = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID1)) )
diff --git a/src/Setrcaname.c b/src/Setrcaname.c
index 5a6bb72..f6f1efb 100644
--- a/src/Setrcaname.c
+++ b/src/Setrcaname.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -121,7 +121,7 @@ void *Setrcaname(void *argument)
   if ( ! lcopy )
     {
       gridsize = vlistGridsizeMax(vlistID1);
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   tsID = 0;
diff --git a/src/Settime.c b/src/Settime.c
index 3873d8a..425b804 100644
--- a/src/Settime.c
+++ b/src/Settime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -182,7 +182,8 @@ void *Settime(void *argument)
       if ( operatorArgc() == 3 )
 	{
 	  const char *timeunits = operatorArgv()[2];
-	  incperiod = (int)strtol(timeunits, NULL, 10);;
+	  incperiod = (int)strtol(timeunits, NULL, 10);
+	  if ( timeunits[0] == '-' || timeunits[0] == '+' ) timeunits++;
 	  while ( isdigit((int) *timeunits) ) timeunits++;
 
 	  get_tunits(timeunits, &incperiod, &incunit, &tunit);
@@ -224,7 +225,7 @@ void *Settime(void *argument)
   else if ( operatorID == SHIFTTIME )
     {
       const char *timeunits = operatorArgv()[0];
-      incperiod = (int)strtol(timeunits, NULL, 10);;
+      incperiod = (int)strtol(timeunits, NULL, 10);
       if ( timeunits[0] == '-' || timeunits[0] == '+' ) timeunits++;
       while ( isdigit((int) *timeunits) ) timeunits++;
 
@@ -373,7 +374,7 @@ void *Settime(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID1 = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID1)) )
diff --git a/src/Setzaxis.c b/src/Setzaxis.c
index 723d5bd..8e4b221 100644
--- a/src/Setzaxis.c
+++ b/src/Setzaxis.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -88,7 +88,7 @@ void *Setzaxis(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Showinfo.c b/src/Showinfo.c
index 0f0710a..7a155ea 100644
--- a/src/Showinfo.c
+++ b/src/Showinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Sinfo.c b/src/Sinfo.c
index 55bf7e3..d52e546 100644
--- a/src/Sinfo.c
+++ b/src/Sinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Smooth9.c b/src/Smooth9.c
index c9050a7..397bd5d 100644
--- a/src/Smooth9.c
+++ b/src/Smooth9.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -67,7 +67,7 @@ void *Smooth9(void *argument)
   vlistDefTaxis(vlistID2, taxisID2);
 
   nvars = vlistNvars(vlistID1);
-  varIDs  = (int *) malloc(nvars*sizeof(int)); 
+  varIDs  = malloc(nvars*sizeof(int)); 
 
   for ( varID = 0; varID < nvars; ++varID )
     {
@@ -87,9 +87,9 @@ void *Smooth9(void *argument)
     }
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize *sizeof(double));
-  mask   = (  int  *) malloc(gridsize *sizeof(int));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize *sizeof(double));
+  mask   = malloc(gridsize *sizeof(int));
  
   streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
 
diff --git a/src/Sort.c b/src/Sort.c
index 73688e4..e6922c7 100644
--- a/src/Sort.c
+++ b/src/Sort.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -49,8 +49,8 @@ static
 int cmpvarcode(const void *s1, const void *s2)
 {
   int cmp = 0;
-  varinfo_t *x = (varinfo_t *) s1;
-  varinfo_t *y = (varinfo_t *) s2;
+  const varinfo_t *x = s1;
+  const varinfo_t *y = s2;
   /*
   printf("%d %d  %d %d\n", x->code, y->code, x, y);
   */
@@ -63,8 +63,8 @@ int cmpvarcode(const void *s1, const void *s2)
 static
 int cmpvarname(const void *s1, const void *s2)
 {
-  varinfo_t *x = (varinfo_t *) s1;
-  varinfo_t *y = (varinfo_t *) s2;
+  const varinfo_t *x = s1;
+  const varinfo_t *y = s2;
 
   return (strcmp(x->name, y->name));
 }
@@ -73,8 +73,8 @@ static
 int cmpvarlevel(const void *s1, const void *s2)
 {
   int cmp = 0;
-  levinfo_t *x = (levinfo_t *) s1;
-  levinfo_t *y = (levinfo_t *) s2;
+  const levinfo_t *x = s1;
+  const levinfo_t *y = s2;
 
   if      ( x->level < y->level ) cmp = -1;
   else if ( x->level > y->level ) cmp =  1;
@@ -86,8 +86,8 @@ static
 int cmpvarlevelrev(const void *s1, const void *s2)
 {
   int cmp = 0;
-  levinfo_t *x = (levinfo_t *) s1;
-  levinfo_t *y = (levinfo_t *) s2;
+  const levinfo_t *x = s1;
+  const levinfo_t *y = s2;
 
   if      ( x->level > y->level ) cmp = -1;
   else if ( x->level < y->level ) cmp =  1;
@@ -164,21 +164,21 @@ void *Sort(void *argument)
 
   nvars   = vlistNvars(vlistID1);
 
-  varInfo = (varinfo_t *) malloc(nvars*sizeof(varinfo_t));
+  varInfo = malloc(nvars*sizeof(varinfo_t));
   for ( varID = 0; varID < nvars; ++varID )
     {
       nlevs = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
       varInfo[varID].nlevs = nlevs;
-      varInfo[varID].levInfo = (levinfo_t *) malloc(nlevs*sizeof(levinfo_t));
+      varInfo[varID].levInfo = malloc(nlevs*sizeof(levinfo_t));
     }
 
-  vardata = (double **) malloc(nvars*sizeof(double*));
+  vardata = malloc(nvars*sizeof(double*));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
       gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
       nlevs    = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      vardata[varID] = (double *) malloc(gridsize*nlevs*sizeof(double));
+      vardata[varID] = malloc(gridsize*nlevs*sizeof(double));
     }
 
   tsID = 0;
diff --git a/src/Sorttimestamp.c b/src/Sorttimestamp.c
index 28cc07f..f83af93 100644
--- a/src/Sorttimestamp.c
+++ b/src/Sorttimestamp.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -41,8 +41,8 @@ static
 int cmpdatetime(const void *s1, const void *s2)
 {
   int cmp = 0;
-  timeinfo_t *x = (timeinfo_t *) s1;
-  timeinfo_t *y = (timeinfo_t *) s2;
+  const timeinfo_t *x = s1;
+  const timeinfo_t *y = s2;
   /*
   printf("%g %g  %d %d\n", x->datetime, y->datetime, x, y);
   */
@@ -105,9 +105,9 @@ void *Sorttimestamp(void *argument)
 	  if ( xtsID >= nalloc )
 	    {
 	      nalloc += NALLOC_INC;
-	      vdate = (int *) realloc(vdate, nalloc*sizeof(int));
-	      vtime = (int *) realloc(vtime, nalloc*sizeof(int));
-	      vars  = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
+	      vdate = realloc(vdate, nalloc*sizeof(int));
+	      vtime = realloc(vtime, nalloc*sizeof(int));
+	      vars  = realloc(vars, nalloc*sizeof(field_t **));
 	    }
 
 	  vdate[xtsID] = taxisInqVdate(taxisID1);
@@ -120,7 +120,7 @@ void *Sorttimestamp(void *argument)
 	      streamInqRecord(streamID1, &varID, &levelID);
 	      gridID   = vlistInqVarGrid(vlistID1, varID);
 	      gridsize = gridInqSize(gridID);
-	      vars[xtsID][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+	      vars[xtsID][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 	      streamReadRecord(streamID1, vars[xtsID][varID][levelID].ptr, &nmiss);
 	      vars[xtsID][varID][levelID].nmiss = nmiss;
 	    }
@@ -134,7 +134,7 @@ void *Sorttimestamp(void *argument)
 
   nts = xtsID;
 
-  timeinfo= (timeinfo_t *) malloc(nts*sizeof(timeinfo_t));
+  timeinfo= malloc(nts*sizeof(timeinfo_t));
 
   for ( tsID = 0; tsID < nts; tsID++ )
     {
diff --git a/src/Specinfo.c b/src/Specinfo.c
index 94bac6c..e03d1c3 100644
--- a/src/Specinfo.c
+++ b/src/Specinfo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/Spectral.c b/src/Spectral.c
index cca8732..9d53913 100644
--- a/src/Spectral.c
+++ b/src/Spectral.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -210,7 +210,7 @@ void *Spectral(void *argument)
 	  maxntr = 1+gridInqTrunc(gridID1);
 	  ncut = args2intlist(operatorArgc(), operatorArgv(), ilist);
 	  wnums = (int *) listArrayPtr(ilist);
-	  waves = (int *) malloc(maxntr*sizeof(int));
+	  waves = malloc(maxntr*sizeof(int));
 	  for ( i = 0; i < maxntr; i++ ) waves[i] = 1;
 	  for ( i = 0; i < ncut; i++ )
 	    {
@@ -227,7 +227,7 @@ void *Spectral(void *argument)
     }
 
   nvars = vlistNvars(vlistID2);
-  vars  = (int *) malloc(nvars*sizeof(int));
+  vars  = malloc(nvars*sizeof(int));
   for ( varID = 0; varID < nvars; varID++ )
     {
       if ( gridID1 == vlistInqVarGrid(vlistID1, varID) )
@@ -243,12 +243,12 @@ void *Spectral(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array1 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
 
   if ( gridID2 != -1 )
     {
       gridsize = gridInqSize(gridID2);
-      array2 = (double *) malloc(gridsize*sizeof(double));
+      array2 = malloc(gridsize*sizeof(double));
     }
 
   tsID = 0;
diff --git a/src/Spectrum.c b/src/Spectrum.c
index 1907bd9..a97caf1 100644
--- a/src/Spectrum.c
+++ b/src/Spectrum.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -194,9 +194,9 @@ void *Spectrum(void *argument)
       if ( tsID >= nalloc )
 	{
 	  nalloc += NALLOC_INC;
-	  vdate = (int *) realloc(vdate, nalloc*sizeof(int));
-	  vtime = (int *) realloc(vtime, nalloc*sizeof(int));
-	  vars  = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
+	  vdate = realloc(vdate, nalloc*sizeof(int));
+	  vtime = realloc(vtime, nalloc*sizeof(int));
+	  vars  = realloc(vars, nalloc*sizeof(field_t **));
 	}
 
       vdate[tsID] = taxisInqVdate(taxisID1);
@@ -209,7 +209,7 @@ void *Spectrum(void *argument)
 	  streamInqRecord(streamID1, &varID, &levelID);
 	  gridID   = vlistInqVarGrid(vlistID1, varID);
 	  gridsize = gridInqSize(gridID);
-	  vars[tsID][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+	  vars[tsID][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 	  streamReadRecord(streamID1, vars[tsID][varID][levelID].ptr, &nmiss);
 	  vars[tsID][varID][levelID].nmiss = nmiss;
 
@@ -251,15 +251,15 @@ void *Spectrum(void *argument)
 
   nfreq = seg_l/2 + 1;
 
-  vars2 = (field_t ***) malloc(nfreq*sizeof(field_t **));
+  vars2 = malloc(nfreq*sizeof(field_t **));
   for ( freq = 0; freq < nfreq; freq++ )
     vars2[freq] = field_malloc(vlistID1, FIELD_PTR);
 
-  array1  = (double *) malloc(nts   * sizeof(double));
-  array2  = (double *) malloc(nfreq * sizeof(double));
-  real    = (double *) malloc(seg_l * sizeof(double));
-  imag    = (double *) malloc(seg_l * sizeof(double));
-  window  = (double *) malloc(seg_l * sizeof(double));
+  array1  = malloc(nts   * sizeof(double));
+  array2  = malloc(nfreq * sizeof(double));
+  real    = malloc(seg_l * sizeof(double));
+  imag    = malloc(seg_l * sizeof(double));
+  window  = malloc(seg_l * sizeof(double));
   	   
   switch (which_window)
     {
diff --git a/src/Split.c b/src/Split.c
index dfb5fbd..882c4d0 100644
--- a/src/Split.c
+++ b/src/Split.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -123,9 +123,9 @@ void *Split(void *argument)
 	    }
 	}
 
-      codes     = (int *) malloc(nsplit*sizeof(int));
-      vlistIDs  = (int *) malloc(nsplit*sizeof(int));
-      streamIDs = (int *) malloc(nsplit*sizeof(int));
+      codes     = malloc(nsplit*sizeof(int));
+      vlistIDs  = malloc(nsplit*sizeof(int));
+      streamIDs = malloc(nsplit*sizeof(int));
       memcpy(codes, itmp, nsplit*sizeof(int));
 
       for ( index = 0; index < nsplit; index++ )
@@ -192,9 +192,9 @@ void *Split(void *argument)
 	    }
 	}
 
-      params    = (int *) malloc(nsplit*sizeof(int));
-      vlistIDs  = (int *) malloc(nsplit*sizeof(int));
-      streamIDs = (int *) malloc(nsplit*sizeof(int));
+      params    = malloc(nsplit*sizeof(int));
+      vlistIDs  = malloc(nsplit*sizeof(int));
+      streamIDs = malloc(nsplit*sizeof(int));
       memcpy(params, itmp, nsplit*sizeof(int));
 
       for ( index = 0; index < nsplit; index++ )
@@ -250,9 +250,9 @@ void *Split(void *argument)
 	    }
 	}
 
-      tabnums   = (int *) malloc(nsplit*sizeof(int));
-      vlistIDs  = (int *) malloc(nsplit*sizeof(int));
-      streamIDs = (int *) malloc(nsplit*sizeof(int));
+      tabnums   = malloc(nsplit*sizeof(int));
+      vlistIDs  = malloc(nsplit*sizeof(int));
+      streamIDs = malloc(nsplit*sizeof(int));
       memcpy(tabnums, itmp, nsplit*sizeof(int));
 
       for ( index = 0; index < nsplit; index++ )
@@ -292,8 +292,8 @@ void *Split(void *argument)
       char varname[CDI_MAX_NAME];
       nsplit = nvars;
 
-      vlistIDs  = (int *) malloc(nsplit*sizeof(int));
-      streamIDs = (int *) malloc(nsplit*sizeof(int));
+      vlistIDs  = malloc(nsplit*sizeof(int));
+      streamIDs = malloc(nsplit*sizeof(int));
 
       for ( index = 0; index < nsplit; index++ )
 	{
@@ -342,9 +342,9 @@ void *Split(void *argument)
 	    }
 	}
 
-      levels    = (double *) malloc(nsplit*sizeof(double));
-      vlistIDs  = (int *) malloc(nsplit*sizeof(int));
-      streamIDs = (int *) malloc(nsplit*sizeof(int));
+      levels    = malloc(nsplit*sizeof(double));
+      vlistIDs  = malloc(nsplit*sizeof(int));
+      streamIDs = malloc(nsplit*sizeof(int));
       memcpy(levels, ftmp, nsplit*sizeof(double));
 
       for ( index = 0; index < nsplit; index++ )
@@ -385,9 +385,9 @@ void *Split(void *argument)
 
       nsplit = vlistNgrids(vlistID1);
 
-      gridIDs   = (int *) malloc(nsplit*sizeof(int));
-      vlistIDs  = (int *) malloc(nsplit*sizeof(int));
-      streamIDs = (int *) malloc(nsplit*sizeof(int));
+      gridIDs   = malloc(nsplit*sizeof(int));
+      vlistIDs  = malloc(nsplit*sizeof(int));
+      streamIDs = malloc(nsplit*sizeof(int));
 
       for ( index = 0; index < nsplit; index++ )
 	gridIDs[index] = vlistGrid(vlistID1, index);
@@ -430,9 +430,9 @@ void *Split(void *argument)
 
       nsplit = vlistNzaxis(vlistID1);
 
-      zaxisIDs  = (int *) malloc(nsplit*sizeof(int));
-      vlistIDs  = (int *) malloc(nsplit*sizeof(int));
-      streamIDs = (int *) malloc(nsplit*sizeof(int));
+      zaxisIDs  = malloc(nsplit*sizeof(int));
+      vlistIDs  = malloc(nsplit*sizeof(int));
+      streamIDs = malloc(nsplit*sizeof(int));
 
       for ( index = 0; index < nsplit; index++ )
 	zaxisIDs[index] = vlistZaxis(vlistID1, index);
@@ -477,7 +477,7 @@ void *Split(void *argument)
     {
       gridsize = vlistGridsizeMax(vlistID1);
       if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   tsID = 0;
diff --git a/src/Splitrec.c b/src/Splitrec.c
index ca4e169..3536211 100644
--- a/src/Splitrec.c
+++ b/src/Splitrec.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -66,7 +66,7 @@ void *Splitrec(void *argument)
     {
       gridsize = vlistGridsizeMax(vlistID1);
       if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   index = 0;
diff --git a/src/Splitsel.c b/src/Splitsel.c
index 537a28d..6712e4f 100644
--- a/src/Splitsel.c
+++ b/src/Splitsel.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -101,7 +101,7 @@ void *Splitsel(void *argument)
     {
       gridsize = vlistGridsizeMax(vlistID1);
       if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   nvars = vlistNvars(vlistID1);
@@ -111,7 +111,7 @@ void *Splitsel(void *argument)
 
   if ( nconst )
     {
-      vars = (field_t **) malloc(nvars*sizeof(field_t *));
+      vars = malloc(nvars*sizeof(field_t *));
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
@@ -121,13 +121,13 @@ void *Splitsel(void *argument)
 	      nlevel  = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	      gridsize = gridInqSize(gridID);
 		  
-	      vars[varID] = (field_t *) malloc(nlevel*sizeof(field_t));
+	      vars[varID] = malloc(nlevel*sizeof(field_t));
 
 	      for ( levelID = 0; levelID < nlevel; levelID++ )
 		{
 		  field_init(&vars[varID][levelID]);
 		  vars[varID][levelID].grid    = gridID;
-		  vars[varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+		  vars[varID][levelID].ptr     = malloc(gridsize*sizeof(double));
 		}
 	    }
 	}
diff --git a/src/Splittime.c b/src/Splittime.c
index a8539fc..53f5373 100644
--- a/src/Splittime.c
+++ b/src/Splittime.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -128,7 +128,7 @@ void *Splittime(void *argument)
     {
       gridsize = vlistGridsizeMax(vlistID1);
       if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   nvars = vlistNvars(vlistID1);
@@ -138,7 +138,7 @@ void *Splittime(void *argument)
 
   if ( nconst )
     {
-      vars = (field_t **) malloc(nvars*sizeof(field_t *));
+      vars = malloc(nvars*sizeof(field_t *));
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
@@ -148,13 +148,13 @@ void *Splittime(void *argument)
 	      nlevel  = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 	      gridsize = gridInqSize(gridID);
 		  
-	      vars[varID] = (field_t *) malloc(nlevel*sizeof(field_t));
+	      vars[varID] = malloc(nlevel*sizeof(field_t));
 
 	      for ( levelID = 0; levelID < nlevel; levelID++ )
 		{
 		  field_init(&vars[varID][levelID]);
 		  vars[varID][levelID].grid    = gridID;
-		  vars[varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+		  vars[varID][levelID].ptr     = malloc(gridsize*sizeof(double));
 		}
 	    }
 	}
diff --git a/src/Splityear.c b/src/Splityear.c
index ba190e6..6fcfb70 100644
--- a/src/Splityear.c
+++ b/src/Splityear.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -74,7 +74,7 @@ void *Splityear(void *argument)
     {
       gridsize = vlistGridsizeMax(vlistID1);
       if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   taxisID1 = vlistInqTaxis(vlistID1);
diff --git a/src/StringUtilities.c b/src/StringUtilities.c
index 3afd07b..125aa2e 100644
--- a/src/StringUtilities.c
+++ b/src/StringUtilities.c
@@ -25,7 +25,7 @@ int StringSplitWithSeperator(  char *source_string, char *seperator, char*** ptr
 		   sep_count++;
 	  }	
  
-	temp_list  = ( char** )malloc ( sizeof( char* ) * (sep_count+1) );
+	temp_list  = malloc ( sizeof( char* ) * (sep_count+1) );
 	
 	if( DBG )
 	  fprintf(stderr, "Input str %s , seperator %s  sep count %d\n", duplicate_src, seperator, sep_count );
diff --git a/src/Subtrend.c b/src/Subtrend.c
index 4871141..7122874 100644
--- a/src/Subtrend.c
+++ b/src/Subtrend.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -68,8 +68,8 @@ void *Subtrend(void *argument)
 
   field_init(&field1);
   field_init(&field4);
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field4.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field4.ptr = malloc(gridsize*sizeof(double));
 
   vars2 = field_malloc(vlistID1, FIELD_PTR);
   vars3 = field_malloc(vlistID1, FIELD_PTR);
diff --git a/src/Tee.c b/src/Tee.c
index 2b25fbe..981fd98 100644
--- a/src/Tee.c
+++ b/src/Tee.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -58,7 +58,7 @@ void *Tee(void *argument)
   streamDefVlist(streamID3, vlistID3);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Templates.c b/src/Templates.c
index ab45331..a4251a1 100644
--- a/src/Templates.c
+++ b/src/Templates.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -52,7 +52,7 @@ void *Template1(void *argument)
   if ( ! lcopy )
     {
       gridsize = vlistGridsizeMax(vlistID1);
-      array = (double *) malloc(gridsize*sizeof(double));
+      array = malloc(gridsize*sizeof(double));
     }
 
   tsID = 0;
@@ -122,7 +122,7 @@ void *Template2(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Test.c b/src/Test.c
index c13836b..9189699 100644
--- a/src/Test.c
+++ b/src/Test.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -99,11 +99,11 @@ void *Testdata(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array = (double *) malloc(gridsize*sizeof(double));
-  fval = (float *) malloc(gridsize*sizeof(float));
-  ival = (int *) malloc(gridsize*sizeof(int));
-  cval = (unsigned char *) malloc(gridsize*sizeof(unsigned char)*4);
-  cval2 = (unsigned char *) malloc(gridsize*sizeof(unsigned char)*4);
+  array = malloc(gridsize*sizeof(double));
+  fval = malloc(gridsize*sizeof(float));
+  ival = malloc(gridsize*sizeof(int));
+  cval = malloc(gridsize*sizeof(unsigned char)*4);
+  cval2 = malloc(gridsize*sizeof(unsigned char)*4);
 
   fp = fopen("testdata", "w");
 
diff --git a/src/Tests.c b/src/Tests.c
index 5ca4878..7f85ff7 100644
--- a/src/Tests.c
+++ b/src/Tests.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -98,8 +98,8 @@ void *Tests(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Timcount.c b/src/Timcount.c
index c31ec47..cf4b76b 100644
--- a/src/Timcount.c
+++ b/src/Timcount.c
@@ -86,14 +86,14 @@ void *Timcount(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   nrecords = vlistNrecs(vlistID1);
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
 
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   vars1 = field_malloc(vlistID1, FIELD_PTR);
 
diff --git a/src/Timpctl.c b/src/Timpctl.c
index c912f94..5f81a7d 100644
--- a/src/Timpctl.c
+++ b/src/Timpctl.c
@@ -95,13 +95,13 @@ void timpctl(int operatorID)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords * sizeof(int));
-  recLevelID = (int *) malloc(nrecords * sizeof(int));
+  recVarID   = malloc(nrecords * sizeof(int));
+  recLevelID = malloc(nrecords * sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize * sizeof(double));
+  field.ptr = malloc(gridsize * sizeof(double));
 
   vars1 = field_malloc(vlistID1, FIELD_PTR);
   hset = hsetCreate(nvars);
diff --git a/src/Timselpctl.c b/src/Timselpctl.c
index 34c0d90..7ba367b 100644
--- a/src/Timselpctl.c
+++ b/src/Timselpctl.c
@@ -100,13 +100,13 @@ void *Timselpctl(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize * sizeof(double));
+  field.ptr = malloc(gridsize * sizeof(double));
 
   vars1 = field_malloc(vlistID1, FIELD_PTR);
   hset = hsetCreate(nvars);
diff --git a/src/Timselstat.c b/src/Timselstat.c
index a875f14..7177730 100644
--- a/src/Timselstat.c
+++ b/src/Timselstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -110,13 +110,13 @@ void *Timselstat(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   vars1 = field_malloc(vlistID1, FIELD_PTR);
   samp1 = field_malloc(vlistID1, FIELD_NONE);
@@ -190,7 +190,7 @@ void *Timselstat(void *argument)
 		  if ( nmiss > 0 || samp1[varID][levelID].ptr )
 		    {
 		      if ( samp1[varID][levelID].ptr == NULL )
-			samp1[varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+			samp1[varID][levelID].ptr = malloc(gridsize*sizeof(double));
 
 		      for ( i = 0; i < gridsize; i++ )
 			if ( DBL_IS_EQUAL(vars1[varID][levelID].ptr[i],
@@ -210,7 +210,7 @@ void *Timselstat(void *argument)
 		    {
 		      if ( samp1[varID][levelID].ptr == NULL )
 			{
-			  samp1[varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+			  samp1[varID][levelID].ptr = malloc(gridsize*sizeof(double));
 			  for ( i = 0; i < gridsize; i++ )
 			    samp1[varID][levelID].ptr[i] = nsets;
 			}
diff --git a/src/Timsort.c b/src/Timsort.c
index 8dcf70d..b8668e1 100644
--- a/src/Timsort.c
+++ b/src/Timsort.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -38,11 +38,9 @@ static
 int cmpdarray(const void *s1, const void *s2)
 {
   int cmp = 0;
-  double *x = (double *) s1;
-  double *y = (double *) s2;
-  /*
-  printf("%d %d  %d %d\n", x->code, y->code, x, y);
-  */
+  const double *x = s1;
+  const double *y = s2;
+
   if      ( *x < *y ) cmp = -1;
   else if ( *x > *y ) cmp =  1;
 
@@ -91,9 +89,9 @@ void *Timsort(void *argument)
       if ( tsID >= nalloc )
 	{
 	  nalloc += NALLOC_INC;
-	  vdate = (int *) realloc(vdate, nalloc*sizeof(int));
-	  vtime = (int *) realloc(vtime, nalloc*sizeof(int));
-	  vars  = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
+	  vdate = realloc(vdate, nalloc*sizeof(int));
+	  vtime = realloc(vtime, nalloc*sizeof(int));
+	  vars  = realloc(vars, nalloc*sizeof(field_t **));
 	}
 
       vdate[tsID] = taxisInqVdate(taxisID1);
@@ -106,7 +104,7 @@ void *Timsort(void *argument)
 	  streamInqRecord(streamID1, &varID, &levelID);
 	  gridID   = vlistInqVarGrid(vlistID1, varID);
 	  gridsize = gridInqSize(gridID);
-	  vars[tsID][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+	  vars[tsID][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 	  streamReadRecord(streamID1, vars[tsID][varID][levelID].ptr, &nmiss);
 	  vars[tsID][varID][levelID].nmiss = nmiss;
 	}
@@ -116,9 +114,9 @@ void *Timsort(void *argument)
 
   nts = tsID;
 
-  sarray = (double **) malloc(ompNumThreads*sizeof(double *));
+  sarray = malloc(ompNumThreads*sizeof(double *));
   for ( i = 0; i < ompNumThreads; i++ )
-    sarray[i] = (double *) malloc(nts*sizeof(double));
+    sarray[i] = malloc(nts*sizeof(double));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
diff --git a/src/Timstat.c b/src/Timstat.c
index a6700ae..528b038 100644
--- a/src/Timstat.c
+++ b/src/Timstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -225,14 +225,14 @@ void *Timstat(void *argument)
       streamDefVlist(streamID3, vlistID3);
     }
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   if ( vlistNumber(vlistID1) != CDI_REAL ) gridsize *= 2;
 
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   vars1 = field_malloc(vlistID1, FIELD_PTR);
   samp1 = field_malloc(vlistID1, FIELD_NONE);
@@ -292,7 +292,7 @@ void *Timstat(void *argument)
 		  if ( nmiss > 0 || samp1[varID][levelID].ptr )
 		    {
 		      if ( samp1[varID][levelID].ptr == NULL )
-			samp1[varID][levelID].ptr = (double *) malloc(nwpv*gridsize*sizeof(double));
+			samp1[varID][levelID].ptr = malloc(nwpv*gridsize*sizeof(double));
 
 		      for ( i = 0; i < nwpv*gridsize; i++ )
 			if ( DBL_IS_EQUAL(vars1[varID][levelID].ptr[i], vars1[varID][levelID].missval) )
@@ -311,7 +311,7 @@ void *Timstat(void *argument)
 		    {
 		      if ( samp1[varID][levelID].ptr == NULL )
 			{
-			  samp1[varID][levelID].ptr = (double *) malloc(nwpv*gridsize*sizeof(double));
+			  samp1[varID][levelID].ptr = malloc(nwpv*gridsize*sizeof(double));
 			  for ( i = 0; i < nwpv*gridsize; i++ )
 			    samp1[varID][levelID].ptr[i] = nsets;
 			}
diff --git a/src/Timstat2.c b/src/Timstat2.c
index 328be19..750ecf8 100644
--- a/src/Timstat2.c
+++ b/src/Timstat2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -148,8 +148,8 @@ void *Timstat2(void *argument)
   nvars  = vlistNvars(vlistID1);
   nrecs  = vlistNrecs(vlistID1);
   nrecs3 = nrecs;
-  recVarID   = (int *) malloc(nrecs*sizeof(int));
-  recLevelID = (int *) malloc(nrecs*sizeof(int));
+  recVarID   = malloc(nrecs*sizeof(int));
+  recLevelID = malloc(nrecs*sizeof(int));
   taxisID1 = vlistInqTaxis(vlistID1);
   taxisID2 = vlistInqTaxis(vlistID2);
   taxisID3 = taxisDuplicate(taxisID1);
@@ -161,11 +161,11 @@ void *Timstat2(void *argument)
  
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array1  = (double *) malloc(gridsize*sizeof(double));
-  array2  = (double *) malloc(gridsize*sizeof(double));
+  array1  = malloc(gridsize*sizeof(double));
+  array2  = malloc(gridsize*sizeof(double));
   				 
-  work    = (double ****) malloc(nvars*sizeof(double ***));
-  nofvals = (int ***)     malloc(nvars*sizeof(int **));
+  work    = malloc(nvars*sizeof(double ***));
+  nofvals = malloc(nvars*sizeof(int **));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
@@ -173,18 +173,18 @@ void *Timstat2(void *argument)
       gridsize = gridInqSize(gridID);
       nlevs    = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
 
-      work[varID]    = (double ***)  malloc(nlevs*sizeof(double **));
-      nofvals[varID] = (int **)      malloc(nlevs*sizeof(int *));  
+      work[varID]    = malloc(nlevs*sizeof(double **));
+      nofvals[varID] = malloc(nlevs*sizeof(int *));  
 
       for ( levelID = 0; levelID < nlevs; levelID++ )
 	{
-	  nofvals[varID][levelID] = (int *) malloc(gridsize*sizeof(int));
+	  nofvals[varID][levelID] = malloc(gridsize*sizeof(int));
 	  memset(nofvals[varID][levelID], 0, gridsize*sizeof(int));
       
-	  work[varID][levelID] = (double **) malloc(nwork*sizeof(double *));
+	  work[varID][levelID] = malloc(nwork*sizeof(double *));
 	  for ( i = 0; i < nwork; i++ )
 	    {
-	      work[varID][levelID][i] = (double *) malloc(gridsize*sizeof(double));
+	      work[varID][levelID][i] = malloc(gridsize*sizeof(double));
 	      memset(work[varID][levelID][i], 0, gridsize*sizeof(double));
 	    }
 	}
diff --git a/src/Timstat3.c b/src/Timstat3.c
index fb1460d..6a20840 100644
--- a/src/Timstat3.c
+++ b/src/Timstat3.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -100,8 +100,8 @@ void *Timstat3(void *argument)
   nvars = vlistNvars(vlistID[0]);
   nrecs = vlistNrecs(vlistID[0]);
   nrecs3 = nrecs;
-  recVarID   = (int *) malloc(nrecs*sizeof(int));
-  recLevelID = (int *) malloc(nrecs*sizeof(int));
+  recVarID   = malloc(nrecs*sizeof(int));
+  recLevelID = malloc(nrecs*sizeof(int));
   taxisID1 = vlistInqTaxis(vlistID[0]);
   taxisID3 = taxisDuplicate(taxisID1);
  
@@ -115,19 +115,19 @@ void *Timstat3(void *argument)
   for ( i = 0; i < NIN; ++i )
     {
       field_init(&in[i]);
-      in[i].ptr = (double *) malloc(gridsize*sizeof(double));
+      in[i].ptr = malloc(gridsize*sizeof(double));
     }
 				 
   for ( i = 0; i < NOUT; ++i )
     {
       field_init(&out[i]);
-      out[i].ptr = (double *) malloc(gridsize*sizeof(double));
+      out[i].ptr = malloc(gridsize*sizeof(double));
     }
 				 
   for ( iw = 0; iw < NFWORK; ++iw )
-    fwork[iw] = (field_t **) malloc(nvars*sizeof(field_t *));
+    fwork[iw] = malloc(nvars*sizeof(field_t *));
   for ( iw = 0; iw < NIWORK; ++iw )
-    iwork[iw] = (int ***)   malloc(nvars*sizeof(int **));
+    iwork[iw] = malloc(nvars*sizeof(int **));
 
   for ( varID = 0; varID < nvars; ++varID )
     {
@@ -138,9 +138,9 @@ void *Timstat3(void *argument)
       missval2 = vlistInqVarMissval(vlistID[1], varID); 
 
       for ( iw = 0; iw < NFWORK; ++iw )
-	fwork[iw][varID] = (field_t *)  malloc(nlevs*sizeof(field_t));
+	fwork[iw][varID] = malloc(nlevs*sizeof(field_t));
       for ( iw = 0; iw < NIWORK; ++iw )
-	iwork[iw][varID] = (int **)  malloc(nlevs*sizeof(int *));  
+	iwork[iw][varID] = malloc(nlevs*sizeof(int *));  
 
       for ( levelID = 0; levelID < nlevs; ++levelID )
 	{
@@ -150,13 +150,13 @@ void *Timstat3(void *argument)
 	      fwork[iw][varID][levelID].grid    = gridID;
 	      fwork[iw][varID][levelID].nmiss   = 0;
 	      fwork[iw][varID][levelID].missval = missval;
-	      fwork[iw][varID][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+	      fwork[iw][varID][levelID].ptr     = malloc(gridsize*sizeof(double));
 	      memset(fwork[iw][varID][levelID].ptr, 0, gridsize*sizeof(double));
 	    }
 
 	  for ( iw = 0; iw < NIWORK; ++iw )
 	    {
-	      iwork[iw][varID][levelID] = (int *) malloc(gridsize*sizeof(int));
+	      iwork[iw][varID][levelID] = malloc(gridsize*sizeof(int));
 	      memset(iwork[iw][varID][levelID], 0, gridsize*sizeof(int));
 	    }
 	}
diff --git a/src/Tocomplex.c b/src/Tocomplex.c
index 76be459..818b164 100644
--- a/src/Tocomplex.c
+++ b/src/Tocomplex.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -70,8 +70,8 @@ void *Tocomplex(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(2*gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(2*gridsize*sizeof(double));
       
   tsID  = 0;
   tsID2 = 0;
diff --git a/src/Transpose.c b/src/Transpose.c
index 37dfe11..db2dbf0 100644
--- a/src/Transpose.c
+++ b/src/Transpose.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -37,8 +37,8 @@ void transxy(int gridID, double *array1, double *array2)
   nx = gridInqXsize(gridID);
   ny = gridInqYsize(gridID);
 
-  a2D1 = (double **) malloc(ny*sizeof(double *));
-  a2D2 = (double **) malloc(nx*sizeof(double *));
+  a2D1 = malloc(ny*sizeof(double *));
+  a2D2 = malloc(nx*sizeof(double *));
 
   for ( j = 0; j < ny; ++j ) a2D1[j] = array1+j*nx;
   for ( i = 0; i < nx; ++i ) a2D2[i] = array2+i*ny;
@@ -98,8 +98,8 @@ void *Transpose(void *argument)
 
   gridsize = vlistGridsizeMax(vlistID1);
 
-  array1 = (double *) malloc(gridsize*sizeof(double));
-  array2 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
+  array2 = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Trend.c b/src/Trend.c
index 3226c2b..0f3e121 100644
--- a/src/Trend.c
+++ b/src/Trend.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -73,16 +73,16 @@ void *Trend(void *argument)
   streamDefVlist(streamID2, vlistID2);
   streamDefVlist(streamID3, vlistID2);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field1);
   field_init(&field2);
 
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field2.ptr = malloc(gridsize*sizeof(double));
 
   for ( w = 0; w < nwork; w++ )
     work[w] = field_calloc(vlistID1, FIELD_PTR);
diff --git a/src/Trms.c b/src/Trms.c
index 6f47ff0..56d5f26 100644
--- a/src/Trms.c
+++ b/src/Trms.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -25,6 +25,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
+#include "grid.h"
 
 
 void trms(field_t field1, field_t field2, double *dp, field_t *field3)
@@ -169,19 +170,19 @@ void *Trms(void *argument)
 
   streamDefVlist(streamID3, vlistID3);
 
-  vardata1 = (double **) malloc(nvars*sizeof(double*));
-  vardata2 = (double **) malloc(nvars*sizeof(double*));
+  vardata1 = malloc(nvars*sizeof(double*));
+  vardata2 = malloc(nvars*sizeof(double*));
 
   gridsize = gridInqSize(vlistInqVarGrid(vlistID1, pvarID));
   nlevel   = vctsize/2 - 1;
-  dp = (double *) malloc(gridsize*nlevel*sizeof(double));
+  dp = malloc(gridsize*nlevel*sizeof(double));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
       gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
       nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      vardata1[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
-      vardata2[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+      vardata1[varID] = malloc(gridsize*nlevel*sizeof(double));
+      vardata2[varID] = malloc(gridsize*nlevel*sizeof(double));
     }
 
   field_init(&field1);
@@ -191,7 +192,7 @@ void *Trms(void *argument)
   lim = vlistGridsizeMax(vlistID1);
   field1.weight = NULL;
   if ( needWeights )
-    field1.weight = (double *) malloc(lim*sizeof(double));
+    field1.weight = malloc(lim*sizeof(double));
 
   field2.weight = NULL;
 
diff --git a/src/Tstepcount.c b/src/Tstepcount.c
index be1dd8a..157a1f8 100644
--- a/src/Tstepcount.c
+++ b/src/Tstepcount.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -111,7 +111,7 @@ void *Tstepcount(void *argument)
       if ( tsID >= nalloc )
 	{
 	  nalloc += NALLOC_INC;
-	  vars  = (field_t ***) realloc(vars, nalloc*sizeof(field_t **));
+	  vars  = realloc(vars, nalloc*sizeof(field_t **));
 	}
 
       vdate = taxisInqVdate(taxisID1);
@@ -124,7 +124,7 @@ void *Tstepcount(void *argument)
 	  streamInqRecord(streamID1, &varID, &levelID);
 	  gridID   = vlistInqVarGrid(vlistID1, varID);
 	  gridsize = gridInqSize(gridID);
-	  vars[tsID][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+	  vars[tsID][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 	  streamReadRecord(streamID1, vars[tsID][varID][levelID].ptr, &nmiss);
 	  vars[tsID][varID][levelID].nmiss = nmiss;
 	}
@@ -134,10 +134,10 @@ void *Tstepcount(void *argument)
 
   nts = tsID;
 
-  mem = (memory_t *) malloc(ompNumThreads*sizeof(memory_t));
+  mem = malloc(ompNumThreads*sizeof(memory_t));
   for ( i = 0; i < ompNumThreads; i++ )
     {
-      mem[i].array1 = (double *) malloc(nts*sizeof(double));
+      mem[i].array1 = malloc(nts*sizeof(double));
     }
 
   for ( varID = 0; varID < nvars; varID++ )
diff --git a/src/Vardup.c b/src/Vardup.c
index aab0df0..d30a16c 100644
--- a/src/Vardup.c
+++ b/src/Vardup.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -79,20 +79,20 @@ void *Vardup(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array    = (double *) malloc(gridsize*sizeof(double));
-  vardata  = (double **) malloc(nvars*sizeof(double *));
-  varnmiss = (int **) malloc(nvars*sizeof(int *));
+  array    = malloc(gridsize*sizeof(double));
+  vardata  = malloc(nvars*sizeof(double *));
+  varnmiss = malloc(nvars*sizeof(int *));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
       gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
       nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      vardata[varID]  = (double *) malloc(gridsize*nlevel*sizeof(double));
-      varnmiss[varID] = (int *) malloc(nlevel*sizeof(int));
+      vardata[varID]  = malloc(gridsize*nlevel*sizeof(double));
+      varnmiss[varID] = malloc(nlevel*sizeof(int));
     }
 
   for ( i = 1; i < nmul; i++ )
diff --git a/src/Vargen.c b/src/Vargen.c
index 3fef57a..6e1440c 100644
--- a/src/Vargen.c
+++ b/src/Vargen.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -34,6 +34,7 @@
 #include "cdo_int.h"
 #include "pstream.h"
 #include "list.h"
+#include "stdnametable.h"
 
 
 #if defined(ENABLE_DATA)
@@ -243,7 +244,7 @@ void *Vargen(void *argument)
       vlistDefVarUnits(vlistID   , varID , "hPa");
       vlistDefVarName(vlistID    , varID2, "T");
       vlistDefVarCode(vlistID    , varID2, 130);
-      vlistDefVarStdname(vlistID , varID2, "air_temperature");
+      vlistDefVarStdname(vlistID , varID2, var_stdname(air_temperature));
       vlistDefVarLongname(vlistID, varID2, "temperature");
       vlistDefVarUnits(vlistID   , varID2, "K");
     }
@@ -268,7 +269,7 @@ void *Vargen(void *argument)
   streamDefVlist(streamID, vlistID);
 
   gridsize = gridInqSize(gridID);
-  array = (double *) malloc(gridsize*sizeof(double));
+  array = malloc(gridsize*sizeof(double));
 
   if ( operatorID == FOR )
     ntimesteps = 1.001 + ((rstop-rstart)/rinc);
diff --git a/src/Varrms.c b/src/Varrms.c
index 160596f..a65473e 100644
--- a/src/Varrms.c
+++ b/src/Varrms.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -25,6 +25,7 @@
 #include "cdo.h"
 #include "cdo_int.h"
 #include "pstream.h"
+#include "grid.h"
 
 
 void *Varrms(void *argument)
@@ -97,15 +98,15 @@ void *Varrms(void *argument)
 
   streamDefVlist(streamID3, vlistID3);
 
-  vardata1 = (double **) malloc(nvars*sizeof(double*));
-  vardata2 = (double **) malloc(nvars*sizeof(double*));
+  vardata1 = malloc(nvars*sizeof(double*));
+  vardata2 = malloc(nvars*sizeof(double*));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
       gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
       nlevel   = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID));
-      vardata1[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
-      vardata2[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+      vardata1[varID] = malloc(gridsize*nlevel*sizeof(double));
+      vardata2[varID] = malloc(gridsize*nlevel*sizeof(double));
     }
 
   field_init(&field1);
@@ -115,7 +116,7 @@ void *Varrms(void *argument)
   lim = vlistGridsizeMax(vlistID1);
   field1.weight = NULL;
   if ( needWeights )
-    field1.weight = (double *) malloc(lim*sizeof(double));
+    field1.weight = malloc(lim*sizeof(double));
 
   field2.weight = NULL;
 
diff --git a/src/Vertint.c b/src/Vertint.c
index e7af8be..5afb701 100644
--- a/src/Vertint.c
+++ b/src/Vertint.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -31,6 +31,7 @@
 #include "pstream.h"
 #include "vinterp.h"
 #include "list.h"
+#include "stdnametable.h"
 
 #define  C_EARTH_GRAV    (9.80665)
 
@@ -174,7 +175,7 @@ void *Vertint(void *argument)
 	{
 	  double *level;
 	  int l;
-	  level = (double *) malloc(nlevel*sizeof(double));
+	  level = malloc(nlevel*sizeof(double));
 	  zaxisInqLevels(zaxisID, level);
 	  for ( l = 0; l < nlevel; l++ )
 	    {
@@ -198,7 +199,7 @@ void *Vertint(void *argument)
 		  nhlevf   = nhlev;
 		  nhlevh   = nhlevf + 1;
 	      
-		  vct = (double *) malloc(nvct*sizeof(double));
+		  vct = malloc(nvct*sizeof(double));
 		  zaxisInqVct(zaxisID, vct);
 
 		  vlistChangeZaxisIndex(vlistID2, i, zaxisIDp);
@@ -219,7 +220,7 @@ void *Vertint(void *argument)
 		  nhlevf   = nhlev - 1;
 		  nhlevh   = nhlev;
 	      
-		  vct = (double *) malloc(nvct*sizeof(double));
+		  vct = malloc(nvct*sizeof(double));
 		  zaxisInqVct(zaxisID, vct);
 
 		  vlistChangeZaxisIndex(vlistID2, i, zaxisIDp);
@@ -237,7 +238,7 @@ void *Vertint(void *argument)
 		  int vctsize;
 		  int voff = 4;
 		  
-		  rvct = (double *) malloc(nvct*sizeof(double));
+		  rvct = malloc(nvct*sizeof(double));
 		  zaxisInqVct(zaxisID, rvct);
 
 		  if ( (int)(rvct[0]+0.5) == 100000 && rvct[voff] < rvct[voff+1] )
@@ -249,7 +250,7 @@ void *Vertint(void *argument)
 		      nhlevh   = nhlev + 1;
 
 		      vctsize = 2*nhlevh;
-		      vct = (double *) malloc(vctsize*sizeof(double));
+		      vct = malloc(vctsize*sizeof(double));
 
 		      vlistChangeZaxisIndex(vlistID2, i, zaxisIDp);
 
@@ -287,16 +288,16 @@ void *Vertint(void *argument)
 
   nvars = vlistNvars(vlistID1);
 
-  vars      = (int *) malloc(nvars*sizeof(int));
-  vardata1  = (double **) malloc(nvars*sizeof(double*));
-  vardata2  = (double **) malloc(nvars*sizeof(double*));
-  varnmiss  = (int **) malloc(nvars*sizeof(int*));
-  varinterp = (int *) malloc(nvars*sizeof(int));
+  vars      = malloc(nvars*sizeof(int));
+  vardata1  = malloc(nvars*sizeof(double*));
+  vardata2  = malloc(nvars*sizeof(double*));
+  varnmiss  = malloc(nvars*sizeof(int*));
+  varinterp = malloc(nvars*sizeof(int));
 
   maxlev   = nhlevh > nplev ? nhlevh : nplev;
 
   if ( Extrapolate == 0 )
-    pnmiss   = (int *) malloc(nplev*sizeof(int));
+    pnmiss   = malloc(nplev*sizeof(int));
 
   // check levels
   if ( zaxisIDh != -1 )
@@ -318,17 +319,17 @@ void *Vertint(void *argument)
 
   if ( zaxisIDh != -1 && ngp > 0 )
     {
-      vert_index = (int *) malloc(ngp*nplev*sizeof(int));
-      ps_prog    = (double *) malloc(ngp*sizeof(double));
-      full_press = (double *) malloc(ngp*nhlevf*sizeof(double));
-      half_press = (double *) malloc(ngp*nhlevh*sizeof(double));
+      vert_index = malloc(ngp*nplev*sizeof(int));
+      ps_prog    = malloc(ngp*sizeof(double));
+      full_press = malloc(ngp*nhlevf*sizeof(double));
+      half_press = malloc(ngp*nhlevh*sizeof(double));
     }
   else
     cdoWarning("No data on hybrid model level found!");
 
   if ( operfunc == func_hl )
     {
-      phlev = (double *) malloc(nplev*sizeof(double));
+      phlev = malloc(nplev*sizeof(double));
       h2p(phlev, plev, nplev);
 
       if ( cdoVerbose )
@@ -411,18 +412,15 @@ void *Vertint(void *argument)
 	  vlistInqVarStdname(vlistID1, varID, stdname);
 	  strtolower(stdname);
 
-	  if      ( strcmp(stdname, "surface_air_pressure") == 0 ) code = 134;
-	  else if ( strcmp(stdname, "air_temperature")      == 0 ) code = 130;
-	  else if ( strcmp(stdname, "surface_geopotential") == 0 ) code = 129;
-	  else if ( strcmp(stdname, "geopotential")         == 0 ) code = 129;
-	  else if ( strcmp(stdname, "geopotential_height")  == 0 ) code = 156;
-	  else
+	  code = echamcode_from_stdname(stdname);
+
+	  if ( code < 0 )
 	    {
-	      /*                        ECHAM                            ECMWF       */
-	      if      ( strcmp(varname, "geosp") == 0 || strcmp(varname, "z")    == 0 ) code = 129;
-	      else if ( strcmp(varname, "st")    == 0 || strcmp(varname, "t")    == 0 ) code = 130;
-	      else if ( strcmp(varname, "aps")   == 0 || strcmp(varname, "sp"  ) == 0 ) code = 134;
-	      else if ( strcmp(varname, "lsp")   == 0 || strcmp(varname, "lnsp") == 0 ) code = 152;
+	      /*                                  ECHAM                            ECMWF       */
+	      if      ( geopID == -1  && (strcmp(varname, "geosp") == 0 || strcmp(varname, "z")    == 0) ) code = 129;
+	      else if ( tempID == -1  && (strcmp(varname, "st")    == 0 || strcmp(varname, "t")    == 0) ) code = 130;
+	      else if ( psID   == -1  && (strcmp(varname, "aps")   == 0 || strcmp(varname, "sp"  ) == 0) ) code = 134;
+	      else if ( lnpsID == -1  && (strcmp(varname, "lsp")   == 0 || strcmp(varname, "lnsp") == 0) ) code = 152;
 	      /* else if ( strcmp(varname, "geopoth") == 0 ) code = 156; */
 	    }
 	}
@@ -449,17 +447,17 @@ void *Vertint(void *argument)
 	cdoAbort("Spectral data unsupported!");
 
       if ( varID == gheightID )
-	vardata1[varID] = (double *) malloc(gridsize*(nlevel+1)*sizeof(double));
+	vardata1[varID] = malloc(gridsize*(nlevel+1)*sizeof(double));
       else
-	vardata1[varID] = (double *) malloc(gridsize*nlevel*sizeof(double));
+	vardata1[varID] = malloc(gridsize*nlevel*sizeof(double));
 
       /* if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID && zaxisIDh != -1 && nlevel == nhlev ) */
       if ( zaxisID == zaxisIDh ||
 	   (zaxisInqType(zaxisID) == ZAXIS_HYBRID && zaxisIDh != -1 && (nlevel == nhlevh || nlevel == nhlevf)) )
 	{
 	  varinterp[varID] = TRUE;
-	  vardata2[varID]  = (double *) malloc(gridsize*nplev*sizeof(double));
-	  varnmiss[varID]  = (int *) malloc(maxlev*sizeof(int));
+	  vardata2[varID]  = malloc(gridsize*nplev*sizeof(double));
+	  varnmiss[varID]  = malloc(maxlev*sizeof(int));
 	  memset(varnmiss[varID], 0, maxlev*sizeof(int));
 	}
       else
@@ -469,27 +467,27 @@ void *Vertint(void *argument)
 		       varID+1, paramstr, nlevel);
 	  varinterp[varID] = FALSE;
 	  vardata2[varID]  = vardata1[varID];
-	  varnmiss[varID]  = (int *) malloc(nlevel*sizeof(int));
+	  varnmiss[varID]  = malloc(nlevel*sizeof(int));
 	}
     }
 
   if ( cdoVerbose )
     {
       cdoPrint("Found:");
-      if ( tempID != -1 ) cdoPrint("  air temperature");
-      if ( psID   != -1 ) cdoPrint("  surface pressure");
-      if ( geopID != -1 ) cdoPrint("  surface geopotential");
-      if ( gheightID != -1 ) cdoPrint("  geopotential height");
+      if ( tempID != -1 )    cdoPrint("  %s", var_stdname(air_temperature));
+      if ( psID   != -1 )    cdoPrint("  %s", var_stdname(surface_air_pressure));
+      if ( geopID != -1 )    cdoPrint("  %s", var_stdname(surface_geopotential));
+      if ( gheightID != -1 ) cdoPrint("  %s", var_stdname(geopotential_height));
     }
 
   if ( tempID != -1 || gheightID != -1 ) geop_needed = TRUE;
 
   if ( zaxisIDh != -1 && geop_needed )
     {
-      geop = (double *) malloc(ngp*sizeof(double));
+      geop = malloc(ngp*sizeof(double));
       if ( geopID == -1 )
 	{
-	  cdoWarning("Orography (surf. geopotential) not found - using zero orography!");
+	  cdoWarning("%s not found - using zero %s!", var_stdname(surface_geopotential), var_stdname(surface_geopotential));
 	  memset(geop, 0, ngp*sizeof(double));
 	}
     }
@@ -504,10 +502,10 @@ void *Vertint(void *argument)
 	  param = vlistInqVarParam(vlistID1, psID);
 	  cdiParamToString(param, paramstr, sizeof(paramstr));
 	  if ( cdoVerbose )
-	    cdoPrint("LOG surface pressure not found - using surface pressure (param=%s)!", paramstr);
+	    cdoWarning("LOG(%s) not found - using %s!", var_stdname(surface_air_pressure), var_stdname(surface_air_pressure));
 	}
       else
-	cdoAbort("Surface pressure not found!");
+	cdoAbort("%s not found!", var_stdname(surface_air_pressure));
     }
 
   streamID2 = streamOpenWrite(cdoStreamName(1), cdoFiletype());
diff --git a/src/Vertstat.c b/src/Vertstat.c
index fe6b600..cfcfaab 100644
--- a/src/Vertstat.c
+++ b/src/Vertstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -94,12 +94,12 @@ void *Vertstat(void *argument)
   gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
-  vars1 = (field_t *) malloc(nvars*sizeof(field_t));
-  samp1 = (field_t *) malloc(nvars*sizeof(field_t));
+  vars1 = malloc(nvars*sizeof(field_t));
+  samp1 = malloc(nvars*sizeof(field_t));
   if ( operfunc == func_std || operfunc == func_var )
-    vars2 = (field_t *) malloc(nvars*sizeof(field_t));
+    vars2 = malloc(nvars*sizeof(field_t));
 
   for ( varID = 0; varID < nvars; varID++ )
     {
@@ -113,7 +113,7 @@ void *Vertstat(void *argument)
       vars1[varID].nsamp   = 0;
       vars1[varID].nmiss   = 0;
       vars1[varID].missval = missval;
-      vars1[varID].ptr     = (double *) malloc(gridsize*sizeof(double));
+      vars1[varID].ptr     = malloc(gridsize*sizeof(double));
       samp1[varID].grid    = gridID;
       samp1[varID].nmiss   = 0;
       samp1[varID].missval = missval;
@@ -124,7 +124,7 @@ void *Vertstat(void *argument)
 	  vars2[varID].grid    = gridID;
 	  vars2[varID].nmiss   = 0;
 	  vars2[varID].missval = missval;
-	  vars2[varID].ptr     = (double *) malloc(gridsize*sizeof(double));
+	  vars2[varID].ptr     = malloc(gridsize*sizeof(double));
 	}
     }
 
@@ -151,7 +151,7 @@ void *Vertstat(void *argument)
 	      if ( nmiss > 0 || samp1[varID].ptr )
 		{
 		  if ( samp1[varID].ptr == NULL )
-		    samp1[varID].ptr = (double *) malloc(gridsize*sizeof(double));
+		    samp1[varID].ptr = malloc(gridsize*sizeof(double));
 
 		  for ( i = 0; i < gridsize; i++ )
 		    if ( DBL_IS_EQUAL(vars1[varID].ptr[i], vars1[varID].missval) )
@@ -170,7 +170,7 @@ void *Vertstat(void *argument)
 		{
 		  if ( samp1[varID].ptr == NULL )
 		    {
-		      samp1[varID].ptr = (double *) malloc(gridsize*sizeof(double));
+		      samp1[varID].ptr = malloc(gridsize*sizeof(double));
 		      for ( i = 0; i < gridsize; i++ )
 			samp1[varID].ptr[i] = vars1[varID].nsamp;
 		    }
diff --git a/src/Vertwind.c b/src/Vertwind.c
index 55cd816..511e20d 100644
--- a/src/Vertwind.c
+++ b/src/Vertwind.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -142,14 +142,14 @@ void *Vertwind(void *argument)
 
   gridsize = gridInqSize(gridID);
   nlevel = zaxisInqSize(zaxisID);
-  level  = (double *) malloc(nlevel*sizeof(double));
+  level  = malloc(nlevel*sizeof(double));
   zaxisInqLevels(zaxisID, level);
 
-  temp    = (double *) malloc(gridsize*nlevel*sizeof(double));
-  sq      = (double *) malloc(gridsize*nlevel*sizeof(double));
-  omega   = (double *) malloc(gridsize*nlevel*sizeof(double));
-  wms     = (double *) malloc(gridsize*nlevel*sizeof(double));
-  fpress  = (double *) malloc(gridsize*nlevel*sizeof(double));
+  temp    = malloc(gridsize*nlevel*sizeof(double));
+  sq      = malloc(gridsize*nlevel*sizeof(double));
+  omega   = malloc(gridsize*nlevel*sizeof(double));
+  wms     = malloc(gridsize*nlevel*sizeof(double));
+  fpress  = malloc(gridsize*nlevel*sizeof(double));
 
 
   if ( zaxisInqType(zaxisID) == ZAXIS_PRESSURE )
@@ -163,13 +163,13 @@ void *Vertwind(void *argument)
     }
   else if ( zaxisInqType(zaxisID) == ZAXIS_HYBRID )
     {
-      ps_prog = (double *) malloc(gridsize*sizeof(double));
-      hpress  = (double *) malloc(gridsize*(nlevel+1)*sizeof(double));
+      ps_prog = malloc(gridsize*sizeof(double));
+      hpress  = malloc(gridsize*(nlevel+1)*sizeof(double));
   
       nvct = zaxisInqVctSize(zaxisID);
       if ( nlevel == (nvct/2 - 1) )
 	{
-	  vct = (double *) malloc(nvct*sizeof(double));
+	  vct = malloc(nvct*sizeof(double));
 	  zaxisInqVct(zaxisID, vct);
 	}
       else
diff --git a/src/Wct.c b/src/Wct.c
index 361d00d..ca22ea3 100755
--- a/src/Wct.c
+++ b/src/Wct.c
@@ -112,8 +112,8 @@ void *Wct(void *argument)
   field_init(&field1);
   field_init(&field2);
 
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field2.ptr = malloc(gridsize*sizeof(double));
 
   if ( cdoVerbose )
     cdoPrint("Number of timesteps: file1 %d, file2 %d", vlistNtsteps(vlistID1), vlistNtsteps(vlistID2));
diff --git a/src/Wind.c b/src/Wind.c
index 25ea8fc..437d74a 100644
--- a/src/Wind.c
+++ b/src/Wind.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -304,19 +304,19 @@ void *Wind(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array1 = (double *) malloc(gridsize*sizeof(double));
+  array1 = malloc(gridsize*sizeof(double));
 
   if ( varID1 != -1 && varID2 != -1 )
     {
       nlev     = zaxisInqSize(vlistInqVarZaxis(vlistID1, varID1));
 
       gridsize = gridInqSize(gridID1);
-      ivar1 = (double *) malloc(nlev*gridsize*sizeof(double));
-      ivar2 = (double *) malloc(nlev*gridsize*sizeof(double));
+      ivar1 = malloc(nlev*gridsize*sizeof(double));
+      ivar2 = malloc(nlev*gridsize*sizeof(double));
   
       gridsize = gridInqSize(gridID2);
-      ovar1 = (double *) malloc(nlev*gridsize*sizeof(double));
-      ovar2 = (double *) malloc(nlev*gridsize*sizeof(double));
+      ovar1 = malloc(nlev*gridsize*sizeof(double));
+      ovar2 = malloc(nlev*gridsize*sizeof(double));
     }
 
   tsID = 0;
diff --git a/src/Writegrid.c b/src/Writegrid.c
index 92010fb..3e12d95 100644
--- a/src/Writegrid.c
+++ b/src/Writegrid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -55,7 +55,7 @@ void *Writegrid(void *argument)
   if ( gridInqXbounds(gridID, NULL) == 0 || gridInqYbounds(gridID, NULL) == 0 )
     cdoAbort("Grid corner missing!");
 
-  mask = (int *) malloc(gridsize*sizeof(int));
+  mask = malloc(gridsize*sizeof(int));
 
   if ( gridInqMask(gridID, NULL) )
     {
diff --git a/src/Writerandom.c b/src/Writerandom.c
index 1cab4c4..66e6532 100644
--- a/src/Writerandom.c
+++ b/src/Writerandom.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -62,11 +62,11 @@ void *Writerandom(void *argument)
 
       streamDefTimestep(streamID2, tsID);
 
-      recdata    = (double **) malloc(nrecs*sizeof(double*));
-      recvarID   = (int *) malloc(nrecs*sizeof(int));
-      reclevelID = (int *) malloc(nrecs*sizeof(int));
-      recnmiss   = (int *) malloc(nrecs*sizeof(int));
-      recindex   = (int *) malloc(nrecs*sizeof(int));
+      recdata    = malloc(nrecs*sizeof(double*));
+      recvarID   = malloc(nrecs*sizeof(int));
+      reclevelID = malloc(nrecs*sizeof(int));
+      recnmiss   = malloc(nrecs*sizeof(int));
+      recindex   = malloc(nrecs*sizeof(int));
 
       for ( recID = 0; recID < nrecs; recID++ )
 	{
@@ -74,7 +74,7 @@ void *Writerandom(void *argument)
 	  gridsize = gridInqSize(vlistInqVarGrid(vlistID1, varID));
 	  recvarID[recID] = varID;
 	  reclevelID[recID] = levelID;
-	  recdata[recID] = (double *) malloc(gridsize*sizeof(double));
+	  recdata[recID] = malloc(gridsize*sizeof(double));
 	  streamReadRecord(streamID1, recdata[recID], &recnmiss[recID]);
 	}
 
diff --git a/src/YAR.c b/src/YAR.c
index c39f450..c935705 100644
--- a/src/YAR.c
+++ b/src/YAR.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -84,8 +84,8 @@ void yar_store_link_cnsrv(remapvars_t *rv, long add1, long add2, double weight)
   if ( rv->num_links >= rv->max_links )
     resize_remap_vars(rv, rv->resize_increment);
 
-  rv->grid1_add[nlink] = add1;
-  rv->grid2_add[nlink] = add2;
+  rv->src_grid_add[nlink] = add1;
+  rv->tgt_grid_add[nlink] = add2;
 
   rv->wts[nlink] = weight;
 }
@@ -142,12 +142,8 @@ void set_source_data(double * source_data, double init_value,
 static
 long find_ij_weights(double plon, double plat, double *restrict src_lats, double *restrict src_lons, double *ig, double *jg)
 {
-#define  TWO      2.0
 #define  THREE    3.0
 #define  HALF     0.5
-#define  PI       M_PI
-#define  PI2      TWO*PI
-#define  PIH      HALF*PI
   long    Max_Iter = 100;
   double  converge = 1.e-10;            /* Convergence criterion */
   long iter;                     /*  iteration counters   */
@@ -245,14 +241,13 @@ void yar_remap_bil(field_t *field1, field_t *field2)
   if ( ! (gridInqXvals(gridIDin, NULL) && gridInqYvals(gridIDin, NULL)) )
     cdoAbort("Source grid has no values");
 
-  remap.grid.restrict_type = 0;
-  remap.grid.num_srch_bins = 0;
-  remap.grid.pinit = FALSE;
+  remap.src_grid.num_srch_bins = 0;
+  remap.tgt_grid.num_srch_bins = 0;
   remap.vars.pinit = FALSE;
 
   if ( cdoTimer ) timer_start(timer_yar_remap_init);
-  remapGridInit(MAP_TYPE_BILINEAR, 0, gridIDin, gridIDout, &remap.grid);
-  remapVarsInit(MAP_TYPE_BILINEAR, &remap.grid, &remap.vars);
+  remap_grids_init(MAP_TYPE_BILINEAR, 0, gridIDin, &remap.src_grid, gridIDout, &remap.tgt_grid);
+  remap_vars_init(MAP_TYPE_BILINEAR, remap.src_grid.size, remap.tgt_grid.size, &remap.vars);
   if ( cdoTimer ) timer_stop(timer_yar_remap_init);
 
 
@@ -260,15 +255,15 @@ void yar_remap_bil(field_t *field1, field_t *field2)
   nlonIn = gridInqXsize(gridIDin);
   nlatIn = gridInqYsize(gridIDin);
   gridsize1 = gridInqSize(gridIDin);
-  lonIn = (double *) malloc(nlonIn*sizeof(double));
-  latIn = (double *) malloc(nlatIn*sizeof(double));
+  lonIn = malloc(nlonIn*sizeof(double));
+  latIn = malloc(nlatIn*sizeof(double));
   gridInqXvals(gridIDin, lonIn);
   gridInqYvals(gridIDin, latIn);
   for ( int i = 0; i < nlonIn; ++i ) lonIn[i] *= DEG2RAD;
   for ( int i = 0; i < nlatIn; ++i ) latIn[i] *= DEG2RAD;
 
-  xlonIn = (double *) malloc((nlonIn+1)*sizeof(double));
-  xlatIn = (double *) malloc((nlatIn+1)*sizeof(double));
+  xlonIn = malloc((nlonIn+1)*sizeof(double));
+  xlatIn = malloc((nlatIn+1)*sizeof(double));
   gridInqXvals(gridIDin, xlonIn);
   gridInqYvals(gridIDin, xlatIn);
   dxIn = xlonIn[1] - xlonIn[0];
@@ -285,15 +280,15 @@ void yar_remap_bil(field_t *field1, field_t *field2)
   nlonOut = gridInqXsize(gridIDout);
   nlatOut = gridInqYsize(gridIDout);
   gridsize2 = gridInqSize(gridIDout);
-  lonOut = (double *) malloc(nlonOut*sizeof(double));
-  latOut = (double *) malloc(nlatOut*sizeof(double));
+  lonOut = malloc(nlonOut*sizeof(double));
+  latOut = malloc(nlatOut*sizeof(double));
   gridInqXvals(gridIDout, lonOut);
   gridInqYvals(gridIDout, latOut);
   for ( int i = 0; i < nlonOut; ++i ) lonOut[i] *= DEG2RAD;
   for ( int i = 0; i < nlatOut; ++i ) latOut[i] *= DEG2RAD;
 
-  xlonOut = (double *) malloc((nlonOut+1)*sizeof(double));
-  xlatOut = (double *) malloc((nlatOut+1)*sizeof(double));
+  xlonOut = malloc((nlonOut+1)*sizeof(double));
+  xlatOut = malloc((nlatOut+1)*sizeof(double));
   gridInqXvals(gridIDout, xlonOut);
   gridInqYvals(gridIDout, xlatOut);
   dxOut = xlonOut[1] - xlonOut[0];
@@ -441,7 +436,7 @@ void yar_remap_bil(field_t *field1, field_t *field2)
 
   if ( cdoTimer ) timer_start(timer_yar_remap);
   yar_remap(array2, missval, gridInqSize(gridIDout), remap.vars.num_links, remap.vars.wts,
-	    remap.vars.num_wts, remap.vars.grid2_add, remap.vars.grid1_add, array1);
+	    remap.vars.num_wts, remap.vars.tgt_grid_add, remap.vars.src_grid_add, array1);
   if ( cdoTimer ) timer_stop(timer_yar_remap);
 
   nmiss = 0;
@@ -489,14 +484,13 @@ void yar_remap_con(field_t *field1, field_t *field2)
   if ( ! (gridInqXvals(gridIDin, NULL) && gridInqYvals(gridIDin, NULL)) )
     cdoAbort("Source grid has no values");
 
-  remap.grid.restrict_type = 0;
-  remap.grid.num_srch_bins = 0;
-  remap.grid.pinit = FALSE;
+  remap.src_grid.num_srch_bins = 0;
+  remap.tgt_grid.num_srch_bins = 0;
   remap.vars.pinit = FALSE;
 
   if ( cdoTimer ) timer_start(timer_yar_remap_init);
-  remapGridInit(MAP_TYPE_CONSERV, 0, gridIDin, gridIDout, &remap.grid);
-  remapVarsInit(MAP_TYPE_CONSERV, &remap.grid, &remap.vars);
+  remap_grids_init(MAP_TYPE_CONSERV, 0, gridIDin, &remap.src_grid, gridIDout, &remap.tgt_grid);
+  remap_vars_init(MAP_TYPE_CONSERV, remap.src_grid.size, remap.tgt_grid.size, &remap.vars);
   if ( cdoTimer ) timer_stop(timer_yar_remap_init);
 
 
@@ -504,12 +498,12 @@ void yar_remap_con(field_t *field1, field_t *field2)
   nlonIn = gridInqXsize(gridIDin);
   nlatIn = gridInqYsize(gridIDin);
   gridsize1 = gridInqSize(gridIDin);
-  lonIn = (double *) malloc((nlonIn+1)*sizeof(double));
-  latIn = (double *) malloc((nlatIn+1)*sizeof(double));
+  lonIn = malloc((nlonIn+1)*sizeof(double));
+  latIn = malloc((nlatIn+1)*sizeof(double));
   gridInqXvals(gridIDin, lonIn);
   gridInqYvals(gridIDin, latIn);
-  xlonIn = (double *) malloc((nlonIn)*sizeof(double));
-  xlatIn = (double *) malloc((nlatIn)*sizeof(double));
+  xlonIn = malloc((nlonIn)*sizeof(double));
+  xlatIn = malloc((nlatIn)*sizeof(double));
   gridInqXvals(gridIDin, xlonIn);
   gridInqYvals(gridIDin, xlatIn);
   dxIn = lonIn[1] - lonIn[0];
@@ -526,12 +520,12 @@ void yar_remap_con(field_t *field1, field_t *field2)
   nlonOut = gridInqXsize(gridIDout);
   nlatOut = gridInqYsize(gridIDout);
   gridsize2 = gridInqSize(gridIDout);
-  lonOut = (double *) malloc((nlonOut+1)*sizeof(double));
-  latOut = (double *) malloc((nlatOut+1)*sizeof(double));
+  lonOut = malloc((nlonOut+1)*sizeof(double));
+  latOut = malloc((nlatOut+1)*sizeof(double));
   gridInqXvals(gridIDout, lonOut);
   gridInqYvals(gridIDout, latOut);
-  xlonOut = (double *) malloc((nlonOut+1)*sizeof(double));
-  xlatOut = (double *) malloc((nlatOut+1)*sizeof(double));
+  xlonOut = malloc((nlonOut+1)*sizeof(double));
+  xlatOut = malloc((nlatOut+1)*sizeof(double));
   gridInqXvals(gridIDout, xlonOut);
   gridInqYvals(gridIDout, xlatOut);
   dxOut = lonOut[1] - lonOut[0];
@@ -611,11 +605,11 @@ void yar_remap_con(field_t *field1, field_t *field2)
   double const epsilon = 1.0e-10; // relative precision 
 
   double *weight;
-  weight = (double *) malloc(gridsize1*sizeof(double));
+  weight = malloc(gridsize1*sizeof(double));
 
   double tgt_area;
   double *area;
-  area = (double *) malloc(gridsize1*sizeof(double));
+  area = malloc(gridsize1*sizeof(double));
 
   struct grid_cell *SourceCell;
   SourceCell = malloc (gridsize1  * sizeof(*SourceCell) );
@@ -746,7 +740,7 @@ void yar_remap_con(field_t *field1, field_t *field2)
 
   if ( cdoTimer ) timer_start(timer_yar_remap);
   yar_remap(array2, missval, gridInqSize(gridIDout), remap.vars.num_links, remap.vars.wts,
-	    remap.vars.num_wts, remap.vars.grid2_add, remap.vars.grid1_add, array1);
+	    remap.vars.num_wts, remap.vars.tgt_grid_add, remap.vars.src_grid_add, array1);
   if ( cdoTimer ) timer_stop(timer_yar_remap);
 
   nmiss = 0;
@@ -844,10 +838,10 @@ void *YAR(void *argument)
   streamDefVlist(streamID2, vlistID2);
 
   gridsize = vlistGridsizeMax(vlistID1);
-  array1   = (double *) malloc(gridsize*sizeof(double));
+  array1   = malloc(gridsize*sizeof(double));
 
   gridsize = gridInqSize(gridID2);
-  array2   = (double *) malloc(gridsize*sizeof(double));
+  array2   = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID1, tsID)) )
diff --git a/src/Ydayarith.c b/src/Ydayarith.c
index ac00f74..cc5ccbf 100644
--- a/src/Ydayarith.c
+++ b/src/Ydayarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -72,8 +72,8 @@ void *Ydayarith(void *argument)
 
   field_init(&field1);
   field_init(&field2);
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field2.ptr = malloc(gridsize*sizeof(double));
 
   taxisID1 = vlistInqTaxis(vlistID1);
   taxisID2 = vlistInqTaxis(vlistID2);
@@ -99,15 +99,15 @@ void *Ydayarith(void *argument)
 
       if ( vardata2[day] != NULL ) cdoAbort("Day %d already allocatd!", day);
 
-      vardata2[day]  = (double **) malloc(nvars*sizeof(double *));
-      varnmiss2[day] = (int **) malloc(nvars*sizeof(int *));
+      vardata2[day]  = malloc(nvars*sizeof(double *));
+      varnmiss2[day] = malloc(nvars*sizeof(int *));
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
 	  gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
 	  nlev     = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
-	  vardata2[day][varID]  = (double *) malloc(nlev*gridsize*sizeof(double));
-	  varnmiss2[day][varID] = (int *) malloc(nlev*sizeof(int));
+	  vardata2[day][varID]  = malloc(nlev*gridsize*sizeof(double));
+	  varnmiss2[day][varID] = malloc(nlev*sizeof(int));
 	}
 
       for ( recID = 0; recID < nrecs; recID++ )
diff --git a/src/Ydaypctl.c b/src/Ydaypctl.c
index 4329964..881a824 100644
--- a/src/Ydaypctl.c
+++ b/src/Ydaypctl.c
@@ -100,12 +100,12 @@ void *Ydaypctl(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID2, tsID)) )
diff --git a/src/Ydaystat.c b/src/Ydaystat.c
index 1643ff9..8d01652 100644
--- a/src/Ydaystat.c
+++ b/src/Ydaystat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -109,12 +109,12 @@ void *Ydaystat(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   otsID = 0;
@@ -166,7 +166,7 @@ void *Ydaystat(void *argument)
 	      if ( nmiss > 0 || samp1[dayoy][varID][levelID].ptr )
 		{
 		  if ( samp1[dayoy][varID][levelID].ptr == NULL )
-		    samp1[dayoy][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+		    samp1[dayoy][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 
 		  for ( i = 0; i < gridsize; i++ )
 		    if ( DBL_IS_EQUAL(vars1[dayoy][varID][levelID].ptr[i],
@@ -186,7 +186,7 @@ void *Ydaystat(void *argument)
 		{
 		  if ( samp1[dayoy][varID][levelID].ptr == NULL )
 		    {
-		      samp1[dayoy][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+		      samp1[dayoy][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 		      for ( i = 0; i < gridsize; i++ )
 			samp1[dayoy][varID][levelID].ptr[i] = nsets[dayoy];
 		    }
diff --git a/src/Ydrunpctl.c b/src/Ydrunpctl.c
index 8ffa1fc..455ad5d 100644
--- a/src/Ydrunpctl.c
+++ b/src/Ydrunpctl.c
@@ -109,16 +109,16 @@ void *Ydrunpctl(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
-  datetime = (datetime_t *) malloc((ndates+1)*sizeof(datetime_t));
+  datetime = malloc((ndates+1)*sizeof(datetime_t));
   
-  vars1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
+  vars1 = malloc((ndates+1)*sizeof(field_t **));
   
   for ( its = 0; its < ndates; its++ )
     {
diff --git a/src/Ydrunstat.c b/src/Ydrunstat.c
index d0c35c0..7e59f99 100644
--- a/src/Ydrunstat.c
+++ b/src/Ydrunstat.c
@@ -128,15 +128,15 @@ void *Ydrunstat(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
-  datetime = (datetime_t *) malloc((ndates+1)*sizeof(datetime_t));
+  datetime = malloc((ndates+1)*sizeof(datetime_t));
   
   stats = ydstatCreate(vlistID1);
-  vars1 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
+  vars1 = malloc((ndates+1)*sizeof(field_t **));
   if ( lvarstd )
-    vars2 = (field_t ***) malloc((ndates+1)*sizeof(field_t **));
+    vars2 = malloc((ndates+1)*sizeof(field_t **));
   
   for ( its = 0; its < ndates; its++ )
     {
@@ -298,7 +298,7 @@ YDAY_STATS *ydstatCreate(int vlistID)
 {
   int dayoy;
   
-  YDAY_STATS *stats = (YDAY_STATS *) malloc(sizeof(YDAY_STATS));
+  YDAY_STATS *stats = malloc(sizeof(YDAY_STATS));
   
   for ( dayoy = 0; dayoy < NDAY; dayoy++ )
     {
diff --git a/src/Yearmonstat.c b/src/Yearmonstat.c
index 56f66d7..e8e0593 100644
--- a/src/Yearmonstat.c
+++ b/src/Yearmonstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -86,13 +86,13 @@ void *Yearmonstat(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
 
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   vars1 = field_malloc(vlistID1, FIELD_PTR);
   samp1 = field_malloc(vlistID1, FIELD_NONE);
@@ -149,7 +149,7 @@ void *Yearmonstat(void *argument)
 		  if ( nmiss > 0 || samp1[varID][levelID].ptr )
 		    {
 		      if ( samp1[varID][levelID].ptr == NULL )
-			samp1[varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+			samp1[varID][levelID].ptr = malloc(gridsize*sizeof(double));
 
 		      for ( i = 0; i < gridsize; i++ )
 			if ( DBL_IS_EQUAL(vars1[varID][levelID].ptr[i], vars1[varID][levelID].missval) )
@@ -170,7 +170,7 @@ void *Yearmonstat(void *argument)
 		    {
 		      if ( samp1[varID][levelID].ptr == NULL )
 			{
-			  samp1[varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+			  samp1[varID][levelID].ptr = malloc(gridsize*sizeof(double));
 			  for ( i = 0; i < gridsize; i++ )
 			    samp1[varID][levelID].ptr[i] = dsets;
 			}
diff --git a/src/Yhourarith.c b/src/Yhourarith.c
index 0f3cfaf..8f5c963 100644
--- a/src/Yhourarith.c
+++ b/src/Yhourarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -99,8 +99,8 @@ void *Yhourarith(void *argument)
 
   field_init(&field1);
   field_init(&field2);
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field2.ptr = malloc(gridsize*sizeof(double));
 
   taxisID1 = vlistInqTaxis(vlistID1);
   taxisID2 = vlistInqTaxis(vlistID2);
@@ -124,15 +124,15 @@ void *Yhourarith(void *argument)
       houroy = hour_of_year(vdate, vtime);
       if ( vardata2[houroy] != NULL ) cdoAbort("Hour of year %d already allocatd!", houroy);
 
-      vardata2[houroy]  = (double **) malloc(nvars*sizeof(double *));
-      varnmiss2[houroy] = (int **) malloc(nvars*sizeof(int *));
+      vardata2[houroy]  = malloc(nvars*sizeof(double *));
+      varnmiss2[houroy] = malloc(nvars*sizeof(int *));
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
 	  gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
 	  nlev     = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
-	  vardata2[houroy][varID]  = (double *) malloc(nlev*gridsize*sizeof(double));
-	  varnmiss2[houroy][varID] = (int *) malloc(nlev*sizeof(int));
+	  vardata2[houroy][varID]  = malloc(nlev*gridsize*sizeof(double));
+	  varnmiss2[houroy][varID] = malloc(nlev*sizeof(int));
 	}
 
       for ( recID = 0; recID < nrecs; recID++ )
diff --git a/src/Yhourstat.c b/src/Yhourstat.c
index 12655a0..47df90d 100644
--- a/src/Yhourstat.c
+++ b/src/Yhourstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -134,12 +134,12 @@ void *Yhourstat(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   otsID = 0;
@@ -183,7 +183,7 @@ void *Yhourstat(void *argument)
 	      if ( nmiss > 0 || samp1[houroy][varID][levelID].ptr )
 		{
 		  if ( samp1[houroy][varID][levelID].ptr == NULL )
-		    samp1[houroy][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+		    samp1[houroy][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 
 		  for ( i = 0; i < gridsize; i++ )
 		    if ( DBL_IS_EQUAL(vars1[houroy][varID][levelID].ptr[i],
@@ -203,7 +203,7 @@ void *Yhourstat(void *argument)
 		{
 		  if ( samp1[houroy][varID][levelID].ptr == NULL )
 		    {
-		      samp1[houroy][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+		      samp1[houroy][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 		      for ( i = 0; i < gridsize; i++ )
 			samp1[houroy][varID][levelID].ptr[i] = nsets[houroy];
 		    }
diff --git a/src/Ymonarith.c b/src/Ymonarith.c
index 3663cba..17defa5 100644
--- a/src/Ymonarith.c
+++ b/src/Ymonarith.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -72,8 +72,8 @@ void *Ymonarith(void *argument)
 
   field_init(&field1);
   field_init(&field2);
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field2.ptr = malloc(gridsize*sizeof(double));
 
   taxisID1 = vlistInqTaxis(vlistID1);
   taxisID2 = vlistInqTaxis(vlistID2);
@@ -98,15 +98,15 @@ void *Ymonarith(void *argument)
 
       if ( vardata2[mon] != NULL ) cdoAbort("Month %d already allocatd!", mon);
 
-      vardata2[mon]  = (double **) malloc(nvars*sizeof(double *));
-      varnmiss2[mon] = (int **) malloc(nvars*sizeof(int *));
+      vardata2[mon]  = malloc(nvars*sizeof(double *));
+      varnmiss2[mon] = malloc(nvars*sizeof(int *));
 
       for ( varID = 0; varID < nvars; varID++ )
 	{
 	  gridsize = gridInqSize(vlistInqVarGrid(vlistID2, varID));
 	  nlev     = zaxisInqSize(vlistInqVarZaxis(vlistID2, varID));
-	  vardata2[mon][varID]  = (double *) malloc(nlev*gridsize*sizeof(double));
-	  varnmiss2[mon][varID] = (int *) malloc(nlev*sizeof(int));
+	  vardata2[mon][varID]  = malloc(nlev*gridsize*sizeof(double));
+	  varnmiss2[mon][varID] = malloc(nlev*sizeof(int));
 	}
 
       for ( recID = 0; recID < nrecs; recID++ )
diff --git a/src/Ymonpctl.c b/src/Ymonpctl.c
index 3c72e90..fb857de 100644
--- a/src/Ymonpctl.c
+++ b/src/Ymonpctl.c
@@ -98,12 +98,12 @@ void *Ymonpctl(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID2, tsID)) )
diff --git a/src/Ymonstat.c b/src/Ymonstat.c
index 7d91888..bce334d 100644
--- a/src/Ymonstat.c
+++ b/src/Ymonstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -43,8 +43,8 @@ static
 int cmpint(const void *s1, const void *s2)
 {
   int cmp = 0;
-  int *x = (int *) s1;
-  int *y = (int *) s2;
+  const int *x = s1;
+  const int *y = s2;
 
   if      ( *x < *y ) cmp = -1;
   else if ( *x > *y ) cmp =  1;
@@ -126,12 +126,12 @@ void *Ymonstat(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   otsID = 0;
@@ -179,7 +179,7 @@ void *Ymonstat(void *argument)
 	      if ( nmiss > 0 || samp1[month][varID][levelID].ptr )
 		{
 		  if ( samp1[month][varID][levelID].ptr == NULL )
-		    samp1[month][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+		    samp1[month][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 
 		  for ( i = 0; i < gridsize; i++ )
 		    if ( DBL_IS_EQUAL(vars1[month][varID][levelID].ptr[i],
@@ -199,7 +199,7 @@ void *Ymonstat(void *argument)
 		{
 		  if ( samp1[month][varID][levelID].ptr == NULL )
 		    {
-		      samp1[month][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+		      samp1[month][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 		      for ( i = 0; i < gridsize; i++ )
 			samp1[month][varID][levelID].ptr[i] = nsets[month];
 		    }
diff --git a/src/Yseaspctl.c b/src/Yseaspctl.c
index fe2b0a2..bf0c69a 100644
--- a/src/Yseaspctl.c
+++ b/src/Yseaspctl.c
@@ -101,12 +101,12 @@ void *Yseaspctl(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   while ( (nrecs = streamInqTimestep(streamID2, tsID)) )
diff --git a/src/Yseasstat.c b/src/Yseasstat.c
index e6d139b..24f5de7 100644
--- a/src/Yseasstat.c
+++ b/src/Yseasstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -125,12 +125,12 @@ void *Yseasstat(void *argument)
   nvars    = vlistNvars(vlistID1);
   nrecords = vlistNrecs(vlistID1);
 
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = vlistGridsizeMax(vlistID1);
   field_init(&field);
-  field.ptr = (double *) malloc(gridsize*sizeof(double));
+  field.ptr = malloc(gridsize*sizeof(double));
 
   tsID = 0;
   otsID = 0;
@@ -190,7 +190,7 @@ void *Yseasstat(void *argument)
 	      if ( nmiss > 0 || samp1[seas][varID][levelID].ptr )
 		{
 		  if ( samp1[seas][varID][levelID].ptr == NULL )
-		    samp1[seas][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+		    samp1[seas][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 
 		  for ( i = 0; i < gridsize; i++ )
 		    if ( DBL_IS_EQUAL(vars1[seas][varID][levelID].ptr[i],
@@ -210,7 +210,7 @@ void *Yseasstat(void *argument)
 		{
 		  if ( samp1[seas][varID][levelID].ptr == NULL )
 		    {
-		      samp1[seas][varID][levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+		      samp1[seas][varID][levelID].ptr = malloc(gridsize*sizeof(double));
 		      for ( i = 0; i < gridsize; i++ )
 			samp1[seas][varID][levelID].ptr[i] = nsets[seas];
 		    }
diff --git a/src/Zonstat.c b/src/Zonstat.c
index 4e6a1a9..213535e 100644
--- a/src/Zonstat.c
+++ b/src/Zonstat.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.1
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -142,8 +142,8 @@ void *Zonstat(void *argument)
   lim = vlistGridsizeMax(vlistID1);
   field_init(&field2);
   field_init(&field2);
-  field1.ptr  = (double *) malloc(lim*sizeof(double));
-  field2.ptr  = (double *) malloc(nlatmax*sizeof(double));
+  field1.ptr  = malloc(lim*sizeof(double));
+  field2.ptr  = malloc(nlatmax*sizeof(double));
   field2.grid = gridID2;
 
   tsID = 0;
diff --git a/src/cdo.c b/src/cdo.c
index 892ee9f..2dadaf7 100644
--- a/src/cdo.c
+++ b/src/cdo.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -149,16 +149,16 @@ void cdo_version(void)
   char *typenames[] = {        "srv",        "ext",        "ieg",        "grb",        "grb2",        "nc",        "nc2",        "nc4",        "nc4c"};
 
   fprintf(stderr, "%s\n", CDO_Version);
+#if defined(USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
+  fprintf(stderr, "Compiled: by %s on %s (%s) %s %s\n",
+	  USER_NAME, HOST_NAME, SYSTEM_TYPE, __DATE__, __TIME__);
+#endif
 #if defined(COMPILER)
   fprintf(stderr, "Compiler: %s\n", COMPILER);
 #endif
 #if defined(COMP_VERSION)
   fprintf(stderr, " version: %s\n", COMP_VERSION);
 #endif
-#if defined(USER_NAME) && defined(HOST_NAME) && defined(SYSTEM_TYPE)
-  fprintf(stderr, "Compiled: by %s on %s (%s) %s %s\n",
-	  USER_NAME, HOST_NAME, SYSTEM_TYPE, __DATE__, __TIME__);
-#endif
 
   printFeatures();
   printLibraries();
@@ -233,7 +233,7 @@ void usage(void)
   operatorPrintAll();
 
   fprintf(stderr, "\n");
-  fprintf(stderr, "  CDO version %s, Copyright (C) 2003-2013 Uwe Schulzweida\n", VERSION);
+  fprintf(stderr, "  CDO version %s, Copyright (C) 2003-2014 Uwe Schulzweida\n", VERSION);
   //  fprintf(stderr, "  Available from <http://code.zmaw.de/projects/cdo>\n");
   fprintf(stderr, "  This is free software and comes with ABSOLUTELY NO WARRANTY\n");
   fprintf(stderr, "  Report bugs to <http://code.zmaw.de/projects/cdo>\n");
@@ -429,6 +429,10 @@ void setDefaultDataType(char *datatypestr)
       dtype = D_CPX;
       datatypestr++;
     }
+  else if ( *datatypestr == 'p' || *datatypestr == 'P' )
+    {
+      datatypestr++;
+    }
 
   if ( isdigit((int) *datatypestr) )
     {
@@ -733,7 +737,7 @@ void defineVarnames(const char *arg)
     {
       char *commapos;
       
-      cdoVarnames = (char **) malloc(MAX_NUM_VARNAMES*sizeof(char *));
+      cdoVarnames = malloc(MAX_NUM_VARNAMES*sizeof(char *));
 
       pbuf = strdup(arg+istart);
       cdoVarnames[cdoNumVarnames++] = pbuf;    
@@ -769,7 +773,7 @@ void get_env_vars(void)
       if ( len > 0 )
 	{
 	  len += 2;
-	  cdoGridSearchDir = (char *) malloc(len);
+	  cdoGridSearchDir = malloc(len);
 	  memcpy(cdoGridSearchDir, envstr, len-1);
 	  if ( cdoGridSearchDir[len-3] != '/' )
 	    {
diff --git a/src/cdo.h b/src/cdo.h
index e66dc1a..221ecbf 100644
--- a/src/cdo.h
+++ b/src/cdo.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -19,6 +19,7 @@
 #define _CDO_H
 
 #include <stdio.h>
+#include <stdbool.h>
 #include "dmemory.h"
 #include "util.h"
 
@@ -116,18 +117,9 @@ int     vlistIsSzipped(int vlistID);
 
 void cdoGenFileSuffix(char *filesuffix, size_t maxlen, int filetype, int vlistID, const char *refname);
 
-int  gridWeights(int gridID, double *weights);
-int  gridGenArea(int gridID, double *area);
-void gaussaw(double pa[], double pw[], int nlat);
-void genXbounds(long xsize, long ysize, const double * restrict grid_center_lon, 
-		double * restrict grid_corner_lon, double dlon);
-void genYbounds(long xsize, long ysize, const double * restrict grid_center_lat,
-		double * restrict grid_corner_lat);
 void writeNCgrid(const char *gridfile, int gridID, int *imask);
 void defineZaxis(const char *zaxisarg);
 void cdiDefTableID(int tableID);
-void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *xvals);
-void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals);
 
 int gridFromName(const char *gridname);
 int zaxisFromName(const char *zaxisname);
diff --git a/src/cdo_int.h b/src/cdo_int.h
index 4fcb416..e7d0410 100644
--- a/src/cdo_int.h
+++ b/src/cdo_int.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -45,7 +45,7 @@ char *strdup(const char *s);
 ({					      	  \
    const char *__old = (s);			  \
    size_t __len = strlen(__old) + 1;		  \
-   char *__new = (char *) malloc(__len);	  \
+   char *__new = malloc(__len);	  \
    (char *) memcpy(__new, __old, __len);	  \
 })
 */
@@ -189,5 +189,7 @@ void job_submit(const char *expname, const char *jobfilename, const char *jobnam
 
 void minmaxval(long nvals, double *array, int *imiss, double *minval, double *maxval);
 
+off_t filesize(const char *filename);
+
 
 #endif  /* _CDO_INT_H */
diff --git a/src/cdo_pthread.c b/src/cdo_pthread.c
index d373f2a..d4f6d60 100644
--- a/src/cdo_pthread.c
+++ b/src/cdo_pthread.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/cdo_vlist.c b/src/cdo_vlist.c
index a5ea7c6..ff51725 100644
--- a/src/cdo_vlist.c
+++ b/src/cdo_vlist.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -40,8 +40,8 @@ void compareGrids(int gridID1, int gridID2)
 		{
 		  double *yvals1, *yvals2;
 
-		  yvals1 = (double *) malloc(ysize*sizeof(double));
-		  yvals2 = (double *) malloc(ysize*sizeof(double));
+		  yvals1 = malloc(ysize*sizeof(double));
+		  yvals2 = malloc(ysize*sizeof(double));
 
 		  gridInqYvals(gridID1, yvals1);
 		  gridInqYvals(gridID2, yvals2);
@@ -78,8 +78,8 @@ void compareGrids(int gridID1, int gridID2)
 		{
 		  double *xvals1, *xvals2;
 
-		  xvals1 = (double *) malloc(xsize*sizeof(double));
-		  xvals2 = (double *) malloc(xsize*sizeof(double));
+		  xvals1 = malloc(xsize*sizeof(double));
+		  xvals2 = malloc(xsize*sizeof(double));
 
 		  gridInqXvals(gridID1, xvals1);
 		  gridInqXvals(gridID2, xvals2);
@@ -109,8 +109,8 @@ void compareGrids(int gridID1, int gridID2)
 static
 int cmpnames(const void *s1, const void *s2)
 {
-  char *name1 = (char *) s1;
-  char *name2 = (char *) s2;
+  const char *name1 = s1;
+  const char *name2 = s2;
 
   return (strcmp(name1, name2));
 }
@@ -140,6 +140,8 @@ void vlistCompare(int vlistID1, int vlistID2, int flag)
 	  char name1[CDI_MAX_NAME], name2[CDI_MAX_NAME];
 	  vlistInqVarName(vlistID1, varID, name1);
 	  vlistInqVarName(vlistID2, varID, name2);
+	  strtolower(name1);
+	  strtolower(name2);
 	  if ( strcmp(name1, name2) != 0 )
 	    {
 	      cdoWarning("Input streams have different parameters!");
diff --git a/src/cdotest.c b/src/cdotest.c
index e72590f..5910409 100755
--- a/src/cdotest.c
+++ b/src/cdotest.c
@@ -154,8 +154,8 @@ void writeNcFile(const char path[], const double array[], int length)
 static
 double **createVars(int nvars, int nts)
 {  
-  double *array = (double *) malloc(nvars*nts*sizeof(double));
-  double **vars = (double **) malloc(nvars*sizeof(double));
+  double *array = malloc(nvars*nts*sizeof(double));
+  double **vars = malloc(nvars*sizeof(double));
   
   int i;
   
@@ -204,7 +204,7 @@ static
 int submitCdoCommand(const char *argument)
 {  
   const char *cdoPath = getCdoPath();
-  char *cdoCommand = (char *) malloc(strlen(cdoPath) + strlen(argument) + 8);
+  char *cdoCommand = malloc(strlen(cdoPath) + strlen(argument) + 8);
   
   int status;
   
diff --git a/src/clipping/area.c b/src/clipping/area.c
new file mode 100644
index 0000000..248bef8
--- /dev/null
+++ b/src/clipping/area.c
@@ -0,0 +1,647 @@
+/**
+ * @file area.c
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <float.h>
+
+#include "area.h"
+#include "clipping.h"
+#include "geometry.h"
+#include "utils.h"
+#include "ensure_array_size.h"
+
+// area tolerance (100 m*m = 0.0001 km*km)
+const double area_tol = 1e-4;
+
+static double scalar_product(double a[], double b[]);
+
+static void cross_product(double a[], double b[], double cross[]);
+
+static double inner_angle ( double plat, double plon, double qlon, double qlat );
+
+static double partial_area ( double a_lon, double a_lat,
+                             double b_lon, double b_lat,
+                             double c_lon, double c_lat );
+
+/* ----------------------------------- */
+
+double cell_approx_area ( struct grid_cell cell ) {
+
+  /* adopted from Robert.G. Chamberlain and William.H. Duquette */
+
+  int m, M;
+  double SUM = 0.0;
+  double area;
+
+  M = cell.num_corners;
+
+  for ( m = 0; m < M; m++ )
+    SUM += ( cell.coordinates_x[(m+2)%M] - cell.coordinates_x[m] ) *
+             sin(cell.coordinates_y[(m+1)%M]);
+
+  area = -EarthRadius2 * SUM;
+
+  return area;
+}
+
+/* ----------------------------------- */
+
+double triangle_area ( struct grid_cell cell ) {
+
+  /* taken from the ICON code, mo_base_geometry.f90
+     provided by Luis Kornblueh, MPI-M. */
+
+  double s01, s12, s20;
+  double ca1, ca2, ca3;
+  double a1, a2, a3;
+
+  double triangle[3][3];
+  double u01[3], u12[3], u20[3];
+
+  if ( cell.num_corners != 3 ) {
+    printf ("Only for triangles!\n");
+    return -1;
+  }
+
+  /* Convert into cartesian coordinates */
+
+  for (int m = 0; m < 3; m++ )
+    LLtoXYZ(cell.coordinates_x[m], cell.coordinates_y[m], triangle[m]);
+
+  /* First, compute cross products Uij = Vi x Vj. */
+
+  cross_product(triangle[0], triangle[1], u01);
+  cross_product(triangle[1], triangle[2], u12);
+  cross_product(triangle[2], triangle[0], u20);
+
+  /*  Normalize Uij to unit vectors. */
+
+  s01 = scalar_product(u01, u01);
+  s12 = scalar_product(u12, u12);
+  s20 = scalar_product(u20, u20);
+
+  /* Test for a degenerated triangle associated with collinear vertices. */
+
+  if ( s01 == 0.0 &&
+       s12 == 0.0 &&
+       s20 == 0.0 )
+    return 0.0;
+
+  s01 = sqrt(s01);
+  s12 = sqrt(s12);
+  s20 = sqrt(s20);
+
+  for (int m = 0; m < 3; m++ ) {
+    u01[m] = u01[m]/s01;
+    u12[m] = u12[m]/s12;
+    u20[m] = u20[m]/s20;
+  }
+
+  /*  Compute interior angles Ai as the dihedral angles between planes:
+
+      CA1 = cos(A1) = -<U01,U20>
+      CA2 = cos(A2) = -<U12,U01>
+      CA3 = cos(A3) = -<U20,U12>
+
+  */
+
+  ca1 = -u01[0]*u20[0]-u01[1]*u20[1]-u01[2]*u20[2];
+  ca2 = -u12[0]*u01[0]-u12[1]*u01[1]-u12[2]*u01[2];
+  ca3 = -u20[0]*u12[0]-u20[1]*u12[1]-u20[2]*u12[2];
+
+  if ( ca1 < -1.0 ) ca1 = -1.0;
+  if ( ca1 >  1.0 ) ca1 =  1.0;
+  if ( ca2 < -1.0 ) ca2 = -1.0;
+  if ( ca2 >  1.0 ) ca2 =  1.0;
+  if ( ca3 < -1.0 ) ca3 = -1.0;
+  if ( ca3 >  1.0 ) ca3 =  1.0;
+
+  a1 = acos(ca1);
+  a2 = acos(ca2);
+  a3 = acos(ca3);
+
+  /*  Compute areas = a1 + a2 + a3 - pi.
+
+      here for a unit sphere: */
+
+  return MAX(( a1+a2+a3-M_PI ) * EarthRadius * EarthRadius, 0.0);
+}
+
+/* ----------------------------------- */
+
+double cell_area ( struct grid_cell cell ) {
+
+  /* generalised version based on the ICON code, mo_base_geometry.f90
+     provided by Luis Kornblueh, MPI-M. */
+
+  int const M = cell.num_corners; // number of vertices
+
+  double area;
+  double s[cell.num_corners];
+  double ca[cell.num_corners];
+  double a[cell.num_corners];
+
+  double p[cell.num_corners][3];
+  double u[cell.num_corners][3];
+
+  /* Convert into cartesian coordinates */
+
+  for (int m = 0; m < M; m++ )
+    LLtoXYZ( cell.coordinates_x[m], cell.coordinates_y[m], p[m]);
+
+  /* First, compute cross products Uij = Vi x Vj. */
+
+  for (int m = 0; m < M; m++ )
+    cross_product (p[m], p[(m+1)%M], u[m]);
+
+  /*  Normalize Uij to unit vectors. */
+
+  area = 0.0;
+
+  for (int m = 0; m < M; m++ ) {
+    s[m] = scalar_product(u[m], u[m]);
+    area += s[m];
+  }
+
+  /* Test for a degenerated cells associated with collinear vertices. */
+
+  if ( area != 0.0 ) {
+
+    for (int m = 0; m < M; m++ )
+      s[m] = sqrt(s[m]);
+
+    for (int m = 0; m < M; m++ )
+      for (int i = 0; i < 3; i++ )
+        u[m][i] = u[m][i]/s[m];
+
+    /*  Compute interior angles Ai as the dihedral angles between planes
+        by using the definition of the scalar product
+
+                    ab = |a| |b| cos (phi)
+
+        As a and b are already normalised this reduces to
+
+                    ab = cos (phi)
+
+        There is no explanation so far for the - in the loop below.
+        But otherwise we don't get the correct results for triangles
+        and cells. Must have something to do with the theorem.
+
+     */
+
+    for (int m = 0; m < M; m++ ) {
+      ca[m] = - scalar_product(u[m], u[(m+1)%M]);
+      if ( ca[m] < -1.0 ) ca[m] = -1.0;
+      if ( ca[m] >  1.0 ) ca[m] =  1.0;
+      a[m] = acos(ca[m]);
+    }
+
+    /*  Compute areas = a1 + a2 + a3 - (M-2) * pi.
+
+        here for a unit sphere: */
+
+    area = - (double) (M-2) * M_PI;
+
+    for (int m = 0; m < M; m++ )
+      area += a[m];
+  }
+
+  return MAX(area * EarthRadius * EarthRadius, 0.0);
+}
+
+/* ----------------------------------- */
+
+double girards_area ( struct grid_cell cell  ) {
+
+  /* Bevis and Cambareri, 1987
+
+     this algorithm provides wrong results if one
+     of the inner angles becomes less than 1e-18 rad
+
+     (R. Redler, M. Hanke 2013)
+  */
+
+  int m;
+  const double tol = 1e-18;
+  double area = 0.0;
+
+  int M = cell.num_corners;
+  if (M < 3) return area;  // a degenerate cell
+
+  double * theta = malloc ( M * sizeof(theta[0]) );
+
+  for ( m = 0; m < M; m++ ) {
+     theta[m] = partial_area(cell.coordinates_x[(m+1)%M], cell.coordinates_y[(m+1)%M],
+                             cell.coordinates_x[(m+2)%M], cell.coordinates_y[(m+2)%M],
+                             cell.coordinates_x[m%M], cell.coordinates_y[m%M]);
+     if ( theta[m] < tol ) {
+       area = cell3d_area ( cell );
+       return area;
+     }
+  }
+
+  /*  Sum up partial areas */
+
+  area = - (double) (M-2) * M_PI;
+
+  for ( m = 0; m < M; m++ )
+    area += theta[m];
+
+  /* Area on Sphere with radius EarthRadius */
+
+  area *= EarthRadius * EarthRadius;
+
+  free ( theta );
+
+  if ( area <= 0.0 ) area = cell3d_area ( cell );
+
+  return area;
+}
+
+/* ----------------------------------- */
+
+double cell3d_area( struct grid_cell cell ) {
+
+   /* http://geomalgorithms.com/a01-_area.html */
+
+   int const M = cell.num_corners;
+   double area = 0.0;
+
+   if (M < 3) return 0.0;  // a degenerated cell
+
+   double an, ax, ay, az; // abs value of normal and its coords
+
+   int  coord;           // coord to ignore: 1=x[1], 2=x[2], 3=x[3]
+
+   double V[cell.num_corners][3];
+   double Norm[3];
+   double edge[2][3];
+
+   /* transform vertices into cartesian coordinates on the earth surface
+      must be done already here to avoid round-off errors later */
+   for (int i = 0; i < M; i++ )
+      LLtoXYZ( cell.coordinates_x[i], cell.coordinates_y[i], V[i]);
+
+   /* compute normal vector */
+   edge[0][0] = V[0][0] - V[1][0];
+   edge[0][1] = V[0][1] - V[1][1];
+   edge[0][2] = V[0][2] - V[1][2];
+   edge[1][0] = V[0][0] - V[2][0];
+   edge[1][1] = V[0][1] - V[2][1];
+   edge[1][2] = V[0][2] - V[2][2];
+
+   cross_product(edge[0], edge[1], Norm);
+
+   /* select largest abs coordinate to ignore for projection */
+   ax = (Norm[0]>0 ? Norm[0] : -Norm[0]);    // abs x-coord
+   ay = (Norm[1]>0 ? Norm[1] : -Norm[1]);    // abs y-coord
+   az = (Norm[2]>0 ? Norm[2] : -Norm[2]);    // abs z-coord
+
+   coord = 3;                    // ignore z-coord x[2]
+   if (ax > ay) {
+       if (ax > az) coord = 1;   // ignore x-coord x[0]
+   }
+   else if (ay > az) coord = 2;  // ignore y-coord x[1]
+
+   /* compute area of the 2D projection
+
+      fabs is used to remain independent from
+      cyclic or anticyclic ordering of vertices */
+
+   for (int i = 1; i<M; i++) {
+        switch (coord) {
+          case 1:
+            area += fabs(V[i%M][1] * (V[(i+1)%M][2] - V[(i-1)%M][2]));
+            continue;
+          case 2:
+            area += fabs(V[i%M][0] * (V[(i+1)%M][2] - V[(i-1)%M][2]));
+            continue;
+          case 3:
+            area += fabs(V[i%M][0] * (V[(i+1)%M][1] - V[(i-1)%M][1]));
+            continue;
+        }
+    }
+    switch (coord) {    // wrap-around term
+      case 1:
+        area += fabs(V[0][1] * (V[1][2] - V[M-1][2]));
+        break;
+      case 2:
+        area += fabs(V[0][0] * (V[1][2] - V[M-1][2]));
+        break;
+      case 3:
+        area += fabs(V[0][0] * (V[1][1] - V[M-1][1]));
+        break;
+    }
+
+    /* scale to get area before projection */
+    an = sqrt( ax*ax + ay*ay + az*az); // length of normal vector
+    switch (coord) {
+      case 1:
+        if ( ax > 0 )
+                area *= (an / (2*ax));
+        else
+          area = 0.0;
+              break;
+      case 2:
+        if ( ay > 0 )
+          area *= (an / (2*ay));
+        else
+          area = 0.0;
+              break;
+      case 3:
+        if ( az > 0 )
+          area *= (an / (2*az));
+        else
+          area = 0.0;
+        break;
+    }
+
+    return area * EarthRadius * EarthRadius;
+}
+
+/** area of a spherical triangle based on L'Huilier's Theorem
+  *
+  * source code is taken from code by Robert Oehmke of Earth System Modeling
+  * Framework (www.earthsystemmodeling.org)
+  *
+  * it has been extended by a more accurate computation of vector angles
+  *
+  * the license statement for this routine is as follows:
+  * Earth System Modeling Framework
+  * Copyright 2002-2013, University Corporation for Atmospheric Research,
+  * Massachusetts Institute of Technology, Geophysical Fluid Dynamics
+  * Laboratory, University of Michigan, National Centers for Environmental
+  * Prediction, Los Alamos National Laboratory, Argonne National Laboratory,
+  * NASA Goddard Space Flight Center.
+  * Licensed under the University of Illinois-NCSA License.
+  */
+static double
+tri_area(double u[3], double v[3], double w[3]) {
+
+  double a = get_vector_angle(u,v);
+  double b = get_vector_angle(u,w);
+  double c = get_vector_angle(w,v);
+
+  double s=0.5*(a+b+c);
+
+  double t = tan ( s / 2.0 ) * tan ( ( s - a ) / 2.0 ) *
+             tan ( ( s - b ) / 2.0 ) * tan ( ( s - c ) / 2.0 );
+
+  return fabs ( 4.0 * atan ( sqrt (fabs ( t ) ) ) );;
+}
+
+double pole_area ( struct grid_cell cell ) {
+
+  double area = 0.0;
+
+  int M = cell.num_corners;
+
+  if (M < 2) return 0.0;
+
+  int closer_to_south_pole = cell.coordinates_y[0] < 0;
+
+  double pole_vec[3] = {0, 0, (closer_to_south_pole)?-1:1};
+
+  // it would also be possible to use the equator instead
+  // of the poles as the baseline
+  // this could be used as special case for cell close
+  // the equator (were the other method is probably most
+  // inaccurate)
+
+  for (int i = 0; i < M; ++i) {
+
+    // if one of the points it at the pole
+    if (fabs(fabs(cell.coordinates_y[i]) - M_PI_2) < 1e-12) continue;
+    if (fabs(fabs(cell.coordinates_y[(i+1)%M]) - M_PI_2) < 1e-12) {
+      ++i; // we can skip the next edge
+      continue;
+    }
+
+    if (cell.edge_type[i] == GREAT_CIRCLE || cell.edge_type[i] == LON_CIRCLE) {
+
+      double a[3];
+      double b[3];
+
+      LLtoXYZ(cell.coordinates_x[i], cell.coordinates_y[i], a);
+      LLtoXYZ(cell.coordinates_x[(i+1)%M], cell.coordinates_y[(i+1)%M], b);
+
+      double edge_direction = a[0]*b[1]-a[1]*b[0]; // 3. component of cross product
+
+      // if the edge is nearly on a circle of longitude
+      if (fabs(edge_direction) < 1e-12) continue;
+
+      double tmp_area = tri_area(a, b, pole_vec);
+
+      // or the other way round
+      if (edge_direction > 0) area -= tmp_area;
+      else                    area += tmp_area;
+
+    } else if (cell.edge_type[i] == LAT_CIRCLE) {
+
+      // the area of a sphere cap is:
+      // A = 2 * PI * r * h (where r == 1 and h == 1 - cos(d_lat))
+      // scaled with the longitude angle this is:
+      // A' = (d_lon / (2 * PI)) * A
+      // => A' = d_lon * (1 - cos(d_lat))
+
+      double d_lon = get_angle(cell.coordinates_x[i], cell.coordinates_x[(i+1)%M]);
+      double d_lat = M_PI_2;
+
+      if (closer_to_south_pole)
+        d_lat += cell.coordinates_y[i];
+      else
+        d_lat -= cell.coordinates_y[i];
+
+      double h = 1 - cos(d_lat);
+
+      area += d_lon * h;
+
+    } else {
+
+      abort_message("ERROR: unsupported edge type\n", __FILE__, __LINE__);
+    }
+  }
+  return fabs(area * EarthRadius * EarthRadius);
+}
+
+static double
+lat_edge_correction(double a[3], double b[3], double lon_a, double lon_b) {
+
+  double const tol = 1e-8;
+
+  if (fabs(a[2] - b[2]) > tol)
+    abort_message("ERROR: latitude of both corners is not identical\n",
+                  __FILE__, __LINE__);
+
+  double h = fabs(a[2]);
+
+  // if we are at the equator or at a pole
+  if (h < tol || fabs(1.0 - h) < tol)
+    return 0.0;
+
+  double lat_area = fabs((1.0 - h) * get_angle(lon_a, lon_b));
+
+  double pole[3] = {0, 0, (a[2] >= 0.0)?1:-1};
+  double gc_area = tri_area(a, b, pole);
+
+  double correction = lat_area - gc_area;
+
+  if (correction < 0) return 0;
+  else return correction;
+}
+
+ /*
+  * source code is originally based on code by Robert Oehmke of Earth System Modeling
+  * Framework (www.earthsystemmodeling.org)
+  *
+  * it has be extended to support YAC data structures and two types of
+  * grid cell edges (great circle and circle of latitude)
+  */
+double huiliers_area(struct grid_cell cell) {
+
+  double tmp_points[cell.num_corners][3];
+  double const tol = 1e-8;
+
+  if (cell.num_corners < 2) return 0;
+
+  // convert lon-lat to xyz
+  for (int i = 0; i < cell.num_corners; i++)
+    LLtoXYZ(cell.coordinates_x[i], cell.coordinates_y[i], tmp_points[i]);
+
+  // sum areas around cell
+  double sum = 0.0;
+
+  for (int i = 2; i < cell.num_corners; i++)
+    sum += tri_area(tmp_points[0], tmp_points[i-1], tmp_points[i]);
+
+  // check for edges of latitude
+  unsigned num_lat_circle_edges = 0;
+  for (unsigned i = 0; i < cell.num_corners; ++i)
+    if (cell.edge_type[i] == LAT_CIRCLE)
+      num_lat_circle_edges++;
+
+  if (num_lat_circle_edges > 2)
+    abort_message("ERROR: invalid cell (has more than two edges that are "
+                  "latitude circles)\n", __FILE__, __LINE__);
+
+  if (num_lat_circle_edges > 0) {
+
+    // compute minimum and maximum height of cell
+    double min = cell.coordinates_y[0], max = cell.coordinates_y[0];
+
+    for (int i = 1; i < cell.num_corners; ++i)
+      if (cell.coordinates_y[i] < min) min = cell.coordinates_y[i];
+      else if (cell.coordinates_y[i] > max) max = cell.coordinates_y[i];
+
+    double min_factor = 1.0;
+
+    if (max <= 0.0) {
+
+      double tmp = max;
+      max = min;
+      min = tmp;
+
+    } else if (signbit(min) != signbit(max))
+      min_factor = -1.0;
+
+    for (int i = 0; i < cell.num_corners; ++i) {
+
+      if (cell.edge_type[i] == LAT_CIRCLE) {
+
+        double correction =
+          lat_edge_correction(tmp_points[i],
+                              tmp_points[(i+1)%cell.num_corners],
+                              cell.coordinates_x[i],
+                              cell.coordinates_x[(i+1)%cell.num_corners]);
+
+        if (fabs(cell.coordinates_y[i] - min) < tol)
+          sum += min_factor * correction;
+        else if (fabs(cell.coordinates_y[i] - max) < tol)
+          sum -= correction;
+        else
+          abort_message("ERROR: internal error...should have not occured\n",
+                        __FILE__, __LINE__);
+      }
+    }
+  }
+
+  // return area
+  return sum * EarthRadius * EarthRadius;
+}
+
+/* ----------------------------------- */
+
+double partial_area ( double a_lon, double a_lat,
+                      double b_lon, double b_lat,
+                      double c_lon, double c_lat ) {
+
+  double theta;
+  double angle_f;
+  double angle_b;
+
+  angle_f = inner_angle ( a_lat, a_lon, b_lat, b_lon );
+  angle_b = inner_angle ( a_lat, a_lon, c_lat, c_lon );
+
+  theta = angle_b - angle_f;
+
+  if ( theta < 0.0 ) theta = theta + M_PI + M_PI;
+
+  return theta;
+}
+
+/* ----------------------------------- */
+
+double inner_angle ( double plat, double plon, double qlat, double qlon ) {
+
+  double t = sin((qlon-plon))*cos(qlat);
+
+  double b = sin(qlat)*cos(plat)
+           - cos(qlat)*sin(plat) * cos((qlon-plon));
+
+  return atan2(b,t);
+}
+
+/* ----------------------------------- */
+
+static double scalar_product(double a[], double b[]) {
+  return (a[0] * b[0] + a[1] * b[1] + a[2] * b[2]);
+}
+
+/* ----------------------------------- */
+
+static void cross_product(double a[], double b[], double cross[]) {
+  cross[0] = a[1]*b[2] - a[2]*b[1];
+  cross[1] = a[2]*b[0] - a[0]*b[2];
+  cross[2] = a[0]*b[1] - a[1]*b[0];
+}
diff --git a/src/clipping/area.h b/src/clipping/area.h
new file mode 100644
index 0000000..e81e51c
--- /dev/null
+++ b/src/clipping/area.h
@@ -0,0 +1,255 @@
+/**
+ * @file area.h
+ *
+ * @copyright Copyright  (C)  2013 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#ifndef AREA_H
+#define AREA_H
+
+#include "grid.h"
+#include "clipping.h"
+
+/** \example test_area.c
+ * A test for different area calculations.
+ */
+
+/** \file area.h
+  * \brief Structs and interfaces for area calculations
+  *
+  **/
+
+extern const double area_tol;
+
+/** \brief Calculate the area of a cell on a sphere
+  *
+  * Taken from:
+  *
+  * http://www.psjournal.com/gis/Area-of-Polygon-on-a-Sphere-Algorithm-2534-.htm
+  *
+  * Bob (Robert G.) Chamberlain <rgc at jpl.nasa.gov>
+  *
+  * See also:
+  * Robert.G. Chamberlain, William.H. Duquette
+  * Jet Propulsion Laboratory
+  * Some Algorithms for Polygons on a Sphere.
+  * Association of American Geographers Annual Meeting San Francisco, California
+  * 17 - 21 April 2007
+  *
+  * Given a cell with N edges, each of which is a segment of a great
+  * circle. The cell must be simply connected (a single piece), without
+  * holes, and no edge may cross another. Neither pole may be inside the
+  * cell.
+  *
+  * The cell is described in a counterclockwise direction by a succession
+  * of vertices, numbered from 0 to N-1. A vertex N, if given, is identical
+  * to vertex 0. Note that "inside" and "outside" are defined by the
+  * requirement that the cell be counterclockwise. (If the cell is
+  * described in a clockwise direction, the area computed will be negative.)
+  *
+  * The location of each vertex is given by latitude and longitude. In this
+  * algorithm, latitude and longitude are expressed in radian.
+  *
+  * Latitude is zero at the equator; north is positive, south is negative.
+  * The latitude of point i is denoted by lat.i or lat.(i)
+  *
+  * Longitude is zero at Greenwich: east is positive, west is negative. The
+  * longitude of point i is denoted by lon.i or lon.(i)
+  *
+  * With the radius of the Earth denoted by R, the area of the cell,
+  * expressed in the square of the units used for R, is given by:
+  *
+  * Area = - ( R^2 / 2 ) * ( SUM )
+  *
+  * SUM = ( lon.1     - lon.(N-1) ) * sin( lat.0 )
+  *     + ( lon.2     - lon.0     ) * sin( lat.1 )
+  *     + ( lon.3     - lon.1     ) * sin( lat.2 )
+  *     + ( lon.4     - lon.2     ) * sin( lat.3 )
+  *     + ...
+  *     + ( lon.(N-1) - lon.(N-3) ) * sin( lat.(N-2) )
+  *     + ( lon.0     - lon.(N-2) ) * sin( lat.(N-1) ) 
+  *
+  * \remark This does not work for cells that include the pole.
+  *
+ **/
+
+double cell_approx_area ( struct grid_cell cell );
+
+/** \brief Calculate the area of a triangle on a sphere
+  *
+  * Adopted from the ICON code, mo_base_geometry.f90
+  * provided by Luis Kornblueh, MPI-M. 
+  *
+  * The algorithm is based on Girards' theorem and formula.
+  *
+  * Converted to c by Rene Redler, MPI-M.
+  *
+  * Vertex coordinates need to be provided as cartesian coordinates
+  *
+  *  The algorithm is based on Girards' theorem and formula.
+  *
+  *  R:  Earth radius
+  *  n:  number of vertices
+  *  pi: guess what
+  *  Theta: Sum of inner angle of the element (in rad)
+  *
+  *  The Formula reads as
+  *
+  *  S = [ Theta - (n-2) * pi ] * R*R
+  *
+  *  Ad with n=3 for triangles simplifies to
+  *
+  *  S = [ Theta - pi ] * R*R
+  *
+  *  @param[in] cell cell for which he area shal be calculated
+  *
+  *  @return approximate area of the cell
+  *
+  **/
+
+double triangle_area ( struct grid_cell cell );
+
+/** \brief Calculate the area of a cell on a sphere
+  *
+  * Generalized version of triangle_area
+  *
+  * The algorithm is based on Girards' theorem and formula.
+  *
+  * Converted to c by Rene Redler, MPI-M.
+  *
+  * Vertex coordinates need to be provided as cartesian coordinates
+  *
+  *  The algorithm is based on Girards' theorem and formula.
+  *
+  *  R:  Earth radius
+  *  n:  number of vertices
+  *  pi: guess what
+  *  Theta: Sum of inner angle of the element (in rad)
+  *
+  *  The Formula reads as
+  *
+  *  S = [ Theta - (n-2) * pi ] * R*R
+  *
+  *  @param[in] cell cell for which he area shall be calculated
+  *
+  *  @return area of the triangle
+  *
+  **/
+
+double cell_area ( struct grid_cell cell );
+
+/** \brief Calculate the area of a cell on a sphere
+  *
+  * Following M. Bevis and G. Cambareri, 1987: Computing the Area
+  *   of a Spherical Polygon of Arbitray Shape. Math. Geology,
+  *   Vol. 19, No 4, 335 - 346.
+  *
+  * The algorithm is based on Girards' theorem and formula.
+  *
+  * Converted to c and expanded for cells by Rene Redler, MPI-M.
+  *
+  * In contrast to the above simple algorithm by Chamberlain and Duquette
+  * this approach seems to work over the pole as well.
+  *
+  *  R:  Earth radius
+  *  n:  number of vertices
+  *  pi: guess what
+  *  Theta: Sum of inner angle of the element (in rad)
+  *
+  *  The Formula reads as
+  *
+  *  S = [ Theta - (n-2) * pi ] * R*R
+  *
+  *  \todo
+  *  - implement an alternative for very small elements
+  *
+  *  This algorithm does not work for very small elements. In this case negative
+  *  areas are delivered which are set to zero currently. An alternative would be
+  *  to transform the coordinates into the cartesian space, ignore the curvature
+  *  of the edges (as they can be neglected for small elements) and calculate the
+  *  area of a plane triangle.
+  *
+  *  http://www.mathopenref.com/coordpolygonarea2.html \n
+  *  http://geomalgorithms.com/a01-_area.html \n
+  *  http://stackoverflow.com/questions/2350604/get-the-area-of-a-3d-surface
+  *  
+  *  @param[in] cell cell for which the area shall be calculated
+  *
+  *  @return area of the cell
+  *
+  **/
+double girards_area ( struct grid_cell cell );
+
+/** \brief Calculate the area of a cell in a 3d plane
+  *
+  *  see http://geomalgorithms.com/a01-_area.html
+  *
+  *  other references:
+  *
+  *  http://www.mathopenref.com/coordpolygonarea2.html \n
+  *  http://geomalgorithms.com/a01-_area.html \n
+  *  http://stackoverflow.com/questions/2350604/get-the-area-of-a-3d-surface
+  *
+  *  @param[in] cell cell for which the area shall be calculated
+  *
+  *  @return area of the cell
+  *
+  **/
+
+double cell3d_area( struct grid_cell cell );
+
+/** \brief Calculate the area of a cell on a sphere
+  *
+  * based on:
+  *
+  * Robert.G. Chamberlain, William.H. Duquette
+  * Jet Propulsion Laboratory
+  * Some Algorithms for Polygons on a Sphere.
+  * Association of American Geographers Annual Meeting San Francisco, California
+  * 17 - 21 April 2007
+  * http://trs-new.jpl.nasa.gov/dspace/bitstream/2014/40409/1/07-03.pdf
+  *
+  * uses different formula to compute the area of the pole triangles
+  *
+  * \todo enable routine to be able to handle latitude circle edges
+  */
+double pole_area ( struct grid_cell cell );
+
+/**
+  * \brief Area calculation taken from ESMF based on L'Huilier's Theorem
+  *
+  * (http://mathworld.wolfram.com/LHuiliersTheorem.html)\n
+  * (http://mathforum.org/library/drmath/view/65316.html)\n
+  * (http://math.stackexchange.com/questions/9819/area-of-a-spherical-triangle)
+  *
+  * The cell in split up into triangles that all have one corner in common,
+  * then the area for each of the triangle is computed and summed up to build
+  * the area of the cell. L'Huilier's Theorem is used to compute the area of
+  * the triangles.
+  */
+double huiliers_area(struct grid_cell cell);
+
+#endif // AREA_H
diff --git a/src/clipping/clipping.c b/src/clipping/clipping.c
new file mode 100644
index 0000000..f1bcdf2
--- /dev/null
+++ b/src/clipping/clipping.c
@@ -0,0 +1,1026 @@
+/**
+ * @file clipping.c
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "geometry.h"
+#include "clipping.h"
+#include "area.h"
+#include "ensure_array_size.h"
+#include "utils.h"
+
+//#define VERBOSE
+
+static double const tol = 1.0e-12;
+
+enum cell_type {
+  LON_LAT_CELL,
+  GREAT_CIRCLE_CELL,
+  MIXED_CELL
+};
+
+struct point_list_element {
+
+  double vec_coords[3];
+  enum edge_type edge_type; // type of edge with next corner
+  int to_be_removed;
+  struct point_list_element * next;
+};
+
+struct point_list {
+
+  struct point_list_element * first;
+  struct point_list_element * last;
+  struct point_list_element * free_elements;
+};
+
+/* internal helper routines for working with linked lists of points */
+
+static void init_point_list(struct point_list * list);
+
+static void reset_point_list(struct point_list * list);
+
+static void generate_point_list(struct point_list * list, struct grid_cell cell);
+
+static struct point_list_element *
+get_free_point_list_element(struct point_list * list);
+
+static void remove_points(struct point_list * list);
+
+static void free_point_list(struct point_list * list);
+
+static unsigned get_cell_points_ordering(struct point_list * cell);
+
+static void generate_overlap_cell(struct point_list * list,
+                                  struct grid_cell * cell);
+
+/* ------------------------- */
+
+void compute_overlap_areas(unsigned N,
+                           struct grid_cell * source_cell,
+                           struct grid_cell target_cell,
+                           double * partial_areas) {
+
+  static struct grid_cell * overlap_buffer = NULL;
+  static unsigned overlap_buffer_size = 0;
+
+  // ensure that there are enough buffer cells
+
+  if (overlap_buffer_size < N) {
+
+    unsigned old_overlap_buffer_size = overlap_buffer_size;
+
+    ENSURE_ARRAY_SIZE(overlap_buffer, overlap_buffer_size, N);
+
+    for (; old_overlap_buffer_size < overlap_buffer_size;
+         ++old_overlap_buffer_size)
+      init_grid_cell(overlap_buffer + old_overlap_buffer_size);
+  }
+
+  /* Do the clipping and get the cell for the overlapping area */
+
+  cell_clipping ( N, source_cell, target_cell, overlap_buffer);
+
+  /* Get the partial areas for the overlapping regions */
+
+  for (unsigned n = 0; n < N; n++) {
+    partial_areas[n] = huiliers_area (overlap_buffer[n]);
+    free_grid_cell(overlap_buffer + n);
+  }
+
+#ifdef VERBOSE
+  for (unsigned n = 0; n < N; n++)
+    printf("overlap area : %lf\n", partial_areas[n]);
+#endif
+}
+
+/* ------------------------- */
+
+static void crossproduct (double a[], double b[], double cross[]) {
+
+/* cross-product in cartesian coordinates */
+
+  cross[0] = a[1] * b[2] - a[2] * b[1];
+  cross[1] = a[2] * b[0] - a[0] * b[2];
+  cross[2] = a[0] * b[1] - a[1] * b[0];
+}
+
+static double dotproduct(double a[], double b[]) {
+
+  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+}
+
+static void compute_norm_vector(double a[], double b[], double norm[]) {
+
+  crossproduct(a, b, norm);
+
+  if ((fabs(norm[0]) < tol) &&
+      (fabs(norm[1]) < tol) &&
+      (fabs(norm[2]) < tol))
+    abort_message("ERROR: a and b are identical -> no norm vector\n",
+                  __FILE__, __LINE__);
+
+  double scale = 1.0 / sqrt(norm[0] * norm[0] + norm[1] * norm[1] + norm[2] * norm[2]);
+
+  norm[0] *= scale;
+  norm[1] *= scale;
+  norm[2] *= scale;
+}
+
+static void compute_lat_circle_z_value(double a[], double b[], double z[]) {
+
+  double temp[3];
+
+  crossproduct(a, b, temp);
+
+  z[0] = 0;
+  z[1] = 0;
+
+  if (temp[2] > 0)
+    z[2] = 1.0 - a[2];
+  else
+    z[2] = -1.0 - a[2];
+}
+
+/**
+ * Determines whether a given point is on a hemisphere that is defined by a plane
+ * through the middle of the sphere.\n
+ * The plane is defined by its norm vector.
+ * @param[in] point point to be checked
+ * @param[in] norm_vec norm vector of the plane dividing the sphere
+ * @returns  0 if the point is not inside the hemisphere
+ *           1 if the point is inside the hemisphere
+ *           2 if the point is in the plane
+ */
+static unsigned is_inside_gc(double point[], double norm_vec[]) {
+
+  double dot;
+
+  // the product is defined as follows
+  // a * b = |a| * |b| * cos(alpha)
+  // where alpha is the angle between a and b
+
+  dot = dotproduct(point, norm_vec);
+
+  // if the point is on the line
+  if (fabs(dot) < tol)
+    return 2;
+
+  return dot < 0;
+}
+
+static unsigned is_inside_latc(double point[], double z) {
+
+  double temp = fabs(point[2] + z);
+
+  if (fabs(1.0 - temp) < tol) return 2;
+  else return temp < 1.0;
+}
+
+static unsigned is_inside(double point[], double help_vec[],
+                          enum edge_type edge_type,
+                          unsigned cell_points_ordering) {
+
+  unsigned ret_val = 0;
+
+  switch (edge_type) {
+
+    case (LON_CIRCLE) :
+    case (GREAT_CIRCLE) :
+      ret_val = is_inside_gc(point, help_vec);
+      break;
+    case (LAT_CIRCLE) :
+      ret_val = is_inside_latc(point, help_vec[2]);
+      break;
+    default:
+      abort_message("invalid edge type\n", __FILE__, __LINE__);
+  };
+
+  if (ret_val == 2) return 2;
+  else return ret_val ^ cell_points_ordering;
+}
+
+static enum cell_type get_cell_type(struct grid_cell target_cell) {
+
+   if ((target_cell.num_corners == 4) &&
+       ((target_cell.edge_type[0] == LAT_CIRCLE &&
+         target_cell.edge_type[1] == LON_CIRCLE &&
+         target_cell.edge_type[2] == LAT_CIRCLE &&
+         target_cell.edge_type[3] == LON_CIRCLE) ||
+        (target_cell.edge_type[0] == LON_CIRCLE &&
+         target_cell.edge_type[1] == LAT_CIRCLE &&
+         target_cell.edge_type[2] == LON_CIRCLE &&
+         target_cell.edge_type[3] == LAT_CIRCLE)))
+      return LON_LAT_CELL;
+   else
+      for (unsigned i = 0; i < target_cell.num_corners; ++i)
+         if (target_cell.edge_type[i] != LON_CIRCLE &&
+             target_cell.edge_type[i] != GREAT_CIRCLE)
+            return MIXED_CELL;
+
+   return GREAT_CIRCLE_CELL;
+}
+
+/**
+ * cell clipping using Sutherland–Hodgman algorithm;
+ */
+void cell_clipping(unsigned N,
+                   struct grid_cell * source_cell,
+                   struct grid_cell target_cell,
+                   struct grid_cell * overlap_buffer) {
+
+  unsigned ncs;               /* number of vertices of source cell */
+  unsigned nct;               /* number of vertices of target cell */
+
+  struct point_list target_list, source_list;
+
+  unsigned target_ordering; /* ordering of target cell corners */
+  unsigned source_ordering; /* ordering of source cell corners */
+
+  double * norm_vec; /* norm vector for temporary target edge plane */
+
+  nct = target_cell.num_corners;
+
+  enum cell_type tgt_cell_type = get_cell_type(target_cell);
+
+  if (tgt_cell_type == MIXED_CELL)
+    abort_message("invalid target cell type (cell contains edges consisting "
+                  "of great circles and circles of latitude)\n", __FILE__,
+                  __LINE__);
+
+  // generate point list for target cell (clip cell)
+  init_point_list(&target_list);
+  generate_point_list(&target_list, target_cell);
+
+  // if there is no target cell (e.g. if all edges of target cell have a length
+  // of zero)
+  if (target_list.first == NULL) {
+    free_point_list(&target_list);
+    return;
+  }
+
+  struct point_list_element * prev_tgt_point = target_list.first;
+  struct point_list_element * curr_tgt_point = target_list.first->next;
+
+  norm_vec = malloc(3 * nct * sizeof(*norm_vec));
+
+  // compute norm vectors for all edges
+  // or for lat circle edges a special z value
+  for (unsigned i = 0; i < nct; ++i) {
+
+    switch (prev_tgt_point->edge_type) {
+
+      case (LON_CIRCLE) :
+      case (GREAT_CIRCLE) :
+        compute_norm_vector(prev_tgt_point->vec_coords, curr_tgt_point->vec_coords,
+                            norm_vec + 3 * i);
+        break;
+      case (LAT_CIRCLE):
+        compute_lat_circle_z_value(prev_tgt_point->vec_coords, curr_tgt_point->vec_coords,
+                            norm_vec + 3 * i);
+        break;
+      default:
+        abort_message("invalid edge type\n", __FILE__, __LINE__);
+    };
+    prev_tgt_point = curr_tgt_point;
+    curr_tgt_point = curr_tgt_point->next;
+  }
+
+  // compute target direction
+  target_ordering = get_cell_points_ordering(&target_list);
+
+  init_point_list(&source_list);
+
+  // for all source cells
+  for (unsigned n = 0; n < N; n++ ) {
+
+    if (get_cell_type(source_cell[n]) == MIXED_CELL)
+      abort_message("invalid source cell type (cell contains edges consisting "
+                    "of great circles and circles of latitude)\n", __FILE__,
+                    __LINE__);
+
+    ncs = source_cell[n].num_corners;
+
+    if (ncs < 2)
+      continue;
+
+    // generate point list for current source list
+    generate_point_list(&source_list, source_cell[n]);
+
+    // compute source direction
+    source_ordering = get_cell_points_ordering(&source_list);
+
+    prev_tgt_point = target_list.first;
+    curr_tgt_point = target_list.first->next;
+
+    for (int i = 0; i < nct; ++i) {
+
+      struct point_list_element * curr_src_point = source_list.first;
+      struct point_list_element * prev_src_point = source_list.last;
+
+      unsigned prev_is_inside, curr_is_inside;
+
+      prev_is_inside = is_inside(prev_src_point->vec_coords, norm_vec + 3 * i,
+                                 prev_tgt_point->edge_type, target_ordering);
+
+      // for all edges of the target cell
+      do {
+
+        curr_is_inside = is_inside(curr_src_point->vec_coords, norm_vec + 3 * i,
+                                   prev_tgt_point->edge_type, target_ordering);
+
+        // if the current edges change from inside/outside to outside/inside
+        if (((curr_is_inside == 0) ^ (prev_is_inside == 0)) &&
+            ((curr_is_inside != 2) && (prev_is_inside != 2))) {
+
+          double p[3], q[3];
+          int intersect;
+
+          struct point_list_element * intersect_point;
+
+          // if the previous point was inside or current edge is the last one
+          if (prev_is_inside ||
+              (curr_is_inside && (prev_src_point == source_list.last))) {
+
+            intersect_point = get_free_point_list_element(&source_list);
+            prev_src_point->next = intersect_point;
+            intersect_point->next = curr_src_point;
+
+            if (prev_src_point == source_list.last)
+              source_list.last = intersect_point;
+
+          } else
+            intersect_point = prev_src_point;
+
+          // get intersection points
+          intersect = intersect_vec(prev_src_point->edge_type,
+                                    prev_src_point->vec_coords,
+                                    curr_src_point->vec_coords,
+                                    prev_tgt_point->edge_type,
+                                    prev_tgt_point->vec_coords,
+                                    curr_tgt_point->vec_coords,
+                                    p, q);
+
+          // if there is an intersection
+          if (intersect != -1) {
+
+            // if both edges are on an identical great circle
+            if (intersect & (1 << 4))
+              abort_message("ERROR: edges on identical circle, this case should"
+                            " have been handled somewhere else\n", __FILE__, __LINE__);
+
+            // if there are two intersection points with the source edge
+            if ((intersect & ((1 << 0) | (1 << 1))) == ((1 << 0) | (1 << 1))) {
+
+              abort_message("ERROR: more than one intersections with the "
+                            "source edges", __FILE__, __LINE__);
+
+            // if p or q is on the source edge
+            } else {
+
+              if (prev_is_inside)
+                intersect_point->edge_type = prev_tgt_point->edge_type;
+              else
+                intersect_point->edge_type = prev_src_point->edge_type;
+
+              if (intersect & (1 << 0)) {
+
+                intersect_point->vec_coords[0] = p[0];
+                intersect_point->vec_coords[1] = p[1];
+                intersect_point->vec_coords[2] = p[2];
+
+              // if q is on the source edge
+              } else if (intersect & (1 << 1)) {
+
+                intersect_point->vec_coords[0] = q[0];
+                intersect_point->vec_coords[1] = q[1];
+                intersect_point->vec_coords[2] = q[2];
+
+              } else {
+
+              for (int i = 0; i < source_cell[n].num_corners; ++i) {
+                fprintf(stderr, "src: %d, %lf, %lf\n", i,
+                        source_cell[n].coordinates_x[i],
+                        source_cell[n].coordinates_y[i]);
+              }
+
+              for (int i = 0; i < target_cell.num_corners; ++i) {
+                fprintf(stderr, "tgt: %d, %lf, %lf\n", i,
+                        target_cell.coordinates_x[i],
+                        target_cell.coordinates_y[i]);
+              }
+
+                abort_message("ERROR: no intersection with source edge was found\n",
+                              __FILE__, __LINE__);
+              }
+            }
+          }
+
+          if (intersect_point == prev_src_point)
+            prev_is_inside = 1;
+
+        // if the one edge is a circle of latitude while the other is not
+        // and both corners are not directly on the edge
+        } else if (((prev_src_point->edge_type == LAT_CIRCLE) ^
+                    (prev_tgt_point->edge_type == LAT_CIRCLE)) && 
+                   !((prev_is_inside == 2) && (curr_is_inside == 2))) {
+
+          double p[3], q[3];
+          int intersect;
+
+          // get intersection points
+          intersect = intersect_vec(prev_src_point->edge_type,
+                                    prev_src_point->vec_coords,
+                                    curr_src_point->vec_coords,
+                                    prev_tgt_point->edge_type,
+                                    prev_tgt_point->vec_coords,
+                                    curr_tgt_point->vec_coords,
+                                    p, q);
+
+          // if there is an intersection possible
+          if (intersect != -1) {
+
+            // if both edges are on an identical great circle
+            if (intersect & (1 << 4))
+              abort_message("ERROR: edges on identical circle, this case should"
+                            " have been handled somewhere else\n", __FILE__, __LINE__);
+
+            // if there are two intersection points with the source edge
+            if ((intersect & ((1 << 0) | (1 << 1))) == ((1 << 0) | (1 << 1))) {
+
+              struct point_list_element * intersect_points[2];
+
+              // if the previous point was inside or current edge is the last one
+              if ((prev_is_inside || prev_src_point == source_list.last) &&
+                  (prev_is_inside != 2)) {
+
+                intersect_points[0] = get_free_point_list_element(&source_list);
+                prev_src_point->next = intersect_points[0];
+                intersect_points[0]->next = curr_src_point;
+
+                if (prev_src_point == source_list.last)
+                  source_list.last = intersect_points[0];
+
+              } else {
+                intersect_points[0] = prev_src_point;
+                intersect_points[0]->to_be_removed = 0;
+              }
+
+              // second intersection point
+              intersect_points[1] = get_free_point_list_element(&source_list);
+
+              if (intersect_points[0] == source_list.last)
+                source_list.first = intersect_points[1];
+
+              intersect_points[1]->next = intersect_points[0]->next;
+              intersect_points[0]->next = intersect_points[1];
+
+              int p_is_first = get_vector_angle(prev_src_point->vec_coords, p) <
+                               get_vector_angle(prev_src_point->vec_coords, q);
+              enum edge_type prev_src_point_edge_type =
+                prev_src_point->edge_type;
+
+              intersect_points[!p_is_first]->vec_coords[0] = p[0];
+              intersect_points[!p_is_first]->vec_coords[1] = p[1];
+              intersect_points[!p_is_first]->vec_coords[2] = p[2];
+              intersect_points[p_is_first]->vec_coords[0] = q[0];
+              intersect_points[p_is_first]->vec_coords[1] = q[1];
+              intersect_points[p_is_first]->vec_coords[2] = q[2];
+              intersect_points[(prev_is_inside != 0) &&
+                               (curr_is_inside != 0)]->edge_type =
+                prev_src_point->edge_type;
+              intersect_points[(prev_is_inside == 0) ||
+                               (curr_is_inside == 0)]->edge_type =
+                prev_tgt_point->edge_type;
+
+              int tgt_edge_inside_src;
+
+              if ((prev_is_inside + curr_is_inside == 3) ||
+                  (prev_is_inside == 0 && curr_is_inside == 2)) {
+
+                double norm_vec[3];
+
+                switch (prev_src_point_edge_type) {
+
+                  case (LON_CIRCLE) :
+                  case (GREAT_CIRCLE) :
+                    compute_norm_vector(prev_src_point->vec_coords,
+                                        curr_src_point->vec_coords,
+                                        norm_vec);
+                    break;
+                  case (LAT_CIRCLE):
+                    compute_lat_circle_z_value(prev_src_point->vec_coords,
+                                               curr_src_point->vec_coords,
+                                               norm_vec);
+                    break;
+                  default:
+                    abort_message("invalid edge type\n", __FILE__, __LINE__);
+                };
+
+                tgt_edge_inside_src =
+                  (is_inside(prev_tgt_point->vec_coords, norm_vec,
+                             prev_src_point_edge_type, source_ordering) == 1) ||
+                  (is_inside(curr_tgt_point->vec_coords, norm_vec,
+                             prev_src_point_edge_type, source_ordering) == 1);
+              }
+
+              // if one source point is on the target edge and the other is inside
+              if (prev_is_inside + curr_is_inside == 3) {
+
+                // if the current source point is on the target edge, then the
+                // second intersection point is just a dummy that is identical
+                // to the current source point but might have the wrong edge
+                // type
+                if (curr_is_inside == 2)
+                  intersect_points[1]->to_be_removed = 1;
+
+                if (curr_is_inside == 2 && tgt_edge_inside_src)
+                  curr_src_point->to_be_removed = 1;
+                if (prev_is_inside == 2 && tgt_edge_inside_src)
+                  prev_src_point->to_be_removed = 1;
+              }
+              if (prev_is_inside == 0 && curr_is_inside == 2) {
+                if (tgt_edge_inside_src)
+                  intersect_points[1]->to_be_removed = 1;
+                else
+                  curr_src_point->to_be_removed = 1;
+              }
+
+              // if the previous point has been reused for an intersection
+              if (intersect_points[0] == prev_src_point)
+                prev_is_inside = 1;
+
+            // if there is only one intersection point
+            } else if (((intersect & ((1 << 0) || (1 << 1))) != 0) &&
+                       (curr_is_inside != 2) && (prev_is_inside != 2)) {
+            
+                abort_message("ERROR: one intersection with source edge. this should"
+                              " not have happened\n", __FILE__, __LINE__);
+            }
+          }
+
+        // if the one edge is a circle of latitude while the other is not
+        // and both corners are directly on the edge
+        } else if (((prev_src_point->edge_type == LAT_CIRCLE) ^
+                    (prev_tgt_point->edge_type == LAT_CIRCLE)) && 
+                   (prev_is_inside == 2) && (curr_is_inside == 2)) {
+
+          double cross_src_z, cross_tgt_z;
+
+          cross_src_z = prev_src_point->vec_coords[0] *
+                        curr_src_point->vec_coords[1] -
+                        prev_src_point->vec_coords[1] *
+                        curr_src_point->vec_coords[0];
+          cross_tgt_z = prev_tgt_point->vec_coords[0] *
+                        curr_tgt_point->vec_coords[1] -
+                        prev_tgt_point->vec_coords[1] *
+                        curr_tgt_point->vec_coords[0];
+
+          int same_ordering = source_ordering == target_ordering;
+          int same_direction = (cross_src_z > 0) == (cross_tgt_z > 0);
+
+          // if source and target cell have the same ordering and both
+          // edges have the same direction or if both cells have different
+          // ordering and the edges have different directions, then we might
+          // have to change the edge type of the source edge
+          if (same_ordering == same_direction) {
+
+            // well...it works...do not ask  ;-)
+            // ((edge is on south hemisphere) XOR (direction of source edge) XOR
+            //  (ordering of source cell))
+            if ((curr_src_point->vec_coords[2] > 0) ^
+                (cross_src_z < 0) ^ source_ordering)
+              prev_src_point->edge_type = LAT_CIRCLE;
+            else
+              prev_src_point->edge_type = GREAT_CIRCLE;
+          }
+        }
+
+        // if the previous points was on the target edge and the current
+        // one is outside
+        if (prev_is_inside == 2 && curr_is_inside == 0)
+          prev_src_point->edge_type = prev_tgt_point->edge_type;
+
+        if (!prev_is_inside)
+          prev_src_point->to_be_removed = 1;
+
+        prev_src_point = curr_src_point;
+        curr_src_point = curr_src_point->next;
+        prev_is_inside = curr_is_inside;
+
+      } while ((prev_src_point != source_list.last) &&
+               (source_list.first != NULL));
+
+      // remove all points that are to be deleted
+      remove_points(&source_list);
+
+      // if there are no more corners in the source cell
+      if (source_list.first == NULL) break;
+
+      prev_tgt_point = curr_tgt_point;
+      curr_tgt_point = curr_tgt_point->next;
+    }
+
+    if (source_list.first != NULL)
+      generate_overlap_cell(&source_list, overlap_buffer + n);
+  }
+
+  free(norm_vec);
+  free_point_list(&source_list);
+  free_point_list(&target_list);
+}
+
+/* ---------------------------------------------------- */
+
+void correct_weights ( unsigned nSourceCells, double * weight ) {
+
+  static unsigned maxIter = 10; // number of iterations to get better accuracy of the weights
+  static double const tol = 1.0e-15;
+
+  unsigned n;
+  unsigned iter;
+
+  double weight_diff;
+
+  for ( iter = 1; iter < maxIter; iter++ ) {
+
+    weight_diff = 1.0;
+
+    for ( n = 0; n < nSourceCells; n++ )
+      weight_diff -= weight[n];
+
+#ifdef VERBOSE
+    printf ("weight sum is %.15f \n", weight_sum); 
+    printf ("weights are  "); 
+    for (unsigned i = 0; i < nSourceCells; ++i)
+      printf (" %.15f", weight[i]); 
+    printf("\n");
+#endif
+
+    if ( fabs(weight_diff) < tol ) break;
+
+    for ( n = 0; n < nSourceCells; n++ )
+      weight[n] += weight[n] * weight_diff;
+  }
+#ifdef VERBOSE
+  if ( fabs(weight_diff) > tol )
+    printf ("weight sum is %.15f \n", weight_sum);
+#endif
+}
+
+/* ---------------------------------------------------- */
+
+static unsigned get_cell_points_ordering(struct point_list * cell) {
+
+  if ((cell->first == NULL) || (cell->first == cell->last))
+    abort_message("ERROR: invalid cell\n", __FILE__, __LINE__);
+
+  double norm_vec[3];
+  struct point_list_element * curr = cell->first;
+
+  compute_norm_vector(curr->vec_coords, curr->next->vec_coords, norm_vec);
+
+  curr = curr->next;
+
+  if (curr->next == cell->first)
+    abort_message("ERROR: invalid cell\n", __FILE__, __LINE__);
+
+  do {
+    curr = curr->next;
+
+    double dot = dotproduct(curr->vec_coords, norm_vec);
+
+    if (fabs(dot) > tol)
+      return dot > 0;
+
+  } while (curr != cell->first);
+
+  abort_message("ERROR: could not determine order of points in cell\n",
+                __FILE__, __LINE__);
+
+  return -1;
+}
+
+static void init_point_list(struct point_list * list) {
+
+  list->first = NULL;
+  list->last = NULL;
+  list->free_elements = NULL;
+}
+
+static void reset_point_list(struct point_list * list) {
+
+  if (list->first != NULL) {
+
+    list->last->next = list->free_elements;
+    list->free_elements = list->first;
+
+    list->first = NULL;
+    list->last = NULL;
+  } else
+    list->last = NULL;
+}
+
+static void remove_points(struct point_list * list) {
+
+  struct point_list_element * curr = list->first;
+  struct point_list_element * prev;
+  struct point_list_element * remaining_points = NULL;
+
+  if (curr == NULL) return;
+
+  unsigned num_edges = 1;
+
+  while (curr != list->last) {
+
+    curr = curr->next;
+    num_edges++;
+  }
+
+  for (unsigned i = 0; i < num_edges; ++i) {
+
+    prev = curr;
+    curr = curr->next;
+
+    if (curr->to_be_removed) {
+      prev->next = curr->next;
+      curr->next = list->free_elements;
+      list->free_elements = curr;
+      curr = prev;
+    } else
+      remaining_points = curr;
+  }
+
+  if ((remaining_points != NULL) &&
+      (remaining_points == remaining_points->next)) {
+
+    remaining_points->next = list->free_elements;
+    list->free_elements = remaining_points;
+    remaining_points = NULL;
+  }
+
+  list->last = remaining_points;
+  if (remaining_points != NULL)
+    list->first = remaining_points->next;
+  else
+    list->first = NULL;
+}
+
+//! returns number of edges/corners
+static unsigned remove_zero_length_edges(struct point_list * list) {
+
+#define DOT_PRODUCT(a,b) (a->vec_coords[0] * b->vec_coords[0] + \
+                          a->vec_coords[1] * b->vec_coords[1] + \
+                          a->vec_coords[2] * b->vec_coords[2])
+
+  struct point_list_element * curr = list->first;
+  double const tol = 1e-8;
+
+  if (curr == NULL) return 0;
+
+  unsigned num_edges = 1;
+  unsigned temp_num_edges;
+
+  while (curr != list->last) {
+
+    curr = curr->next;
+    num_edges++;
+  }
+
+  temp_num_edges = num_edges;
+
+  for (unsigned i = 0; i < num_edges; ++i) {
+
+    // if both points are nearly identical (angle between them is very small)
+    if (get_vector_angle(curr->vec_coords, curr->next->vec_coords) < tol) {
+      curr->to_be_removed = 1;
+      temp_num_edges--;
+    }
+
+    curr = curr->next;
+  }
+
+  remove_points(list);
+
+  return temp_num_edges;
+}
+
+static void generate_point_list(struct point_list * list,
+                                struct grid_cell cell) {
+
+  reset_point_list(list);
+
+  if (cell.num_corners == 0) return;
+
+  struct point_list_element * curr = get_free_point_list_element(list);
+
+  list->first = curr;
+  LLtoXYZ(cell.coordinates_x[0], cell.coordinates_y[0], curr->vec_coords);
+
+  for (unsigned i = 1; i < cell.num_corners; ++i) {
+
+    double vec_coords[3];
+
+    LLtoXYZ(cell.coordinates_x[i], cell.coordinates_y[i], vec_coords);
+
+    curr->next = get_free_point_list_element(list);
+    curr->edge_type = cell.edge_type[i - 1];
+    curr = curr->next;
+
+    curr->vec_coords[0] = vec_coords[0];
+    curr->vec_coords[1] = vec_coords[1];
+    curr->vec_coords[2] = vec_coords[2];
+    curr->edge_type = cell.edge_type[i];
+  }
+
+  curr->next = list->first;
+  list->last = curr;
+
+  remove_zero_length_edges(list);
+}
+
+static struct point_list_element *
+get_free_point_list_element(struct point_list * list) {
+
+  struct point_list_element * element;
+
+  if (list->free_elements == NULL) {
+
+    for (int i = 0; i < 7; ++i) {
+
+      element = malloc(1 * sizeof(*element));
+
+      element->next = list->free_elements;
+      list->free_elements = element;
+    }
+
+    element = malloc(1 * sizeof(*element));
+
+  } else {
+
+    element = list->free_elements;
+    list->free_elements = list->free_elements->next;
+  }
+
+  element->next = NULL;
+  element->to_be_removed = 0;
+
+  return element;
+}
+
+static void free_point_list(struct point_list * list) {
+
+  struct point_list_element * element;
+
+  if (list->first != NULL) {
+
+    list->last->next = NULL;
+
+    while (list->first != NULL) {
+
+      element = list->first;
+      list->first = element->next;
+      free(element);
+    }
+  }
+
+  while (list->free_elements != NULL) {
+
+    element = list->free_elements;
+    list->free_elements = element->next;
+    free(element);
+  }
+
+  list->first = NULL;
+  list->last = NULL;
+  list->free_elements = NULL;
+}
+
+static int is_lat_cell(struct point_list * list, unsigned num_edges) {
+
+  struct point_list_element * curr = list->first;
+  int lat_cell = 1;
+
+  for (unsigned i = 0; i < num_edges; ++i, curr = curr->next)
+    lat_cell &= curr->edge_type == LAT_CIRCLE;
+
+  return lat_cell;
+}
+
+static int is_empty_gc_cell(struct point_list * list, unsigned num_edges) {
+
+  double const tol = 1e-6;
+
+  if ((num_edges == 2) &&
+      (list->first->edge_type != LAT_CIRCLE) &&
+      (list->last->edge_type != LAT_CIRCLE))
+    return 1;
+
+  struct point_list_element * curr = list->first;
+    
+  for (unsigned i = 0; i < num_edges; ++i) {
+
+    if (curr->edge_type == LAT_CIRCLE) return 0;
+    curr = curr->next;
+  }
+
+  double ref_norm[3];
+
+  compute_norm_vector(curr->vec_coords, curr->next->vec_coords, ref_norm);
+
+  for (unsigned i = 0; i < num_edges-1; ++i) {
+
+    curr = curr->next;
+
+    double norm[3];
+
+    compute_norm_vector(curr->vec_coords, curr->next->vec_coords, norm);
+
+    if (((fabs(ref_norm[0] - norm[0]) > tol) ||
+         (fabs(ref_norm[1] - norm[1]) > tol) ||
+         (fabs(ref_norm[2] - norm[2]) > tol)) &&
+        ((fabs(ref_norm[0] + norm[0]) > tol) ||
+         (fabs(ref_norm[1] + norm[1]) > tol) ||
+         (fabs(ref_norm[2] + norm[2]) > tol)))
+      return 0;
+  }
+
+  return 1;
+}
+
+static void generate_overlap_cell(struct point_list * list,
+                                  struct grid_cell * cell) {
+
+  //! \todo test whether all points of the cell are on a single
+  //!       great circle --> empty cell
+
+  unsigned num_edges = remove_zero_length_edges(list);
+
+  if ((num_edges < 2) ||
+      is_lat_cell(list, num_edges) ||
+      is_empty_gc_cell(list, num_edges)){
+
+    reset_point_list(list);
+    return;
+  }
+  /*
+  if ( num_edges > cell->num_corners )
+    {
+      cell->coordinates_x = realloc(cell->coordinates_x, num_edges * sizeof(*cell->coordinates_x));
+      cell->coordinates_y = realloc(cell->coordinates_y, num_edges * sizeof(*cell->coordinates_y));
+      cell->edge_type = realloc(cell->edge_type, num_edges * sizeof(*cell->edge_type));
+      cell->num_corners = num_edges;
+    }
+  */
+  cell->coordinates_x = malloc(num_edges * sizeof(*cell->coordinates_x));
+  cell->coordinates_y = malloc(num_edges * sizeof(*cell->coordinates_y));
+  cell->edge_type = malloc(num_edges * sizeof(*cell->edge_type));
+  cell->num_corners = num_edges;
+
+  struct point_list_element * curr = list->first;
+
+  for (unsigned i = 0; i < num_edges; ++i) {
+
+    struct point p;
+
+    XYZtoLL(curr->vec_coords, &p.lon, &p.lat);
+
+    cell->coordinates_x[i] = p.lon;
+    cell->coordinates_y[i] = p.lat;
+    cell->edge_type[i] = curr->edge_type;
+
+    curr = curr->next;
+  }
+}
diff --git a/src/clipping/clipping.h b/src/clipping/clipping.h
new file mode 100644
index 0000000..fbbb278
--- /dev/null
+++ b/src/clipping/clipping.h
@@ -0,0 +1,114 @@
+/**
+ * @file clipping.h
+ * @brief Structs and interfaces for cell clipping
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#ifndef CLIPPING_H
+#define CLIPPING_H
+
+#include "points.h"
+
+/** \example test_clipping.c
+ * This contains some examples on how to use the cell_clipping routine.
+ */
+
+
+/**
+  * \brief cell clipping to get the cells describing the intersections
+  *
+  * The routine takes (a list of) source cells and a target cell. It sets the
+  * target cell data and does some further initialisation. Thus it needs to be
+  * called for each new target cell intersection calculation
+  *
+  * The vertices of source and target cells can be either provided in a clockwise
+  * or anticlockwise sense. However, the same sense must be used for source and
+  * target cells.
+  *
+  * @param[in] N              number of source cells
+  * @param[in] source_cell    list of source cells
+  * @param[in] target_cell    target cell
+  * @param[in] overlap_buffer buffer for the overlaps between the target and
+  *                           the source cells
+  *
+  * \remark Valid for convex cells only!
+  *
+ **/
+void cell_clipping ( unsigned N,
+                     struct grid_cell * source_cell,
+                     struct grid_cell target_cell,
+                     struct grid_cell * overlap_buffer );
+
+/**
+  * \brief calculates partial areas for all overlapping parts of the source
+  *        cells, this is required for conservative remapping
+  *
+  * Some of the underlying concepts can be found in
+  *
+  * See e.g. Joseph O'Rourke, Computational Geometry in C, 2nd Ed., 1998
+  *          Sec. 7.6 Intersections of Convex Polygons, page 253.
+  *
+  * The routine takes (a list of) source cells and a target cell. It determines the
+  * clipping points of the intersection between a source and the target cells using
+  * cell_clipping internally. In a second step areas are calculated for each
+  * intersection described in the overlap cells. If a target cell is fully
+  * covered by N source cells the N partial areas should add up to the area of
+  * the target cell.
+  *
+  * The vertices of source and target cells can be either provided in a clockwise
+  * or anticlockwise sense. However, the same sense must be used for source and
+  * target cells.
+  *
+  * @param[in]  N             number of source cells
+  * @param[in]  source_cell   list of source cells
+  * @param[in]  target_cell   target cell
+  * @param[out] partial_areas list of N partial weights, one weight for each
+  *                           source-target intersection
+  *
+  * \remark Valid for convex cells only!
+  *
+ **/
+void compute_overlap_areas(unsigned N,
+                           struct grid_cell * source_cell,
+                           struct grid_cell target_cell,
+                           double * partial_areas);
+
+/**
+  * \brief correct interpolation weights
+  *
+  * Returns weights with a sum close to 1.0
+  *
+  * @param[in]  N                 number of source cells
+  * @param[out] weight            list of N partial weights
+  *
+ **/
+void correct_weights ( unsigned N, double * weight );
+
+#endif // CLIPPING_H
diff --git a/src/clipping/dep_list.h b/src/clipping/dep_list.h
new file mode 100644
index 0000000..0abbe2e
--- /dev/null
+++ b/src/clipping/dep_list.h
@@ -0,0 +1,215 @@
+/**
+ * @file dep_list.h
+ * @brief Utlity functions for dependency lists 
+ *
+ * Dependency lists and small general functions
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Thomas Jahns <jahns at dkrz.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Thomas Jahns <jahns at dkrz.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Thomas Jahns <jahns at dkrz.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#ifndef DEP_LIST_H
+#define DEP_LIST_H
+
+/** \example test_dep_list.c
+ * This contains examples on how to use struct dep_list.
+ */
+
+/** \brief dependency list
+ *
+ * data structure for storing and working with dependencies between unsigned integer data\n
+ * possible applications of a dep_list are:
+ *    - the corner ids for all cells (cell 0 -> corners 0, 1, 4, 3; cell 1 -> corners 1, 2, 5, 4; 2 -> 3, 4 , 7, 6; 3 -> 4, 5, 8, 7)
+ *    - neighbour cell ids (cell 0 -> neighbours 1, 2, 3; cell 1 -> neighbours 0, 2, 3; 2 -> 0, 1, 3; 3 -> 0, 1, 2)
+ *
+ * The element index (in the example the cell index) goes from 0 to n-1, where n is the total number of elements in the dependency list.\n
+ * The dependencies can have any valid unsigned integer number. However, one has to be careful when using \ref invert_dep_list, because if the values of the dependencies are to big the resulting dependency list can be big.
+ */
+struct dep_list {
+   unsigned num_elements;           //!< total number of elements in the dependency list
+   unsigned * num_deps_per_element; //!< array containing the number of dependencies per element
+   unsigned * dependencies;         //!< array containing all dependencies
+
+   /**
+    * \brief exclusive prefix sum for faster access of dependencies array
+    *
+    * this array is automatically generated and contains a exclusive prefix sum\n
+    *   [0]=0, [1]=num_dep[0], [2]=num_dep[0]+num_dep[1], ...\n
+    * see: http://en.wikipedia.org/wiki/Prefix_sum
+    */
+   unsigned * prescan;
+};
+
+/**
+ * initialises a dependency list, can be used in order to avoid memory access violations
+ * @param[in,out] list dependency list that is to be initialised
+ */
+void init_dep_list (struct dep_list * list);
+
+/**
+ * initialises an empty dependency list, can be used if the dependencies themselves are not know a priori
+ * @param[in,out] list dependency list that is to be initialised
+ * @param[in] num_elements number of elements in the dependency list
+ */
+void init_empty_dep_list(struct dep_list * list, unsigned num_elements);
+
+/**
+ * initialises dependency list and sets the dependencies (a previous call to init_dep_list is not mandatory)
+ * @param[in,out] list dependency list that is to be initialised
+ * @param[in] num_elements number of elements in the dependency list
+ * @param[in] num_deps_per_element array of size num_elements that contains for each element the number of associated dependencies
+ * @param[in] dependencies array that contains all dependencies, entries 0 to num_deps_per_element[0]-1 contain dependencies for element 0, entries num_deps_per_element[0] to num_deps_per_element[0]+num_deps_per_element[1]-1 contain the dependencies for element 1, etc.
+ *
+ * \remark This routine makes no copy of the array passed to it. The array are assumed to be on the heap and will be freed by a call to \ref free_dep_list.
+ */
+void set_dependencies (struct dep_list * list, unsigned num_elements,
+                       unsigned * num_deps_per_element, unsigned * dependencies);
+/**
+ * adds dependencies to an existing dependency list
+ * @param[in,out] list dependency list to be edited
+ * @param[in] element element of the list to be changed
+ * @param[in] num_dependencies number of dependencies to be added
+ * @param[in] dependencies array containing the dependencies, which are supposed to be added to the list
+ */
+void add_dependencies (struct dep_list * list, unsigned element,
+                       unsigned num_dependencies, unsigned * dependencies);
+
+/**
+ * gets all dependencies for a given element
+ * @param[in] list dependency list
+ * @param[in] index element index
+ * @return pointer to a constant array containing the dependencies for the given element index
+ *
+ * \remark the number of dependencies for the respective element can be retrieved from list.num_deps_per_element[index]
+ */
+unsigned const * get_dependencies_of_element (struct dep_list list, unsigned index);
+
+/**
+ * gets the total number of dependencies stored in the given list
+ * @param[in] list dependency list
+ * @return total number of dependencies in list
+ */
+unsigned get_total_num_dependencies(struct dep_list list);
+
+/**
+ * gets the position of a dependency for a given element in the dep_list::dependencies array
+ * @param[in] list dependency list
+ * @param[in] index element index
+ * @param[in] dependency dependency of provided element
+ * @return position of dependency in dep_list::dependencies array \n -1 in case index and/or dependency is invalid
+ */
+unsigned get_dependency_index(struct dep_list list, unsigned index, unsigned dependency);
+
+/**
+ * gets the position of the first dependency of an element in the dep_list::dependencies array
+ * @param[in] list dependency list
+ * @param[in] index element index
+ * @return position of the first dependency of an element in the dep_list::dependencies array
+ */
+unsigned get_dependency_offset(struct dep_list list, unsigned index);
+
+/**
+ * search for a given dependency in a dependency list
+ * @param[in] list dependency list
+ * @param[in] dependency dependency that is to be searched for
+ * @return 0 if the list does not contain the respective dependency
+ */
+unsigned list_contains_dependency(struct dep_list list, unsigned dependency);
+
+/**
+ * gets the element and dependency associated to a given position in the dep_list::dependencies array
+ * @param[in] list dependency list
+ * @param[in] dep_index position in dep_list::dependencies
+ * @param[out] index element index associated to dep_index
+ * @param[out] dependency dependency associated to dep_index
+ */
+void get_dependency(struct dep_list list, unsigned dep_index,
+                    unsigned * index, unsigned * dependency);
+
+/**
+ * generates an inverted dependency list
+ * @param[in] dep dependency list that is to be inverted
+ * @param[out] inv_dep inverted version of dep (initialising inv_dep is no required)
+ */
+void invert_dep_list(struct dep_list dep, struct dep_list * inv_dep);
+
+/**
+ * removes all dependencies of the provided elements
+ * @param[in,out] dep dependency list
+ * @param[in] element_indices array with all element indices for which the dependencies have to be removed from dep
+ * @param[in] num_elements number of indices in element_indices array
+ * \remark element indices == -1 are being ignored
+ */
+void remove_dependencies_of_elements(struct dep_list * dep, unsigned * element_indices,
+                                     unsigned num_elements);
+
+/**
+ * removes all given dependencies
+ * @param[in,out] dep dependency list
+ * @param[in] dependencies array containing the dependencies that have to be removed
+ * @param[in] num_dependencies number of dependencies in dependencies array
+ * \remark dependencies == -1 are being ignored
+ */
+void remove_dependencies(struct dep_list * dep, unsigned * dependencies,
+                         unsigned num_dependencies);
+
+/**
+ * makes a copy of a dependency list
+ * @param[in] src source dependency list
+ * @param[out] tgt target dependency list (initialising tgt is not required)
+ */
+void copy_dep_list(struct dep_list src, struct dep_list * tgt);
+
+/**
+ * packs a dependency list into a buffer that can be sent to other processes via the MPI library for example
+ * @param[in] list dependency list to be packed
+ * @param[in,out] buf pointer to an array into which the dependency list is to packed (if too small this array will be reallocated)
+ * @param[in] offset offset in the buffer at which the data is to be written
+ * @param[out] data_size size of the data the is added to the buffer
+ * @param[in,out] buf_size size of the buffer (this is being updated if necessary)
+ * \remark *buf == NULL and *buf_size=0 are valid input values
+ * @see unpack_dep_list
+ */
+void pack_dep_list(struct dep_list list, unsigned ** buf, unsigned offset,
+                   unsigned * data_size, unsigned * buf_size);
+/**
+ * unpacks a packed dependency list
+ * @param[out] list dependency into which the unpacked data is to be written (initialising is not required)
+ * @param[in] buf buffer containing packed dependency list
+ * @param[out] data_size size of the data the was occupied by the packed dependency list
+ * @see pack_dep_list
+ */
+void unpack_dep_list(struct dep_list * list, unsigned * buf, unsigned * data_size);
+
+/**
+ * frees a dependency list
+ * @param[in,out] list dependency list to be freed
+ */
+void free_dep_list(struct dep_list * list);
+
+#endif // DEP_LIST_H
diff --git a/src/clipping/ensure_array_size.c b/src/clipping/ensure_array_size.c
new file mode 100644
index 0000000..ee9123a
--- /dev/null
+++ b/src/clipping/ensure_array_size.c
@@ -0,0 +1,47 @@
+/**
+ * @file ensure_array_size.c
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "ensure_array_size.h"
+
+void
+realloc_array(void **array, size_t elem_size, size_t *curr_array_size,
+              size_t requested_size)
+{
+  const size_t array_inc_size = (1024 + elem_size - 1)/ elem_size;
+  *curr_array_size = array_inc_size
+    * ((requested_size + array_inc_size) / array_inc_size);
+  *array = realloc(*array, *curr_array_size * elem_size);
+  if (*array == NULL && (*curr_array_size * elem_size)) {
+     fprintf(stderr, "error in realloc\n");
+     exit(EXIT_FAILURE);
+  }
+}
diff --git a/src/clipping/ensure_array_size.h b/src/clipping/ensure_array_size.h
new file mode 100644
index 0000000..306a376
--- /dev/null
+++ b/src/clipping/ensure_array_size.h
@@ -0,0 +1,55 @@
+/**
+ * @file ensure_array_size.h
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Thomas Jahns <jahns at dkrz.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Thomas Jahns <jahns at dkrz.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Thomas Jahns <jahns at dkrz.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#ifndef ENSURE_ARRAY_SIZE_H
+#define ENSURE_ARRAY_SIZE_H
+
+#include <stdlib.h>
+
+void
+realloc_array(void **array, size_t elem_size, size_t *curr_array_size,
+              size_t requested_size);
+
+#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)            \
+  do {                                                                  \
+    if ((req_size) > (curr_array_size))                                 \
+    {                                                                   \
+      size_t casize = (curr_array_size);                                \
+                                                                        \
+      realloc_array((void **)&(arrayp), sizeof(*(arrayp)), &casize,     \
+                    (req_size));                                        \
+      (curr_array_size) = casize;                                       \
+    }                                                                   \
+  }                                                                     \
+  while(0)
+
+#endif
diff --git a/src/clipping/geometry.h b/src/clipping/geometry.h
new file mode 100644
index 0000000..8d8d3a5
--- /dev/null
+++ b/src/clipping/geometry.h
@@ -0,0 +1,585 @@
+/**
+ * @file geometry.h
+ * @brief Structs and interfaces for investigating the geometry and relations of cells
+ *
+ * The functions are used to determine relations between
+ * source and target cells. Complete cells are constructed
+ * on the sphere by connecting cell vertices along either
+ * great circles (along the orthodrome) or directly (along
+ * the loxodrome).
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#ifndef GEOMETRY_H
+#define GEOMETRY_H
+
+#include "grid.h"
+
+struct line {
+   struct {
+      double x;
+      double y;
+   } p1, p2;
+};
+
+struct point {
+   double lon, lat;
+};
+
+struct edge {
+   struct point points[2];
+   enum edge_type edge_type;
+};
+
+/**
+ * defines a spherical cap, which is used as a convex hull to describe the extents of subdomain
+ */
+struct bounding_circle {
+
+   //! the middle point of the spherical cap in spherical coordinates (in rad)
+   double base_point[2];
+   //! the middle point of the spherical cap in cartesian coordinates (is a unit vector)
+   double base_vector[3];
+   //! angle between the middle point and the boundary of the spherical cap
+   double inc_angle; // height >= pi -> everything
+};
+
+/** \example test_check_overlap.c
+ * This contains examples on how to use check_overlap_cells.
+ */
+
+/**
+ * checks whether two cells overlap \n
+ * @param[in] cell_a
+ * @param[in] cell_b
+ * @return 0 if both cells do not overlap
+ * @see check_overlap_cells
+ */
+int check_overlap_cells (struct grid_cell const cell_a, 
+                         struct grid_cell const cell_b);
+
+/**
+ * checks whether two cells overlap \n
+ * @param[in] cell_a
+ * @param[in] circle_a bounding circle of cell a
+ * @param[in] cell_b
+ * @param[in] circle_b bounding circle of cell b
+ * @return 0 if both cells do not overlap
+ * @see check_overlap_cells
+ */
+int check_overlap_cells2 (struct grid_cell const cell_a,
+                          struct bounding_circle circle_a,
+                          struct grid_cell const cell_b,
+                          struct bounding_circle circle_b);
+
+/** \example test_point_in_cell.c
+ * This contains examples on how to use point_in_cell.
+ */
+
+/**
+ * checks whether a given point is within a given cell \n
+ * @param[in] point
+ * @param[in] cell
+ * @return 0 if the point is not in the cell
+ */
+int point_in_cell (struct point point, struct grid_cell cell);
+
+/** \example test_point_in_cell.c
+ * This contains examples on how to use point_in_cell.
+ */
+
+/**
+ * checks whether a given point is within a given cell \n
+ * @param[in] point
+ * @param[in] cell
+ * @param[in] bnd_circle
+ * @return 0 if the point is not in the cell
+ */
+int point_in_cell2 (struct point point, struct grid_cell cell,
+                    struct bounding_circle bnd_circle);
+
+/**
+ * computes the angle between two longitude coordinates (in rad) \n
+ * takes into account that longitude have a period of 2 pi
+ * @param[in] a_lon
+ * @param[in] b_lon
+ * @return angle between both coordinates (in rad)
+ */
+double get_angle(double a_lon, double b_lon);
+
+/** \example test_find_overlap.c
+ * This contains an example on how to use find_overlapping_cells.
+ */
+
+/**
+ * searches for overlapping cells between grids \n
+ * the user needs to provide a dependency list containing an initial search result that is used as a starting point, which is then refined
+ * @param[in] src_grid source %grid
+ * @param[in] tgt_grid target %grid
+ * @param[in] initial_src_to_tgt_dep dependency list containing for each source cell a list of target cell that might overlap
+ * @param[out] src_to_tgt_dep dependency list containing the result of the search
+ */
+void find_overlapping_cells (struct grid * src_grid, struct grid * tgt_grid,
+                             struct dep_list initial_src_to_tgt_dep, 
+                             struct dep_list * src_to_tgt_dep);
+
+/**
+ * searches for all overlapping cells of a given grid that overlap with a
+ * given cell\n
+ * the user needs to provide initial search results that are used as a starting
+ * point, which is then refined
+ * @param[in]     src_cell             cell for which the search is to conducted
+ * @param[in]     src_bnd_circle       bounding circle of source cell
+ * @param[in]     tgt_grid             grid on which overlapping cells are to
+ *                                     be searched
+ * @param[in]     initial_dep          initial search results
+ * @param[in]     num_initial_deps     number of dependencies in initial_dep
+ * @param[in,out] deps                 NULL or pointer to pointer returned by a
+ *                                     standard allocation routine
+ * @param[in,out] deps_size            number of elements that fit into deps or
+ *                                     0 if deps equals NULL
+ * @param[out]    num_deps             number of overlapping cells
+ * @param[in]     src_index            any number (no entry in
+ *                                     tgts_already_touched is allowed to be
+ *                                     bigger than src_index)
+ * @param[in,out] tgts_already_touched array with the size of the target grid
+ *                                     and no entry bigger than src_index
+ * @param[in,out] stack                NULL or pointer to pointer returned by a
+ *                                     standard allocation routine
+ * @param[in,out] stack_size           number of elements that fit into stack
+ *                                     or 0 if stack equals NULL
+ * @remarks the user is responsible to free the memory associated with deps
+ *          and stack
+ */
+void find_overlapping_cells_s (struct grid_cell src_cell,
+                               struct bounding_circle src_bnd_circle,
+                               struct grid * tgt_grid,
+                               unsigned const * initial_dep,
+                               unsigned num_initial_deps, unsigned ** deps,
+                               unsigned * deps_size, unsigned * num_deps,
+                               unsigned src_index,
+                               unsigned * tgts_already_touched,
+                               unsigned ** stack, unsigned * stack_size);
+
+/** \example test_gcxgc.c
+ * This contains examples on how to use gcxgc and gcxgc_vec
+ */
+
+/**
+ * computes the intersection points of two great circles \n
+ * based on http://www.geoclub.de/viewtopic.php?f=54&t=29689
+ * @param[in] edge_a edge defining a great circle
+ * @param[in] edge_b edge defining a great circle
+ * @param[out] p intersection point
+ * @param[out] q intersection point
+ * @return  0 if the intersection points are neither on edge a or b \n
+ *          1st bit will be set if p is on edge a \n
+ *          2nd bit will be set if q is on edge a \n
+ *          3rd bit will be set if p is on edge b \n
+ *          4th bit will be set if q is on edge b
+  *         5th bit will be set if both great circles are identically
+ *
+ * \remark the user can provide NULL for p and/or q in that case the intersection points will not be returned
+ */
+int gcxgc (struct edge edge_a, struct edge edge_b,
+           struct point * p, struct point * q);
+
+/**
+ * computes the intersection points of two great circles \n
+ * based on http://www.geoclub.de/viewtopic.php?f=54&t=29689
+ * @param[in] a first point of edge a the is on a great circle
+ * @param[in] b second point of edge a the is on a great circle
+ * @param[in] c first point of edge b the is on a great circle
+ * @param[in] d second point of edge b the is on a great circle
+ * @param[out] p intersection point
+ * @param[out] q intersection point
+ * @return  0 if the intersection points are neither on edge a or b \n
+ *          1st bit will be set if p is on edge a \n
+ *          2nd bit will be set if q is on edge a \n
+ *          3rd bit will be set if p is on edge b \n
+ *          4th bit will be set if q is on edge b
+  *         5th bit will be set if both great circles are identically
+ *
+ * \remark the user can provide NULL for p and/or q in that case the intersection points will not be returned
+ */
+ int gcxgc_vec (double a[3], double b[3], double c[3], double d[3],
+                double p[3], double q[3]);
+
+/** \example test_loncxlatc.c
+ * This contains examples on loncxlatc and loncxlatc_vec
+ */
+
+/** \brief compute the intersection point of a meridian and a parallel
+ *
+ * compute the intersection points of a circle of longitude (defined by a and b)
+ * and a circle of latitude (defined by c and d)
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ **/
+int loncxlatc_vec (double a[3], double b[3], double c[3], double d[3],
+                   double p[3], double q[3]);
+
+/** \brief compute the intersection point of a meridian and a parallel
+ *
+ * compute the intersection points of a circle of longitude (defined by a and b)
+ * and a circle of latitude (defined by c and d)
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ **/
+int loncxlatc (struct edge edge_a, struct edge edge_b,
+               struct point * p, struct point * q);
+
+/** \example test_latcxlatc.c
+ * This contains examples on latcxlatc and latcxlatc_vec
+ */
+
+/** \brief compute the intersection point two circles of latitude
+ *
+ * compute the intersection points of two circle of latitude
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ *      - 5th bit will be set if both edges are on the same circle of latitude
+ **/
+int latcxlatc_vec (double a[3], double b[3], double c[3], double d[3],
+                   double p[3], double q[3]);
+
+/** \brief compute the intersection point two circles of latitude
+ *
+ * compute the intersection points of two circle of latitude
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ *      - 5th bit will be set if both edges are on the same circle of latitude
+ **/
+int latcxlatc (struct edge edge_a, struct edge edge_b,
+               struct point * p, struct point * q);
+
+/** \example test_loncxlonc.c
+ * This contains examples on loncxlonc loncxlonc_vec
+ */
+
+/** \brief compute the intersection point two circles of longitude
+ *
+ * compute the intersection points of two circle of longitude
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ *      - 5th bit will be set if both edges are on the same circle of longitude
+ **/
+int loncxlonc_vec (double a[3], double b[3], double c[3], double d[3],
+                   double p[3], double q[3]);
+
+/** \brief compute the intersection point two circles of longitude
+ *
+ * compute the intersection points of two circle of longitude
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ *      - 5th bit will be set if both edges are on the same circle of longitude
+ **/
+int loncxlonc (struct edge edge_a, struct edge edge_b,
+               struct point * p, struct point * q);
+
+/** \example test_gcxlatc.c
+ * This contains examples on gcxlatc and gcxlatc_vec.
+ */
+
+/**
+ * compute the intersection points of a great circles
+ * and a circle of latitude \n
+ * based on http://geospatialmethods.org/spheres/GCIntersect.html
+ * @param[in] edge_a edge defining a great circle
+ * @param[in] edge_b edge defining a circle of latitude
+ * @param[out] p intersection point
+ * @param[out] q intersection point
+ * @return  0 if the intersection points are neither on edge a or b \n
+ *         -1 if the two circles do not intersect \n
+ *          1st bit will be set if p is on edge a \n
+ *          2nd bit will be set if q is on edge a \n
+ *          3rd bit will be set if p is on edge b \n
+ *          4th bit will be set if q is on edge b
+ *
+ * \remarks if -1 is returned neither p or q is set
+ * \remarks if the two circles only have one intersection point,
+ *          p and q will be identically, but only the p bits will be set
+ */
+int gcxlatc (struct edge edge_a, struct edge edge_b,
+             struct point * p, struct point * q);
+
+/**
+ * compute the intersection points of a great circles
+ * and a circle of latitude \n
+ * based on http://geospatialmethods.org/spheres/GCIntersect.html
+ * @param[in] edge_a edge defining a great circle
+ * @param[in] edge_b edge defining a circle of latitude
+ * @param[out] p intersection point
+ * @param[out] q intersection point
+ * @return  0 if the intersection points are neither on edge a or b \n
+ *         -1 if the two circles do not intersect \n
+ *          1st bit will be set if p is on edge a \n
+ *          2nd bit will be set if q is on edge a \n
+ *          3rd bit will be set if p is on edge b \n
+ *          4th bit will be set if q is on edge b
+ *
+ * \remarks if -1 is returned neither p or q is set
+ * \remarks if the two circles only have one intersection point,
+ *          p and q will be identically, but only the p bits will be set
+ */
+int gcxlatc_vec(double a[3], double b[3], double c[3], double d[3],
+                double p[3], double q[3]);
+
+/**
+ * computes the intersection points of two edges
+ * @param[in]  edge_a       edge a
+ * @param[in]  edge_b       edge b
+ * @param[out] intersection intersection point
+ * @return  0 if the edges do not intersect \n
+ *          1 if the edges intersect
+ *
+ * \remarks if intersection is not NULL and the edges intersect
+ *          the intersection point is returned
+ * \remarks only one intersection is returned even if the edges intersect twice
+ */
+int intersect (struct edge const edge_a, struct edge const edge_b,
+               struct point * intersection);
+
+/**
+ * computes the intersection points of two edges
+ * @param[in]  edge_type_a type of edge a
+ * @param[in]  a           first point of edge a
+ * @param[in]  b           second point of edge a
+ * @param[in]  edge_type_b type of edge b
+ * @param[in]  c           first point of edge b
+ * @param[in]  d           second point of edge b
+ * @param[out] p           first intersection point
+ * @param[out] q           second intersection point
+ * @return  0 if the intersection points are neither on edge a or b \n
+ *         -1 if the two circles do not intersect \n
+ *          1st bit will be set if p is on edge a \n
+ *          2nd bit will be set if q is on edge a \n
+ *          3rd bit will be set if p is on edge b \n
+ *          4th bit will be set if q is on edge b \n
+ *          5th bit will be set if both circles are identically
+ *
+ * \remarks if -1 is returned neither p or q is set
+ * \remarks if the two circles only have one intersection point,
+ *          p and q will be identically, but only the p bits will be set
+ */
+int intersect_vec (enum edge_type edge_type_a, double a[3], double b[3],
+                   enum edge_type edge_type_b, double c[3], double d[3],
+                   double p[3], double q[3]);
+
+/** \example test_cell_bnd_circle.c
+ * These are some examples on how to use \ref get_cell_bounding_circle.
+ */
+
+/**
+ * gets the bounding circle for a grid cell
+ * @param[in] cell grid cell (coordinates have to be in radian)
+ * @param[out] bnd_circle bounding circle of the grid cell
+ */
+void get_cell_bounding_circle(struct grid_cell cell,
+                              struct bounding_circle * bnd_circle);
+
+/**
+ * computes the circumscribe circle for a triangle on the sphere
+ * @param[in]  a          coordinates of first point (xyz)
+ * @param[in]  b          coordinates of second point (xyz)
+ * @param[in]  c          coordinates of thrid point (xyz)
+ * @param[out] bnd_circle circumscribe circle
+ * @remark it is assumed that all three edges of the triangle are great circles
+ */
+void get_cell_circumscribe_circle_unstruct_triangle(
+   double a[3], double b[3], double c[3], struct bounding_circle * bnd_circle);
+
+/**
+ * computes the smallest bounding circle for a triangle on the sphere
+ * @param[in]  a          coordinates of first point (xyz)
+ * @param[in]  b          coordinates of second point (xyz)
+ * @param[in]  c          coordinates of thrid point (xyz)
+ * @param[out] bnd_circle bounding circle
+ * @remark it is assumed that all three edges of the triangle are great circles
+ */
+void get_cell_bounding_circle_unstruct_triangle(
+   double a[3], double b[3], double c[3], struct bounding_circle * bnd_circle);
+
+/**
+ * computes the circumscribe circle for a quad on the sphere
+ * @param[in]  a          coordinates of first point (xyz)
+ * @param[in]  b          coordinates of second point (xyz)
+ * @param[in]  c          coordinates of thrid point (xyz)
+ * @param[in]  d          coordinates of fourth point (xyz)
+ * @param[out] bnd_circle circumscribe circle
+ * @remark it is assumed that all edges of the quad are either circles of
+ *         longitude or latitude
+ */
+void get_cell_circumscribe_circle_reg_quad(
+   double a[3], double b[3], double c[3], double d[3],
+   struct bounding_circle * bnd_circle);
+
+/**
+ * computes the smallest bounding circle for a triangle on the sphere
+ * @param[in]  a          coordinates of first point (xyz)
+ * @param[in]  b          coordinates of second point (xyz)
+ * @param[in]  c          coordinates of thrid point (xyz)
+ * @param[in]  d          coordinates of fourth point (xyz)
+ * @param[out] bnd_circle bounding circle
+ * @remark it is assumed that all edges of the quad are either circles of
+ *         longitude or latitude
+ */
+void get_cell_bounding_circle_reg_quad(
+   double a[3], double b[3], double c[3], double d[3],
+   struct bounding_circle * bnd_circle);
+
+/** \example test_grid_bnd_circle.c
+ * These are some examples on how to use \ref get_grid_bounding_circle.
+ */
+
+/**
+ * gets a bounding circle for a grid
+ * @param[in] grid
+ * @param[out] bnd_circle bounding circle of the grid
+ */
+void get_grid_bounding_circle(struct grid * grid,
+                              struct bounding_circle * bnd_circle);
+
+/**
+ * gets all cells of a grid that have an overlap with the area defined by the given bounding circle
+ * @param[in] grid
+ * @param[in] extent bounding circle defining an area against which all cells of the grid are going to checked
+ * @param[in,out] matching_cells array containing the matching cells (if required the array will be reallocated)
+ * @param[in,out] curr_matching_cells_array_size size of matching_cells array (if the matching_cells array is reallocated the size will be updated as well)
+ * @param[in,out] local_ids local ids of the matching cells (if required the array will be reallocated)
+ * @param[in,out] curr_local_ids_array_size size of matching_cells array (if the local_ids array is reallocated the size will be updated as well)
+ * @param[out] num_matching_cells number of matching cells
+ * @param[in] offset number of cells/local ids already in the matching_cells and local_ids array (these will not be overwritten)
+ *
+ * \remark *matching_cells == NULL and *curr_matching_cells_array_size == 0 are valid input values
+ * \remark *local_ids == NULL and *curr_local_ids_array_size == 0 are valid input values
+ * \remark if matching_cells == NULL or local_ids == NULL the respective data is not returned by this routine
+ */
+void get_matching_grid_cells(struct grid * grid, struct bounding_circle extent,
+                             struct grid_cell ** matching_cells,
+                             unsigned * curr_matching_cells_array_size,
+                             unsigned ** local_ids, unsigned * curr_local_ids_array_size,
+                             unsigned * num_matching_cells, unsigned offset);
+
+/**
+ * checks whether two extents overlap
+ * @param[in] extent_a bounding circle
+ * @param[in] extent_b bounding circle
+ * @return 0 if the bounding circles do not overlap
+ */
+unsigned extents_overlap(struct bounding_circle * extent_a,
+                         struct bounding_circle * extent_b);
+
+/**
+ * checks whether a point is within a bounding circle
+ * @param[in] point point to be checked (coordinates in radian)
+ * @param[in] bnd_circle bounding circle
+ * @return 0 if point is not within the bounding circle
+ */
+unsigned point_in_bounding_circle(struct point point,
+                                  struct bounding_circle * bnd_circle);
+
+/**
+ * converts lon-lat coordinates into xyz ones
+ * @param[in]  lon   longitude coordinates in radian
+ * @param[in]  lat   latitude coordinates in radian
+ * @param[out] p_out xyz coordinates
+ */
+void LLtoXYZ(double lon, double lat, double p_out[]);
+
+/**
+ * converts lon-lat coordinates into xyz ones
+ * @param[in]  lon   longitude coordinates in deg
+ * @param[in]  lat   latitude coordinates in deg
+ * @param[out] p_out xyz coordinates
+ */
+void LLtoXYZ_deg(double lon, double lat, double p_out[]);
+
+/**
+ * converts lon-lat coordinates into xyz ones
+ * @param[in]  p_in xyz coordinates
+ * @param[out] lon  longitude coordinate in radian
+ * @param[out] lat  latitude coordinate in radian
+ */
+void XYZtoLL(double p_in[], double * lon, double * lat);
+
+/**
+ * computes the great circle distance in rad for two points given in xyz coordinates
+ * @param[in] a_vector point coordinates of point a
+ * @param[in] b_vector point coordinates of point b
+ * @return great circle distance in rad between both points
+ */
+double get_vector_angle(double a_vector[3], double b_vector[3]);
+
+/**
+ * computes the great circle distance in rad for two points given in lon-lat coordinates
+ * @param[in] a point coordinates of point a (in rad)
+ * @param[in] b point coordinates of point b (in rad)
+ * @return great circle distance in rad between both points
+ */
+double get_point_angle(struct point * a, struct point * b);
+
+#endif // GEOMETRY_H
diff --git a/src/clipping/geometry_tools.c b/src/clipping/geometry_tools.c
new file mode 100644
index 0000000..7961ca8
--- /dev/null
+++ b/src/clipping/geometry_tools.c
@@ -0,0 +1,120 @@
+/**
+ * @file geometry_tools.c
+ * @brief Set of functions to work with coordinates
+ *
+ * Note: Not all functions are documented by Doxygen. See the source code
+ * and \ref geometry.h for further details.
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#include <math.h>
+
+#include "geometry.h"
+
+double get_vector_angle(double a_vector[3], double b_vector[3]) {
+
+   double dot_product = a_vector[0]*b_vector[0]+a_vector[1]*b_vector[1]+a_vector[2]*b_vector[2];
+
+   double angle;
+
+   // the acos most accurate in the range [-0.5;0.5]
+   if (fabs(dot_product) <= 0.5) // the range in which the acos is most accurate
+      angle = acos(dot_product);
+   else {
+
+#define CROSS_PRODUCT3D(out,a,b) \
+  out[0]=a[1]*b[2]-a[2]*b[1]; \
+  out[1]=a[2]*b[0]-a[0]*b[2]; \
+  out[2]=a[0]*b[1]-a[1]*b[0];
+#define NORM(a) sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2])
+
+      double temp_vector[3];
+
+      CROSS_PRODUCT3D(temp_vector, a_vector, b_vector);
+
+      double asin_tmp = asin(NORM(temp_vector));
+
+      if (dot_product < 0.0) // if the angle is bigger than (PI / 2)
+         angle = M_PI - asin_tmp;
+      else
+         angle = asin_tmp;
+
+#undef NORM
+#undef CROSS_PRODUCT3D
+   }
+
+   if (angle < 0.0) return 0;
+   if (angle > M_PI) return M_PI;
+   return angle;
+}
+
+  /* Taken from http://www.geoclub.de/viewtopic.php?f=54&t=29689
+
+     Further information:
+     http://en.wikipedia.org/wiki/List_of_common_coordinate_transformations */
+
+void LLtoXYZ(double lon, double lat, double p_out[]) {
+
+   double cos_lat = cos(lat);
+   p_out[0] = cos_lat * cos(lon);
+   p_out[1] = cos_lat * sin(lon);
+   p_out[2] = sin(lat);
+}
+
+void LLtoXYZ_deg(double lon, double lat, double p_out[]) {
+
+   lon *= rad;
+   lat *= rad;
+
+   LLtoXYZ(lon, lat, p_out);
+}
+
+/** \brief compute longitude angle between two points in radian 
+**/
+double get_angle (double a_lon, double b_lon) {
+
+   while (a_lon - b_lon >   M_PI) b_lon += 2 * M_PI;
+   while (a_lon - b_lon < - M_PI) b_lon -= 2 * M_PI;
+
+   return a_lon - b_lon;
+}
+
+void XYZtoLL (double p_in[], double * lon, double * lat) {
+
+/*  convert from cartesian to spherical coordinates
+    taken from:
+    http://www.geoclub.de/viewtopic.php?f=54&t=29689
+
+    Further information:
+    http://en.wikipedia.org/wiki/List_of_common_coordinate_transformations */
+
+   *lon = atan2(p_in[1] , p_in[0]);
+   *lat = M_PI_2 - acos(p_in[2]);
+}
diff --git a/src/clipping/grid.h b/src/clipping/grid.h
new file mode 100644
index 0000000..92c2697
--- /dev/null
+++ b/src/clipping/grid.h
@@ -0,0 +1,473 @@
+/**
+ * @file grid.h
+ * @brief Structs and interfaces to handle grids
+ *
+ * struct grid is used as an abstraction for all types of grids. It contains longitude
+ * and latitude data of the corners and the mapping between cells and their corners and
+ * edges. \n
+ * In addition to the struct grid definition this file contains the declaration of a
+ * set of routines that are valid for all grid types and do certain operations on grids.
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#ifndef GRID_H
+#define GRID_H
+
+/** \example test_grid.c
+ * This shows how to work with struct grid.
+ */
+
+#include "dep_list.h"
+#include "math.h"
+#include "grid_cell.h"
+
+#define EARTH_RADIUS 6371.2290
+
+static double const EarthRadius  = EARTH_RADIUS;
+static double const rad          = M_PI / 180.0;
+static double const deg          = 180.0 / M_PI;
+static double const EarthRadius2 = EARTH_RADIUS * EARTH_RADIUS / 2.0 ;
+
+// forward declaration required by grid_vtable
+struct grid;
+struct bounding_circle;
+
+struct grid_vtable {
+
+   struct grid * (*copy)(struct grid *);
+   void (*get_2d_extent)(struct grid *, double (* extent)[2]);
+   void (*get_grid_cell) (struct grid *, unsigned, struct grid_cell *);
+   void (*get_grid_cell2) (struct grid *, unsigned, struct grid_cell *,
+                           struct bounding_circle * bnd_circle);
+   unsigned (*get_size_x_coords)(struct grid *);
+   unsigned (*get_size_y_coords)(struct grid *);
+   double const * (*get_x_coords)(struct grid *);
+   double const * (*get_y_coords)(struct grid *);
+   void (*set_x_coords)(struct grid *, double *);
+   void (*set_y_coords)(struct grid *, double *);
+   unsigned (*get_size_cell_grid_x_coords)(struct grid *);
+   unsigned (*get_size_cell_grid_y_coords)(struct grid *);
+   unsigned (*get_num_grid_cells)(struct grid *);
+   unsigned (*get_num_grid_corners)(struct grid *);
+   unsigned (*get_num_cell_corners)(struct grid *, unsigned);
+   unsigned (*get_num_corner_cells)(struct grid *, unsigned);
+   unsigned (*get_num_grid_edges)(struct grid *);
+   unsigned (*get_num_corner_edges)(struct grid *, unsigned);
+   unsigned (*get_num_cell_edges) (struct grid *, unsigned);
+   unsigned const * (*get_corner_edges)(struct grid *, unsigned);
+   unsigned const * (*get_cell_edge_indices)(struct grid *, unsigned);
+   enum edge_type (*get_edge_type)(struct grid *, unsigned);
+   unsigned const * (*get_cell_corner_indices)(struct grid *, unsigned);
+   unsigned const * (*get_corner_cell_indices)(struct grid *, unsigned);
+   unsigned const * (*get_cell_x_coord_indices) (struct grid *, unsigned);
+   unsigned const * (*get_cell_y_coord_indices) (struct grid *, unsigned);
+   double (*get_corner_x_coord) (struct grid *, unsigned);
+   double (*get_corner_y_coord) (struct grid *, unsigned);
+   unsigned (*get_corner_x_coord_index) (struct grid *, unsigned);
+   unsigned (*get_corner_y_coord_index) (struct grid *, unsigned);
+   int (*get_aux_grid_cell)(struct grid *, unsigned, unsigned *, enum edge_type *);
+   struct dep_list (*get_cell_neigh_dep_list)(struct grid *);
+   void (*get_boundary_corners) (struct grid *, unsigned *, unsigned *);
+   struct grid * (*generate_cell_grid)(struct grid *, double *, double *);
+   struct grid * (*generate_subgrid)(struct grid *, unsigned *, unsigned,
+                                     unsigned **, unsigned **, unsigned **);
+   void (*pack_grid)(struct grid *, double **, unsigned, unsigned *, unsigned *,
+                     unsigned **, unsigned, unsigned *, unsigned *);
+   struct grid_search * (*get_grid_search)(struct grid * grid);
+   void (*delete)(struct grid *);
+};
+
+struct grid {
+
+   struct grid_vtable *vtable;
+};
+
+/**
+ * computes the 2d %grid extent of a given %grid
+ * @param[in] grid is a pointer to a declared grid object
+ * @param[out] extent is the computed 2d extent
+ */
+void get_2d_grid_extent(struct grid * grid, double (* extent)[2]);
+
+/**
+ * gets a %grid cell from a grid object
+ * @param[in] grid
+ * @param[in] cell_index local cell index of the requested cell
+ * @param[out] cell requested cell (grid_cell object has be initialised once before)
+ * @see init_grid_cell
+ */
+void get_grid_cell (struct grid * grid, unsigned cell_index, 
+                    struct grid_cell * cell);
+
+/**
+ * gets a %grid cell from a grid object\n
+ * in addition the bounding circle for this grid cell is also returned
+ * @param[in] grid
+ * @param[in] cell_index local cell index of the requested cell
+ * @param[out] cell requested cell (grid_cell object has be initialised once before)
+ * @see init_grid_cell
+ */
+void get_grid_cell2 (struct grid * grid, unsigned cell_index, 
+                     struct grid_cell * cell,
+                     struct bounding_circle * bnd_circle);
+
+/**
+ * @param[in] grid
+ * @return size of the array returned by \ref get_x_coords
+ */
+unsigned get_size_x_coords(struct grid * grid);
+
+/**
+ * @param[in] grid
+ * @return size of the array returned by \ref get_y_coords
+ */
+unsigned get_size_y_coords(struct grid * grid);
+
+/**
+ * returns an array that contains the x coordinates of all corners of the grid
+ * @param[in] grid
+ * @return x coordinates of all corners of the grid
+ */
+double const * get_x_coords(struct grid * grid);
+
+/**
+ * returns an array that contains the y coordinates of all corners of the grid
+ * @param[in] grid
+ * @return y coordinates of all corners of the grid
+ */
+double const * get_y_coords(struct grid * grid);
+
+/**
+ * sets the array that contains the x coordinates of all corners of the grid
+ * @param[in] grid
+ * @param[in] x_coords
+ */
+void set_x_coords(struct grid * grid, double * x_coords);
+
+/**
+ * set the array that contains the y coordinates of all corners of the grid
+ * @param[in] grid
+ * @param[in] y_coords
+ */
+void set_y_coords(struct grid * grid, double * y_coords);
+
+/**
+ * gets the size of the x coordiante array of a cell %grid generated by \ref generate_cell_grid for the given %grid object
+ * @param[in] grid
+ * @return size of x coordiante for a potential cell grid
+ * @see generate_cell_grid
+ */
+unsigned get_size_cell_grid_x_coords(struct grid * grid);
+
+/**
+ * gets the size of the y coordiante array of a cell %grid generated by \ref generate_cell_grid for the given %grid object
+ * @param[in] grid
+ * @return size of y coordiante array for a potential cell grid
+ * @see generate_cell_grid
+ */
+unsigned get_size_cell_grid_y_coords(struct grid * grid);
+
+/**
+ * gets the number of cells in the given %grid
+ * @param[in] grid
+ * @return number of cells in the %grid
+ */
+unsigned get_num_grid_cells (struct grid * grid);
+
+/**
+ * gets the number of corners in the given %grid
+ * @param[in] grid
+ * @return number of corners in the %grid
+ */
+unsigned get_num_grid_corners (struct grid * grid); 
+
+/**
+ * gets the number of corners for a cell of a given %grid
+ * @param[in] grid
+ * @param[in] cell_index local id of the respective cell
+ * @return number of corners for the specified cell in %grid
+ */
+unsigned get_num_cell_corners (struct grid * grid, unsigned cell_index);
+
+/**
+ * gets the number of cells associated to a corner of a given %grid
+ * @param[in] grid
+ * @param[in] corner_index local id of the respective corner
+ * @return number of cells for the specified corner in %grid
+ */
+unsigned get_num_corner_cells (struct grid * grid, unsigned corner_index);
+
+/**
+ * gets the number of edges in the given %grid
+ * @param[in] grid
+ * @return number of edges in %grid
+ */
+unsigned get_num_grid_edges (struct grid * grid);
+
+/**
+ * gets the number of edges that are associated with a corner of a given %grid
+ * this is identical to the number of corners directly connected to the given corner
+ * @param[in] grid
+ * @param[in] corner_index local index of the respective corner
+ * @return number of edges associated with given corner
+ */
+unsigned get_num_corner_edges (struct grid * grid, unsigned corner_index);
+
+/**
+ * gets the number of edges for a cell of a given %grid (identical to \ref get_num_cell_corners)
+ * @param[in] grid
+ * @param[in] cell_index local id of the respective cell
+ * @return number of edges for the specified cell in %grid
+ * @see get_num_cell_corners
+ */
+unsigned get_num_cell_edges (struct grid * grid, unsigned cell_index);
+
+/**
+ * gets neighbour corners of a corner of a given %grid
+ * @param[in] grid
+ * @param[in] corner_index local id of a corner in %grid
+ * @return array containing the local ids of all corners directly linked to the given corner
+ * @see get_num_corner_edges
+ */
+unsigned const * get_corner_edges (struct grid * grid, unsigned corner_index);
+
+/**
+ * gets the %edges of a cell for a given %grid
+ * @param[in] grid
+ * @param[in] cell_index local id of the respective cell
+ * @return array that contains the local ids of all edges for the given cell
+ * @see get_num_cell_edges
+ */
+unsigned const * get_cell_edge_indices (struct grid * grid, unsigned cell_index);
+
+/**
+ * gets the type of an %edge for a given %grid
+ * @param[in] grid
+ * @param[in] edge_index local id of the respective edge
+ * @return type of the specified %edge
+ */
+enum edge_type get_edge_type(struct grid * grid, unsigned edge_index);
+
+/**
+ * gets the corners of a cell for a given grid
+ * @param[in] grid
+ * @param[in] cell_index local id of the respective cell
+ * @return array that contains the local ids of all corners for the given cell
+ * @see get_num_cell_corners
+ */
+unsigned const * get_cell_corner_indices (struct grid * grid, unsigned cell_index);
+
+/**
+ * gets the cells associated with a corner for a given grid
+ * @param[in] grid
+ * @param[in] corner_index local id of the respective corner
+ * @return array that contains the local ids of all cells for the given cell
+ * @see get_num_corner_cells
+ */
+unsigned const * get_corner_cell_indices (struct grid * grid, unsigned corner_index);
+
+
+/**
+ * gets indices to access x coordiante array for all corners of a cell for a given %grid
+ * @param[in] grid
+ * @param[in] cell_index local id of the respective cell
+ * @return array containing an index for each corner for the respective cell; these indices can be used to access x coordiante array (these indices are not the local corner ids)
+ * @see get_num_cell_corners
+ */
+unsigned const * get_cell_x_coord_indices (struct grid * grid, unsigned cell_index);
+
+/**
+ * gets indices to access y coordiante array for all corners of a cell for a given %grid
+ * @param[in] grid
+ * @param[in] cell_index local id of the respective cell
+ * @return array containing an index for each corner for the respective cell; these indices can be used to access y coordiante array (these indices are not the local corner ids)
+ * @see get_num_cell_corners
+ */
+unsigned const * get_cell_y_coord_indices (struct grid * grid, unsigned cell_index);
+
+/**
+ * gets the x coordinate for a corner of a given %grid
+ * @param[in] grid
+ * @param[in] corner_index local id of a corner in %grid
+ * @return x coordinate of the given corner
+ * @see get_num_grid_corners
+ */
+double get_corner_x_coord (struct grid * grid, unsigned corner_index);
+
+/**
+ * gets the y coordinate for a corner of a given %grid
+ * @param[in] grid
+ * @param[in] corner_index local id of a corner in %grid
+ * @return y coordinate of the given corner
+ * @see get_num_grid_corners
+ */
+double get_corner_y_coord (struct grid * grid, unsigned corner_index);
+
+/**
+ * gets an index that can used to access x coordiante array for a corner of a given %grid
+ * @param[in] grid
+ * @param[in] corner_index local id of a corner in %grid
+ * @return index that can be used to get the actual coordinate from x coordiante array (this is not the local corner id)
+ * @see get_num_grid_corners
+ */
+unsigned get_corner_x_coord_index (struct grid * grid, unsigned corner_index);
+
+/**
+ * gets an index that can used to access y coordiante array for a corner of a given %grid
+ * @param[in] grid
+ * @param[in] corner_index local id of a corner in %grid
+ * @return index that can be used to get the actual coordinate from y coordiante array (this is not the local corner id)
+ * @see get_num_grid_corners
+ */
+unsigned get_corner_y_coord_index (struct grid * grid, unsigned corner_index);
+
+/**
+ * computes the cell, whose corners are the cells, which have the given corner
+ * in common
+ *
+ * @param[in]  grid
+ * @param[in]  corner_index         index of the corner around which the auxiliary cell
+ *                                  is to be built
+ * @param[out] cell_indices cell indices of the auxiliary cell
+ * @param[out] edge_type type of the edges of the auxiliary cell
+ * @return return 0 in case there is no auxiliary cell
+ * @see get_num_corner_cells
+ */
+int get_aux_grid_cell(struct grid * grid, unsigned corner_index,
+                      unsigned * cell_indices, enum edge_type * edge_type);
+
+/**
+ * gets a dependency list containing all cell neighbourhood information for the given %grid
+ * @param[in] grid
+ * @return dependency list that contains for each local cell id the local ids of all neighbour cells
+ */
+struct dep_list get_cell_neigh_dep_list(struct grid * grid);
+
+/**
+ * makes a complete copy of a grid
+ * @param[in] grid grid to be copied
+ * @returns copy of the given grid
+ */
+struct grid * copy_grid(struct grid * grid);
+
+/** \example test_polecover.c
+ * This contains examples for cell_covers_pole.
+ */
+
+/**
+ * checks whether a given cell covers a pole on the globe
+ * @param[in] num_corners number of corners for the given cell
+ * @param[in] corners_lon longitude coordinates of the given cell
+ * @param[in] corners_lat latitude coordinates of the given cell
+ * @return 0 if the given cell does not cover a pole
+ */
+unsigned cell_covers_pole (unsigned num_corners, double * const corners_lon, 
+                                                 double * const corners_lat);
+
+/**
+ * get local ids of all boundary corners of the given grid
+ * @param[in] grid
+ * @param[in,out] bnd_corners array with the boundary corners (user must provide this array, it must be big enough to be able to hole all boundary cells)
+ * @param[out] num_bnd_corners number of boundary corners written to bnd_corners
+ */
+void get_boundary_corners (struct grid * grid, unsigned * bnd_corners,
+                           unsigned * num_bnd_corners);
+
+/**
+ * generates a grid that has a corner for each cell of the input %grid (the corners of the new %grid are in the same order as the cells of the input %grid)
+ * @param[in] grid input %grid
+ * @param[in] coordinates_x longitude data for the corners of the cell %grid (the layout of this array depends on the %grid type)
+ * @param[in] coordinates_y latitude data for the corners of the cell %grid (the layout of this array depends on the %grid type)
+ * @returns the generated cell grid
+ */
+struct grid * generate_cell_grid(struct grid * grid, double * coordinates_x, 
+                                 double * coordinates_y);
+
+/**
+ * generates a grid the contains the selected cells from the input grid (it may actually contain more cells)
+ * @param[in] grid input %grid
+ * @param[in] selected_local_cell_ids local ids of all cells that are to be included in the subgrid
+ * @param[in] num_local_cells num of local ids in selected_local_cell_ids
+ * @param[out] local_cell_ids pointer to an array containing the local ids of the input %grid for all cells of subgrid (the user is responsible for freeing the memory of the array)
+ * @param[out] local_corner_ids pointer to an array containing the local ids of the input %grid for all corners of subgrid (the user is responsible for freeing the memory of the array)
+ * @param[out] local_edge_ids pointer to an array containing the local ids of the input %grid for all edges of subgrid (the user is responsible for freeing the memory of the array)
+ * @returns the generate subgrid
+ */
+struct grid * generate_subgrid(struct grid * grid, unsigned * selected_local_cell_ids,
+                               unsigned num_local_cells, unsigned ** local_cell_ids,
+                               unsigned ** local_corner_ids, unsigned ** local_edge_ids);
+
+/**
+ * packs given grid into a double and unsigned buffer
+ * @param[in] grid
+ * @param[in,out] dble_buf pointer to double buffer (buffer is reallocated by this routine if necessary)
+ * @param[in] dble_buf_offset number of elements already in the buffer (this data is not overwritten by this routine)
+ * @param[out] dble_buf_data_size number of elements added to the buffer by this routine
+ * @param[in,out] dble_buf_size size of dble_buf (this is adjusted in case this routine reallocates dble_buf)
+ * @param[in,out] uint_buf pointer to double buffer (buffer is reallocated by this routine if necessary)
+ * @param[in] uint_buf_offset number of elements already in the buffer (this data is not overwritten by this routine)
+ * @param[out] uint_buf_data_size number of elements added to the buffer by this routine
+ * @param[in,out] uint_buf_size size of uint_buf (this is adjusted in case this routine reallocates uint_buf)
+ * @see unpack_grid
+ */
+void pack_grid(struct grid * grid, double ** dble_buf,
+               unsigned dble_buf_offset, unsigned * dble_buf_data_size,
+               unsigned * dble_buf_size, unsigned ** uint_buf,
+               unsigned uint_buf_offset, unsigned * uint_buf_data_size,
+               unsigned * uint_buf_size);
+
+/**
+ * unpacks a grid from the provided double and unsigned buffers; the unpacked grid is identical to the one packed into these buffers by \ref pack_grid
+ * @param[in] dble_buf
+ * @param[out] dble_buf_data_size number of elements extracted from dble_buf
+ * @param[in] uint_buf
+ * @param[out] uint_buf_data_size number of elements extracted from uint_buf
+ * @returns unpacked grid
+ * @see pack_grid
+ */
+struct grid * unpack_grid(double * dble_buf, unsigned * dble_buf_data_size,
+                          unsigned * uint_buf, unsigned * uint_buf_data_size);
+
+/**
+ * generates a grid search object for the given grid
+ * @param[in] grid
+ * @return 
+ */
+struct grid_search * get_grid_search(struct grid * grid);
+
+/**
+ * frees all memory associated with the given %grid (memory objects provided by the user must be taken care of by him; e.g. coordinates_x and coordinates_y provided to \ref reg2d_grid_new)
+ * @param[in] grid
+ */
+void delete_grid(struct grid * grid);
+
+#undef EARTH_RADIUS
+
+#endif // GRID_H
diff --git a/src/clipping/grid_cell.c b/src/clipping/grid_cell.c
new file mode 100644
index 0000000..f099f68
--- /dev/null
+++ b/src/clipping/grid_cell.c
@@ -0,0 +1,148 @@
+/**
+ * @file grid_cell.c
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *                                 Thomas Jahns <jahns at dkrz.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ *         Thomas Jahns <jahns at dkrz.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ *             Thomas Jahns <jahns at dkrz.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "grid_cell.h"
+#include "utils.h"
+#include "ensure_array_size.h"
+
+void init_grid_cell(struct grid_cell * cell) {
+
+   cell->coordinates_x = NULL;
+   cell->coordinates_y = NULL;
+   cell->edge_type = NULL;
+   cell->num_corners = 0;
+}
+
+void copy_grid_cell(struct grid_cell in_cell, struct grid_cell * out_cell) {
+
+   int flag;
+
+   flag = ((out_cell->coordinates_x == NULL) << 0) +
+          ((out_cell->coordinates_y == NULL) << 1) +
+          ((out_cell->edge_type == NULL)     << 2);
+
+   if (flag != 0 && flag != 7)
+      abort_message("ERROR: inconsistent grid_cell data structure\n",
+                    __FILE__, __LINE__);
+
+   if ((out_cell->coordinates_x == NULL) ||
+       (in_cell.num_corners > out_cell->num_corners)) {
+
+      free(out_cell->coordinates_x);
+      free(out_cell->coordinates_y);
+      free(out_cell->edge_type);
+      out_cell->coordinates_x = malloc(in_cell.num_corners *
+                                       sizeof(*(out_cell->coordinates_x)));
+      out_cell->coordinates_y = malloc(in_cell.num_corners *
+                                       sizeof(*(out_cell->coordinates_y)));
+      out_cell->edge_type = malloc(in_cell.num_corners *
+                                   sizeof(*(out_cell->edge_type)));
+   }
+
+   memcpy(out_cell->coordinates_x, in_cell.coordinates_x,
+          in_cell.num_corners * sizeof(*(out_cell->coordinates_x)));
+   memcpy(out_cell->coordinates_y, in_cell.coordinates_y,
+          in_cell.num_corners * sizeof(*(out_cell->coordinates_y)));
+   memcpy(out_cell->edge_type, in_cell.edge_type,
+          in_cell.num_corners * sizeof(*(out_cell->edge_type)));
+   out_cell->num_corners = in_cell.num_corners;
+}
+
+void free_grid_cell(struct grid_cell * cell) {
+
+   if (cell->coordinates_x != NULL) free(cell->coordinates_x);
+   if (cell->coordinates_y != NULL) free(cell->coordinates_y);
+   if (cell->edge_type != NULL) free(cell->edge_type);
+
+   init_grid_cell(cell);
+}
+
+void pack_grid_cell(struct grid_cell cell, double ** dble_buf,
+                    unsigned dble_buf_offset, unsigned * dble_buf_data_size,
+                    unsigned * dble_buf_size, unsigned ** uint_buf,
+                    unsigned uint_buf_offset, unsigned * uint_buf_data_size,
+                    unsigned * uint_buf_size) {
+
+   unsigned required_dble_buf_size, required_uint_buf_size;
+
+   required_dble_buf_size = 2 * cell.num_corners;
+   required_uint_buf_size = cell.num_corners + 1;
+
+   ENSURE_ARRAY_SIZE(*dble_buf, *dble_buf_size, dble_buf_offset+required_dble_buf_size);
+   ENSURE_ARRAY_SIZE(*uint_buf, *uint_buf_size, uint_buf_offset+required_uint_buf_size);
+
+   memcpy((*dble_buf)+dble_buf_offset, cell.coordinates_x, cell.num_corners * sizeof(double));
+   memcpy((*dble_buf)+dble_buf_offset+cell.num_corners, cell.coordinates_y,
+          cell.num_corners * sizeof(double));
+
+   *dble_buf_data_size = required_dble_buf_size;
+
+   (*uint_buf)[uint_buf_offset] = cell.num_corners;
+
+   unsigned i;
+   for (i = 1; i <= cell.num_corners; ++i)
+      (*uint_buf)[uint_buf_offset+i] = cell.edge_type[i-1];
+
+   *uint_buf_data_size = required_uint_buf_size;
+}
+
+void unpack_grid_cell(struct grid_cell * cell, double * dble_buf,
+                      unsigned * dble_buf_data_size, unsigned * uint_buf,
+                      unsigned * uint_buf_data_size) {
+
+   unsigned num_corners;
+
+   num_corners = uint_buf[0];
+
+   *dble_buf_data_size = 2 * num_corners;
+   *uint_buf_data_size = num_corners + 1;
+
+   if (num_corners != cell->num_corners) {
+      cell->coordinates_x = realloc (cell->coordinates_x, num_corners * sizeof(cell->coordinates_x[0]));
+      cell->coordinates_y = realloc (cell->coordinates_y, num_corners * sizeof(cell->coordinates_y[0]));
+      cell->edge_type = realloc (cell->edge_type, num_corners * sizeof(cell->edge_type[0]));
+   }
+
+   cell->num_corners = num_corners;
+   memcpy(cell->coordinates_x, dble_buf, num_corners * sizeof(double));
+   memcpy(cell->coordinates_y, dble_buf+num_corners, num_corners * sizeof(double));
+
+   unsigned i;
+   for (i = 1; i <= num_corners; ++i)
+     cell->edge_type[i-1] = (enum edge_type)uint_buf[i];
+}
diff --git a/src/clipping/grid_cell.h b/src/clipping/grid_cell.h
new file mode 100644
index 0000000..64d9a43
--- /dev/null
+++ b/src/clipping/grid_cell.h
@@ -0,0 +1,84 @@
+/**
+ * @file grid_cell.h
+ * @brief Structs and interfaces to handle grid cells
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#ifndef GRID_CELL_H
+#define GRID_CELL_H
+
+enum edge_type {
+   GREAT_CIRCLE = 0, //!< great circle
+   LAT_CIRCLE   = 1, //!< latitude circle
+   LON_CIRCLE   = 2, //!< longitude circle
+};
+
+struct grid_cell {
+   double * coordinates_x, * coordinates_y;
+   enum edge_type * edge_type;
+   unsigned num_corners;
+};
+
+/**
+ * initiates a grid_cell object
+ * before the first being used a grid_cell object has to be initialised
+ * @param[in] cell object to be initialised
+ * @see free_grid_cell
+ * @see get_grid_cell
+ */
+void init_grid_cell(struct grid_cell * cell);
+
+/**
+ * copies a given grid cell
+ * @param[in]  in_cell  cell to be copied
+ * @param[out] out_cell copied cell
+ * @remarks out_cell needs to be a cell that has previously been
+ *          initialised or a cell that already contains valid data
+ */
+void copy_grid_cell(struct grid_cell in_cell, struct grid_cell * out_cell);
+
+/**
+ * frees all memory associated with a grid_cell object and reinitialised
+ * the cell
+ * @param[in,out] cell
+ */
+void free_grid_cell(struct grid_cell * cell);
+
+void pack_grid_cell(struct grid_cell cell, double ** dble_buf,
+                    unsigned dble_buf_offset, unsigned * dble_buf_data_size,
+                    unsigned * dble_buf_size, unsigned ** uint_buf,
+                    unsigned uint_buf_offset, unsigned * uint_buf_data_size,
+                    unsigned * uint_buf_size);
+
+void unpack_grid_cell(struct grid_cell * cell, double * dble_buf,
+                      unsigned * dble_buf_data_size, unsigned * uint_buf,
+                      unsigned * uint_buf_data_size);
+
+#endif // GRID_CELL_H
diff --git a/src/clipping/intersection.c b/src/clipping/intersection.c
new file mode 100644
index 0000000..5aac186
--- /dev/null
+++ b/src/clipping/intersection.c
@@ -0,0 +1,1395 @@
+/**
+ * @file intersection.c
+ * @brief Set of functions to determine the intersection between two edges
+ *
+ * very interesting literature:
+ * - http://geospatialmethods.org/spheres/GCIntersect.html
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#include <stdlib.h>
+#include <math.h>
+
+#include "utils.h"
+#include "geometry.h"
+
+static double const tol = 1.0e-12;
+
+static void crossproduct (double a[], double b[], double cross[]) {
+
+/* crossproduct in cartesian coordinates */
+
+   cross[0] = a[1] * b[2] - a[2] * b[1];
+   cross[1] = a[2] * b[0] - a[0] * b[2];
+   cross[2] = a[0] * b[1] - a[1] * b[0];
+}
+
+static int vector_is_between (double a[], double b[], double p[], double e_ab[]) {
+
+/* determines whether p is between a and b
+   (a, b, p are in the same plane AB)
+   e_ab is the crossproduct of a and b */
+
+   // if a and b are the same point
+   if (fabs(e_ab[0]) < tol && fabs(e_ab[1]) < tol && fabs(e_ab[2]) < tol) {
+
+      return fabs(a[0]-p[0]) < tol &&
+             fabs(a[1]-p[1]) < tol &&
+             fabs(a[2]-p[2]) < tol;
+   }
+
+   double cross_ap, cross_pb; // we only need one element of the cross product
+   int needed_index;
+
+   needed_index = 0;
+   if (fabs(e_ab[1]) > fabs(e_ab[0])) needed_index |= 1;
+   if (fabs(e_ab[2]) > fabs(e_ab[0])) needed_index |= 2;
+   if (fabs(e_ab[2]) > fabs(e_ab[1])) needed_index |= 4;
+
+   switch (needed_index) {
+      case (0): // index 0 is biggest value in e_ab
+      case (4):
+         cross_ap = a[1] * p[2] - a[2] * p[1];
+         cross_pb = p[1] * b[2] - p[2] * b[1];
+
+         return (e_ab[0] > - tol && cross_ap > - tol && cross_pb > - tol) ||
+                (e_ab[0] < + tol && cross_ap < + tol && cross_pb < + tol);
+
+      case (1): // index 1 is biggest value in e_ab
+      case (3):
+         cross_ap = a[2] * p[0] - a[0] * p[2];
+         cross_pb = p[2] * b[0] - p[0] * b[2];
+
+         return (e_ab[1] > - tol && cross_ap > - tol && cross_pb > - tol) ||
+                (e_ab[1] < + tol && cross_ap < + tol && cross_pb < + tol);
+
+      case (6): // index 2 is biggest value in e_ab
+      case (7):
+         cross_ap = a[0] * p[1] - a[1] * p[0];
+         cross_pb = p[0] * b[1] - p[1] * b[0];
+
+
+         return (e_ab[2] > - tol && cross_ap > - tol && cross_pb > - tol) ||
+                (e_ab[2] < + tol && cross_ap < + tol && cross_pb < + tol);
+
+      default:
+         abort_message("internal error", __FILE__, __LINE__);
+         // this function should never reach this point...
+         return -1;
+   };
+}
+
+/** \brief compute the intersection points of two great circles
+  *
+  * if p and q are != NULL they contain the intersection points
+  *
+  * the return value is :
+  *    -  0 if the intersection points are neither between (a and b) or (c and d)
+  *    - 1st bit will be set if p is between a and b
+  *    - 2nd bit will be set if q is between a and b
+  *    - 3rd bit will be set if p is between c and d
+  *    - 4th bit will be set if q is between c and d
+  *    - 5th bit will be set if both great circles are identically
+  *
+  * based on
+  * - http://www.geoclub.de/viewtopic.php?f=54&t=29689
+  **/
+
+ int gcxgc (struct edge edge_a, struct edge edge_b,
+            struct point * p, struct point * q) {
+
+   double a[3], b[3], c[3], d[3], p_[3], q_[3];
+
+   LLtoXYZ( edge_a.points[0].lon, edge_a.points[0].lat, a);
+   LLtoXYZ( edge_a.points[1].lon, edge_a.points[1].lat, b);
+   LLtoXYZ( edge_b.points[0].lon, edge_b.points[0].lat, c);
+   LLtoXYZ( edge_b.points[1].lon, edge_b.points[1].lat, d);
+
+   int ret_val =  gcxgc_vec(a, b, c, d, p_, q_);
+
+   if (p != NULL) XYZtoLL(p_, &(p->lon), &(p->lat));
+   if (q != NULL) XYZtoLL(q_, &(q->lon), &(q->lat));
+
+   return ret_val;
+}
+
+/** \brief compute the intersection points of two great circles
+  *
+  * if p and q are != NULL they contain the intersection points
+  *
+  * the return value is :
+  *    -  0 if the intersection points are neither between (a and b) or (c and d)
+  *    - 1st bit will be set if p is between a and b
+  *    - 2nd bit will be set if q is between a and b
+  *    - 3rd bit will be set if p is between c and d
+  *    - 4th bit will be set if q is between c and d
+  *    - 5th bit will be set if both great circles are identically
+  *
+  * based on
+  * - http://www.geoclub.de/viewtopic.php?f=54&t=29689
+  **/
+ int gcxgc_vec (double a[3], double b[3], double c[3], double d[3],
+                double p[3], double q[3]) {
+
+   double e_ab[3], e_cd[3], n;
+   double cross_ab[3], cross_cd[3];
+
+   // compute unit vector of ab plane
+   crossproduct(a, b, cross_ab);
+   n = 1.0 / sqrt(cross_ab[0] * cross_ab[0] +
+                  cross_ab[1] * cross_ab[1] +
+                  cross_ab[2] * cross_ab[2]);
+   e_ab[0] = cross_ab[0] * n;
+   e_ab[1] = cross_ab[1] * n;
+   e_ab[2] = cross_ab[2] * n;
+
+   // compute unit vector of cd plane
+   crossproduct(c, d, cross_cd);
+   n = 1.0 / sqrt(cross_cd[0] * cross_cd[0] +
+                  cross_cd[1] * cross_cd[1] +
+                  cross_cd[2] * cross_cd[2]);
+   e_cd[0] = cross_cd[0] * n;
+   e_cd[1] = cross_cd[1] * n;
+   e_cd[2] = cross_cd[2] * n;
+
+   double f1, f2;
+
+   // compute cos between e and c_/d_ times length of e
+   f1 = e_ab[0] * c[0] + e_ab[1] * c[1] + e_ab[2] * c[2];
+   f2 = e_ab[0] * d[0] + e_ab[1] * d[1] + e_ab[2] * d[2];
+
+   // if both great circles are nearly identically
+   if ((fabs(f1) < tol) && (fabs(f2) < tol)) {
+
+      int ret_value = 1 << 4;
+
+      int a_between_cd, b_between_cd, c_between_ab, d_between_ab;
+
+      a_between_cd = vector_is_between(c, d, a, cross_cd) << 0;
+      b_between_cd = vector_is_between(c, d, b, cross_cd) << 1;
+      c_between_ab = vector_is_between(a, b, c, cross_ab) << 2;
+      d_between_ab = vector_is_between(a, b, d, cross_ab) << 3;
+
+      switch (a_between_cd + b_between_cd + c_between_ab + d_between_ab) {
+
+         case (0):
+            p[0] = a[0], p[1] = a[1], p[2] = a[2];
+            q[0] = b[0], q[1] = b[1], q[2] = b[2];
+            ret_value |= 1 + 2;
+            return ret_value;
+         case (1+2):
+         case (1+2+4):
+         case (1+2+8):
+            p[0] = a[0], p[1] = a[1], p[2] = a[2];
+            q[0] = b[0], q[1] = b[1], q[2] = b[2];
+            break;
+         case (1+4):
+         case (1+4+8):
+            p[0] = a[0], p[1] = a[1], p[2] = a[2];
+            q[0] = c[0], q[1] = c[1], q[2] = c[2];
+            break;
+         case (1+8):
+            p[0] = a[0], p[1] = a[1], p[2] = a[2];
+            q[0] = d[0], q[1] = d[1], q[2] = d[2];
+            break;
+         case (2+4):
+         case (2+4+8):
+            p[0] = b[0], p[1] = b[1], p[2] = b[2];
+            q[0] = c[0], q[1] = c[1], q[2] = c[2];
+            break;
+         case (2+8):
+            p[0] = b[0], p[1] = b[1], p[2] = b[2];
+            q[0] = d[0], q[1] = d[1], q[2] = d[2];
+            break;
+         case (4+8):
+            p[0] = c[0], p[1] = c[1], p[2] = c[2];
+            q[0] = d[0], q[1] = d[1], q[2] = d[2];
+            break;
+         case (1+2+4+8):
+            p[0] = a[0], p[1] = a[1], p[2] = a[2];
+            q[0] = a[0], q[1] = a[1], q[2] = a[2];
+            break;
+         default:
+            abort_message("internal error", __FILE__, __LINE__);
+      }
+
+      ret_value |= 1 + 2 + 4 + 8;
+
+      return ret_value;
+   }
+
+   double g[3];
+
+   // compute line intersection of both planes defined by the two great circles
+   if (fabs(f1) > fabs(f2)) {
+
+      n = - (f2 / f1);
+
+      g[0] = n * c[0] + d[0];
+      g[1] = n * c[1] + d[1];
+      g[2] = n * c[2] + d[2];
+
+   } else {
+
+      n = - (f1 / f2);
+
+      g[0] = c[0] + n * d[0];
+      g[1] = c[1] + n * d[1];
+      g[2] = c[2] + n * d[2];
+   }
+
+   // normalise g
+   n = 1.0 / sqrt(g[0] * g[0] + g[1] * g[1] + g[2] * g[2]);
+
+   g[0]=g[0]*n;
+   g[1]=g[1]*n;
+   g[2]=g[2]*n;
+
+   // determine p and q
+   double p_[3], q_[3];
+
+   p_[0]= g[0];
+   p_[1]= g[1];
+   p_[2]= g[2];
+
+   q_[0]=-p_[0];
+   q_[1]=-p_[1];
+   q_[2]=-p_[2];
+
+   // set p and q
+   if (p != 0) {
+      p[0] = p_[0];
+      p[1] = p_[1];
+      p[2] = p_[2];
+   }
+   if (q != 0) {
+      q[0] = q_[0];
+      q[1] = q_[1];
+      q[2] = q_[2];
+   }
+
+   int result;
+
+   result = 0;
+   if (vector_is_between(a, b, p_, e_ab)) result |= 1 << 0;
+   if (vector_is_between(a, b, q_, e_ab)) result |= 1 << 1;
+   if (vector_is_between(c, d, p_, e_cd)) result |= 1 << 2;
+   if (vector_is_between(c, d, q_, e_cd)) result |= 1 << 3;
+
+   return result;
+}
+
+/** \brief compute the intersection point two circles of latitude
+ *
+ * compute the intersection points of two circle of latitude
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ *      - 5th bit will be set if both edges are on the same circle of latitude
+ **/
+int latcxlatc (struct edge edge_a, struct edge edge_b,
+               struct point * p, struct point * q) {
+
+   // two circles of latitude can only intersect if they are on the same latitude
+   if (fabs(edge_a.points[0].lat - edge_b.points[0].lat) > tol)
+      return -1;
+
+   int ret_value = 1 << 4;
+
+   // if the circles are on a pole
+   if (fabs(fabs(edge_a.points[0].lat) - M_PI_2) < tol) {
+
+      if (p != NULL) *p = edge_a.points[0];
+      if (q != NULL) *q = edge_a.points[0];
+
+      ret_value |= 1 + 4;
+
+      return ret_value;
+   }
+
+   // check whether the two circles overlap
+   
+   double angle_ab;
+   double angle_ac;
+   double angle_ad;
+   double angle_bc;
+   double angle_bd;
+   double angle_cd;
+   double angle_cb;
+
+   angle_ab = fabs(get_angle(edge_a.points[0].lon, edge_a.points[1].lon));
+   angle_ac = fabs(get_angle(edge_a.points[0].lon, edge_b.points[0].lon));
+   angle_ad = fabs(get_angle(edge_a.points[0].lon, edge_b.points[1].lon));
+   angle_bc = fabs(get_angle(edge_a.points[1].lon, edge_b.points[0].lon));
+   angle_bd = fabs(get_angle(edge_a.points[1].lon, edge_b.points[1].lon));
+   angle_cd = fabs(get_angle(edge_b.points[0].lon, edge_b.points[1].lon));
+   angle_cb = fabs(get_angle(edge_b.points[0].lon, edge_a.points[1].lon));
+
+   int a_between_cd, b_between_cd, c_between_ab, d_between_ab;
+
+   a_between_cd = ((angle_cd + tol) > (angle_ac + angle_ad)) << 0;
+   b_between_cd = ((angle_cd + tol) > (angle_bc + angle_bd)) << 1;
+   c_between_ab = ((angle_ab + tol) > (angle_ac + angle_cb)) << 2;
+   d_between_ab = ((angle_ab + tol) > (angle_ad + angle_bd)) << 3;
+
+   switch (a_between_cd + b_between_cd + c_between_ab + d_between_ab) {
+      case (0):
+      {
+         if (p != NULL) *p = edge_a.points[0];
+         if (q != NULL) *q = edge_a.points[1];
+         ret_value |= 1 + 2;
+         return ret_value;
+      }
+      case (1+2):
+      case (1+2+4):
+      case (1+2+8):
+         if (p != NULL) *p = edge_a.points[0];
+         if (q != NULL) *q = edge_a.points[1];
+         break;
+      case (1+4):
+      case (1+4+8):
+         if (p != NULL) *p = edge_a.points[0];
+         if (q != NULL) *q = edge_b.points[0];
+         break;
+      case (1+8):
+         if (p != NULL) *p = edge_a.points[0];
+         if (q != NULL) *q = edge_b.points[1];
+         break;
+      case (2+4):
+      case (2+4+8):
+         if (p != NULL) *p = edge_a.points[1];
+         if (q != NULL) *q = edge_b.points[0];
+         break;
+      case (2+8):
+         if (p != NULL) *p = edge_a.points[1];
+         if (q != NULL) *q = edge_b.points[1];
+         break;
+      case (4+8):
+         if (p != NULL) *p = edge_b.points[0];
+         if (q != NULL) *q = edge_b.points[1];
+         break;
+      case (1+2+4+8):
+         if (p != NULL) *p = edge_a.points[0];
+         if (q != NULL) *q = edge_a.points[0];
+         break;
+      default:
+         abort_message("internal error", __FILE__, __LINE__);
+   }
+
+   if (angle_ab < tol || angle_cd < tol)
+      ret_value |= 1 + 4;
+   else
+      ret_value |= 1 + 2 + 4 + 8;
+
+   return ret_value;
+}
+
+/** \brief compute the intersection point two circles of latitude
+ *
+ * compute the intersection points of two circle of latitude
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ *      - 5th bit will be set if both edges are on the same circle of latitude
+ **/
+int latcxlatc_vec (double a[3], double b[3], double c[3], double d[3],
+                   double p[3], double q[3]) {
+
+   // two circles of latitude can only intersect if they are on the same latitude
+   if (fabs(a[2] - c[2]) > tol)
+      return -1;
+
+   int result = 16;
+
+   double cross_ab[3], cross_cd[3];
+
+   crossproduct(a, b, cross_ab);
+   crossproduct(c, d, cross_cd);
+
+   double a_[3] = {a[0], a[1], 0};
+   double b_[3] = {b[0], b[1], 0};
+   double c_[3] = {c[0], c[1], 0};
+   double d_[3] = {d[0], d[1], 0};
+
+   int a_between_cd, b_between_cd, c_between_ab, d_between_ab;
+
+   a_between_cd = vector_is_between(c_, d_, a_, cross_cd);
+   b_between_cd = vector_is_between(c_, d_, b_, cross_cd);
+   c_between_ab = vector_is_between(a_, b_, c_, cross_ab);
+   d_between_ab = vector_is_between(a_, b_, d_, cross_ab);
+
+   if (a_between_cd && b_between_cd && c_between_ab && d_between_ab) {
+
+      p[0] = a[0], p[1] = a[1], p[2] = a[2];
+      q[0] = a[0], q[1] = a[1], q[2] = a[2];
+
+      result |= 1 + 4;
+
+   } else if (a_between_cd) {
+
+      p[0] = a[0], p[1] = a[1], p[2] = a[2];
+
+      result |= 1 + 2 + 4 + 8;
+
+      if (b_between_cd) q[0] = b[0], q[1] = b[1], q[2] = b[2];
+      else if (c_between_ab) q[0] = c[0], q[1] = c[1], q[2] = c[2];
+      else if (d_between_ab) q[0] = d[0], q[1] = d[1], q[2] = d[2];
+      else abort_message("internal error", __FILE__, __LINE__);
+
+   } else if (b_between_cd) {
+
+      p[0] = b[0], p[1] = b[1], p[2] = b[2];
+
+      result |= 1 + 2 + 4 + 8;
+
+      if (c_between_ab) q[0] = c[0], q[1] = c[1], q[2] = c[2];
+      else if (d_between_ab) q[0] = d[0], q[1] = d[1], q[2] = d[2];
+      else abort_message("internal error", __FILE__, __LINE__);
+
+   } else if (c_between_ab && d_between_ab) {
+
+      p[0] = c[0], p[1] = c[1], p[2] = c[2];
+      q[0] = d[0], q[1] = d[1], q[2] = d[2];
+
+      result |= 1 + 2 + 4 + 8;
+
+   } else {
+
+      p[0] = a[0], p[1] = a[1], p[2] = a[2];
+      q[0] = b[0], q[1] = b[1], q[2] = b[2];
+
+      result |= 1 + 2;
+   }
+
+   return result;
+}
+
+/** \brief compute the intersection point two circles of longitude
+ *
+ * compute the intersection points of two circle of longitude
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ *      - 5th bit will be set if both edges are on the same circle of longitude
+ **/
+int loncxlonc (struct edge edge_a, struct edge edge_b,
+               struct point * p, struct point * q) {
+
+   double angle_ab = fabs(get_angle(edge_a.points[0].lon, edge_a.points[1].lon));
+   double angle_ac = fabs(get_angle(edge_a.points[0].lon, edge_b.points[0].lon));
+   double angle_ad = fabs(get_angle(edge_a.points[0].lon, edge_b.points[1].lon));
+   double angle_cd = fabs(get_angle(edge_b.points[0].lon, edge_b.points[1].lon));
+
+   int ret_value = 0;
+
+   // if both edges are on identical circles of longitude
+   if ((angle_ac < tol) || (fabs(M_PI - angle_ac) < tol)) {
+
+      ret_value |= 16;
+
+      // rotate circles to the equator (lat == 0)
+
+      double lon_a, lon_b, lon_c, lon_d;
+
+      lon_a = edge_a.points[0].lat;
+      lon_b = (angle_ab < tol)?(edge_a.points[1].lat):(M_PI - edge_a.points[1].lat);
+      lon_c = (angle_ac < tol)?(edge_b.points[0].lat):(M_PI - edge_b.points[0].lat);
+      lon_d = (angle_ad < tol)?(edge_b.points[1].lat):(M_PI - edge_b.points[1].lat);
+
+      double angle_ab_ = fabs(get_angle(lon_a, lon_b));
+      double angle_ac_ = fabs(get_angle(lon_a, lon_c));
+      double angle_ad_ = fabs(get_angle(lon_a, lon_d));
+      double angle_cb_ = fabs(get_angle(lon_c, lon_b));
+      double angle_cd_ = fabs(get_angle(lon_c, lon_d));
+      double angle_bc_ = fabs(get_angle(lon_b, lon_c));
+      double angle_bd_ = fabs(get_angle(lon_b, lon_d));
+
+      int a_between_cd, b_between_cd, c_between_ab, d_between_ab;
+
+      a_between_cd = ((angle_cd_ + tol) > (angle_ac_ + angle_ad_)) << 0;
+      b_between_cd = ((angle_cd_ + tol) > (angle_bc_ + angle_bd_)) << 1;
+      c_between_ab = ((angle_ab_ + tol) > (angle_ac_ + angle_cb_)) << 2;
+      d_between_ab = ((angle_ab_ + tol) > (angle_ad_ + angle_bd_)) << 3;
+
+      switch (a_between_cd + b_between_cd + c_between_ab + d_between_ab) {
+
+         case (0):
+         {
+            double temp = (edge_a.points[0].lat > 0)?M_PI_2:-M_PI_2;
+            if (p != NULL) *p = (struct point){.lon = 0, .lat = temp};
+            if (q != NULL) *q = (struct point){.lon = 0, .lat = -temp};
+            // if edge a goes across a pole
+            if ((angle_ab > tol) || (fabs(edge_a.points[0].lat) > (M_PI_2 - tol)) ||
+                                    (fabs(edge_a.points[1].lat) > (M_PI_2 - tol))) {
+
+               ret_value |= 1 << 0;
+            }
+            // if edge b goes across a pole
+            if ((angle_cd > tol) || (fabs(edge_b.points[0].lat) > (M_PI_2 - tol)) ||
+                                    (fabs(edge_b.points[1].lat) > (M_PI_2 - tol))) {
+
+               ret_value |= ((edge_b.points[0].lat > 0) ^ (temp < 0))?(1 << 2):(1 << 3);
+            }
+            return ret_value;
+         }
+         case (1+2):
+         case (1+2+4):
+         case (1+2+8):
+            if (p != NULL) *p = edge_a.points[0];
+            if (q != NULL) *q = edge_a.points[1];
+            break;
+         case (1+4):
+         case (1+4+8):
+            if (p != NULL) *p = edge_a.points[0];
+            if (q != NULL) *q = edge_b.points[0];
+            break;
+         case (1+8):
+            if (p != NULL) *p = edge_a.points[0];
+            if (q != NULL) *q = edge_b.points[1];
+            break;
+         case (2+4):
+         case (2+4+8):
+            if (p != NULL) *p = edge_a.points[1];
+            if (q != NULL) *q = edge_b.points[0];
+            break;
+         case (2+8):
+            if (p != NULL) *p = edge_a.points[1];
+            if (q != NULL) *q = edge_b.points[1];
+            break;
+         case (4+8):
+            if (p != NULL) *p = edge_b.points[0];
+            if (q != NULL) *q = edge_b.points[1];
+            break;
+         case (1+2+4+8):
+            if (p != NULL) *p = edge_a.points[0];
+            if (q != NULL) *q = edge_a.points[0];
+            break;
+         default:
+            abort_message("internal error", __FILE__, __LINE__);
+      }
+      ret_value |= 1 + 2 + 4 + 8;
+
+   } else {
+
+      double sign = (edge_a.points[0].lat > 0)?1.0:-1.0;
+
+      if (p != NULL)
+         p->lon = edge_a.points[0].lon, p->lat = M_PI_2 * sign;
+      if (q != NULL)
+         q->lon = edge_a.points[0].lon+M_PI, q->lat = -M_PI_2 * sign;
+
+      // if edge a goes across a pole
+      if ((angle_ab > tol) || (fabs(edge_a.points[0].lat) > (M_PI_2 - tol)) ||
+                              (fabs(edge_a.points[1].lat) > (M_PI_2 - tol))) {
+
+         ret_value |= 1 << 0;
+      }
+
+      // if edge b goes across a pole
+      if ((angle_cd > tol) || (fabs(edge_b.points[0].lat) > (M_PI_2 - tol)) ||
+                              (fabs(edge_b.points[1].lat) > (M_PI_2 - tol))) {
+
+         ret_value |= ((edge_b.points[0].lat > 0) ^ (sign < 0))?(1 << 2):(1 << 3);
+      }
+
+      // if both edges are only points at the poles
+      if ((fabs(edge_a.points[0].lat) > (M_PI_2 - tol)) &&
+          (fabs(edge_a.points[1].lat) > (M_PI_2 - tol)) &&
+          (fabs(edge_b.points[0].lat) > (M_PI_2 - tol)) &&
+          (fabs(edge_b.points[1].lat) > (M_PI_2 - tol)))
+         ret_value |= 1 << 4;
+   }
+
+   return ret_value;
+}
+
+/** \brief compute the intersection point two circles of longitude
+ *
+ * compute the intersection points of two circle of longitude
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ *      - 5th bit will be set if both edges are on the same circle of longitude
+ **/
+int loncxlonc_vec (double a[3], double b[3], double c[3], double d[3],
+                   double p[3], double q[3]) {
+
+   int ret_value = 0;
+
+   double cross_ab[3], cross_cd[3];
+
+   crossproduct(a, b, cross_ab);
+   crossproduct(c, d, cross_cd);
+
+   double abs_norm_cross_ab[2], abs_norm_cross_cd[2];
+
+   // abs_norm_cross_ab[2] = 0;
+   // abs_norm_cross_cd[2] = 0;
+
+   double * ref_point;
+
+   ref_point = (fabs(a[2]) > fabs(b[2]))?b:a;
+   // if both points are at the pole
+   if (fabs(ref_point[2]) > 1.0-tol) {
+      abs_norm_cross_ab[0] = 1;
+      abs_norm_cross_ab[1] = 0;
+      ret_value |= 16;
+   } else {
+      double scale = 1.0 / sqrt(ref_point[0]*ref_point[0] +
+                                ref_point[1]*ref_point[1]);
+      abs_norm_cross_ab[0] = ref_point[1] * scale;
+      abs_norm_cross_ab[1] = ref_point[0] * scale;
+      if (abs_norm_cross_ab[0] < 0) {
+         abs_norm_cross_ab[0] *= -1.0;
+         abs_norm_cross_ab[1] *= -1.0;
+      }
+   }
+
+   ref_point = (fabs(c[2]) > fabs(d[2]))?d:c;
+   // if both points are at the pole
+   if (fabs(ref_point[2]) > 1.0-tol) {
+      abs_norm_cross_cd[0] = 1;
+      abs_norm_cross_cd[1] = 0;
+      ret_value |= 16;
+   } else {
+      double scale = 1.0 / sqrt(ref_point[0]*ref_point[0] +
+                                ref_point[1]*ref_point[1]);
+      abs_norm_cross_cd[0] = ref_point[1] * scale;
+      abs_norm_cross_cd[1] = ref_point[0] * scale;
+      if (abs_norm_cross_cd[0] < 0) {
+         abs_norm_cross_cd[0] *= -1.0;
+         abs_norm_cross_cd[1] *= -1.0;
+      }
+   }
+
+   // if both edges are on the same circle of longitude
+   if (fabs(abs_norm_cross_ab[0] - abs_norm_cross_cd[0]) < tol &&
+       fabs(abs_norm_cross_ab[1] - abs_norm_cross_cd[1]) < tol) {
+
+      ret_value |= 16;
+
+      int a_between_cd, b_between_cd, c_between_ab, d_between_ab;
+
+      a_between_cd = vector_is_between(c, d, a, cross_cd) << 0;
+      b_between_cd = vector_is_between(c, d, b, cross_cd) << 1;
+      c_between_ab = vector_is_between(a, b, c, cross_ab) << 2;
+      d_between_ab = vector_is_between(a, b, d, cross_ab) << 3;
+
+      switch (a_between_cd + b_between_cd + c_between_ab + d_between_ab) {
+
+         case (0):
+            p[0] = 0, p[1] = 0, p[2] = 1;
+            q[0] = 0, q[1] = 0, q[2] = -1;
+            break;
+         case (1+2):
+         case (1+2+4):
+         case (1+2+8):
+            p[0] = a[0], p[1] = a[1], p[2] = a[2];
+            q[0] = b[0], q[1] = b[1], q[2] = b[2];
+            break;
+         case (1+4):
+         case (1+4+8):
+            p[0] = a[0], p[1] = a[1], p[2] = a[2];
+            q[0] = c[0], q[1] = c[1], q[2] = c[2];
+            break;
+         case (1+8):
+            p[0] = a[0], p[1] = a[1], p[2] = a[2];
+            q[0] = d[0], q[1] = d[1], q[2] = d[2];
+            break;
+         case (2+4):
+         case (2+4+8):
+            p[0] = b[0], p[1] = b[1], p[2] = b[2];
+            q[0] = c[0], q[1] = c[1], q[2] = c[2];
+            break;
+         case (2+8):
+            p[0] = b[0], p[1] = b[1], p[2] = b[2];
+            q[0] = d[0], q[1] = d[1], q[2] = d[2];
+            break;
+         case (4+8):
+            p[0] = c[0], p[1] = c[1], p[2] = c[2];
+            q[0] = d[0], q[1] = d[1], q[2] = d[2];
+            break;
+         case (1+2+4+8):
+            p[0] = a[0], p[1] = a[1], p[2] = a[2];
+            q[0] = a[0], q[1] = a[1], q[2] = a[2];
+            break;
+         default:
+            abort_message("internal error", __FILE__, __LINE__);
+      }
+
+   } else {
+
+      p[0] = 0, p[1] = 0; p[2] = 1;
+      q[0] = 0, q[1] = 0; q[2] = -1;
+   }
+
+   if (vector_is_between(a, b, p, cross_ab)) ret_value |= 1;
+   if (vector_is_between(a, b, q, cross_ab)) ret_value |= 2;
+   if (vector_is_between(c, d, p, cross_cd)) ret_value |= 4;
+   if (vector_is_between(c, d, q, cross_cd)) ret_value |= 8;
+
+   return ret_value;
+}
+
+/** \brief compute the intersection point of a meridian and a parallel
+ *
+ * compute the intersection points of a circle of longitude (defined by a and b)
+ * and a circle of latitude (defined by c and d)
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ **/
+int loncxlatc (struct edge edge_a, struct edge edge_b,
+               struct point * p, struct point * q) {
+
+   double lon_a, lat_a[2];
+   double lon_b[2], lat_b;
+
+   unsigned ret_value;
+
+   ret_value = 0;
+
+   lon_a = edge_a.points[0].lon;
+
+   if (edge_a.points[0].lat > edge_a.points[1].lat) {
+
+      lat_a[0] = edge_a.points[1].lat;
+      lat_a[1] = edge_a.points[0].lat;
+   } else {
+      lat_a[0] = edge_a.points[0].lat;
+      lat_a[1] = edge_a.points[1].lat;
+   }
+
+   lat_b = edge_b.points[0].lat;
+
+   if (edge_b.points[0].lon > edge_b.points[1].lon) {
+
+      lon_b[0] = edge_b.points[1].lon;
+      lon_b[1] = edge_b.points[0].lon;
+   } else {
+      lon_b[0] = edge_b.points[0].lon;
+      lon_b[1] = edge_b.points[1].lon;
+   }
+
+   unsigned a_goes_across_pole;
+   unsigned b_is_on_pole;
+
+   a_goes_across_pole = fabs(get_angle(edge_a.points[0].lon,
+                                           edge_a.points[1].lon)) > tol;
+   b_is_on_pole = fabs(M_PI_2 - fabs(lat_b)) < tol;
+
+   if (b_is_on_pole) {
+
+      if (p != NULL) *p = edge_b.points[0];
+      if (q != NULL) *q = edge_b.points[1];
+
+      if (((a_goes_across_pole) && (fabs(lat_b - lat_a[0]) < M_PI_2)) ||
+          ((fabs(lat_b - lat_a[0]) < tol) ||
+           (fabs(lat_b - lat_a[1]) < tol))){
+
+         ret_value |= 1;
+      }
+
+      ret_value |= 4;
+
+   } else {
+
+      if (p != NULL) p->lon = lon_a, p->lat = lat_b;
+      if (q != NULL) q->lon = lon_a + M_PI, q->lat = lat_b;
+
+      double angle_cd, angle_cp, angle_cq;
+
+      angle_cd = get_angle(lon_b[0], lon_b[1]);
+      angle_cp = get_angle(lon_b[0], lon_a);
+      angle_cq = get_angle(lon_b[0], lon_a + M_PI);
+
+      if (angle_cd > 0) {
+         if (angle_cp <= angle_cd + tol && angle_cp > -tol) ret_value |= 1 << 2;
+         if (angle_cq <= angle_cd + tol && angle_cq > -tol) ret_value |= 1 << 3;
+      } else {
+         if (angle_cp >= angle_cd - tol && angle_cp < tol) ret_value |= 1 << 2;
+         if (angle_cq >= angle_cd - tol && angle_cq < tol) ret_value |= 1 << 3;
+      }
+
+      if (a_goes_across_pole) {
+
+         if (lat_a[0] > 0.0) {
+
+            if (lat_b > lat_a[0]) ret_value |= 1 << 0;
+            if (lat_b > lat_a[1]) ret_value |= 1 << 1;
+
+         } else {
+
+            if (lat_b < lat_a[0]) ret_value |= 1 << 0;
+            if (lat_b < lat_a[1]) ret_value |= 1 << 1;
+         }
+      } else if ((lat_b >= lat_a[0]) && (lat_b <= lat_a[1])) ret_value |= 1 << 0;
+   }
+
+   return ret_value;
+}
+
+/** \brief compute the intersection point of a meridian and a parallel
+ *
+ * compute the intersection points of a circle of longitude (defined by a and b)
+ * and a circle of latitude (defined by c and d)
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *      - 0 if the intersection points are neither between (a and b) or (c and d)
+ *      - -1 if an error occurred
+ *      - 1st bit will be set if p is between a and b
+ *      - 2nd bit will be set if q is between a and b
+ *      - 3rd bit will be set if p is between c and d
+ *      - 4th bit will be set if q is between c and d
+ **/
+int loncxlatc_vec (double a[3], double b[3], double c[3], double d[3],
+                   double p[3], double q[3]) {
+
+   unsigned ret_value;
+
+   ret_value = 0;
+
+   if (fabs(a[0] * b[1] - a[1] * b[0]) > tol)
+      abort_message("edge is not a circle of longitude", __FILE__, __LINE__);
+
+   unsigned ab_goes_across_pole;
+   unsigned cd_is_on_pole;
+   unsigned ab_is_point;
+   unsigned cd_is_point;
+
+   ab_goes_across_pole =
+      ((fabs(1.0 - fabs(a[2])) < tol || fabs(1.0 - fabs(b[2])) < tol) ||
+       (((a[0] > 0.0) ^ (b[0] > 0.0)) && ((a[1] > 0.0) ^ (b[1] > 0.0))));
+
+   cd_is_on_pole = fabs(1.0 - fabs(c[2])) < tol;
+
+   ab_is_point = fabs(a[0]-b[0]) < tol &&
+                 fabs(a[1]-b[1]) < tol &&
+                 fabs(a[2]-b[2]) < tol;
+
+   cd_is_point = fabs(c[0]-d[0]) < tol &&
+                 fabs(c[1]-d[1]) < tol &&
+                 fabs(c[2]-d[2]) < tol;
+
+   if (cd_is_on_pole) {
+
+      if (((ab_goes_across_pole) && (fabs(a[2] - c[2]) < 1.0)) ||
+          ((fabs(a[2] - c[2]) < tol)) || (fabs(b[2] - c[2]) < tol))
+         ret_value |= 1;
+
+         if (p != NULL)
+            p[0] = c[0], p[1] = c[1], p[2] = c[2];
+         if (q != NULL)
+            q[0] = c[0], q[1] = c[1], q[2] = c[2];
+
+      ret_value |= 4;
+
+   } else {
+
+      /*
+      // the cos is too inaccurate close to the equator
+      {
+         if (fabs(a[2]) < fabs(b[2])) {
+
+            double scale = cos(c[2]) / cos(a[2]);
+
+            if (p != NULL)
+               p[0] = a[0] * scale, p[1] = a[1] * scale, p[2] = c[2];
+            if (q != NULL)
+               q[0] = -a[0] * scale, q[1] = -a[1] * scale, q[2] = c[2];
+         } else {d
+
+            double scale = cos(c[2]) / cos(b[2]);
+
+            if (p != NULL)
+               p[0] = b[0] * scale, p[1] = b[1] * scale, p[2] = c[2];
+            if (q != NULL)
+               q[0] = -b[0] * scale, q[1] = -b[1] * scale, q[2] = c[2];
+         }
+      }
+      */
+      {
+
+         if (fabs(a[2]) < fabs(b[2])) {
+
+            double scale = sqrt((1.0 - c[2] * c[2])/
+                                (a[0] * a[0] + a[1] * a[1]));
+
+            if (p != NULL)
+               p[0] = a[0] * scale, p[1] = a[1] * scale, p[2] = c[2];
+            if (q != NULL)
+               q[0] = -a[0] * scale, q[1] = -a[1] * scale, q[2] = c[2];
+
+         } else {
+
+            double scale = sqrt((1.0 - c[2] * c[2])/
+                                (b[0] * b[0] + b[1] * b[1]));
+
+            if (p != NULL)
+               p[0] = b[0] * scale, p[1] = b[1] * scale, p[2] = c[2];
+            if (q != NULL)
+               q[0] = -b[0] * scale, q[1] = -b[1] * scale, q[2] = c[2];
+         }
+      }
+
+      
+
+      if (cd_is_point) {
+
+         if (fabs(c[0]-p[0]) < tol &&
+             fabs(c[1]-p[1]) < tol &&
+             fabs(c[2]-p[2]) < tol) ret_value |= 1 << 2;
+         if (fabs(c[0]-q[0]) < tol &&
+             fabs(c[1]-q[1]) < tol &&
+             fabs(c[2]-q[2]) < tol) ret_value |= 1 << 3;
+
+      } else {
+
+         double angle_cd, angle_cp, angle_dp, angle_cq, angle_dq;
+
+         angle_cd = get_vector_angle(c, d);
+         angle_cp = get_vector_angle(c, p);
+         angle_dp = get_vector_angle(d, p);
+         angle_cq = get_vector_angle(c, q);
+         angle_dq = get_vector_angle(d, q);
+
+         if (angle_cp < tol || angle_dp < tol ||
+             (angle_cp < angle_cd + tol && angle_dp < angle_cd + tol))
+            ret_value |= 1 << 2;
+         if (angle_cq < tol || angle_dq < tol ||
+             (angle_cq < angle_cd + tol && angle_dq < angle_cd + tol))
+            ret_value |= 1 << 3;
+      }
+
+      if (ab_is_point) {
+         if (fabs(a[0]-p[0]) < tol &&
+             fabs(a[1]-p[1]) < tol &&
+             fabs(a[2]-p[2]) < tol) ret_value |= 1 << 0;
+         if (fabs(a[0]-q[0]) < tol &&
+             fabs(a[1]-q[1]) < tol &&
+             fabs(a[2]-q[2]) < tol) ret_value |= 1 << 1;
+      } else {
+
+         double cross_ab[3];
+
+         crossproduct(a, b, cross_ab);
+
+         if (vector_is_between(a, b, p, cross_ab)) ret_value |= 1 << 0;
+         if (vector_is_between(a, b, q, cross_ab)) ret_value |= 1 << 1;
+      }
+   }
+
+   return ret_value;
+}
+
+/** \brief compute the intersection of a great circle with the parallel
+ *
+ *  compute the intersection points of a great circle (defined by a and b)
+ * and a circle of latitude (defined by c and d)
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *    - 0 if the intersection points are neither between (a and b) or (c and d)
+ *    - -1 if the two circles do not intersect or an error occurred
+ *    - 1st bit will be set if p is between a and b
+ *    - 2nd bit will be set if q is between a and b
+ *    - 3rd bit will be set if p is between c and d
+ *    - 4th bit will be set if q is between c and d
+ *    - 5th bit will be set if both circles are identically
+ *
+ *   based on
+ *   - http://geospatialmethods.org/spheres/GCIntersect.html
+ **/
+int gcxlatc(struct edge edge_a, struct edge edge_b,
+            struct point * p, struct point * q) {
+
+   // if the great circle is nearly a lon circle, then the accuracy of the normal
+   // computation gets messy, therefore we handle it as a lon circle...
+
+   if (fabs(edge_a.points[0].lon - edge_a.points[1].lon) < tol) {
+
+      edge_a.points[0].lon = edge_a.points[1].lon = (edge_a.points[0].lon + edge_a.points[1].lon) / 2.0;
+      edge_a.edge_type = LON_CIRCLE;
+
+      return loncxlatc(edge_a, edge_b, p, q);
+   }
+
+   // if the great circle is the equator, we handle the great circle as a circle of latitude
+   if (fabs(edge_a.points[0].lat) < tol && fabs(edge_a.points[1].lat) < tol) {
+
+      edge_a.points[0].lat = edge_a.points[1].lat = 0;
+      edge_a.edge_type = LAT_CIRCLE;
+      return latcxlatc(edge_a, edge_b, p, q);
+   }
+
+   double a[3], b[3], c[3], d[3], p_[3], q_[3];
+
+   LLtoXYZ(edge_a.points[0].lon, edge_a.points[0].lat, a);
+   LLtoXYZ(edge_a.points[1].lon, edge_a.points[1].lat, b);
+   LLtoXYZ(edge_b.points[0].lon, edge_b.points[0].lat, c);
+   LLtoXYZ(edge_b.points[1].lon, edge_b.points[1].lat, d);
+
+   int ret_value = gcxlatc_vec(a, b, c, d, p_, q_);
+
+   if (ret_value == -1) return -1;
+
+   if (p != NULL) XYZtoLL(p_, &p->lon, &p->lat);
+   if (q != NULL) XYZtoLL(q_, &q->lon, &q->lat);
+
+   return ret_value;
+}
+
+/** \brief compute the intersection of a great circle with the parallel
+ *
+ *  compute the intersection points of a great circle (defined by a and b)
+ * and a circle of latitude (defined by c and d)
+ * if p and q are != NULL they contain the intersection points
+ * the return value is:
+ *    - 0 if the intersection points are neither between (a and b) or (c and d)
+ *    - -1 if the two circles do not intersect or an error occurred
+ *    - 1st bit will be set if p is between a and b
+ *    - 2nd bit will be set if q is between a and b
+ *    - 3rd bit will be set if p is between c and d
+ *    - 4th bit will be set if q is between c and d
+ *    - 5th bit will be set if both circles are identically
+ * \remarks if -1 is returned neither p or q is set
+ * \remarks if the two circles only have one intersection point,
+ *          p and q will be identically, but only the p bits will be set
+ **/
+
+int gcxlatc_vec(double a[3], double b[3], double c[3], double d[3],
+                double p[3], double q[3]) {
+
+   unsigned result = 0;
+
+   double cross_ab[3], scale;
+   
+   crossproduct(a, b, cross_ab);
+   scale = sqrt(cross_ab[0]*cross_ab[0]+
+                cross_ab[1]*cross_ab[1]+
+                cross_ab[2]*cross_ab[2]);
+
+   // if the great circle is the equator
+   if (fabs(a[2]) < tol && fabs(b[2]) < tol) {
+
+      return latcxlatc_vec(a, b, c, d, p, q);
+
+   // if the great circle is  a circle of longitude
+   } else if (scale < tol || fabs(cross_ab[2]/scale) < tol) {
+
+      return loncxlatc_vec(a, b, c, d, p, q);
+   }
+
+   double t[3], s[3];
+
+   if (fabs(a[2]) > fabs(b[2])) {
+
+      double scale = c[2] / a[2];
+
+      t[0] = scale * a[0];
+      t[1] = scale * a[1];
+      
+   } else {
+
+      double scale = c[2] / b[2];
+
+      t[0] = scale * b[0];
+      t[1] = scale * b[1];
+   }
+
+   t[2] = c[2];
+
+   s[2] = 0;
+
+   if (fabs(a[2]) < tol)
+      s[0] = a[0], s[1] = a[1];
+   else if (fabs(b[2]) < tol)
+      s[0] = b[0], s[1] = b[1];
+   else if (fabs(a[2]) > fabs(b[2])) {
+      double scale = b[2] / a[2];
+      s[0] = b[0] - scale * a[0];
+      s[1] = b[1] - scale * a[1];
+   } else {
+      double scale = a[2] / b[2];
+      s[0] = a[0] - scale * b[0];
+      s[1] = a[1] - scale * b[1];
+   }
+
+   if (fabs(s[0]) < tol && fabs(s[1]) < tol)
+      abort_message("internal error", __FILE__, __LINE__);
+
+   {
+      // the intersection of the planes of both circles is defined by:
+      // x = t + n * s
+
+      // x_0^2 + x_1^2 + x_2^2 = 1
+      // x_2 = c_2
+
+      double a_ = s[0] * s[0] + s[1] * s[1];
+      double b_ = 2.0 * (t[0] * s[0] + t[1] * s[1]);
+      double c_ = t[0] * t[0] + t[1] * t[1] + c[2] * c[2] - 1.0;
+
+      double temp = b_ * b_ - 4.0 * a_ * c_;
+
+      // no intersection possible
+      if (temp < 0.0) {
+        if (temp < -tol)
+          return -1;
+        else
+          temp = 0;
+      }
+
+      double n[2];
+
+      n[0] = - (b_ + sqrt(temp)) / (2.0 * a_);
+      n[1] = - (b_ - sqrt(temp)) / (2.0 * a_);
+
+      p[0] = t[0] + n[0] * s[0];
+      p[1] = t[1] + n[0] * s[1];
+      p[2] = t[2] + n[0] * s[2];
+
+      double cross_cd[3] = {0, 0, c[0]*d[1]-c[1]*d[0]};
+      double temp_c[3] = {c[0], c[1], 0};
+      double temp_d[3] = {d[0], d[1], 0};
+      double temp_p[3] = {p[0], p[1], 0};
+
+      if (vector_is_between(a, b, p, cross_ab)) result |= 1;
+      if (vector_is_between(temp_c, temp_d, temp_p, cross_cd)) result |= 4;
+
+      if (fabs(n[0] - n[1]) >= tol) {
+
+         q[0] = t[0] + n[1] * s[0];
+         q[1] = t[1] + n[1] * s[1];
+         q[2] = t[2] + n[1] * s[2];
+
+         double temp_q[3] = {q[0], q[1], 0};
+
+         if (vector_is_between(a, b, q, cross_ab)) result |= 2;
+         if (vector_is_between(temp_c, temp_d, temp_q, cross_cd)) result |= 8;
+      } else
+         q[0] = p[0], q[1] = p[1], q[2] = p[2];
+   }
+
+   return result;
+}
+
+int intersect (struct edge const edge_a, struct edge const edge_b,
+               struct point * intersection) {
+
+   int switch_edges;
+
+   switch_edges = 0;
+
+   int (*intersect_func)(struct edge, struct edge, struct point *, struct point *);
+
+   // if both edges are on circles of latitude
+   if (edge_a.edge_type == LAT_CIRCLE && edge_b.edge_type == LAT_CIRCLE) {
+
+      intersect_func = latcxlatc;
+
+   // if both edges are on circle of longitude
+   } else if (edge_a.edge_type == LON_CIRCLE && edge_b.edge_type == LON_CIRCLE) {
+
+      intersect_func = loncxlonc;
+
+   // if both edges are on great circles
+   } else if ((edge_a.edge_type == GREAT_CIRCLE &&
+        edge_b.edge_type == GREAT_CIRCLE) ||
+       (edge_a.edge_type == LON_CIRCLE   &&
+        edge_b.edge_type == GREAT_CIRCLE) ||
+       (edge_a.edge_type == GREAT_CIRCLE &&
+        edge_b.edge_type == LON_CIRCLE)) {
+
+      intersect_func = gcxgc;
+
+   // if one edge a is on a great circle and edge b on a circle of latitude
+   } else if (edge_a.edge_type == GREAT_CIRCLE &&
+              edge_b.edge_type == LAT_CIRCLE) {
+
+      intersect_func = gcxlatc;
+
+   // if one edge a is on a circle of latitude and edge b on a great circle
+   } else if (edge_a.edge_type == LAT_CIRCLE &&
+              edge_b.edge_type == GREAT_CIRCLE ) {
+
+      switch_edges = 1;
+      intersect_func = gcxlatc;
+
+   // if one edge a is on a circle of longitude and edge b on a circle of latitude
+   } else if (edge_a.edge_type == LON_CIRCLE &&
+              edge_b.edge_type == LAT_CIRCLE) {
+
+      intersect_func = loncxlatc;
+
+   // if one edge a is on a circle of latitude and edge b on a circle of longitude
+   } else if (edge_a.edge_type == LAT_CIRCLE &&
+              edge_b.edge_type == LON_CIRCLE ) {
+
+      switch_edges = 1;
+      intersect_func = loncxlatc;
+
+   } else {
+
+      abort_message ( "ERROR: unknown edge type.", __FILE__, __LINE__ );
+      exit(EXIT_FAILURE);
+   }
+
+   unsigned const p_on_a = 1 << 0;
+   unsigned const q_on_a = 1 << 1;
+   unsigned const p_on_b = 1 << 2;
+   unsigned const q_on_b = 1 << 3;
+
+   int ret_value;
+
+   struct point p, q;
+
+   // compute the intersection between both circles
+   if (switch_edges) ret_value = intersect_func(edge_b, edge_a, &p, &q);
+   else              ret_value = intersect_func(edge_a, edge_b, &p, &q);
+
+   // check whether the circles defined by the edges intersect
+   if (ret_value > 0) {
+
+      // check for intersection of the edges
+      if ( (ret_value & p_on_a) && (ret_value & p_on_b) ) {
+
+         if (intersection != NULL) *intersection = p;
+         return 1;
+
+      } else if ( (ret_value & q_on_a) && (ret_value & q_on_b) ) {
+
+         if (intersection != NULL) *intersection = q;
+         return 1;
+      }
+   }
+   return 0;
+}
+
+int intersect_vec (enum edge_type edge_type_a, double a[3], double b[3],
+                   enum edge_type edge_type_b, double c[3], double d[3],
+                   double p[3], double q[3]) {
+
+   int switch_edges;
+
+   switch_edges = 0;
+
+   int (*intersect_func)(double *, double *, double *, double *, double *, double *);
+
+   // if both edges are on circles of latitude
+   if (edge_type_a == LAT_CIRCLE &&
+       edge_type_b == LAT_CIRCLE) {
+
+      intersect_func = latcxlatc_vec;
+
+   // if both edges are on circle of longitude
+   } else if (edge_type_a == LON_CIRCLE &&
+              edge_type_b == LON_CIRCLE) {
+
+      intersect_func = loncxlonc_vec;
+
+   // if both edges are on great circles
+   } else if ((edge_type_a == GREAT_CIRCLE &&
+               edge_type_b == GREAT_CIRCLE) ||
+              (edge_type_a == LON_CIRCLE   &&
+               edge_type_b == GREAT_CIRCLE) ||
+              (edge_type_a == GREAT_CIRCLE &&
+               edge_type_b == LON_CIRCLE)) {
+
+      intersect_func = gcxgc_vec;
+
+   // if one edge a is on a great circle and edge b on a circle of latitude
+   } else if (edge_type_a == GREAT_CIRCLE &&
+              edge_type_b == LAT_CIRCLE) {
+
+      intersect_func = gcxlatc_vec;
+
+   // if one edge a is on a circle of latitude and edge b on a great circle
+   } else if (edge_type_a == LAT_CIRCLE &&
+              edge_type_b == GREAT_CIRCLE ) {
+
+      switch_edges = 1;
+      intersect_func = gcxlatc_vec;
+
+   // if one edge a is on a circle of longitude and edge b on a circle of latitude
+   } else if (edge_type_a == LON_CIRCLE &&
+              edge_type_b == LAT_CIRCLE) {
+
+      intersect_func = loncxlatc_vec;
+
+   // if one edge a is on a circle of latitude and edge b on a circle of longitude
+   } else if (edge_type_a == LAT_CIRCLE &&
+              edge_type_b == LON_CIRCLE ) {
+
+      switch_edges = 1;
+      intersect_func = loncxlatc_vec;
+
+   } else {
+
+      abort_message ( "ERROR: unknown edge type.", __FILE__, __LINE__ );
+      exit(EXIT_FAILURE);
+   }
+
+   int ret_value;
+
+   // compute the intersection between both circles
+   if (switch_edges) ret_value = intersect_func(c, d, a, b, p, q);
+   else              ret_value = intersect_func(a, b, c, d, p, q);
+
+   if (switch_edges)
+      ret_value = (ret_value & (~(1 + 2 + 4 + 8))) +
+                  ((ret_value & (1 + 2)) << 2) +
+                  ((ret_value & (4 + 8)) >> 2);
+
+   return ret_value;
+}
diff --git a/src/clipping/points.h b/src/clipping/points.h
new file mode 100644
index 0000000..e3d75e1
--- /dev/null
+++ b/src/clipping/points.h
@@ -0,0 +1,103 @@
+/**
+ * @file points.h
+ * @brief Structs and interfaces for points
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#ifndef POINTS_H
+#define POINTS_H
+
+/** \example test_points.c
+ * This shows how to work with struct points.
+ */
+
+#include "grid.h"
+
+enum location {
+
+   CELL =   0,
+   CORNER = 1,
+   EDGE =   2,
+};
+
+struct points {
+
+   enum location location;
+
+   double * coordinates_x, * coordinates_y;
+
+   struct grid * base_grid;
+
+   struct grid * point_grid;
+};
+
+enum location get_location(int const location);
+
+/**
+ * initialises a struct points
+ * @param[in,out] points        points to be initialised
+ * @param[in]     base_grid     grid on which the points situated
+ * @param[in]     location      location of the points
+ * @param[in]     coordinates_x x coordinates of the points
+ * @param[in]     coordinates_y y coordinates of the points
+ *
+ * \remarks - for CORNER and CELL points the coordinates need to be provided in the same
+ *            way that is used to initialise the base_grid
+ * \remarks - for EDGE points the coordinates need to have an entry for each edge (in
+ *            the order of the local ids)
+ */
+void init_points(struct points * points, struct grid * base_grid, enum location location,
+                 double * coordinates_x, double * coordinates_y);
+
+/**
+ * returns a grid that has the points defined by the struct points as corners
+ * @param[in] points points for which the point grid is to be generated
+ * @return a point grid
+ *
+ * \remarks does not work for EDGE
+ */
+struct grid * get_point_grid(struct points * points);
+struct grid * get_base_grid(struct points * points);
+
+void get_coordinate_array_sizes (struct grid * grid, enum location location, unsigned * sizes);
+
+/**
+ * returns the number of points in the struct points
+ * @param[in] points
+ * @return number of points
+ */
+unsigned get_data_size(struct points points);
+
+void get_point_coordinates (struct points * points, unsigned local_point_id,
+                            double * coordinates);
+
+void free_points(struct points * points);
+
+#endif // POINTS_H
diff --git a/src/clipping/utils.c b/src/clipping/utils.c
new file mode 100644
index 0000000..1fdc995
--- /dev/null
+++ b/src/clipping/utils.c
@@ -0,0 +1,99 @@
+/**
+ * @file utils.c
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+static void ** pointer_lookup_table = NULL;
+static unsigned pointer_lookup_table_size = 0;
+
+unsigned pointer_to_unique_id(void * pointer) {
+
+   pointer_lookup_table = realloc (pointer_lookup_table,
+      ++pointer_lookup_table_size * sizeof(pointer_lookup_table[0]));
+
+   pointer_lookup_table[pointer_lookup_table_size-1] = pointer;
+
+   return pointer_lookup_table_size - 1;
+}
+
+void * unique_id_to_pointer(unsigned id) {
+
+   if (id < pointer_lookup_table_size)
+      return pointer_lookup_table[id];
+   else
+      return NULL;
+}
+
+void free_pointer_unique_lookup() {
+
+  free(pointer_lookup_table);
+  pointer_lookup_table = NULL;
+  pointer_lookup_table_size = 0;
+}
+
+void abort_message ( char * text, char * file, int line )
+{
+  fprintf(stderr, "%s \n", text); 
+  fprintf(stderr, "Aborting in file %s, line %i ...\n", file, line );
+  exit(EXIT_FAILURE);
+}
+
+/* ------------------------------------
+
+   Source: http://www.cse.yorku.ca/~oz/hash.html 
+
+unsigned long hash(const char *str) {
+
+  unsigned long hash = 5381;
+  int c;
+
+  while ((c = *str++))
+    hash = ((hash << 5) + hash) + c; 
+
+  return hash;
+}
+
+  ------------------------------------*/
+
+/*  Source http://snipplr.com/view/9022/string-hash-table/ */
+
+#define NHASH 29989 //Use a prime number!
+#define MULT 31
+
+unsigned int hash(const char *str) {
+  unsigned int h = 0;
+  for(; *str; str++)
+    h = MULT * h + *str;
+  return h % NHASH;
+}
diff --git a/src/clipping/utils.h b/src/clipping/utils.h
new file mode 100644
index 0000000..301ca70
--- /dev/null
+++ b/src/clipping/utils.h
@@ -0,0 +1,115 @@
+/**
+ * @file utils.h
+ * @brief Utlity functions
+ *
+ * Small general utility functions:
+ *  - pointer-id conversion
+ *  - hash
+ *  - sorting
+ *
+ * @copyright Copyright  (C)  2013 Moritz Hanke <hanke at dkrz.de>
+ *                                 Rene Redler <rene.redler at mpimet.mpg.de>
+ *
+ * @version 1.0
+ * @author Moritz Hanke <hanke at dkrz.de>
+ *         Rene Redler <rene.redler at mpimet.mpg.de>
+ */
+/*
+ * Keywords:
+ * Maintainer: Moritz Hanke <hanke at dkrz.de>
+ *             Rene Redler <rene.redler at mpimet.mpg.de>
+ * URL: https://redmine.dkrz.de/doc/YAC/html/index.html
+ *
+ * This file is part of YAC.
+ *
+ * YAC 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.
+ *
+ * YAC 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 YAC.  If not, see <http://www.gnu.org/licenses/gpl.txt>.
+ */
+
+#ifndef UTILS_H
+#define UTILS_H
+
+/**
+ * gives a unique index for a given pointer
+ * @param[in] pointer
+ * @return unique value associated to pointer
+ * @see unique_id_to_pointer
+ */
+unsigned pointer_to_unique_id(void * pointer);
+
+/**
+ * gives the pointer that is associated to the given id
+ * @param[in] id unique index previously returned by pointer_to_unique_id
+ * @return pointer the is associated to the given id \n NULL if the id is invalid
+ */
+void *   unique_id_to_pointer(unsigned id);
+
+/**
+ * frees all memory used for the pointer/unique_id conversion
+ * \remarks this should only be called after the last call to 
+ *          \ref pointer_to_unique_id and \ref unique_id_to_pointer, because afterwords
+ *          \ref unique_id_to_pointer will not be able to return the respective pointers
+ *          for previously valid unique ids
+ */
+void free_pointer_unique_lookup();
+
+/**
+ * prints a short error message and info from where it was called
+ * followed by an exit. 
+ */
+void abort_message ( char * text, char * file, int line );
+
+/** \example test_quicksort.c
+ * This contains an example of how to use quicksort_index.
+ */
+
+void quicksort_index ( int * a, int n, int * idx);
+
+/* --------------------------------------------------------------------
+
+   Hash function
+
+   This algorithm (k=33) was first reported by dan bernstein many
+   years ago in comp.lang.c. another version of this algorithm (now
+   favored by bernstein) uses xor: hash(i) = hash(i - 1) * 33 ^
+   str[i]; the magic of number 33 (why it works better than many other
+   constants, prime or not) has never been adequately explained.
+
+   Source: http://www.cse.yorku.ca/~oz/hash.html 
+
+   --------------------------------------------------------------------- */
+
+unsigned int hash(const char *str);
+
+/* =======================================================================
+   Macros
+   ======================================================================= */
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+#define ASSERT(c) \
+if (!(c)) {\
+   fprintf(stderr, "### Assertion violation: %s in %s:%d\n",\
+           #c, __FILE__, __LINE__);\
+   abort ();\
+}
+
+#define ASSERT2(c, a, b) \
+if (!(c)) {\
+   fprintf(stderr, "### Assertion violation: %s (%s = %d, %s = %d) in %s:%d\n", #c, #a, a, #b, b, __FILE__, __LINE__);\
+   abort();\
+}
+
+#endif // UTILS_H
diff --git a/src/color.c b/src/color.c
index 25158f3..f49cf5f 100644
--- a/src/color.c
+++ b/src/color.c
@@ -171,7 +171,7 @@ int cptRead(FILE *fp, CPT *cpt)
 	
   cptInit(cpt);
 
-  cpt->lut = (LUT *) calloc(1, n_alloc*sizeof(LUT));
+  cpt->lut = calloc(1, n_alloc*sizeof(LUT));
 	
   /* Save the original setting since it may be modified by settings in the CPT file */
   color_model = RGB; 
@@ -320,7 +320,7 @@ int cptRead(FILE *fp, CPT *cpt)
       if (n == n_alloc) {
 	i = n_alloc;
 	n_alloc += small_chunk;
-	cpt->lut = (LUT *) realloc((void *)cpt->lut, (size_t)n_alloc*sizeof (LUT));
+	cpt->lut = realloc((void *)cpt->lut, (size_t)n_alloc*sizeof (LUT));
 	memset ((void *)&cpt->lut[i], 0, (size_t)(small_chunk * sizeof (LUT)));  /* Initialize new structs to zero */
       }
     }
@@ -339,7 +339,7 @@ int cptRead(FILE *fp, CPT *cpt)
       return (READERR);
     }
 		
-  cpt->lut = (LUT *) realloc((void *)cpt->lut, (size_t)n*sizeof (LUT));
+  cpt->lut = realloc((void *)cpt->lut, (size_t)n*sizeof (LUT));
   ncolors = n;
   for (i = annot = 0, gap = FALSE; i < ncolors - 1; i++) {
     if ( fabs(cpt->lut[i].z_high - cpt->lut[i+1].z_low) > 0 ) gap = TRUE;
diff --git a/src/commandline.c b/src/commandline.c
index 7a8a26e..0babf21 100644
--- a/src/commandline.c
+++ b/src/commandline.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/ecacore.c b/src/ecacore.c
index 291c855..93edbeb 100755
--- a/src/ecacore.c
+++ b/src/ecacore.c
@@ -108,32 +108,32 @@ void eca1(const ECA_REQUEST_1 *request)
   streamDefVlist(ostreamID, ovlistID);
 
   nrecords   = vlistNrecs(ivlistID);
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = gridInqSize(gridID);
 
   field_init(&field1);
   field_init(&field2);
 
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
   if ( IS_SET(request->var2.h2) || IS_SET(request->var2.h3) ) 
-    field2.ptr = (double *) malloc(gridsize*sizeof(double));
+    field2.ptr = malloc(gridsize*sizeof(double));
   else
     field2.ptr = NULL;
 
   nlevels = zaxisInqSize(zaxisID);
 
-  var12 = (field_t *) malloc(nlevels*sizeof(field_t));
-  samp1 = (field_t *) malloc(nlevels*sizeof(field_t));
-  samp2 = (field_t *) malloc(nlevels*sizeof(field_t));
+  var12 = malloc(nlevels*sizeof(field_t));
+  samp1 = malloc(nlevels*sizeof(field_t));
+  samp2 = malloc(nlevels*sizeof(field_t));
   if ( IS_SET(request->var1.f3) ) 
-    var13 = (field_t *) malloc(nlevels*sizeof(field_t));
+    var13 = malloc(nlevels*sizeof(field_t));
     
   if ( IS_SET(request->var2.h2) ) 
-    var21 = (field_t *) malloc(nlevels*sizeof(field_t));
+    var21 = malloc(nlevels*sizeof(field_t));
   if ( IS_SET(request->var2.h3) ) 
-    var23 = (field_t *) malloc(nlevels*sizeof(field_t));
+    var23 = malloc(nlevels*sizeof(field_t));
       
   for ( levelID = 0; levelID < nlevels; levelID++ )
     {
@@ -141,13 +141,13 @@ void eca1(const ECA_REQUEST_1 *request)
       var12[levelID].grid    = gridID;
       var12[levelID].nmiss   = 0;
       var12[levelID].missval = missval;
-      var12[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+      var12[levelID].ptr     = malloc(gridsize*sizeof(double));
 
       field_init(&samp1[levelID]);
       samp1[levelID].grid    = gridID;
       samp1[levelID].nmiss   = 0;
       samp1[levelID].missval = missval;
-      samp1[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+      samp1[levelID].ptr     = malloc(gridsize*sizeof(double));
 
       field_init(&samp2[levelID]);
       samp2[levelID].grid    = gridID;
@@ -161,7 +161,7 @@ void eca1(const ECA_REQUEST_1 *request)
           var13[levelID].grid    = gridID;
           var13[levelID].nmiss   = 0;
           var13[levelID].missval = missval;
-          var13[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+          var13[levelID].ptr     = malloc(gridsize*sizeof(double));
         }
       if ( IS_SET(request->var2.h2) )
         {
@@ -169,7 +169,7 @@ void eca1(const ECA_REQUEST_1 *request)
           var21[levelID].grid    = gridID;
           var21[levelID].nmiss   = 0;
           var21[levelID].missval = missval;
-          var21[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+          var21[levelID].ptr     = malloc(gridsize*sizeof(double));
         }
       if ( IS_SET(request->var2.h3) )
         {
@@ -177,7 +177,7 @@ void eca1(const ECA_REQUEST_1 *request)
           var23[levelID].grid    = gridID;
           var23[levelID].nmiss   = 0;
           var23[levelID].missval = missval;
-          var23[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+          var23[levelID].ptr     = malloc(gridsize*sizeof(double));
         }
     }
 
@@ -246,7 +246,7 @@ void eca1(const ECA_REQUEST_1 *request)
                 {
                   if ( IS_NOT_SET(samp2[levelID].ptr) )
                     {
-                      samp2[levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+                      samp2[levelID].ptr = malloc(gridsize*sizeof(double));
                       for ( i = 0; i < gridsize; i++ )
                         samp2[levelID].ptr[i] = nsets;
                     }
@@ -480,29 +480,29 @@ void eca2(const ECA_REQUEST_2 *request)
   streamDefVlist(ostreamID, ovlistID);
 
   nrecords   = vlistNrecs(ivlistID1);
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = gridInqSize(gridID);
 
   field_init(&field1);
   field_init(&field2);
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field2.ptr = malloc(gridsize*sizeof(double));
 
   nlevels = zaxisInqSize(zaxisID);
   
-  var14 = (field_t *) malloc(nlevels*sizeof(field_t));
-  samp1 = (field_t *) malloc(nlevels*sizeof(field_t));
-  samp2 = (field_t *) malloc(nlevels*sizeof(field_t));
-  samp3 = (field_t *) malloc(nlevels*sizeof(field_t));
+  var14 = malloc(nlevels*sizeof(field_t));
+  samp1 = malloc(nlevels*sizeof(field_t));
+  samp2 = malloc(nlevels*sizeof(field_t));
+  samp3 = malloc(nlevels*sizeof(field_t));
   
   if ( request->var1.epilog == PERCENT_OF_TOTAL_AMOUNT )
-    total = (field_t *) malloc(nlevels*sizeof(field_t));
+    total = malloc(nlevels*sizeof(field_t));
   if ( IS_SET(request->var1.f5) )
-    var15 = (field_t *) malloc(nlevels*sizeof(field_t));
+    var15 = malloc(nlevels*sizeof(field_t));
   if ( IS_SET(request->var2.h2) )
-    var22 = (field_t *) malloc(nlevels*sizeof(field_t));
+    var22 = malloc(nlevels*sizeof(field_t));
       
   for ( levelID = 0; levelID < nlevels; levelID++ )
     {
@@ -510,19 +510,19 @@ void eca2(const ECA_REQUEST_2 *request)
       var14[levelID].grid    = gridID;
       var14[levelID].nmiss   = 0;
       var14[levelID].missval = missval1;
-      var14[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+      var14[levelID].ptr     = malloc(gridsize*sizeof(double));
       
       field_init(&samp1[levelID]);
       samp1[levelID].grid    = gridID;
       samp1[levelID].nmiss   = 0;
       samp1[levelID].missval = missval1;
-      samp1[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+      samp1[levelID].ptr     = malloc(gridsize*sizeof(double));
 
       field_init(&samp2[levelID]);
       samp2[levelID].grid    = gridID;
       samp2[levelID].nmiss   = 0;
       samp2[levelID].missval = missval1;
-      samp2[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+      samp2[levelID].ptr     = malloc(gridsize*sizeof(double));
 
       field_init(&samp3[levelID]);
       samp3[levelID].grid    = gridID;
@@ -536,7 +536,7 @@ void eca2(const ECA_REQUEST_2 *request)
           total[levelID].grid    = gridID;
           total[levelID].nmiss   = 0;
           total[levelID].missval = missval1;
-          total[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+          total[levelID].ptr     = malloc(gridsize*sizeof(double));
         }
       if ( IS_SET(request->var1.f5) )
         {
@@ -544,7 +544,7 @@ void eca2(const ECA_REQUEST_2 *request)
           var15[levelID].grid    = gridID;
           var15[levelID].nmiss   = 0;
           var15[levelID].missval = missval1;
-          var15[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+          var15[levelID].ptr     = malloc(gridsize*sizeof(double));
         }
       if ( IS_SET(request->var2.h2) )
         {
@@ -552,7 +552,7 @@ void eca2(const ECA_REQUEST_2 *request)
           var22[levelID].grid    = gridID;
           var22[levelID].nmiss   = 0;
           var22[levelID].missval = missval1;
-          var22[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+          var22[levelID].ptr     = malloc(gridsize*sizeof(double));
         }
     }
 
@@ -637,7 +637,7 @@ void eca2(const ECA_REQUEST_2 *request)
                 {
                   if ( IS_NOT_SET(samp3[levelID].ptr) )
                     {
-                      samp3[levelID].ptr = (double *) malloc(gridsize*sizeof(double));
+                      samp3[levelID].ptr = malloc(gridsize*sizeof(double));
                       for ( i = 0; i < gridsize; i++ )
                         samp3[levelID].ptr[i] = nsets;
                     }
@@ -854,20 +854,20 @@ void eca3(const ECA_REQUEST_3 *request)
   streamDefVlist(ostreamID, ovlistID);
 
   nrecords   = vlistNrecs(ivlistID1);
-  recVarID   = (int *) malloc(nrecords*sizeof(int));
-  recLevelID = (int *) malloc(nrecords*sizeof(int));
+  recVarID   = malloc(nrecords*sizeof(int));
+  recLevelID = malloc(nrecords*sizeof(int));
 
   gridsize = gridInqSize(gridID);
 
   field_init(&field1);
   field_init(&field2);
-  field1.ptr = (double *) malloc(gridsize*sizeof(double));
-  field2.ptr = (double *) malloc(gridsize*sizeof(double));
+  field1.ptr = malloc(gridsize*sizeof(double));
+  field2.ptr = malloc(gridsize*sizeof(double));
 
   nlevels = zaxisInqSize(zaxisID);
 
-  var1 = (field_t *) malloc(nlevels*sizeof(field_t));
-  var2 = (field_t *) malloc(nlevels*sizeof(field_t));
+  var1 = malloc(nlevels*sizeof(field_t));
+  var2 = malloc(nlevels*sizeof(field_t));
         
   for ( levelID = 0; levelID < nlevels; levelID++ )
     {
@@ -875,13 +875,13 @@ void eca3(const ECA_REQUEST_3 *request)
       var1[levelID].grid    = gridID;
       var1[levelID].nmiss   = 0;
       var1[levelID].missval = missval;
-      var1[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+      var1[levelID].ptr     = malloc(gridsize*sizeof(double));
             
       field_init(&var2[levelID]);
       var2[levelID].grid    = gridID;
       var2[levelID].nmiss   = 0;
       var2[levelID].missval = missval;
-      var2[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+      var2[levelID].ptr     = malloc(gridsize*sizeof(double));
     }
 
   itsID   = 0;
@@ -1074,8 +1074,8 @@ void eca4(const ECA_REQUEST_4 *request)
   streamDefVlist(ostreamID, ovlistID);
 
   nrecords    = vlistNrecs(ivlistID1);
-  recVarID    = (int *) malloc(nrecords*sizeof(int));
-  recLevelID  = (int *) malloc(nrecords*sizeof(int));
+  recVarID    = malloc(nrecords*sizeof(int));
+  recLevelID  = malloc(nrecords*sizeof(int));
 
   gridtype = gridInqType(gridID);
   if ( gridtype != GRID_UNSTRUCTURED && gridtype != GRID_CURVILINEAR ) 
@@ -1094,27 +1094,27 @@ void eca4(const ECA_REQUEST_4 *request)
   * southern hemisphere                                                      */
   field_init(&fieldGt);
   field_init(&fieldLt);
-  fieldGt.ptr = (double *) malloc(gridsize*sizeof(double));
-  fieldLt.ptr = (double *) malloc(gridsize*sizeof(double));
+  fieldGt.ptr = malloc(gridsize*sizeof(double));
+  fieldLt.ptr = malloc(gridsize*sizeof(double));
 
   /* field for the land-water-distribution */
   field_init(&mask);
-  mask.ptr    = (double *) malloc(gridsize*sizeof(double));
+  mask.ptr    = malloc(gridsize*sizeof(double));
 
   nlevels     = zaxisInqSize(zaxisID);
 
-  startCount  = (field_t *) malloc(nlevels*sizeof(field_t));
-  endCount    = (field_t *) malloc(nlevels*sizeof(field_t));
-  gslDuration = (field_t *) malloc(nlevels*sizeof(field_t));
-  gslFirstDay = (field_t *) malloc(nlevels*sizeof(field_t));
+  startCount  = malloc(nlevels*sizeof(field_t));
+  endCount    = malloc(nlevels*sizeof(field_t));
+  gslDuration = malloc(nlevels*sizeof(field_t));
+  gslFirstDay = malloc(nlevels*sizeof(field_t));
 
   /* because of the different definitions for northern and southern hemisphere,
    * the values of the last year have to be present
    * THE LAST YEAR HAS THE INDEX 1 */
   for ( int h = 0; h < 2; h++ )
   {
-    startDateWithHist[h] = (field_t *) malloc(nlevels*sizeof(field_t));
-    endDateWithHist[h]   = (field_t *) malloc(nlevels*sizeof(field_t));
+    startDateWithHist[h] = malloc(nlevels*sizeof(field_t));
+    endDateWithHist[h]   = malloc(nlevels*sizeof(field_t));
   }
 
   for ( levelID = 0; levelID < nlevels; levelID++ )
@@ -1124,7 +1124,7 @@ void eca4(const ECA_REQUEST_4 *request)
     startCount[levelID].size     = gridsize;
     startCount[levelID].nmiss    = 0;
     startCount[levelID].missval  = missval;
-    startCount[levelID].ptr      = (double *) malloc(gridsize*sizeof(double));
+    startCount[levelID].ptr      = malloc(gridsize*sizeof(double));
     memset(startCount[levelID].ptr, 0, gridsize*sizeof(double));
 
     field_init(&endCount[levelID]);
@@ -1132,7 +1132,7 @@ void eca4(const ECA_REQUEST_4 *request)
     endCount[levelID].size       = gridsize;
     endCount[levelID].nmiss      = 0;
     endCount[levelID].missval    = missval;
-    endCount[levelID].ptr        = (double *) malloc(gridsize*sizeof(double));
+    endCount[levelID].ptr        = malloc(gridsize*sizeof(double));
     memset(endCount[levelID].ptr, 0, gridsize*sizeof(double));
 
     field_init(&gslDuration[levelID]);
@@ -1140,14 +1140,14 @@ void eca4(const ECA_REQUEST_4 *request)
     gslDuration[levelID].size    = gridsize;
     gslDuration[levelID].nmiss   = 0;
     gslDuration[levelID].missval = missval;
-    gslDuration[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+    gslDuration[levelID].ptr     = malloc(gridsize*sizeof(double));
 
     field_init(&gslFirstDay[levelID]);
     gslFirstDay[levelID].grid    = gridID;
     gslFirstDay[levelID].size    = gridsize;
     gslFirstDay[levelID].nmiss   = 0;
     gslFirstDay[levelID].missval = missval;
-    gslFirstDay[levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+    gslFirstDay[levelID].ptr     = malloc(gridsize*sizeof(double));
 
     for ( int h = 0; h < 2; h++ )
     {
@@ -1156,14 +1156,14 @@ void eca4(const ECA_REQUEST_4 *request)
       startDateWithHist[h][levelID].size    = gridsize;
       startDateWithHist[h][levelID].nmiss   = 0;
       startDateWithHist[h][levelID].missval = missval;
-      startDateWithHist[h][levelID].ptr     = (double *) malloc(gridsize*sizeof(double));
+      startDateWithHist[h][levelID].ptr     = malloc(gridsize*sizeof(double));
 
       field_init(&endDateWithHist[h][levelID]);
       endDateWithHist[h][levelID].grid      = gridID;
       endDateWithHist[h][levelID].size      = gridsize;
       endDateWithHist[h][levelID].nmiss     = 0;
       endDateWithHist[h][levelID].missval   = missval;
-      endDateWithHist[h][levelID].ptr       = (double *) malloc(gridsize*sizeof(double));
+      endDateWithHist[h][levelID].ptr       = malloc(gridsize*sizeof(double));
     }
   }
 
diff --git a/src/expr.c b/src/expr.c
index 0a5a1cf..90c8000 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -50,7 +50,7 @@ static func_t fun_sym_tbl[] =
   {0, "asinh", asinh},
   {0, "acosh", acosh},
   {0, "atanh", atanh},
-  {0, "gamma", gamma},
+  {0, "gamma", tgamma},
 
   /* array functions
   {1, "min",   min},
@@ -70,7 +70,7 @@ nodeType *expr_con_con(int oper, nodeType *p1, nodeType *p2)
 {
   nodeType *p;
 
-  p = (nodeType *) malloc(sizeof(nodeType));
+  p = malloc(sizeof(nodeType));
 
   p->type = typeCon;
 
@@ -106,7 +106,7 @@ nodeType *expr_con_var(int oper, nodeType *p1, nodeType *p2)
   ngp  = gridInqSize(gridID);
   nlev = zaxisInqSize(zaxisID);
 
-  p = (nodeType *) malloc(sizeof(nodeType));
+  p = malloc(sizeof(nodeType));
 
   p->type     = typeVar;
   p->tmpvar   = 1;
@@ -115,7 +115,7 @@ nodeType *expr_con_var(int oper, nodeType *p1, nodeType *p2)
   p->zaxisID  = zaxisID;
   p->missval  = missval1;
 
-  p->data = (double *) malloc(ngp*nlev*sizeof(double));
+  p->data = malloc(ngp*nlev*sizeof(double));
 
   switch ( oper )
     {
@@ -208,7 +208,7 @@ nodeType *expr_var_con(int oper, nodeType *p1, nodeType *p2)
   ngp  = gridInqSize(gridID);
   nlev = zaxisInqSize(zaxisID);
 
-  p = (nodeType *) malloc(sizeof(nodeType));
+  p = malloc(sizeof(nodeType));
 
   p->type     = typeVar;
   p->tmpvar   = 1;
@@ -217,7 +217,7 @@ nodeType *expr_var_con(int oper, nodeType *p1, nodeType *p2)
   p->zaxisID  = zaxisID;
   p->missval  = missval1;
 
-  p->data = (double *) malloc(ngp*nlev*sizeof(double));
+  p->data = malloc(ngp*nlev*sizeof(double));
 
   switch ( oper )
     {
@@ -323,7 +323,7 @@ nodeType *expr_var_var(int oper, nodeType *p1, nodeType *p2)
   nlev1 = zaxisInqSize(p1->zaxisID);
   nlev2 = zaxisInqSize(p2->zaxisID);
 
-  p = (nodeType *) malloc(sizeof(nodeType));
+  p = malloc(sizeof(nodeType));
 
   p->type     = typeVar;
   p->tmpvar   = 1;
@@ -353,7 +353,7 @@ nodeType *expr_var_var(int oper, nodeType *p1, nodeType *p2)
       p->missval = p1->missval;
     }
 
-  p->data = (double *) malloc(ngp*nlev*sizeof(double));
+  p->data = malloc(ngp*nlev*sizeof(double));
 
   for ( k = 0; k < nlev; k++ )
     {
@@ -517,7 +517,7 @@ nodeType *ex_fun_con(char *fun, nodeType *p1)
   int i;
   int funcID = -1;
 
-  p = (nodeType *) malloc(sizeof(nodeType));
+  p = malloc(sizeof(nodeType));
 
   p->type = typeCon;
 
@@ -530,7 +530,7 @@ nodeType *ex_fun_con(char *fun, nodeType *p1)
 	}
 
   if ( funcID == -1 )
-    cdoAbort("Function %s not available!", fun);
+    cdoAbort("Function >%s< not available!", fun);
 
   p->u.con.value = fun_sym_tbl[funcID].func(p1->u.con.value);
 
@@ -556,7 +556,7 @@ nodeType *ex_fun_var(char *fun, nodeType *p1)
   ngp  = gridInqSize(gridID);
   nlev = zaxisInqSize(zaxisID);
 
-  p = (nodeType *) malloc(sizeof(nodeType));
+  p = malloc(sizeof(nodeType));
 
   p->type     = typeVar;
   p->tmpvar   = 1;
@@ -565,7 +565,7 @@ nodeType *ex_fun_var(char *fun, nodeType *p1)
   p->zaxisID  = zaxisID;
   p->missval  = missval;
 
-  p->data = (double *) malloc(ngp*nlev*sizeof(double));
+  p->data = malloc(ngp*nlev*sizeof(double));
 
   for ( i = 0; i < NumFunc; i++)
     if ( strcmp(fun, fun_sym_tbl[i].name) == 0 )
@@ -575,7 +575,7 @@ nodeType *ex_fun_var(char *fun, nodeType *p1)
       }
 
   if ( funcID == -1 )
-    cdoAbort("Function %s not available!", fun);
+    cdoAbort("Function >%s< not available!", fun);
 
   if ( nmiss > 0 )
     {
@@ -648,7 +648,7 @@ nodeType *ex_uminus_var(nodeType *p1)
   ngp  = gridInqSize(gridID);
   nlev = zaxisInqSize(zaxisID);
 
-  p = (nodeType *) malloc(sizeof(nodeType));
+  p = malloc(sizeof(nodeType));
 
   p->type     = typeVar;
   p->tmpvar   = 1;
@@ -657,7 +657,7 @@ nodeType *ex_uminus_var(nodeType *p1)
   p->zaxisID  = zaxisID;
   p->missval  = missval;
 
-  p->data = (double *) malloc(ngp*nlev*sizeof(double));
+  p->data = malloc(ngp*nlev*sizeof(double));
 
   if ( nmiss > 0 )
     {
@@ -680,7 +680,7 @@ nodeType *ex_uminus_con(nodeType *p1)
 {
   nodeType *p;
 
-  p = (nodeType *) malloc(sizeof(nodeType));
+  p = malloc(sizeof(nodeType));
 
   p->type = typeCon;
 
@@ -844,16 +844,16 @@ nodeType *expr_run(nodeType *p, parse_parm_t *parse_arg)
       switch( p->u.opr.oper )
 	{
         case '=':
-	  parse_arg->gridID2  = -1;
-	  parse_arg->zaxisID2 = -1;
-          parse_arg->tsteptype2  = -1;
+	  parse_arg->gridID2    = -1;
+	  parse_arg->zaxisID2   = -1;
+          parse_arg->tsteptype2 = -1;
 
 	  rnode = expr_run(p->u.opr.op[1], parse_arg);
 
 	  if ( parse_arg->init )
 	    {
 	      if ( parse_arg->debug )
-		printf("\tpop var\t%s\n", p->u.opr.op[0]->u.var.nm);
+		printf("\tpop  var \t%s\n", p->u.opr.op[0]->u.var.nm);
 	      /*
 	      if ( p->u.opr.op[1]->type != typeVar )
 		cdoAbort("Operand not variable!");
diff --git a/src/expr.h b/src/expr.h
index 3ef05b0..ba66b2b 100644
--- a/src/expr.h
+++ b/src/expr.h
@@ -14,7 +14,7 @@ char *strdup(const char *s);
 ({					      	  \
    const char *__old = (s);			  \
    size_t __len = strlen(__old) + 1;		  \
-   char *__new = (char *) malloc(__len);	  \
+   char *__new = malloc(__len);	  \
    (char *) memcpy(__new, __old, __len);	  \
 })
 */
diff --git a/src/expr_lex.c b/src/expr_lex.c
index 7fcfe34..f01d3f3 100644
--- a/src/expr_lex.c
+++ b/src/expr_lex.c
@@ -9,7 +9,7 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
+#define YY_FLEX_SUBMINOR_VERSION 37
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -31,7 +31,7 @@
 
 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
 
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
 
 /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
  * if you want the limit (max/min) macros for int types. 
@@ -54,7 +54,6 @@ typedef int flex_int32_t;
 typedef unsigned char flex_uint8_t; 
 typedef unsigned short int flex_uint16_t;
 typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
 
 /* Limits of integral types. */
 #ifndef INT8_MIN
@@ -85,6 +84,8 @@ typedef unsigned int flex_uint32_t;
 #define UINT32_MAX             (4294967295U)
 #endif
 
+#endif /* ! C99 */
+
 #endif /* ! FLEXINT_H */
 
 #ifdef __cplusplus
@@ -95,11 +96,11 @@ typedef unsigned int flex_uint32_t;
 #else	/* ! __cplusplus */
 
 /* C99 requires __STDC__ to be defined as 1. */
-#if defined(__STDC__)
+#if defined (__STDC__)
 
 #define YY_USE_CONST
 
-#endif	/* defined(__STDC__) */
+#endif	/* defined (__STDC__) */
 #endif	/* ! __cplusplus */
 
 #ifdef YY_USE_CONST
@@ -170,6 +171,11 @@ typedef void* yyscan_t;
 typedef struct yy_buffer_state *YY_BUFFER_STATE;
 #endif
 
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
 #define EOB_ACT_CONTINUE_SCAN 0
 #define EOB_ACT_END_OF_FILE 1
 #define EOB_ACT_LAST_MATCH 2
@@ -192,11 +198,6 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE;
 
 #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
 
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
 #ifndef YY_STRUCT_YY_BUFFER_STATE
 #define YY_STRUCT_YY_BUFFER_STATE
 struct yy_buffer_state
@@ -214,7 +215,7 @@ struct yy_buffer_state
 	/* Number of characters read into yy_ch_buf, not including EOB
 	 * characters.
 	 */
-	int yy_n_chars;
+	yy_size_t 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
@@ -293,7 +294,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
 
 YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
 YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
 
 void *yyalloc (yy_size_t ,yyscan_t yyscanner );
 void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
@@ -325,7 +326,7 @@ void yyfree (void * ,yyscan_t yyscanner );
 
 /* Begin user sect3 */
 
-#define yywrap(n) 1
+#define yywrap(yyscanner) 1
 #define YY_SKIP_YYWRAP
 
 typedef unsigned char YY_CHAR;
@@ -509,7 +510,7 @@ goto find_rule; \
    LPH [A-Za-z_] Alphabetic character
    LPHDGT [A-Za-z0-9_] Alphanumeric character
    XPN [eE][+-]?[0-9]+ Real number Exponent */
-#line 513 "expr_lex.c"
+#line 514 "expr_lex.c"
 
 #define INITIAL 0
 
@@ -538,8 +539,8 @@ struct yyguts_t
     size_t yy_buffer_stack_max; /**< capacity of stack. */
     YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
     char yy_hold_char;
-    int yy_n_chars;
-    int yyleng_r;
+    yy_size_t yy_n_chars;
+    yy_size_t yyleng_r;
     char *yy_c_buf_p;
     int yy_init;
     int yy_start;
@@ -603,7 +604,7 @@ FILE *yyget_out (yyscan_t yyscanner );
 
 void yyset_out  (FILE * out_str ,yyscan_t yyscanner );
 
-int yyget_leng (yyscan_t yyscanner );
+yy_size_t yyget_leng (yyscan_t yyscanner );
 
 char *yyget_text (yyscan_t yyscanner );
 
@@ -611,6 +612,10 @@ int yyget_lineno (yyscan_t yyscanner );
 
 void yyset_lineno (int line_number ,yyscan_t yyscanner );
 
+int yyget_column  (yyscan_t yyscanner );
+
+void yyset_column (int column_no ,yyscan_t yyscanner );
+
 YYSTYPE * yyget_lval (yyscan_t yyscanner );
 
 void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
@@ -655,7 +660,7 @@ static int input (yyscan_t yyscanner );
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -666,7 +671,7 @@ static int input (yyscan_t yyscanner );
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		int n; \
+		size_t n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -754,7 +759,7 @@ YY_DECL
 #line 35 "expr_lex.l"
 
 
-#line 758 "expr_lex.c"
+#line 763 "expr_lex.c"
 
     yylval = yylval_param;
 
@@ -960,7 +965,7 @@ YY_RULE_SETUP
 #line 83 "expr_lex.l"
 ECHO;
 	YY_BREAK
-#line 964 "expr_lex.c"
+#line 969 "expr_lex.c"
 			case YY_STATE_EOF(INITIAL):
 				yyterminate();
 
@@ -1147,7 +1152,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
 	else
 		{
-			int num_to_read =
+			yy_size_t num_to_read =
 			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
 
 		while ( num_to_read <= 0 )
@@ -1163,7 +1168,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			yyg->yy_n_chars, (size_t) num_to_read );
+			yyg->yy_n_chars, num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
 		}
@@ -1255,6 +1260,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 	if ( ! yy_is_jam )
 		*yyg->yy_state_ptr++ = yy_current_state;
 
+	(void)yyg;
 	return yy_is_jam ? 0 : yy_current_state;
 }
 
@@ -1283,7 +1289,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
 
 		else
 			{ /* need more input */
-			int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+			yy_size_t offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
 			++yyg->yy_c_buf_p;
 
 			switch ( yy_get_next_buffer( yyscanner ) )
@@ -1447,10 +1453,6 @@ static void yy_load_buffer_state  (yyscan_t yyscanner)
 	yyfree((void *) b ,yyscanner );
 }
 
-#ifndef __cplusplus
-extern int isatty (int );
-#endif /* __cplusplus */
-    
 /* Initializes or reinitializes a buffer.
  * This function is sometimes called more than once on the same buffer,
  * such as during a yyrestart() or at EOF.
@@ -1567,7 +1569,7 @@ void yypop_buffer_state (yyscan_t yyscanner)
  */
 static void yyensure_buffer_stack (yyscan_t yyscanner)
 {
-	int num_to_alloc;
+	yy_size_t num_to_alloc;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
 	if (!yyg->yy_buffer_stack) {
@@ -1660,12 +1662,12 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
 
 /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
  * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len , yyscan_t yyscanner)
 {
 	YY_BUFFER_STATE b;
 	char *buf;
@@ -1780,7 +1782,7 @@ FILE *yyget_out  (yyscan_t yyscanner)
 /** Get the length of the current token.
  * @param yyscanner The scanner object.
  */
-int yyget_leng  (yyscan_t yyscanner)
+yy_size_t yyget_leng  (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
     return yyleng;
@@ -1816,7 +1818,7 @@ void yyset_lineno (int  line_number , yyscan_t yyscanner)
 
         /* lineno is only valid if an input buffer exists. */
         if (! YY_CURRENT_BUFFER )
-           yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner); 
+           YY_FATAL_ERROR( "yyset_lineno called with no buffer" );
     
     yylineno = line_number;
 }
@@ -1831,7 +1833,7 @@ void yyset_column (int  column_no , yyscan_t yyscanner)
 
         /* column is only valid if an input buffer exists. */
         if (! YY_CURRENT_BUFFER )
-           yy_fatal_error( "yyset_column called with no buffer" , yyscanner); 
+           YY_FATAL_ERROR( "yyset_column called with no buffer" );
     
     yycolumn = column_no;
 }
@@ -2041,7 +2043,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
 
 void *yyalloc (yy_size_t  size , yyscan_t yyscanner)
 {
-	return (void *) malloc( size );
+	return malloc( size );
 }
 
 void *yyrealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
@@ -2053,7 +2055,7 @@ void *yyrealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
 	 * any pointer type to void*, and deal with argument conversions
 	 * as though doing an assignment.
 	 */
-	return (void *) realloc( (char *) ptr, size );
+	return realloc( (char *) ptr, size );
 }
 
 void yyfree (void * ptr , yyscan_t yyscanner)
diff --git a/src/expr_yacc.c b/src/expr_yacc.c
index 769e6ae..f1c5e8d 100644
--- a/src/expr_yacc.c
+++ b/src/expr_yacc.c
@@ -1,9 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.4.2.  */
+/* A Bison parser, made by GNU Bison 2.7.  */
 
-/* Skeleton implementation for Bison's Yacc-like parsers in C
+/* Bison implementation for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
-   Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2012 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
@@ -45,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.4.2"
+#define YYBISON_VERSION "2.7"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -59,14 +58,11 @@
 /* Pull parsers.  */
 #define YYPULL 1
 
-/* Using locations.  */
-#define YYLSP_NEEDED 0
 
 
 
 /* Copy the first part of user declarations.  */
-
-/* Line 189 of yacc.c  */
+/* Line 371 of yacc.c  */
 #line 1 "expr_yacc.y"
 
 #include <stdio.h>
@@ -93,14 +89,16 @@ void freeNode(nodeType *p);
 int expr_run(nodeType *p, parse_parm_t *parse_arg);
 
 
+/* Line 371 of yacc.c  */
+#line 94 "expr_yacc.c"
 
-/* Line 189 of yacc.c  */
-#line 99 "expr_yacc.c"
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
+# ifndef YY_NULL
+#  if defined __cplusplus && 201103L <= __cplusplus
+#   define YY_NULL nullptr
+#  else
+#   define YY_NULL 0
+#  endif
+# endif
 
 /* Enabling verbose error messages.  */
 #ifdef YYERROR_VERBOSE
@@ -110,11 +108,17 @@ int expr_run(nodeType *p, parse_parm_t *parse_arg);
 # define YYERROR_VERBOSE 0
 #endif
 
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
+/* In a future release of Bison, this section will be replaced
+   by #include "expr_yacc.h".  */
+#ifndef YY_YY_EXPR_YACC_H_INCLUDED
+# define YY_YY_EXPR_YACC_H_INCLUDED
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
 #endif
-
 
 /* Tokens.  */
 #ifndef YYTOKENTYPE
@@ -144,7 +148,6 @@ int expr_run(nodeType *p, parse_parm_t *parse_arg);
 
 
 
-
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -152,11 +155,26 @@ int expr_run(nodeType *p, parse_parm_t *parse_arg);
 #endif
 
 
-/* Copy the second part of user declarations.  */
+#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 (parse_parm_t *parse_arg, void *scanner);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !YY_YY_EXPR_YACC_H_INCLUDED  */
 
+/* Copy the second part of user declarations.  */
 
-/* Line 264 of yacc.c  */
-#line 160 "expr_yacc.c"
+/* Line 390 of yacc.c  */
+#line 178 "expr_yacc.c"
 
 #ifdef short
 # undef short
@@ -209,24 +227,24 @@ typedef short int yytype_int16;
 # if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
 #  endif
 # endif
 # ifndef YY_
-#  define YY_(msgid) msgid
+#  define YY_(Msgid) Msgid
 # endif
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
+# define YYUSE(E) ((void) (E))
 #else
-# define YYUSE(e) /* empty */
+# define YYUSE(E) /* empty */
 #endif
 
 /* Identity function, used to suppress warnings about constant conditions.  */
 #ifndef lint
-# define YYID(n) (n)
+# define YYID(N) (N)
 #else
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
@@ -259,11 +277,12 @@ YYID (yyi)
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (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
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
 #     endif
 #    endif
 #   endif
@@ -286,24 +305,24 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
 	     && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined malloc && ! defined EXIT_SUCCESS && (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__ \
+#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
@@ -332,23 +351,7 @@ union yyalloc
      ((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
+# define YYCOPY_NEEDED 1
 
 /* Relocate STACK from its old location to the new one.  The
    local variables YYSIZE and YYSTACKSIZE give the old and new number of
@@ -368,19 +371,39 @@ union yyalloc
 
 #endif
 
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYSIZE_T yyi;                         \
+          for (yyi = 0; yyi < (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (YYID (0))
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  3
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   122
+#define YYLAST   123
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  24
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  6
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  26
+#define YYNRULES  27
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  50
+#define YYNSTATES  51
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -426,35 +449,36 @@ static const yytype_uint8 yytranslate[] =
    YYRHS.  */
 static const yytype_uint8 yyprhs[] =
 {
-       0,     0,     3,     5,     8,     9,    11,    14,    19,    23,
-      25,    28,    30,    32,    35,    39,    43,    47,    51,    55,
-      59,    63,    67,    71,    75,    79,    83
+       0,     0,     3,     5,     8,     9,    11,    14,    19,    22,
+      26,    28,    31,    33,    35,    38,    42,    46,    50,    54,
+      58,    62,    66,    70,    74,    78,    82,    86
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
       25,     0,    -1,    26,    -1,    26,    27,    -1,    -1,    19,
-      -1,    29,    19,    -1,     4,     8,    29,    19,    -1,    20,
-      28,    21,    -1,    27,    -1,    28,    27,    -1,     3,    -1,
-       4,    -1,    14,    29,    -1,    29,    13,    29,    -1,    29,
-      14,    29,    -1,    29,    15,    29,    -1,    29,    16,    29,
-      -1,    29,     7,    29,    -1,    29,     6,    29,    -1,    29,
-      17,    29,    -1,    29,    12,    29,    -1,    29,    11,    29,
-      -1,    29,     9,    29,    -1,    29,    10,    29,    -1,    22,
-      29,    23,    -1,     5,    22,    29,    23,    -1
+      -1,    29,    19,    -1,     4,     8,    29,    19,    -1,     4,
+      19,    -1,    20,    28,    21,    -1,    27,    -1,    28,    27,
+      -1,     3,    -1,     4,    -1,    14,    29,    -1,    29,    13,
+      29,    -1,    29,    14,    29,    -1,    29,    15,    29,    -1,
+      29,    16,    29,    -1,    29,     7,    29,    -1,    29,     6,
+      29,    -1,    29,    17,    29,    -1,    29,    12,    29,    -1,
+      29,    11,    29,    -1,    29,     9,    29,    -1,    29,    10,
+      29,    -1,    22,    29,    23,    -1,     5,    22,    29,    23,
+      -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint8 yyrline[] =
 {
-       0,    49,    49,    53,    54,    58,    59,    60,    61,    65,
-      66,    70,    71,    72,    73,    74,    75,    76,    77,    78,
-      79,    80,    81,    82,    83,    84,    85
+       0,    49,    49,    53,    54,    58,    59,    60,    61,    62,
+      66,    67,    71,    72,    73,    74,    75,    76,    77,    78,
+      79,    80,    81,    82,    83,    84,    85,    86
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 0
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
@@ -462,7 +486,7 @@ static const char *const yytname[] =
   "$end", "error", "$undefined", "CONSTANT", "VARIABLE", "FUNCTION",
   "'>'", "'<'", "'='", "NE", "EQ", "LE", "GE", "'+'", "'-'", "'*'", "'/'",
   "'^'", "UMINUS", "';'", "'{'", "'}'", "'('", "')'", "$accept", "program",
-  "function", "stmt", "stmt_list", "expr", 0
+  "function", "stmt", "stmt_list", "expr", YY_NULL
 };
 #endif
 
@@ -480,35 +504,36 @@ static const yytype_uint16 yytoknum[] =
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    24,    25,    26,    26,    27,    27,    27,    27,    28,
-      28,    29,    29,    29,    29,    29,    29,    29,    29,    29,
-      29,    29,    29,    29,    29,    29,    29
+       0,    24,    25,    26,    26,    27,    27,    27,    27,    27,
+      28,    28,    29,    29,    29,    29,    29,    29,    29,    29,
+      29,    29,    29,    29,    29,    29,    29,    29
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
-       0,     2,     1,     2,     0,     1,     2,     4,     3,     1,
-       2,     1,     1,     2,     3,     3,     3,     3,     3,     3,
-       3,     3,     3,     3,     3,     3,     4
+       0,     2,     1,     2,     0,     1,     2,     4,     2,     3,
+       1,     2,     1,     1,     2,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     3,     3,     3,     4
 };
 
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+   Performed when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       4,     0,     2,     1,    11,    12,     0,     0,     5,     0,
-       0,     3,     0,     0,     0,    12,    13,     9,     0,     0,
+       4,     0,     2,     1,    12,    13,     0,     0,     5,     0,
+       0,     3,     0,     0,     8,     0,    13,    14,    10,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     6,     0,     0,     8,    10,    25,    19,    18,    23,
-      24,    22,    21,    14,    15,    16,    17,    20,     7,    26
+       0,     0,     6,     0,     0,     9,    11,    26,    20,    19,
+      24,    25,    23,    22,    15,    16,    17,    18,    21,     7,
+      27
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int8 yydefgoto[] =
 {
-      -1,     1,     2,    11,    18,    12
+      -1,     1,     2,    11,    19,    12
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
@@ -516,11 +541,12 @@ static const yytype_int8 yydefgoto[] =
 #define YYPACT_NINF -18
 static const yytype_int8 yypact[] =
 {
-     -18,     2,    25,   -18,   -18,    -4,   -17,    45,   -18,    25,
-      45,   -18,    89,    45,    45,   -18,   -18,   -18,    21,    59,
-      45,    45,    45,    45,    45,    45,    45,    45,    45,    45,
-      45,   -18,   103,    74,   -18,   -18,   -18,    38,    38,    38,
-      38,    38,    38,    16,    16,    -9,    -9,    -9,   -18,   -18
+     -18,     4,    26,   -18,   -18,    -6,   -17,    46,   -18,    26,
+      46,   -18,    90,    46,   -18,    46,   -18,   -18,   -18,    22,
+      60,    46,    46,    46,    46,    46,    46,    46,    46,    46,
+      46,    46,   -18,   104,    75,   -18,   -18,   -18,    39,    39,
+      39,    39,    39,    39,    17,    17,   -10,   -10,   -10,   -18,
+     -18
 };
 
 /* YYPGOTO[NTERM-NUM].  */
@@ -531,41 +557,46 @@ static const yytype_int8 yypgoto[] =
 
 /* 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.  */
+   number is the opposite.  If YYTABLE_NINF, syntax error.  */
 #define YYTABLE_NINF -1
 static const yytype_uint8 yytable[] =
 {
-      16,    17,     3,    19,    13,    14,    32,    33,    30,     0,
-      35,     0,     0,    37,    38,    39,    40,    41,    42,    43,
-      44,    45,    46,    47,     4,     5,     6,     0,     4,     5,
-       6,    28,    29,    30,     0,     7,     0,     0,     0,     7,
-       8,     9,    34,    10,     8,     9,     0,    10,     4,    15,
-       6,    26,    27,    28,    29,    30,     0,     0,     0,     7,
-       0,     0,     0,     0,     0,    20,    21,    10,    22,    23,
-      24,    25,    26,    27,    28,    29,    30,     0,     0,     0,
-      20,    21,    36,    22,    23,    24,    25,    26,    27,    28,
-      29,    30,     0,     0,     0,    20,    21,    49,    22,    23,
-      24,    25,    26,    27,    28,    29,    30,     0,    31,    20,
-      21,     0,    22,    23,    24,    25,    26,    27,    28,    29,
-      30,     0,    48
+      17,    18,    13,    20,     3,    15,    33,    31,    34,     0,
+       0,    36,     0,    14,    38,    39,    40,    41,    42,    43,
+      44,    45,    46,    47,    48,     4,     5,     6,     0,     4,
+       5,     6,    29,    30,    31,     0,     7,     0,     0,     0,
+       7,     8,     9,    35,    10,     8,     9,     0,    10,     4,
+      16,     6,    27,    28,    29,    30,    31,     0,     0,     0,
+       7,     0,     0,     0,     0,     0,    21,    22,    10,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,     0,     0,
+       0,    21,    22,    37,    23,    24,    25,    26,    27,    28,
+      29,    30,    31,     0,     0,     0,    21,    22,    50,    23,
+      24,    25,    26,    27,    28,    29,    30,    31,     0,    32,
+      21,    22,     0,    23,    24,    25,    26,    27,    28,    29,
+      30,    31,     0,    49
 };
 
+#define yypact_value_is_default(Yystate) \
+  (!!((Yystate) == (-18)))
+
+#define yytable_value_is_error(Yytable_value) \
+  YYID (0)
+
 static const yytype_int8 yycheck[] =
 {
-       7,     9,     0,    10,     8,    22,    13,    14,    17,    -1,
-      18,    -1,    -1,    20,    21,    22,    23,    24,    25,    26,
-      27,    28,    29,    30,     3,     4,     5,    -1,     3,     4,
-       5,    15,    16,    17,    -1,    14,    -1,    -1,    -1,    14,
-      19,    20,    21,    22,    19,    20,    -1,    22,     3,     4,
-       5,    13,    14,    15,    16,    17,    -1,    -1,    -1,    14,
-      -1,    -1,    -1,    -1,    -1,     6,     7,    22,     9,    10,
-      11,    12,    13,    14,    15,    16,    17,    -1,    -1,    -1,
-       6,     7,    23,     9,    10,    11,    12,    13,    14,    15,
-      16,    17,    -1,    -1,    -1,     6,     7,    23,     9,    10,
-      11,    12,    13,    14,    15,    16,    17,    -1,    19,     6,
-       7,    -1,     9,    10,    11,    12,    13,    14,    15,    16,
-      17,    -1,    19
+       7,     9,     8,    10,     0,    22,    13,    17,    15,    -1,
+      -1,    19,    -1,    19,    21,    22,    23,    24,    25,    26,
+      27,    28,    29,    30,    31,     3,     4,     5,    -1,     3,
+       4,     5,    15,    16,    17,    -1,    14,    -1,    -1,    -1,
+      14,    19,    20,    21,    22,    19,    20,    -1,    22,     3,
+       4,     5,    13,    14,    15,    16,    17,    -1,    -1,    -1,
+      14,    -1,    -1,    -1,    -1,    -1,     6,     7,    22,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    -1,    -1,
+      -1,     6,     7,    23,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    -1,    -1,    -1,     6,     7,    23,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    -1,    19,
+       6,     7,    -1,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    -1,    19
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -573,10 +604,11 @@ static const yytype_int8 yycheck[] =
 static const yytype_uint8 yystos[] =
 {
        0,    25,    26,     0,     3,     4,     5,    14,    19,    20,
-      22,    27,    29,     8,    22,     4,    29,    27,    28,    29,
-       6,     7,     9,    10,    11,    12,    13,    14,    15,    16,
-      17,    19,    29,    29,    21,    27,    23,    29,    29,    29,
-      29,    29,    29,    29,    29,    29,    29,    29,    19,    23
+      22,    27,    29,     8,    19,    22,     4,    29,    27,    28,
+      29,     6,     7,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    19,    29,    29,    21,    27,    23,    29,    29,
+      29,    29,    29,    29,    29,    29,    29,    29,    29,    19,
+      23
 };
 
 #define yyerrok		(yyerrstatus = 0)
@@ -606,72 +638,35 @@ static const yytype_uint8 yystos[] =
 
 #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								\
-    {								\
+#define YYBACKUP(Token, Value)                                  \
+do                                                              \
+  if (yychar == YYEMPTY)                                        \
+    {                                                           \
+      yychar = (Token);                                         \
+      yylval = (Value);                                         \
+      YYPOPSTACK (yylen);                                       \
+      yystate = *yyssp;                                         \
+      goto yybackup;                                            \
+    }                                                           \
+  else                                                          \
+    {                                                           \
       yyerror (parse_arg, scanner, YY_("syntax error: cannot back up")); \
       YYERROR;							\
     }								\
 while (YYID (0))
 
-
+/* Error token number */
 #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.  */
-
+/* This macro is provided for backward compatibility. */
 #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
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
 #endif
 
 
 /* YYLEX -- calling `yylex' with the right arguments.  */
-
 #ifdef YYLEX_PARAM
 # define YYLEX yylex (&yylval, YYLEX_PARAM)
 #else
@@ -723,6 +718,8 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, parse_arg, scanner)
     void *scanner;
 #endif
 {
+  FILE *yyo = yyoutput;
+  YYUSE (yyo);
   if (!yyvaluep)
     return;
   YYUSE (parse_arg);
@@ -736,7 +733,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, parse_arg, scanner)
   switch (yytype)
     {
       default:
-	break;
+        break;
     }
 }
 
@@ -866,7 +863,6 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
-

 
 #if YYERROR_VERBOSE
 
@@ -969,115 +965,145 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # 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];
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
 
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
+{
+  YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULL;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - Assume YYFAIL is not used.  It's too flawed to consider.  See
+       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+       for details.  YYERROR is fine as it does not invoke this
+       function.
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
     {
-      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;
-	  }
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          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 yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                {
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
+                  if (! (yysize <= yysize1
+                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                    return 2;
+                  yysize = yysize1;
+                }
+              }
+        }
+    }
 
-      yyf = YY_(yyformat);
-      yysize1 = yysize + yystrlen (yyf);
-      yysize_overflow |= (yysize1 < yysize);
-      yysize = yysize1;
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
 
-      if (yysize_overflow)
-	return YYSIZE_MAXIMUM;
+  {
+    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+      return 2;
+    yysize = yysize1;
+  }
 
-      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;
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
     }
+
+  /* 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 = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
 }
 #endif /* YYERROR_VERBOSE */
-

 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
@@ -1110,32 +1136,16 @@ yydestruct (yymsg, yytype, yyvaluep, parse_arg, scanner)
     {
 
       default:
-	break;
+        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 (parse_parm_t *parse_arg, void *scanner);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
 
 
 
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
+/*----------.
+| yyparse.  |
+`----------*/
 
 #ifdef YYPARSE_PARAM
 #if (defined __STDC__ || defined __C99__FUNC__ \
@@ -1163,8 +1173,31 @@ yyparse (parse_arg, scanner)
 /* The lookahead symbol.  */
 int yychar;
 
+
+#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma ("GCC diagnostic push") \
+    _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
+    _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma ("GCC diagnostic pop")
+#else
+/* Default value used for initialization, for pacifying older GCCs
+   or non-GCC compilers.  */
+static YYSTYPE yyval_default;
+# define YY_INITIAL_VALUE(Value) = Value
+#endif
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
 /* The semantic value of the lookahead symbol.  */
-YYSTYPE yylval;
+YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
 
     /* Number of syntax errors so far.  */
     int yynerrs;
@@ -1177,7 +1210,7 @@ YYSTYPE yylval;
        `yyss': related to states.
        `yyvs': related to semantic values.
 
-       Refer to the stacks thru separate pointers, to allow yyoverflow
+       Refer to the stacks through separate pointers, to allow yyoverflow
        to reallocate them elsewhere.  */
 
     /* The state stack.  */
@@ -1195,7 +1228,7 @@ YYSTYPE yylval;
   int yyn;
   int yyresult;
   /* Lookahead token as an internal (translated) token number.  */
-  int yytoken;
+  int yytoken = 0;
   /* The variables used to return semantic value and location from the
      action routines.  */
   YYSTYPE yyval;
@@ -1213,9 +1246,8 @@ YYSTYPE yylval;
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yytoken = 0;
-  yyss = yyssa;
-  yyvs = yyvsa;
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
   yystacksize = YYINITDEPTH;
 
   YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1224,14 +1256,6 @@ YYSTYPE yylval;
   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;
 
 /*------------------------------------------------------------.
@@ -1323,7 +1347,7 @@ yybackup:
 
   /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yypact_value_is_default (yyn))
     goto yydefault;
 
   /* Not known => get a lookahead token if don't already have one.  */
@@ -1354,8 +1378,8 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-	goto yyerrlab;
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
@@ -1372,7 +1396,9 @@ yybackup:
   yychar = YYEMPTY;
 
   yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
   goto yynewstate;
 
@@ -1409,179 +1435,171 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 49 "expr_yacc.y"
     { return(0); }
     break;
 
   case 3:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 53 "expr_yacc.y"
     { expr_run((yyvsp[(2) - (2)].nPtr), (parse_parm_t *) parse_arg); freeNode((yyvsp[(2) - (2)].nPtr)); }
     break;
 
   case 5:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 58 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr(';', 2, NULL, NULL); }
     break;
 
   case 6:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 59 "expr_yacc.y"
     { (yyval.nPtr) = (yyvsp[(1) - (2)].nPtr); }
     break;
 
   case 7:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 60 "expr_yacc.y"
     { (yyval.nPtr) = expr_opr('=', 2, expr_var((yyvsp[(1) - (4)].varnm)), (yyvsp[(3) - (4)].nPtr)); }
     break;
 
   case 8:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 61 "expr_yacc.y"
-    { (yyval.nPtr) = (yyvsp[(2) - (3)].nPtr); }
+    { (yyval.nPtr) = expr_opr('=', 2, expr_var((yyvsp[(1) - (2)].varnm)), expr_var((yyvsp[(1) - (2)].varnm))); }
     break;
 
   case 9:
-
-/* Line 1464 of yacc.c  */
-#line 65 "expr_yacc.y"
-    { (yyval.nPtr) = (yyvsp[(1) - (1)].nPtr); }
+/* Line 1792 of yacc.c  */
+#line 62 "expr_yacc.y"
+    { (yyval.nPtr) = (yyvsp[(2) - (3)].nPtr); }
     break;
 
   case 10:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 66 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr(';', 2, (yyvsp[(1) - (2)].nPtr), (yyvsp[(2) - (2)].nPtr)); }
+    { (yyval.nPtr) = (yyvsp[(1) - (1)].nPtr); }
     break;
 
   case 11:
-
-/* Line 1464 of yacc.c  */
-#line 70 "expr_yacc.y"
-    { (yyval.nPtr) = expr_con((yyvsp[(1) - (1)].cvalue)); }
+/* Line 1792 of yacc.c  */
+#line 67 "expr_yacc.y"
+    { (yyval.nPtr) = expr_opr(';', 2, (yyvsp[(1) - (2)].nPtr), (yyvsp[(2) - (2)].nPtr)); }
     break;
 
   case 12:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 71 "expr_yacc.y"
-    { (yyval.nPtr) = expr_var((yyvsp[(1) - (1)].varnm)); }
+    { (yyval.nPtr) = expr_con((yyvsp[(1) - (1)].cvalue)); }
     break;
 
   case 13:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 72 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr(UMINUS, 1, (yyvsp[(2) - (2)].nPtr)); }
+    { (yyval.nPtr) = expr_var((yyvsp[(1) - (1)].varnm)); }
     break;
 
   case 14:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 73 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr('+', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    { (yyval.nPtr) = expr_opr(UMINUS, 1, (yyvsp[(2) - (2)].nPtr)); }
     break;
 
   case 15:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 74 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr('-', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    { (yyval.nPtr) = expr_opr('+', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 16:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 75 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr('*', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    { (yyval.nPtr) = expr_opr('-', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 17:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 76 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr('/', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    { (yyval.nPtr) = expr_opr('*', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 18:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 77 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr('<', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    { (yyval.nPtr) = expr_opr('/', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 19:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 78 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr('>', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    { (yyval.nPtr) = expr_opr('<', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 20:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 79 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr('^', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    { (yyval.nPtr) = expr_opr('>', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 21:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 80 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr(GE, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    { (yyval.nPtr) = expr_opr('^', 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 22:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 81 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr(LE, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    { (yyval.nPtr) = expr_opr(GE, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 23:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 82 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr(NE, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    { (yyval.nPtr) = expr_opr(LE, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 24:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 83 "expr_yacc.y"
-    { (yyval.nPtr) = expr_opr(EQ, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
+    { (yyval.nPtr) = expr_opr(NE, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 25:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 84 "expr_yacc.y"
-    { (yyval.nPtr) = (yyvsp[(2) - (3)].nPtr); }
+    { (yyval.nPtr) = expr_opr(EQ, 2, (yyvsp[(1) - (3)].nPtr), (yyvsp[(3) - (3)].nPtr)); }
     break;
 
   case 26:
-
-/* Line 1464 of yacc.c  */
+/* Line 1792 of yacc.c  */
 #line 85 "expr_yacc.y"
-    { (yyval.nPtr) = expr_fun((yyvsp[(1) - (4)].fname), (yyvsp[(3) - (4)].nPtr)); }
+    { (yyval.nPtr) = (yyvsp[(2) - (3)].nPtr); }
     break;
 
+  case 27:
+/* Line 1792 of yacc.c  */
+#line 86 "expr_yacc.y"
+    { (yyval.nPtr) = expr_fun((yyvsp[(1) - (4)].fname), (yyvsp[(3) - (4)].nPtr)); }
+    break;
 
 
-/* Line 1464 of yacc.c  */
-#line 1583 "expr_yacc.c"
+/* Line 1792 of yacc.c  */
+#line 1590 "expr_yacc.c"
       default: break;
     }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -1609,6 +1627,10 @@ yyreduce:
 | yyerrlab -- here on detecting error |
 `------------------------------------*/
 yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -1616,37 +1638,36 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (parse_arg, scanner, YY_("syntax error"));
 #else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
       {
-	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 (parse_arg, scanner, yymsg);
-	  }
-	else
-	  {
-	    yyerror (parse_arg, scanner, YY_("syntax error"));
-	    if (yysize != 0)
-	      goto yyexhaustedlab;
-	  }
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (parse_arg, scanner, yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
       }
+# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -1705,7 +1726,7 @@ yyerrlab1:
   for (;;)
     {
       yyn = yypact[yystate];
-      if (yyn != YYPACT_NINF)
+      if (!yypact_value_is_default (yyn))
 	{
 	  yyn += YYTERROR;
 	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -1728,7 +1749,9 @@ yyerrlab1:
       YY_STACK_PRINT (yyss, yyssp);
     }
 
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
 
   /* Shift the error token.  */
@@ -1752,7 +1775,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -1764,8 +1787,13 @@ yyexhaustedlab:
 
 yyreturn:
   if (yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-		 yytoken, &yylval, parse_arg, scanner);
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval, parse_arg, scanner);
+    }
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
@@ -1789,9 +1817,8 @@ yyreturn:
 }
 
 
-
-/* Line 1684 of yacc.c  */
-#line 88 "expr_yacc.y"
+/* Line 2055 of yacc.c  */
+#line 89 "expr_yacc.y"
 
 
 #define SIZEOF_NODETYPE ((char *)&p->u.con - (char *)p)
@@ -1803,7 +1830,7 @@ nodeType *expr_con(double value)
 
   /* allocate node */
   nodeSize = SIZEOF_NODETYPE + sizeof(conNodeType);
-  if ((p = (nodeType *) malloc(nodeSize)) == NULL)
+  if ((p = malloc(nodeSize)) == NULL)
     yyerror(NULL, NULL, "Out of memory");
 
   /* copy information */
@@ -1820,7 +1847,7 @@ nodeType *expr_var(char *nm)
 
   /* allocate node */
   nodeSize = SIZEOF_NODETYPE + sizeof(varNodeType);
-  if ((p = (nodeType *) malloc(nodeSize)) == NULL)
+  if ((p = malloc(nodeSize)) == NULL)
     yyerror(NULL, NULL, "Out of memory");
 
   /* copy information */
@@ -1837,7 +1864,7 @@ nodeType *expr_fun(char *fname, nodeType *op)
 
   /* allocate node */
   nodeSize = SIZEOF_NODETYPE + sizeof(funNodeType);
-  if ((p = (nodeType *) malloc(nodeSize)) == NULL)
+  if ((p = malloc(nodeSize)) == NULL)
     yyerror(NULL, NULL, "Out of memory");
 
   /* copy information */
@@ -1857,7 +1884,7 @@ nodeType *expr_opr(int oper, int nops, ...)
 
   /* allocate node */
   nodeSize = SIZEOF_NODETYPE + sizeof(oprNodeType) + (nops - 1)*sizeof(nodeType*);
-  if ((p = (nodeType *) malloc(nodeSize)) == NULL)
+  if ((p = malloc(nodeSize)) == NULL)
     yyerror(NULL, NULL, "Out of memory");
 
   /* copy information */
@@ -1891,38 +1918,41 @@ void yyerror(void *parse_arg, void *scanner, char *s)
 {
   fprintf(stdout, "%s\n", s);
 }
-
 /*
 int main(void)
 {
   int i;
   static char fexpr[] = "nvar = q*(geosp+234.56); xx = geosp+999-log(aps);";
+  void *scanner;
+  int yy_scan_string(const char *str, void *scanner);
 
   parse_parm_t parse_arg;
 
   printf("%s\n", fexpr);
 
-  yy_scan_string(fexpr);
+  yylex_init(&scanner);
+  yyset_extra(&parse_arg, scanner);
 
-  parse_arg.nvar = 0;
-  parse_arg.init = 1;
+  yy_scan_string(fexpr, scanner);
+
+  parse_arg.nvars1 = 0;
+  parse_arg.init  = 1;
   parse_arg.debug = 1;
 
-  yyparse((void *)&parse_arg);
+  yyparse((void *)&parse_arg, scanner);
 
-  for ( i = 0; i < parse_arg.nvar; i++ )
+  for ( i = 0; i < parse_arg.nvars1; i++ )
     printf("vars %d %s\n", i, parse_arg.var[i]);
 
-  yy_scan_string(fexpr);
+  yy_scan_string(fexpr, scanner);
 
   parse_arg.init = 0;
 
-  yyparse((void *)&parse_arg);
+  yyparse((void *)&parse_arg, scanner);
 
-  for ( i = 0; i < parse_arg.nvar; i++ )
+  for ( i = 0; i < parse_arg.nvars1; i++ )
     printf("vars %d %s\n", i, parse_arg.var[i]);
 
   return 0;
 }
 */
-
diff --git a/src/expr_yacc.h b/src/expr_yacc.h
index 4ee9d50..067f8b8 100644
--- a/src/expr_yacc.h
+++ b/src/expr_yacc.h
@@ -1,9 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.4.2.  */
+/* A Bison parser, made by GNU Bison 2.7.  */
 
-/* Skeleton interface for Bison's Yacc-like parsers in C
+/* Bison interface for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software
-   Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2012 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
@@ -31,6 +30,15 @@
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
+#ifndef YY_YY_EXPR_YACC_H_INCLUDED
+# define YY_YY_EXPR_YACC_H_INCLUDED
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
 
 /* Tokens.  */
 #ifndef YYTOKENTYPE
@@ -60,7 +68,6 @@
 
 
 
-
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -68,5 +75,18 @@
 #endif
 
 
+#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 (parse_parm_t *parse_arg, void *scanner);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
 
-
+#endif /* !YY_YY_EXPR_YACC_H_INCLUDED  */
diff --git a/src/field.c b/src/field.c
index 1ead9c2..a81ebee 100644
--- a/src/field.c
+++ b/src/field.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -560,7 +560,7 @@ double fldpctl(field_t field, const int p)
     {
       if ( nmiss > 0 )
         {
-          array2 = (double *) malloc((len - nmiss)*sizeof(double));
+          array2 = malloc((len - nmiss)*sizeof(double));
 
           for ( i = 0, j = 0; i < len; i++ ) 
             if ( !DBL_IS_EQUAL(array[i], missval) )
diff --git a/src/field.h b/src/field.h
index 57fae7f..74d9cc6 100644
--- a/src/field.h
+++ b/src/field.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/field2.c b/src/field2.c
index 7c3586f..c1c1ca1 100644
--- a/src/field2.c
+++ b/src/field2.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/fieldc.c b/src/fieldc.c
index 5b34853..1ad9d2a 100644
--- a/src/fieldc.c
+++ b/src/fieldc.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/fieldmem.c b/src/fieldmem.c
index b5a82e3..4bdfdf7 100644
--- a/src/fieldmem.c
+++ b/src/fieldmem.c
@@ -24,7 +24,7 @@ field_t **field_allocate(int vlistID, int ptype, int init)
 
   nvars = vlistNvars(vlistID);
 
-  field = (field_t **) malloc(nvars*sizeof(field_t *));
+  field = malloc(nvars*sizeof(field_t *));
 
   for ( varID = 0; varID < nvars; ++varID )
     {
@@ -35,7 +35,7 @@ field_t **field_allocate(int vlistID, int ptype, int init)
       nlevel   = zaxisInqSize(zaxisID);
       missval  = vlistInqVarMissval(vlistID, varID);
 
-      field[varID] = (field_t *)  malloc(nlevel*sizeof(field_t));
+      field[varID] = malloc(nlevel*sizeof(field_t));
       for ( levelID = 0; levelID < nlevel; ++levelID )
 	{
 	  field_init(&field[varID][levelID]);
@@ -50,13 +50,13 @@ field_t **field_allocate(int vlistID, int ptype, int init)
 
 	  if ( ptype == FIELD_ALL || ptype == FIELD_PTR )
 	    {
-	      field[varID][levelID].ptr = (double *) malloc(nwpv*gridsize*sizeof(double));
+	      field[varID][levelID].ptr = malloc(nwpv*gridsize*sizeof(double));
 	      if ( init ) memset(field[varID][levelID].ptr, 0, nwpv*gridsize*sizeof(double));
 	    }
 
 	  if ( ptype == FIELD_ALL || ptype == FIELD_PTR )
 	    {
-	      field[varID][levelID].weight = (double *) malloc(nwpv*gridsize*sizeof(double));
+	      field[varID][levelID].weight = malloc(nwpv*gridsize*sizeof(double));
 	      if ( init ) memset(field[varID][levelID].weight, 0, nwpv*gridsize*sizeof(double));
 	    }    
 	}
diff --git a/src/fieldmer.c b/src/fieldmer.c
index 9af558c..6b53fd0 100644
--- a/src/fieldmer.c
+++ b/src/fieldmer.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -366,7 +366,7 @@ void merpctl(field_t field1, field_t *field2, int p)
   nx = gridInqXsize(grid);
   ny = gridInqYsize(grid);
   
-  array2 = (double *) malloc(nx*sizeof(double));
+  array2 = malloc(nx*sizeof(double));
   
   if ( nmiss > 0 )
     {
diff --git a/src/fieldzon.c b/src/fieldzon.c
index 2d45f67..4f0ba58 100644
--- a/src/fieldzon.c
+++ b/src/fieldzon.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -422,7 +422,7 @@ void zonpctl(field_t field1, field_t *field2, int p)
   
   if ( nmiss > 0 )
     {
-      array2 = (double *) malloc(nx*sizeof(double));
+      array2 = malloc(nx*sizeof(double));
       
       for ( j = 0; j < ny; j++ )
         {
diff --git a/src/fouriertrans.c b/src/fouriertrans.c
index e604b30..a17cb01 100644
--- a/src/fouriertrans.c
+++ b/src/fouriertrans.c
@@ -2005,9 +2005,9 @@ void fc2gp(double *trig, long *ifax, double *fc, double *gp, long nlat, long nlo
   jump = (nlon + 2);
   lot  = nlev * nlat;
 
-  wfc = (double *) malloc(lot*jump*sizeof(double));
+  wfc = malloc(lot*jump*sizeof(double));
 #if ! defined(_OPENMP)
-  wgp = (double *) malloc(lot*jump*sizeof(double));
+  wgp = malloc(lot*jump*sizeof(double));
 #endif
 
   for ( lev = 0; lev < nlev; ++lev )
@@ -2033,7 +2033,7 @@ void fc2gp(double *trig, long *ifax, double *fc, double *gp, long nlat, long nlo
   nvex  = lot - (nblox-1)*NFFT;
   nvex0 = nvex;
 
-  istartv = (long *) malloc(nblox*sizeof(long));
+  istartv = malloc(nblox*sizeof(long));
 
   istart = 0;
   for ( nb = 0; nb < nblox; nb++ )
@@ -2049,7 +2049,7 @@ void fc2gp(double *trig, long *ifax, double *fc, double *gp, long nlat, long nlo
   for ( nb = 0; nb < nblox; nb++ )
     {
 #if defined(_OPENMP)
-      wgp = (double *) malloc(lot*jump*sizeof(double));
+      wgp = malloc(lot*jump*sizeof(double));
 #endif
       istart = istartv[nb];
       if ( nb == 0 ) nvex = nvex0;
@@ -2174,8 +2174,8 @@ void gp2fc(double *trig, long *ifax, double *gp, double *fc, long nlat, long nlo
   jump = (nlon + 2);
   lot  = nlev * nlat;
 
-  wfc = (double *) malloc(lot * jump * sizeof(double));
-  wgp = (double *) malloc(lot * jump * sizeof(double));
+  wfc = malloc(lot * jump * sizeof(double));
+  wgp = malloc(lot * jump * sizeof(double));
 
   rix = 0;
   wix = 0;
diff --git a/src/grid.c b/src/grid.c
index 8768009..28329df 100644
--- a/src/grid.c
+++ b/src/grid.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -109,7 +109,7 @@ int gridToZonal(int gridID1)
 
       if ( gridInqYvals(gridID1, NULL) )
 	{
-	  yvals = (double *) malloc(gridsize*sizeof(double));
+	  yvals = malloc(gridsize*sizeof(double));
 
 	  gridInqYvals(gridID1, yvals);
 	  gridDefYvals(gridID2, yvals);
@@ -146,7 +146,7 @@ int gridToMeridional(int gridID1)
 
       if ( gridInqXvals(gridID1, NULL) )
 	{
-	  xvals = (double *) malloc(gridsize*sizeof(double));
+	  xvals = malloc(gridsize*sizeof(double));
 
 	  gridInqXvals(gridID1, xvals);
 	  gridDefXvals(gridID2, xvals);
@@ -165,59 +165,168 @@ int gridToMeridional(int gridID1)
 }
 
 
-void gridGenXbounds(int nx, double *xvals, double *xbounds)
+void grid_gen_corners(long n, const double* restrict vals, double* restrict corners)
 {
-  int i;
+  long i;
 
-  for ( i = 0; i < nx-1; i++ )
+  for ( i = 0; i < n-1; ++i )
     {
-      xbounds[2*i+1]   = 0.5*(xvals[i] + xvals[i+1]);
-      xbounds[2*(i+1)] = 0.5*(xvals[i] + xvals[i+1]);
+      corners[i+1] = 0.5*(vals[i] + vals[i+1]);
     }
 
-  xbounds[0]      = 2*xvals[0] - xbounds[1];
-  xbounds[2*nx-1] = 2*xvals[nx-1] - xbounds[2*(nx-1)];
+  corners[0] = 2*vals[0] - corners[1];
+  corners[n] = 2*vals[n-1] - corners[n-1];
 }
 
 
-void gridGenYbounds(int ny, double *yvals, double *ybounds)
+void grid_gen_bounds(long n, const double* restrict vals, double* restrict bounds)
 {
-  int i;
+  long i;
 
-  for ( i = 0; i < ny-1; i++ )
+  for ( i = 0; i < n-1; ++i )
     {
-      ybounds[2*i+1]   = 0.5*(yvals[i] + yvals[i+1]);
-      ybounds[2*(i+1)] = 0.5*(yvals[i] + yvals[i+1]);
+      bounds[2*i+1]   = 0.5*(vals[i] + vals[i+1]);
+      bounds[2*(i+1)] = 0.5*(vals[i] + vals[i+1]);
     }
 
-  ybounds[0]      = 2*yvals[0] - ybounds[1];
-  ybounds[2*ny-1] = 2*yvals[ny-1] - ybounds[2*(ny-1)];
+  bounds[0]     = 2*vals[0] - bounds[1];
+  bounds[2*n-1] = 2*vals[n-1] - bounds[2*(n-1)];
+}
+
 
-  if ( yvals[0] > yvals[ny-1] )
+void grid_check_lat_borders(int n, double *ybounds)
+{
+  if ( ybounds[0] > ybounds[n-1] )
     {
-      if ( ybounds[0]      >  88 ) ybounds[0]      =  90;
-      if ( ybounds[2*ny-1] < -88 ) ybounds[2*ny-1] = -90;
+      if ( ybounds[0]   >  88 ) ybounds[0]   =  90;
+      if ( ybounds[n-1] < -88 ) ybounds[n-1] = -90;
     }
   else
     {
-      if ( ybounds[0]      < -88 ) ybounds[0]      = -90;
-      if ( ybounds[2*ny-1] >  88 ) ybounds[2*ny-1] =  90;
+      if ( ybounds[0]   < -88 ) ybounds[0]   = -90;
+      if ( ybounds[n-1] >  88 ) ybounds[n-1] =  90;
     }
 }
 
 
-void gridGenYboundsM(int ny, double *yvals, double *ybounds)
+void grid_cell_center_to_bounds_X2D(const char* xunitstr, long xsize, long ysize, const double* restrict grid_center_lon, 
+				    double* restrict grid_corner_lon, double dlon)
 {
-  int i;
+  long i, j, index;
+  double minlon, maxlon;
 
-  for ( i = 0; i < ny-1; i++ )
+  if ( ! (dlon > 0) ) dlon = 360./xsize;
+  /*
+  if ( xsize == 1 || (grid_center_lon[xsize-1]-grid_center_lon[0]+dlon) < 359 )
+    cdoAbort("Cannot calculate Xbounds for %d vals with dlon = %g", xsize, dlon);
+  */
+  for ( i = 0; i < xsize; ++i )
     {
-      ybounds[2*i+1]   = 0.5*(yvals[i] + yvals[i+1]);
-      ybounds[2*(i+1)] = 0.5*(yvals[i] + yvals[i+1]);
+      minlon = grid_center_lon[i] - 0.5*dlon;
+      maxlon = grid_center_lon[i] + 0.5*dlon;
+      for ( j = 0; j < ysize; ++j )
+	{
+	  index = (j<<2)*xsize + (i<<2);
+	  grid_corner_lon[index  ] = minlon;
+	  grid_corner_lon[index+1] = maxlon;
+	  grid_corner_lon[index+2] = maxlon;
+	  grid_corner_lon[index+3] = minlon;
+	}
     }
+}
+
+static
+double genYmin(double y1, double y2)
+{
+  double ymin, dy;
+
+  dy = y2 - y1;
+  ymin = y1 - dy/2;
+
+  if ( y1 < -85 && ymin < -87.5 ) ymin = -90;
+
+  if ( cdoVerbose )
+    cdoPrint("genYmin: y1 = %g  y2 = %g  dy = %g  ymin = %g", y1, y2, dy, ymin);
+
+  return (ymin);
+}
+
+static
+double genYmax(double y1, double y2)
+{
+  double ymax, dy;
+
+  dy = y1 - y2;
+  ymax = y1 + dy/2;
+
+  if ( y1 > 85 && ymax > 87.5 ) ymax = 90;
+
+  if ( cdoVerbose )
+    cdoPrint("genYmax: y1 = %g  y2 = %g  dy = %g  ymax = %g", y1, y2, dy, ymax);
 
-  ybounds[0]      = 2*yvals[0] - ybounds[1];
-  ybounds[2*ny-1] = 2*yvals[ny-1] - ybounds[2*(ny-1)];
+  return (ymax);
+}
+
+
+
+/*****************************************************************************/
+
+void grid_cell_center_to_bounds_Y2D(const char* yunitstr, long xsize, long ysize, const double* restrict grid_center_lat, double* restrict grid_corner_lat)
+{
+  long i, j, index;
+  double minlat, maxlat;
+  double firstlat, lastlat;
+
+  firstlat = grid_center_lat[0];
+  lastlat  = grid_center_lat[xsize*ysize-1];
+
+  // if ( ysize == 1 ) cdoAbort("Cannot calculate Ybounds for 1 value!");
+
+  for ( j = 0; j < ysize; ++j )
+    {
+      if ( ysize == 1 )
+	{
+	  minlat = grid_center_lat[0] - 360./ysize;
+	  maxlat = grid_center_lat[0] + 360./ysize;
+	}
+      else
+	{
+	  index = j*xsize;
+	  if ( firstlat > lastlat )
+	    {
+	      if ( j == 0 )
+		maxlat = genYmax(grid_center_lat[index], grid_center_lat[index+xsize]);
+	      else
+		maxlat = 0.5*(grid_center_lat[index]+grid_center_lat[index-xsize]);
+
+	      if ( j == (ysize-1) )
+		minlat = genYmin(grid_center_lat[index], grid_center_lat[index-xsize]);
+	      else
+		minlat = 0.5*(grid_center_lat[index]+grid_center_lat[index+xsize]);
+	    }
+	  else
+	    {
+	      if ( j == 0 )
+		minlat = genYmin(grid_center_lat[index], grid_center_lat[index+xsize]);
+	      else
+		minlat = 0.5*(grid_center_lat[index]+grid_center_lat[index-xsize]);
+
+	      if ( j == (ysize-1) )
+		maxlat = genYmax(grid_center_lat[index], grid_center_lat[index-xsize]);
+	      else
+		maxlat = 0.5*(grid_center_lat[index]+grid_center_lat[index+xsize]);
+	    }
+	}
+
+      for ( i = 0; i < xsize; ++i )
+	{
+	  index = (j<<2)*xsize + (i<<2);
+	  grid_corner_lat[index  ] = minlat;
+	  grid_corner_lat[index+1] = minlat;
+	  grid_corner_lat[index+2] = maxlat;
+	  grid_corner_lat[index+3] = maxlat;
+	}
+    }
 }
 
 
@@ -266,7 +375,7 @@ void gridGenRotBounds(int gridID, int nx, int ny,
 }
 
 static
-void gridGenXbounds2D(int nx, int ny, const double * restrict xbounds, double * restrict xbounds2D)
+void gridGenXbounds2D(long nx, long ny, const double* restrict xbounds, double* restrict xbounds2D)
 {
   long i, j, index;
   double minlon, maxlon;
@@ -293,7 +402,7 @@ void gridGenXbounds2D(int nx, int ny, const double * restrict xbounds, double *
 }
 
 static
-void gridGenYbounds2D(int nx, int ny, const double * restrict ybounds, double * restrict ybounds2D)
+void gridGenYbounds2D(long nx, long ny, const double* restrict ybounds, double* restrict ybounds2D)
 {
   long i, j, index;
   double minlat, maxlat;
@@ -342,7 +451,7 @@ char *gen_param(const char *fmt, ...)
   va_end(args);
 
   len++;
-  rstr = (char *) malloc(len*sizeof(char));
+  rstr = malloc(len*sizeof(char));
   memcpy(rstr, str, len*sizeof(char));
 
   return (rstr);
@@ -359,8 +468,7 @@ void lcc_to_geo(int gridID, int gridsize, double *xvals, double *yvals)
   long i;
   proj_info_t proj;
 
-  gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm,
-	     &projflag, &scanflag);
+  gridInqLCC(gridID, &originLon, &originLat, &lonParY, &lat1, &lat2, &xincm, &yincm, &projflag, &scanflag);
   /*
     while ( originLon < 0 ) originLon += 360;
     while ( lonParY   < 0 ) lonParY   += 360;
@@ -417,6 +525,8 @@ void sinusoidal_to_geo(int gridsize, double *xvals, double *yvals)
       res = pj_inv(data, libProj);
       xvals[i] = res.u*RAD2DEG;
       yvals[i] = res.v*RAD2DEG;
+      if ( xvals[i] < -9000. || xvals[i] > 9000. ) xvals[i] = -9999.;
+      if ( yvals[i] < -9000. || yvals[i] > 9000. ) yvals[i] = -9999.;
     }
 #else
   cdoAbort("proj4 support not compiled in!");
@@ -461,6 +571,8 @@ void laea_to_geo(int gridID, int gridsize, double *xvals, double *yvals)
       res = pj_inv(data, libProj);
       xvals[i] = res.u*RAD2DEG;
       yvals[i] = res.v*RAD2DEG;
+      if ( xvals[i] < -9000. || xvals[i] > 9000. ) xvals[i] = -9999.;
+      if ( yvals[i] < -9000. || yvals[i] > 9000. ) yvals[i] = -9999.;
     }
 #else
   cdoAbort("proj4 support not compiled in!");
@@ -609,8 +721,8 @@ int qu2reg_subarea(int gridsize, int np, double xfirst, double xlast,
 
   for ( j = 0; j < ny; ++j ) nwork += rowlon[j];
 
-  pwork = (double **) malloc(ny*sizeof(double *));
-  work  = (double *) malloc(ny*np4*sizeof(double));
+  pwork = malloc(ny*sizeof(double *));
+  work  = malloc(ny*np4*sizeof(double));
   wlen = 0;
   pwork[0] = work;
   for ( j = 1; j < ny; ++j )
@@ -697,7 +809,7 @@ void field2regular(int gridID1, int gridID2, double missval, double *array, int
   ny = gridInqYsize(gridID1);
   np = gridInqNP(gridID1);
 
-  rowlon = (int *) malloc(ny*sizeof(int));
+  rowlon = malloc(ny*sizeof(int));
   gridInqRowlon(gridID1, rowlon);
 
   xfirstandlast[0] = 0.;
@@ -739,7 +851,7 @@ int gridToRegular(int gridID1)
   ny = gridInqYsize(gridID1);
   np = gridInqNP(gridID1);
 
-  yvals = (double *) malloc(ny*sizeof(double));
+  yvals = malloc(ny*sizeof(double));
   gridInqYvals(gridID1, yvals);
 
   xfirstandlast[0] = 0.;
@@ -761,7 +873,7 @@ int gridToRegular(int gridID1)
       grib_get_reduced_row(np4, xfirst, xlast, &row_count, &ilon_first, &ilon_last);
 
       nx = row_count;
-      xvals = (double *) malloc(nx*sizeof(double));
+      xvals = malloc(nx*sizeof(double));
       for ( i = 0; i < nx; ++i )
 	{
 	  xvals[i] = ((ilon_first+i)*360.)/np4;
@@ -773,7 +885,7 @@ int gridToRegular(int gridID1)
   else
     {
       nx = 2*ny;
-      xvals = (double *) malloc(nx*sizeof(double));
+      xvals = malloc(nx*sizeof(double));
       for ( i = 0; i < nx; ++i ) xvals[i] = i * 360./nx;
     }
 
@@ -800,7 +912,7 @@ void gridCopyMask(int gridID1, int gridID2, long gridsize)
   if ( gridInqMask(gridID1, NULL) )
     {
       int *mask;
-      mask = (int *) malloc(gridsize*sizeof(int));
+      mask = malloc(gridsize*sizeof(int));
       gridInqMask(gridID1, mask);
       gridDefMask(gridID2, mask);
       free(mask);
@@ -885,8 +997,8 @@ int gridToCurvilinear(int gridID1, int lbounds)
 	gridDefXsize(gridID2, nx);
 	gridDefYsize(gridID2, ny);
 
-	xvals2D = (double *) malloc(gridsize*sizeof(double));
-	yvals2D = (double *) malloc(gridsize*sizeof(double));
+	xvals2D = malloc(gridsize*sizeof(double));
+	yvals2D = malloc(gridsize*sizeof(double));
 
 
 	if ( gridtype == GRID_LCC )
@@ -905,8 +1017,8 @@ int gridToCurvilinear(int gridID1, int lbounds)
 	    if ( ! (gridInqXvals(gridID1, NULL) && gridInqYvals(gridID1, NULL)) )
 	      Error("Grid has no values");
 
-	    xvals = (double *) malloc(nx*sizeof(double));
-	    yvals = (double *) malloc(ny*sizeof(double));
+	    xvals = malloc(nx*sizeof(double));
+	    yvals = malloc(ny*sizeof(double));
 
 	    gridInqXvals(gridID1, xvals);
 	    gridInqYvals(gridID1, yvals);
@@ -961,8 +1073,8 @@ int gridToCurvilinear(int gridID1, int lbounds)
 
 	if ( gridtype == GRID_LCC )
 	  {		
-	    xbounds2D = (double *) malloc(4*gridsize*sizeof(double));
-	    ybounds2D = (double *) malloc(4*gridsize*sizeof(double));
+	    xbounds2D = malloc(4*gridsize*sizeof(double));
+	    ybounds2D = malloc(4*gridsize*sizeof(double));
 
 	    for ( j = 0; j < ny; j++ )
 	      for ( i = 0; i < nx; i++ )
@@ -994,7 +1106,7 @@ int gridToCurvilinear(int gridID1, int lbounds)
 	  {
 	    if ( gridInqXbounds(gridID1, NULL) )
 	      {
-		xbounds = (double *) malloc(2*nx*sizeof(double));
+		xbounds = malloc(2*nx*sizeof(double));
 		gridInqXbounds(gridID1, xbounds);
 		if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN )
 		  if ( check_range(2*nx, xbounds, -720, 720) )
@@ -1006,13 +1118,13 @@ int gridToCurvilinear(int gridID1, int lbounds)
 	      }
 	    else if ( nx > 1 )
 	      {
-		xbounds = (double *) malloc(2*nx*sizeof(double));
-		gridGenXbounds(nx, xvals, xbounds);
+		xbounds = malloc(2*nx*sizeof(double));
+		grid_gen_bounds(nx, xvals, xbounds);
 	      }
 
 	    if ( gridInqYbounds(gridID1, NULL) )
 	      {
-		ybounds = (double *) malloc(2*ny*sizeof(double));
+		ybounds = malloc(2*ny*sizeof(double));
 		gridInqYbounds(gridID1, ybounds);
 		if ( gridtype == GRID_LONLAT || gridtype == GRID_GAUSSIAN )
 		  if ( check_range(2*ny, ybounds, -180, 180) )
@@ -1024,19 +1136,22 @@ int gridToCurvilinear(int gridID1, int lbounds)
 	      }
 	    else if ( ny > 1 )
 	      {
-		ybounds = (double *) malloc(2*ny*sizeof(double));
+		ybounds = malloc(2*ny*sizeof(double));
 		if ( gridtype == GRID_SINUSOIDAL || 
 		     gridtype == GRID_LAEA       || 
 		     gridtype == GRID_LCC2 )
-		  gridGenYboundsM(ny, yvals, ybounds);
+		  grid_gen_bounds(ny, yvals, ybounds);
 		else
-		  gridGenYbounds(ny, yvals, ybounds);
+		  {
+		    grid_gen_bounds(ny, yvals, ybounds);
+		    grid_check_lat_borders(2*ny, ybounds);
+		  }
 	      }
 
 	    if ( xbounds && ybounds )
 	      {
-		xbounds2D = (double *) malloc(4*gridsize*sizeof(double));
-		ybounds2D = (double *) malloc(4*gridsize*sizeof(double));
+		xbounds2D = malloc(4*gridsize*sizeof(double));
+		ybounds2D = malloc(4*gridsize*sizeof(double));
 
 		if ( gridIsRotated(gridID1) )
 		  {
@@ -1070,7 +1185,7 @@ int gridToCurvilinear(int gridID1, int lbounds)
 			  {
 			    sinusoidal_to_geo(4*gridsize, xbounds2D, ybounds2D);
 			    /*
-			    xvals2D = (double *) malloc(gridsize*sizeof(double));
+			    xvals2D = malloc(gridsize*sizeof(double));
 			    for ( j = 0; j < 4; ++j )
 			      {
 				for ( i = 0; i < gridsize; ++i ) xvals2D[i] = xbounds2D[i*4+j];
@@ -1157,11 +1272,11 @@ int gridToUnstructured(int gridID1, int lbounds)
 	gridDefXsize(gridID2, gridsize);
 	gridDefYsize(gridID2, gridsize);
 
-	xvals = (double *) malloc(nx*sizeof(double));
-	yvals = (double *) malloc(ny*sizeof(double));
+	xvals = malloc(nx*sizeof(double));
+	yvals = malloc(ny*sizeof(double));
 
-	xvals2D = (double *) malloc(gridsize*sizeof(double));
-	yvals2D = (double *) malloc(gridsize*sizeof(double));
+	xvals2D = malloc(gridsize*sizeof(double));
+	yvals2D = malloc(gridsize*sizeof(double));
 
 	gridInqXvals(gridID1, xvals);
 	gridInqYvals(gridID1, yvals);
@@ -1204,30 +1319,31 @@ int gridToUnstructured(int gridID1, int lbounds)
 
 	    if ( gridInqXbounds(gridID1, NULL) )
 	      {
-		xbounds = (double *) malloc(2*nx*sizeof(double));
+		xbounds = malloc(2*nx*sizeof(double));
 		gridInqXbounds(gridID1, xbounds);
 	      }
 	    else if ( nx > 1 )
 	      {
-		xbounds = (double *) malloc(2*nx*sizeof(double));
-		gridGenXbounds(nx, xvals, xbounds);
+		xbounds = malloc(2*nx*sizeof(double));
+		grid_gen_bounds(nx, xvals, xbounds);
 	      }
 
 	    if ( gridInqYbounds(gridID1, NULL) )
 	      {
-		ybounds = (double *) malloc(2*ny*sizeof(double));
+		ybounds = malloc(2*ny*sizeof(double));
 		gridInqYbounds(gridID1, ybounds);
 	      }
 	    else if ( ny > 1 )
 	      {
-		ybounds = (double *) malloc(2*ny*sizeof(double));
-		gridGenYbounds(ny, yvals, ybounds);
+		ybounds = malloc(2*ny*sizeof(double));
+		grid_gen_bounds(ny, yvals, ybounds);
+		grid_check_lat_borders(2*ny, ybounds);
 	      }
 
 	    if ( xbounds && ybounds )
 	      {
-		xbounds2D = (double *) malloc(4*gridsize*sizeof(double));
-		ybounds2D = (double *) malloc(4*gridsize*sizeof(double));
+		xbounds2D = malloc(4*gridsize*sizeof(double));
+		ybounds2D = malloc(4*gridsize*sizeof(double));
 
 		if ( gridIsRotated(gridID1) )
 		  {
@@ -1279,13 +1395,13 @@ int gridToUnstructured(int gridID1, int lbounds)
 	ni2 = gridInqGMEni2(gridID1);
 	ni3 = gridInqGMEni3(gridID1);
 
-	imask   = (int *) malloc(gridsize*sizeof(int));
-	xvals   = (double *) malloc(gridsize*sizeof(double));
-	yvals   = (double *) malloc(gridsize*sizeof(double));
+	imask   = malloc(gridsize*sizeof(int));
+	xvals   = malloc(gridsize*sizeof(double));
+	yvals   = malloc(gridsize*sizeof(double));
 	if ( lbounds )
 	  {
-	    xbounds = (double *) malloc(nv*gridsize*sizeof(double));
-	    ybounds = (double *) malloc(nv*gridsize*sizeof(double));
+	    xbounds = malloc(nv*gridsize*sizeof(double));
+	    ybounds = malloc(nv*gridsize*sizeof(double));
 	  }
 
 	gme_grid(lbounds, gridsize, xvals, yvals, xbounds, ybounds, imask, ni, nd, ni2, ni3);
@@ -1363,14 +1479,14 @@ int gridCurvilinearToRegular(int gridID1)
   nx = gridInqXsize(gridID1);
   ny = gridInqYsize(gridID1);
 	
-  xvals2D = (double *) malloc(gridsize*sizeof(double));
-  yvals2D = (double *) malloc(gridsize*sizeof(double));
+  xvals2D = malloc(gridsize*sizeof(double));
+  yvals2D = malloc(gridsize*sizeof(double));
 
   gridInqXvals(gridID1, xvals2D);
   gridInqYvals(gridID1, yvals2D);
 
-  xvals = (double *) malloc(nx*sizeof(double));
-  yvals = (double *) malloc(ny*sizeof(double));
+  xvals = malloc(nx*sizeof(double));
+  yvals = malloc(ny*sizeof(double));
 
   for ( i = 0; i < nx; i++ ) xvals[i] = xvals2D[i];
   for ( j = 0; j < ny; j++ ) yvals[j] = yvals2D[j*nx];
@@ -1440,7 +1556,7 @@ int gridGenWeights(int gridID, double *grid_area, double *grid_wgts)
   if ( gridtype == GRID_GME )
     {
       gridID = gridToUnstructured(gridID, 1);	  
-      grid_mask = (int *) malloc(gridsize*sizeof(int));
+      grid_mask = malloc(gridsize*sizeof(int));
       gridInqMaskGME(gridID, grid_mask);
     }
 
@@ -1570,7 +1686,7 @@ int gridWeights(int gridID, double *grid_wgts)
   gridtype = gridInqType(gridID);
   gridsize = gridInqSize(gridID);
   
-  grid_area = (double *) malloc(gridsize*sizeof(double));
+  grid_area = malloc(gridsize*sizeof(double));
 
   a_status = 0;
 
diff --git a/src/grid.h b/src/grid.h
index b8e79b0..9aa3fdb 100644
--- a/src/grid.h
+++ b/src/grid.h
@@ -18,6 +18,19 @@
 void grid_to_radian(const char *units, long nvals, double *restrict values, const char *description);
 void grid_to_degree(const char *units, long nvals, double *restrict values, const char *description);
 
+void grid_gen_corners(long n, const double* restrict vals, double* restrict corners);
+void grid_cell_center_to_bounds_X2D(const char* xunitstr, long xsize, long ysize,
+				    const double* restrict grid_center_lon, double* restrict grid_corner_lon, double dlon);
+void grid_cell_center_to_bounds_Y2D(const char* yunitstr, long xsize, long ysize,
+				    const double* restrict grid_center_lat, double* restrict grid_corner_lat);
+
+void gridGenXvals(int xsize, double xfirst, double xlast, double xinc, double *xvals);
+void gridGenYvals(int gridtype, int ysize, double yfirst, double ylast, double yinc, double *yvals);
+
+int  gridWeights(int gridID, double *weights);
+int  gridGenArea(int gridID, double *area);
+void gaussaw(double pa[], double pw[], int nlat);
+
 int referenceToGrid(int gridID);
 int gridToZonal(int gridID);
 int gridToMeridional(int gridID);
diff --git a/src/grid_area.c b/src/grid_area.c
index d42173c..5ebdc62 100644
--- a/src/grid_area.c
+++ b/src/grid_area.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -223,7 +223,7 @@ double huiliers_area(int num_corners, double *cell_corner_lon, double *cell_corn
 }
 
 
-int gridGenArea(int gridID, double *area)
+int gridGenArea(int gridID, double* area)
 {
   int status = 0;
   int gridtype;
@@ -231,9 +231,9 @@ int gridGenArea(int gridID, double *area)
   int lgriddestroy = FALSE;
   long i;
   long nv, gridsize;
-  double *grid_corner_lon = NULL;
-  double *grid_corner_lat = NULL;
-  int *grid_mask = NULL;
+  int* grid_mask = NULL;
+  double* grid_corner_lon = NULL;
+  double* grid_corner_lat = NULL;
 
   gridsize = gridInqSize(gridID);
   gridtype = gridInqType(gridID);
@@ -257,7 +257,7 @@ int gridGenArea(int gridID, double *area)
 	{
 	  lgriddestroy = TRUE;
 	  gridID = gridToUnstructured(gridID, 1);
-	  grid_mask = (int *) malloc(gridsize*sizeof(int));
+	  grid_mask = malloc(gridsize*sizeof(int));
 	  gridInqMaskGME(gridID, grid_mask);
 	}
       else
@@ -302,8 +302,8 @@ int gridGenArea(int gridID, double *area)
       return (status);
     }
 
-  grid_corner_lon = (double *) malloc(nv*gridsize*sizeof(double));
-  grid_corner_lat = (double *) malloc(nv*gridsize*sizeof(double));
+  grid_corner_lon = malloc(nv*gridsize*sizeof(double));
+  grid_corner_lat = malloc(nv*gridsize*sizeof(double));
 
   if ( gridInqYbounds(gridID, NULL) && gridInqXbounds(gridID, NULL) )
     {
@@ -314,25 +314,27 @@ int gridGenArea(int gridID, double *area)
     {
       if ( lgrid_gen_bounds )
 	{
+	  char xunitstr[CDI_MAX_NAME];
+	  char yunitstr[CDI_MAX_NAME];
 	  int nlon = gridInqXsize(gridID);
 	  int nlat = gridInqYsize(gridID);
 	  double dlon = 0;
-	  if ( nlon == 1 )
-	    {
-	      dlon = 1;
-	    }
+	  if ( nlon == 1 ) dlon = 1;
 
 	  double *grid_center_lon = NULL;
 	  double *grid_center_lat = NULL;
 
-	  grid_center_lon = (double *) malloc(gridsize*sizeof(double));
-	  grid_center_lat = (double *) malloc(gridsize*sizeof(double));
+	  grid_center_lon = malloc(gridsize*sizeof(double));
+	  grid_center_lat = malloc(gridsize*sizeof(double));
 
 	  gridInqXvals(gridID, grid_center_lon);
 	  gridInqYvals(gridID, grid_center_lat);
 
-	  genXbounds(nlon, nlat, grid_center_lon, grid_corner_lon, dlon);
-	  genYbounds(nlon, nlat, grid_center_lat, grid_corner_lat);
+	  gridInqXunits(gridID, xunitstr);
+	  gridInqYunits(gridID, yunitstr);
+
+	  grid_cell_center_to_bounds_X2D(xunitstr, nlon, nlat, grid_center_lon, grid_corner_lon, dlon);
+	  grid_cell_center_to_bounds_Y2D(yunitstr, nlon, nlat, grid_center_lat, grid_corner_lat);
 
 	  free(grid_center_lon);
 	  free(grid_center_lat);
diff --git a/src/grid_gme.c b/src/grid_gme.c
index fb7fe9a..7fbeba4 100644
--- a/src/grid_gme.c
+++ b/src/grid_gme.c
@@ -758,7 +758,7 @@ void glo_coor(double *pxn, double *prlon, double *prlat,
    * icosahedral triangles into mni equal parts.                 
    */  
 
-  if ((mcosv = (int *) malloc (knd*sizeof(int))) == NULL ) 
+  if ((mcosv = malloc (knd*sizeof(int))) == NULL ) 
     {
       perror("malloc mcosv");
       exit (-1);
@@ -1341,9 +1341,9 @@ void gme_grid(int lbounds, int gridsize, double *rlon, double *rlat,
       exit (-1);
     }
 
-  xn    = (double *) malloc(gridsize*3*sizeof(double));
-  rlonx = (double *) malloc((ni+3)*(ni+3)*nd*sizeof(double));
-  rlatx = (double *) malloc((ni+3)*(ni+3)*nd*sizeof(double));
+  xn    = malloc(gridsize*3*sizeof(double));
+  rlonx = malloc((ni+3)*(ni+3)*nd*sizeof(double));
+  rlatx = malloc((ni+3)*(ni+3)*nd*sizeof(double));
 
   im1s = 0;
   im1e = ni;
@@ -1361,7 +1361,7 @@ void gme_grid(int lbounds, int gridsize, double *rlon, double *rlat,
     {
       struct polygon *poly;
       
-      poly  = (struct polygon *) malloc((ni+1)*(ni+1)*nd*sizeof(struct polygon));
+      poly  = malloc((ni+1)*(ni+1)*nd*sizeof(struct polygon));
 
       neighbours(rlonx,rlatx,im1s-1,im1e+1,im2s-1,im2e+1,nd, poly,im1s,im1e,im2s,im2e,nd);
 
@@ -1415,42 +1415,42 @@ int main(int argc, char *argv[])
 
   factorni(ni, &ni2, &ni3);  
 
-  if (( poly  = (struct polygon *) malloc((ni+1)*(ni+1)*nd*sizeof(struct polygon))) == NULL) {
+  if (( poly  = malloc((ni+1)*(ni+1)*nd*sizeof(struct polygon))) == NULL) {
     perror("malloc poly");
     exit (-1);
   } 
   
-  if (( xn  = (double *) malloc((ni+1)*(ni+1)*3*nd*sizeof(double))) == NULL) {
+  if (( xn  = malloc((ni+1)*(ni+1)*3*nd*sizeof(double))) == NULL) {
     perror("malloc xn");
     exit (-1);
   } 
   
-  if ((rlon = (double *) malloc((ni+1)*(ni+1)*nd*sizeof(double))) == NULL) {
+  if ((rlon = malloc((ni+1)*(ni+1)*nd*sizeof(double))) == NULL) {
     perror("malloc rlon");
     exit (-1);
   } 
   
-  if ((rlat = (double *) malloc((ni+1)*(ni+1)*nd*sizeof(double))) == NULL) {
+  if ((rlat = malloc((ni+1)*(ni+1)*nd*sizeof(double))) == NULL) {
     perror("malloc rlat");
     exit (-1);
   } 
 
-  if ((rlonx = (double *) malloc((ni+3)*(ni+3)*nd*sizeof(double))) == NULL) {
+  if ((rlonx = malloc((ni+3)*(ni+3)*nd*sizeof(double))) == NULL) {
     perror("malloc rlonx");
     exit (-1);
   } 
   
-  if ((rlatx = (double *) malloc((ni+3)*(ni+3)*nd*sizeof(double))) == NULL) {
+  if ((rlatx = malloc((ni+3)*(ni+3)*nd*sizeof(double))) == NULL) {
     perror("malloc rlatx");
     exit (-1);
   } 
 
-  if ((mask = (int *) malloc((ni+1)*(ni+1)*nd*sizeof(int))) == NULL) {
+  if ((mask = malloc((ni+1)*(ni+1)*nd*sizeof(int))) == NULL) {
     perror("malloc mask");
     exit (-1);
   } 
 
-  if (( area  = (double *) malloc((ni+1)*(ni+1)*nd*sizeof(double))) == NULL) {
+  if (( area  = malloc((ni+1)*(ni+1)*nd*sizeof(double))) == NULL) {
     perror("malloc area");
     exit (-1);
   } 
diff --git a/src/griddes.c b/src/griddes.c
index 63b12d1..69d952d 100644
--- a/src/griddes.c
+++ b/src/griddes.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -204,13 +204,13 @@ int gridDefine(griddes_t grid)
 
 	if ( (grid.def_xfirst || grid.def_xlast || grid.def_xinc) && grid.xvals == NULL )
 	  {
-	    grid.xvals = (double *) malloc(grid.xsize*sizeof(double));
+	    grid.xvals = malloc(grid.xsize*sizeof(double));
 	    gridGenXvals(grid.xsize, grid.xfirst, grid.xlast, grid.xinc, grid.xvals);
 
 	    if ( grid.genBounds && grid.xbounds == NULL && grid.xsize > 1 )
 	      {
 		grid.nvertex = 2;
-		grid.xbounds = (double *) malloc(grid.xsize*grid.nvertex*sizeof(double));
+		grid.xbounds = malloc(grid.xsize*grid.nvertex*sizeof(double));
 		for ( i = 0; i < (int) grid.xsize-1; i++ )
 		  {
 		    grid.xbounds[2*i+1]   = 0.5*(grid.xvals[i] + grid.xvals[i+1]);
@@ -224,13 +224,13 @@ int gridDefine(griddes_t grid)
 	if ( (grid.def_yfirst || grid.def_ylast || grid.def_yinc) && grid.yvals == NULL )
 	  {
 	    if ( ! grid.def_ylast ) grid.ylast = grid.yfirst;
-	    grid.yvals = (double *) malloc(grid.ysize*sizeof(double));
+	    grid.yvals = malloc(grid.ysize*sizeof(double));
 	    gridGenYvals(grid.type, grid.ysize, grid.yfirst, grid.ylast, grid.yinc, grid.yvals);
 
 	    if ( grid.genBounds && grid.ybounds == NULL && grid.ysize > 1 )
 	      {
 		grid.nvertex = 2;
-		grid.ybounds = (double *) malloc(grid.ysize*grid.nvertex*sizeof(double));
+		grid.ybounds = malloc(grid.ysize*grid.nvertex*sizeof(double));
 		for ( i = 0; i < (int) grid.ysize-1; i++ )
 		  {
 		    grid.ybounds[2*i+1]   = 0.5*(grid.yvals[i] + grid.yvals[i+1]);
@@ -416,14 +416,14 @@ int gridDefine(griddes_t grid)
 
 	if ( grid.def_xfirst && grid.def_xinc && grid.xvals == NULL )
 	  {
-	    grid.xvals = (double *) malloc(grid.xsize*sizeof(double));
+	    grid.xvals = malloc(grid.xsize*sizeof(double));
 	    for ( i = 0; i < grid.xsize; ++i )
 	      grid.xvals[i] = grid.xfirst + i*grid.xinc;
 	  }
 
 	if ( grid.def_yfirst && grid.def_yinc && grid.yvals == NULL )
 	  {
-	    grid.yvals = (double *) malloc(grid.ysize*sizeof(double));
+	    grid.yvals = malloc(grid.ysize*sizeof(double));
 	    for ( i = 0; i < grid.ysize; ++i )
 	      grid.yvals[i] = grid.yfirst + i*grid.yinc;
 	  }
@@ -595,7 +595,7 @@ double *readfield(griddes_t *grid, int record, char *format, char *filename)
   if ( format == NULL )   Error("format undefined!");
   if ( filename == NULL ) Error("file name undefined!");
 
-  vals = (double *) malloc(grid->size*sizeof(double));
+  vals = malloc(grid->size*sizeof(double));
 
   if ( strcmp(format, "extra") == 0 )
     {
@@ -630,7 +630,7 @@ double *readfield4(griddes_t *grid, int record, char *format, char *filename)
   if ( format == NULL )   Error("format undefined!");
   if ( filename == NULL ) Error("file name undefined!");
 
-  vals  = (double *) malloc(4*grid->size*sizeof(double));
+  vals  = malloc(4*grid->size*sizeof(double));
 
   if ( strcmp(format, "extra") == 0 )
     {
@@ -980,8 +980,8 @@ int gridFromFile(FILE *gfp, const char *dname)
 	  double flat = 0, flon = 0;
 	  if ( grid.size == 0 ) grid.size = grid.xsize * grid.ysize;
 	  
-	  grid.xvals = (double *) malloc(grid.size*sizeof(double));
-	  grid.yvals = (double *) malloc(grid.size*sizeof(double));
+	  grid.xvals = malloc(grid.size*sizeof(double));
+	  grid.yvals = malloc(grid.size*sizeof(double));
 	  for ( i = 0; i < (int) grid.size; i++ )
 	    {
 	      if ( ! readline(gfp, line, MAX_LINE_LEN) )
@@ -1004,7 +1004,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 	    {
 	      long count = 0;
 	      pline = skipSeparator(pline + len);
-	      grid.mask = (int *) malloc(size*sizeof(int));
+	      grid.mask = malloc(size*sizeof(int));
 
 	      for ( i = 0; i < size; i++ )
 		{
@@ -1046,7 +1046,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 	  if ( size > 0 )
 	    {
 	      pline = skipSeparator(pline + len);
-	      grid.xvals = (double *) malloc(size*sizeof(double));
+	      grid.xvals = malloc(size*sizeof(double));
 
 	      for ( i = 0; i < size; i++ )
 		{
@@ -1081,7 +1081,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 	  if ( size > 0 )
 	    {
 	      pline = skipSeparator(pline + len);
-	      grid.yvals = (double *) malloc(size*sizeof(double));
+	      grid.yvals = malloc(size*sizeof(double));
 
 	      for ( i = 0; i < size; i++ )
 		{
@@ -1121,7 +1121,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 	  if ( size > 0 && grid.nvertex > 0 )
 	    {	  
 	      pline = skipSeparator(pline + len);
-	      grid.xbounds = (double *) malloc(size*grid.nvertex*sizeof(double));
+	      grid.xbounds = malloc(size*grid.nvertex*sizeof(double));
 
 	      for ( i = 0; i < (int) (size*grid.nvertex); i++ )
 		{
@@ -1164,7 +1164,7 @@ int gridFromFile(FILE *gfp, const char *dname)
 	  if ( size > 0 && grid.nvertex > 0 )
 	    {	  
 	      pline = skipSeparator(pline + len);
-	      grid.ybounds = (double *) malloc(size*grid.nvertex*sizeof(double));
+	      grid.ybounds = malloc(size*grid.nvertex*sizeof(double));
 
 	      for ( i = 0; i < (int) (size*grid.nvertex); i++ )
 		{
@@ -1284,8 +1284,8 @@ int gridFromPingo(FILE *gfp, const char *dname)
       grid.xsize = nlon;
       grid.ysize = nlat;
 
-      grid.xvals = (double *) malloc(grid.xsize*sizeof(double));
-      grid.yvals = (double *) malloc(grid.ysize*sizeof(double));
+      grid.xvals = malloc(grid.xsize*sizeof(double));
+      grid.yvals = malloc(grid.ysize*sizeof(double));
 
       if ( ! input_ival(gfp, &nlon) ) return (gridID);
       if ( nlon == 2 )
@@ -1353,8 +1353,8 @@ int gridFromPingo(FILE *gfp, const char *dname)
       if ( nlat > 2 ) /* check if gaussian */
 	{
 	  double *yvals, *yw;
-	  yvals = (double *) malloc(grid.ysize*sizeof(double));
-	  yw    = (double *) malloc(grid.ysize*sizeof(double));
+	  yvals = malloc(grid.ysize*sizeof(double));
+	  yw    = malloc(grid.ysize*sizeof(double));
 	  gaussaw(yvals, yw, grid.ysize);
 	  free(yw);
 	  for ( i = 0; i < (int) grid.ysize; i++ )
@@ -1511,8 +1511,8 @@ void gen_grid_lonlat(griddes_t *grid, const char *pline, double inc, double lon1
   grid->xsize = nlon;
   grid->ysize = nlat;
 
-  grid->xvals = (double *) malloc(grid->xsize*sizeof(double));
-  grid->yvals = (double *) malloc(grid->ysize*sizeof(double));
+  grid->xvals = malloc(grid->xsize*sizeof(double));
+  grid->yvals = malloc(grid->ysize*sizeof(double));
 
   for ( i = 0; i < nlon; ++i ) grid->xvals[i] = lon1 + inc/2 + i*inc;
   for ( i = 0; i < nlat; ++i ) grid->yvals[i] = lat1 + inc/2 + i*inc;
@@ -1611,8 +1611,8 @@ int gridFromName(const char *gridname)
 	  grid.type = GRID_LONLAT;
 	  grid.xsize = 1;
 	  grid.ysize = 1;
-	  grid.xvals = (double *) malloc(sizeof(double));
-	  grid.yvals = (double *) malloc(sizeof(double));
+	  grid.xvals = malloc(sizeof(double));
+	  grid.yvals = malloc(sizeof(double));
 	  grid.xvals[0] = atof(pline);
 	  while ( isdigit((int) *pline) || ispunct((int) *pline) || *pline == '-' ) pline++;
 	  if ( *pline == '_' ) pline++;
@@ -1798,8 +1798,8 @@ int cdoDefineGrid(const char *gridfile)
 	{
 	  if ( cmpstr(buffer+1, "HDF", len) == 0 )
 	    {
-	      if ( cdoDebug ) cdoPrint("Grid from netCDF4 file");
-	      gridID = gridFromNCfile(gridfile);
+	      if ( cdoDebug ) cdoPrint("Grid from HDF5 file");
+	      gridID = gridFromH5file(gridfile);
 	    }
 	}
 
@@ -1807,8 +1807,8 @@ int cdoDefineGrid(const char *gridfile)
 	{
 	  if ( cmpstr(buffer+1, "HDF", len) == 0 )
 	    {
-	      if ( cdoDebug ) cdoPrint("Grid from HDF5 file");
-	      gridID = gridFromH5file(gridfile);
+	      if ( cdoDebug ) cdoPrint("Grid from netCDF4 file");
+	      gridID = gridFromNCfile(gridfile);
 	    }
 	}
 
diff --git a/src/griddes_h5.c b/src/griddes_h5.c
index daab7ae..e314665 100644
--- a/src/griddes_h5.c
+++ b/src/griddes_h5.c
@@ -290,22 +290,30 @@ void correct_sinxvals(int xsize, int ysize, double *xvals)
 
 int gridFromH5file(const char *gridfile)
 {
-  int gridID = -1;
+  int       gridID = -1;
 #if defined(HAVE_LIBHDF5)
-  hid_t	  file_id;	/* HDF5 File ID	        	*/
-  hid_t	  lon_id = -1;	/* Dataset ID	        	*/
-  hid_t	  lat_id = -1;	/* Dataset ID	        	*/
-  hid_t   dataspace;   
-  hsize_t dims_out[9];  /* dataset dimensions           */
-  herr_t  status;	/* Generic return value		*/
-  int     rank;
-  griddes_t    grid;
+  hid_t     fapl_id = H5P_DEFAULT;
+  hid_t	    file_id;	    /* HDF5 File ID	        	*/
+  hid_t	    lon_id = -1;    /* Dataset ID	        	*/
+  hid_t	    lat_id = -1;    /* Dataset ID	        	*/
+  hid_t     att_id;
+  hid_t     dataspace;   
+  hsize_t   dims_out[9];    /* dataset dimensions               */
+  herr_t    status;	    /* Generic return value		*/
+  int       rank;
+  griddes_t grid;
 
 
   gridInit(&grid);
 
+  fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+  H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG);
+
   /* Open an existing file. */
-  file_id = H5Fopen(gridfile, H5F_ACC_RDONLY, H5P_DEFAULT);
+  file_id = H5Fopen(gridfile, H5F_ACC_RDONLY, fapl_id);
+
+  H5Pclose(fapl_id);
+
   if ( file_id < 0 ) return(gridID);
 
   if ( h5find_object(file_id, "lon") > 0 && 
@@ -333,9 +341,24 @@ int gridFromH5file(const char *gridfile)
 
       if ( rank != 2 )
 	{
-	  cdoWarning("Unexpected rank = %d!", rank);
+	  //if ( cdoVerbose ) cdoWarning("Unexpected rank = %d!", rank);
+	  goto RETURN;
+	}
+
+      att_id = H5Aopen_name(lon_id, "bounds");
+      if ( att_id >= 0 )
+	{
+	  H5Aclose(att_id);
+	  goto RETURN;
+	}
+
+      att_id = H5Aopen_name(lat_id, "bounds");
+      if ( att_id >= 0 )
+	{
+	  H5Aclose(att_id);
 	  goto RETURN;
 	}
+
       /*
       printf("\nRank: %d\nDimensions: %lu x %lu \n", rank,
 	     (unsigned long)(dims_out[1]), (unsigned long)(dims_out[0]));
@@ -363,8 +386,8 @@ int gridFromH5file(const char *gridfile)
       grid.ysize = (int)dims_out[0];
       grid.size  = grid.xsize*grid.ysize;
 
-      grid.xvals = (double *) malloc(grid.size*sizeof(double));
-      grid.yvals = (double *) malloc(grid.size*sizeof(double));
+      grid.xvals = malloc(grid.size*sizeof(double));
+      grid.yvals = malloc(grid.size*sizeof(double));
 
       if ( ftype )
 	{
@@ -374,7 +397,7 @@ int gridFromH5file(const char *gridfile)
       else
 	{
 	  int *iarray, i;
-	  iarray = (int *) malloc(grid.size*sizeof(int));
+	  iarray = malloc(grid.size*sizeof(int));
 	  status = H5Dread(lon_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, iarray);
 	  for ( i = 0; i < grid.size; ++i ) grid.xvals[i] = iarray[i];
 	  status = H5Dread(lat_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, iarray);
@@ -400,7 +423,6 @@ int gridFromH5file(const char *gridfile)
       double xscale = 1, yscale = 1;
       double xoffset = 0, yoffset = 0;
       hid_t grp_id;
-      hid_t att_id;
       int i;
 
       grp_id = H5Gopen(file_id, "/where/lon/what");
@@ -460,7 +482,7 @@ int gridFromH5file(const char *gridfile)
 
 	  if ( rank != 2 )
 	    {
-	      cdoWarning("Unexpected rank = %d!", rank);
+	      //if ( cdoVerbose ) cdoWarning("Unexpected rank = %d!", rank);
 	      goto RETURN;
 	    }
 	  /*
@@ -490,8 +512,8 @@ int gridFromH5file(const char *gridfile)
 	  grid.ysize = (int)dims_out[0];
 	  grid.size  = grid.xsize*grid.ysize;
 
-	  grid.xvals = (double *) malloc(grid.size*sizeof(double));
-	  grid.yvals = (double *) malloc(grid.size*sizeof(double));
+	  grid.xvals = malloc(grid.size*sizeof(double));
+	  grid.yvals = malloc(grid.size*sizeof(double));
 
 	  if ( ftype )
 	    {
@@ -501,7 +523,7 @@ int gridFromH5file(const char *gridfile)
 	  else
 	    {
 	      int *iarray, i;
-	      iarray = (int *) malloc(grid.size*sizeof(int));
+	      iarray = malloc(grid.size*sizeof(int));
 	      status = H5Dread(lon_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, iarray);
 	      for ( i = 0; i < grid.size; ++i ) grid.xvals[i] = iarray[i];
 	      status = H5Dread(lat_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, iarray);
@@ -525,11 +547,11 @@ int gridFromH5file(const char *gridfile)
 	}
     }
 
-  /* Close file */
-  status = H5Fclose(file_id);
-
  RETURN:
 
+  /* Close file */
+  if ( file_id >= 0 )  status = H5Fclose(file_id);
+
 #else
   cdoWarning("HDF5 support not compiled in!");
 #endif
diff --git a/src/griddes_nc.c b/src/griddes_nc.c
index 141ea01..7bd5f7a 100644
--- a/src/griddes_nc.c
+++ b/src/griddes_nc.c
@@ -108,10 +108,10 @@ int gridFromNCfile(const char *gridfile)
 
       /* allocate grid coordinates and read data */
 
-      grid.xvals   = (double *) malloc(grid.size*sizeof(double));
-      grid.yvals   = (double *) malloc(grid.size*sizeof(double));
-      grid.xbounds = (double *) malloc(grid.nvertex*grid.size*sizeof(double));
-      grid.ybounds = (double *) malloc(grid.nvertex*grid.size*sizeof(double));
+      grid.xvals   = malloc(grid.size*sizeof(double));
+      grid.yvals   = malloc(grid.size*sizeof(double));
+      grid.xbounds = malloc(grid.nvertex*grid.size*sizeof(double));
+      grid.ybounds = malloc(grid.nvertex*grid.size*sizeof(double));
 
       nce(nc_inq_vartype(nc_file_id, nc_gridlat_id, &xtype));
       if ( xtype == NC_FLOAT )  grid.prec = DATATYPE_FLT32;
@@ -132,7 +132,7 @@ int gridFromNCfile(const char *gridfile)
       if ( nc_inq_varid(nc_file_id, "grid_imask", &nc_gridmask_id) == NC_NOERR )
 	{
 	  int i;
-	  grid.mask = (int *) malloc(grid.size*sizeof(int));
+	  grid.mask = malloc(grid.size*sizeof(int));
 	  nce(nc_get_var_int(nc_file_id, nc_gridmask_id, grid.mask));
 	  for ( i = 0; i < grid.size; ++i )
 	    if ( grid.mask[i] != 1 ) break;
@@ -308,7 +308,7 @@ void writeNCgrid(const char *gridfile, int gridID, int *grid_imask)
 
   nce(nc_put_var_int(nc_file_id, nc_grdimask_id, grid_imask));
 
-  vals = (double *) malloc(gridInqNvertex(gridID)*gridsize*sizeof(double));
+  vals = malloc(gridInqNvertex(gridID)*gridsize*sizeof(double));
 
   gridInqYvals(gridID, vals);
   nce(nc_put_var_double(nc_file_id, nc_gridlat_id, vals));
diff --git a/src/gridreference.c b/src/gridreference.c
index 6bac951..6a3409b 100644
--- a/src/gridreference.c
+++ b/src/gridreference.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -20,8 +20,6 @@
 
 #if defined(HAVE_LIBCURL)
 #include <curl/curl.h>
-#include <curl/types.h>
-#include <curl/easy.h>
 #include <errno.h>
 #endif
 
@@ -33,7 +31,8 @@
  * callback function for curl for writing the network retrieved grid file
  */
 static
-size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
+size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
+{
   size_t written;
   written = fwrite(ptr, size, nmemb, stream);
   return written;
diff --git a/src/hetaeta.c b/src/hetaeta.c
index 6442318..1566347 100644
--- a/src/hetaeta.c
+++ b/src/hetaeta.c
@@ -513,67 +513,67 @@ void hetaeta(int ltq, int ngp, const int *imiss,
   nlev2p1 = nlev2+1;
 
 #if defined(_OPENMP)
-  ph1_2    = (double **) malloc(ompNumThreads*sizeof(double *));
-  lnph1_2  = (double **) malloc(ompNumThreads*sizeof(double *));
-  fi1_2    = (double **) malloc(ompNumThreads*sizeof(double *));
-
-  pf1_2    = (double **) malloc(ompNumThreads*sizeof(double *));
-  lnpf1_2  = (double **) malloc(ompNumThreads*sizeof(double *));
-  tv1_2    = (double **) malloc(ompNumThreads*sizeof(double *));
-  theta1_2 = (double **) malloc(ompNumThreads*sizeof(double *));
-  rh1_2    = (double **) malloc(ompNumThreads*sizeof(double *));
-  zvar_2   = (double **) malloc(ompNumThreads*sizeof(double *));
-
-  ph2_2    = (double **) malloc(ompNumThreads*sizeof(double *));
-  lnph2_2  = (double **) malloc(ompNumThreads*sizeof(double *));
-  fi2_2    = (double **) malloc(ompNumThreads*sizeof(double *));
-
-  pf2_2    = (double **) malloc(ompNumThreads*sizeof(double *));
-  rh2_2    = (double **) malloc(ompNumThreads*sizeof(double *));
-  wgt_2    = (double **) malloc(ompNumThreads*sizeof(double *));
-  idx_2    = (long **)   malloc(ompNumThreads*sizeof(long *));
+  ph1_2    = malloc(ompNumThreads*sizeof(double *));
+  lnph1_2  = malloc(ompNumThreads*sizeof(double *));
+  fi1_2    = malloc(ompNumThreads*sizeof(double *));
+
+  pf1_2    = malloc(ompNumThreads*sizeof(double *));
+  lnpf1_2  = malloc(ompNumThreads*sizeof(double *));
+  tv1_2    = malloc(ompNumThreads*sizeof(double *));
+  theta1_2 = malloc(ompNumThreads*sizeof(double *));
+  rh1_2    = malloc(ompNumThreads*sizeof(double *));
+  zvar_2   = malloc(ompNumThreads*sizeof(double *));
+
+  ph2_2    = malloc(ompNumThreads*sizeof(double *));
+  lnph2_2  = malloc(ompNumThreads*sizeof(double *));
+  fi2_2    = malloc(ompNumThreads*sizeof(double *));
+
+  pf2_2    = malloc(ompNumThreads*sizeof(double *));
+  rh2_2    = malloc(ompNumThreads*sizeof(double *));
+  wgt_2    = malloc(ompNumThreads*sizeof(double *));
+  idx_2    = malloc(ompNumThreads*sizeof(long *));
 
   if ( ltq )
     {
-      zt2_2       = (double **) malloc(ompNumThreads*sizeof(double *));
-      zq2_2       = (double **) malloc(ompNumThreads*sizeof(double *));
-      rh_pbl_2    = (double **) malloc(ompNumThreads*sizeof(double *));
-      theta_pbl_2 = (double **) malloc(ompNumThreads*sizeof(double *));
+      zt2_2       = malloc(ompNumThreads*sizeof(double *));
+      zq2_2       = malloc(ompNumThreads*sizeof(double *));
+      rh_pbl_2    = malloc(ompNumThreads*sizeof(double *));
+      theta_pbl_2 = malloc(ompNumThreads*sizeof(double *));
     }
 
   if ( nvars > 0 )
     {
-      vars_pbl_2  = (double ***) malloc(ompNumThreads*sizeof(double **));
+      vars_pbl_2  = malloc(ompNumThreads*sizeof(double **));
     }
 
   for ( i = 0; i < ompNumThreads; i++ )
     {
-      ph1_2[i]    = (double *) malloc(nlev1p1*sizeof(double));
-      lnph1_2[i]  = (double *) malloc(nlev1p1*sizeof(double));
-      fi1_2[i]    = (double *) malloc(nlev1p1*sizeof(double));
-
-      pf1_2[i]    = (double *) malloc(nlev1*sizeof(double));
-      lnpf1_2[i]  = (double *) malloc(nlev1*sizeof(double));
-      tv1_2[i]    = (double *) malloc(nlev1*sizeof(double));
-      theta1_2[i] = (double *) malloc(nlev1*sizeof(double));
-      rh1_2[i]    = (double *) malloc(nlev1*sizeof(double));
-      zvar_2[i]   = (double *) malloc(nlev1*sizeof(double));
-
-      ph2_2[i]    = (double *) malloc(nlev2p1*sizeof(double));
-      lnph2_2[i]  = (double *) malloc(nlev2p1*sizeof(double));
-      fi2_2[i]    = (double *) malloc(nlev2p1*sizeof(double));
-
-      pf2_2[i]    = (double *) malloc(nlev2*sizeof(double));
-      rh2_2[i]    = (double *) malloc(nlev2*sizeof(double));
-      wgt_2[i]    = (double *) malloc(nlev2*sizeof(double));
-      idx_2[i]    = (long *)   malloc(nlev2*sizeof(long));
+      ph1_2[i]    = malloc(nlev1p1*sizeof(double));
+      lnph1_2[i]  = malloc(nlev1p1*sizeof(double));
+      fi1_2[i]    = malloc(nlev1p1*sizeof(double));
+
+      pf1_2[i]    = malloc(nlev1*sizeof(double));
+      lnpf1_2[i]  = malloc(nlev1*sizeof(double));
+      tv1_2[i]    = malloc(nlev1*sizeof(double));
+      theta1_2[i] = malloc(nlev1*sizeof(double));
+      rh1_2[i]    = malloc(nlev1*sizeof(double));
+      zvar_2[i]   = malloc(nlev1*sizeof(double));
+
+      ph2_2[i]    = malloc(nlev2p1*sizeof(double));
+      lnph2_2[i]  = malloc(nlev2p1*sizeof(double));
+      fi2_2[i]    = malloc(nlev2p1*sizeof(double));
+
+      pf2_2[i]    = malloc(nlev2*sizeof(double));
+      rh2_2[i]    = malloc(nlev2*sizeof(double));
+      wgt_2[i]    = malloc(nlev2*sizeof(double));
+      idx_2[i]    = malloc(nlev2*sizeof(long));
 
       if ( ltq )
 	{
-	  zt2_2[i]       = (double *) malloc(nlev2*sizeof(double));
-	  zq2_2[i]       = (double *) malloc(nlev2*sizeof(double));
-	  rh_pbl_2[i]    = (double *) malloc(nlev2*sizeof(double));
-	  theta_pbl_2[i] = (double *) malloc(nlev2*sizeof(double));
+	  zt2_2[i]       = malloc(nlev2*sizeof(double));
+	  zq2_2[i]       = malloc(nlev2*sizeof(double));
+	  rh_pbl_2[i]    = malloc(nlev2*sizeof(double));
+	  theta_pbl_2[i] = malloc(nlev2*sizeof(double));
 	}
 
       if ( nvars > 0 )
@@ -583,64 +583,64 @@ void hetaeta(int ltq, int ngp, const int *imiss,
 	      fprintf(stderr, "Too many vars (max = %d)!\n", MAX_VARS);
 	      exit(-1);
 	    }
-	  vars_pbl_2[i]  = (double **) malloc(nvars*sizeof(double *));
+	  vars_pbl_2[i]  = malloc(nvars*sizeof(double *));
 	  for ( iv = 0; iv < nvars; ++iv )
-	    vars_pbl_2[i][iv] = (double *) malloc(nlev2*sizeof(double));
+	    vars_pbl_2[i][iv] = malloc(nlev2*sizeof(double));
 	}
     }
 #else
-  /* etah1  = (double *) malloc(nlev1p1*sizeof(double)); */
-  ph1    = (double *) malloc(nlev1p1*sizeof(double));
-  lnph1  = (double *) malloc(nlev1p1*sizeof(double));
-  fi1    = (double *) malloc(nlev1p1*sizeof(double));
-
-  pf1    = (double *) malloc(nlev1*sizeof(double));
-  lnpf1  = (double *) malloc(nlev1*sizeof(double));
-  tv1    = (double *) malloc(nlev1*sizeof(double));
-  theta1 = (double *) malloc(nlev1*sizeof(double));
-  rh1    = (double *) malloc(nlev1*sizeof(double));
-  zvar   = (double *) malloc(nlev1*sizeof(double));
-
-  ph2    = (double *) malloc(nlev2p1*sizeof(double));
-  lnph2  = (double *) malloc(nlev2p1*sizeof(double));
-  fi2    = (double *) malloc(nlev2p1*sizeof(double));
-
-  pf2    = (double *) malloc(nlev2*sizeof(double));
-  /* lnpf2  = (double *) malloc(nlev2*sizeof(double)); */
-  rh2    = (double *) malloc(nlev2*sizeof(double));
-  wgt    = (double *) malloc(nlev2*sizeof(double));
-  idx    = (long *)   malloc(nlev2*sizeof(long));
+  /* etah1  = malloc(nlev1p1*sizeof(double)); */
+  ph1    = malloc(nlev1p1*sizeof(double));
+  lnph1  = malloc(nlev1p1*sizeof(double));
+  fi1    = malloc(nlev1p1*sizeof(double));
+
+  pf1    = malloc(nlev1*sizeof(double));
+  lnpf1  = malloc(nlev1*sizeof(double));
+  tv1    = malloc(nlev1*sizeof(double));
+  theta1 = malloc(nlev1*sizeof(double));
+  rh1    = malloc(nlev1*sizeof(double));
+  zvar   = malloc(nlev1*sizeof(double));
+
+  ph2    = malloc(nlev2p1*sizeof(double));
+  lnph2  = malloc(nlev2p1*sizeof(double));
+  fi2    = malloc(nlev2p1*sizeof(double));
+
+  pf2    = malloc(nlev2*sizeof(double));
+  /* lnpf2  = malloc(nlev2*sizeof(double)); */
+  rh2    = malloc(nlev2*sizeof(double));
+  wgt    = malloc(nlev2*sizeof(double));
+  idx    = malloc(nlev2*sizeof(long));
 
   if ( ltq )
     {
-      zt2       = (double *) malloc(nlev2*sizeof(double));
-      zq2       = (double *) malloc(nlev2*sizeof(double));
-      rh_pbl    = (double *) malloc(nlev2*sizeof(double));
-      theta_pbl = (double *) malloc(nlev2*sizeof(double));
+      zt2       = malloc(nlev2*sizeof(double));
+      zq2       = malloc(nlev2*sizeof(double));
+      rh_pbl    = malloc(nlev2*sizeof(double));
+      theta_pbl = malloc(nlev2*sizeof(double));
     }
 
   if ( nvars > 0 )
     {
-      vars_pbl  = (double **) malloc(nvars*sizeof(double *));
+      vars_pbl  = malloc(nvars*sizeof(double *));
       for ( iv = 0; iv < nvars; ++iv )
-	vars_pbl[iv] = (double *) malloc(nlev2*sizeof(double));
+	vars_pbl[iv] = malloc(nlev2*sizeof(double));
     }
 #endif
   
-  af1    = (double *) malloc(nlev1*sizeof(double));
-  bf1    = (double *) malloc(nlev1*sizeof(double));
-  etaf1  = (double *) malloc(nlev1*sizeof(double));
+  af1    = malloc(nlev1*sizeof(double));
+  bf1    = malloc(nlev1*sizeof(double));
+  etaf1  = malloc(nlev1*sizeof(double));
 
-  etah2  = (double *) malloc(nlev2p1*sizeof(double));
+  etah2  = malloc(nlev2p1*sizeof(double));
 
-  af2    = (double *) malloc(nlev2*sizeof(double));
-  bf2    = (double *) malloc(nlev2*sizeof(double));
-  etaf2  = (double *) malloc(nlev2*sizeof(double));
+  af2    = malloc(nlev2*sizeof(double));
+  bf2    = malloc(nlev2*sizeof(double));
+  etaf2  = malloc(nlev2*sizeof(double));
 
-  w1     = (double *) malloc(nlev2*sizeof(double));
-  w2     = (double *) malloc(nlev2*sizeof(double));
-  jl1    = (long *)   malloc(nlev2*sizeof(long));
-  jl2    = (long *)   malloc(nlev2*sizeof(long));
+  w1     = malloc(nlev2*sizeof(double));
+  w2     = malloc(nlev2*sizeof(double));
+  jl1    = malloc(nlev2*sizeof(long));
+  jl2    = malloc(nlev2*sizeof(long));
 
 
   /******* set coordinate system ETA's, A's, B's
@@ -1027,30 +1027,30 @@ int main (int argc, char *argv[])
   int ij, k;
   int ltq = 1;
 
-  fis1 = (double *) malloc(NGP*sizeof(double));
-  ps1  = (double *) malloc(NGP*sizeof(double));
-  fis2 = (double *) malloc(NGP*sizeof(double));
-  ps2  = (double *) malloc(NGP*sizeof(double));
-
-  tscor  = (double *) malloc(NGP*sizeof(double));
-  pscor  = (double *) malloc(NGP*sizeof(double));
-  secor  = (double *) malloc(NGP*sizeof(double));
-
-  t1  = (double *) malloc(NGP*19*sizeof(double));
-  q1  = (double *) malloc(NGP*19*sizeof(double));
-  u1  = (double *) malloc(NGP*19*sizeof(double));
-  v1  = (double *) malloc(NGP*19*sizeof(double));
-  cl1 = (double *) malloc(NGP*19*sizeof(double));
-  ci1 = (double *) malloc(NGP*19*sizeof(double));
-  cc1 = (double *) malloc(NGP*19*sizeof(double));
-
-  t2  = (double *) malloc(NGP*40*sizeof(double));
-  q2  = (double *) malloc(NGP*40*sizeof(double));
-  u2  = (double *) malloc(NGP*40*sizeof(double));
-  v2  = (double *) malloc(NGP*40*sizeof(double));
-  cl2 = (double *) malloc(NGP*40*sizeof(double));
-  ci2 = (double *) malloc(NGP*40*sizeof(double));
-  cc2 = (double *) malloc(NGP*40*sizeof(double));
+  fis1 = malloc(NGP*sizeof(double));
+  ps1  = malloc(NGP*sizeof(double));
+  fis2 = malloc(NGP*sizeof(double));
+  ps2  = malloc(NGP*sizeof(double));
+
+  tscor  = malloc(NGP*sizeof(double));
+  pscor  = malloc(NGP*sizeof(double));
+  secor  = malloc(NGP*sizeof(double));
+
+  t1  = malloc(NGP*19*sizeof(double));
+  q1  = malloc(NGP*19*sizeof(double));
+  u1  = malloc(NGP*19*sizeof(double));
+  v1  = malloc(NGP*19*sizeof(double));
+  cl1 = malloc(NGP*19*sizeof(double));
+  ci1 = malloc(NGP*19*sizeof(double));
+  cc1 = malloc(NGP*19*sizeof(double));
+
+  t2  = malloc(NGP*40*sizeof(double));
+  q2  = malloc(NGP*40*sizeof(double));
+  u2  = malloc(NGP*40*sizeof(double));
+  v2  = malloc(NGP*40*sizeof(double));
+  cl2 = malloc(NGP*40*sizeof(double));
+  ci2 = malloc(NGP*40*sizeof(double));
+  cc2 = malloc(NGP*40*sizeof(double));
 
   for ( ij = 0; ij < NGP; ++ij )
     {
diff --git a/src/history.c b/src/history.c
index fe40dff..f582a39 100644
--- a/src/history.c
+++ b/src/history.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -64,7 +64,7 @@ void cdoInqHistory(int fileID)
   if ( ghistorysize > 0 )
     {
       size_t len;
-      ghistory = (char *) malloc(ghistorysize+1);
+      ghistory = malloc(ghistorysize+1);
       ghistory[ghistorysize] = 0;
       streamInqHistoryString(fileID, ghistory);
       len = strlen(ghistory);
@@ -87,7 +87,7 @@ void cdoDefHistory(int fileID, char *histstring)
   strtimeptr = get_strtimeptr();
   
   historysize = ghistorysize+strlen(strtimeptr)+strlen(histstring)+2;
-  history = (char *) malloc(historysize);
+  history = malloc(historysize);
 
   strcpy(history, strtimeptr);
   strcat(history, histstring);
diff --git a/src/institution.c b/src/institution.c
index d011d23..54f0f2b 100644
--- a/src/institution.c
+++ b/src/institution.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/interpol.c b/src/interpol.c
index 51b72c2..b26007c 100644
--- a/src/interpol.c
+++ b/src/interpol.c
@@ -23,7 +23,6 @@
 * @param nelem  length of the sorted list
 * @param x      the element to find a position for 
 */
-static
 long find_element(double x, long nelem, const double *restrict array)
 {
   long ii;
@@ -84,11 +83,13 @@ long find_element(double x, long nelem, const double *restrict array)
 	}
     }
 
+  if ( mid > 1 && IS_EQUAL(x,array[mid-1]) ) mid--;
+
   return (mid);
 }
+
 /*
-static
-long find_element_old(double x, long nelem, const double *array)
+long find_element(double x, long nelem, const double *array)
 {
   long ii;
 
@@ -107,7 +108,6 @@ long find_element_old(double x, long nelem, const double *array)
 }
 */
 
-static
 int rect_grid_search(long *ii, long *jj, double x, double y, long nxm, long nym, const double *restrict xm, const double *restrict ym)
 {
   int lfound = 0;
@@ -124,7 +124,7 @@ int rect_grid_search(long *ii, long *jj, double x, double y, long nxm, long nym,
   return (lfound);
 }
 
-static
+
 int rect_grid_search2(long *imin, long *imax, double xmin, double xmax, long nxm, const double *restrict xm)
 {
   int lfound = 0;
@@ -236,7 +236,7 @@ void intlinarr2(double missval, int lon_is_circular,
   if ( lon_is_circular ) nlon1--;
   gridsize1 = nlon1*nym;
 
-  grid1_mask = (int *) calloc(1, gridsize1*sizeof(int));
+  grid1_mask = calloc(1, gridsize1*sizeof(int));
   for ( jj = 0; jj < nym; ++jj )
     for ( ii = 0; ii < nlon1; ++ii )
       {
@@ -337,32 +337,27 @@ void boundbox_from_corners(long ic, long nc, const double *restrict corner_lon,
   long inc, j;
   double clon, clat;
 
+  inc = ic*nc;
+  clat = corner_lat[inc];
+  clon = corner_lon[inc];
+
+  bound_box[0] = clat;
+  bound_box[1] = clat;
+  bound_box[2] = clon;
+  bound_box[3] = clon;
+
+  for ( j = 1; j < nc; ++j )
     {
-      inc = ic*nc;
-      clat = corner_lat[inc];
-      clon = corner_lon[inc];
-      bound_box[0] = clat;
-      bound_box[1] = clat;
-      bound_box[2] = clon;
-      bound_box[3] = clon;
-      for ( j = 1; j < nc; ++j )
-	{
-	  clat = corner_lat[inc+j];
-	  clon = corner_lon[inc+j];
-	  if ( clat < bound_box[0] ) bound_box[0] = clat;
-	  if ( clat > bound_box[1] ) bound_box[1] = clat;
-	  if ( clon < bound_box[2] ) bound_box[2] = clon;
-	  if ( clon > bound_box[3] ) bound_box[3] = clon;
-	}
+      clat = corner_lat[inc+j];
+      clon = corner_lon[inc+j];
+      if ( clat < bound_box[0] ) bound_box[0] = clat;
+      if ( clat > bound_box[1] ) bound_box[1] = clat;
+      if ( clon < bound_box[2] ) bound_box[2] = clon;
+      if ( clon > bound_box[3] ) bound_box[3] = clon;
     }
 }
 
 #if defined(HAVE_LIBYAC)
-#include "points.h"
-#include "grid_reg2d.h"
-#include "grid_search.h"
-#include "bucket_search.h"
-#include "search.h"
 #include "clipping.h"
 #include "area.h"
 #endif
@@ -377,32 +372,35 @@ void intconarr2(double missval, int lon_is_circular,
   long i, ii = -1, jj = -1;
   long gridsize1;
   long nlon1 = nxm;
+  long nx, ny;
   double findex = 0;
   int *grid1_mask = NULL;
 
-  printf(" nxm, nym %ld %ld\n", nxm, nym);
+  nx = nxm - 1;
+  ny = nym - 1;
+  printf(" nx, ny %ld %ld\n", nx, ny);
   //if ( lon_is_circular ) nlon1--;
-  gridsize1 = (nxm-1)*(nym-1);
+  gridsize1 = nx*ny;
 
-  deps = (int *) malloc(gridsize1*sizeof(int));
+  deps = malloc(gridsize1*sizeof(int));
 
-  grid1_mask = (int *) calloc(1, gridsize1*sizeof(int));
-  for ( jj = 0; jj < nym-1; ++jj )
-    for ( ii = 0; ii < nxm-1; ++ii )
+  grid1_mask = calloc(1, gridsize1*sizeof(int));
+  for ( jj = 0; jj < ny; ++jj )
+    for ( ii = 0; ii < nx; ++ii )
       {
-	if ( !DBL_IS_EQUAL(fieldm[jj*(nxm-1)+ii], missval) ) grid1_mask[jj*(nxm-1)+ii] = 1;
+	if ( !DBL_IS_EQUAL(fieldm[jj*nx+ii], missval) ) grid1_mask[jj*nx+ii] = 1;
       }
 
   double grid1_bound_box[4];
   grid1_bound_box[0] = ym[0];
-  grid1_bound_box[1] = ym[nym-1];
-  if ( ym[0] > ym[nym-1] )
+  grid1_bound_box[1] = ym[ny];
+  if ( ym[0] > ym[ny] )
     {
-      grid1_bound_box[0] = ym[nym-1];
+      grid1_bound_box[0] = ym[ny];
       grid1_bound_box[1] = ym[0];
     }
   grid1_bound_box[2] = xm[0];
-  grid1_bound_box[3] = xm[nxm-1];
+  grid1_bound_box[3] = xm[nx];
  
   progressInit();
 
@@ -414,11 +412,11 @@ void intconarr2(double missval, int lon_is_circular,
   double weight_sum;
 
   double *weight;
-  weight = (double *) malloc(gridsize1*sizeof(double));
+  weight = malloc(gridsize1*sizeof(double));
 
   double tgt_area;
   double *area;
-  area = (double *) malloc(gridsize1*sizeof(double));
+  area = malloc(gridsize1*sizeof(double));
 
   struct grid_cell *SourceCell;
   SourceCell = malloc (gridsize1  * sizeof(*SourceCell) );
@@ -438,9 +436,6 @@ void intconarr2(double missval, int lon_is_circular,
   TargetCell.coordinates_y = malloc (nc2 * sizeof(*TargetCell.coordinates_y) );
 
   unsigned const * curr_deps;
-  //struct polygons polygons;
-
-  //polygon_create ( &polygons );
 #endif
 
   /*
@@ -474,7 +469,7 @@ void intconarr2(double missval, int lon_is_circular,
       restrict_boundbox(grid1_bound_box, bound_box);
       bound_lon1 = bound_box[2];
       bound_lon2 = bound_box[3];
-      //  printf("bound_box %ld  lon: %g %g lat: %g %g\n", i+1, bound_box[2]*RAD2DEG, bound_box[3]*RAD2DEG, bound_box[0]*RAD2DEG, bound_box[1]*RAD2DEG);
+      //printf("bound_box %ld  lon: %g %g lat: %g %g\n", i, bound_box[2]*RAD2DEG, bound_box[3]*RAD2DEG, bound_box[0]*RAD2DEG, bound_box[1]*RAD2DEG);
       /*
 #if defined(_OPENMP)
 #pragma omp atomic
@@ -487,6 +482,7 @@ void intconarr2(double missval, int lon_is_circular,
       //     for ( int k = 0; k < nxm; ++k ) printf("x: %d %g\n", k+1, xm[k]);
       //    for ( int k = 0; k < nym; ++k ) printf("y: %d %g\n", k+1, ym[k]*RAD2DEG);
       long imin = nxm, imax = -1, jmin = nym, jmax = -1;
+      long im, jm;
 
       lfound = rect_grid_search2(&jmin, &jmax, bound_box[0], bound_box[1], nym, ym);
       bound_lon1 = bound_box[2];
@@ -498,9 +494,9 @@ void intconarr2(double missval, int lon_is_circular,
 	  if ( bound_lon2 > grid1_bound_box[3] && bound_lon1 < grid1_bound_box[3] ) bound_lon2 = grid1_bound_box[3];
 	  lfound = rect_grid_search2(&imin, &imax, bound_lon1, bound_lon2, nxm, xm);
 	  //printf("imin %ld  imax %ld  jmin %ld jmax %ld\n", imin, imax, jmin, jmax);
-	  for ( long jm = jmin; jm <= jmax; ++jm )
-	    for ( long im = imin; im <= imax; ++im )
-	      deps[ndeps++] = jm*(nxm-1) + im;
+	  for ( jm = jmin; jm <= jmax; ++jm )
+	    for ( im = imin; im <= imax; ++im )
+	      deps[ndeps++] = jm*nx + im;
 	}
 
 
@@ -515,9 +511,9 @@ void intconarr2(double missval, int lon_is_circular,
 	  if ( bound_lon2 > grid1_bound_box[3] && bound_lon1 < grid1_bound_box[3] ) bound_lon2 = grid1_bound_box[3];
 	  lfound = rect_grid_search2(&imin, &imax, bound_lon1, bound_lon2, nxm, xm);
 	  //printf("imin %ld  imax %ld  jmin %ld jmax %ld\n", imin, imax, jmin, jmax);
-	  for ( long jm = jmin; jm <= jmax; ++jm )
-	    for ( long im = imin; im <= imax; ++im )
-	      deps[ndeps++] = jm*(nxm-1) + im;
+	  for ( jm = jmin; jm <= jmax; ++jm )
+	    for ( im = imin; im <= imax; ++im )
+	      deps[ndeps++] = jm*nx + im;
 	}
 
       bound_lon1 = bound_box[2];
@@ -531,9 +527,9 @@ void intconarr2(double missval, int lon_is_circular,
 	  if ( bound_lon2 > grid1_bound_box[3] && bound_lon1 < grid1_bound_box[3] ) bound_lon2 = grid1_bound_box[3];
 	  lfound = rect_grid_search2(&imin, &imax, bound_lon1, bound_lon2, nxm, xm);
 	  //printf("imin %ld  imax %ld  jmin %ld jmax %ld\n", imin, imax, jmin, jmax);
-	  for ( long jm = jmin; jm <= jmax; ++jm )
-	    for ( long im = imin; im <= imax; ++im )
-	      deps[ndeps++] = jm*(nxm-1) + im;
+	  for ( jm = jmin; jm <= jmax; ++jm )
+	    for ( im = imin; im <= imax; ++im )
+	      deps[ndeps++] = jm*nx + im;
 	}
 
       //for ( long id = 0; id < ndeps; ++id )
@@ -549,15 +545,17 @@ void intconarr2(double missval, int lon_is_circular,
       int ilat2 = index2/nlonOut;
       int ilon2 = index2 - ilat2*nlonOut;
       */
+      double addtest = 0;
+      //if ( i == 296 ) addtest = 360*DEG2RAD;
       for ( int ic = 0; ic < nc2; ++ic )
 	{
-	  TargetCell.coordinates_x[ic] =  x[index2*nc2+ic];
-	  TargetCell.coordinates_y[ic] =  y[index2*nc2+ic];
+	  TargetCell.coordinates_x[ic] =  addtest+x[index2*nc2+ic];
+	  TargetCell.coordinates_y[ic] =          y[index2*nc2+ic];
 	}
 
       if ( cdoVerbose )
 	{
-	  printf("target:\n");
+	  printf("target:       ");
 	  for ( int n = 0; n < nc2; ++n )
 	    printf(" %g %g", TargetCell.coordinates_x[n]/DEG2RAD, TargetCell.coordinates_y[n]/DEG2RAD);
 	  printf("\n");
@@ -572,44 +570,43 @@ void intconarr2(double missval, int lon_is_circular,
       for ( int k = 0; k < num_deps; ++k )
 	{
 	  int index1 = deps[k];
-	  int ilat1 = index1/(nxm-1);
-	  int ilon1 = index1 - ilat1*(nxm-1);
+	  int ilat1 = index1/nx;
+	  int ilon1 = index1 - ilat1*nx;
 	  /*
 	  if ( cdoVerbose )
 	    printf("  dep: %d %d %d %d %d %d\n", k, nlonOut, nlatOut, index1, ilon1, ilat1);
 	  */
 	  if ( ym[ilat1] < ym[ilat1+1] )
 	    {
-	      SourceCell[k].coordinates_x[0] =  xm[ilon1];
-	      SourceCell[k].coordinates_y[0] =  ym[ilat1];
-	      SourceCell[k].coordinates_x[1] =  xm[ilon1+1];
-	      SourceCell[k].coordinates_y[1] =  ym[ilat1];
-	      SourceCell[k].coordinates_x[2] =  xm[ilon1+1];
-	      SourceCell[k].coordinates_y[2] =  ym[ilat1+1];
-	      SourceCell[k].coordinates_x[3] =  xm[ilon1];
-	      SourceCell[k].coordinates_y[3] =  ym[ilat1+1];
+	      SourceCell[k].coordinates_x[0] =  addtest+xm[ilon1];
+	      SourceCell[k].coordinates_y[0] =          ym[ilat1];
+	      SourceCell[k].coordinates_x[1] =  addtest+xm[ilon1+1];
+	      SourceCell[k].coordinates_y[1] =          ym[ilat1];
+	      SourceCell[k].coordinates_x[2] =  addtest+xm[ilon1+1];
+	      SourceCell[k].coordinates_y[2] =          ym[ilat1+1];
+	      SourceCell[k].coordinates_x[3] =  addtest+xm[ilon1];
+	      SourceCell[k].coordinates_y[3] =          ym[ilat1+1];
 	    }
 	  else
 	    {
-	      SourceCell[k].coordinates_x[0] =  xm[ilon1];
-	      SourceCell[k].coordinates_y[0] =  ym[ilat1+1];
-	      SourceCell[k].coordinates_x[1] =  xm[ilon1+1];
-	      SourceCell[k].coordinates_y[1] =  ym[ilat1+1];
-	      SourceCell[k].coordinates_x[2] =  xm[ilon1+1];
-	      SourceCell[k].coordinates_y[2] =  ym[ilat1];
-	      SourceCell[k].coordinates_x[3] =  xm[ilon1];
-	      SourceCell[k].coordinates_y[3] =  ym[ilat1];
+	      SourceCell[k].coordinates_x[0] =  addtest+xm[ilon1];
+	      SourceCell[k].coordinates_y[0] =          ym[ilat1+1];
+	      SourceCell[k].coordinates_x[1] =  addtest+xm[ilon1+1];
+	      SourceCell[k].coordinates_y[1] =          ym[ilat1+1];
+	      SourceCell[k].coordinates_x[2] =  addtest+xm[ilon1+1];
+	      SourceCell[k].coordinates_y[2] =          ym[ilat1];
+	      SourceCell[k].coordinates_x[3] =  addtest+xm[ilon1];
+	      SourceCell[k].coordinates_y[3] =          ym[ilat1];
 	    }
 	  if ( cdoVerbose )
 	    {
-	      printf("source: %d\n", k);
+	      printf("source: %d %d", num_deps, k);
 	      for ( int n = 0; n < 4; ++n )
 		printf(" %g %g", SourceCell[k].coordinates_x[n]/DEG2RAD, SourceCell[k].coordinates_y[n]/DEG2RAD);
 	      printf("\n");
 	    }
 	}
       
-      //polygon_partial_weights(num_deps, SourceCell, TargetCell, weight, &polygons);
       compute_overlap_areas ( nSourceCells, SourceCell, TargetCell, area);
 
       tgt_area = huiliers_area(TargetCell);
@@ -625,8 +622,8 @@ void intconarr2(double missval, int lon_is_circular,
 	{
 	  int index1 = deps[k];
 	  /*
-	  int ilat1 = index1/(nxm-1);
-	  int ilon1 = index1 - ilat1*(nxm-1);
+	  int ilat1 = index1/nx;
+	  int ilon1 = index1 - ilat1*nx;
 	  long add1, add2;
 
 	  add1 = index1;
@@ -634,7 +631,13 @@ void intconarr2(double missval, int lon_is_circular,
 
 	  yar_store_link_cnsrv(&remap.vars, add1, add2, weight[k]);
 	  */
-	  field[i] += fieldm[index1] * weight[k];
+	  if ( weight[k] > 0 )
+	    {
+	      if ( cdoVerbose )
+		printf("tgt_grid_add %ld, src_grid_add %ld,  weight[n] %g, tgt_area  %g\n", i, index1,  weight[k], tgt_area);
+	      //printf("tgt_grid_add %ld, n %ld, src_grid_add %ld,  weight[n] %g, tgt_area  %g\n", i, k, index1,  weight[k], tgt_area);
+	      field[i] += fieldm[index1] * weight[k];
+	    }
 	  /*
 	  if ( cdoVerbose )
 	    printf("  result dep: %ld %d %d  %g\n", i, k, index1, weight[k]);
@@ -646,7 +649,6 @@ void intconarr2(double missval, int lon_is_circular,
 #if defined(HAVE_LIBYAC)
   free(weight);
   free(area);
-  //polygon_destroy ( &polygons );
 #endif
 
   if ( findex < gridsize2 ) progressStatus(0, 1, 1);
@@ -718,13 +720,13 @@ void intgridbil(field_t *field1, field_t *field2)
   nlon1 = gridInqXsize(gridID1);
   nlat1 = gridInqYsize(gridID1);
 
-  array1_2D = (double **) malloc(nlat1*sizeof(double *));
+  array1_2D = malloc(nlat1*sizeof(double *));
   for ( ilat = 0; ilat < nlat1; ilat++ )
     array1_2D[ilat] = array1 + ilat*nlon1;
 
   if ( lon_is_circular ) nlon1 += 1;
-  lon1 = (double *) malloc(nlon1*sizeof(double));
-  lat1 = (double *) malloc(nlat1*sizeof(double));
+  lon1 = malloc(nlon1*sizeof(double));
+  lat1 = malloc(nlat1*sizeof(double));
   gridInqXvals(gridID1, lon1);
   gridInqYvals(gridID1, lat1);
   if ( lon_is_circular ) lon1[nlon1-1] = 0;
@@ -756,9 +758,9 @@ void intgridbil(field_t *field1, field_t *field2)
       if ( lon2 > lon1[nlon1-1] )
 	{
 	  field  = array1_2D;
-	  array1_2D = (double **) malloc(nlat1*sizeof(double *));
-	  lon1 = (double *) realloc(lon1, (nlon1+1)*sizeof(double));
-	  array = (double *) malloc(nlat1*(nlon1+1)*sizeof(double));
+	  array1_2D = malloc(nlat1*sizeof(double *));
+	  lon1 = realloc(lon1, (nlon1+1)*sizeof(double));
+	  array = malloc(nlat1*(nlon1+1)*sizeof(double));
 
 	  for ( ilat = 0; ilat < nlat1; ilat++ )
 	    {
@@ -798,8 +800,8 @@ void intgridbil(field_t *field1, field_t *field2)
 
       gridsize2 = gridInqSize(gridID2);
 
-      lon2 = (double *) malloc(gridsize2*sizeof(double));
-      lat2 = (double *) malloc(gridsize2*sizeof(double));
+      lon2 = malloc(gridsize2*sizeof(double));
+      lat2 = malloc(gridsize2*sizeof(double));
       gridInqXvals(gridID2, lon2);
       gridInqYvals(gridID2, lat2);
 
@@ -835,20 +837,6 @@ void intgridbil(field_t *field1, field_t *field2)
 }
 
 
-void gridGenBounds1(int ny, double *yvals, double *ybounds)
-{
-  int i;
-
-  for ( i = 0; i < ny-1; i++ )
-    {
-      ybounds[i+1] = 0.5*(yvals[i] + yvals[i+1]);
-    }
-
-  ybounds[0]  = 2*yvals[0] - ybounds[1];
-  ybounds[ny] = 2*yvals[ny-1] - ybounds[ny-1];
-}
-
-
 void intgridcon(field_t *field1, field_t *field2)
 {
   int nlon1, nlat1;
@@ -881,8 +869,8 @@ void intgridcon(field_t *field1, field_t *field2)
   nlon1 = gridInqXsize(gridID1);
   nlat1 = gridInqYsize(gridID1);
 
-  lon1 = (double *) malloc(nlon1*sizeof(double));
-  lat1 = (double *) malloc(nlat1*sizeof(double));
+  lon1 = malloc(nlon1*sizeof(double));
+  lat1 = malloc(nlat1*sizeof(double));
   gridInqXvals(gridID1, lon1);
   gridInqYvals(gridID1, lat1);
 
@@ -893,16 +881,19 @@ void intgridcon(field_t *field1, field_t *field2)
 
   nlon1b = nlon1 + 1;
   nlat1b = nlat1 + 1;
-  lon1bounds = (double *) malloc(nlon1b*sizeof(double));
-  lat1bounds = (double *) malloc(nlat1b*sizeof(double));
+  lon1bounds = malloc(nlon1b*sizeof(double));
+  lat1bounds = malloc(nlat1b*sizeof(double));
 
-  gridGenBounds1(nlon1, lon1, lon1bounds);
-  gridGenBounds1(nlat1, lat1, lat1bounds);
+  grid_gen_corners(nlon1, lon1, lon1bounds);
+  grid_gen_corners(nlat1, lat1, lat1bounds);
 
-  for ( int i = 0; i < nlat1; ++i )
-    printf("lat1 %d %g\n", i+1, lat1[i]*RAD2DEG);
-  printf("lat1bounds: %g %g %g ... %g %g %g\n", lat1bounds[0]*RAD2DEG, lat1bounds[1]*RAD2DEG, lat1bounds[2]*RAD2DEG, lat1bounds[nlat1b-3]*RAD2DEG, lat1bounds[nlat1b-2]*RAD2DEG, lat1bounds[nlat1b-1]*RAD2DEG);
-  printf("lon1bounds: %g %g %g ... %g %g %g\n", lon1bounds[0]*RAD2DEG, lon1bounds[1]*RAD2DEG, lon1bounds[2]*RAD2DEG, lon1bounds[nlon1b-3]*RAD2DEG, lon1bounds[nlon1b-2]*RAD2DEG, lon1bounds[nlon1b-1]*RAD2DEG);
+  if ( cdoVerbose )
+    {
+      for ( int i = 0; i < nlat1; ++i )
+	printf("lat1 %d %g\n", i+1, lat1[i]*RAD2DEG);
+      printf("lat1bounds: %g %g %g ... %g %g %g\n", lat1bounds[0]*RAD2DEG, lat1bounds[1]*RAD2DEG, lat1bounds[2]*RAD2DEG, lat1bounds[nlat1b-3]*RAD2DEG, lat1bounds[nlat1b-2]*RAD2DEG, lat1bounds[nlat1b-1]*RAD2DEG);
+      printf("lon1bounds: %g %g %g ... %g %g %g\n", lon1bounds[0]*RAD2DEG, lon1bounds[1]*RAD2DEG, lon1bounds[2]*RAD2DEG, lon1bounds[nlon1b-3]*RAD2DEG, lon1bounds[nlon1b-2]*RAD2DEG, lon1bounds[nlon1b-1]*RAD2DEG);
+    }
 
   nlon2 = gridInqXsize(gridID2);
   nlat2 = gridInqYsize(gridID2);
@@ -926,14 +917,12 @@ void intgridcon(field_t *field1, field_t *field2)
   else
     nc2 = 4;
 
-  printf("nc2: %d\n", nc2);
-
   double *grid2_corner_lon = NULL, *grid2_corner_lat = NULL;
 
   if ( gridInqYbounds(gridID2, NULL) && gridInqXbounds(gridID2, NULL) )
     {
-      grid2_corner_lon = (double *) malloc(nc2*gridsize2*sizeof(double));
-      grid2_corner_lat = (double *) malloc(nc2*gridsize2*sizeof(double));
+      grid2_corner_lon = malloc(nc2*gridsize2*sizeof(double));
+      grid2_corner_lat = malloc(nc2*gridsize2*sizeof(double));
       gridInqXbounds(gridID2, grid2_corner_lon);
       gridInqYbounds(gridID2, grid2_corner_lat);
     }
@@ -1022,8 +1011,8 @@ void interpolate(field_t *field1, field_t *field2)
   out_nlon = gridInqXsize(gridIDo);
   out_nlat = gridInqYsize(gridIDo);
 
-  lon_array = (double *) malloc((nlon + 2) * sizeof(double));
-  lat_array = (double *) malloc((nlat + 2) * sizeof(double));
+  lon_array = malloc((nlon + 2) * sizeof(double));
+  lat_array = malloc((nlat + 2) * sizeof(double));
   lon = lon_array + 1;
   lat = lat_array + 1;
 
@@ -1074,9 +1063,9 @@ void interpolate(field_t *field1, field_t *field2)
   if ( lat[nlat] < -90 ) lat[nlat] = -99;
   if ( lat[nlat] >  90 ) lat[nlat] =  99;
 
-  lono_array = (double *) malloc((out_nlon < 2 ? 4 : out_nlon + 2) * sizeof(double));
+  lono_array = malloc((out_nlon < 2 ? 4 : out_nlon + 2) * sizeof(double));
   lono = lono_array + 1;
-  lato_array = (double *) malloc((out_nlat < 2 ? 4 : out_nlat + 2) * sizeof(double));
+  lato_array = malloc((out_nlat < 2 ? 4 : out_nlat + 2) * sizeof(double));
   lato = lato_array + 1;
 
   gridInqXvals(gridIDo, lono);
@@ -1148,13 +1137,13 @@ void interpolate(field_t *field1, field_t *field2)
 
   nxlon = 2*nlon + 1;
   nxlat = 2*nlat + 1;
-  xin_array = (double *) malloc(nxlon * nxlat * sizeof(double));
-  xin = (double **) malloc(nxlat * sizeof(double *));
+  xin_array = malloc(nxlon * nxlat * sizeof(double));
+  xin = malloc(nxlat * sizeof(double *));
 
   for (ilat = 0; ilat < nxlat; ilat++)
     xin[ilat] = xin_array + ilat * nxlon;
 
-  xlon = (double *) malloc(nxlon * sizeof (double));
+  xlon = malloc(nxlon * sizeof (double));
   for ( ilon = 0; ilon < nlon; ilon++ )
     {
       xlon[2*ilon + 1] = lon[ilon];
@@ -1162,7 +1151,7 @@ void interpolate(field_t *field1, field_t *field2)
     }
   xlon[2 * nlon] = (lon[nlon - 1] + lon[nlon]) / 2;
 
-  xlat = (double *) malloc((2 * nlat + 1) * sizeof (double));
+  xlat = malloc((2 * nlat + 1) * sizeof (double));
   for ( ilat = 0; ilat < nlat; ilat++ )
     {
       xlat[2*ilat + 1] = lat[ilat];
@@ -1170,18 +1159,18 @@ void interpolate(field_t *field1, field_t *field2)
     }
   xlat[2 * nlat] = (lat[nlat - 1] + lat[nlat]) / 2;
 
-  in0 = (double **) malloc(nlat * sizeof (double *));
+  in0 = malloc(nlat * sizeof (double *));
   for (ilat = 0; ilat < nlat; ilat++)
     in0[ilat] = arrayIn + ilat * nlon;
 
-  ilon11 = (long *) malloc(out_nlon * sizeof(long));
-  ilon12 = (long *) malloc(out_nlon * sizeof(long));
-  ilon21 = (long *) malloc(out_nlon * sizeof(long));
-  ilon22 = (long *) malloc(out_nlon * sizeof(long));
-  volon11 = (double *) malloc(out_nlon * sizeof(double));
-  volon12 = (double *) malloc(out_nlon * sizeof(double));
-  volon21 = (double *) malloc(out_nlon * sizeof(double));
-  volon22 = (double *) malloc(out_nlon * sizeof(double));
+  ilon11 = malloc(out_nlon * sizeof(long));
+  ilon12 = malloc(out_nlon * sizeof(long));
+  ilon21 = malloc(out_nlon * sizeof(long));
+  ilon22 = malloc(out_nlon * sizeof(long));
+  volon11 = malloc(out_nlon * sizeof(double));
+  volon12 = malloc(out_nlon * sizeof(double));
+  volon21 = malloc(out_nlon * sizeof(double));
+  volon22 = malloc(out_nlon * sizeof(double));
 
   for (olon = 0; olon < out_nlon; olon++)
     {
@@ -1206,8 +1195,8 @@ void interpolate(field_t *field1, field_t *field2)
       ilon22[olon] = l22;
     }
 
-  ilat1 = (long *) malloc(out_nlat * sizeof(long));
-  ilat2 = (long *) malloc(out_nlat * sizeof(long));
+  ilat1 = malloc(out_nlat * sizeof(long));
+  ilat2 = malloc(out_nlat * sizeof(long));
 
   xlat_is_ascending = xlat[0] <= xlat[nxlat - 1];
   for ( olat = 0; olat < out_nlat; olat++ )
@@ -1245,7 +1234,7 @@ void interpolate(field_t *field1, field_t *field2)
       ilat2[olat] = l2;
     }
 
-  xout = (double **) malloc(out_nlat * sizeof (double *));
+  xout = malloc(out_nlat * sizeof (double *));
   for (olat = 0; olat < out_nlat; olat++)
     xout[olat] = arrayOut + olat * out_nlon;
 
@@ -1550,17 +1539,17 @@ void contrast(void)
 
   if (rec == 1)
     {
-      xin_array = (double *) malloc((nlat + 2) * (nlon + 2) * sizeof(double));
-      xin = (double **) malloc((nlat + 2) * sizeof(double *));
+      xin_array = malloc((nlat + 2) * (nlon + 2) * sizeof(double));
+      xin = malloc((nlat + 2) * sizeof(double *));
       *xin = *(xin + 1);
       for (ilat = -1; ilat <= nlat; ilat++)
 	xin[ilat] = xin_array + (ilat + 1) * (nlon + 2) + 1;
-      xout = (double **) malloc(nlat * sizeof(double *));
+      xout = malloc(nlat * sizeof(double *));
       for (ilat = 0; ilat < nlat; ilat++)
 	xout[ilat] = out[0] + ilat * nlon;
       for (j = 0; j < 17; j++)
 	{
-	  xwork[j] = (double **) malloc(nlat * sizeof(double *));
+	  xwork[j] = malloc(nlat * sizeof(double *));
 	  for (ilat = 0; ilat < nlat; ilat++)
 	    xwork[j][ilat] = work[j] + ilat * nlon;
 	}
diff --git a/src/job.c b/src/job.c
index dffa234..f53dc0a 100644
--- a/src/job.c
+++ b/src/job.c
@@ -55,7 +55,7 @@ static drmaa_job_template_t *create_job_template(const char *expname, const char
   /* determine current path */
 
   size = pathconf(".", _PC_PATH_MAX);
-  if ( (dir = (char *)malloc((size_t)size)) != NULL )
+  if ( (dir = malloc((size_t)size)) != NULL )
     {
       ptr = getcwd(dir, (size_t)size);
     }
@@ -67,7 +67,7 @@ static drmaa_job_template_t *create_job_template(const char *expname, const char
   len2 = strlen(GRID_TMPDIR);
   len = len1+len2+2;
 
-  output_path = (char *) malloc(len*sizeof(char));
+  output_path = malloc(len*sizeof(char));
   /*
   strcpy(output_path, host);
   strcat(output_path, ":");
@@ -348,9 +348,7 @@ int job_submit(const char *expname, const char *jobfilename, const char *jobname
 
 
 #if defined(HAVE_LIBCURL)
-#  include <curl/curl.h>
-#  include <curl/types.h>
-#  include <curl/easy.h>
+#include <curl/curl.h>
 #endif
 
 struct FtpFile {
@@ -359,7 +357,7 @@ struct FtpFile {
 };
 
 
-int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
+size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
 {
   struct FtpFile *out=(struct FtpFile *)stream;
   if(out && !out->stream) {
@@ -371,13 +369,13 @@ int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
 }
 
 
-int my_progress_func(int *stdout_is_tty,
-                     double t, /* dltotal */
-                     double d, /* dlnow */
-                     double ultotal,
-                     double ulnow)
+int my_progress_func(void *stdout_is_tty,
+			double t, /* dltotal */
+			double d, /* dlnow */
+			double ultotal,
+			double ulnow)
 {
-  if ( *stdout_is_tty )
+  if ( *(char*)stdout_is_tty )
     {
       fprintf(stdout, "\b\b\b\b\b%4d%%", (int) (d*100/t));
       fflush(stdout);
diff --git a/src/kvlist.c b/src/kvlist.c
index 0d2333b..8c36694 100644
--- a/src/kvlist.c
+++ b/src/kvlist.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -284,7 +284,7 @@ void *kvlParseFile(const char *filename)
   filesize = (size_t) ftell(fp);
   fseek(fp, 0L, SEEK_SET);
 
-  buffer = (char *) malloc(filesize);
+  buffer = malloc(filesize);
   nitems = fread(buffer, 1, filesize, fp);
 
   fclose(fp);
@@ -295,7 +295,7 @@ void *kvlParseFile(const char *filename)
       return (kvl);
     }
  
-  kvl = (kvl_t *) calloc(1, sizeof(kvl_t));
+  kvl = calloc(1, sizeof(kvl_t));
   kvl->buffer = buffer;
   kvl->buffersize = filesize;
   kvl->filename = strdup(filename);
diff --git a/src/kvlist.h b/src/kvlist.h
index 174f4fc..9721a39 100644
--- a/src/kvlist.h
+++ b/src/kvlist.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/list.c b/src/list.c
index 1cca323..5268455 100644
--- a/src/list.c
+++ b/src/list.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -45,7 +45,7 @@ LIST *listNew(int type)
     }
   else
     {
-      list = (LIST *) malloc(sizeof(LIST));
+      list = malloc(sizeof(LIST));
       listInit(list, type);
     }
 
@@ -75,9 +75,9 @@ static void listCheck(LIST *list, int num)
     {
       list->nalloc += list->allinc;
       if ( list->type == INT_LIST )
-	list->array = (int *) realloc(list->array, list->nalloc*sizeof(int));
+	list->array = realloc(list->array, list->nalloc*sizeof(int));
       else
-	list->array = (double *) realloc(list->array, list->nalloc*sizeof(double));
+	list->array = realloc(list->array, list->nalloc*sizeof(double));
     }
 }
 
diff --git a/src/list.h b/src/list.h
index 2dfdf41..cf85b8f 100644
--- a/src/list.h
+++ b/src/list.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/magics_template_parser.c b/src/magics_template_parser.c
index 658be13..d6d7a5a 100644
--- a/src/magics_template_parser.c
+++ b/src/magics_template_parser.c
@@ -165,7 +165,7 @@ int SetMagicsParameterValue( char *param_name, char *param_type, char *param_val
 		split_str_count = StringSplitWithSeperator( param_value, sep_char, &split_str );
 		if( split_str_count )
 		  {
-			float_param_list = ( double *) malloc ( sizeof( double ) * split_str_count );
+			float_param_list = malloc ( sizeof( double ) * split_str_count );
 			for( i = 0; i < split_str_count; i++ )
 			  {
 #if 0
@@ -194,7 +194,7 @@ int SetMagicsParameterValue( char *param_name, char *param_type, char *param_val
 		split_str_count = StringSplitWithSeperator( param_value, sep_char, &split_str );
 		if( split_str_count )
 		  {
-			int_param_list = ( int *) malloc ( sizeof( int ) * split_str_count );
+			int_param_list = malloc ( sizeof( int ) * split_str_count );
 			for( i = 0; i < split_str_count; i++ )
 			{
 				int_param_list[i] = atoi( split_str[i] );			
diff --git a/src/merge_sort2.c b/src/merge_sort2.c
index 2fbfece..2607328 100644
--- a/src/merge_sort2.c
+++ b/src/merge_sort2.c
@@ -71,7 +71,7 @@ void sort_par(long num_links, double *restrict add1, int parent, int par_depth)
 	     "       in this implementation of merge sort\n");
     }
 
-  idx = (long *) malloc(num_links*sizeof(long));
+  idx = malloc(num_links*sizeof(long));
 
   /* SPLIT AND SORT THE DATA FRAGMENTS */
   add_srt[0] = 0;                  add_srt[1] = num_links/nsplit;
diff --git a/src/modules.c b/src/modules.c
index 4dadf30..a9b6485 100644
--- a/src/modules.c
+++ b/src/modules.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -293,7 +293,7 @@ void *Maggraph(void *argument);
 #define  ConsecstatOperators    {"consects", "consecsum"}
 #define  CopyOperators          {"copy", "selall", "szip"}
 #define  DeltimeOperators       {"delday", "del29feb"}
-#define  DeriveparOperators     {"geopotheight"}
+#define  DeriveparOperators     {"geopotheight", "sealevelpressure"}
 #define  DetrendOperators       {"detrend"}
 #define  DiffOperators          {"diff", "diff2", "diffp", "diffn", "diffc"}
 #define  DuplicateOperators     {"duplicate"}
@@ -321,7 +321,7 @@ void *Maggraph(void *argument);
 #define  FourierOperators       {"fourier"}
 #define  GatherOperators        {"gather"}
 #define  GengridOperators       {"gengrid"}
-#define  GradsdesOperators      {"gradsdes1", "gradsdes2", "dumpmap"}
+#define  GradsdesOperators      {"gradsdes", "dumpmap"}
 #define  GridboxstatOperators   {"gridboxmin", "gridboxmax", "gridboxsum", "gridboxmean", "gridboxavg", "gridboxvar", "gridboxstd"}
 #define  GridcellOperators      {"gridarea", "gridweights", "gridmask", "griddx", "griddy"}
 #define  HarmonicOperators      {"harmonic"}
@@ -369,8 +369,8 @@ void *Maggraph(void *argument);
 #define  PressureOperators      {"pressure_fl", "pressure_hl", "deltap"}
 #define  RegresOperators        {"regres"}
 #define  RemapOperators         {"remap"}
-#define    RemapgridOperators   {"remapcon", "remapbil", "remapbic", "remapdis", "remapnn", "remaplaf", "remapcon2", "remapsum"}
-#define    GenweightsOperators  {"gencon", "genbil", "genbic", "gendis", "gennn", "genlaf", "gencon2"}
+#define    RemapgridOperators   {"remapcons", "remapcon", "remapbil", "remapbic", "remapdis", "remapnn", "remaplaf", "remapcon2", "remapsum"}
+#define    GenweightsOperators  {"gencons", "gencon", "genbil", "genbic", "gendis", "gennn", "genlaf", "gencon2"}
 #define  RemapetaOperators      {"remapeta", "remapeta_s", "remapeta_z"}
 #define  ReplaceOperators       {"replace"}
 #define  ReplacevaluesOperators {"setvals", "setrtoc", "setrtoc2"}
@@ -793,7 +793,6 @@ static char *opalias[][2] =
   {"ggstat",              "info"       },
   {"ggstats",             "sinfo"      },
   {"globavg",             "fldavg"     },
-  {"gradsdes",            "gradsdes2"  },
   {"infos",               "sinfo"      },
   {"infov",               "infon"      },
   {"intgrid",             "intgridbil" },
diff --git a/src/modules.h b/src/modules.h
index 0a97a33..888ad29 100644
--- a/src/modules.h
+++ b/src/modules.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/namelist.c b/src/namelist.c
index 603175f..e931170 100644
--- a/src/namelist.c
+++ b/src/namelist.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -74,7 +74,7 @@ namelist_t *namelistNew(const char *name)
 {
   namelist_t *namelist;
 
-  namelist = (namelist_t *) malloc(sizeof(namelist_t));
+  namelist = malloc(sizeof(namelist_t));
 
   namelist_init(namelist, name);
 
@@ -190,7 +190,7 @@ int namelistAdd(namelist_t *nml, const char *name, int type, int dis, void *ptr,
       return (-1);
     }
 
-  nml_entry = (nml_entry_t *) malloc(sizeof(nml_entry_t));
+  nml_entry = malloc(sizeof(nml_entry_t));
 
   nml_entry->name = strdup(name);
   nml_entry->type = type;
@@ -259,6 +259,8 @@ static void getnite(FILE *nmlfp, namelist_t *nml)
 		{
 		  if ( !(islower((int) nml->line.linelc[j]) ||
 			 (((int) nml->line.linelc[j]) == '_') ||
+			 (((int) nml->line.linelc[j]) == '-') ||
+			 (((int) nml->line.linelc[j]) == '+') ||
 			 isdigit((int) nml->line.linelc[j])) )
 		    {
 		      nml->line.namitl = j - 1;
@@ -381,7 +383,7 @@ static void rdnlsgl(namelist_t *nml, void *var, int ntyp, int nlen, int *nocc)
       if ( *nocc < nlen )
 	{
 	  len = nml->line.namitl - nml->line.namitf + 1;
-	  ((char **)var)[*nocc] = (char*) calloc((size_t)len+1, sizeof(char));
+	  ((char **)var)[*nocc] = calloc((size_t)len+1, sizeof(char));
 	  for ( i = 0; i < len; i++ )
 	    ((char **)var)[*nocc][i] = nml->line.lineac[nml->line.namitf+i];
 	  *nocc += 1;
diff --git a/src/namelist.h b/src/namelist.h
index 12bdae1..9e453e9 100644
--- a/src/namelist.h
+++ b/src/namelist.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/operator_help.h b/src/operator_help.h
index 68a07d6..e41b944 100644
--- a/src/operator_help.h
+++ b/src/operator_help.h
@@ -2042,15 +2042,13 @@ static char *TimpctlHelp[] = {
     "    timpctl,p  ifile1 ifile2 ifile3 ofile",
     "",
     "DESCRIPTION",
-    "    This operator computes percentiles over all timesteps in ifile1.",
-    "    The algorithm uses histograms with minimum and maximum bounds given in",
-    "    ifile2 and ifile3, respectively. The default number of",
-    "    histogram bins is 101. The default can be overridden by setting the",
-    "    environment variable CDO_PCTL_NBINS to a different value. The files",
-    "    ifile2 and ifile3 should be the result of corresponding",
-    "    timmin and timmax operations, respectively.",
-    "    The date information of a timestep in ofile is the date of the",
-    "    last contributing timestep in ifile1.",
+    "    This operator computes percentiles over all timesteps in ifile1. The algorithm uses ",
+    "    histograms with minimum and maximum bounds given in ifile2 and ifile3, respectively. ",
+    "    The default number of histogram bins is 101. The default can be overridden by setting the",
+    "    environment variable CDO_PCTL_NBINS to a different value. The files ifile2 and ifile3",
+    "    should be the result of corresponding timmin and timmax operations, respectively.",
+    "    The date information of a timestep in ofile is the date of the last contributing ",
+    "    timestep in ifile1.",
     "    ",
     "    o(1,x) = pth percentile {i(t',x), t_1<t'<=t_n}",
     "",
@@ -3807,26 +3805,24 @@ static char *OutputHelp[] = {
 
 static char *GradsdesHelp[] = {
     "NAME",
-    "    gradsdes1, gradsdes2 - GrADS data descriptor file",
+    "    gradsdes - GrADS data descriptor file",
     "",
     "SYNOPSIS",
-    "    <operator>  ifile",
+    "    gradsdes[,mapversion]  ifile",
     "",
     "DESCRIPTION",
     "    Creates a GrADS data descriptor file. Supported file formats are GRIB1, netCDF, SERVICE, ",
     "    EXTRA and IEG. For GRIB1 files the GrADS map file is also generated. For SERVICE and EXTRA",
     "    files the grid have to be specified with the CDO option '-g <grid>'. This module takes ifile",
     "    in order to create filenames for the descriptor (ifile.ctl) and the map (ifile.gmp) file.",
-    "    \"gradsdes\" is an alias for gradsdes2.",
     "",
-    "OPERATORS",
-    "    gradsdes1  GrADS data descriptor file (version 1 GRIB map)",
-    "               Creates a GrADS data descriptor file. Generated a machine",
-    "               specific version 1 GrADS map file for GRIB1 datasets.",
-    "    gradsdes2  GrADS data descriptor file (version 2 GRIB map)",
-    "               Creates a GrADS data descriptor file. Generated a machine ",
-    "               independent version 2 GrADS map file for GRIB1 datasets.",
-    "               This map file can be used only with GrADS version 1.8 or newer. ",
+    "PARAMETER",
+    "    mapversion  INTEGER  Format version of the GrADS map file for GRIB1 datasets. Use 1 for a machine",
+    "                specific version 1 GrADS map file, 2 for a machine independent version 2 GrADS map file",
+    "                and 4 to support GRIB files >2GB. ",
+    "                A version 2 map file can be used only with GrADS version 1.8 or newer.",
+    "                A version 4 map file can be used only with GrADS version 2.0 or newer.",
+    "                The default is 4 for files >2GB, otherwise 2.",
     NULL
 };
 
@@ -4327,9 +4323,11 @@ static char *EcaCfdHelp[] = {
     "DESCRIPTION",
     "    Let ifile be a time series of the daily minimum temperature TN, then the largest number of",
     "    consecutive days where TN < 0 °C is counted. Note that TN have to be given in units of Kelvin.",
+    "    A further output variable is the number of frost periods of more than 5 days.",
     "    The date information of a timestep in ofile is the date of the last contributing timestep in ifile.",
     "    The following variables are created: ",
     "    - consecutive_frost_days_index_per_time_period",
+    "    - number_of_cfd_periods_with_more_than_5days_per_time_period",
     NULL
 };
 
@@ -4344,9 +4342,11 @@ static char *EcaCsuHelp[] = {
     "    Let ifile be a time series of the daily maximum temperature TX, then the largest number of consecutive",
     "    days where TX > T is counted. The number T is an optional parameter with default T = 25°C.",
     "    Note that TN have to be given in units of Kelvin, whereas T have to be given in degrees Celsius.",
+    "    A further output variable is the number of summer periods of more than 5 days.",
     "    The date information of a timestep in ofile is the date of the last contributing timestep in ifile.",
     "    The following variables are created: ",
     "    - consecutive_summer_days_index_per_time_period",
+    "    - number_of_csu_periods_with_more_than_5days_per_time_period",
     "",
     "PARAMETER",
     "    T  FLOAT   Temperature threshold (unit: °C; default: T = 25°C)",
diff --git a/src/percentiles.c b/src/percentiles.c
index 97b9a1b..71f755b 100644
--- a/src/percentiles.c
+++ b/src/percentiles.c
@@ -77,7 +77,7 @@ static void histBin(HISTOGRAM *hist)
   
   assert( hist->nsamp == DBL_CAPACITY(hist->nbins) );
 
-  values = (double *) malloc(hist->nsamp * sizeof(double));
+  values = malloc(hist->nsamp * sizeof(double));
 
   for ( i = 0; i < hist->nsamp; i++ )
     values[i] = DBL_PTR(hist->ptr)[i];
@@ -164,14 +164,14 @@ HISTOGRAM_SET *hsetCreate(int nvars)
   
   assert( nvars > 0);
   
-  hset = (HISTOGRAM_SET *) malloc(sizeof(HISTOGRAM_SET));
+  hset = malloc(sizeof(HISTOGRAM_SET));
   if ( hset == NULL )
     cdoAbort("Not enough memory (%s)", __func__);
     
   hset->nvars   = nvars;
-  hset->nlevels = (int *) malloc(nvars * sizeof(int));
-  hset->grids   = (int *) malloc(nvars * sizeof(int));
-  hset->histograms = (HISTOGRAM ***) malloc(nvars * sizeof(HISTOGRAM **));
+  hset->nlevels = malloc(nvars * sizeof(int));
+  hset->grids   = malloc(nvars * sizeof(int));
+  hset->histograms = malloc(nvars * sizeof(HISTOGRAM **));
   if ( hset->histograms == NULL )
     cdoAbort("Not enough memory (%s)", __func__);
   
@@ -211,13 +211,13 @@ void hsetCreateVarLevels(HISTOGRAM_SET *hset, int varID, int nlevels, int grid)
   hset->nlevels[varID] = nlevels;
   hset->grids[varID]   = grid;
 
-  hset->histograms[varID] = (HISTOGRAM **) malloc(nlevels * sizeof(HISTOGRAM *));
+  hset->histograms[varID] = malloc(nlevels * sizeof(HISTOGRAM *));
   if ( hset->histograms[varID] == NULL )
     cdoAbort("Not enough memory (%s)", __func__);
 
   for ( levelID = 0; levelID < nlevels; levelID++ )
     {
-      hists = hset->histograms[varID][levelID] = (HISTOGRAM *) malloc(nhists * sizeof(HISTOGRAM));
+      hists = hset->histograms[varID][levelID] = malloc(nhists * sizeof(HISTOGRAM));
       if ( hists == NULL )
         cdoAbort("Not enough memory (%s)", __func__);
         
diff --git a/src/pipe.c b/src/pipe.c
index 026e5a8..86e7fea 100644
--- a/src/pipe.c
+++ b/src/pipe.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -87,28 +87,28 @@ void pipe_init(pipe_t *pipe)
   pipe->usedata = TRUE;
   pipe->pstreamptr_in = 0;
 
-  pipe->mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));
+  pipe->mutex = malloc(sizeof(pthread_mutex_t));
   pthread_mutex_init(pipe->mutex, &m_attr);
 
-  pipe->tsDef = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
+  pipe->tsDef = malloc(sizeof(pthread_cond_t));
   pthread_cond_init(pipe->tsDef, &c_attr);
-  pipe->tsInq = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
+  pipe->tsInq = malloc(sizeof(pthread_cond_t));
   pthread_cond_init(pipe->tsInq, &c_attr);
 
-  pipe->recDef = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
+  pipe->recDef = malloc(sizeof(pthread_cond_t));
   pthread_cond_init(pipe->recDef, &c_attr);
-  pipe->recInq = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
+  pipe->recInq = malloc(sizeof(pthread_cond_t));
   pthread_cond_init(pipe->recInq, &c_attr);
   
-  pipe->vlistDef = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
+  pipe->vlistDef = malloc(sizeof(pthread_cond_t));
   pthread_cond_init(pipe->vlistDef, &c_attr);
-  pipe->isclosed = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
+  pipe->isclosed = malloc(sizeof(pthread_cond_t));
   pthread_cond_init(pipe->isclosed, &c_attr);
 
-  pipe->writeCond = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
+  pipe->writeCond = malloc(sizeof(pthread_cond_t));
   pthread_cond_init(pipe->writeCond, &c_attr);
 
-  pipe->readCond = (pthread_cond_t *) malloc(sizeof(pthread_cond_t));
+  pipe->readCond = malloc(sizeof(pthread_cond_t));
   pthread_cond_init(pipe->readCond, &c_attr);
 
   pthread_mutexattr_destroy(&m_attr);
@@ -120,7 +120,7 @@ pipe_t *pipeNew()
 {
   pipe_t *pipe;
 
-  pipe = (pipe_t *) malloc(sizeof(pipe_t));
+  pipe = malloc(sizeof(pipe_t));
 
   pipe_init(pipe);
 
diff --git a/src/pipe.h b/src/pipe.h
index 8a9470e..a2af23f 100644
--- a/src/pipe.h
+++ b/src/pipe.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/printinfo.h b/src/printinfo.h
index 2ad9706..23b5672 100644
--- a/src/printinfo.h
+++ b/src/printinfo.h
@@ -313,8 +313,8 @@ void printGridInfo(int vlistID)
 	      int i;
 	      double *xvals, *yvals;
 	      double xfirst, xlast, yfirst, ylast;
-	      xvals = (double *) malloc(gridsize*sizeof(double));
-	      yvals = (double *) malloc(gridsize*sizeof(double));
+	      xvals = malloc(gridsize*sizeof(double));
+	      yvals = malloc(gridsize*sizeof(double));
 
 	      gridInqXvals(gridID, xvals);
 	      gridInqYvals(gridID, yvals);
diff --git a/src/process.c b/src/process.c
index 1160916..e05a236 100644
--- a/src/process.c
+++ b/src/process.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -406,7 +406,7 @@ char *getOperatorArg(const char *xoperator)
 	  len = strlen(commapos+1);
 	  if ( len )
 	    {
-	      operatorArg = (char *) malloc(len+1);
+	      operatorArg = malloc(len+1);
 	      strcpy(operatorArg, commapos+1);
 	    }
 	}
@@ -512,7 +512,7 @@ void setStreamNames(int argc, char *argv[])
 	  globArgc = getGlobArgc(argc, argv, globArgc);
 	  len = 0;
 	  for ( i = globArgcStart; i < globArgc; i++ ) len += strlen(argv[i]) + 1;
-	  streamname = (char *) calloc(1, len);
+	  streamname = calloc(1, len);
 	  for ( i = globArgcStart; i < globArgc; i++ )
 	    {
 	      strcat(streamname, argv[i]);
@@ -522,7 +522,7 @@ void setStreamNames(int argc, char *argv[])
 	  Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
 	  ac = globArgc - globArgcStart;
 	  //printf("setStreamNames:  ac %d  streamname1: %s\n", ac, streamname);
-	  Process[processID].streamNames[Process[processID].streamCnt].argv = (char **) malloc(ac*sizeof(char *));
+	  Process[processID].streamNames[Process[processID].streamCnt].argv = malloc(ac*sizeof(char *));
 	  for ( i = 0; i < ac; ++i )
 	    Process[processID].streamNames[Process[processID].streamCnt].argv[i] = argv[i+globArgcStart];
 	  Process[processID].streamNames[Process[processID].streamCnt].argc = ac;
@@ -532,11 +532,11 @@ void setStreamNames(int argc, char *argv[])
       else
 	{
 	  len = strlen(argv[globArgc]) + 1;
-	  streamname = (char *) malloc(len);
+	  streamname = malloc(len);
 	  strcpy(streamname, argv[globArgc]);
 	  Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
 	  ac = 1;
-	  Process[processID].streamNames[Process[processID].streamCnt].argv = (char **) malloc(ac*sizeof(char *));
+	  Process[processID].streamNames[Process[processID].streamCnt].argv = malloc(ac*sizeof(char *));
 	  Process[processID].streamNames[Process[processID].streamCnt].argv[0] = argv[globArgc];
 	  Process[processID].streamNames[Process[processID].streamCnt].argc = ac;
 	  Process[processID].streamNames[Process[processID].streamCnt].args = streamname;
@@ -567,7 +567,7 @@ int expand_wildcards(int processID, int streamCnt)
 	  free(Process[processID].streamNames[0].argv);
 	  free(Process[processID].streamNames[0].args);
 
-	  Process[processID].streamNames = (argument_t *) realloc(Process[processID].streamNames, streamCnt*sizeof(argument_t));
+	  Process[processID].streamNames = realloc(Process[processID].streamNames, streamCnt*sizeof(argument_t));
 	      
 	  // move output streams to the end
 	  for ( i = 1; i < Process[processID].streamCnt; ++i )
@@ -576,7 +576,7 @@ int expand_wildcards(int processID, int streamCnt)
 	  for ( i = 0; i < glob_arg->argc; ++i )
 	    {
 	      // printf("add %d %s\n", i, glob_arg->argv[i]);
-	      Process[processID].streamNames[i].argv    = (char **) malloc(sizeof(char *));
+	      Process[processID].streamNames[i].argv    = malloc(sizeof(char *));
 	      Process[processID].streamNames[i].argc    = 1;
 	      Process[processID].streamNames[i].argv[0] = strdupx(glob_arg->argv[i]);
 	      Process[processID].streamNames[i].args    = strdupx(glob_arg->argv[i]);
@@ -688,7 +688,7 @@ void setStreams(int argc, char *argv[])
 
   Process[processID].streamCnt  = 0; /* filled in setStreamNames */
   if ( streamCnt )
-    Process[processID].streamNames = (argument_t *) malloc(streamCnt*sizeof(argument_t));
+    Process[processID].streamNames = malloc(streamCnt*sizeof(argument_t));
   for ( i = 0; i < streamCnt; i++ )
     {
       Process[processID].streamNames[i].argc = 0;
@@ -874,7 +874,7 @@ void operatorInputArg(const char *enter)
 		  while ( pline[len] != ' '  && pline[len] != ',' &&
 			  pline[len] != '\\' && len < linelen ) len++;
 
-		  Process[processID].oargv[oargc] = (char *) malloc(len+1);
+		  Process[processID].oargv[oargc] = malloc(len+1);
 		  memcpy(Process[processID].oargv[oargc], pline, len);
 		  Process[processID].oargv[oargc][len] = '\0';
 		  oargc++;
diff --git a/src/process.h b/src/process.h
index 4ad92ec..87cc808 100644
--- a/src/process.h
+++ b/src/process.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/pstream.c b/src/pstream.c
index bc4246b..d42253f 100644
--- a/src/pstream.c
+++ b/src/pstream.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -101,7 +101,7 @@ void pstream_list_new(void)
 {
   assert(_pstreamList == NULL);
 
-  _pstreamList = (pstreamPtrToIdx *) malloc(_pstream_max*sizeof(pstreamPtrToIdx));
+  _pstreamList = malloc(_pstream_max*sizeof(pstreamPtrToIdx));
 }
 
 static
@@ -213,7 +213,7 @@ pstream_t *pstream_new_entry(void)
 {
   pstream_t *pstreamptr;
 
-  pstreamptr = (pstream_t *) malloc(sizeof(pstream_t));
+  pstreamptr = malloc(sizeof(pstream_t));
 
   if ( pstreamptr ) pstream_init_entry(pstreamptr);
 
@@ -325,7 +325,7 @@ int pstreamOpenRead(const argument_t *argument)
       char *operatorArg;
       char *operatorName;
       char *newarg;
-      char *pipename = (char *) malloc(16);
+      char *pipename = malloc(16);
       int rval;
       pthread_t thrID;
       pthread_attr_t attr;
@@ -333,17 +333,17 @@ int pstreamOpenRead(const argument_t *argument)
       size_t len;
       size_t stacksize;
       int status;
-      argument_t *newargument = (argument_t *) malloc(sizeof(argument_t));
+      argument_t *newargument = malloc(sizeof(argument_t));
 
       newargument->argc = argument->argc + 1;
-      newargument->argv = (char **) malloc(newargument->argc*sizeof(char *));
+      newargument->argv = malloc(newargument->argc*sizeof(char *));
       memcpy(newargument->argv, argument->argv, argument->argc*sizeof(char *));
 
       operatorArg  = argument->argv[0];
       operatorName = getOperatorName(operatorArg);
 
       len = strlen(argument->args);
-      newarg = (char *) malloc(len+16);
+      newarg = malloc(len+16);
       strcpy(newarg, argument->args);
       sprintf(pipename, "(pipe%d.%d)", processSelf() + 1, processInqChildNum() + 1);
       newarg[len] = ' ';
@@ -455,7 +455,7 @@ int pstreamOpenRead(const argument_t *argument)
 		  if ( nfiles == 0 ) cdoAbort("No imput file found in %s", pch);
 
 		  pstreamptr->mfiles = nfiles;
-		  pstreamptr->mfnames = (char **) malloc(nfiles*sizeof(char *));
+		  pstreamptr->mfnames = malloc(nfiles*sizeof(char *));
 		  
 		  rewind(fp);
 
@@ -476,7 +476,7 @@ int pstreamOpenRead(const argument_t *argument)
 		  char line[65536];
 
 		  pstreamptr->mfiles = nfiles;
-		  pstreamptr->mfnames = (char **) malloc(nfiles*sizeof(char *));
+		  pstreamptr->mfnames = malloc(nfiles*sizeof(char *));
 		  
 		  strcpy(line, pch);
 		  for ( i = 0; i < len; i++ ) if ( line[i] == ',' ) line[i] = 0;
@@ -513,7 +513,7 @@ int pstreamOpenRead(const argument_t *argument)
 	      pclose(pfp);
 
 	      pstreamptr->mfiles = nfiles;
-	      pstreamptr->mfnames = (char **) malloc(nfiles*sizeof(char *));
+	      pstreamptr->mfnames = malloc(nfiles*sizeof(char *));
 
 	      for ( j = 0; j < nfiles; j++ )
 		pstreamptr->mfnames[j] = fnames[j];
@@ -523,14 +523,14 @@ int pstreamOpenRead(const argument_t *argument)
       if ( pstreamptr->mfiles )
 	{
 	  len = strlen(pstreamptr->mfnames[0]);
-	  filename = (char *) malloc(len+1);
+	  filename = malloc(len+1);
 	  strcpy(filename, pstreamptr->mfnames[0]);
 	  pstreamptr->nfiles = 1;
 	}
       else
 	{
 	  len = strlen(argument->args);
-	  filename = (char *) malloc(len+1);
+	  filename = malloc(len+1);
 	  strcpy(filename, argument->args);
 	}
 
@@ -656,7 +656,7 @@ int pstreamOpenWrite(const argument_t *argument, int filetype)
   else
     {
       /* extern int cdoDefaultInstID; */
-      char *filename = (char *) malloc(strlen(argument->args)+1);
+      char *filename = malloc(strlen(argument->args)+1);
 
       pstreamptr = pstream_new_entry();
       if ( ! pstreamptr ) Error("No memory");
@@ -759,7 +759,7 @@ int pstreamOpenAppend(const argument_t *argument)
     }
   else
     {
-      char *filename = (char *) malloc(strlen(argument->args)+1);
+      char *filename = malloc(strlen(argument->args)+1);
 
       pstreamptr = pstream_new_entry();
       if ( ! pstreamptr ) Error("No memory");
@@ -1008,7 +1008,7 @@ void pstreamDefVarlist(pstream_t *pstreamptr, int vlistID)
     cdoAbort("Internal problem, varlist already allocated!");
 
   nvars = vlistNvars(vlistID);
-  varlist = (varlist_t *) malloc(nvars*sizeof(varlist_t));
+  varlist = malloc(nvars*sizeof(varlist_t));
 
   for ( varID = 0; varID < nvars; ++varID )
     {
@@ -1383,7 +1383,7 @@ int pstreamInqTimestep(int pstreamID, int tsID)
 	  streamClose(pstreamptr->fileID);
 
 	  len = strlen(pstreamptr->mfnames[nfile]);
-	  filename = (char *) malloc(len+1);
+	  filename = malloc(len+1);
 	  strcpy(filename, pstreamptr->mfnames[nfile]);
 	  pstreamptr->nfiles++;
 
@@ -1706,6 +1706,15 @@ int pstreamInqByteorder(int pstreamID)
   return (byteorder);
 }
 
+void pstreamInqGinfo(int pstreamID, int *intnum, float *fltnum, off_t *bignum)
+{
+  pstream_t *pstreamptr;
+
+  pstreamptr = pstream_to_pointer(pstreamID);
+
+  streamInqGinfo(pstreamptr->fileID, intnum, fltnum, bignum);
+}
+
 
 void openLock(void)
 {
diff --git a/src/pstream.h b/src/pstream.h
index e9eead6..3842518 100644
--- a/src/pstream.h
+++ b/src/pstream.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -41,6 +41,8 @@
 
 #define  streamCopyRecord         pstreamCopyRecord
 
+#define  streamInqGinfo           pstreamInqGinfo
+
 
 int     pstreamOpenWrite(const argument_t *argument, int filetype);
 int     pstreamOpenRead(const argument_t *argument);
@@ -64,4 +66,7 @@ void    pstreamWriteRecordF(int pstreamID, float *data, int nmiss);
 void    pstreamReadRecord(int pstreamID, double *data, int *nmiss);
 void    pstreamCopyRecord(int pstreamIDdest, int pstreamIDsrc);
 
+void    pstreamInqGinfo(int pstreamID, int *intnum, float *fltnum, off_t *bignum);
+
+
 #endif  /* _PSTREAM_H */
diff --git a/src/pstream_int.h b/src/pstream_int.h
index 90d5e95..d623ad4 100644
--- a/src/pstream_int.h
+++ b/src/pstream_int.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/readline.c b/src/readline.c
index c2768c1..ed0f4bd 100644
--- a/src/readline.c
+++ b/src/readline.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/remap.h b/src/remap.h
index fd411f3..db37303 100644
--- a/src/remap.h
+++ b/src/remap.h
@@ -2,6 +2,15 @@
 #include <omp.h>
 #endif
 
+#include <math.h>
+
+#define  PI       M_PI
+#define  PI2      2.0*PI
+#define  PIH      0.5*PI
+
+#define  REMAP_GRID_BASIS_SRC  1
+#define  REMAP_GRID_BASIS_TGT  2
+
 #define  RESTR_TYPE  int  /* restrict data types: 0 -> double, float; 1 -> int */
 
 typedef RESTR_TYPE restr_t;
@@ -14,7 +23,12 @@ typedef RESTR_TYPE restr_t;
 #  define RESTR_ABS(x)   fabs(x)
 #endif
 */
-
+/* short
+#  define RESTR_SFAC     4000
+#  define RESTR_SCALE(x) ((short) (0.5+RESTR_SFAC*(x)))
+#  define RESTR_ABS(x)   abs(x)
+*/
+/* int */
 #  define RESTR_SFAC     100000000
 #  define RESTR_SCALE(x) ((int) (0.5+RESTR_SFAC*(x)))
 #  define RESTR_ABS(x)   abs(x)
@@ -34,122 +48,112 @@ typedef RESTR_TYPE restr_t;
 #define  MAP_TYPE_BILINEAR  2
 #define  MAP_TYPE_BICUBIC   3
 #define  MAP_TYPE_DISTWGT   4
-#define  MAP_TYPE_DISTWGT1  5
+#define  MAP_TYPE_CONSPHERE 5
 
 #define  SUBMAP_TYPE_NONE   0
 #define  SUBMAP_TYPE_LAF    1
 #define  SUBMAP_TYPE_SUM    2
 
-#define  RESTRICT_LATITUDE  1
-#define  RESTRICT_LATLON    2
-
 
 typedef struct {
-  int      pinit;            /* TRUE if the pointers are initialized     */
-  int      gridID1;
-  int      gridID2;
+  int      lwrite_remap;
+  int      gridID;
   int      store_link_fast;
+  int      remap_grid_type;
   int      lextrapolate;
   int      non_global;
-  int      grid1_is_cyclic, grid2_is_cyclic;
-  long     grid1_size, grid2_size; /* total points on each grid */
-  int      grid1_rank, grid2_rank; /* rank of each grid */
-  long     grid1_corners, grid2_corners; /* number of corners for each grid cell */
-
-  int      grid1_dims[2], grid2_dims[2]; /* size of each grid dimension */
-
-  int      grid1_nvgp;         /* size of grid1_vgpm           */
-  int     *grid1_vgpm;         /* flag which cells are valid   */
-
-  int      grid2_nvgp;         /* size of grid2_vgpm           */
-  int     *grid2_vgpm;         /* flag which cells are valid   */
-
-  int     *grid1_mask;         /* flag which cells participate */
-  int     *grid2_mask;         /* flag which cells participate */
-
-  double  *grid1_center_lat;   /* lat/lon coordinates for      */
-  double  *grid1_center_lon;   /* each grid center in radians  */
-  double  *grid2_center_lat; 
-  double  *grid2_center_lon;
-  double  *grid1_area;         /* tot area of each grid1 cell     */
-  double  *grid2_area;         /* tot area of each grid2 cell     */
-  /* double  *grid1_area_in; */     /* area of grid1 cell from file    */
-  /* double  *grid2_area_in; */     /* area of grid2 cell from file    */
-  double  *grid1_frac;         /* fractional area of grid cells   */
-  double  *grid2_frac;         /* participating in remapping      */
-
-  double  *grid1_corner_lat;   /* lat/lon coordinates for         */
-  double  *grid1_corner_lon;   /* each grid corner in radians     */
-  double  *grid2_corner_lat; 
-  double  *grid2_corner_lon;
-
-  int      lneed_grid1_corners;
-  int      lneed_grid2_corners;
-  int      luse_grid1_corners;  /* use corners for bounding boxes  */
-  int      luse_grid2_corners;  /* use corners for bounding boxes  */
-  /* int      luse_grid1_area;   */ /* use area from grid file         */
-  /* int      luse_grid2_area;   */ /* use area from grid file         */
-
-  restr_t *grid1_bound_box;    /* lat/lon bounding box for use    */
-  restr_t *grid2_bound_box;    /* in restricting grid searches    */
-
-  double   threshhold;         /* threshold for coord transformation */
-  int      restrict_type;
-  int      num_srch_bins;      /* num of bins for restricted srch */
-
-  int     *bin_addr1;       /* min,max adds for grid1 cells in this lat bin  */
-  int     *bin_addr2;       /* min,max adds for grid2 cells in this lat bin  */
-
-  restr_t *bin_lats;        /* min,max latitude for each search bin   */
-  restr_t *bin_lons;        /* min,max longitude for each search bin  */
+  int      is_cyclic;
+  int      rank;                  /* rank of the grid */
+  long     size;                  /* total points on the grid */
+  long     num_cell_corners;      /* number of corners for each grid cell */
+
+  int      dims[2];               /* size of grid dimension */
+
+  int      nvgp;                  /* size of vgpm           */
+  int*     vgpm;                  /* flag which cells are valid   */
+
+  int*     mask;                  /* flag which cells participate */
+
+  double*  reg2d_center_lon;      /* reg2d lon/lat coordinates for */
+  double*  reg2d_center_lat;      /* each grid center in radians   */
+  double*  reg2d_corner_lon;      /* reg2d lon/lat coordinates for */
+  double*  reg2d_corner_lat;      /* each grid corner in radians   */
+
+  double*  cell_center_lon;       /* lon/lat coordinates for       */
+  double*  cell_center_lat;       /* each grid center in radians   */
+  double*  cell_corner_lon;       /* lon/lat coordinates for         */
+  double*  cell_corner_lat;       /* each grid corner in radians     */
+
+  double*  cell_area;             /* tot area of each grid cell     */
+  double*  cell_frac;             /* fractional area of grid cells participating in remapping  */
+
+  int      lneed_cell_corners;
+  int      luse_cell_corners;     /* use corners for bounding boxes  */
+
+  restr_t *cell_bound_box;        /* lon/lat bounding box for use    */
+
+  int      num_srch_bins;         /* num of bins for restricted srch */
+
+  int*     bin_addr;              /* min,max adds for grid cells in this lat bin  */
+
+  restr_t* bin_lats;              /* min,max latitude for each search bin   */
 }
 remapgrid_t;
 
 typedef struct {
-  int   option;
-  int   max_links;
-  int   num_blks;
-  int  *num_links;
-  int **src_add;
-  int **dst_add;
-  int **w_index;
+  int      option;
+  int      max_links;
+  int      num_blks;
+  int*     num_links;
+  int**    src_add;
+  int**    dst_add;
+  int**    w_index;
 }
 remaplink_t;
 
 typedef struct {
-  int   pinit;            /* TRUE if the pointers are initialized     */
-  long  max_links;        /* current size of link arrays              */
-  long  num_links;        /* actual number of links for remapping     */
-  long  num_wts;          /* num of weights used in remapping         */
-  int   map_type;         /* identifier for remapping method          */
-  int   norm_opt;         /* option for normalization (conserv only)  */
-  int   resize_increment; /* default amount to increase array size    */
+  int      sort_add;
+  int      pinit;            /* TRUE if the pointers are initialized     */
+  long     max_links;        /* current size of link arrays              */
+  long     num_links;        /* actual number of links for remapping     */
+  long     num_wts;          /* num of weights used in remapping         */
+  int      map_type;         /* identifier for remapping method          */
+  int      norm_opt;         /* option for normalization (conserv only)  */
+  int      resize_increment; /* default amount to increase array size    */
 
-  int  *grid1_add;        /* grid1 address for each link              */
-  int  *grid2_add;        /* grid2 address for each link              */
+  int*     src_grid_add;     /* source grid address for each link        */
+  int*     tgt_grid_add;     /* target grid address for each link        */
 
-  double *wts;            /* map weights for each link [max_links*num_wts] */
+  double*  wts;              /* map weights for each link [max_links*num_wts] */
 
-  remaplink_t  links;
+  remaplink_t links;
 }
 remapvars_t;
 
 typedef struct {
-  int gridID;
-  int gridsize;
-  int nmiss;
-  remapgrid_t grid;
+  int      gridID;
+  int      gridsize;
+  int      nmiss;
+  remapgrid_t src_grid;
+  remapgrid_t tgt_grid;
   remapvars_t vars;
 }
 remap_t;
 
-void remap_set_max_iter(long max_iter);
+#define  REMAP_STORE_LINK_FAST  1
+#define  REMAP_WRITE_REMAP      2
+#define  REMAP_MAX_ITER         3
+#define  REMAP_NUM_SRCH_BINS    4
+
+void remap_set_threshhold(double threshhold);
+void remap_set_int(int remapvar, int value);
 
-void remapGridInit(int map_type, int lextrapolate, int gridID1, int gridID2, remapgrid_t *rg);
-void remapVarsInit(int map_type, remapgrid_t *rg, remapvars_t *rv);
+
+void remap_grids_init(int map_type, int lextrapolate, int gridID1, remapgrid_t *src_grid, int gridID2, remapgrid_t *tgt_grid);
+void remap_vars_init(int map_type, long src_grid_size, long tgt_grid_size, remapvars_t *rv);
 
 void remapVarsFree(remapvars_t *rv);
-void remapGridFree(remapgrid_t *rg);
+void remapGridFree(remapgrid_t *grid);
 
 void remap(double *restrict dst_array, double missval, long dst_size, long num_links, double *restrict map_wts, 
 	   long num_wts, const int *restrict dst_add, const int *restrict src_add, const double *restrict src_array, 
@@ -162,27 +166,31 @@ void remap_laf(double *restrict dst_array, double missval, long dst_size, long n
 void remap_sum(double *restrict dst_array, double missval, long dst_size, long num_links, double *restrict map_wts,
 	       long num_wts, const int *restrict dst_add, const int *restrict src_add, const double *restrict src_array);
 
-void remap_bilin(remapgrid_t *rg, remapvars_t *rv);
-void remap_bicub(remapgrid_t *rg, remapvars_t *rv);
-void remap_conserv(remapgrid_t *rg, remapvars_t *rv);
-void remap_distwgt(remapgrid_t *rg, remapvars_t *rv);
-void remap_distwgt1(remapgrid_t *rg, remapvars_t *rv);
+void remap_bilin(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
+void remap_bicub(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
+void remap_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
+void remap_consphere(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
+void remap_distwgt(int num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
 
 void resize_remap_vars(remapvars_t *rv, int increment);
 
-void remap_stat(int remap_order, remapgrid_t rg, remapvars_t rv, const double *restrict array1, 
+void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, remapvars_t rv, const double *restrict array1, 
 		const double *restrict array2, double missval);
-void remap_gradients(remapgrid_t rg, const double *restrict array, double *restrict grad1_lat,
-		     double *restrict grad1_lon, double *restrict grad1_latlon);
+void remap_gradients(remapgrid_t grid, const double *restrict array, double *restrict grad_lat,
+		     double *restrict grad_lon, double *restrict grad_latlon);
 
 void reorder_links(remapvars_t *rv);
 
 void sort_add(long num_links, long num_wts, int *restrict add1, int *restrict add2, double *restrict weights);
 void sort_iter(long num_links, long num_wts, int *restrict add1, int *restrict add2, double *restrict weights, int parent);
 
-void write_remap_scrip(const char *interp_file, int map_type, int submap_type, 
-		       int remap_order, remapgrid_t rg, remapvars_t rv);
-void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *map_type, int *submap_type,
-		      int *remap_order, remapgrid_t *rg, remapvars_t *rv);
+void write_remap_scrip(const char *interp_file, int map_type, int submap_type, int num_neighbors,
+		       int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, remapvars_t rv);
+void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *map_type, int *submap_type, int *num_neighbors,
+		      int *remap_order, remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv);
+
+void store_link_bilin(remapvars_t *rv, int dst_add, int *restrict src_add, double *restrict weights);
+
 
-void store_link_bilin(remapvars_t *rv, int dst_add, const int *restrict src_add, const double *restrict weights);
+void calc_bin_addr(long gridsize, long nbins, const restr_t* restrict bin_lats, const restr_t* restrict cell_bound_box, int* restrict bin_addr);
+void calc_lat_bins(remapgrid_t* src_grid, remapgrid_t* tgt_grid, int map_type);
diff --git a/src/remap_scrip_io.c b/src/remap_scrip_io.c
index 5a50d9b..ae072b9 100644
--- a/src/remap_scrip_io.c
+++ b/src/remap_scrip_io.c
@@ -15,8 +15,8 @@
 #include "remap.h"
 
 
-void remapGridInitPointer(remapgrid_t *rg);
-void remapGridRealloc(int map_type, remapgrid_t *rg);
+void remapgrid_init(remapgrid_t *grid);
+void remapGridRealloc(int map_type, remapgrid_t *grid);
 
 
 #if defined(HAVE_LIBNETCDF)
@@ -32,8 +32,8 @@ void nce(int istat)
 #endif
 
 
-void write_remap_scrip(const char *interp_file, int map_type, int submap_type, 
-		       int remap_order, remapgrid_t rg, remapvars_t rv)
+void write_remap_scrip(const char *interp_file, int map_type, int submap_type, int num_neighbors,
+		       int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, remapvars_t rv)
 {
   /*
     Writes remap data to a netCDF file using SCRIP conventions
@@ -84,10 +84,10 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type,
   char map_method[64] = "unknown";
   char tmp_string[64] = "unknown";
   char history[1024] = "date and time";
-  char grid1_name[64] = "source grid";
-  char grid2_name[64] = "dest grid";
-  char *grid1_units = "radians";
-  char *grid2_units = "radians";
+  char src_grid_name[64] = "source grid";
+  char tgt_grid_name[64] = "dest grid";
+  char *src_grid_units = "radians";
+  char *tgt_grid_units = "radians";
   time_t date_and_time_in_sec;
   struct tm *date_and_time;
   long i;
@@ -121,6 +121,20 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type,
 	  strcpy(map_method, "Conservative remapping");
 	  break;
 	}
+    case MAP_TYPE_CONSPHERE:
+      lgridarea = TRUE;
+      /*
+      if ( submap_type == SUBMAP_TYPE_LAF )
+	{
+	  strcpy(map_method, "Largest area fraction");
+	  break;
+	}
+      else
+      */
+	{
+	  strcpy(map_method, "Conservative remapping using clipping on sphere");
+	  break;
+	}
     case MAP_TYPE_BILINEAR:
       strcpy(map_method, "Bilinear remapping");
       break;
@@ -128,23 +142,26 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type,
       strcpy(map_method, "Bicubic remapping");
       break;
     case MAP_TYPE_DISTWGT:
-      strcpy(map_method, "Distance weighted avg of nearest neighbors");
-      break;
-    case MAP_TYPE_DISTWGT1:
-      strcpy(map_method, "Nearest neighbor");
+      if ( num_neighbors == 1 )
+	strcpy(map_method, "Nearest neighbor");
+      else
+	strcpy(map_method, "Distance weighted avg of nearest neighbors");
       break;
     }
 
+  if ( rv.num_links == 0 )
+    cdoAbort("Number of remap links is 0, no remap weights found!");
+
   {
     size_t filesize;
     size_t nele1, nele2;
 
     nele1 = 4*8 + 4;
     nele2 = 4*8 + 4;
-    if ( rg.lneed_grid1_corners ) nele1 += rg.grid1_corners*2*8;
-    if ( rg.lneed_grid2_corners ) nele2 += rg.grid2_corners*2*8;
-    filesize = rg.grid1_size*(nele1) +
-               rg.grid2_size*(nele2) +
+    if ( src_grid.lneed_cell_corners ) nele1 += src_grid.num_cell_corners*2*8;
+    if ( tgt_grid.lneed_cell_corners ) nele2 += tgt_grid.num_cell_corners*2*8;
+    filesize = src_grid.size*(nele1) +
+               tgt_grid.size*(nele2) +
                rv.num_links*(4 + 4 + rv.num_wts*8);
 
     if ( cdoVerbose )
@@ -193,27 +210,27 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type,
   nce(nc_put_att_text(nc_file_id, NC_GLOBAL, "conventions", strlen(tmp_string), tmp_string));
 
   /* Source and destination grid names */
-  gridName(gridInqType(rg.gridID1), grid1_name);
-  nce(nc_put_att_text(nc_file_id, NC_GLOBAL, "source_grid", strlen(grid1_name), grid1_name));
+  gridName(gridInqType(src_grid.gridID), src_grid_name);
+  nce(nc_put_att_text(nc_file_id, NC_GLOBAL, "source_grid", strlen(src_grid_name), src_grid_name));
 
-  gridName(gridInqType(rg.gridID2), grid2_name);
-  nce(nc_put_att_text(nc_file_id, NC_GLOBAL, "dest_grid", strlen(grid2_name), grid2_name));
+  gridName(gridInqType(tgt_grid.gridID), tgt_grid_name);
+  nce(nc_put_att_text(nc_file_id, NC_GLOBAL, "dest_grid", strlen(tgt_grid_name), tgt_grid_name));
 
   /* Prepare netCDF dimension info */
 
   /* Define grid size dimensions */
-  nce(nc_def_dim(nc_file_id, "src_grid_size", rg.grid1_size, &nc_srcgrdsize_id));
-  nce(nc_def_dim(nc_file_id, "dst_grid_size", rg.grid2_size, &nc_dstgrdsize_id));
+  nce(nc_def_dim(nc_file_id, "src_grid_size", src_grid.size, &nc_srcgrdsize_id));
+  nce(nc_def_dim(nc_file_id, "dst_grid_size", tgt_grid.size, &nc_dstgrdsize_id));
 
   /* Define grid corner dimension */
-  if ( rg.lneed_grid1_corners )
-    nce(nc_def_dim(nc_file_id, "src_grid_corners", rg.grid1_corners, &nc_srcgrdcorn_id));
-  if ( rg.lneed_grid2_corners )
-    nce(nc_def_dim(nc_file_id, "dst_grid_corners", rg.grid2_corners, &nc_dstgrdcorn_id));
+  if ( src_grid.lneed_cell_corners )
+    nce(nc_def_dim(nc_file_id, "src_grid_corners", src_grid.num_cell_corners, &nc_srcgrdcorn_id));
+  if ( tgt_grid.lneed_cell_corners )
+    nce(nc_def_dim(nc_file_id, "dst_grid_corners", tgt_grid.num_cell_corners, &nc_dstgrdcorn_id));
 
   /* Define grid rank dimension */
-  nce(nc_def_dim(nc_file_id, "src_grid_rank", rg.grid1_rank, &nc_srcgrdrank_id));
-  nce(nc_def_dim(nc_file_id, "dst_grid_rank", rg.grid2_rank, &nc_dstgrdrank_id));
+  nce(nc_def_dim(nc_file_id, "src_grid_rank", src_grid.rank, &nc_srcgrdrank_id));
+  nce(nc_def_dim(nc_file_id, "dst_grid_rank", tgt_grid.rank, &nc_dstgrdrank_id));
 
   /* Define map size dimensions */
   nce(nc_def_dim(nc_file_id, "num_links", rv.num_links, &nc_numlinks_id));
@@ -238,7 +255,7 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type,
   nc_dims2_id[0] = nc_srcgrdsize_id;
   nc_dims2_id[1] = nc_srcgrdcorn_id;
 
-  if ( rg.lneed_grid1_corners )
+  if ( src_grid.lneed_cell_corners )
     {
       nce(nc_def_var(nc_file_id, "src_grid_corner_lat", NC_DOUBLE, 2, nc_dims2_id, &nc_srcgrdcrnrlat_id));
       nce(nc_def_var(nc_file_id, "src_grid_corner_lon", NC_DOUBLE, 2, nc_dims2_id, &nc_srcgrdcrnrlon_id));
@@ -247,26 +264,26 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type,
   nc_dims2_id[0] = nc_dstgrdsize_id;
   nc_dims2_id[1] = nc_dstgrdcorn_id;
 
-  if ( rg.lneed_grid2_corners )
+  if ( tgt_grid.lneed_cell_corners )
     {
       nce(nc_def_var(nc_file_id, "dst_grid_corner_lat", NC_DOUBLE, 2, nc_dims2_id, &nc_dstgrdcrnrlat_id));
       nce(nc_def_var(nc_file_id, "dst_grid_corner_lon", NC_DOUBLE, 2, nc_dims2_id, &nc_dstgrdcrnrlon_id));
     }
 
   /* Define units for all coordinate arrays */
-  nce(nc_put_att_text(nc_file_id, nc_srcgrdcntrlat_id, "units", strlen(grid1_units), grid1_units));
-  nce(nc_put_att_text(nc_file_id, nc_dstgrdcntrlat_id, "units", strlen(grid2_units), grid2_units));
-  nce(nc_put_att_text(nc_file_id, nc_srcgrdcntrlon_id, "units", strlen(grid1_units), grid1_units));
-  nce(nc_put_att_text(nc_file_id, nc_dstgrdcntrlon_id, "units", strlen(grid2_units), grid2_units));
-  if ( rg.lneed_grid1_corners )
+  nce(nc_put_att_text(nc_file_id, nc_srcgrdcntrlat_id, "units", strlen(src_grid_units), src_grid_units));
+  nce(nc_put_att_text(nc_file_id, nc_dstgrdcntrlat_id, "units", strlen(tgt_grid_units), tgt_grid_units));
+  nce(nc_put_att_text(nc_file_id, nc_srcgrdcntrlon_id, "units", strlen(src_grid_units), src_grid_units));
+  nce(nc_put_att_text(nc_file_id, nc_dstgrdcntrlon_id, "units", strlen(tgt_grid_units), tgt_grid_units));
+  if ( src_grid.lneed_cell_corners )
     {
-      nce(nc_put_att_text(nc_file_id, nc_srcgrdcrnrlat_id, "units", strlen(grid1_units), grid1_units));
-      nce(nc_put_att_text(nc_file_id, nc_srcgrdcrnrlon_id, "units", strlen(grid1_units), grid1_units));
+      nce(nc_put_att_text(nc_file_id, nc_srcgrdcrnrlat_id, "units", strlen(src_grid_units), src_grid_units));
+      nce(nc_put_att_text(nc_file_id, nc_srcgrdcrnrlon_id, "units", strlen(src_grid_units), src_grid_units));
     }
-  if ( rg.lneed_grid2_corners )
+  if ( tgt_grid.lneed_cell_corners )
     {
-      nce(nc_put_att_text(nc_file_id, nc_dstgrdcrnrlat_id, "units", strlen(grid2_units), grid2_units));
-      nce(nc_put_att_text(nc_file_id, nc_dstgrdcrnrlon_id, "units", strlen(grid2_units), grid2_units));
+      nce(nc_put_att_text(nc_file_id, nc_dstgrdcrnrlat_id, "units", strlen(tgt_grid_units), tgt_grid_units));
+      nce(nc_put_att_text(nc_file_id, nc_dstgrdcrnrlon_id, "units", strlen(tgt_grid_units), tgt_grid_units));
     }
 
   /* Define grid mask */
@@ -313,57 +330,53 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type,
 
   /* Write mapping data */
 
-  nce(nc_put_var_int(nc_file_id, nc_srcgrddims_id, rg.grid1_dims));
-  nce(nc_put_var_int(nc_file_id, nc_dstgrddims_id, rg.grid2_dims));
+  nce(nc_put_var_int(nc_file_id, nc_srcgrddims_id, src_grid.dims));
+  nce(nc_put_var_int(nc_file_id, nc_dstgrddims_id, tgt_grid.dims));
 
-  nce(nc_put_var_int(nc_file_id, nc_srcgrdimask_id, rg.grid1_mask));
-  nce(nc_put_var_int(nc_file_id, nc_dstgrdimask_id, rg.grid2_mask));
+  nce(nc_put_var_int(nc_file_id, nc_srcgrdimask_id, src_grid.mask));
+  nce(nc_put_var_int(nc_file_id, nc_dstgrdimask_id, tgt_grid.mask));
 
-  nce(nc_put_var_double(nc_file_id, nc_srcgrdcntrlat_id, rg.grid1_center_lat)); 
-  nce(nc_put_var_double(nc_file_id, nc_srcgrdcntrlon_id, rg.grid1_center_lon));
+  if ( src_grid.cell_center_lat ) nce(nc_put_var_double(nc_file_id, nc_srcgrdcntrlat_id, src_grid.cell_center_lat)); 
+  if ( src_grid.cell_center_lon ) nce(nc_put_var_double(nc_file_id, nc_srcgrdcntrlon_id, src_grid.cell_center_lon));
 
-  if ( rg.lneed_grid1_corners )
+  if ( src_grid.lneed_cell_corners )
     {
-      nce(nc_put_var_double(nc_file_id, nc_srcgrdcrnrlat_id, rg.grid1_corner_lat));
-      nce(nc_put_var_double(nc_file_id, nc_srcgrdcrnrlon_id, rg.grid1_corner_lon));
+      nce(nc_put_var_double(nc_file_id, nc_srcgrdcrnrlat_id, src_grid.cell_corner_lat));
+      nce(nc_put_var_double(nc_file_id, nc_srcgrdcrnrlon_id, src_grid.cell_corner_lon));
     }
 
-  nce(nc_put_var_double(nc_file_id, nc_dstgrdcntrlat_id, rg.grid2_center_lat));
-  nce(nc_put_var_double(nc_file_id, nc_dstgrdcntrlon_id, rg.grid2_center_lon));
+  if ( tgt_grid.cell_center_lat ) nce(nc_put_var_double(nc_file_id, nc_dstgrdcntrlat_id, tgt_grid.cell_center_lat));
+  if ( tgt_grid.cell_center_lon ) nce(nc_put_var_double(nc_file_id, nc_dstgrdcntrlon_id, tgt_grid.cell_center_lon));
 
-  if ( rg.lneed_grid2_corners )
+  if ( tgt_grid.lneed_cell_corners )
     {
-      nce(nc_put_var_double(nc_file_id, nc_dstgrdcrnrlat_id, rg.grid2_corner_lat));
-      nce(nc_put_var_double(nc_file_id, nc_dstgrdcrnrlon_id, rg.grid2_corner_lon));
+      nce(nc_put_var_double(nc_file_id, nc_dstgrdcrnrlat_id, tgt_grid.cell_corner_lat));
+      nce(nc_put_var_double(nc_file_id, nc_dstgrdcrnrlon_id, tgt_grid.cell_corner_lon));
     }
-  /*
-  if ( luse_grid1_area )
-    nce(nc_put_var_double(nc_file_id, nc_srcgrdarea_id, rg.grid1_area_in));
-  else
-  */
+
   if ( lgridarea )
-    nce(nc_put_var_double(nc_file_id, nc_srcgrdarea_id, rg.grid1_area));
+    nce(nc_put_var_double(nc_file_id, nc_srcgrdarea_id, src_grid.cell_area));
 
-  nce(nc_put_var_double(nc_file_id, nc_srcgrdfrac_id, rg.grid1_frac));
+  nce(nc_put_var_double(nc_file_id, nc_srcgrdfrac_id, src_grid.cell_frac));
 
   /*
-  if ( luse_grid2_area )
-    nce(nc_put_var_double(nc_file_id, nc_dstgrdarea_id, rg.grid2_area_in));
+  if ( luse_cell_area )
+    nce(nc_put_var_double(nc_file_id, nc_dstgrdarea_id, tgt_grid.cell_area_in));
   else
   */
   if ( lgridarea )
-    nce(nc_put_var_double(nc_file_id, nc_dstgrdarea_id, rg.grid2_area));
+    nce(nc_put_var_double(nc_file_id, nc_dstgrdarea_id, tgt_grid.cell_area));
 
-  nce(nc_put_var_double(nc_file_id, nc_dstgrdfrac_id, rg.grid2_frac));
+  nce(nc_put_var_double(nc_file_id, nc_dstgrdfrac_id, tgt_grid.cell_frac));
 
   for ( i = 0; i < rv.num_links; i++ )
     {
-      rv.grid1_add[i]++;
-      rv.grid2_add[i]++;
+      rv.src_grid_add[i]++;
+      rv.tgt_grid_add[i]++;
     }
 
-  nce(nc_put_var_int(nc_file_id, nc_srcadd_id, rv.grid1_add));
-  nce(nc_put_var_int(nc_file_id, nc_dstadd_id, rv.grid2_add));
+  nce(nc_put_var_int(nc_file_id, nc_srcadd_id, rv.src_grid_add));
+  nce(nc_put_var_int(nc_file_id, nc_dstadd_id, rv.tgt_grid_add));
 
   nce(nc_put_var_double(nc_file_id, nc_rmpmatrix_id, rv.wts));
 
@@ -377,8 +390,8 @@ void write_remap_scrip(const char *interp_file, int map_type, int submap_type,
 
 /*****************************************************************************/
 
-void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *map_type, int *submap_type,
-		      int *remap_order, remapgrid_t *rg, remapvars_t *rv)
+void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *map_type, int *submap_type, int *num_neighbors,
+		      int *remap_order, remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
 {
   /*
     The routine reads a netCDF file to extract remapping info in SCRIP format
@@ -429,10 +442,10 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
   char map_method[64];      /* character string for map_type             */
   char normalize_opt[64];   /* character string for normalization option */
   char convention[64];      /* character string for output convention    */
-  char grid1_name[64];      /* grid name for source grid                 */
-  char grid2_name[64];      /* grid name for dest   grid                 */
-  char grid1_units[64];
-  char grid2_units[64];
+  char src_grid_name[64];      /* grid name for source grid                 */
+  char tgt_grid_name[64];      /* grid name for dest   grid                 */
+  char src_grid_units[64];
+  char tgt_grid_units[64];
   size_t attlen, dimlen;
 
   int gridID1_gme_c = -1;
@@ -488,14 +501,26 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
   if ( memcmp(map_method, "Conservative", 12) == 0 )
     {
       int iatt;
-      rv->map_type = MAP_TYPE_CONSERV;
+      if ( memcmp(map_method, "Conservative remapping using clipping on sphere", 47) == 0 )
+	rv->map_type = MAP_TYPE_CONSPHERE;
+      else
+	rv->map_type = MAP_TYPE_CONSERV;
+
       status = nc_get_att_int(nc_file_id, NC_GLOBAL, "remap_order", &iatt);
       if ( status == NC_NOERR ) *remap_order = iatt;
     }
   else if ( memcmp(map_method, "Bilinear", 8) == 0 ) rv->map_type = MAP_TYPE_BILINEAR;
   else if ( memcmp(map_method, "Bicubic",  7) == 0 ) rv->map_type = MAP_TYPE_BICUBIC;
-  else if ( memcmp(map_method, "Distance", 8) == 0 ) rv->map_type = MAP_TYPE_DISTWGT;
-  else if ( memcmp(map_method, "Nearest",  7) == 0 ) rv->map_type = MAP_TYPE_DISTWGT1;
+  else if ( memcmp(map_method, "Distance", 8) == 0 )
+    {
+      rv->map_type = MAP_TYPE_DISTWGT;
+      *num_neighbors = 4;
+    }
+  else if ( memcmp(map_method, "Nearest",  7) == 0 )
+    {
+      rv->map_type = MAP_TYPE_DISTWGT;
+      *num_neighbors = 1;
+    }
   else if ( memcmp(map_method, "Largest",  7) == 0 )
     {
       rv->map_type = MAP_TYPE_CONSERV;
@@ -533,103 +558,101 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
 
   /* Source and destination grid names */
 
-  nce(nc_get_att_text (nc_file_id, NC_GLOBAL, "source_grid", grid1_name));
+  nce(nc_get_att_text (nc_file_id, NC_GLOBAL, "source_grid", src_grid_name));
   nce(nc_inq_attlen(nc_file_id, NC_GLOBAL, "source_grid", &attlen));
-  grid1_name[attlen] = 0;
+  src_grid_name[attlen] = 0;
   
-  nce(nc_get_att_text (nc_file_id, NC_GLOBAL, "dest_grid", grid2_name));
+  nce(nc_get_att_text (nc_file_id, NC_GLOBAL, "dest_grid", tgt_grid_name));
   nce(nc_inq_attlen(nc_file_id, NC_GLOBAL, "dest_grid", &attlen));
-  grid2_name[attlen] = 0;
+  tgt_grid_name[attlen] = 0;
  
   if ( cdoVerbose )
-    cdoPrint("Remapping between: %s and %s", grid1_name, grid2_name);
+    cdoPrint("Remapping between: %s and %s", src_grid_name, tgt_grid_name);
+
+  /* Initialize remapgrid structure */
+  remapgrid_init(src_grid);
+  remapgrid_init(tgt_grid);
 
   /* Read dimension information */
 
   nce(nc_inq_dimid(nc_file_id, "src_grid_size", &nc_srcgrdsize_id));
   nce(nc_inq_dimlen(nc_file_id, nc_srcgrdsize_id, &dimlen));
-  rg->grid1_size = dimlen;
+  src_grid->size = dimlen;
   /*
-  if (  rg->grid1_size != gridInqSize(gridID1) )
+  if (  src_grid->size != gridInqSize(gridID1) )
     cdoAbort("Source grids have different size!");
   */
   nce(nc_inq_dimid(nc_file_id, "dst_grid_size", &nc_dstgrdsize_id));
   nce(nc_inq_dimlen(nc_file_id, nc_dstgrdsize_id, &dimlen));
-  rg->grid2_size = dimlen;
+  tgt_grid->size = dimlen;
   /*
-  if ( rg->grid2_size != gridInqSize(gridID2) )
+  if ( tgt_grid->size != gridInqSize(gridID2) )
     cdoAbort("Target grids have different size!");
   */
-  rg->grid1_corners = 0;
-  rg->luse_grid1_corners = FALSE;
-  rg->lneed_grid1_corners = FALSE;
   status = nc_inq_dimid(nc_file_id, "src_grid_corners", &nc_srcgrdcorn_id);
   if ( status == NC_NOERR )
     {
       nce(nc_inq_dimlen(nc_file_id, nc_srcgrdcorn_id, &dimlen));
-      rg->grid1_corners = dimlen;
-      rg->luse_grid1_corners = TRUE;
-      rg->lneed_grid1_corners = TRUE;
+      src_grid->num_cell_corners = dimlen;
+      src_grid->luse_cell_corners = TRUE;
+      src_grid->lneed_cell_corners = TRUE;
     }
 
-  rg->grid2_corners = 0;
-  rg->luse_grid2_corners = FALSE;
-  rg->lneed_grid2_corners = FALSE;
   status = nc_inq_dimid(nc_file_id, "dst_grid_corners", &nc_dstgrdcorn_id);
   if ( status == NC_NOERR )
     {
       nce(nc_inq_dimlen(nc_file_id, nc_dstgrdcorn_id, &dimlen));
-      rg->grid2_corners = dimlen;
-      rg->luse_grid2_corners = TRUE;
-      rg->lneed_grid2_corners = TRUE;
+      tgt_grid->num_cell_corners = dimlen;
+      tgt_grid->luse_cell_corners = TRUE;
+      tgt_grid->lneed_cell_corners = TRUE;
     }
 
   nce(nc_inq_dimid(nc_file_id, "src_grid_rank", &nc_srcgrdrank_id));
   nce(nc_inq_dimlen(nc_file_id, nc_srcgrdrank_id, &dimlen));
-  rg->grid1_rank = dimlen;
+  src_grid->rank = dimlen;
 
   nce(nc_inq_dimid(nc_file_id, "dst_grid_rank", &nc_dstgrdrank_id));
   nce(nc_inq_dimlen(nc_file_id, nc_dstgrdrank_id, &dimlen));
-  rg->grid2_rank = dimlen;
+  tgt_grid->rank = dimlen;
 
   nce(nc_inq_dimid(nc_file_id, "num_links", &nc_numlinks_id));
   nce(nc_inq_dimlen(nc_file_id, nc_numlinks_id, &dimlen));
   rv->num_links = dimlen;
 
+  if ( rv->num_links == 0 )
+    cdoAbort("Number of remap links is 0, no remap weights found!");
+
   nce(nc_inq_dimid(nc_file_id, "num_wgts", &nc_numwgts_id));
   nce(nc_inq_dimlen(nc_file_id, nc_numwgts_id, &dimlen));
   rv->num_wts = dimlen;
 
-  rg->gridID1 = gridID1;
-  rg->gridID2 = gridID2;
-
-  /* Initialize all pointer */
-  rg->pinit = FALSE;
-  remapGridInitPointer(rg);
+  src_grid->gridID = gridID1;
+  tgt_grid->gridID = gridID2;
 
   if ( gridInqType(gridID1) == GRID_GME )
     {
-      rg->grid1_nvgp = gridInqSize(gridID1);
+      src_grid->nvgp = gridInqSize(gridID1);
       gridID1_gme_c = gridToUnstructured(gridID1, 1);
     }
 
-  remapGridRealloc(rv->map_type, rg);
+  remapGridRealloc(rv->map_type, src_grid);
+  remapGridRealloc(rv->map_type, tgt_grid);
 
-  if ( gridInqType(gridID1) == GRID_GME ) gridInqMaskGME(gridID1_gme_c, rg->grid1_vgpm);    
+  if ( gridInqType(gridID1) == GRID_GME ) gridInqMaskGME(gridID1_gme_c, src_grid->vgpm);    
 
   rv->pinit = TRUE;
   rv->wts = NULL;
 
   rv->max_links = rv->num_links;
 
-  rv->resize_increment = (int) (0.1 * MAX(rg->grid1_size, rg->grid2_size));
+  rv->resize_increment = (int) (0.1 * MAX(src_grid->size, tgt_grid->size));
 
   /* Allocate address and weight arrays for mapping 1 */
 
-  rv->grid1_add = (int *) malloc(rv->num_links*sizeof(int));
-  rv->grid2_add = (int *) malloc(rv->num_links*sizeof(int));
+  rv->src_grid_add = malloc(rv->num_links*sizeof(int));
+  rv->tgt_grid_add = malloc(rv->num_links*sizeof(int));
 
-  rv->wts = (double *) malloc(rv->num_wts*rv->num_links*sizeof(double));
+  rv->wts = malloc(rv->num_wts*rv->num_links*sizeof(double));
 
   /* Get variable ids */
 
@@ -637,7 +660,7 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
   nce(nc_inq_varid(nc_file_id, "src_grid_imask", &nc_srcgrdimask_id));
   nce(nc_inq_varid(nc_file_id, "src_grid_center_lat", &nc_srcgrdcntrlat_id));
   nce(nc_inq_varid(nc_file_id, "src_grid_center_lon", &nc_srcgrdcntrlon_id));
-  if ( rg->grid1_corners )
+  if ( src_grid->num_cell_corners )
     {
       nce(nc_inq_varid(nc_file_id, "src_grid_corner_lat", &nc_srcgrdcrnrlat_id));
       nce(nc_inq_varid(nc_file_id, "src_grid_corner_lon", &nc_srcgrdcrnrlon_id));
@@ -652,7 +675,7 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
   nce(nc_inq_varid(nc_file_id, "dst_grid_imask", &nc_dstgrdimask_id));
   nce(nc_inq_varid(nc_file_id, "dst_grid_center_lat", &nc_dstgrdcntrlat_id));
   nce(nc_inq_varid(nc_file_id, "dst_grid_center_lon", &nc_dstgrdcntrlon_id));
-  if ( rg->grid2_corners )
+  if ( tgt_grid->num_cell_corners )
     {
       nce(nc_inq_varid(nc_file_id, "dst_grid_corner_lat", &nc_dstgrdcrnrlat_id));
       nce(nc_inq_varid(nc_file_id, "dst_grid_corner_lon", &nc_dstgrdcrnrlon_id));
@@ -669,77 +692,77 @@ void read_remap_scrip(const char *interp_file, int gridID1, int gridID2, int *ma
 
   /* Read all variables */
 
-  nce(nc_get_var_int(nc_file_id, nc_srcgrddims_id, rg->grid1_dims));
+  nce(nc_get_var_int(nc_file_id, nc_srcgrddims_id, src_grid->dims));
 
-  nce(nc_get_var_int(nc_file_id, nc_srcgrdimask_id, rg->grid1_mask));
+  nce(nc_get_var_int(nc_file_id, nc_srcgrdimask_id, src_grid->mask));
 
-  nce(nc_get_var_double(nc_file_id, nc_srcgrdcntrlat_id, rg->grid1_center_lat));
-  nce(nc_get_var_double(nc_file_id, nc_srcgrdcntrlon_id, rg->grid1_center_lon));
+  nce(nc_get_var_double(nc_file_id, nc_srcgrdcntrlat_id, src_grid->cell_center_lat));
+  nce(nc_get_var_double(nc_file_id, nc_srcgrdcntrlon_id, src_grid->cell_center_lon));
 
-  nce(nc_get_att_text(nc_file_id, nc_srcgrdcntrlat_id, "units", grid1_units));
+  nce(nc_get_att_text(nc_file_id, nc_srcgrdcntrlat_id, "units", src_grid_units));
   nce(nc_inq_attlen(nc_file_id, nc_srcgrdcntrlat_id, "units", &attlen));
-  grid1_units[attlen] = 0;
+  src_grid_units[attlen] = 0;
 
-  grid_to_radian(grid1_units, rg->grid1_size, rg->grid1_center_lon, "grid1 center lon"); 
-  grid_to_radian(grid1_units, rg->grid1_size, rg->grid1_center_lat, "grid1 center lat"); 
+  grid_to_radian(src_grid_units, src_grid->size, src_grid->cell_center_lon, "source grid center lon"); 
+  grid_to_radian(src_grid_units, src_grid->size, src_grid->cell_center_lat, "source grid center lat"); 
 
-  if ( rg->grid1_corners )
+  if ( src_grid->num_cell_corners )
     {
-      nce(nc_get_var_double(nc_file_id, nc_srcgrdcrnrlat_id, rg->grid1_corner_lat));
-      nce(nc_get_var_double(nc_file_id, nc_srcgrdcrnrlon_id, rg->grid1_corner_lon));
+      nce(nc_get_var_double(nc_file_id, nc_srcgrdcrnrlat_id, src_grid->cell_corner_lat));
+      nce(nc_get_var_double(nc_file_id, nc_srcgrdcrnrlon_id, src_grid->cell_corner_lon));
 
-      nce(nc_get_att_text(nc_file_id, nc_srcgrdcrnrlat_id, "units", grid1_units));
+      nce(nc_get_att_text(nc_file_id, nc_srcgrdcrnrlat_id, "units", src_grid_units));
       nce(nc_inq_attlen(nc_file_id, nc_srcgrdcrnrlat_id, "units", &attlen));
-      grid1_units[attlen] = 0;
+      src_grid_units[attlen] = 0;
 
-      grid_to_radian(grid1_units, rg->grid1_corners*rg->grid1_size, rg->grid1_corner_lon, "grid1 corner lon"); 
-      grid_to_radian(grid1_units, rg->grid1_corners*rg->grid1_size, rg->grid1_corner_lat, "grid1 corner lat"); 
+      grid_to_radian(src_grid_units, src_grid->num_cell_corners*src_grid->size, src_grid->cell_corner_lon, "source grid corner lon"); 
+      grid_to_radian(src_grid_units, src_grid->num_cell_corners*src_grid->size, src_grid->cell_corner_lat, "source grid corner lat"); 
     }
 
   if ( lgridarea )
-    nce(nc_get_var_double(nc_file_id, nc_srcgrdarea_id, rg->grid1_area));
+    nce(nc_get_var_double(nc_file_id, nc_srcgrdarea_id, src_grid->cell_area));
 
-  nce(nc_get_var_double(nc_file_id, nc_srcgrdfrac_id, rg->grid1_frac));
+  nce(nc_get_var_double(nc_file_id, nc_srcgrdfrac_id, src_grid->cell_frac));
 
-  nce(nc_get_var_int(nc_file_id, nc_dstgrddims_id, rg->grid2_dims));
+  nce(nc_get_var_int(nc_file_id, nc_dstgrddims_id, tgt_grid->dims));
 
-  nce(nc_get_var_int(nc_file_id, nc_dstgrdimask_id, rg->grid2_mask));
+  nce(nc_get_var_int(nc_file_id, nc_dstgrdimask_id, tgt_grid->mask));
 
-  nce(nc_get_var_double(nc_file_id, nc_dstgrdcntrlat_id, rg->grid2_center_lat));
-  nce(nc_get_var_double(nc_file_id, nc_dstgrdcntrlon_id, rg->grid2_center_lon));
+  nce(nc_get_var_double(nc_file_id, nc_dstgrdcntrlat_id, tgt_grid->cell_center_lat));
+  nce(nc_get_var_double(nc_file_id, nc_dstgrdcntrlon_id, tgt_grid->cell_center_lon));
 
-  nce(nc_get_att_text(nc_file_id, nc_dstgrdcntrlat_id, "units", grid2_units));
+  nce(nc_get_att_text(nc_file_id, nc_dstgrdcntrlat_id, "units", tgt_grid_units));
   nce(nc_inq_attlen(nc_file_id, nc_dstgrdcntrlat_id, "units", &attlen));
-  grid2_units[attlen] = 0;
+  tgt_grid_units[attlen] = 0;
 
-  grid_to_radian(grid2_units, rg->grid2_size, rg->grid2_center_lon, "grid2 center lon"); 
-  grid_to_radian(grid2_units, rg->grid2_size, rg->grid2_center_lat, "grid2 center lat"); 
+  grid_to_radian(tgt_grid_units, tgt_grid->size, tgt_grid->cell_center_lon, "target grid center lon"); 
+  grid_to_radian(tgt_grid_units, tgt_grid->size, tgt_grid->cell_center_lat, "target grid center lat"); 
 
-  if ( rg->grid2_corners )
+  if ( tgt_grid->num_cell_corners )
     {
-      nce(nc_get_var_double(nc_file_id, nc_dstgrdcrnrlat_id, rg->grid2_corner_lat));
-      nce(nc_get_var_double(nc_file_id, nc_dstgrdcrnrlon_id, rg->grid2_corner_lon));
+      nce(nc_get_var_double(nc_file_id, nc_dstgrdcrnrlat_id, tgt_grid->cell_corner_lat));
+      nce(nc_get_var_double(nc_file_id, nc_dstgrdcrnrlon_id, tgt_grid->cell_corner_lon));
 
-      nce(nc_get_att_text(nc_file_id, nc_dstgrdcrnrlat_id, "units", grid2_units));
+      nce(nc_get_att_text(nc_file_id, nc_dstgrdcrnrlat_id, "units", tgt_grid_units));
       nce(nc_inq_attlen(nc_file_id, nc_dstgrdcrnrlat_id, "units", &attlen));
-      grid2_units[attlen] = 0;
+      tgt_grid_units[attlen] = 0;
       
-      grid_to_radian(grid2_units, rg->grid2_corners*rg->grid2_size, rg->grid2_corner_lon, "grid2 corner lon"); 
-      grid_to_radian(grid2_units, rg->grid2_corners*rg->grid2_size, rg->grid2_corner_lat, "grid2 corner lat"); 
+      grid_to_radian(tgt_grid_units, tgt_grid->num_cell_corners*tgt_grid->size, tgt_grid->cell_corner_lon, "target grid corner lon"); 
+      grid_to_radian(tgt_grid_units, tgt_grid->num_cell_corners*tgt_grid->size, tgt_grid->cell_corner_lat, "target grid corner lat"); 
     }
 
   if ( lgridarea )
-    nce(nc_get_var_double(nc_file_id, nc_dstgrdarea_id, rg->grid2_area));
+    nce(nc_get_var_double(nc_file_id, nc_dstgrdarea_id, tgt_grid->cell_area));
 
-  nce(nc_get_var_double(nc_file_id, nc_dstgrdfrac_id, rg->grid2_frac));
+  nce(nc_get_var_double(nc_file_id, nc_dstgrdfrac_id, tgt_grid->cell_frac));
 
-  nce(nc_get_var_int(nc_file_id, nc_srcadd_id, rv->grid1_add));
-  nce(nc_get_var_int(nc_file_id, nc_dstadd_id, rv->grid2_add));
+  nce(nc_get_var_int(nc_file_id, nc_srcadd_id, rv->src_grid_add));
+  nce(nc_get_var_int(nc_file_id, nc_dstadd_id, rv->tgt_grid_add));
 
   for ( i = 0; i < rv->num_links; i++ )
     {
-      rv->grid1_add[i]--;
-      rv->grid2_add[i]--;
+      rv->src_grid_add[i]--;
+      rv->tgt_grid_add[i]--;
     }
 
   nce(nc_get_var_double(nc_file_id, nc_rmpmatrix_id, rv->wts));
diff --git a/src/remap_search_latbins.c b/src/remap_search_latbins.c
new file mode 100644
index 0000000..aab528c
--- /dev/null
+++ b/src/remap_search_latbins.c
@@ -0,0 +1,125 @@
+#include "cdo.h"
+#include "remap.h"
+
+void calc_bin_addr(long gridsize, long nbins, const restr_t* restrict bin_lats, const restr_t* restrict cell_bound_box, int* restrict bin_addr)
+{
+  long n, n2, nele, nele4;
+  restr_t cell_bound_box_lat1, cell_bound_box_lat2;
+
+  for ( n = 0; n < nbins; ++n )
+    {
+      n2 = n<<1;
+      bin_addr[n2  ] = gridsize;
+      bin_addr[n2+1] = 0;
+    }
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) \
+  private(n, n2, nele4, cell_bound_box_lat1, cell_bound_box_lat2)  \
+  shared(gridsize, nbins, bin_lats, cell_bound_box, bin_addr)
+#endif
+  for ( nele = 0; nele < gridsize; ++nele )
+    {
+      nele4 = nele<<2;
+      cell_bound_box_lat1 = cell_bound_box[nele4  ];
+      cell_bound_box_lat2 = cell_bound_box[nele4+1];
+      for ( n = 0; n < nbins; ++n )
+	{
+	  n2 = n<<1;
+	  if ( cell_bound_box_lat1 <= bin_lats[n2+1] &&
+	       cell_bound_box_lat2 >= bin_lats[n2  ] )
+	    {
+	      /*
+#if defined(_OPENMP)
+	      if ( nele < bin_addr[n2  ] || nele > bin_addr[n2+1] )
+#pragma omp critical
+#endif
+	      */
+		{
+		  bin_addr[n2  ] = MIN(nele, bin_addr[n2  ]);
+		  bin_addr[n2+1] = MAX(nele, bin_addr[n2+1]);
+		}
+	    }
+	}
+    }
+}
+/*
+static
+void calc_bin_addr(long gridsize, long nbins, const restr_t* restrict bin_lats, const restr_t* restrict cell_bound_box, int* restrict bin_addr)
+{
+  long n, n2, nele, nele4;
+
+  for ( n = 0; n < nbins; ++n )
+    {
+      n2 = n<<1;
+      bin_addr[n2  ] = gridsize;
+      bin_addr[n2+1] = 0;
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) \
+  private(nele4)	\
+  shared(n2, gridsize, bin_lats, cell_bound_box, bin_addr)
+#endif
+      for ( nele = 0; nele < gridsize; ++nele )
+	{
+	  nele4 = nele<<2;
+
+	  if ( cell_bound_box[nele4  ] <= bin_lats[n2+1] &&
+	       cell_bound_box[nele4+1] >= bin_lats[n2  ] )
+	    {
+	      bin_addr[n2  ] = MIN(nele, bin_addr[n2  ]);
+	      bin_addr[n2+1] = MAX(nele, bin_addr[n2+1]);
+	    }
+	}
+    }
+}
+*/
+
+void calc_lat_bins(remapgrid_t* src_grid, remapgrid_t* tgt_grid, int map_type)
+{
+  long nbins;
+  long n;      /* Loop counter                  */
+  long n2;
+  double dlat;                /* lat/lon intervals for search bins  */
+  restr_t *bin_lats = NULL;
+
+  nbins = src_grid->num_srch_bins;
+  dlat = PI/nbins;
+
+  if ( cdoVerbose ) cdoPrint("Using %d latitude bins to restrict search.", nbins);
+
+  if ( nbins > 0 )
+    {
+      bin_lats = src_grid->bin_lats = realloc(src_grid->bin_lats, 2*nbins*sizeof(restr_t));
+
+      for ( n = 0; n < nbins; ++n )
+	{
+	  n2 = n<<1;
+	  bin_lats[n2  ] = RESTR_SCALE((n  )*dlat - PIH);
+	  bin_lats[n2+1] = RESTR_SCALE((n+1)*dlat - PIH);
+	}
+
+      src_grid->bin_addr = realloc(src_grid->bin_addr, 2*nbins*sizeof(int));
+
+      calc_bin_addr(src_grid->size, nbins, bin_lats, src_grid->cell_bound_box, src_grid->bin_addr);
+
+      if ( map_type == MAP_TYPE_CONSERV || map_type == MAP_TYPE_CONSPHERE )
+	{
+	  tgt_grid->bin_addr = realloc(tgt_grid->bin_addr, 2*nbins*sizeof(int));
+
+	  calc_bin_addr(tgt_grid->size, nbins, bin_lats, tgt_grid->cell_bound_box, tgt_grid->bin_addr);
+
+	  free(src_grid->bin_lats); src_grid->bin_lats = NULL;
+	}
+   }
+
+  if ( map_type == MAP_TYPE_CONSPHERE )
+    {
+      free(tgt_grid->cell_bound_box); tgt_grid->cell_bound_box = NULL;
+    }
+ 
+  if ( map_type == MAP_TYPE_DISTWGT )
+    {
+      free(src_grid->cell_bound_box); src_grid->cell_bound_box = NULL;
+    }
+}
diff --git a/src/remaplib.c b/src/remaplib.c
index 702b864..4d10601 100644
--- a/src/remaplib.c
+++ b/src/remaplib.c
@@ -38,13 +38,13 @@
 
 */
 /*
+  2013-11-08 Uwe Schulzweida: split remapgrid class to src_grid and tgt_grid
   2012-01-16 Uwe Schulzweida: alloc grid2_bound_box only for conservative remapping
   2011-01-07 Uwe Schulzweida: Changed remap weights from 2D to 1D array
   2009-05-25 Uwe Schulzweida: Changed restrict data type from double to int
   2009-01-11 Uwe Schulzweida: OpenMP parallelization
  */
 
-
 #if defined(HAVE_CONFIG_H)
 #  include "config.h"
 #endif
@@ -60,6 +60,8 @@
 #include "util.h"  /* progressStatus */
 
 
+#define IS_REG2D_GRID(gridID)  (!gridIsRotated(gridID) && (gridInqType(gridID) == GRID_LONLAT || gridInqType(gridID) == GRID_GAUSSIAN))
+
 /* used for store_link_fast */
 
 #define BLK_SIZE 4096
@@ -97,11 +99,28 @@ typedef struct
 #define  QUART    0.25
 #define  BIGNUM   1.e+20
 #define  TINY     1.e-14
-#define  PI       M_PI
-#define  PI2      TWO*PI
-#define  PIH      HALF*PI
 
 
+#define  REMAP_GRID_TYPE_REG2D     1
+#define  REMAP_GRID_TYPE_CURVE2D   2
+#define  REMAP_GRID_TYPE_UNSTRUCT  3
+
+
+static int  remap_store_link_fast = TRUE;
+static int  remap_write_remap     = FALSE;
+static int  remap_num_srch_bins   = 180;
+#define  DEFAULT_MAX_ITER  100
+static long remap_max_iter        = DEFAULT_MAX_ITER;  /* Max iteration count for i, j iteration */
+
+void remap_set_int(int remapvar, int value)
+{
+  if      ( remapvar == REMAP_STORE_LINK_FAST ) remap_store_link_fast = value;
+  else if ( remapvar == REMAP_WRITE_REMAP     ) remap_write_remap     = value;
+  else if ( remapvar == REMAP_MAX_ITER        ) remap_max_iter        = value;
+  else if ( remapvar == REMAP_NUM_SRCH_BINS   ) remap_num_srch_bins   = value;
+  else      cdoAbort("Unsupported remap variable (%d)!", remapvar);
+}
+
 /* static double north_thresh =  1.45;  */ /* threshold for coord transformation */
 /* static double south_thresh = -2.00;  */ /* threshold for coord transformation */
 static double north_thresh =  2.00;  /* threshold for coord transformation */
@@ -113,40 +132,28 @@ extern int timer_remap, timer_remap_con, timer_remap_con_l1, timer_remap_con_l2;
 extern int timer_remap_bil, timer_remap_nn;
 
 
-void remapGridFree(remapgrid_t *rg)
+void remapGridFree(remapgrid_t *grid)
 {
-  if ( rg->pinit == TRUE )
-    {
-      rg->pinit = FALSE;
-
-      if ( rg->grid1_vgpm ) free(rg->grid1_vgpm);
-      if ( rg->grid2_vgpm ) free(rg->grid2_vgpm);
-      free(rg->grid1_mask);
-      free(rg->grid2_mask);
-      free(rg->grid1_center_lat);
-      free(rg->grid1_center_lon);
-      free(rg->grid2_center_lat);
-      free(rg->grid2_center_lon);
-      if ( rg->grid1_area ) free(rg->grid1_area);
-      if ( rg->grid2_area ) free(rg->grid2_area);
-      if ( rg->grid1_frac ) free(rg->grid1_frac);
-      if ( rg->grid2_frac ) free(rg->grid2_frac);
-
-      if ( rg->grid1_corner_lat ) free(rg->grid1_corner_lat);
-      if ( rg->grid1_corner_lon ) free(rg->grid1_corner_lon);
-      if ( rg->grid2_corner_lat ) free(rg->grid2_corner_lat);
-      if ( rg->grid2_corner_lon ) free(rg->grid2_corner_lon);
-
-      if ( rg->grid1_bound_box ) free(rg->grid1_bound_box);
-      if ( rg->grid2_bound_box ) free(rg->grid2_bound_box);
-
-      free(rg->bin_addr1);
-      free(rg->bin_addr2);
-      if ( rg->bin_lats ) free(rg->bin_lats);
-      if ( rg->bin_lons ) free(rg->bin_lons);
-    }
-  else
-    fprintf(stderr, "%s Warning: grid not initialized!\n", __func__);
+  if ( grid->vgpm ) free(grid->vgpm);
+  if ( grid->mask ) free(grid->mask);
+
+  if ( grid->reg2d_center_lat ) free(grid->reg2d_center_lat);
+  if ( grid->reg2d_center_lon ) free(grid->reg2d_center_lon);
+  if ( grid->reg2d_corner_lat ) free(grid->reg2d_corner_lat);
+  if ( grid->reg2d_corner_lon ) free(grid->reg2d_corner_lon);
+
+  if ( grid->cell_center_lat ) free(grid->cell_center_lat);
+  if ( grid->cell_center_lon ) free(grid->cell_center_lon);
+  if ( grid->cell_corner_lat ) free(grid->cell_corner_lat);
+  if ( grid->cell_corner_lon ) free(grid->cell_corner_lon);
+
+  if ( grid->cell_area ) free(grid->cell_area);
+  if ( grid->cell_frac ) free(grid->cell_frac);
+
+  if ( grid->cell_bound_box ) free(grid->cell_bound_box);
+
+  if ( grid->bin_addr ) free(grid->bin_addr);
+  if ( grid->bin_lats ) free(grid->bin_lats);
 
 } /* remapGridFree */
 
@@ -160,8 +167,10 @@ void remapVarsFree(remapvars_t *rv)
     {
       rv->pinit = FALSE;
 
-      free(rv->grid1_add);
-      free(rv->grid2_add);
+      rv->sort_add = FALSE;
+
+      free(rv->src_grid_add);
+      free(rv->tgt_grid_add);
       free(rv->wts);
 
       if ( rv->links.option == TRUE )
@@ -191,235 +200,82 @@ void remapVarsFree(remapvars_t *rv)
 
 /*****************************************************************************/
 
-void genXbounds(long xsize, long ysize, const double *restrict grid_center_lon, 
-		double *restrict grid_corner_lon, double dlon)
-{
-  long i, j, index;
-  double minlon, maxlon;
-
-  if ( ! (dlon > 0) ) dlon = 360./xsize;
-  /*
-  if ( xsize == 1 || (grid_center_lon[xsize-1]-grid_center_lon[0]+dlon) < 359 )
-    cdoAbort("Cannot calculate Xbounds for %d vals with dlon = %g", xsize, dlon);
-  */
-  for ( i = 0; i < xsize; ++i )
-    {
-      minlon = grid_center_lon[i] - HALF*dlon;
-      maxlon = grid_center_lon[i] + HALF*dlon;
-      for ( j = 0; j < ysize; ++j )
-	{
-	  index = (j<<2)*xsize + (i<<2);
-	  grid_corner_lon[index  ] = minlon;
-	  grid_corner_lon[index+1] = maxlon;
-	  grid_corner_lon[index+2] = maxlon;
-	  grid_corner_lon[index+3] = minlon;
-	}
-    }
-}
-
-
-double genYmin(double y1, double y2)
+void remapgrid_init(remapgrid_t *grid)
 {
-  double ymin, dy;
+  grid->remap_grid_type  = -1;
+  grid->num_srch_bins    = remap_num_srch_bins; // only for source grid ?
 
-  dy = y2 - y1;
-  ymin = y1 - dy/2;
+  grid->num_cell_corners = 0;
+  grid->luse_cell_corners  = FALSE;
+  grid->lneed_cell_corners = FALSE;
 
-  if ( y1 < -85 && ymin < -87.5 ) ymin = -90;
-
-  if ( cdoVerbose )
-    cdoPrint("genYmin: y1 = %g  y2 = %g  dy = %g  ymin = %g", y1, y2, dy, ymin);
-
-  return (ymin);
-}
+  grid->nvgp             = 0;
+  grid->vgpm             = NULL;
 
+  grid->mask             = NULL;
 
-double genYmax(double y1, double y2)
-{
-  double ymax, dy;
+  grid->reg2d_center_lon = NULL;
+  grid->reg2d_center_lat = NULL;
+  grid->reg2d_corner_lon = NULL;
+  grid->reg2d_corner_lat = NULL;
 
-  dy = y1 - y2;
-  ymax = y1 + dy/2;
+  grid->cell_center_lon  = NULL;
+  grid->cell_center_lat  = NULL;
+  grid->cell_corner_lon  = NULL;
+  grid->cell_corner_lat  = NULL;
 
-  if ( y1 > 85 && ymax > 87.5 ) ymax = 90;
+  grid->cell_area        = NULL;
+  grid->cell_frac        = NULL;
 
-  if ( cdoVerbose )
-    cdoPrint("genYmax: y1 = %g  y2 = %g  dy = %g  ymax = %g", y1, y2, dy, ymax);
+  grid->cell_bound_box   = NULL;
 
-  return (ymax);
+  grid->bin_addr         = NULL;
+  grid->bin_lats         = NULL;
 }
 
-
-
 /*****************************************************************************/
 
-void genYbounds(long xsize, long ysize, const double *restrict grid_center_lat,
-		double *restrict grid_corner_lat)
+void remapGridRealloc(int map_type, remapgrid_t *grid)
 {
-  long i, j, index;
-  double minlat, maxlat;
-  double firstlat, lastlat;
+  long nalloc;
 
-  firstlat = grid_center_lat[0];
-  lastlat  = grid_center_lat[xsize*ysize-1];
+  if ( grid->nvgp )
+    grid->vgpm   = realloc(grid->vgpm, grid->nvgp*sizeof(int));
 
-  // if ( ysize == 1 ) cdoAbort("Cannot calculate Ybounds for 1 value!");
+  grid->mask     = realloc(grid->mask, grid->size*sizeof(int));
 
-  for ( j = 0; j < ysize; ++j )
+  if ( remap_write_remap == TRUE || grid->remap_grid_type != REMAP_GRID_TYPE_REG2D )
     {
-      if ( ysize == 1 )
-	{
-	  minlat = grid_center_lat[0] - 360./ysize;
-	  maxlat = grid_center_lat[0] + 360./ysize;
-	}
-      else
-	{
-	  index = j*xsize;
-	  if ( firstlat > lastlat )
-	    {
-	      if ( j == 0 )
-		maxlat = genYmax(grid_center_lat[index], grid_center_lat[index+xsize]);
-	      else
-		maxlat = 0.5*(grid_center_lat[index]+grid_center_lat[index-xsize]);
-
-	      if ( j == (ysize-1) )
-		minlat = genYmin(grid_center_lat[index], grid_center_lat[index-xsize]);
-	      else
-		minlat = 0.5*(grid_center_lat[index]+grid_center_lat[index+xsize]);
-	    }
-	  else
-	    {
-	      if ( j == 0 )
-		minlat = genYmin(grid_center_lat[index], grid_center_lat[index+xsize]);
-	      else
-		minlat = 0.5*(grid_center_lat[index]+grid_center_lat[index-xsize]);
-
-	      if ( j == (ysize-1) )
-		maxlat = genYmax(grid_center_lat[index], grid_center_lat[index-xsize]);
-	      else
-		maxlat = 0.5*(grid_center_lat[index]+grid_center_lat[index+xsize]);
-	    }
-	}
-
-      for ( i = 0; i < xsize; ++i )
-	{
-	  index = (j<<2)*xsize + (i<<2);
-	  grid_corner_lat[index  ] = minlat;
-	  grid_corner_lat[index+1] = minlat;
-	  grid_corner_lat[index+2] = maxlat;
-	  grid_corner_lat[index+3] = maxlat;
-	}
+      grid->cell_center_lon = realloc(grid->cell_center_lon, grid->size*sizeof(double));
+      grid->cell_center_lat = realloc(grid->cell_center_lat, grid->size*sizeof(double));
     }
-}
-
-/*****************************************************************************/
-
-void remapGridInitPointer(remapgrid_t *rg)
-{
-  rg->pinit = TRUE;
-
-  rg->grid1_nvgp       = 0;
-  rg->grid2_nvgp       = 0;
-  
-  rg->grid1_vgpm       = NULL;
-  rg->grid2_vgpm       = NULL;
-
-  rg->grid1_mask       = NULL;
-  rg->grid2_mask       = NULL;
-  rg->grid1_center_lat = NULL;
-  rg->grid1_center_lon = NULL;
-  rg->grid2_center_lat = NULL;
-  rg->grid2_center_lon = NULL;
-  rg->grid1_area       = NULL;
-  rg->grid2_area       = NULL;
-  rg->grid1_frac       = NULL;
-  rg->grid2_frac       = NULL;
-
-  rg->grid1_corner_lat = NULL;
-  rg->grid1_corner_lon = NULL;
-  rg->grid2_corner_lat = NULL;
-  rg->grid2_corner_lon = NULL;
-
-  rg->grid1_bound_box  = NULL;
-  rg->grid2_bound_box  = NULL;
-
-  rg->bin_addr1        = NULL;
-  rg->bin_addr2        = NULL;
-  rg->bin_lats         = NULL;
-  rg->bin_lons         = NULL;
-}
 
-/*****************************************************************************/
-
-void remapGridRealloc(int map_type, remapgrid_t *rg)
-{
-  long nalloc;
-
-  if ( rg->grid1_nvgp )
-    rg->grid1_vgpm     = (int *) realloc(rg->grid1_vgpm, rg->grid1_nvgp*sizeof(int));
-
-  if ( rg->grid2_nvgp )
-    rg->grid2_vgpm     = (int *) realloc(rg->grid2_vgpm, rg->grid2_nvgp*sizeof(int));
-
-  rg->grid1_mask       = (int *) realloc(rg->grid1_mask, rg->grid1_size*sizeof(int));
-  rg->grid2_mask       = (int *) realloc(rg->grid2_mask, rg->grid2_size*sizeof(int));
-  rg->grid1_center_lat = (double *) realloc(rg->grid1_center_lat, rg->grid1_size*sizeof(double));
-  rg->grid1_center_lon = (double *) realloc(rg->grid1_center_lon, rg->grid1_size*sizeof(double));
-  rg->grid2_center_lat = (double *) realloc(rg->grid2_center_lat, rg->grid2_size*sizeof(double));
-  rg->grid2_center_lon = (double *) realloc(rg->grid2_center_lon, rg->grid2_size*sizeof(double));
-
-  if ( map_type == MAP_TYPE_CONSERV )
+  if ( map_type == MAP_TYPE_CONSERV || map_type == MAP_TYPE_CONSPHERE )
     {
-      rg->grid1_area = (double *) realloc(rg->grid1_area, rg->grid1_size*sizeof(double));
-      rg->grid2_area = (double *) realloc(rg->grid2_area, rg->grid2_size*sizeof(double));
-
-      memset(rg->grid1_area, 0, rg->grid1_size*sizeof(double));
-      memset(rg->grid2_area, 0, rg->grid2_size*sizeof(double));
+      grid->cell_area = realloc(grid->cell_area, grid->size*sizeof(double));
+      memset(grid->cell_area, 0, grid->size*sizeof(double));
     }
 
-  rg->grid1_frac = (double *) realloc(rg->grid1_frac, rg->grid1_size*sizeof(double));
-  rg->grid2_frac = (double *) realloc(rg->grid2_frac, rg->grid2_size*sizeof(double));
-
-  memset(rg->grid1_frac, 0, rg->grid1_size*sizeof(double));
-  memset(rg->grid2_frac, 0, rg->grid2_size*sizeof(double));
+  grid->cell_frac = realloc(grid->cell_frac, grid->size*sizeof(double));
+  memset(grid->cell_frac, 0, grid->size*sizeof(double));
 
-  if ( rg->lneed_grid1_corners )
+  if ( grid->lneed_cell_corners )
     {
-      if ( rg->grid1_corners == 0 )
+      if ( grid->num_cell_corners == 0 )
 	{
-	  cdoAbort("grid1 corner missing!");
+	  cdoAbort("Grid cell corner missing!");
 	}
       else
 	{
-	  nalloc = rg->grid1_corners*rg->grid1_size;
-	  rg->grid1_corner_lat = (double *) realloc(rg->grid1_corner_lat, nalloc*sizeof(double));
-	  rg->grid1_corner_lon = (double *) realloc(rg->grid1_corner_lon, nalloc*sizeof(double));
-	  
-	  memset(rg->grid1_corner_lat, 0, nalloc*sizeof(double));
-	  memset(rg->grid1_corner_lon, 0, nalloc*sizeof(double));
-	}
-    }
+	  nalloc = grid->num_cell_corners*grid->size;
 
-  if ( rg->lneed_grid2_corners )
-    {
-      if ( rg->grid2_corners == 0 )
-	{
-	  cdoAbort("grid2 corner missing!");
-	}
-      else
-	{
-	  nalloc = rg->grid2_corners*rg->grid2_size;
-	  rg->grid2_corner_lat = (double *) realloc(rg->grid2_corner_lat, nalloc*sizeof(double));
-	  rg->grid2_corner_lon = (double *) realloc(rg->grid2_corner_lon, nalloc*sizeof(double));
-  
-	  memset(rg->grid2_corner_lat, 0, nalloc*sizeof(double));
-	  memset(rg->grid2_corner_lon, 0, nalloc*sizeof(double));
+	  grid->cell_corner_lon = realloc(grid->cell_corner_lon, nalloc*sizeof(double));
+	  memset(grid->cell_corner_lon, 0, nalloc*sizeof(double));
+
+	  grid->cell_corner_lat = realloc(grid->cell_corner_lat, nalloc*sizeof(double));  
+	  memset(grid->cell_corner_lat, 0, nalloc*sizeof(double));
 	}
     }
-
-  rg->grid1_bound_box = (restr_t *) realloc(rg->grid1_bound_box, 4*rg->grid1_size*sizeof(restr_t));
-  if ( rg->luse_grid2_corners )
-    rg->grid2_bound_box = (restr_t *) realloc(rg->grid2_bound_box, 4*rg->grid2_size*sizeof(restr_t));
 }
 
 /*****************************************************************************/
@@ -529,12 +385,50 @@ void boundbox_from_center(int lonIsCyclic, long size, long nx, long ny, const do
     }
 }
 
+static
+void check_lon_range2(long nc, long nlons, double *corners, double *centers)
+{
+  long n, k;
+
+  assert(corners != NULL);
+  /*
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) shared(nlons, lons)
+#endif
+  */
+  for ( n = 0; n < nlons; ++n )
+    {
+      bool lneg = false, lpos = false;
+
+      for ( k = 0; k < nc; ++k )
+	{
+ 	  if      ( !lneg && corners[n*nc+k] > -PI && corners[n*nc+k] < 0. ) lneg = true;
+	  else if ( !lpos && corners[n*nc+k] <  PI && corners[n*nc+k] > 0. ) lpos = true;
+	}
+
+      if ( lneg && lpos )
+	{
+	  if ( centers[n] > PI )
+	    for ( k = 0; k < nc; ++k ) corners[n*nc+k] += PI2;
+	}
+      else
+	{
+	  for ( k = 0; k < nc; ++k )
+	    {
+	      if ( corners[n*nc+k] > PI2  ) corners[n*nc+k] -= PI2;
+	      if ( corners[n*nc+k] < ZERO ) corners[n*nc+k] += PI2;
+	    }
+	}
+    }
+}
 
 static
 void check_lon_range(long nlons, double *lons)
 {
   long n;
 
+  assert(lons != NULL);
+
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) shared(nlons, lons)
 #endif
@@ -550,6 +444,8 @@ void check_lat_range(long nlats, double *lats)
 {
   long n;
 
+  assert(lats != NULL);
+
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) shared(nlats, lats)
 #endif
@@ -565,6 +461,8 @@ void check_lon_boundbox_range(long nlons, restr_t *bound_box)
 {
   long n, n4;
 
+  assert(bound_box != NULL);
+
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) shared(nlons, bound_box) private(n4)
 #endif
@@ -573,7 +471,7 @@ void check_lon_boundbox_range(long nlons, restr_t *bound_box)
       n4 = n<<2;
       if ( RESTR_ABS(bound_box[n4+3] - bound_box[n4+2]) > RESTR_SCALE(PI) )
 	{
-	  bound_box[n4+2] = 0;
+	  bound_box[n4+2] = RESTR_SCALE(0.);
 	  bound_box[n4+3] = RESTR_SCALE(PI2);
 	}
     }
@@ -584,6 +482,8 @@ void check_lat_boundbox_range(long nlats, restr_t *restrict bound_box, double *r
 {
   long n, n4;
 
+  assert(bound_box != NULL);
+
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) shared(nlats, bound_box, lats) private(n4)
 #endif
@@ -608,8 +508,8 @@ int expand_lonlat_grid(int gridID)
   nxp4 = nx+4;
   nyp4 = ny+4;
 
-  xvals = (double *) malloc(nxp4*sizeof(double));
-  yvals = (double *) malloc(nyp4*sizeof(double));
+  xvals = malloc(nxp4*sizeof(double));
+  yvals = malloc(nyp4*sizeof(double));
   gridInqXvals(gridID, xvals+2);
   gridInqYvals(gridID, yvals+2);
 
@@ -664,8 +564,8 @@ int expand_curvilinear_grid(int gridID)
   nyp4 = ny+4;
   gridsize_new = gridsize + 4*(nx+2) + 4*(ny+2);
 
-  xvals = (double *) malloc(gridsize_new*sizeof(double));
-  yvals = (double *) malloc(gridsize_new*sizeof(double));
+  xvals = malloc(gridsize_new*sizeof(double));
+  yvals = malloc(gridsize_new*sizeof(double));
   gridInqXvals(gridID, xvals);
   gridInqYvals(gridID, yvals);
 
@@ -731,604 +631,376 @@ int expand_curvilinear_grid(int gridID)
   return(gridIDnew);
 }
 
+/*****************************************************************************/
+
 static
-void calc_lat_bins(remapgrid_t *rg, int map_type)
+void grid_check_lat_borders_rad(int n, double *ybounds)
 {
-  long nbins;
-  long n;      /* Loop counter                  */
-  long nele;   /* Element loop counter          */
-  long n2, nele4;
-  double dlat;                /* lat/lon intervals for search bins  */
-  long grid1_size, grid2_size;
-
-  grid1_size = rg->grid1_size;
-  grid2_size = rg->grid2_size;
-
-  nbins = rg->num_srch_bins;
-  dlat = PI/nbins;
-
-  if ( cdoVerbose )
-    cdoPrint("Using %d latitude bins to restrict search.", nbins);
-
-  if ( nbins > 0 )
+  if ( ybounds[0] > ybounds[n-1] )
     {
-      rg->bin_lats  = (restr_t *) realloc(rg->bin_lats, 2*nbins*sizeof(restr_t));
-      rg->bin_lons  = (restr_t *) realloc(rg->bin_lons, 2*nbins*sizeof(restr_t));
+      if ( RAD2DEG*ybounds[0]   >  88 ) ybounds[0]   =  PIH;
+      if ( RAD2DEG*ybounds[n-1] < -88 ) ybounds[n-1] = -PIH;
     }
-
-  for ( n = 0; n < nbins; ++n )
+  else
     {
-      n2 = n<<1;
-      rg->bin_lats[n2  ] = RESTR_SCALE((n  )*dlat - PIH);
-      rg->bin_lats[n2+1] = RESTR_SCALE((n+1)*dlat - PIH);
-      rg->bin_lons[n2  ] = 0;
-      rg->bin_lons[n2+1] = RESTR_SCALE(PI2);
+      if ( RAD2DEG*ybounds[0]   < -88 ) ybounds[0]   = -PIH;
+      if ( RAD2DEG*ybounds[n-1] >  88 ) ybounds[n-1] =  PIH;
     }
+}
 
-  if ( nbins > 0 ) rg->bin_addr1 = (int *) realloc(rg->bin_addr1, 2*nbins*sizeof(int));
-  for ( n = 0; n < nbins; ++n )
-    {
-      n2 = n<<1;
-      rg->bin_addr1[n2  ] = grid1_size;
-      rg->bin_addr1[n2+1] = 0;
-    }
+static
+void remap_define_reg2d(int gridID, remapgrid_t *grid)
+{
+  char unitstr[CDI_MAX_NAME];
+  long nx, nxm, ny;
+  long nxp1, nyp1;
 
-#if defined(_OPENMP)
-#pragma omp parallel for default(none) \
-  private(n, n2, nele4)		       \
-  shared(grid1_size, nbins, rg)
-#endif
-  for ( nele = 0; nele < grid1_size; ++nele )
-    {
-      nele4 = nele<<2;
-      for ( n = 0; n < nbins; ++n )
-	{
-	  n2 = n<<1;
-	  if ( rg->grid1_bound_box[nele4  ] <= rg->bin_lats[n2+1] &&
-	       rg->grid1_bound_box[nele4+1] >= rg->bin_lats[n2  ] )
-	    {
-#if defined(_OPENMP)
-#pragma omp critical
-#endif
-	      {
-		rg->bin_addr1[n2  ] = MIN(nele, rg->bin_addr1[n2  ]);
-		rg->bin_addr1[n2+1] = MAX(nele, rg->bin_addr1[n2+1]);
-	      }
-	    }
-	}
-    }
+  nx = grid->dims[0];
+  ny = grid->dims[1];
 
-  if ( map_type == MAP_TYPE_CONSERV )
-    {
-      if ( nbins > 0 ) rg->bin_addr2 = (int *) realloc(rg->bin_addr2, 2*nbins*sizeof(int));
-      for ( n = 0; n < nbins; ++n )
-	{
-	  n2 = n<<1;
-	  rg->bin_addr2[n2  ] = grid2_size;
-	  rg->bin_addr2[n2+1] = 0;
-	}
+  nxp1 = nx + 1;
+  nyp1 = ny + 1;
 
-#if defined(_OPENMP)
-#pragma omp parallel for default(none) \
-  private(n, n2, nele4)		       \
-  shared(grid2_size, nbins, rg)
-#endif
-      for ( nele = 0; nele < grid2_size; ++nele )
-	{
-	  nele4 = nele<<2;
-	  for ( n = 0; n < nbins; n++ )
-	    {
-	      n2 = n<<1;
-	      if ( rg->grid2_bound_box[nele4  ] <= rg->bin_lats[n2+1] &&
-		   rg->grid2_bound_box[nele4+1] >= rg->bin_lats[n2  ] )
-		{
-#if defined(_OPENMP)
-#pragma omp critical
-#endif
-		  {
-		    rg->bin_addr2[n2  ] = MIN(nele, rg->bin_addr2[n2  ]);
-		    rg->bin_addr2[n2+1] = MAX(nele, rg->bin_addr2[n2+1]);
-		  }
-		}
-	    }
-	}
+  nxm = nx;
+  if ( grid->is_cyclic ) nxm++;
 
-      free(rg->bin_lats); rg->bin_lats = NULL;
-      free(rg->bin_lons); rg->bin_lons = NULL;
-    }
+  if ( grid->size != nx*ny ) cdoAbort("Internal error, wrong dimensions!");
 
-  if ( map_type == MAP_TYPE_DISTWGT || map_type == MAP_TYPE_DISTWGT1 )
-    {
-      free(rg->grid1_bound_box); rg->grid1_bound_box = NULL;
-    }
-}
+  grid->reg2d_center_lon = realloc(grid->reg2d_center_lon, nxm*sizeof(double));
+  grid->reg2d_center_lat = realloc(grid->reg2d_center_lat,  ny*sizeof(double));
+ 
+  gridInqXvals(gridID, grid->reg2d_center_lon);
+  gridInqYvals(gridID, grid->reg2d_center_lat);
 
-static
-void calc_lonlat_bins(remapgrid_t *rg, int map_type)
-{
-  long i, j;   /* Logical 2d addresses          */
-  long nbins;
-  long n;      /* Loop counter                  */
-  long nele;   /* Element loop counter          */
-  long n2, nele4;
-  double dlat, dlon;                /* lat/lon intervals for search bins  */
-  long grid1_size, grid2_size;
+  /* Convert lat/lon units if required */
 
-  grid1_size = rg->grid1_size;
-  grid2_size = rg->grid2_size;
+  gridInqYunits(gridID, unitstr);
 
-  nbins = rg->num_srch_bins;
+  grid_to_radian(unitstr, nx, grid->reg2d_center_lon, "grid reg2d center lon"); 
+  grid_to_radian(unitstr, ny, grid->reg2d_center_lat, "grid reg2d center lat"); 
 
-  dlat = PI /nbins;
-  dlon = PI2/nbins;
+  if ( grid->is_cyclic ) grid->reg2d_center_lon[nx] = grid->reg2d_center_lon[0] + PI2;
 
-  if ( cdoVerbose )
-    cdoPrint("Using %d lat/lon boxes to restrict search.", nbins);
+  grid->reg2d_corner_lon = malloc(nxp1*sizeof(double));
+  grid->reg2d_corner_lat = malloc(nyp1*sizeof(double));
 
-  rg->bin_addr1 = (int *) realloc(rg->bin_addr1, 2*nbins*nbins*sizeof(int));
-  if ( map_type == MAP_TYPE_CONSERV )
-    rg->bin_addr2 = (int *) realloc(rg->bin_addr2, 2*nbins*nbins*sizeof(int));
-  rg->bin_lats  = (restr_t *) realloc(rg->bin_lats, 2*nbins*nbins*sizeof(restr_t));
-  rg->bin_lons  = (restr_t *) realloc(rg->bin_lons, 2*nbins*nbins*sizeof(restr_t));
+  grid_gen_corners(nx, grid->reg2d_center_lon, grid->reg2d_corner_lon);
+  grid_gen_corners(ny, grid->reg2d_center_lat, grid->reg2d_corner_lat);
+  grid_check_lat_borders_rad(ny+1, grid->reg2d_corner_lat);
 
-  n = 0;
-  for ( j = 0; j < nbins; j++ )
-    for ( i = 0; i < nbins; i++ )
-      {
-	n2 = n<<1;
-	rg->bin_lats[n2  ]  = RESTR_SCALE((j  )*dlat - PIH);
-	rg->bin_lats[n2+1]  = RESTR_SCALE((j+1)*dlat - PIH);
-	rg->bin_lons[n2  ]  = RESTR_SCALE((i  )*dlon);
-	rg->bin_lons[n2+1]  = RESTR_SCALE((i+1)*dlon);
-	rg->bin_addr1[n2  ] = grid1_size;
-	rg->bin_addr1[n2+1] = 0;
-	if ( map_type == MAP_TYPE_CONSERV )
-	  {
-	    rg->bin_addr2[n2  ] = grid2_size;
-	    rg->bin_addr2[n2+1] = 0;
-	  }
+  //for ( long i = 0; i < nxp1; ++i ) printf("lon %ld %g\n", i, grid->reg2d_corner_lon[i]);
+  //for ( long i = 0; i < nyp1; ++i ) printf("lat %ld %g\n", i, grid->reg2d_corner_lat[i]);
 
-	n++;
-      }
+}
 
-  rg->num_srch_bins = nbins*nbins;
+static
+void remap_define_grid(int map_type, int gridID, remapgrid_t *grid)
+{
+  char xunitstr[CDI_MAX_NAME];
+  char yunitstr[CDI_MAX_NAME];
+  long gridsize;
+  long i;
+  int lgrid_destroy = FALSE;
+  int lgrid_gen_bounds = FALSE;
+  int gridID_gme = -1;
 
-  for ( nele = 0; nele < grid1_size; nele++ )
-    {
-      nele4 = nele<<2;
-      for ( n = 0; n < nbins*nbins; n++ )
-	if ( rg->grid1_bound_box[nele4  ] <= rg->bin_lats[2*n+1] &&
-	     rg->grid1_bound_box[nele4+1] >= rg->bin_lats[2*n  ] &&
-	     rg->grid1_bound_box[nele4+2] <= rg->bin_lons[2*n+1] &&
-	     rg->grid1_bound_box[nele4+3] >= rg->bin_lons[2*n  ] )
-	  {
-	    rg->bin_addr1[2*n  ] = MIN(nele,rg->bin_addr1[2*n  ]);
-	    rg->bin_addr1[2*n+1] = MAX(nele,rg->bin_addr1[2*n+1]);
-	  }
-    }
-  
-  if ( map_type == MAP_TYPE_CONSERV )
+  if ( gridInqType(grid->gridID) != GRID_UNSTRUCTURED && gridInqType(grid->gridID) != GRID_CURVILINEAR )
     {
-      for ( nele = 0; nele < grid2_size; nele++ )
+      if ( gridInqType(grid->gridID) == GRID_GME )
 	{
-	  nele4 = nele<<2;
-	  for ( n = 0; n < nbins*nbins; n++ )
-	    if ( rg->grid2_bound_box[nele4  ] <= rg->bin_lats[2*n+1] &&
-		 rg->grid2_bound_box[nele4+1] >= rg->bin_lats[2*n  ] &&
-		 rg->grid2_bound_box[nele4+2] <= rg->bin_lons[2*n+1] &&
-		 rg->grid2_bound_box[nele4+3] >= rg->bin_lons[2*n  ] )
-	      {
-		rg->bin_addr2[2*n  ] = MIN(nele,rg->bin_addr2[2*n  ]);
-		rg->bin_addr2[2*n+1] = MAX(nele,rg->bin_addr2[2*n+1]);
-	      }
+	  gridID_gme = gridToUnstructured(grid->gridID, 1);
+	  grid->nvgp = gridInqSize(gridID_gme);
+	  gridID = gridDuplicate(gridID_gme);
+	  gridCompress(gridID);
+	  grid->luse_cell_corners = TRUE;
+	}
+      else if ( remap_write_remap == TRUE || grid->remap_grid_type != REMAP_GRID_TYPE_REG2D )
+	{
+	  lgrid_destroy = TRUE;
+	  gridID = gridToCurvilinear(grid->gridID, 1);
+	  lgrid_gen_bounds = TRUE;
 	}
-  
-      free(rg->bin_lats); rg->bin_lats = NULL;
-      free(rg->bin_lons); rg->bin_lons = NULL;
-    }
-
-  if ( map_type == MAP_TYPE_DISTWGT || map_type == MAP_TYPE_DISTWGT1 )
-    { 
-      free(rg->grid1_bound_box); rg->grid1_bound_box = NULL;
     }
-}
-
-/*****************************************************************************/
-
-void remapGridInit(int map_type, int lextrapolate, int gridID1, int gridID2, remapgrid_t *rg)
-{
-  char units[CDI_MAX_NAME];
-  long i, i4;
-  long nx, ny;
-  long grid1_size, grid2_size;
-  int lgrid1_destroy = FALSE, lgrid2_destroy = FALSE;
-  int lgrid1_gen_bounds = FALSE, lgrid2_gen_bounds = FALSE;
-  int gridID1_gme = -1;
-  int gridID2_gme = -1;
 
-  rg->store_link_fast = FALSE;
+  gridsize = grid->size = gridInqSize(gridID);
 
-  north_thresh =  rg->threshhold;
-  south_thresh = -rg->threshhold;
+  grid->dims[0] = gridInqXsize(gridID);
+  grid->dims[1] = gridInqYsize(gridID);
 
-  if ( cdoVerbose ) cdoPrint("threshhold: north=%g  south=%g", north_thresh, south_thresh);
+  grid->is_cyclic = gridIsCircular(gridID);
 
-  if ( lextrapolate > 0 )
-    rg->lextrapolate = TRUE;
+  if ( gridInqType(gridID) == GRID_UNSTRUCTURED )
+    grid->rank = 1;
   else
-    rg->lextrapolate = FALSE;
+    grid->rank = 2;
 
-  if ( map_type == MAP_TYPE_CONSERV )
-    {
-      rg->luse_grid1_corners  = TRUE;
-      rg->luse_grid2_corners  = TRUE;
-      rg->lneed_grid1_corners = TRUE;
-      rg->lneed_grid2_corners = TRUE;
-    }
+  if ( gridInqType(gridID) == GRID_UNSTRUCTURED )
+    grid->num_cell_corners = gridInqNvertex(gridID);
   else
-    {
-      rg->luse_grid1_corners  = FALSE;
-      rg->luse_grid2_corners  = FALSE;
-      rg->lneed_grid1_corners = FALSE;
-      rg->lneed_grid2_corners = FALSE;
-    }
+    grid->num_cell_corners = 4;
 
-  /* Initialize all pointer */
-  if ( rg->pinit == FALSE ) remapGridInitPointer(rg);
+  remapGridRealloc(map_type, grid);
 
-  rg->gridID1 = gridID1;
-  rg->gridID2 = gridID2;
+  /* Initialize logical mask */
 
-  if ( !rg->lextrapolate && gridInqSize(rg->gridID1) > 1 &&
-       (map_type == MAP_TYPE_DISTWGT || map_type == MAP_TYPE_DISTWGT1) &&
-       ((gridInqType(gridID1) == GRID_LONLAT && gridIsRotated(gridID1)) ||
-	(gridInqType(gridID1) == GRID_LONLAT && rg->non_global)) )
-    {
-      rg->gridID1 = gridID1 = expand_lonlat_grid(gridID1);
-    }
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) shared(gridsize, grid)
+#endif
+  for ( i = 0; i < gridsize; ++i ) grid->mask[i] = TRUE;
 
-  if ( gridInqType(gridID1) == GRID_UNSTRUCTURED )
-    {
-      if ( gridInqYvals(gridID1, NULL) == 0 || gridInqXvals(gridID1, NULL) == 0 )
-	{
-	  if ( gridInqNumber(gridID1) > 0 )
-	    {
-	      rg->gridID1 = gridID1 = referenceToGrid(gridID1);
-	      if ( gridID1 == -1 ) cdoAbort("Reference to source grid not found!");
-	    }
-	}
-    }
 
-  if ( gridInqType(gridID2) == GRID_UNSTRUCTURED )
-    {
-      if ( gridInqYvals(gridID2, NULL) == 0 || gridInqXvals(gridID2, NULL) == 0 )
-	{
-	  if ( gridInqNumber(gridID2) > 0 )
-	    {
-	      rg->gridID2 = gridID2 = referenceToGrid(gridID2);
-	      if ( gridID2 == -1 ) cdoAbort("Reference to target grid not found!");
-	    }
-	}
-    }
+  if ( remap_write_remap == FALSE && grid->remap_grid_type == REMAP_GRID_TYPE_REG2D ) return;
 
-  if ( gridInqSize(rg->gridID1) > 1 && 
-       (gridInqType(rg->gridID1) == GRID_LCC || 
-	gridInqType(rg->gridID1) == GRID_LAEA || 
-	gridInqType(rg->gridID1) == GRID_SINUSOIDAL) )
-    {
-      rg->gridID1 = gridID1 = gridToCurvilinear(rg->gridID1, 1);
-    }
 
-  if ( !rg->lextrapolate && gridInqSize(rg->gridID1) > 1 &&
-       (map_type == MAP_TYPE_DISTWGT || map_type == MAP_TYPE_DISTWGT1) &&
-       (gridInqType(gridID1) == GRID_CURVILINEAR && rg->non_global) )
-    {
-      rg->gridID1 = gridID1 = expand_curvilinear_grid(gridID1);
-    }
+  gridInqXvals(gridID, grid->cell_center_lon);
+  gridInqYvals(gridID, grid->cell_center_lat);
+
+  gridInqXunits(gridID, xunitstr);
+  gridInqYunits(gridID, yunitstr);
 
-  if ( map_type == MAP_TYPE_DISTWGT || map_type == MAP_TYPE_DISTWGT1 )
+
+  if ( grid->lneed_cell_corners )
     {
-      if ( gridInqType(rg->gridID1) == GRID_UNSTRUCTURED )
-	{
-	  rg->luse_grid1_corners  = TRUE;
-	  rg->lneed_grid1_corners = FALSE; /* full grid search */
-	}
-      if ( gridInqType(rg->gridID2) == GRID_UNSTRUCTURED )
+      if ( gridInqYbounds(gridID, NULL) && gridInqXbounds(gridID, NULL) )
 	{
-	  rg->luse_grid2_corners  = TRUE;
-	  rg->lneed_grid2_corners = FALSE; /* full grid search */
+	  gridInqXbounds(gridID, grid->cell_corner_lon);
+	  gridInqYbounds(gridID, grid->cell_corner_lat);
 	}
-    }
-
-  if ( gridInqType(rg->gridID1) != GRID_UNSTRUCTURED && gridInqType(rg->gridID1) != GRID_CURVILINEAR )
-    {
-      if ( gridInqType(rg->gridID1) == GRID_GME )
+      else if ( lgrid_gen_bounds )
 	{
-	  gridID1_gme = gridToUnstructured(rg->gridID1, 1);
-	  rg->grid1_nvgp = gridInqSize(gridID1_gme);
-	  gridID1 = gridDuplicate(gridID1_gme);
-	  gridCompress(gridID1);
-	  rg->luse_grid1_corners = TRUE;
+	  grid_cell_center_to_bounds_X2D(xunitstr, grid->dims[0], grid->dims[1], grid->cell_center_lon, grid->cell_corner_lon, 0);
+	  grid_cell_center_to_bounds_Y2D(yunitstr, grid->dims[0], grid->dims[1], grid->cell_center_lat, grid->cell_corner_lat);
 	}
       else
 	{
-	  lgrid1_destroy = TRUE;
-	  gridID1 = gridToCurvilinear(rg->gridID1, 1);
-	  lgrid1_gen_bounds = TRUE;
+	  cdoAbort("Grid corner missing!");
 	}
     }
 
-  if ( gridInqType(rg->gridID2) != GRID_UNSTRUCTURED && gridInqType(rg->gridID2) != GRID_CURVILINEAR )
+
+  if ( gridInqType(grid->gridID) == GRID_GME ) gridInqMaskGME(gridID_gme, grid->vgpm);
+
+  /* Convert lat/lon units if required */
+
+  grid_to_radian(xunitstr, grid->size, grid->cell_center_lon, "grid center lon"); 
+  grid_to_radian(yunitstr, grid->size, grid->cell_center_lat, "grid center lat"); 
+  /* Note: using units from cell center instead from bounds */
+  if ( grid->num_cell_corners && grid->lneed_cell_corners )
     {
-      if ( gridInqType(rg->gridID2) == GRID_GME )
-	{
-	  gridID2_gme = gridToUnstructured(rg->gridID2, 1);
-	  rg->grid2_nvgp = gridInqSize(gridID2_gme);
-	  gridID2 = gridDuplicate(gridID2_gme);
-	  gridCompress(gridID2);
-	  rg->luse_grid2_corners = TRUE;
-	}
-      else
-	{
-	  lgrid2_destroy = TRUE;
-	  gridID2 = gridToCurvilinear(rg->gridID2, 1);
-	  lgrid2_gen_bounds = TRUE;
-	}
+      grid_to_radian(xunitstr, grid->num_cell_corners*grid->size, grid->cell_corner_lon, "grid corner lon"); 
+      grid_to_radian(yunitstr, grid->num_cell_corners*grid->size, grid->cell_corner_lat, "grid corner lat"); 
     }
 
-  grid1_size = rg->grid1_size = gridInqSize(gridID1);
-  grid2_size = rg->grid2_size = gridInqSize(gridID2);
+  if ( lgrid_destroy ) gridDestroy(gridID);
 
-  rg->grid1_is_cyclic = gridIsCircular(gridID1);
-  rg->grid2_is_cyclic = gridIsCircular(gridID2);
+  /* Convert longitudes to 0,2pi interval */
 
-  if ( gridInqType(gridID1) == GRID_UNSTRUCTURED )
-    rg->grid1_rank = 1;
-  else
-    rg->grid1_rank = 2;
+  check_lon_range(grid->size, grid->cell_center_lon);
 
-  if ( gridInqType(gridID2) == GRID_UNSTRUCTURED )
-    rg->grid2_rank = 1;
-  else
-    rg->grid2_rank = 2;
-
-  if ( gridInqType(gridID1) == GRID_UNSTRUCTURED )
-    rg->grid1_corners = gridInqNvertex(gridID1);
-  else
-    rg->grid1_corners = 4;
+  if ( grid->num_cell_corners && grid->lneed_cell_corners )
+    {
+      //check_lon_range2(grid->num_cell_corners, grid->size, grid->cell_corner_lon, grid->cell_center_lon);
+	check_lon_range(grid->num_cell_corners*grid->size, grid->cell_corner_lon);
+    }
+  /*  Make sure input latitude range is within the machine values for +/- pi/2 */
 
-  if ( gridInqType(gridID2) == GRID_UNSTRUCTURED )
-    rg->grid2_corners = gridInqNvertex(gridID2);
-  else
-    rg->grid2_corners = 4;
+  check_lat_range(grid->size, grid->cell_center_lat);
 
-  remapGridRealloc(map_type, rg);
+  if ( grid->num_cell_corners && grid->lneed_cell_corners )
+    check_lat_range(grid->num_cell_corners*grid->size, grid->cell_corner_lat);
+}
 
-  rg->grid1_dims[0] = gridInqXsize(gridID1);
-  rg->grid1_dims[1] = gridInqYsize(gridID1);
- 
-  gridInqXvals(gridID1, rg->grid1_center_lon);
-  gridInqYvals(gridID1, rg->grid1_center_lat);
+/*  Compute bounding boxes for restricting future grid searches */
+static
+void cell_bounding_boxes(remapgrid_t *grid, int remap_grid_basis)
+{
+  if ( remap_grid_basis == REMAP_GRID_BASIS_SRC || grid->luse_cell_corners )
+    grid->cell_bound_box = realloc(grid->cell_bound_box, 4*grid->size*sizeof(restr_t));
 
-  if ( rg->lneed_grid1_corners )
+  if ( grid->luse_cell_corners )
     {
-      if ( gridInqYbounds(gridID1, NULL) && gridInqXbounds(gridID1, NULL) )
+      if ( grid->lneed_cell_corners )
 	{
-	  gridInqXbounds(gridID1, rg->grid1_corner_lon);
-	  gridInqYbounds(gridID1, rg->grid1_corner_lat);
-	}
-      else if ( lgrid1_gen_bounds )
-	{
-	  genXbounds(rg->grid1_dims[0], rg->grid1_dims[1], rg->grid1_center_lon, rg->grid1_corner_lon, 0);
-	  genYbounds(rg->grid1_dims[0], rg->grid1_dims[1], rg->grid1_center_lat, rg->grid1_corner_lat);
+	  if ( cdoVerbose ) cdoPrint("Grid: boundbox_from_corners");
+
+	  boundbox_from_corners(grid->size, grid->num_cell_corners, 
+				grid->cell_corner_lon, grid->cell_corner_lat, grid->cell_bound_box);
 	}
-      else
+      else /* full grid search */
 	{
-	  cdoAbort("grid1 corner missing!");
+	  long gridsize;
+	  long i, i4;
+	  
+	  gridsize = grid->size;
+  
+	  if ( cdoVerbose ) cdoPrint("Grid: bounds missing -> full grid search!");
+
+	  for ( i = 0; i < gridsize; ++i )
+	    {
+	      i4 = i<<2;
+	      grid->cell_bound_box[i4  ] = RESTR_SCALE(-PIH);
+	      grid->cell_bound_box[i4+1] = RESTR_SCALE( PIH);
+	      grid->cell_bound_box[i4+2] = RESTR_SCALE(0.);
+	      grid->cell_bound_box[i4+3] = RESTR_SCALE(PI2);
+	    }
 	}
     }
+  else if ( remap_grid_basis == REMAP_GRID_BASIS_SRC )
+    {
+      long nx, ny;
 
-  /* Initialize logical mask */
+      if ( grid->rank != 2 ) cdoAbort("Internal problem, grid rank = %d!", grid->rank);
 
-#if defined(_OPENMP)
-#pragma omp parallel for default(none) shared(grid1_size, rg)
-#endif
-  for ( i = 0; i < grid1_size; ++i ) rg->grid1_mask[i] = TRUE;
+      nx = grid->dims[0];
+      ny = grid->dims[1];
 
-  if ( gridInqType(rg->gridID1) == GRID_GME ) gridInqMaskGME(gridID1_gme, rg->grid1_vgpm);
+      if ( cdoVerbose ) cdoPrint("Grid: boundbox_from_center");
 
-  /* Convert lat/lon units if required */
+      boundbox_from_center(grid->is_cyclic, grid->size, nx, ny, 
+			   grid->cell_center_lon, grid->cell_center_lat, grid->cell_bound_box);
+    }
 
-  gridInqYunits(gridID1, units);
+  if ( remap_grid_basis == REMAP_GRID_BASIS_SRC || grid->lneed_cell_corners )
+    check_lon_boundbox_range(grid->size, grid->cell_bound_box);
 
-  grid_to_radian(units, rg->grid1_size, rg->grid1_center_lon, "grid1 center lon"); 
-  grid_to_radian(units, rg->grid1_size, rg->grid1_center_lat, "grid1 center lat"); 
-  /* Note: using units from latitude instead from bounds */
-  if ( rg->grid1_corners && rg->lneed_grid1_corners )
-    {
-      grid_to_radian(units, rg->grid1_corners*rg->grid1_size, rg->grid1_corner_lon, "grid1 corner lon"); 
-      grid_to_radian(units, rg->grid1_corners*rg->grid1_size, rg->grid1_corner_lat, "grid1 corner lat"); 
-    }
+  /* Try to check for cells that overlap poles */
 
-  if ( lgrid1_destroy ) gridDestroy(gridID1);
+  if ( remap_grid_basis == REMAP_GRID_BASIS_SRC || grid->lneed_cell_corners )
+    check_lat_boundbox_range(grid->size, grid->cell_bound_box, grid->cell_center_lat);
+}
 
-  /* Data for grid 2 */
 
-  rg->grid2_dims[0] = gridInqXsize(gridID2);
-  rg->grid2_dims[1] = gridInqYsize(gridID2);
+void remap_grids_init(int map_type, int lextrapolate, int gridID1, remapgrid_t *src_grid, int gridID2, remapgrid_t *tgt_grid)
+{
+  int reg2d_src_gridID = gridID1;
+  int reg2d_tgt_gridID = gridID2;
 
-  gridInqXvals(gridID2, rg->grid2_center_lon);
-  gridInqYvals(gridID2, rg->grid2_center_lat);
+  /* Initialize remapgrid structure */
+  remapgrid_init(src_grid);
+  remapgrid_init(tgt_grid);
 
-  if ( rg->lneed_grid2_corners )
+  if ( map_type == MAP_TYPE_BILINEAR || map_type == MAP_TYPE_BICUBIC ||
+       map_type == MAP_TYPE_DISTWGT  || map_type == MAP_TYPE_CONSPHERE )
     {
-      if ( gridInqYbounds(gridID2, NULL) && gridInqXbounds(gridID2, NULL) )
-	{
-	  gridInqXbounds(gridID2, rg->grid2_corner_lon);
-	  gridInqYbounds(gridID2, rg->grid2_corner_lat);
-	}
-      else if ( lgrid2_gen_bounds )
-	{
-	  genXbounds(rg->grid2_dims[0], rg->grid2_dims[1], rg->grid2_center_lon, rg->grid2_corner_lon, 0);
-	  genYbounds(rg->grid2_dims[0], rg->grid2_dims[1], rg->grid2_center_lat, rg->grid2_corner_lat);
-	}
-      else
-	{
-	  cdoAbort("grid2 corner missing!");
-	}
+      if ( IS_REG2D_GRID(gridID1) ) src_grid->remap_grid_type = REMAP_GRID_TYPE_REG2D;
+      // src_grid->remap_grid_type = 0;
     }
 
-  /* Initialize logical mask */
-
-  if ( gridInqMask(rg->gridID2, NULL) )
+  if ( map_type == MAP_TYPE_CONSPHERE && src_grid->remap_grid_type == REMAP_GRID_TYPE_REG2D )
     {
-      gridInqMask(rg->gridID2, rg->grid2_mask);
-      for ( i = 0; i < grid2_size; ++i )
-	{
-	  if ( rg->grid2_mask[i] > 0 && rg->grid2_mask[i] < 255 )
-	    rg->grid2_mask[i] = TRUE;
-	  else
-	    rg->grid2_mask[i] = FALSE;
-	}
+      if ( IS_REG2D_GRID(gridID2) ) tgt_grid->remap_grid_type = REMAP_GRID_TYPE_REG2D;
+      else src_grid->remap_grid_type = -1;
     }
+
+  if ( lextrapolate > 0 )
+    src_grid->lextrapolate = TRUE;
   else
-    {
-#if defined(_OPENMP)
-#pragma omp parallel for default(none) shared(grid2_size, rg)
-#endif
-      for ( i = 0; i < grid2_size; ++i ) rg->grid2_mask[i] = TRUE;
-    }
+    src_grid->lextrapolate = FALSE;
 
-  if ( gridInqType(rg->gridID2) == GRID_GME ) gridInqMaskGME(gridID2_gme, rg->grid2_vgpm);
+  if ( map_type == MAP_TYPE_CONSERV || map_type == MAP_TYPE_CONSPHERE )
+    {
+      if ( src_grid->remap_grid_type != REMAP_GRID_TYPE_REG2D )
+	{
+	  src_grid->luse_cell_corners  = TRUE;
+	  src_grid->lneed_cell_corners = TRUE;
+	}
 
-  /* Convert lat/lon units if required */
+      if ( tgt_grid->remap_grid_type != REMAP_GRID_TYPE_REG2D )
+	{
+	  tgt_grid->luse_cell_corners  = TRUE;
+	  tgt_grid->lneed_cell_corners = TRUE;
+	}
+    }
 
-  gridInqYunits(gridID2, units);
+  src_grid->gridID = gridID1;
+  tgt_grid->gridID = gridID2;
 
-  grid_to_radian(units, rg->grid2_size, rg->grid2_center_lon, "grid2 center lon"); 
-  grid_to_radian(units, rg->grid2_size, rg->grid2_center_lat, "grid2 center lat"); 
-  /* Note: using units from latitude instead from bounds */
-  if ( rg->grid2_corners && rg->lneed_grid2_corners )
+  if ( !src_grid->lextrapolate && gridInqSize(src_grid->gridID) > 1 &&
+       map_type == MAP_TYPE_DISTWGT &&
+       ((gridInqType(gridID1) == GRID_LONLAT && gridIsRotated(gridID1)) ||
+	(gridInqType(gridID1) == GRID_LONLAT && src_grid->non_global)) )
     {
-      grid_to_radian(units, rg->grid2_corners*rg->grid2_size, rg->grid2_corner_lon, "grid2 corner lon"); 
-      grid_to_radian(units, rg->grid2_corners*rg->grid2_size, rg->grid2_corner_lat, "grid2 corner lat"); 
+      src_grid->gridID = gridID1 = expand_lonlat_grid(gridID1);
     }
 
-  if ( lgrid2_destroy ) gridDestroy(gridID2);
-
-  /* Convert longitudes to 0,2pi interval */
-
-  check_lon_range(rg->grid1_size, rg->grid1_center_lon);
-  check_lon_range(rg->grid2_size, rg->grid2_center_lon);
-
-  if ( rg->grid1_corners && rg->lneed_grid1_corners )
-    check_lon_range(rg->grid1_corners*rg->grid1_size, rg->grid1_corner_lon);
-
-  if ( rg->grid2_corners && rg->lneed_grid2_corners )
-    check_lon_range(rg->grid2_corners*rg->grid2_size, rg->grid2_corner_lon);
-
-
-  /*  Make sure input latitude range is within the machine values for +/- pi/2 */
-
-  check_lat_range(rg->grid1_size, rg->grid1_center_lat);
-  check_lat_range(rg->grid2_size, rg->grid2_center_lat);
-
-  if ( rg->grid1_corners && rg->lneed_grid1_corners )
-    check_lat_range(rg->grid1_corners*rg->grid1_size, rg->grid1_corner_lat);
-  
-  if ( rg->grid2_corners && rg->lneed_grid2_corners )
-    check_lat_range(rg->grid2_corners*rg->grid2_size, rg->grid2_corner_lat);
-
-
-  /*  Compute bounding boxes for restricting future grid searches */
-
-  if ( rg->luse_grid1_corners )
+  if ( gridInqType(gridID1) == GRID_UNSTRUCTURED )
     {
-      if ( rg->lneed_grid1_corners )
+      if ( gridInqYvals(gridID1, NULL) == 0 || gridInqXvals(gridID1, NULL) == 0 )
 	{
-	  if ( cdoVerbose ) cdoPrint("Grid1: boundbox_from_corners");
-
-	  boundbox_from_corners(rg->grid1_size, rg->grid1_corners, 
-				rg->grid1_corner_lon, rg->grid1_corner_lat, rg->grid1_bound_box);
+	  if ( gridInqNumber(gridID1) > 0 )
+	    {
+	      src_grid->gridID = gridID1 = referenceToGrid(gridID1);
+	      if ( gridID1 == -1 ) cdoAbort("Reference to source grid not found!");
+	    }
 	}
-      else /* full grid search */
-	{
-	  if ( cdoVerbose ) cdoPrint("Grid1: bounds missing -> full grid search!");
+    }
 
-	  for ( i = 0; i < grid1_size; ++i )
+  if ( gridInqType(gridID2) == GRID_UNSTRUCTURED )
+    {
+      if ( gridInqYvals(gridID2, NULL) == 0 || gridInqXvals(gridID2, NULL) == 0 )
+	{
+	  if ( gridInqNumber(gridID2) > 0 )
 	    {
-	      i4 = i<<2;
-	      rg->grid1_bound_box[i4  ] = RESTR_SCALE(-PIH);
-	      rg->grid1_bound_box[i4+1] = RESTR_SCALE( PIH);
-	      rg->grid1_bound_box[i4+2] = 0;
-	      rg->grid1_bound_box[i4+3] = RESTR_SCALE(PI2);
+	      tgt_grid->gridID = gridID2 = referenceToGrid(gridID2);
+	      if ( gridID2 == -1 ) cdoAbort("Reference to target grid not found!");
 	    }
 	}
     }
-  else
-    {
-      if ( rg->grid1_rank != 2 ) cdoAbort("Internal problem, grid1 rank = %d!", rg->grid1_rank);
-
-      nx = rg->grid1_dims[0];
-      ny = rg->grid1_dims[1];
 
-      if ( cdoVerbose ) cdoPrint("Grid1: boundbox_from_center");
-
-      boundbox_from_center(rg->grid1_is_cyclic, rg->grid1_size, nx, ny, 
-			   rg->grid1_center_lon, rg->grid1_center_lat, rg->grid1_bound_box);
+  if ( gridInqSize(src_grid->gridID) > 1 && 
+       (gridInqType(src_grid->gridID) == GRID_LCC || 
+	gridInqType(src_grid->gridID) == GRID_LAEA || 
+	gridInqType(src_grid->gridID) == GRID_SINUSOIDAL) )
+    {
+      src_grid->gridID = gridID1 = gridToCurvilinear(src_grid->gridID, 1);
     }
 
+  if ( !src_grid->lextrapolate && gridInqSize(src_grid->gridID) > 1 &&
+       map_type == MAP_TYPE_DISTWGT &&
+       (gridInqType(gridID1) == GRID_CURVILINEAR && src_grid->non_global) )
+    {
+      src_grid->gridID = gridID1 = expand_curvilinear_grid(gridID1);
+    }
 
-  if ( rg->luse_grid2_corners )
+  if ( map_type == MAP_TYPE_DISTWGT )
     {
-      if ( rg->lneed_grid2_corners )
+      if ( gridInqType(src_grid->gridID) == GRID_UNSTRUCTURED )
 	{
-	  if ( cdoVerbose ) cdoPrint("Grid2: boundbox_from_corners");
-
-	  boundbox_from_corners(rg->grid2_size, rg->grid2_corners, 
-				rg->grid2_corner_lon, rg->grid2_corner_lat, rg->grid2_bound_box);
+	  src_grid->luse_cell_corners  = TRUE;
+	  src_grid->lneed_cell_corners = FALSE; /* full grid search */
 	}
-      else /* full grid search */
+      /* not used !
+      if ( gridInqType(tgt_grid->gridID) == GRID_UNSTRUCTURED )
 	{
-	  if ( cdoVerbose ) cdoPrint("Grid2: bounds missing -> full grid search!");
-
-	  for ( i = 0; i < grid2_size; ++i )
-	    {
-	      i4 = i<<2;
-	      rg->grid2_bound_box[i4  ] = RESTR_SCALE(-PIH);
-	      rg->grid2_bound_box[i4+1] = RESTR_SCALE( PIH);
-	      rg->grid2_bound_box[i4+2] = 0;
-	      rg->grid2_bound_box[i4+3] = RESTR_SCALE(PI2);
-	    }
+	  tgt_grid->luse_cell_corners  = TRUE;
+	  tgt_grid->lneed_cell_corners = FALSE;
 	}
+      */
     }
 
-  check_lon_boundbox_range(rg->grid1_size, rg->grid1_bound_box);
-  if ( rg->lneed_grid2_corners )
-    check_lon_boundbox_range(rg->grid2_size, rg->grid2_bound_box);
-
-
-  /* Try to check for cells that overlap poles */
-
-  check_lat_boundbox_range(rg->grid1_size, rg->grid1_bound_box, rg->grid1_center_lat);
-  if ( rg->lneed_grid2_corners )
-    check_lat_boundbox_range(rg->grid2_size, rg->grid2_bound_box, rg->grid2_center_lat);
+  //if ( src_grid->remap_grid_type != REMAP_GRID_TYPE_REG2D )
+    remap_define_grid(map_type, gridID1, src_grid);
 
+  remap_define_grid(map_type, gridID2, tgt_grid);
 
-  /*
-    Set up and assign address ranges to search bins in order to 
-    further restrict later searches
-  */
-  if ( rg->restrict_type == RESTRICT_LATITUDE || rg->restrict_type == 0 )
+  if ( src_grid->remap_grid_type == REMAP_GRID_TYPE_REG2D && tgt_grid->remap_grid_type == REMAP_GRID_TYPE_REG2D )
     {
-      calc_lat_bins(rg, map_type);
+      remap_define_reg2d(reg2d_src_gridID, src_grid);
+      remap_define_reg2d(reg2d_tgt_gridID, tgt_grid);
     }
-  else if ( rg->restrict_type == RESTRICT_LATLON )
+  else if ( src_grid->remap_grid_type == REMAP_GRID_TYPE_REG2D )
     {
-      calc_lonlat_bins(rg, map_type);
+      remap_define_reg2d(reg2d_src_gridID, src_grid);
     }
   else
-    cdoAbort("Unknown search restriction method!");
+    {
+      cell_bounding_boxes(src_grid, REMAP_GRID_BASIS_SRC);
+      cell_bounding_boxes(tgt_grid, REMAP_GRID_BASIS_TGT);
+      /*
+	Set up and assign address ranges to search bins in order to further restrict later searches
+      */
+      calc_lat_bins(src_grid, tgt_grid, map_type);
+    }
 
 }  /* remapGridInit */
 
@@ -1338,44 +1010,65 @@ void remapGridInit(int map_type, int lextrapolate, int gridID1, int gridID2, rem
     This routine initializes some variables and provides an initial
     allocation of arrays (fairly large so frequent resizing unnecessary).
 */
-void remapVarsInit(int map_type, remapgrid_t *rg, remapvars_t *rv)
+void remap_vars_init(int map_type, long src_grid_size, long tgt_grid_size, remapvars_t *rv)
 {
   /* Initialize all pointer */
   if ( rv->pinit == FALSE )
     {
       rv->pinit = TRUE;
 
-      rv->grid1_add = NULL;
-      rv->grid2_add = NULL;
-      rv->wts       = NULL;
+      rv->src_grid_add = NULL;
+      rv->tgt_grid_add = NULL;
+      rv->wts          = NULL;
     }
 
   /* Determine the number of weights */
 
-  if      ( map_type == MAP_TYPE_CONSERV  ) rv->num_wts = 3;
-  else if ( map_type == MAP_TYPE_BILINEAR ) rv->num_wts = 1;
-  else if ( map_type == MAP_TYPE_BICUBIC  ) rv->num_wts = 4;
-  else if ( map_type == MAP_TYPE_DISTWGT  ) rv->num_wts = 1;
-  else if ( map_type == MAP_TYPE_DISTWGT1 ) rv->num_wts = 1;
+#if defined(_OPENMP)
+  if ( ompNumThreads > 1 )
+    {
+      if      ( map_type == MAP_TYPE_CONSERV   ) rv->sort_add = TRUE;
+      else if ( map_type == MAP_TYPE_CONSPHERE ) rv->sort_add = TRUE;
+      else if ( map_type == MAP_TYPE_BILINEAR  ) rv->sort_add = TRUE;
+      else if ( map_type == MAP_TYPE_BICUBIC   ) rv->sort_add = TRUE;
+      else if ( map_type == MAP_TYPE_DISTWGT   ) rv->sort_add = TRUE;
+      else cdoAbort("Unknown mapping method!");
+    }
+  else
+#endif
+    {
+      if      ( map_type == MAP_TYPE_CONSERV   ) rv->sort_add = TRUE;
+      else if ( map_type == MAP_TYPE_CONSPHERE ) rv->sort_add = TRUE;
+      else if ( map_type == MAP_TYPE_BILINEAR  ) rv->sort_add = FALSE;
+      else if ( map_type == MAP_TYPE_BICUBIC   ) rv->sort_add = FALSE;
+      else if ( map_type == MAP_TYPE_DISTWGT   ) rv->sort_add = TRUE;
+      else cdoAbort("Unknown mapping method!");
+    }
+
+  if      ( map_type == MAP_TYPE_CONSERV   ) rv->num_wts = 3;
+  else if ( map_type == MAP_TYPE_CONSPHERE ) rv->num_wts = 1;
+  else if ( map_type == MAP_TYPE_BILINEAR  ) rv->num_wts = 1;
+  else if ( map_type == MAP_TYPE_BICUBIC   ) rv->num_wts = 4;
+  else if ( map_type == MAP_TYPE_DISTWGT   ) rv->num_wts = 1;
   else cdoAbort("Unknown mapping method!");
 
-  /*
+   /*
     Initialize num_links and set max_links to four times the largest 
     of the destination grid sizes initially (can be changed later).
     Set a default resize increment to increase the size of link
     arrays if the number of links exceeds the initial size
   */
   rv->num_links = 0;
-  rv->max_links = 4 * rg->grid2_size;
+  rv->max_links = 4 * tgt_grid_size;
 
-  rv->resize_increment = (int) (0.1 * MAX(rg->grid1_size, rg->grid2_size));
+  rv->resize_increment = (int) (0.1 * MAX(src_grid_size, tgt_grid_size));
 
   /*  Allocate address and weight arrays for mapping 1 */
 
-  rv->grid1_add = (int *) realloc(rv->grid1_add, rv->max_links*sizeof(int));
-  rv->grid2_add = (int *) realloc(rv->grid2_add, rv->max_links*sizeof(int));
+  rv->src_grid_add = realloc(rv->src_grid_add, rv->max_links*sizeof(int));
+  rv->tgt_grid_add = realloc(rv->tgt_grid_add, rv->max_links*sizeof(int));
 
-  rv->wts = (double *) realloc(rv->wts, rv->num_wts*rv->max_links*sizeof(double));
+  rv->wts = realloc(rv->wts, rv->num_wts*rv->max_links*sizeof(double));
 
   rv->links.option    = FALSE;
   rv->links.max_links = 0;
@@ -1405,10 +1098,10 @@ void resize_remap_vars(remapvars_t *rv, int increment)
 
   if ( rv->max_links )
     {
-      rv->grid1_add = (int *) realloc(rv->grid1_add, rv->max_links*sizeof(int));
-      rv->grid2_add = (int *) realloc(rv->grid2_add, rv->max_links*sizeof(int));
+      rv->src_grid_add = realloc(rv->src_grid_add, rv->max_links*sizeof(int));
+      rv->tgt_grid_add = realloc(rv->tgt_grid_add, rv->max_links*sizeof(int));
 
-      rv->wts = (double *) realloc(rv->wts, rv->num_wts*rv->max_links*sizeof(double));
+      rv->wts = realloc(rv->wts, rv->num_wts*rv->max_links*sizeof(double));
     }
 
 } /* resize_remap_vars */
@@ -1529,7 +1222,7 @@ long get_max_add(long num_links, long size, const int *restrict add)
   long max_add;
   int *isum;
 
-  isum = (int *) malloc(size*sizeof(int));
+  isum = malloc(size*sizeof(int));
   memset(isum, 0, size*sizeof(int));
 
   for ( n = 0; n < num_links; ++n ) isum[add[n]]++;
@@ -1609,16 +1302,16 @@ void remap_laf(double *restrict dst_array, double missval, long dst_size, long n
   max_cls = get_max_add(num_links, dst_size, dst_add);
 
 #if defined(_OPENMP)
-  src_cls2 = (double **) malloc(ompNumThreads*sizeof(double *));
-  src_wts2 = (double **) malloc(ompNumThreads*sizeof(double *));
+  src_cls2 = malloc(ompNumThreads*sizeof(double *));
+  src_wts2 = malloc(ompNumThreads*sizeof(double *));
   for ( i = 0; i < ompNumThreads; ++i )
     {
-      src_cls2[i] = (double *) malloc(max_cls*sizeof(double));
-      src_wts2[i] = (double *) malloc(max_cls*sizeof(double));
+      src_cls2[i] = malloc(max_cls*sizeof(double));
+      src_wts2[i] = malloc(max_cls*sizeof(double));
     }
 #else
-  src_cls = (double *) malloc(max_cls*sizeof(double));
-  src_wts = (double *) malloc(max_cls*sizeof(double));
+  src_cls = malloc(max_cls*sizeof(double));
+  src_wts = malloc(max_cls*sizeof(double));
 #endif
 
   for ( n = 0; n < num_links; ++n )
@@ -1778,14 +1471,15 @@ void remap_sum(double *restrict dst_array, double missval, long dst_size, long n
 }
 
 
-#define  DEFAULT_MAX_ITER  100
-
-static long    Max_Iter = DEFAULT_MAX_ITER;  /* Max iteration count for i, j iteration */
 static double  converge = 1.e-10;            /* Convergence criterion */
 
-void remap_set_max_iter(long max_iter)
+/* threshold for coord transformation */
+void remap_set_threshhold(double threshhold)
 {
-  if ( max_iter > 0 ) Max_Iter = max_iter;
+  north_thresh =  threshhold;
+  south_thresh = -threshhold;  
+
+  if ( cdoVerbose ) cdoPrint("threshhold: north=%g  south=%g", north_thresh, south_thresh);
 }
 
 
@@ -1795,11 +1489,104 @@ void remap_set_max_iter(long max_iter)
 /*                                                                         */
 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
 
+long find_element(double x, long nelem, const double *restrict array);
+int rect_grid_search(long *ii, long *jj, double x, double y, long nxm, long nym, const double *restrict xm, const double *restrict ym);
+
 static
-int grid_search(remapgrid_t *rg, int *restrict src_add, double *restrict src_lats, 
-		double *restrict src_lons,  double plat, double plon, const int *restrict src_grid_dims,
-		const double *restrict src_center_lat, const double *restrict src_center_lon,
-		const restr_t *restrict src_grid_bound_box, const int *restrict src_bin_add)
+int grid_search_reg2d_nn(long nx, long ny, int *restrict nbr_add, double *restrict nbr_dist, double plat, double plon,
+			 const double *restrict src_center_lat, const double *restrict src_center_lon)
+{
+  int search_result = 0;
+  long n, srch_add;
+  long i;
+  long ii, jj;
+  long jjskip;
+  double coslat, sinlat;
+  double dist_min, distance; /* For computing dist-weighted avg */
+  double *sincoslon;
+  double coslat_dst = cos(plat);
+  double sinlat_dst = sin(plat);
+  double coslon_dst = cos(plon);
+  double sinlon_dst = sin(plon);
+
+  dist_min = BIGNUM;
+  for ( n = 0; n < 4; ++n ) nbr_dist[n] = BIGNUM;  
+
+  long jjf = 0, jjl = ny-1;
+  if ( plon >= src_center_lon[0] && plon <= src_center_lon[nx-1] )
+    {
+      if ( src_center_lat[0] < src_center_lat[ny-1] )
+	{
+	  if ( plat <= src_center_lat[0] )
+	    { jjf = 0; jjl = 1; }
+	  else
+	    { jjf = ny-2; jjl = ny-1; }
+	}
+      else
+	{
+	  if ( plat >= src_center_lat[0] )
+	    { jjf = 0; jjl = 1; }
+	  else
+	    { jjf = ny-2; jjl = ny-1; }
+	}
+    }
+
+  sincoslon = malloc(nx*sizeof(double));
+
+  for ( ii = 0; ii < nx; ++ii )
+    sincoslon[ii] = coslon_dst*cos(src_center_lon[ii]) + sinlon_dst*sin(src_center_lon[ii]);
+
+  for ( jj = jjf; jj <= jjl; ++jj )
+    {
+      coslat = coslat_dst*cos(src_center_lat[jj]);
+      sinlat = sinlat_dst*sin(src_center_lat[jj]);
+
+      jjskip = jj > 1 && jj < (ny-2);
+
+      for ( ii = 0; ii < nx; ++ii )
+	{
+	  if ( jjskip && ii > 1 && ii < (nx-2) ) continue;
+
+	  srch_add = jj*nx + ii;
+
+	  distance = acos(coslat*sincoslon[ii] + sinlat);
+
+	  if ( distance < dist_min )
+	    {
+	      for ( n = 0; n < 4; ++n )
+		{
+		  if ( distance < nbr_dist[n] )
+		    {
+		      for ( i = 3; i > n; --i )
+			{
+			  nbr_add [i] = nbr_add [i-1];
+			  nbr_dist[i] = nbr_dist[i-1];
+			}
+		      search_result = -1;
+		      nbr_add [n] = srch_add;
+		      nbr_dist[n] = distance;
+		      dist_min = nbr_dist[3];
+		      break;
+		    }
+		}
+	    }
+	}
+    }
+
+  free(sincoslon);
+
+  for ( n = 0; n < 4; ++n ) nbr_dist[n] = ONE/(nbr_dist[n] + TINY);
+  distance = 0.0;
+  for ( n = 0; n < 4; ++n ) distance += nbr_dist[n];
+  for ( n = 0; n < 4; ++n ) nbr_dist[n] /= distance;
+
+  return (search_result);
+}
+
+static
+int grid_search_reg2d(remapgrid_t *src_grid, int *restrict src_add, double *restrict src_lats, 
+		      double *restrict src_lons,  double plat, double plon, const int *restrict src_grid_dims,
+		      const double *restrict src_center_lat, const double *restrict src_center_lon)
 {
   /*
     Output variables:
@@ -1817,103 +1604,243 @@ int grid_search(remapgrid_t *rg, int *restrict src_add, double *restrict src_lat
 
     double src_center_lat[]        ! latitude  of each src grid center 
     double src_center_lon[]        ! longitude of each src grid center
-
-    restr_t src_grid_bound_box[][4] ! bound box for source grid
-
-    int src_bin_add[][2]           ! latitude bins for restricting
   */
   /*  Local variables */
-  long n, n2, next_n, srch_add, srch_add4;    /* dummy indices                    */
-  long nx, ny;                                /* dimensions of src grid           */
-  long min_add, max_add;                      /* addresses for restricting search */
-  long i, j, jp1, ip1, n_add, e_add, ne_add;  /* addresses                        */
-  long nbins;
-  /* Vectors for cross-product check */
-  double vec1_lat, vec1_lon;
-  double vec2_lat, vec2_lon, cross_product;
-  double coslat_dst, sinlat_dst, coslon_dst, sinlon_dst;
-  double dist_min, distance; /* For computing dist-weighted avg */
-  int scross[4], scross_last = 0;
   int search_result = 0;
-  restr_t rlat, rlon;
+  int lfound;
+  long n;
+  long nx, nxm, ny;
+  long ii, iix, jj;
 
-  nbins = rg->num_srch_bins;
+  for ( n = 0; n < 4; ++n ) src_add[n] = 0;
 
-  rlat = RESTR_SCALE(plat);
-  rlon = RESTR_SCALE(plon);
+  nx = src_grid_dims[0];
+  ny = src_grid_dims[1];
 
-  /* restrict search first using bins */
+  nxm = nx;
+  if ( src_grid->is_cyclic ) nxm++;
 
-  for ( n = 0; n < 4; ++n ) src_add[n] = 0;
+  if ( /*plon < 0   &&*/ plon < src_center_lon[0]     ) plon += PI2;
+  if ( /*plon > PI2 &&*/ plon > src_center_lon[nxm-1] ) plon -= PI2;
 
-  min_add = rg->grid1_size-1;
-  max_add = 0;
+  lfound = rect_grid_search(&ii, &jj, plon, plat, nxm, ny, src_center_lon, src_center_lat);
 
-  for ( n = 0; n < nbins; ++n )
+  if ( lfound )
     {
-      n2 = n<<1;
-      if ( rlat >= rg->bin_lats[n2] && rlat <= rg->bin_lats[n2+1] &&
-	   rlon >= rg->bin_lons[n2] && rlon <= rg->bin_lons[n2+1] )
-	{
-	  if ( src_bin_add[n2  ] < min_add ) min_add = src_bin_add[n2  ];
-	  if ( src_bin_add[n2+1] > max_add ) max_add = src_bin_add[n2+1];
-	}
-    }
- 
-  /* Now perform a more detailed search */
+      iix = ii;
+      if ( src_grid->is_cyclic && iix == (nxm-1) ) iix = 0;
+      src_add[0] = (jj-1)*nx+(ii-1);
+      src_add[1] = (jj-1)*nx+(iix);
+      src_add[2] = (jj)*nx+(iix);
+      src_add[3] = (jj)*nx+(ii-1);
 
-  nx = src_grid_dims[0];
-  ny = src_grid_dims[1];
+      src_lons[0] = src_center_lon[ii-1];
+      src_lons[1] = src_center_lon[iix];
+      /* For consistency, we must make sure all lons are in same 2pi interval */
+      if ( src_lons[0] > PI2 ) src_lons[0] -= PI2;
+      if ( src_lons[0] < 0   ) src_lons[0] += PI2;
+      if ( src_lons[1] > PI2 ) src_lons[1] -= PI2;
+      if ( src_lons[1] < 0   ) src_lons[1] += PI2;
+      src_lons[2] = src_lons[1];
+      src_lons[3] = src_lons[0];
 
-  /* srch_loop */
-  for ( srch_add = min_add; srch_add <= max_add; ++srch_add )
-    {
-      srch_add4 = srch_add<<2;
-      /* First check bounding box */
-      if ( rlat >= src_grid_bound_box[srch_add4  ] && 
-           rlat <= src_grid_bound_box[srch_add4+1] &&
-           rlon >= src_grid_bound_box[srch_add4+2] &&
-	   rlon <= src_grid_bound_box[srch_add4+3] )
-	{
-	  /* We are within bounding box so get really serious */
+      src_lats[0] = src_center_lat[jj-1];
+      src_lats[1] = src_lats[0];
+      src_lats[2] = src_center_lat[jj];
+      src_lats[3] = src_lats[2];
 
-          /* Determine neighbor addresses */
-          j = srch_add/nx;
-          i = srch_add - j*nx;
+      search_result = 1;
+      
+      return (search_result);
+    }
 
-          if ( i < (nx-1) )
-            ip1 = i + 1;
-          else
-	    {
-	      /* 2009-01-09 Uwe Schulzweida: bug fix */
-	      if ( rg->grid1_is_cyclic )
-		ip1 = 0;
-	      else
-		ip1 = i;
-	    }
+  /*
+    If no cell found, point is likely either in a box that straddles either pole or is outside 
+    the grid. Fall back to a distance-weighted average of the four closest points.
+    Go ahead and compute weights here, but store in src_lats and return -add to prevent the 
+    parent routine from computing bilinear weights.
+  */
+  if ( !src_grid->lextrapolate ) return (search_result);
 
-          if ( j < (ny-1) )
-            jp1 = j + 1;
-          else
-	    {
-	      /* 2008-12-17 Uwe Schulzweida: latitute cyclic ??? (bug fix) */
-	      jp1 = j;
-	    }
+  /*
+    printf("Could not find location for %g %g\n", plat*RAD2DEG, plon*RAD2DEG);
+    printf("Using nearest-neighbor average for this point\n");
+  */
+  search_result = grid_search_reg2d_nn(nx, ny, src_add, src_lats, plat, plon, src_center_lat, src_center_lon);
 
-          n_add  = jp1*nx + i;
-          e_add  = j  *nx + ip1;
-	  ne_add = jp1*nx + ip1;
+  return (search_result);
+}  /* grid_search_reg2d */
 
-          src_lats[0] = src_center_lat[srch_add];
-          src_lats[1] = src_center_lat[e_add];
-          src_lats[2] = src_center_lat[ne_add];
-          src_lats[3] = src_center_lat[n_add];
 
-          src_lons[0] = src_center_lon[srch_add];
+static
+int grid_search_nn(long min_add, long max_add, int *restrict nbr_add, double *restrict nbr_dist, 
+		   double plat, double plon,
+		   const double *restrict src_center_lat, const double *restrict src_center_lon)
+{
+  int search_result = 0;
+  long n, srch_add;
+  long i;
+  double dist_min, distance; /* For computing dist-weighted avg */
+  double coslat_dst = cos(plat);
+  double sinlat_dst = sin(plat);
+  double coslon_dst = cos(plon);
+  double sinlon_dst = sin(plon);
+
+  dist_min = BIGNUM;
+  for ( n = 0; n < 4; ++n ) nbr_dist[n] = BIGNUM;
+  for ( srch_add = min_add; srch_add <= max_add; ++srch_add )
+    {
+      distance = acos(coslat_dst*cos(src_center_lat[srch_add])*
+		     (coslon_dst*cos(src_center_lon[srch_add]) +
+                      sinlon_dst*sin(src_center_lon[srch_add]))+
+		      sinlat_dst*sin(src_center_lat[srch_add]));
+
+      if ( distance < dist_min )
+	{
+          for ( n = 0; n < 4; ++n )
+	    {
+	      if ( distance < nbr_dist[n] )
+		{
+		  for ( i = 3; i > n; --i )
+		    {
+		      nbr_add [i] = nbr_add [i-1];
+		      nbr_dist[i] = nbr_dist[i-1];
+		    }
+		  search_result = -1;
+		  nbr_add [n] = srch_add;
+		  nbr_dist[n] = distance;
+		  dist_min = nbr_dist[3];
+		  break;
+		}
+	    }
+        }
+    }
+
+  for ( n = 0; n < 4; ++n ) nbr_dist[n] = ONE/(nbr_dist[n] + TINY);
+  distance = 0.0;
+  for ( n = 0; n < 4; ++n ) distance += nbr_dist[n];
+  for ( n = 0; n < 4; ++n ) nbr_dist[n] /= distance;
+
+  return (search_result);
+}
+
+static
+int grid_search(remapgrid_t *src_grid, int *restrict src_add, double *restrict src_lats, 
+		double *restrict src_lons,  double plat, double plon, const int *restrict src_grid_dims,
+		const double *restrict src_center_lat, const double *restrict src_center_lon,
+		const restr_t *restrict src_grid_bound_box, const int *restrict src_bin_add)
+{
+  /*
+    Output variables:
+
+    int    src_add[4]              ! address of each corner point enclosing P
+    double src_lats[4]             ! latitudes  of the four corner points
+    double src_lons[4]             ! longitudes of the four corner points
+
+    Input variables:
+
+    double plat                    ! latitude  of the search point
+    double plon                    ! longitude of the search point
+
+    int src_grid_dims[2]           ! size of each src grid dimension
+
+    double src_center_lat[]        ! latitude  of each src grid center 
+    double src_center_lon[]        ! longitude of each src grid center
+
+    restr_t src_grid_bound_box[][4] ! bound box for source grid
+
+    int src_bin_add[][2]           ! latitude bins for restricting
+  */
+  /*  Local variables */
+  long n, n2, next_n, srch_add, srch_add4;    /* dummy indices                    */
+  long nx, ny;                                /* dimensions of src grid           */
+  long min_add, max_add;                      /* addresses for restricting search */
+  long i, j, jp1, ip1, n_add, e_add, ne_add;  /* addresses                        */
+  long nbins;
+  /* Vectors for cross-product check */
+  double vec1_lat, vec1_lon;
+  double vec2_lat, vec2_lon, cross_product;
+  int scross[4], scross_last = 0;
+  int search_result = 0;
+  restr_t rlat, rlon;
+  restr_t *bin_lats = src_grid->bin_lats;
+
+  nbins = src_grid->num_srch_bins;
+
+  rlat = RESTR_SCALE(plat);
+  rlon = RESTR_SCALE(plon);
+
+  /* restrict search first using bins */
+
+  for ( n = 0; n < 4; ++n ) src_add[n] = 0;
+
+  min_add = src_grid->size-1;
+  max_add = 0;
+
+  for ( n = 0; n < nbins; ++n )
+    {
+      n2 = n<<1;
+      if ( rlat >= bin_lats[n2] && rlat <= bin_lats[n2+1] )
+	{
+	  if ( src_bin_add[n2  ] < min_add ) min_add = src_bin_add[n2  ];
+	  if ( src_bin_add[n2+1] > max_add ) max_add = src_bin_add[n2+1];
+	}
+    }
+ 
+  /* Now perform a more detailed search */
+
+  nx = src_grid_dims[0];
+  ny = src_grid_dims[1];
+
+  /* srch_loop */
+  for ( srch_add = min_add; srch_add <= max_add; ++srch_add )
+    {
+      srch_add4 = srch_add<<2;
+      /* First check bounding box */
+      if ( rlon >= src_grid_bound_box[srch_add4+2] &&
+	   rlon <= src_grid_bound_box[srch_add4+3] &&
+	   rlat >= src_grid_bound_box[srch_add4  ] &&
+	   rlat <= src_grid_bound_box[srch_add4+1])
+	{
+	  /* We are within bounding box so get really serious */
+
+          /* Determine neighbor addresses */
+          j = srch_add/nx;
+          i = srch_add - j*nx;
+
+          if ( i < (nx-1) )
+            ip1 = i + 1;
+          else
+	    {
+	      /* 2009-01-09 Uwe Schulzweida: bug fix */
+	      if ( src_grid->is_cyclic )
+		ip1 = 0;
+	      else
+		ip1 = i;
+	    }
+
+          if ( j < (ny-1) )
+            jp1 = j + 1;
+          else
+	    {
+	      /* 2008-12-17 Uwe Schulzweida: latitute cyclic ??? (bug fix) */
+	      jp1 = j;
+	    }
+
+          n_add  = jp1*nx + i;
+          e_add  = j  *nx + ip1;
+	  ne_add = jp1*nx + ip1;
+
+          src_lons[0] = src_center_lon[srch_add];
           src_lons[1] = src_center_lon[e_add];
           src_lons[2] = src_center_lon[ne_add];
           src_lons[3] = src_center_lon[n_add];
 
+          src_lats[0] = src_center_lat[srch_add];
+          src_lats[1] = src_center_lat[e_add];
+          src_lats[2] = src_center_lat[ne_add];
+          src_lats[3] = src_center_lat[n_add];
+
 	  /* For consistency, we must make sure all lons are in same 2pi interval */
 
           vec1_lon = src_lons[0] - plon;
@@ -1996,61 +1923,22 @@ int grid_search(remapgrid_t *rg, int *restrict src_add, double *restrict src_lat
     Go ahead and compute weights here, but store in src_lats and return -add to prevent the 
     parent routine from computing bilinear weights.
   */
-  if ( ! rg->lextrapolate ) return (search_result);
+  if ( !src_grid->lextrapolate ) return (search_result);
 
   /*
     printf("Could not find location for %g %g\n", plat*RAD2DEG, plon*RAD2DEG);
     printf("Using nearest-neighbor average for this point\n");
   */
-  coslat_dst = cos(plat);
-  sinlat_dst = sin(plat);
-  coslon_dst = cos(plon);
-  sinlon_dst = sin(plon);
-
-  dist_min = BIGNUM;
-  for ( n = 0; n < 4; ++n ) src_lats[n] = BIGNUM;
-  for ( srch_add = min_add; srch_add <= max_add; ++srch_add )
-    {
-      distance = acos(coslat_dst*cos(src_center_lat[srch_add])*
-		     (coslon_dst*cos(src_center_lon[srch_add]) +
-                      sinlon_dst*sin(src_center_lon[srch_add]))+
-		      sinlat_dst*sin(src_center_lat[srch_add]));
-
-      if ( distance < dist_min )
-	{
-          for ( n = 0; n < 4; ++n )
-	    {
-	      if ( distance < src_lats[n] )
-		{
-		  for ( i = 3; i > n; --i )
-		    {
-		      src_add [i] = src_add [i-1];
-		      src_lats[i] = src_lats[i-1];
-		    }
-		  search_result = -1;
-		  src_add [n] = srch_add;
-		  src_lats[n] = distance;
-		  dist_min = src_lats[3];
-		  break;
-		}
-	    }
-        }
-    }
-
-  for ( n = 0; n < 4; ++n ) src_lons[n] = ONE/(src_lats[n] + TINY);
-  distance = 0.0;
-  for ( n = 0; n < 4; ++n ) distance += src_lons[n];
-  for ( n = 0; n < 4; ++n ) src_lats[n] = src_lons[n]/distance;
+  search_result = grid_search_nn(min_add, max_add, src_add, src_lats, plat, plon, src_center_lat, src_center_lon);
 
   return (search_result);
 }  /* grid_search */
 
-
 /*
   This routine stores the address and weight for four links associated with one destination
   point in the appropriate address and weight arrays and resizes those arrays if necessary.
 */
-void store_link_bilin(remapvars_t *rv, int dst_add, const int *restrict src_add, const double *restrict weights)
+void store_link_bilin(remapvars_t *rv, int dst_add, int *restrict src_add, double *restrict weights)
 {
   /*
     Input variables:
@@ -2071,11 +1959,34 @@ void store_link_bilin(remapvars_t *rv, int dst_add, const int *restrict src_add,
   if ( rv->num_links >= rv->max_links ) 
     resize_remap_vars(rv, rv->resize_increment);
 
+  if ( rv->sort_add == FALSE )
+    {
+      for ( n = 0; n < 3; ++n )
+	if ( src_add[n] > src_add[n+1] ) break;
+
+      if ( n < 2 ) rv->sort_add = TRUE;
+      else if ( n == 2 ) // swap 3rd and 4th elements
+	{
+	  {
+	    int itmp;
+	    itmp = src_add[2];
+	    src_add[2] = src_add[3];
+	    src_add[3] = itmp;
+	  }
+	  {
+	    double dtmp;
+	    dtmp = weights[2];
+	    weights[2] = weights[3];
+	    weights[3] = dtmp;
+	  }
+	}
+    }
+
   for ( n = 0; n < 4; ++n )
     {
-      rv->grid1_add[nlink+n] = src_add[n];
-      rv->grid2_add[nlink+n] = dst_add;
-      rv->wts      [nlink+n] = weights[n];
+      rv->src_grid_add[nlink+n] = src_add[n];
+      rv->tgt_grid_add[nlink+n] = dst_add;
+      rv->wts         [nlink+n] = weights[n];
     }
 
 } /* store_link_bilin */
@@ -2114,7 +2025,7 @@ long find_ij_weights(double plon, double plat, double *restrict src_lats, double
   iguess = HALF;
   jguess = HALF;
 
-  for ( iter = 0; iter < Max_Iter; ++iter )
+  for ( iter = 0; iter < remap_max_iter; ++iter )
     {
       dthp = plat - src_lats[0] - dth1*iguess - dth2*jguess - dth3*iguess*jguess;
       dphp = plon - src_lons[0];
@@ -2153,12 +2064,12 @@ long find_ij_weights(double plon, double plat, double *restrict src_lats, double
 
   -----------------------------------------------------------------------
 */
-void remap_bilin(remapgrid_t *rg, remapvars_t *rv)
+void remap_bilin(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
 {
   /*   Local variables */
   int  lwarn = TRUE;
   int  search_result;
-  long grid2_size;
+  long tgt_grid_size;
   long dst_add;                  /*  destination addresss */
   long n, icount;
   long iter;                     /*  iteration counters   */
@@ -2171,28 +2082,29 @@ void remap_bilin(remapgrid_t *rg, remapvars_t *rv)
 
   double plat, plon;             /*  lat/lon coords of destination point    */
   double findex = 0;
+  int remap_grid_type = src_grid->remap_grid_type;
 
   if ( cdoTimer ) timer_start(timer_remap_bil);
 
   progressInit();
 
-  grid2_size = rg->grid2_size;
+  tgt_grid_size = tgt_grid->size;
 
-  /* Compute mappings from grid1 to grid2 */
+  /* Compute mappings from source to target grid */
 
-  if ( rg->grid1_rank != 2 )
-    cdoAbort("Can not do bilinear interpolation when grid1_rank != 2"); 
+  if ( src_grid->rank != 2 )
+    cdoAbort("Can not do bilinear interpolation when source grid rank != 2"); 
 
   /* Loop over destination grid */
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, cdoVerbose, grid2_size, rg, rv, Max_Iter, converge, lwarn, findex) \
+  shared(ompNumThreads, cdoTimer, cdoVerbose, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, rv, remap_max_iter, converge, lwarn, findex) \
   private(dst_add, n, icount, iter, src_add, src_lats, src_lons, wgts, plat, plon, search_result)    \
   schedule(dynamic,1)
 #endif
   /* grid_loop1 */
-  for ( dst_add = 0; dst_add < grid2_size; ++dst_add )
+  for ( dst_add = 0; dst_add < tgt_grid_size; ++dst_add )
     {
       int lprogress = 1;
 #if defined(_OPENMP)
@@ -2202,26 +2114,29 @@ void remap_bilin(remapgrid_t *rg, remapvars_t *rv)
 #pragma omp atomic
 #endif
       findex++;
-      if ( lprogress ) progressStatus(0, 1, findex/grid2_size);
+      if ( lprogress ) progressStatus(0, 1, findex/tgt_grid_size);
 
-      if ( ! rg->grid2_mask[dst_add] ) continue;
+      if ( ! tgt_grid->mask[dst_add] ) continue;
 
-      plat = rg->grid2_center_lat[dst_add];
-      plon = rg->grid2_center_lon[dst_add];
+      plat = tgt_grid->cell_center_lat[dst_add];
+      plon = tgt_grid->cell_center_lon[dst_add];
 
       /* Find nearest square of grid points on source grid  */
-
-      search_result = grid_search(rg, src_add, src_lats, src_lons, 
-				  plat, plon, rg->grid1_dims,
-				  rg->grid1_center_lat, rg->grid1_center_lon,
-				  rg->grid1_bound_box, rg->bin_addr1);
-     
+      if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
+	search_result = grid_search_reg2d(src_grid, src_add, src_lats, src_lons, 
+					  plat, plon, src_grid->dims,
+					  src_grid->reg2d_center_lat, src_grid->reg2d_center_lon);
+      else
+	search_result = grid_search(src_grid, src_add, src_lats, src_lons, 
+				    plat, plon, src_grid->dims,
+				    src_grid->cell_center_lat, src_grid->cell_center_lon,
+				    src_grid->cell_bound_box, src_grid->bin_addr);
 
       /* Check to see if points are land points */
       if ( search_result > 0 )
 	{
 	  for ( n = 0; n < 4; ++n )
-	    if ( ! rg->grid1_mask[src_add[n]] ) search_result = 0;
+	    if ( ! src_grid->mask[src_add[n]] ) search_result = 0;
 	}
 
       /* If point found, find local iw,jw coordinates for weights  */
@@ -2229,11 +2144,11 @@ void remap_bilin(remapgrid_t *rg, remapvars_t *rv)
 	{
 	  double iw, jw;  /*  current guess for bilinear coordinate  */
 
-          rg->grid2_frac[dst_add] = ONE;
+          tgt_grid->cell_frac[dst_add] = ONE;
 
 	  iter = find_ij_weights(plon, plat, src_lats, src_lons, &iw, &jw);
 
-          if ( iter < Max_Iter )
+          if ( iter < remap_max_iter )
 	    {
 	      /* Successfully found iw,jw - compute weights */
 
@@ -2256,18 +2171,18 @@ void remap_bilin(remapgrid_t *rg, remapvars_t *rv)
 		  cdoPrint("Src grid lons: %g %g %g %g", src_lons[0], src_lons[1], src_lons[2], src_lons[3]);
 		  cdoPrint("Src grid addresses: %d %d %d %d", src_add[0], src_add[1], src_add[2], src_add[3]);
 		  cdoPrint("Src grid lats: %g %g %g %g",
-			   rg->grid1_center_lat[src_add[0]], rg->grid1_center_lat[src_add[1]],
-			   rg->grid1_center_lat[src_add[2]], rg->grid1_center_lat[src_add[3]]);
+			   src_grid->cell_center_lat[src_add[0]], src_grid->cell_center_lat[src_add[1]],
+			   src_grid->cell_center_lat[src_add[2]], src_grid->cell_center_lat[src_add[3]]);
 		  cdoPrint("Src grid lons: %g %g %g %g",
-			   rg->grid1_center_lon[src_add[0]], rg->grid1_center_lon[src_add[1]],
-			   rg->grid1_center_lon[src_add[2]], rg->grid1_center_lon[src_add[3]]);
+			   src_grid->cell_center_lon[src_add[0]], src_grid->cell_center_lon[src_add[1]],
+			   src_grid->cell_center_lon[src_add[2]], src_grid->cell_center_lon[src_add[3]]);
 		  cdoPrint("Current iw,jw : %g %g", iw, jw);
 		}
 
 	      if ( cdoVerbose || lwarn )
 		{
 		  lwarn = FALSE;
-		  //  cdoWarning("Iteration for iw,jw exceed max iteration count of %d!", Max_Iter);
+		  //  cdoWarning("Iteration for iw,jw exceed max iteration count of %d!", remap_max_iter);
 		  cdoWarning("Bilinear interpolation failed for some grid points - used a distance-weighted average instead!");
 		}
 
@@ -2277,13 +2192,14 @@ void remap_bilin(remapgrid_t *rg, remapvars_t *rv)
 
       /*
 	Search for bilinear failed - use a distance-weighted average instead (this is typically near the pole)
+	Distance was stored in src_lats!
       */
       if ( search_result < 0 )
 	{
           icount = 0;
           for ( n = 0; n < 4; ++n )
 	    {
-	      if ( rg->grid1_mask[src_add[n]] )
+	      if ( src_grid->mask[src_add[n]] )
 		icount++;
 	      else
 		src_lats[n] = ZERO;
@@ -2297,7 +2213,7 @@ void remap_bilin(remapgrid_t *rg, remapvars_t *rv)
 	      for ( n = 0; n < 4; ++n ) sum_wgts += fabs(src_lats[n]);
 	      for ( n = 0; n < 4; ++n ) wgts[n] = fabs(src_lats[n])/sum_wgts;
 
-	      rg->grid2_frac[dst_add] = ONE;
+	      tgt_grid->cell_frac[dst_add] = ONE;
 
 #if defined(_OPENMP)
 #pragma omp critical
@@ -2322,7 +2238,7 @@ void remap_bilin(remapgrid_t *rg, remapvars_t *rv)
   point in the appropriate address and weight arrays and resizes those arrays if necessary.
 */
 static
-void store_link_bicub(remapvars_t *rv, int dst_add, const int *restrict src_add, double weights[4][4])
+void store_link_bicub(remapvars_t *rv, int dst_add, int *restrict src_add, double weights[4][4])
 {
   /*
     Input variables:
@@ -2343,17 +2259,39 @@ void store_link_bicub(remapvars_t *rv, int dst_add, const int *restrict src_add,
   if ( rv->num_links >= rv->max_links ) 
     resize_remap_vars(rv, rv->resize_increment);
 
+  if ( rv->sort_add == FALSE )
+    {
+      for ( n = 0; n < 3; ++n )
+	if ( src_add[n] > src_add[n+1] ) break;
+
+      if ( n < 2 ) rv->sort_add = TRUE;
+      else if ( n == 2 ) // swap 3rd and 4th elements
+	{
+	  {
+	    int itmp;
+	    itmp = src_add[2];
+	    src_add[2] = src_add[3];
+	    src_add[3] = itmp;
+	  }
+	  {
+	    double dtmp[4];
+	    for ( k = 0; k < 4; ++k ) dtmp[k] = weights[k][2];
+	    for ( k = 0; k < 4; ++k ) weights[k][2] = weights[k][3];
+	    for ( k = 0; k < 4; ++k ) weights[k][3] = dtmp[k];
+	  }
+	}
+    }
+
   for ( n = 0; n < 4; ++n )
     {
-      rv->grid1_add[nlink+n] = src_add[n];
-      rv->grid2_add[nlink+n] = dst_add;
+      rv->src_grid_add[nlink+n] = src_add[n];
+      rv->tgt_grid_add[nlink+n] = dst_add;
       for ( k = 0; k < 4; ++k )
 	rv->wts[4*(nlink+n)+k] = weights[k][n];
     }
 
 } /* store_link_bicub */
 
-
 /*
   -----------------------------------------------------------------------
 
@@ -2361,11 +2299,12 @@ void store_link_bicub(remapvars_t *rv, int dst_add, const int *restrict src_add,
 
   -----------------------------------------------------------------------
 */
-void remap_bicub(remapgrid_t *rg, remapvars_t *rv)
+void remap_bicub(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
 {
   /*   Local variables */
   int  lwarn = TRUE;
   int  search_result;
+  long tgt_grid_size;
   long n, icount;
   long dst_add;        /*  destination addresss */
   long iter;           /*  iteration counters   */
@@ -2378,24 +2317,27 @@ void remap_bicub(remapgrid_t *rg, remapvars_t *rv)
 
   double plat, plon;             /*  lat/lon coords of destination point    */
   double findex = 0;
+  int remap_grid_type = src_grid->remap_grid_type;
 
   progressInit();
 
-  /* Compute mappings from grid1 to grid2 */
+  tgt_grid_size = tgt_grid->size;
 
-  if ( rg->grid1_rank != 2 )
-    cdoAbort("Can not do bicubic interpolation when grid1_rank != 2"); 
+  /* Compute mappings from source to target grid */
+
+  if ( src_grid->rank != 2 )
+    cdoAbort("Can not do bicubic interpolation when source grid rank != 2"); 
 
   /* Loop over destination grid */
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, cdoVerbose, rg, rv, Max_Iter, converge, lwarn, findex) \
+  shared(ompNumThreads, cdoTimer, cdoVerbose, remap_grid_type, tgt_grid_size, src_grid, tgt_grid, rv, remap_max_iter, converge, lwarn, findex) \
   private(dst_add, n, icount, iter, src_add, src_lats, src_lons, wgts, plat, plon, search_result) \
   schedule(dynamic,1)
 #endif
   /* grid_loop1 */
-  for ( dst_add = 0; dst_add < rg->grid2_size; ++dst_add )
+  for ( dst_add = 0; dst_add < tgt_grid_size; ++dst_add )
     {
       int lprogress = 1;
 #if defined(_OPENMP)
@@ -2405,24 +2347,29 @@ void remap_bicub(remapgrid_t *rg, remapvars_t *rv)
 #pragma omp atomic
 #endif
       findex++;
-      if ( lprogress ) progressStatus(0, 1, findex/rg->grid2_size);
+      if ( lprogress ) progressStatus(0, 1, findex/tgt_grid_size);
 
-      if ( ! rg->grid2_mask[dst_add] ) continue;
+      if ( ! tgt_grid->mask[dst_add] ) continue;
 
-      plat = rg->grid2_center_lat[dst_add];
-      plon = rg->grid2_center_lon[dst_add];
+      plat = tgt_grid->cell_center_lat[dst_add];
+      plon = tgt_grid->cell_center_lon[dst_add];
 
       /* Find nearest square of grid points on source grid  */
-      search_result = grid_search(rg, src_add, src_lats, src_lons, 
-				  plat, plon, rg->grid1_dims,
-				  rg->grid1_center_lat, rg->grid1_center_lon,
-				  rg->grid1_bound_box, rg->bin_addr1);
+      if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
+	search_result = grid_search_reg2d(src_grid, src_add, src_lats, src_lons, 
+					  plat, plon, src_grid->dims,
+					  src_grid->reg2d_center_lat, src_grid->reg2d_center_lon);
+      else
+	search_result = grid_search(src_grid, src_add, src_lats, src_lons, 
+				    plat, plon, src_grid->dims,
+				    src_grid->cell_center_lat, src_grid->cell_center_lon,
+				    src_grid->cell_bound_box, src_grid->bin_addr);
 
       /* Check to see if points are land points */
       if ( search_result > 0 )
 	{
 	  for ( n = 0; n < 4; ++n )
-	    if ( ! rg->grid1_mask[src_add[n]] ) search_result = 0;
+	    if ( ! src_grid->mask[src_add[n]] ) search_result = 0;
 	}
 
       /* If point found, find local iw,jw coordinates for weights  */
@@ -2430,11 +2377,11 @@ void remap_bicub(remapgrid_t *rg, remapvars_t *rv)
 	{
 	  double iw, jw;  /*  current guess for bilinear coordinate  */
 
-          rg->grid2_frac[dst_add] = ONE;
+          tgt_grid->cell_frac[dst_add] = ONE;
 
 	  iter = find_ij_weights(plon, plat, src_lats, src_lons, &iw, &jw);
 
-          if ( iter < Max_Iter )
+          if ( iter < remap_max_iter )
 	    {
 	      /* Successfully found iw,jw - compute weights */
 
@@ -2465,7 +2412,7 @@ void remap_bicub(remapgrid_t *rg, remapvars_t *rv)
 	      if ( cdoVerbose || lwarn )
 		{
 		  lwarn = FALSE;
-		  // cdoWarning("Iteration for iw,jw exceed max iteration count of %d!", Max_Iter);
+		  // cdoWarning("Iteration for iw,jw exceed max iteration count of %d!", remap_max_iter);
 		  cdoWarning("Bicubic interpolation failed for some grid points - used a distance-weighted average instead!");
 		}
 
@@ -2481,7 +2428,7 @@ void remap_bicub(remapgrid_t *rg, remapvars_t *rv)
           icount = 0;
           for ( n = 0; n < 4; ++n )
 	    {
-	      if ( rg->grid1_mask[src_add[n]] )
+	      if ( src_grid->mask[src_add[n]] )
 		icount++;
 	      else
 		src_lats[n] = ZERO;
@@ -2498,7 +2445,7 @@ void remap_bicub(remapgrid_t *rg, remapvars_t *rv)
 	      for ( n = 0; n < 4; ++n ) wgts[2][n] = ZERO;
 	      for ( n = 0; n < 4; ++n ) wgts[3][n] = ZERO;
 
-	      rg->grid2_frac[dst_add] = ONE;
+	      tgt_grid->cell_frac[dst_add] = ONE;
 
 #if defined(_OPENMP)
 #pragma omp critical
@@ -2517,76 +2464,36 @@ void remap_bicub(remapgrid_t *rg, remapvars_t *rv)
 /*                                                                         */
 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
 
-#define  num_neighbors  4  /* num nearest neighbors to interpolate from */
-
 static
-void get_restrict_add(remapgrid_t *rg, double plat, double plon, const int *restrict src_bin_add,
-		      long *minadd, long *maxadd)
+void get_restrict_add(remapgrid_t *src_grid, double plat, const int *restrict src_bin_add, long *minadd, long *maxadd)
 {
-  long n, n2, nmax;
-  long min_add = 0, max_add = 0, nm1, np1, i, j, ip1, im1, jp1, jm1;
+  long n, n2;
+  long min_add = 0, max_add = 0, nm1, np1;
   long nbins;
-  restr_t rlat, rlon;
+  restr_t rlat;
+  restr_t *bin_lats = src_grid->bin_lats;
+
+  nbins = src_grid->num_srch_bins;
 
-  nbins = rg->num_srch_bins;
   rlat = RESTR_SCALE(plat);
-  rlon = RESTR_SCALE(plon);
 
-  if ( rg->restrict_type == RESTRICT_LATITUDE )
+  for ( n = 0; n < nbins; ++n )
     {
-      for ( n = 0; n < nbins; ++n )
+      n2 = n<<1;
+      if ( rlat >= bin_lats[n2  ] && rlat <= bin_lats[n2+1] )
 	{
-	  n2 = n<<1;
-	  if ( rlat >= rg->bin_lats[n2  ] && rlat <= rg->bin_lats[n2+1] )
-	    {
-	      min_add = src_bin_add[n2  ];
-	      max_add = src_bin_add[n2+1];
-
-	      nm1 = MAX(n-1, 0);
-	      np1 = MIN(n+1, rg->num_srch_bins-1);
+	  min_add = src_bin_add[n2  ];
+	  max_add = src_bin_add[n2+1];
 
-	      min_add = MIN(min_add, src_bin_add[2*nm1  ]);
-	      max_add = MAX(max_add, src_bin_add[2*nm1+1]);
-	      min_add = MIN(min_add, src_bin_add[2*np1  ]);
-	      max_add = MAX(max_add, src_bin_add[2*np1+1]);
-	    }
-	}
-    }
-  else if ( rg->restrict_type == RESTRICT_LATLON )
-    {
-      n = 0;
-      nmax = NINT(sqrt((double)rg->num_srch_bins)) - 1;
-      for ( j = 0; j < nmax; ++j )
-	{
-	  jp1 = MIN(j+1,nmax);
-	  jm1 = MAX(j-1,0);
-	  for ( i = 0; i < nmax; ++i )
-	    {
-	      ip1 = MIN(i+1, nmax);
-	      im1 = MAX(i-1, 0);
+	  nm1 = MAX(n-1, 0);
+	  np1 = MIN(n+1, nbins-1);
 
-	      n = n+1;
-	      if ( rlat >= rg->bin_lats[2*n  ] && rlat <= rg->bin_lats[2*n+1] &&
-		   rlon >= rg->bin_lons[2*n  ] && rlon <= rg->bin_lons[2*n+1] )
-		{
-		  min_add = src_bin_add[2*n  ];
-		  max_add = src_bin_add[2*n+1];
-
-		  nm1 = (jm1-1)*nmax + im1;
-		  np1 = (jp1-1)*nmax + ip1;
-		  nm1 = MAX(nm1, 0);
-		  np1 = MIN(np1, rg->num_srch_bins-1);
-
-		  min_add = MIN(min_add, src_bin_add[2*nm1  ]);
-		  max_add = MAX(max_add, src_bin_add[2*nm1+1]);
-		  min_add = MIN(min_add, src_bin_add[2*np1  ]);
-		  max_add = MAX(max_add, src_bin_add[2*np1+1]);
-		}
-	    }
+	  min_add = MIN(min_add, src_bin_add[2*nm1  ]);
+	  max_add = MAX(max_add, src_bin_add[2*nm1+1]);
+	  min_add = MIN(min_add, src_bin_add[2*np1  ]);
+	  max_add = MAX(max_add, src_bin_add[2*np1+1]);
 	}
     }
-  else
-    cdoAbort("Unknown search restriction method!");
 
   *minadd = min_add;
   *maxadd = max_add;
@@ -2602,11 +2509,12 @@ void get_restrict_add(remapgrid_t *rg, double plat, double plon, const int *rest
    point and computes a distance to each of the neighbors.
 */
 static
-void grid_search_nbr(remapgrid_t *rg, int *restrict nbr_add, double *restrict nbr_dist, 
-		     double plat, double plon, double coslat_dst, double coslon_dst, 
-		     double sinlat_dst, double sinlon_dst, const int *restrict src_bin_add,
-		     const double *restrict sinlat, const double *restrict coslat,
-		     const double *restrict sinlon, const double *restrict coslon)
+void grid_search_nbr_reg2d(int num_neighbors, remapgrid_t *src_grid, int *restrict nbr_add, double *restrict nbr_dist, 
+			   double plat, double plon, const int *restrict src_grid_dims,
+			   double coslat_dst, double coslon_dst, double sinlat_dst, double sinlon_dst,
+			   const double *restrict sinlat, const double *restrict coslat,
+			   const double *restrict sinlon, const double *restrict coslon,
+			   const double *restrict src_center_lat, const double *restrict src_center_lon)
 {
   /*
     Output variables:
@@ -2616,57 +2524,200 @@ void grid_search_nbr(remapgrid_t *rg, int *restrict nbr_add, double *restrict nb
 
     Input variables:
 
-    int src_bin_add[][2]  ! search bins for restricting search
-
     double plat,         ! latitude  of the search point
     double plon,         ! longitude of the search point
-    double coslat_dst,   ! cos(lat)  of the search point
-    double coslon_dst,   ! cos(lon)  of the search point
-    double sinlat_dst,   ! sin(lat)  of the search point
-    double sinlon_dst    ! sin(lon)  of the search point
   */
   /*  Local variables */
+  int lfound;
   long n, nadd, nchk;
-  long min_add, max_add;
-  double distance;     /* Angular distance */
+  long nx, nxm, ny;
+  long ii, jj;
+  long i, j, ix;
+  int src_add[25];
+  long num_add = 0;
+  double distance;   //  Angular distance
+  /*
+  double coslat_dst = cos(plat);  // cos(lat)  of the search point
+  double coslon_dst = cos(plon);  // cos(lon)  of the search point
+  double sinlat_dst = sin(plat);  // sin(lat)  of the search point
+  double sinlon_dst = sin(plon);  // sin(lon)  of the search point
+  */
+  nx = src_grid_dims[0];
+  ny = src_grid_dims[1];
 
-  /* Loop over source grid and find nearest neighbors                         */
-  /* restrict the search using search bins expand the bins to catch neighbors */
+  nxm = nx;
+  if ( src_grid->is_cyclic ) nxm++;
+
+  if ( plon < src_center_lon[0]     ) plon += PI2;
+  if ( plon > src_center_lon[nxm-1] ) plon -= PI2;
+
+  lfound = rect_grid_search(&ii, &jj, plon, plat, nxm, ny, src_center_lon, src_center_lat);
+
+  if ( lfound )
+    {
+      if ( src_grid->is_cyclic && ii == (nxm-1) ) ii = 0;
+
+      for ( j = (jj-2); j <= (jj+2); ++j )
+	for ( i = (ii-2); i <= (ii+2); ++i )
+	  {
+	    ix = i;
+	    
+	    if ( src_grid->is_cyclic )
+	      {
+		if ( ix <   0 ) ix += nx;
+		if ( ix >= nx ) ix -= nx;
+	      }
+
+	    if ( ix >= 0 && ix < nx && j >= 0 && j < ny )
+	      src_add[num_add++] = j*nx+ix;
+	  }
+      /*
+      num_add = 0;
+
+      for ( j = (jj-1); j <= jj; ++j )
+	for ( i = (ii-1); i <= ii; ++i )
+	  {
+	    ix = i;
+	    if ( src_grid->is_cyclic && ix == (nxm-1) ) ix = 0;
 
-  get_restrict_add(rg, plat, plon, src_bin_add, &min_add, &max_add);
+	    src_add[num_add++] = j*nx+ix;
+	  }
+      */
+    }
 
   /* Initialize distance and address arrays */
   for ( n = 0; n < num_neighbors; ++n )
     {
-      nbr_add[n]  = 0;
+      nbr_add[n]  = -1;
       nbr_dist[n] = BIGNUM;
     }
 
-  for ( nadd = min_add; nadd <= max_add; ++nadd )
+  if ( lfound )
     {
-      /* Find distance to this point */
-      distance =  sinlat_dst*sinlat[nadd] + coslat_dst*coslat[nadd]*
-	         (coslon_dst*coslon[nadd] + sinlon_dst*sinlon[nadd]);
-      /* 2008-07-30 Uwe Schulzweida: check that distance is inside the range of -1 to 1,
-                                     otherwise the result of acos(distance) is NaN */
-      if ( distance >  1 ) distance =  1;
-      if ( distance < -1 ) distance = -1;
-      distance = acos(distance);
+      long ix, iy;
 
-      /* Uwe Schulzweida: if distance is zero, set to small number */
-      if ( IS_EQUAL(distance, 0) ) distance = TINY;
-
-      /* Store the address and distance if this is one of the smallest four so far */
-      for ( nchk = 0; nchk < num_neighbors; ++nchk )
+      for ( long na = 0; na < num_add; ++na )
 	{
-          if ( distance < nbr_dist[nchk] )
+	  nadd = src_add[na];
+
+	  iy = nadd/nx;
+	  ix = nadd - iy*nx;
+
+	  /* Find distance to this point */
+	  distance =  sinlat_dst*sinlat[iy] + coslat_dst*coslat[iy]*
+	             (coslon_dst*coslon[ix] + sinlon_dst*sinlon[ix]);
+	  /*
+	  distance =  sinlat_dst*sinlat[nadd] + coslat_dst*coslat[nadd]*
+	             (coslon_dst*coslon[nadd] + sinlon_dst*sinlon[nadd]);
+	  */
+	  /* 2008-07-30 Uwe Schulzweida: check that distance is inside the range of -1 to 1,
+	                                 otherwise the result of acos(distance) is NaN */
+	  if ( distance >  1 ) distance =  1;
+	  if ( distance < -1 ) distance = -1;
+	  distance = acos(distance);
+
+	  /* Uwe Schulzweida: if distance is zero, set to small number */
+	  if ( IS_EQUAL(distance, 0) ) distance = TINY;
+
+	  /* Store the address and distance if this is one of the smallest four so far */
+	  for ( nchk = 0; nchk < num_neighbors; ++nchk )
 	    {
-	      for ( n = num_neighbors-1; n > nchk; --n )
+	      if ( distance < nbr_dist[nchk] )
 		{
-		  nbr_add[n]  = nbr_add[n-1];
-		  nbr_dist[n] = nbr_dist[n-1];
+		  for ( n = num_neighbors-1; n > nchk; --n )
+		    {
+		      nbr_add[n]  = nbr_add[n-1];
+		      nbr_dist[n] = nbr_dist[n-1];
+		    }
+		  nbr_add[nchk]  = nadd;
+		  nbr_dist[nchk] = distance;
+		  break;
 		}
-	      nbr_add[nchk]  = nadd + 1;
+	      else if ( num_neighbors == 1 && distance <= nbr_dist[0] && nadd < nbr_add[0] )
+		{
+		  nbr_add[0]  = nadd;
+		  nbr_dist[0] = distance;
+		}
+	    }
+	}
+    }
+  else if ( src_grid->lextrapolate )
+    {
+      int search_result;
+      search_result = grid_search_reg2d_nn(nx, ny, nbr_add, nbr_dist, plat, plon, src_center_lat, src_center_lon);
+      
+      if ( search_result >= 0 )
+	for ( n = 0; n < 4; ++n ) nbr_add[n] = -1;
+    }
+}  /*  grid_search_nbr_reg2d  */
+
+static
+void grid_search_nbr(int num_neighbors, remapgrid_t *src_grid, int *restrict nbr_add, double *restrict nbr_dist, 
+		     double plat, double plon, const int *restrict src_bin_add,
+		     double coslat_dst, double coslon_dst, double sinlat_dst, double sinlon_dst,
+		     const double *restrict sinlat, const double *restrict coslat,
+		     const double *restrict sinlon, const double *restrict coslon)
+{
+  /*
+    Output variables:
+
+    int nbr_add[num_neighbors]     ! address of each of the closest points
+    double nbr_dist[num_neighbors] ! distance to each of the closest points
+
+    Input variables:
+
+    int src_bin_add[][2]  ! search bins for restricting search
+
+    double plat,         ! latitude  of the search point
+    double plon,         ! longitude of the search point
+  */
+  /*  Local variables */
+  long n, nadd, nchk;
+  long min_add, max_add;
+  double distance;     /* Angular distance */
+  /* result changed a little on a few points with high resolution grid
+  double xcoslat_dst = cos(plat);  // cos(lat)  of the search point
+  double xcoslon_dst = cos(plon);  // cos(lon)  of the search point
+  double xsinlat_dst = sin(plat);  // sin(lat)  of the search point
+  double xsinlon_dst = sin(plon);  // sin(lon)  of the search point
+  */
+  /* Loop over source grid and find nearest neighbors                         */
+  /* restrict the search using search bins expand the bins to catch neighbors */
+
+  get_restrict_add(src_grid, plat, src_bin_add, &min_add, &max_add);
+
+  /* Initialize distance and address arrays */
+  for ( n = 0; n < num_neighbors; ++n )
+    {
+      nbr_add[n]  = -1;
+      nbr_dist[n] = BIGNUM;
+    }
+
+  for ( nadd = min_add; nadd <= max_add; ++nadd )
+    {
+      /* Find distance to this point */
+      distance =  sinlat_dst*sinlat[nadd] + coslat_dst*coslat[nadd]*
+	         (coslon_dst*coslon[nadd] + sinlon_dst*sinlon[nadd]);
+      /* 2008-07-30 Uwe Schulzweida: check that distance is inside the range of -1 to 1,
+                                     otherwise the result of acos(distance) is NaN */
+      if ( distance >  1 ) distance =  1;
+      if ( distance < -1 ) distance = -1;
+      distance = acos(distance);
+
+      /* Uwe Schulzweida: if distance is zero, set to small number */
+      if ( IS_EQUAL(distance, 0) ) distance = TINY;
+
+      /* Store the address and distance if this is one of the smallest four so far */
+      for ( nchk = 0; nchk < num_neighbors; ++nchk )
+	{
+          if ( distance < nbr_dist[nchk] )
+	    {
+	      for ( n = num_neighbors-1; n > nchk; --n )
+		{
+		  nbr_add[n]  = nbr_add[n-1];
+		  nbr_dist[n] = nbr_dist[n-1];
+		}
+	      nbr_add[nchk]  = nadd;
 	      nbr_dist[nchk] = distance;
 	      break;
 	    }
@@ -2684,8 +2735,8 @@ void store_link_nbr(remapvars_t *rv, int add1, int add2, double weights)
 {
   /*
     Input variables:
-    int  add1         ! address on grid1
-    int  add2         ! address on grid2
+    int  add1         ! address on source grid
+    int  add2         ! address on target grid
     double weights    ! remapping weight for this link
   */
   long nlink;
@@ -2700,13 +2751,12 @@ void store_link_nbr(remapvars_t *rv, int add1, int add2, double weights)
   if ( rv->num_links >= rv->max_links ) 
     resize_remap_vars(rv, rv->resize_increment);
 
-  rv->grid1_add[nlink] = add1;
-  rv->grid2_add[nlink] = add2;
-  rv->wts[nlink]       = weights;
+  rv->src_grid_add[nlink] = add1;
+  rv->tgt_grid_add[nlink] = add2;
+  rv->wts[nlink]          = weights;
 
 } /* store_link_nbr */
 
-
 /*
   -----------------------------------------------------------------------
 
@@ -2715,63 +2765,90 @@ void store_link_nbr(remapvars_t *rv, int add1, int add2, double weights)
 
   -----------------------------------------------------------------------
 */
-void remap_distwgt(remapgrid_t *rg, remapvars_t *rv)
+void remap_distwgt(int num_neighbors, remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
 {
   /*  Local variables */
 
-  long grid1_size;
-  long grid2_size;
+  long src_grid_size;
+  long tgt_grid_size;
   long n;
   long dst_add;                   /* destination address                     */
   int nbr_mask[num_neighbors];    /* mask at nearest neighbors               */
   int nbr_add[num_neighbors];     /* source address at nearest neighbors     */
   double nbr_dist[num_neighbors]; /* angular distance four nearest neighbors */
+  double dist_tot;         /* sum of neighbor distances (for normalizing) */
   double coslat_dst;       /* cos(lat) of destination grid point */
   double coslon_dst;       /* cos(lon) of destination grid point */
   double sinlat_dst;       /* sin(lat) of destination grid point */
   double sinlon_dst;       /* sin(lon) of destination grid point */
-  double dist_tot;         /* sum of neighbor distances (for normalizing) */
   double *coslat, *sinlat; /* cosine, sine of grid lats (for distance)    */
   double *coslon, *sinlon; /* cosine, sine of grid lons (for distance)    */
   double wgtstmp;          /* hold the link weight                        */
+  double plat, plon;             /*  lat/lon coords of destination point    */
   double findex = 0;
+  int remap_grid_type = src_grid->remap_grid_type;
 
   progressInit();
 
-  /* Compute mappings from grid1 to grid2 */
+  /* Compute mappings from source to target grid */
 
-  grid1_size = rg->grid1_size;
-  grid2_size = rg->grid2_size;
+  src_grid_size = src_grid->size;
+  tgt_grid_size = tgt_grid->size;
 
   /* Compute cos, sin of lat/lon on source grid for distance calculations */
 
-  coslat = (double *) malloc(grid1_size*sizeof(double));
-  coslon = (double *) malloc(grid1_size*sizeof(double));
-  sinlat = (double *) malloc(grid1_size*sizeof(double));
-  sinlon = (double *) malloc(grid1_size*sizeof(double));
+  if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
+    {
+      long nx = src_grid->dims[0];
+      long ny = src_grid->dims[1];
+
+      coslat = malloc(ny*sizeof(double));
+      coslon = malloc(nx*sizeof(double));
+      sinlat = malloc(ny*sizeof(double));
+      sinlon = malloc(nx*sizeof(double));
+
+      for ( n = 0; n < nx; ++n )
+	{
+	  double rlon = src_grid->reg2d_center_lon[n];
+	  if ( rlon > PI2  ) rlon -= PI2;
+	  if ( rlon < ZERO ) rlon += PI2;
+	  coslon[n] = cos(rlon);
+	  sinlon[n] = sin(rlon);
+	}
+      for ( n = 0; n < ny; ++n )
+	{
+	  coslat[n] = cos(src_grid->reg2d_center_lat[n]);
+	  sinlat[n] = sin(src_grid->reg2d_center_lat[n]);
+	}
+    }
+  else
+    {
+      coslat = malloc(src_grid_size*sizeof(double));
+      coslon = malloc(src_grid_size*sizeof(double));
+      sinlat = malloc(src_grid_size*sizeof(double));
+      sinlon = malloc(src_grid_size*sizeof(double));
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(rg, grid1_size, coslat, coslon, sinlat, sinlon)
+  shared(src_grid, src_grid_size, coslat, coslon, sinlat, sinlon)
 #endif
-  for ( n = 0; n < grid1_size; ++n )
-    {
-      coslat[n] = cos(rg->grid1_center_lat[n]);
-      coslon[n] = cos(rg->grid1_center_lon[n]);
-      sinlat[n] = sin(rg->grid1_center_lat[n]);
-      sinlon[n] = sin(rg->grid1_center_lon[n]);
+      for ( n = 0; n < src_grid_size; ++n )
+	{
+	  coslat[n] = cos(src_grid->cell_center_lat[n]);
+	  coslon[n] = cos(src_grid->cell_center_lon[n]);
+	  sinlat[n] = sin(src_grid->cell_center_lat[n]);
+	  sinlon[n] = sin(src_grid->cell_center_lon[n]);
+	}
     }
 
   /* Loop over destination grid  */
-  /* grid_loop1 */
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, rg, rv, grid2_size, coslat, coslon, sinlat, sinlon, findex) \
-  private(dst_add, n, coslat_dst, coslon_dst, sinlat_dst, sinlon_dst, dist_tot, \
-	  nbr_add, nbr_dist, nbr_mask, wgtstmp)	\
+  shared(ompNumThreads, cdoTimer, num_neighbors, remap_grid_type, src_grid, tgt_grid, rv, tgt_grid_size, coslat, coslon, sinlat, sinlon, findex) \
+  private(dst_add, n, coslat_dst, coslon_dst, sinlat_dst, sinlon_dst, dist_tot, nbr_add, nbr_dist, nbr_mask, wgtstmp, plat, plon) \
   schedule(dynamic,1)
 #endif
-  for ( dst_add = 0; dst_add < grid2_size; ++dst_add )
+  for ( dst_add = 0; dst_add < tgt_grid_size; ++dst_add )
     {
       int lprogress = 1;
 #if defined(_OPENMP)
@@ -2781,37 +2858,42 @@ void remap_distwgt(remapgrid_t *rg, remapvars_t *rv)
 #pragma omp atomic
 #endif
       findex++;
-      if ( lprogress ) progressStatus(0, 1, findex/grid2_size);
-
-      if ( ! rg->grid2_mask[dst_add] ) continue;
+      if ( lprogress ) progressStatus(0, 1, findex/tgt_grid_size);
 
-      coslat_dst = cos(rg->grid2_center_lat[dst_add]);
-      coslon_dst = cos(rg->grid2_center_lon[dst_add]);
-      sinlat_dst = sin(rg->grid2_center_lat[dst_add]);
-      sinlon_dst = sin(rg->grid2_center_lon[dst_add]);
+      if ( ! tgt_grid->mask[dst_add] ) continue;
 	
+      plat = tgt_grid->cell_center_lat[dst_add];
+      plon = tgt_grid->cell_center_lon[dst_add];
+
+      coslat_dst = cos(plat);
+      coslon_dst = cos(plon);
+      sinlat_dst = sin(plat);
+      sinlon_dst = sin(plon);
+
       /* Find nearest grid points on source grid and distances to each point */
+      if ( remap_grid_type == REMAP_GRID_TYPE_REG2D )
+	grid_search_nbr_reg2d(num_neighbors, src_grid, nbr_add, nbr_dist, 
+			      plat, plon, src_grid->dims,
+			      coslat_dst, coslon_dst, sinlat_dst, sinlon_dst,
+			      sinlat, coslat, sinlon, coslon,
+			      src_grid->reg2d_center_lat, src_grid->reg2d_center_lon);
+      else
+	grid_search_nbr(num_neighbors, src_grid, nbr_add, nbr_dist, 
+			plat, plon, src_grid->bin_addr,
+			coslat_dst, coslon_dst, sinlat_dst, sinlon_dst,
+			sinlat, coslat, sinlon, coslon);
 
-      grid_search_nbr(rg, nbr_add, nbr_dist, 
-		      rg->grid2_center_lat[dst_add],
-		      rg->grid2_center_lon[dst_add],
-		      coslat_dst, coslon_dst, 
-		      sinlat_dst, sinlon_dst,
-		      rg->bin_addr1,
-		      sinlat, coslat, sinlon, coslon);
+      /* Compute weights based on inverse distance if mask is false, eliminate those points */
 
-      /*
-         Compute weights based on inverse distance
-	 if mask is false, eliminate those points
-      */
       dist_tot = ZERO;
       for ( n = 0; n < num_neighbors; ++n )
 	{
+	  // printf("dst_add %ld %ld %d %g\n", dst_add, n, nbr_add[n], nbr_dist[n]);
 	  nbr_mask[n] = FALSE;
 
 	  /* Uwe Schulzweida: check if nbr_add is valid */
-	  if ( nbr_add[n] > 0 )
-	    if ( rg->grid1_mask[nbr_add[n]-1] )
+	  if ( nbr_add[n] >= 0 )
+	    if ( src_grid->mask[nbr_add[n]] )
 	      {
 		nbr_dist[n] = ONE/nbr_dist[n];
 		dist_tot = dist_tot + nbr_dist[n];
@@ -2827,15 +2909,14 @@ void remap_distwgt(remapgrid_t *rg, remapvars_t *rv)
 	    {
 	      wgtstmp = nbr_dist[n]/dist_tot;
 
-	      rg->grid2_frac[dst_add] = ONE;
+	      tgt_grid->cell_frac[dst_add] = ONE;
 #if defined(_OPENMP)
 #pragma omp critical
 #endif
-	      store_link_nbr(rv, nbr_add[n]-1, dst_add, wgtstmp);
+	      store_link_nbr(rv, nbr_add[n], dst_add, wgtstmp);
 	    }
 	}
-
-    } /* grid_loop1 */
+    } /* for ( dst_add = 0; dst_add < tgt_grid_size; ++dst_add ) */
 
   free(coslat);
   free(coslon);
@@ -2844,239 +2925,6 @@ void remap_distwgt(remapgrid_t *rg, remapvars_t *rv)
 
 }  /* remap_distwgt */
 
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-/*                                                                         */
-/*      INTERPOLATION USING A DISTANCE-WEIGHTED AVERAGE WITH 1 NEIGHBOR    */
-/*                                                                         */
-/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
-
-/*
-   This routine finds the closest num_neighbor points to a search 
-   point and computes a distance to each of the neighbors.
-*/
-static
-void grid_search_nbr1(remapgrid_t *rg, int *restrict nbr_add, double *restrict nbr_dist, 
-		      double plat, double plon, double coslat_dst, double coslon_dst, 
-		      double sinlat_dst, double sinlon_dst, const int *restrict src_bin_add, 
-                      const double *restrict sinlat, const double *restrict coslat,
-		      const double *restrict sinlon, const double *restrict coslon)
-{
-  /*
-    Output variables:
-
-    int nbr_add[0]     ! address of each of the closest points
-    double nbr_dist[0] ! distance to each of the closest points
-
-    Input variables:
-
-    int src_bin_add[][2] ! search bins for restricting search
-
-    double plat,         ! latitude  of the search point
-    double plon,         ! longitude of the search point
-    double coslat_dst,   ! cos(lat)  of the search point
-    double coslon_dst,   ! cos(lon)  of the search point
-    double sinlat_dst,   ! sin(lat)  of the search point
-    double sinlon_dst    ! sin(lon)  of the search point
-  */
-  /*  Local variables */
-  long nadd;
-  long min_add, max_add;
-  double distance;     /* Angular distance */
-
-  /* Loop over source grid and find nearest neighbors                         */
-  /* restrict the search using search bins expand the bins to catch neighbors */
-
-  get_restrict_add(rg, plat, plon, src_bin_add, &min_add, &max_add);
-
-  /* Initialize distance and address arrays */
-  nbr_add[0]  = 0;
-  nbr_dist[0] = BIGNUM;
-
-  // printf("%g %g  min %d  max %d  range %d\n", plon, plat, min_add, max_add, max_add-min_add);
-  //#define TESTVECTOR
-
-#ifdef  TESTVECTOR
-  long i = 0;
-  long ni = max_add - min_add + 1;
-  double *distvect = malloc(ni*sizeof(double));
-
-  for ( i = 0; i < ni; ++i )
-    {
-      nadd = min_add + i;
-      /* Find distance to this point */
-      distvect[i] =  sinlat_dst*sinlat[nadd] + coslat_dst*coslat[nadd]*
-	            (coslon_dst*coslon[nadd] + sinlon_dst*sinlon[nadd]);
-      /* 2008-07-30 Uwe Schulzweida: check that distance is inside the range of -1 to 1,
-                                     otherwise the result of acos(distance) is NaN */
-      if ( distvect[i] >  1 ) distvect[i] =  1;
-      if ( distvect[i] < -1 ) distvect[i] = -1;
-    }
-
-  for ( i = 0; i < ni; ++i )
-    distvect[i] = acos(distvect[i]);
-
-  /* Store the address and distance if this is the smallest so far */
-  for ( i = 0; i < ni; ++i )
-    if ( distvect[i] < nbr_dist[0] )
-      {
-	nbr_add[0]  = min_add + i + 1;
-	nbr_dist[0] = distvect[i];
-      }
-
-  free(distvect);
-
-#else
-  for ( nadd = min_add; nadd <= max_add; ++nadd )
-    {
-      /* Find distance to this point */
-      distance =  sinlat_dst*sinlat[nadd] + coslat_dst*coslat[nadd]*
-	         (coslon_dst*coslon[nadd] + sinlon_dst*sinlon[nadd]);
-      /* 2008-07-30 Uwe Schulzweida: check that distance is inside the range of -1 to 1,
-                                     otherwise the result of acos(distance) is NaN */
-      if ( distance >  1 ) distance =  1;
-      if ( distance < -1 ) distance = -1;
-      distance = acos(distance);
-
-      /* Store the address and distance if this is the smallest so far */
-      if ( distance < nbr_dist[0] )
-	{
-	  nbr_add[0]  = nadd + 1;
-	  nbr_dist[0] = distance;
-        }
-    }
-#endif
-
-}  /*  grid_search_nbr1  */
-
-/*
-  -----------------------------------------------------------------------
-
-   This routine computes the inverse-distance weights for a
-   nearest-neighbor interpolation.
-
-  -----------------------------------------------------------------------
-*/
-void remap_distwgt1(remapgrid_t *rg, remapvars_t *rv)
-{
-
-  /*  Local variables */
-  long grid1_size;
-  long grid2_size;
-  long n;
-  long dst_add;            /* destination address */
-  int nbr_mask;            /* mask at nearest neighbors */
-  int nbr_add;             /* source address at nearest neighbors     */
-  double nbr_dist;         /* angular distance four nearest neighbors */
-  double coslat_dst;       /* cos(lat) of destination grid point */
-  double coslon_dst;       /* cos(lon) of destination grid point */
-  double sinlat_dst;       /* sin(lat) of destination grid point */
-  double sinlon_dst;       /* sin(lon) of destination grid point */
-  double *coslat, *sinlat; /* cosine, sine of grid lats (for distance)    */
-  double *coslon, *sinlon; /* cosine, sine of grid lons (for distance)    */
-  double wgtstmp;          /* hold the link weight                        */
-  double findex = 0;
-
-  if ( cdoTimer ) timer_start(timer_remap_nn);
-
-  progressInit();
-
-  /* Compute mappings from grid1 to grid2 */
-
-  grid1_size = rg->grid1_size;
-  grid2_size = rg->grid2_size;
-
-  /* Compute cos, sin of lat/lon on source grid for distance calculations */
-
-  coslat = (double *) malloc(grid1_size*sizeof(double));
-  coslon = (double *) malloc(grid1_size*sizeof(double));
-  sinlat = (double *) malloc(grid1_size*sizeof(double));
-  sinlon = (double *) malloc(grid1_size*sizeof(double));
-
-#if defined(_OPENMP)
-#pragma omp parallel for default(none) \
-  shared(rg, grid1_size, coslat, coslon, sinlat, sinlon)
-#endif
-  for ( n = 0; n < grid1_size; ++n )
-    {
-      coslat[n] = cos(rg->grid1_center_lat[n]);
-      coslon[n] = cos(rg->grid1_center_lon[n]);
-      sinlat[n] = sin(rg->grid1_center_lat[n]);
-      sinlon[n] = sin(rg->grid1_center_lon[n]);
-    }
-
-  /* Loop over destination grid  */
-  /* grid_loop1 */
-#if defined(_OPENMP)
-#pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, rg, rv, grid2_size, coslat, coslon, sinlat, sinlon, findex) \
-  private(dst_add, n, coslat_dst, coslon_dst, sinlat_dst, sinlon_dst, nbr_add, nbr_dist, nbr_mask, wgtstmp)	\
-  schedule(dynamic,1)
-#endif
-  for ( dst_add = 0; dst_add < grid2_size; ++dst_add )
-    {
-      int lprogress = 1;
-#if defined(_OPENMP)
-      if ( omp_get_thread_num() != 0 ) lprogress = 0;
-#endif
-#if defined(_OPENMP)
-#pragma omp atomic
-#endif
-      findex++;
-      if ( lprogress ) progressStatus(0, 1, findex/grid2_size);
-
-      if ( ! rg->grid2_mask[dst_add] ) continue;
-
-      coslat_dst = cos(rg->grid2_center_lat[dst_add]);
-      coslon_dst = cos(rg->grid2_center_lon[dst_add]);
-      sinlat_dst = sin(rg->grid2_center_lat[dst_add]);
-      sinlon_dst = sin(rg->grid2_center_lon[dst_add]);
-	
-      /* Find nearest grid points on source grid and  distances to each point */
-
-      grid_search_nbr1(rg, &nbr_add, &nbr_dist,
-		       rg->grid2_center_lat[dst_add],
-		       rg->grid2_center_lon[dst_add],
-		       coslat_dst, coslon_dst, 
-		       sinlat_dst, sinlon_dst,
-		       rg->bin_addr1,
-		       sinlat, coslat, sinlon, coslon);
-
-      /*
-         Compute weights based on inverse distance
-         if mask is false, eliminate those points
-      */
-      nbr_mask = FALSE;
-
-      /* Uwe Schulzweida: check if nbr_add is valid */
-      if ( nbr_add > 0 )
-	if ( rg->grid1_mask[nbr_add-1] )
-	  {
-	    nbr_mask = TRUE;
-	  }
-
-      /* Store the link */
-
-      if ( nbr_mask )
-	{
-	  wgtstmp = ONE;
-
-	  rg->grid2_frac[dst_add] = ONE;
-#if defined(_OPENMP)
-#pragma omp critical
-#endif
-	  store_link_nbr(rv, nbr_add-1, dst_add, wgtstmp);
-	}
-
-    } /* grid_loop1 */
-
-  free(coslat);
-  free(coslon);
-  free(sinlat);
-  free(sinlon);
-
-  if ( cdoTimer ) timer_stop(timer_remap_nn);
-}  /* remap_distwgt1 */
-
 
 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
 /*                                                                         */
@@ -3151,8 +2999,8 @@ void pole_intersection(long *location, double *intrsct_lat, double *intrsct_lon,
 
   /* Convert coordinates */
 
-  srch_corner_x = (double *) malloc(srch_corners*num_srch_cells*sizeof(double));
-  srch_corner_y = (double *) malloc(srch_corners*num_srch_cells*sizeof(double));
+  srch_corner_x = malloc(srch_corners*num_srch_cells*sizeof(double));
+  srch_corner_y = malloc(srch_corners*num_srch_cells*sizeof(double));
 
   if ( beglat > ZERO )
     {
@@ -4073,9 +3921,9 @@ void grid_store_init(grid_store_t *grid_store, long gridsize)
 	    grid_store->blk_size, grid_store->max_size%grid_store->blk_size, 
 	    grid_store->max_size, grid_store->nblocks);
 
-  grid_store->blksize = (int *) malloc(grid_store->nblocks*sizeof(int));
-  grid_store->nlayers = (int *) malloc(grid_store->nblocks*sizeof(int));
-  grid_store->layers  = (grid_layer_t **) malloc(grid_store->nblocks*sizeof(grid_layer_t *));
+  grid_store->blksize = malloc(grid_store->nblocks*sizeof(int));
+  grid_store->nlayers = malloc(grid_store->nblocks*sizeof(int));
+  grid_store->layers  = malloc(grid_store->nblocks*sizeof(grid_layer_t *));
 
   nblocks = grid_store->nblocks;
   for ( iblk = 0; iblk < nblocks; ++iblk )
@@ -4132,13 +3980,13 @@ void grid_store_delete(grid_store_t *grid_store)
     address and weight arrays and resizes those arrays if necessary.
 */
 static
-void store_link_cnsrv_fast(remapvars_t *rv, long add1, long add2, double *weights, grid_store_t *grid_store)
+void store_link_cnsrv_fast(remapvars_t *rv, long add1, long add2, long num_wts, double *weights, grid_store_t *grid_store)
 {
   /*
     Input variables:
-    int  add1         ! address on grid1
-    int  add2         ! address on grid2
-    double weights[6] ! array of remapping weights for this link
+    int  add1         ! address on source grid
+    int  add2         ! address on target grid
+    double weights[]  ! array of remapping weights for this link
   */
   /* Local variables */
   long nlink; /* link index */
@@ -4149,9 +3997,15 @@ void store_link_cnsrv_fast(remapvars_t *rv, long add1, long add2, double *weight
 
   /*  If all weights are ZERO, do not bother storing the link */
 
-  if ( IS_EQUAL(weights[0], 0) && IS_EQUAL(weights[1], 0) && IS_EQUAL(weights[2], 0) &&
-       IS_EQUAL(weights[3], 0) && IS_EQUAL(weights[4], 0) && IS_EQUAL(weights[5], 0) ) return;
-
+  if ( num_wts == 3 )
+    {
+      if ( IS_EQUAL(weights[0], 0) && IS_EQUAL(weights[1], 0) && IS_EQUAL(weights[2], 0) ) return;
+    }
+  else
+    {
+      if ( IS_EQUAL(weights[0], 0) ) return;
+    }
+    
   /* If the link already exists, add the weight to the current weight arrays */
 
   iblk  = BLK_NUM(add2);
@@ -4168,7 +4022,7 @@ void store_link_cnsrv_fast(remapvars_t *rv, long add1, long add2, double *weight
 	{
 	  break;
 	}
-      else if ( add1 == rv->grid1_add[nlink] )
+      else if ( add1 == rv->src_grid_add[nlink] )
 	{
 	  lstore_link = TRUE;
 	  break;
@@ -4178,10 +4032,7 @@ void store_link_cnsrv_fast(remapvars_t *rv, long add1, long add2, double *weight
 
   if ( lstore_link )
     {
-      rv->wts[3*nlink  ] += weights[0];
-      rv->wts[3*nlink+1] += weights[1];
-      rv->wts[3*nlink+2] += weights[2];
-	      
+      for ( i = 0; i < num_wts; ++i ) rv->wts[num_wts*nlink+i] += weights[i];	      
       return;
     }
 
@@ -4198,9 +4049,9 @@ void store_link_cnsrv_fast(remapvars_t *rv, long add1, long add2, double *weight
     }
   else
     {
-      grid_layer = (grid_layer_t *) malloc(sizeof(grid_layer_t));
+      grid_layer = malloc(sizeof(grid_layer_t));
       grid_layer->next = NULL;
-      grid_layer->grid2_link = (int *) malloc(grid_store->blksize[iblk]*sizeof(int));
+      grid_layer->grid2_link = malloc(grid_store->blksize[iblk]*sizeof(int));
 
       blksize = grid_store->blksize[iblk];
       for ( i = 0; i < blksize; ++i )
@@ -4215,12 +4066,10 @@ void store_link_cnsrv_fast(remapvars_t *rv, long add1, long add2, double *weight
   if ( rv->num_links >= rv->max_links )
     resize_remap_vars(rv, rv->resize_increment);
 
-  rv->grid1_add[nlink] = add1;
-  rv->grid2_add[nlink] = add2;
+  rv->src_grid_add[nlink] = add1;
+  rv->tgt_grid_add[nlink] = add2;
 
-  rv->wts[3*nlink  ] = weights[0];
-  rv->wts[3*nlink+1] = weights[1];
-  rv->wts[3*nlink+2] = weights[2];
+  for ( i = 0; i < num_wts; ++i ) rv->wts[num_wts*nlink+i] = weights[i];	      
 
 }  /* store_link_cnsrv_fast */
 
@@ -4235,17 +4084,16 @@ void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict we
 {
   /*
     Input variables:
-    int  add1         ! address on grid1
-    int  add2         ! address on grid2
-    double weights[6] ! array of remapping weights for this link
+    int  add1         ! address on source grid
+    int  add2         ! address on target grid
+    double weights[3] ! array of remapping weights for this link
   */
   /* Local variables */
   long nlink, min_link, max_link; /* link index */
 
   /*  If all weights are ZERO, do not bother storing the link */
 
-  if ( IS_EQUAL(weights[0], 0) && IS_EQUAL(weights[1], 0) && IS_EQUAL(weights[2], 0) &&
-       IS_EQUAL(weights[3], 0) && IS_EQUAL(weights[4], 0) && IS_EQUAL(weights[5], 0) ) return;
+  if ( IS_EQUAL(weights[0], 0) && IS_EQUAL(weights[1], 0) && IS_EQUAL(weights[2], 0) ) return;
 
   /*  Restrict the range of links to search for existing links */
 
@@ -4272,8 +4120,8 @@ void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict we
 	estrip = MIN(max_link-strip+1, STRIPLENGTH);
 	for ( nlink = 0; nlink < estrip; ++nlink )
 	  {
-	    if ( add2 == rv->grid2_add[strip+nlink] &&
-		 add1 == rv->grid1_add[strip+nlink] )
+	    if ( add2 == rv->tgt_grid_add[strip+nlink] &&
+		 add1 == rv->src_grid_add[strip+nlink] )
 	      ilink = strip + nlink;
 	  }
 	if (ilink != (max_link + 1)) break;
@@ -4286,8 +4134,8 @@ void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict we
     long ilink = max_link + 1;
     for ( nlink = min_link; nlink <= max_link; ++nlink )
       {
-	if ( add2 == rv->grid2_add[nlink] )
-	  if ( add1 == rv->grid1_add[nlink] ) ilink = nlink;
+	if ( add2 == rv->tgt_grid_add[nlink] )
+	  if ( add1 == rv->src_grid_add[nlink] ) ilink = nlink;
       }
     if ( ilink != (max_link + 1) ) nlink = ilink;
   }
@@ -4295,8 +4143,8 @@ void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict we
 #else
   for ( nlink = min_link; nlink <= max_link; ++nlink )
     {
-      if ( add2 == rv->grid2_add[nlink] )
-	if ( add1 == rv->grid1_add[nlink] ) break;
+      if ( add2 == rv->tgt_grid_add[nlink] )
+	if ( add1 == rv->src_grid_add[nlink] ) break;
     }
 #endif
 
@@ -4320,8 +4168,8 @@ void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict we
   if ( rv->num_links >= rv->max_links )
     resize_remap_vars(rv, rv->resize_increment);
 
-  rv->grid1_add[nlink] = add1;
-  rv->grid2_add[nlink] = add2;
+  rv->src_grid_add[nlink] = add1;
+  rv->tgt_grid_add[nlink] = add2;
 
   rv->wts[3*nlink  ] = weights[0];
   rv->wts[3*nlink+1] = weights[1];
@@ -4334,28 +4182,125 @@ void store_link_cnsrv(remapvars_t *rv, long add1, long add2, double *restrict we
 
 }  /* store_link_cnsrv */
 
+int rect_grid_search2(long *imin, long *imax, double xmin, double xmax, long nxm, const double *restrict xm);
+
 static
-long get_srch_cells(long grid1_add, long nbins, int *bin_addr1, int *bin_addr2,
-		    restr_t *grid1_bound_box, restr_t *grid2_bound_box, long grid2_size, int *srch_add)
+long get_srch_cells_reg2d(const int *restrict src_grid_dims, 
+			  const double *restrict src_corner_lat, const double *restrict src_corner_lon,
+			  const double *restrict tgt_cell_bound_box, int *srch_add)
 {
+  long nx = src_grid_dims[0];
+  long ny = src_grid_dims[1];
   long num_srch_cells;  /* num cells in restricted search arrays   */
-  long min_add;         /* addresses for restricting search of     */
-  long max_add;         /* destination grid                        */
-  long n, n2;           /* generic counters                        */
-  long grid2_add;       /* current linear address for grid2 cell   */
-  long grid1_addm4, grid2_addm4;
-  int  lmask;
-  restr_t bound_box_lat1, bound_box_lat2, bound_box_lon1, bound_box_lon2;
+  int lfound;
+  long nxp1, nyp1;
+  double src_lon_min, src_lon_max;
+  int debug = 0;
 
-  /* Restrict searches first using search bins */
+  nxp1 = nx+1;
+  nyp1 = ny+1;
 
-  min_add = grid2_size - 1;
-  max_add = 0;
+  src_lon_min = src_corner_lon[0];
+  src_lon_max = src_corner_lon[nx];
 
-  for ( n = 0; n < nbins; ++n )
-    {
-      n2 = n<<1;
-      if ( grid1_add >= bin_addr1[n2] && grid1_add <= bin_addr1[n2+1] )
+  double bound_lon1, bound_lon2;
+
+  num_srch_cells = 0;
+
+  long imin = nxp1, imax = -1, jmin = nyp1, jmax = -1;
+  long im, jm;
+
+  lfound = rect_grid_search2(&jmin, &jmax, tgt_cell_bound_box[0], tgt_cell_bound_box[1], nyp1, src_corner_lat);
+  if ( jmin > 0 ) jmin--;
+  if ( jmax < (ny-2) ) jmax++;
+  bound_lon1 = tgt_cell_bound_box[2];
+  bound_lon2 = tgt_cell_bound_box[3];
+  if ( bound_lon1 <= src_lon_max && bound_lon2 >= src_lon_min )
+    {
+      if ( debug ) printf("  b1 %g %g\n", bound_lon1*RAD2DEG, bound_lon2*RAD2DEG);
+      if ( bound_lon1 < src_lon_min && bound_lon2 > src_lon_min ) bound_lon1 = src_lon_min;
+      if ( bound_lon2 > src_lon_max && bound_lon1 < src_lon_max ) bound_lon2 = src_lon_max;
+      lfound = rect_grid_search2(&imin, &imax, bound_lon1, bound_lon2, nxp1, src_corner_lon);
+      if ( imin != -1 )
+	{
+	  if ( debug )
+	    printf("   %g %g imin %ld  imax %ld  jmin %ld jmax %ld\n", RAD2DEG*src_corner_lon[imin], RAD2DEG*src_corner_lon[imax+1], imin, imax, jmin, jmax);
+	  for ( jm = jmin; jm <= jmax; ++jm )
+	    for ( im = imin; im <= imax; ++im )
+	      srch_add[num_srch_cells++] = jm*nx + im;
+	}
+    }
+
+  bound_lon1 = tgt_cell_bound_box[2];
+  bound_lon2 = tgt_cell_bound_box[3];
+  if ( bound_lon1 <= src_lon_min && bound_lon2 >= src_lon_min )
+    {
+      long imin2 = nxp1, imax2 = -1;
+      bound_lon1 += 2*M_PI;
+      bound_lon2 += 2*M_PI;
+      if ( debug ) printf("  b2 %g %g\n", bound_lon1*RAD2DEG, bound_lon2*RAD2DEG);
+      if ( bound_lon1 < src_lon_min && bound_lon2 > src_lon_min ) bound_lon1 = src_lon_min;
+      if ( bound_lon2 > src_lon_max && bound_lon1 < src_lon_max ) bound_lon2 = src_lon_max;
+      lfound = rect_grid_search2(&imin2, &imax2, bound_lon1, bound_lon2, nxp1, src_corner_lon);
+      if ( imin2 != -1 && imin2 == imax ) imin2 += 1;
+      if ( imax2 != -1 && imax2 == imax ) imax2 += 1;
+      if ( imin2 != -1 )
+	{
+	  if ( debug )
+	    printf("   %g %g imin %ld  imax %ld  jmin %ld jmax %ld\n", RAD2DEG*src_corner_lon[imin2], RAD2DEG*src_corner_lon[imax2+1], imin2, imax2, jmin, jmax);
+	  for ( jm = jmin; jm <= jmax; ++jm )
+	    for ( im = imin2; im <= imax2; ++im )
+	      srch_add[num_srch_cells++] = jm*nx + im;
+	}
+    }
+
+  bound_lon1 = tgt_cell_bound_box[2];
+  bound_lon2 = tgt_cell_bound_box[3];
+  if ( bound_lon1 <= src_lon_max && bound_lon2 >= src_lon_max )
+    {
+      long imin3 = nxp1, imax3 = -1;
+      bound_lon1 -= 2*M_PI;
+      bound_lon2 -= 2*M_PI;
+      if ( debug ) printf("  b3 %g %g\n", bound_lon1*RAD2DEG, bound_lon2*RAD2DEG);
+      if ( bound_lon1 < src_lon_min && bound_lon2 > src_lon_min ) bound_lon1 = src_lon_min;
+      if ( bound_lon2 > src_lon_max && bound_lon1 < src_lon_max ) bound_lon2 = src_lon_max;
+      lfound = rect_grid_search2(&imin3, &imax3, bound_lon1, bound_lon2, nxp1, src_corner_lon);
+      if ( imin3 != -1 && imin3 == imin ) imin3 -= 1;
+      if ( imax3 != -1 && imax3 == imin ) imax3 -= 1;
+      if ( imin3 != -1 )
+	{
+	  if ( debug )
+	    printf("   %g %g imin %ld  imax %ld  jmin %ld jmax %ld\n", RAD2DEG*src_corner_lon[imin3], RAD2DEG*src_corner_lon[imax3+1], imin3, imax3, jmin, jmax);
+	  for ( jm = jmin; jm <= jmax; ++jm )
+	    for ( im = imin3; im <= imax3; ++im )
+	      srch_add[num_srch_cells++] = jm*nx + im;
+	}
+    }
+
+  return (num_srch_cells);
+}
+
+static
+long get_srch_cells(long tgt_grid_add, long nbins, int *bin_addr1, int *bin_addr2,
+		    restr_t *tgt_cell_bound_box, restr_t *src_cell_bound_box, long src_grid_size, int *srch_add)
+{
+  long num_srch_cells;  /* num cells in restricted search arrays   */
+  long min_add;         /* addresses for restricting search of     */
+  long max_add;         /* destination grid                        */
+  long n, n2;           /* generic counters                        */
+  long src_grid_add;    /* current linear address for src cell     */
+  long src_grid_addm4;
+  restr_t bound_box_lat1, bound_box_lat2, bound_box_lon1, bound_box_lon2;
+
+  /* Restrict searches first using search bins */
+
+  min_add = src_grid_size - 1;
+  max_add = 0;
+
+  for ( n = 0; n < nbins; ++n )
+    {
+      n2 = n<<1;
+      if ( tgt_grid_add >= bin_addr1[n2] && tgt_grid_add <= bin_addr1[n2+1] )
 	{
 	  if ( bin_addr2[n2  ] < min_add ) min_add = bin_addr2[n2  ];
 	  if ( bin_addr2[n2+1] > max_add ) max_add = bin_addr2[n2+1];
@@ -4364,44 +4309,66 @@ long get_srch_cells(long grid1_add, long nbins, int *bin_addr1, int *bin_addr2,
 
   /* Further restrict searches using bounding boxes */
 
-  grid1_addm4 = grid1_add<<2;
-  bound_box_lat1 = grid1_bound_box[grid1_addm4  ];
-  bound_box_lat2 = grid1_bound_box[grid1_addm4+1];
-  bound_box_lon1 = grid1_bound_box[grid1_addm4+2];
-  bound_box_lon2 = grid1_bound_box[grid1_addm4+3];
+  bound_box_lat1 = tgt_cell_bound_box[0];
+  bound_box_lat2 = tgt_cell_bound_box[1];
+  bound_box_lon1 = tgt_cell_bound_box[2];
+  bound_box_lon2 = tgt_cell_bound_box[3];
 
   num_srch_cells = 0;
-  for ( grid2_add = min_add; grid2_add <= max_add; ++grid2_add )
+  for ( src_grid_add = min_add; src_grid_add <= max_add; ++src_grid_add )
+    {
+      src_grid_addm4 = src_grid_add<<2;
+      if ( (src_cell_bound_box[src_grid_addm4+2] <= bound_box_lon2)  &&
+	   (src_cell_bound_box[src_grid_addm4+3] >= bound_box_lon1) )
+	{
+	  if ( (src_cell_bound_box[src_grid_addm4  ] <= bound_box_lat2)  &&
+	       (src_cell_bound_box[src_grid_addm4+1] >= bound_box_lat1) )
+	    {
+	      srch_add[num_srch_cells] = src_grid_add;
+	      num_srch_cells++;
+	    }
+	}
+    }
+
+  if ( bound_box_lon1 < RESTR_SCALE(0.) || bound_box_lon2 > RESTR_SCALE(PI2) )
     {
-      grid2_addm4 = grid2_add<<2;
-      lmask = (grid2_bound_box[grid2_addm4  ] <= bound_box_lat2)  &&
-	      (grid2_bound_box[grid2_addm4+1] >= bound_box_lat1)  &&
-	      (grid2_bound_box[grid2_addm4+2] <= bound_box_lon2)  &&
-	      (grid2_bound_box[grid2_addm4+3] >= bound_box_lon1);
+      if ( bound_box_lon1 < RESTR_SCALE(0.) )
+	{
+	  bound_box_lon1 += RESTR_SCALE(PI2);
+	  bound_box_lon2 += RESTR_SCALE(PI2);
+	}
+      else
+	{
+	  bound_box_lon1 -= RESTR_SCALE(PI2);
+	  bound_box_lon2 -= RESTR_SCALE(PI2);
+	}
 
-      if ( lmask )
+      for ( src_grid_add = min_add; src_grid_add <= max_add; ++src_grid_add )
 	{
-	  srch_add[num_srch_cells] = grid2_add;
-	  num_srch_cells++;
+	  src_grid_addm4 = src_grid_add<<2;
+	  if ( (src_cell_bound_box[src_grid_addm4+2] <= bound_box_lon2)  &&
+	       (src_cell_bound_box[src_grid_addm4+3] >= bound_box_lon1) )
+	    {
+	      if ( (src_cell_bound_box[src_grid_addm4  ] <= bound_box_lat2)  &&
+		   (src_cell_bound_box[src_grid_addm4+1] >= bound_box_lat1) )
+		{
+		  long ii;
+		  for ( ii = 0; ii < num_srch_cells; ++ii )
+		    if ( srch_add[ii] == src_grid_add ) break;
+		  
+		  if ( ii == num_srch_cells )
+		    {
+		      srch_add[num_srch_cells] = src_grid_add;
+		      num_srch_cells++;
+		    }
+		}
+	    }
 	}
     }
 
   return (num_srch_cells);
 }
 
-#if defined(_OPENMP)
-static
-void *alloc_srch_corner(size_t n)
-{
-  return (malloc(n*sizeof(double)));
-}
-
-static
-void free_srch_corner(void *p)
-{
-  free(p);
-}
-#endif
 
 /*
   -----------------------------------------------------------------------
@@ -4412,7 +4379,7 @@ void free_srch_corner(void *p)
 
   -----------------------------------------------------------------------
 */
-void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
+void remap_conserv(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
 {
   /* local variables */
 
@@ -4421,12 +4388,12 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
   long ioffset;
   long max_subseg = 100000; /* max number of subsegments per segment to prevent infinite loop */
                             /* 1000 is too small!!! */
-  long grid1_size;
-  long grid2_size;
-  long grid1_corners;
-  long grid2_corners;
-  long grid1_add;       /* current linear address for grid1 cell   */
-  long grid2_add;       /* current linear address for grid2 cell   */
+  long src_grid_size;
+  long tgt_grid_size;
+  long src_num_cell_corners;
+  long tgt_num_cell_corners;
+  long src_grid_add;       /* current linear address for source grid cell   */
+  long tgt_grid_add;       /* current linear address for target grid cell   */
   long n, n3, k;        /* generic counters                        */
   long corner;          /* corner of cell that segment starts from */
   long next_corn;       /* corner of cell that segment ends on     */
@@ -4441,21 +4408,20 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
   double beglat, endlat, beglon, endlon;   /* endpoints of current seg.  */
   double norm_factor = 0;                  /* factor for normalizing wts */
 
-  double *grid2_centroid_lat, *grid2_centroid_lon;   /* centroid coords  */
-  double *grid1_centroid_lat, *grid1_centroid_lon;   /* on each grid     */
+  double *tgt_centroid_lat, *tgt_centroid_lon;   /* centroid coords  */
+  double *src_centroid_lat, *src_centroid_lon;   /* on each grid     */
 
   double begseg[2];         /* begin lat/lon for full segment */
   double weights[6];        /* local wgt array */
+  long    num_wts;
 
   long    max_srch_cells;   /* num cells in restricted search arrays  */
   long    num_srch_cells;   /* num cells in restricted search arrays  */
   long    srch_corners;     /* num of corners of srch cells           */
   long    nsrch_corners;
-  int    *srch_add;         /* global address of cells in srch arrays */
-#if defined(_OPENMP)
-  int **srch_add2;
-  int ompthID, i;
-#endif
+  int*    srch_add;         /* global address of cells in srch arrays */
+  int*    srch_add2[ompNumThreads];
+  int     ompthID, i;
   double *srch_corner_lat;  /* lat of each corner of srch cells */
   double *srch_corner_lon;  /* lon of each corner of srch cells */
 
@@ -4479,12 +4445,13 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 
   progressInit();
 
-  nbins = rg->num_srch_bins;
+  nbins = src_grid->num_srch_bins;
+  num_wts = rv->num_wts;
 
-  if ( rg->store_link_fast )
+  if ( remap_store_link_fast )
     {
-      grid_store = (grid_store_t *) malloc(sizeof(grid_store_t));
-      grid_store_init(grid_store, rg->grid2_size);
+      grid_store = malloc(sizeof(grid_store_t));
+      grid_store_init(grid_store, tgt_grid->size);
     }
 
   if ( cdoVerbose )
@@ -4495,23 +4462,23 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 
   if ( cdoTimer ) timer_start(timer_remap_con);
 
-  grid1_size = rg->grid1_size;
-  grid2_size = rg->grid2_size;
+  src_grid_size = src_grid->size;
+  tgt_grid_size = tgt_grid->size;
 
-  grid1_corners = rg->grid1_corners;
-  grid2_corners = rg->grid2_corners;
+  src_num_cell_corners = src_grid->num_cell_corners;
+  tgt_num_cell_corners = tgt_grid->num_cell_corners;
 
-  if ( ! rg->store_link_fast )
+  if ( ! remap_store_link_fast )
     {
-      link_add1[0] = (int *) malloc(grid1_size*sizeof(int));
-      link_add1[1] = (int *) malloc(grid1_size*sizeof(int));
-      link_add2[0] = (int *) malloc(grid2_size*sizeof(int));
-      link_add2[1] = (int *) malloc(grid2_size*sizeof(int));
+      link_add1[0] = malloc(src_grid_size*sizeof(int));
+      link_add1[1] = malloc(src_grid_size*sizeof(int));
+      link_add2[0] = malloc(tgt_grid_size*sizeof(int));
+      link_add2[1] = malloc(tgt_grid_size*sizeof(int));
 
 #if defined(SX)
 #pragma vdir nodep
 #endif
-      for ( n = 0; n < grid1_size; ++n )
+      for ( n = 0; n < src_grid_size; ++n )
 	{
 	  link_add1[0][n] = -1;
 	  link_add1[1][n] = -1;
@@ -4520,7 +4487,7 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 #if defined(SX)
 #pragma vdir nodep
 #endif
-      for ( n = 0; n < grid2_size; ++n )
+      for ( n = 0; n < tgt_grid_size; ++n )
 	{
 	  link_add2[0][n] = -1;
 	  link_add2[1][n] = -1;
@@ -4529,64 +4496,75 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 
   /* Initialize centroid arrays */
 
-  grid1_centroid_lat = (double *) malloc(grid1_size*sizeof(double));
-  grid1_centroid_lon = (double *) malloc(grid1_size*sizeof(double));
-  grid2_centroid_lat = (double *) malloc(grid2_size*sizeof(double));
-  grid2_centroid_lon = (double *) malloc(grid2_size*sizeof(double));
+  src_centroid_lat = malloc(src_grid_size*sizeof(double));
+  src_centroid_lon = malloc(src_grid_size*sizeof(double));
+  tgt_centroid_lat = malloc(tgt_grid_size*sizeof(double));
+  tgt_centroid_lon = malloc(tgt_grid_size*sizeof(double));
 
-  for ( n = 0; n < grid1_size; ++n )
+  for ( n = 0; n < src_grid_size; ++n )
     {
-      grid1_centroid_lat[n] = 0;
-      grid1_centroid_lon[n] = 0;
+      src_centroid_lat[n] = 0;
+      src_centroid_lon[n] = 0;
     }
 
-  for ( n = 0; n < grid2_size; ++n )
+  for ( n = 0; n < tgt_grid_size; ++n )
     {
-      grid2_centroid_lat[n] = 0;
-      grid2_centroid_lon[n] = 0;
+      tgt_centroid_lat[n] = 0;
+      tgt_centroid_lon[n] = 0;
     }
 
-  /*  Integrate around each cell on grid1 */
+  double* srch_corner_lat2[ompNumThreads];
+  double* srch_corner_lon2[ompNumThreads];
+  long max_srch_cells2[ompNumThreads];
+
+  /*  Integrate around each cell on source grid */
 
-#if defined(_OPENMP)
-  srch_add2 = (int **) malloc(ompNumThreads*sizeof(int *));
   for ( i = 0; i < ompNumThreads; ++i )
-    srch_add2[i] = (int *) malloc(grid2_size*sizeof(int));
-#else
-  srch_add = (int *) malloc(grid2_size*sizeof(int));
-#endif
+    {
+      srch_corner_lat2[i] = NULL;
+      srch_corner_lon2[i] = NULL;
+    }
 
-  srch_corners    = grid2_corners;
-  max_srch_cells  = 0;
-  srch_corner_lat = NULL;
-  srch_corner_lon = NULL;
+  for ( i = 0; i < ompNumThreads; ++i )
+    max_srch_cells2[i] = 0;
+
+  for ( i = 0; i < ompNumThreads; ++i )
+    srch_add2[i] = malloc(tgt_grid_size*sizeof(int));
+
+  srch_corners    = tgt_num_cell_corners;
 
   if ( cdoTimer ) timer_start(timer_remap_con_l1);
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, nbins, grid1_centroid_lon, grid1_centroid_lat, \
-         grid_store, link_add1, link_add2, rv, cdoVerbose, max_subseg, \
-	 grid1_corners,	srch_corners, rg, grid2_size, grid1_size, srch_add2, findex) \
-  private(ompthID, srch_add, n, k, num_srch_cells, max_srch_cells, \
-	  grid1_add, grid2_add, ioffset, nsrch_corners, corner, next_corn, beglat, beglon, \
+  shared(ompNumThreads, cdoTimer, nbins, num_wts, src_centroid_lon, src_centroid_lat, \
+         remap_store_link_fast, grid_store, link_add1, link_add2, rv, cdoVerbose, max_subseg, \
+	 srch_corner_lat2, srch_corner_lon2, max_srch_cells2, 		\
+	 src_num_cell_corners,	srch_corners, src_grid, tgt_grid, tgt_grid_size, src_grid_size, srch_add2, findex) \
+  private(ompthID, srch_add, n, k, num_srch_cells, max_srch_cells, 	\
+	  src_grid_add, tgt_grid_add, ioffset, nsrch_corners, corner, next_corn, beglat, beglon, \
 	  endlat, endlon, lrevers, begseg, lbegin, num_subseg, srch_corner_lat, srch_corner_lon, \
 	  weights, intrsct_lat, intrsct_lon, intrsct_lat_off, intrsct_lon_off, intrsct_x, intrsct_y, \
 	  last_loc, lcoinc, lthresh, luse_last, avoid_pole_count, avoid_pole_offset)
 #endif
-  for ( grid1_add = 0; grid1_add < grid1_size; ++grid1_add )
+  for ( src_grid_add = 0; src_grid_add < src_grid_size; ++src_grid_add )
     {
-      int lprogress = 1;
 #if defined(_OPENMP)
       ompthID = omp_get_thread_num();
-      srch_add = srch_add2[ompthID];
-      if ( ompthID != 0 ) lprogress = 0;
+#else
+      ompthID = 0;
 #endif
+
+      int lprogress = 1;
+      if ( ompthID != 0 ) lprogress = 0;
+
 #if defined(_OPENMP)
 #pragma omp atomic
 #endif
       findex++;
-      if ( lprogress ) progressStatus(0, 0.5, findex/grid1_size);
+      if ( lprogress ) progressStatus(0, 0.5, findex/src_grid_size);
+
+      srch_add = srch_add2[ompthID];
 
       lthresh   = FALSE;
       luse_last = FALSE;
@@ -4594,62 +4572,66 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
       avoid_pole_offset = TINY;
 
       /* Get search cells */
-      num_srch_cells = get_srch_cells(grid1_add, nbins, rg->bin_addr1, rg->bin_addr2,
-				      rg->grid1_bound_box, rg->grid2_bound_box , grid2_size, srch_add);
+      num_srch_cells = get_srch_cells(src_grid_add, nbins, src_grid->bin_addr, tgt_grid->bin_addr,
+				      src_grid->cell_bound_box+src_grid_add*4, tgt_grid->cell_bound_box, tgt_grid_size, srch_add);
 
       if ( num_srch_cells == 0 ) continue;
 
       /* Create search arrays */
 
-#if defined(_OPENMP)
-	  srch_corner_lat = (double *) alloc_srch_corner(srch_corners*num_srch_cells);
-	  srch_corner_lon = (double *) alloc_srch_corner(srch_corners*num_srch_cells);
-#else
+      max_srch_cells  = max_srch_cells2[ompthID];
+      srch_corner_lat = srch_corner_lat2[ompthID];
+      srch_corner_lon = srch_corner_lon2[ompthID];
+
       if ( num_srch_cells > max_srch_cells )
 	{
-	  max_srch_cells = num_srch_cells;
-	  srch_corner_lat = (double *) realloc(srch_corner_lat, srch_corners*num_srch_cells*sizeof(double));
-	  srch_corner_lon = (double *) realloc(srch_corner_lon, srch_corners*num_srch_cells*sizeof(double));
+	  srch_corner_lat = realloc(srch_corner_lat, srch_corners*num_srch_cells*sizeof(double));
+	  srch_corner_lon = realloc(srch_corner_lon, srch_corners*num_srch_cells*sizeof(double));
+
+	  max_srch_cells  = num_srch_cells;
+
+	  max_srch_cells2[ompthID]  = max_srch_cells;
+	  srch_corner_lat2[ompthID] = srch_corner_lat;
+	  srch_corner_lon2[ompthID] = srch_corner_lon;
 	}
-#endif
 
       /* gather1 */
       for ( n = 0; n < num_srch_cells; ++n )
 	{
-	  grid2_add = srch_add[n];
-	  ioffset = grid2_add*srch_corners;
+	  tgt_grid_add = srch_add[n];
+	  ioffset = tgt_grid_add*srch_corners;
 
 	  nsrch_corners = n*srch_corners;
 	  for ( k = 0; k < srch_corners; k++ )
 	    {
-	      srch_corner_lat[nsrch_corners+k] = rg->grid2_corner_lat[ioffset+k];
-	      srch_corner_lon[nsrch_corners+k] = rg->grid2_corner_lon[ioffset+k];
+	      srch_corner_lat[nsrch_corners+k] = tgt_grid->cell_corner_lat[ioffset+k];
+	      srch_corner_lon[nsrch_corners+k] = tgt_grid->cell_corner_lon[ioffset+k];
 	    }
 	}
 
       /* Integrate around this cell */
 
-      ioffset = grid1_add*grid1_corners;
+      ioffset = src_grid_add*src_num_cell_corners;
 
-      for ( corner = 0; corner < grid1_corners; ++corner )
+      for ( corner = 0; corner < src_num_cell_corners; ++corner )
 	{
-          next_corn = (corner+1)%grid1_corners;
+          next_corn = (corner+1)%src_num_cell_corners;
 
           /* Define endpoints of the current segment */
 
-          beglat = rg->grid1_corner_lat[ioffset+corner];
-          beglon = rg->grid1_corner_lon[ioffset+corner];
-          endlat = rg->grid1_corner_lat[ioffset+next_corn];
-          endlon = rg->grid1_corner_lon[ioffset+next_corn];
+          beglat = src_grid->cell_corner_lat[ioffset+corner];
+          beglon = src_grid->cell_corner_lon[ioffset+corner];
+          endlat = src_grid->cell_corner_lat[ioffset+next_corn];
+          endlon = src_grid->cell_corner_lon[ioffset+next_corn];
           lrevers = FALSE;
 
 	  /*  To ensure exact path taken during both sweeps, always integrate segments in the same direction (SW to NE). */
           if ( (endlat < beglat) || (IS_EQUAL(endlat, beglat) && endlon < beglon) )
 	    {
-	      beglat = rg->grid1_corner_lat[ioffset+next_corn];
-	      beglon = rg->grid1_corner_lon[ioffset+next_corn];
-	      endlat = rg->grid1_corner_lat[ioffset+corner];
-	      endlon = rg->grid1_corner_lon[ioffset+corner];
+	      beglat = src_grid->cell_corner_lat[ioffset+next_corn];
+	      beglon = src_grid->cell_corner_lon[ioffset+next_corn];
+	      endlat = src_grid->cell_corner_lat[ioffset+corner];
+	      endlon = src_grid->cell_corner_lon[ioffset+corner];
 	      lrevers = TRUE;
 	    }
 
@@ -4674,7 +4656,7 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 		  num_subseg++;
 		  if ( num_subseg >= max_subseg )
 		    cdoAbort("Integration stalled: num_subseg exceeded limit (grid1[%d]: lon1=%g lon2=%g lat1=%g lat2=%g)!",
-			     grid1_add, beglon, endlon, beglat, endlat);
+			     src_grid_add, beglon, endlon, beglat, endlat);
 
 		  /* Uwe Schulzweida: skip very small regions */
 		  if ( num_subseg%1000 == 0 )
@@ -4683,14 +4665,14 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 			{
 			  if ( cdoVerbose )
 			    cdoPrint("Skip very small region (grid1[%d]): lon=%g dlon=%g lat=%g dlat=%g",
-				     grid1_add, beglon, endlon-beglon, beglat, endlat-beglat);
+				     src_grid_add, beglon, endlon-beglon, beglat, endlat-beglat);
 			  break;
 			}
 		    }
 
 		  /* Find next intersection of this segment with a gridline on grid 2. */
 
-		  intersection(&grid2_add, &intrsct_lat, &intrsct_lon, &lcoinc,
+		  intersection(&tgt_grid_add, &intrsct_lat, &intrsct_lon, &lcoinc,
 			       beglat, beglon, endlat, endlon, begseg, 
 			       lbegin, lrevers,
                                num_srch_cells, srch_corners, srch_add,
@@ -4703,12 +4685,12 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 
 		  /* Compute line integral for this subsegment. */
 
-		  if ( grid2_add != -1 )
+		  if ( tgt_grid_add != -1 )
 		    line_integral(weights, beglon, intrsct_lon, beglat, intrsct_lat,
-				  rg->grid1_center_lon[grid1_add], rg->grid2_center_lon[grid2_add]);
+				  src_grid->cell_center_lon[src_grid_add], tgt_grid->cell_center_lon[tgt_grid_add]);
 		  else
 		    line_integral(weights, beglon, intrsct_lon, beglat, intrsct_lat,
-				  rg->grid1_center_lon[grid1_add], rg->grid1_center_lon[grid1_add]);
+				  src_grid->cell_center_lon[src_grid_add], src_grid->cell_center_lon[src_grid_add]);
 
 		  /* If integrating in reverse order, change sign of weights */
 
@@ -4718,26 +4700,26 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 		    Store the appropriate addresses and weights. 
 		    Also add contributions to cell areas and centroids.
 		  */
-		  if ( grid2_add != -1 )
-		    if ( rg->grid1_mask[grid1_add] )
+		  if ( tgt_grid_add != -1 )
+		    if ( src_grid->mask[src_grid_add] )
 		      {
 #if defined(_OPENMP)
 #pragma omp critical
 #endif
 			{
-			  if ( rg->store_link_fast )
-			    store_link_cnsrv_fast(rv, grid1_add, grid2_add, weights, grid_store);
+			  if ( remap_store_link_fast )
+			    store_link_cnsrv_fast(rv, src_grid_add, tgt_grid_add, num_wts, weights, grid_store);
 			  else
-			    store_link_cnsrv(rv, grid1_add, grid2_add, weights, link_add1, link_add2);
+			    store_link_cnsrv(rv, src_grid_add, tgt_grid_add, weights, link_add1, link_add2);
 
-			  rg->grid2_frac[grid2_add] += weights[3];
+			  tgt_grid->cell_frac[tgt_grid_add] += weights[3];
 			}
-			rg->grid1_frac[grid1_add] += weights[0];
+			src_grid->cell_frac[src_grid_add] += weights[0];
 		      }
 
-		  rg->grid1_area[grid1_add]     += weights[0];
-		  grid1_centroid_lat[grid1_add] += weights[1];
-		  grid1_centroid_lon[grid1_add] += weights[2];
+		  src_grid->cell_area[src_grid_add] += weights[0];
+		  src_centroid_lat[src_grid_add] += weights[1];
+		  src_centroid_lon[src_grid_add] += weights[2];
 
 		  /* Reset beglat and beglon for next subsegment. */
 		  beglat = intrsct_lat;
@@ -4746,41 +4728,36 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 	    }
           /* End of segment */
         }
-#if defined(_OPENMP)
-      free_srch_corner(srch_corner_lat);
-      free_srch_corner(srch_corner_lon);
-#endif
     }
 
   if ( cdoTimer ) timer_stop(timer_remap_con_l1);
 
   /* Finished with all cells: deallocate search arrays */
 
-#if ! defined(_OPENMP)
-  if ( srch_corner_lon ) free(srch_corner_lon);
-  if ( srch_corner_lat ) free(srch_corner_lat);
-#endif
+  for ( i = 0; i < ompNumThreads; ++i )
+    {
+      free(srch_corner_lon2[i]);
+      free(srch_corner_lat2[i]);
+    }
 
-#if defined(_OPENMP)
   for ( i = 0; i < ompNumThreads; ++i )
     free(srch_add2[i]);
 
-  free(srch_add2);
-#else
-  free(srch_add);
-#endif
+  /* Integrate around each cell on target grid */
 
-  /* Integrate around each cell on grid2 */
+  for ( i = 0; i < ompNumThreads; ++i )
+    {
+      srch_corner_lat2[i] = NULL;
+      srch_corner_lon2[i] = NULL;
+    }
 
-#if defined(_OPENMP)
-  srch_add2 = (int **) malloc(ompNumThreads*sizeof(int *));
   for ( i = 0; i < ompNumThreads; ++i )
-    srch_add2[i] = (int *) malloc(grid1_size*sizeof(int));
-#else
-  srch_add = (int *) malloc(grid1_size*sizeof(int));
-#endif
+    max_srch_cells2[i] = 0;
+
+  for ( i = 0; i < ompNumThreads; ++i )
+    srch_add2[i] = malloc(src_grid_size*sizeof(int));
 
-  srch_corners    = grid1_corners;
+  srch_corners    = src_num_cell_corners;
   max_srch_cells  = 0;
   srch_corner_lat = NULL;
   srch_corner_lon = NULL;
@@ -4791,28 +4768,34 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(ompNumThreads, cdoTimer, nbins, grid2_centroid_lon, grid2_centroid_lat, \
-         grid_store, link_add1, link_add2, rv, cdoVerbose, max_subseg, \
-	 grid2_corners, srch_corners, rg, grid2_size, grid1_size, srch_add2, findex) \
-  private(ompthID, srch_add, n, k, num_srch_cells, max_srch_cells, \
-	  grid1_add, grid2_add, ioffset, nsrch_corners, corner, next_corn, beglat, beglon, \
+  shared(ompNumThreads, cdoTimer, nbins, num_wts, tgt_centroid_lon, tgt_centroid_lat, \
+         remap_store_link_fast, grid_store, link_add1, link_add2, rv, cdoVerbose, max_subseg, \
+	 srch_corner_lat2, srch_corner_lon2, max_srch_cells2, 		\
+	 tgt_num_cell_corners, srch_corners, src_grid, tgt_grid, tgt_grid_size, src_grid_size, srch_add2, findex) \
+  private(ompthID, srch_add, n, k, num_srch_cells, max_srch_cells,	\
+	  src_grid_add, tgt_grid_add, ioffset, nsrch_corners, corner, next_corn, beglat, beglon, \
 	  endlat, endlon, lrevers, begseg, lbegin, num_subseg, srch_corner_lat, srch_corner_lon, \
 	  weights, intrsct_lat, intrsct_lon, intrsct_lat_off, intrsct_lon_off, intrsct_x, intrsct_y, \
 	  last_loc, lcoinc, lthresh, luse_last, avoid_pole_count, avoid_pole_offset)
 #endif
-  for ( grid2_add = 0; grid2_add < grid2_size; ++grid2_add )
+  for ( tgt_grid_add = 0; tgt_grid_add < tgt_grid_size; ++tgt_grid_add )
     {
-      int lprogress = 1;
 #if defined(_OPENMP)
       ompthID = omp_get_thread_num();
-      srch_add = srch_add2[ompthID];
-      if ( ompthID != 0 ) lprogress = 0;
+#else
+      ompthID = 0;
 #endif
+
+      int lprogress = 1;
+      if ( ompthID != 0 ) lprogress = 0;
+
 #if defined(_OPENMP)
 #pragma omp atomic
 #endif
       findex++;
-      if ( lprogress ) progressStatus(0.5, 0.5, findex/grid2_size);
+      if ( lprogress ) progressStatus(0.5, 0.5, findex/tgt_grid_size);
+
+      srch_add = srch_add2[ompthID];
 
       lthresh   = FALSE;
       luse_last = FALSE;
@@ -4820,60 +4803,64 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
       avoid_pole_offset = TINY;
 
       /* Get search cells */
-      num_srch_cells = get_srch_cells(grid2_add, nbins, rg->bin_addr2, rg->bin_addr1,
-				      rg->grid2_bound_box, rg->grid1_bound_box , grid1_size, srch_add);
+      num_srch_cells = get_srch_cells(tgt_grid_add, nbins, tgt_grid->bin_addr, src_grid->bin_addr,
+				      tgt_grid->cell_bound_box+tgt_grid_add*4, src_grid->cell_bound_box, src_grid_size, srch_add);
 
       if ( num_srch_cells == 0 ) continue;
 
       /* Create search arrays */
       
-#if defined(_OPENMP)
-	  srch_corner_lat = (double *) alloc_srch_corner(srch_corners*num_srch_cells);
-	  srch_corner_lon = (double *) alloc_srch_corner(srch_corners*num_srch_cells);
-#else
+      max_srch_cells  = max_srch_cells2[ompthID];
+      srch_corner_lat = srch_corner_lat2[ompthID];
+      srch_corner_lon = srch_corner_lon2[ompthID];
+
       if ( num_srch_cells > max_srch_cells )
 	{
-	  max_srch_cells = num_srch_cells;
-	  srch_corner_lat = (double *) realloc(srch_corner_lat, srch_corners*num_srch_cells*sizeof(double));
-	  srch_corner_lon = (double *) realloc(srch_corner_lon, srch_corners*num_srch_cells*sizeof(double));
+	  srch_corner_lat = realloc(srch_corner_lat, srch_corners*num_srch_cells*sizeof(double));
+	  srch_corner_lon = realloc(srch_corner_lon, srch_corners*num_srch_cells*sizeof(double));
+
+	  max_srch_cells  = num_srch_cells;
+
+	  max_srch_cells2[ompthID]  = max_srch_cells;
+	  srch_corner_lat2[ompthID] = srch_corner_lat;
+	  srch_corner_lon2[ompthID] = srch_corner_lon;
 	}
-#endif
 
       /* gather2 */
       for ( n = 0; n < num_srch_cells; ++n )
 	{
-	  grid1_add = srch_add[n];
-	  ioffset = grid1_add*srch_corners;
+	  src_grid_add = srch_add[n];
+	  ioffset = src_grid_add*srch_corners;
 
 	  nsrch_corners = n*srch_corners;
 	  for ( k = 0; k < srch_corners; ++k )
 	    {
-	      srch_corner_lat[nsrch_corners+k] = rg->grid1_corner_lat[ioffset+k];
-	      srch_corner_lon[nsrch_corners+k] = rg->grid1_corner_lon[ioffset+k];
+	      srch_corner_lat[nsrch_corners+k] = src_grid->cell_corner_lat[ioffset+k];
+	      srch_corner_lon[nsrch_corners+k] = src_grid->cell_corner_lon[ioffset+k];
 	    }
 	}
 
       /* Integrate around this cell */
 
-      ioffset = grid2_add*grid2_corners;
+      ioffset = tgt_grid_add*tgt_num_cell_corners;
 
-      for ( corner = 0; corner < grid2_corners; ++corner )
+      for ( corner = 0; corner < tgt_num_cell_corners; ++corner )
 	{
-          next_corn = (corner+1)%grid2_corners;
+          next_corn = (corner+1)%tgt_num_cell_corners;
 
-          beglat = rg->grid2_corner_lat[ioffset+corner];
-          beglon = rg->grid2_corner_lon[ioffset+corner];
-          endlat = rg->grid2_corner_lat[ioffset+next_corn];
-          endlon = rg->grid2_corner_lon[ioffset+next_corn];
+          beglat = tgt_grid->cell_corner_lat[ioffset+corner];
+          beglon = tgt_grid->cell_corner_lon[ioffset+corner];
+          endlat = tgt_grid->cell_corner_lat[ioffset+next_corn];
+          endlon = tgt_grid->cell_corner_lon[ioffset+next_corn];
           lrevers = FALSE;
 
 	  /* To ensure exact path taken during both sweeps, always integrate in the same direction */
           if ( (endlat < beglat) || (IS_EQUAL(endlat, beglat) && endlon < beglon) )
 	    {
-	      beglat = rg->grid2_corner_lat[ioffset+next_corn];
-	      beglon = rg->grid2_corner_lon[ioffset+next_corn];
-	      endlat = rg->grid2_corner_lat[ioffset+corner];
-	      endlon = rg->grid2_corner_lon[ioffset+corner];
+	      beglat = tgt_grid->cell_corner_lat[ioffset+next_corn];
+	      beglon = tgt_grid->cell_corner_lon[ioffset+next_corn];
+	      endlat = tgt_grid->cell_corner_lat[ioffset+corner];
+	      endlon = tgt_grid->cell_corner_lon[ioffset+corner];
 	      lrevers = TRUE;
 	    }
 
@@ -4898,7 +4885,7 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 		  num_subseg++;
 		  if ( num_subseg >= max_subseg )
 		    cdoAbort("Integration stalled: num_subseg exceeded limit (grid2[%d]: lon1=%g lon2=%g lat1=%g lat2=%g)!",
-			     grid2_add, beglon, endlon, beglat, endlat);
+			     tgt_grid_add, beglon, endlon, beglat, endlat);
 
 		  /* Uwe Schulzweida: skip very small regions */
 		  if ( num_subseg%1000 == 0 )
@@ -4907,14 +4894,14 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 			{
 			  if ( cdoVerbose )
 			    cdoPrint("Skip very small region (grid2[%d]): lon=%g dlon=%g lat=%g dlat=%g",
-				     grid2_add, beglon, endlon-beglon, beglat, endlat-beglat);
+				     tgt_grid_add, beglon, endlon-beglon, beglat, endlat-beglat);
 			  break;
 			}
 		    }
 
 		  /* Find next intersection of this segment with a gridline on grid 2. */
 
-		  intersection(&grid1_add, &intrsct_lat, &intrsct_lon, &lcoinc,
+		  intersection(&src_grid_add, &intrsct_lat, &intrsct_lon, &lcoinc,
 			       beglat, beglon, endlat, endlon, begseg,
 			       lbegin, lrevers,
                                num_srch_cells, srch_corners, srch_add,
@@ -4927,12 +4914,12 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 
 		  /* Compute line integral for this subsegment. */
 
-		  if ( grid1_add != -1 )
+		  if ( src_grid_add != -1 )
 		    line_integral(weights, beglon, intrsct_lon, beglat, intrsct_lat,
-				  rg->grid1_center_lon[grid1_add], rg->grid2_center_lon[grid2_add]);
+				  src_grid->cell_center_lon[src_grid_add], tgt_grid->cell_center_lon[tgt_grid_add]);
 		  else
 		    line_integral(weights, beglon, intrsct_lon, beglat, intrsct_lat,
-				  rg->grid2_center_lon[grid2_add], rg->grid2_center_lon[grid2_add]);
+				  tgt_grid->cell_center_lon[tgt_grid_add], tgt_grid->cell_center_lon[tgt_grid_add]);
 
 		  /* If integrating in reverse order, change sign of weights */
 
@@ -4943,28 +4930,28 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 		    Also add contributions to cell areas and centroids.
 		    If there is a coincidence, do not store weights
 		    because they have been captured in the previous loop.
-		    The grid1 mask is the master mask
+		    The source grid mask is the master mask
 		  */
-		  if ( ! lcoinc && grid1_add != -1 )
-		    if ( rg->grid1_mask[grid1_add] )
+		  if ( ! lcoinc && src_grid_add != -1 )
+		    if ( src_grid->mask[src_grid_add] )
 		      {
 #if defined(_OPENMP)
 #pragma omp critical
 #endif
 			{
-			  if ( rg->store_link_fast )
-			    store_link_cnsrv_fast(rv, grid1_add, grid2_add, weights, grid_store);
+			  if ( remap_store_link_fast )
+			    store_link_cnsrv_fast(rv, src_grid_add, tgt_grid_add, num_wts, weights, grid_store);
 			  else
-			    store_link_cnsrv(rv, grid1_add, grid2_add, weights, link_add1, link_add2);
+			    store_link_cnsrv(rv, src_grid_add, tgt_grid_add, weights, link_add1, link_add2);
 
-			  rg->grid1_frac[grid1_add] += weights[0];
+			  src_grid->cell_frac[src_grid_add] += weights[0];
 			}
-			rg->grid2_frac[grid2_add] += weights[3];
+			tgt_grid->cell_frac[tgt_grid_add] += weights[3];
 		      }
 
-		  rg->grid2_area[grid2_add]     += weights[3];
-		  grid2_centroid_lat[grid2_add] += weights[4];
-		  grid2_centroid_lon[grid2_add] += weights[5];
+		  tgt_grid->cell_area[tgt_grid_add] += weights[3];
+		  tgt_centroid_lat[tgt_grid_add] += weights[4];
+		  tgt_centroid_lon[tgt_grid_add] += weights[5];
 
 		  /* Reset beglat and beglon for next subsegment. */
 		  beglat = intrsct_lat;
@@ -4973,30 +4960,21 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 	    }
           /* End of segment */
 	}
-#if defined(_OPENMP)
-      free_srch_corner(srch_corner_lat);
-      free_srch_corner(srch_corner_lon);
-#endif
     }
 
   if ( cdoTimer ) timer_stop(timer_remap_con_l2);
 
   /* Finished with all cells: deallocate search arrays */
 
-#if ! defined(_OPENMP)
-  if ( srch_corner_lon ) free(srch_corner_lon);
-  if ( srch_corner_lat ) free(srch_corner_lat);
-#endif
+  for ( i = 0; i < ompNumThreads; ++i )
+    {
+      free(srch_corner_lon2[i]);
+      free(srch_corner_lat2[i]);
+    }
 
-#if defined(_OPENMP)
   for ( i = 0; i < ompNumThreads; ++i )
     free(srch_add2[i]);
 
-  free(srch_add2);
-#else
-  free(srch_add);
-#endif
-
   /*
      Correct for situations where N/S pole not explicitly included in
      grid (i.e. as a grid corner point). If pole is missing from only
@@ -5012,51 +4990,51 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
   weights[4] =  PI*PI;
   weights[5] =  ZERO;
 
-  grid1_add = -1;
+  src_grid_add = -1;
   /* pole_loop1 */
-  for ( n = 0; n < grid1_size; ++n )
-    if ( rg->grid1_area[n] < -THREE*PIH && rg->grid1_center_lat[n] > ZERO )
+  for ( n = 0; n < src_grid_size; ++n )
+    if ( src_grid->cell_area[n] < -THREE*PIH && src_grid->cell_center_lat[n] > ZERO )
       {
-	grid1_add = n;
+	src_grid_add = n;
 #ifndef SX
 	break;
 #endif
       }
 
-  grid2_add = -1;
+  tgt_grid_add = -1;
   /* pole_loop2 */
-  for ( n = 0; n < grid2_size; ++n )
-    if ( rg->grid2_area[n] < -THREE*PIH && rg->grid2_center_lat[n] > ZERO )
+  for ( n = 0; n < tgt_grid_size; ++n )
+    if ( tgt_grid->cell_area[n] < -THREE*PIH && tgt_grid->cell_center_lat[n] > ZERO )
       {
-	grid2_add = n;
+	tgt_grid_add = n;
 #ifndef SX
 	break;
 #endif
       }
 
-  if ( grid1_add != -1 )
+  if ( src_grid_add != -1 )
     {
-      rg->grid1_area[grid1_add]     += weights[0];
-      grid1_centroid_lat[grid1_add] += weights[1];
-      grid1_centroid_lon[grid1_add] += weights[2];
+      src_grid->cell_area[src_grid_add]     += weights[0];
+      src_centroid_lat[src_grid_add] += weights[1];
+      src_centroid_lon[src_grid_add] += weights[2];
     }
 
-  if ( grid2_add != -1 )
+  if ( tgt_grid_add != -1 )
     {
-      rg->grid2_area[grid2_add]     += weights[3];
-      grid2_centroid_lat[grid2_add] += weights[4];
-      grid2_centroid_lon[grid2_add] += weights[5];
+      tgt_grid->cell_area[tgt_grid_add]     += weights[3];
+      tgt_centroid_lat[tgt_grid_add] += weights[4];
+      tgt_centroid_lon[tgt_grid_add] += weights[5];
     }
 
-  if ( grid1_add != -1 && grid2_add != -1 )
+  if ( src_grid_add != -1 && tgt_grid_add != -1 )
     {
-      if ( rg->store_link_fast )
-	store_link_cnsrv_fast(rv, grid1_add, grid2_add, weights, grid_store);
+      if ( remap_store_link_fast )
+	store_link_cnsrv_fast(rv, src_grid_add, tgt_grid_add, num_wts, weights, grid_store);
       else
-	store_link_cnsrv(rv, grid1_add, grid2_add, weights, link_add1, link_add2);
+	store_link_cnsrv(rv, src_grid_add, tgt_grid_add, weights, link_add1, link_add2);
 
-      rg->grid1_frac[grid1_add] += weights[0];
-      rg->grid2_frac[grid2_add] += weights[3];
+      src_grid->cell_frac[src_grid_add] += weights[0];
+      tgt_grid->cell_frac[tgt_grid_add] += weights[3];
     }
 
   /* South Pole */
@@ -5067,54 +5045,54 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
   weights[4] = -PI*PI;
   weights[5] =  ZERO;
 
-  grid1_add = -1;
+  src_grid_add = -1;
   /* pole_loop3 */
-  for ( n = 0; n < grid1_size; ++n )
-    if ( rg->grid1_area[n] < -THREE*PIH && rg->grid1_center_lat[n] < ZERO )
+  for ( n = 0; n < src_grid_size; ++n )
+    if ( src_grid->cell_area[n] < -THREE*PIH && src_grid->cell_center_lat[n] < ZERO )
       {
-	grid1_add = n;
+	src_grid_add = n;
 #ifndef SX
 	break;
 #endif
       }
 
-  grid2_add = -1;
+  tgt_grid_add = -1;
   /* pole_loop4 */
-  for ( n = 0; n < grid2_size; ++n )
-    if ( rg->grid2_area[n] < -THREE*PIH && rg->grid2_center_lat[n] < ZERO )
+  for ( n = 0; n < tgt_grid_size; ++n )
+    if ( tgt_grid->cell_area[n] < -THREE*PIH && tgt_grid->cell_center_lat[n] < ZERO )
       {
-	grid2_add = n;
+	tgt_grid_add = n;
 #ifndef SX
 	break;
 #endif
       }
 
-  if ( grid1_add != -1 )
+  if ( src_grid_add != -1 )
     {
-      rg->grid1_area[grid1_add]     += weights[0];
-      grid1_centroid_lat[grid1_add] += weights[1];
-      grid1_centroid_lon[grid1_add] += weights[2];
+      src_grid->cell_area[src_grid_add]     += weights[0];
+      src_centroid_lat[src_grid_add] += weights[1];
+      src_centroid_lon[src_grid_add] += weights[2];
     }
 
-  if ( grid2_add != -1 )
+  if ( tgt_grid_add != -1 )
     {
-      rg->grid2_area[grid2_add]     += weights[3];
-      grid2_centroid_lat[grid2_add] += weights[4];
-      grid2_centroid_lon[grid2_add] += weights[5];
+      tgt_grid->cell_area[tgt_grid_add]     += weights[3];
+      tgt_centroid_lat[tgt_grid_add] += weights[4];
+      tgt_centroid_lon[tgt_grid_add] += weights[5];
     }
 
-  if ( grid1_add != -1 && grid2_add != -1 )
+  if ( src_grid_add != -1 && tgt_grid_add != -1 )
     {
-      if ( rg->store_link_fast )
-	store_link_cnsrv_fast(rv, grid1_add, grid2_add, weights, grid_store);
+      if ( remap_store_link_fast )
+	store_link_cnsrv_fast(rv, src_grid_add, tgt_grid_add, num_wts, weights, grid_store);
       else
-	store_link_cnsrv(rv, grid1_add, grid2_add, weights, link_add1, link_add2);
+	store_link_cnsrv(rv, src_grid_add, tgt_grid_add, weights, link_add1, link_add2);
 
-      rg->grid1_frac[grid1_add] += weights[0];
-      rg->grid2_frac[grid2_add] += weights[3];
+      src_grid->cell_frac[src_grid_add] += weights[0];
+      tgt_grid->cell_frac[tgt_grid_add] += weights[3];
     }
 
-  if ( rg->store_link_fast )
+  if ( remap_store_link_fast )
     {
       grid_store_delete(grid_store);
       free(grid_store);
@@ -5123,18 +5101,18 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 
   /* Finish centroid computation */
 
-  for ( n = 0; n < grid1_size; ++n )
-    if ( IS_NOT_EQUAL(rg->grid1_area[n], 0) )
+  for ( n = 0; n < src_grid_size; ++n )
+    if ( IS_NOT_EQUAL(src_grid->cell_area[n], 0) )
       {
-        grid1_centroid_lat[n] /= rg->grid1_area[n];
-        grid1_centroid_lon[n] /= rg->grid1_area[n];
+        src_centroid_lat[n] /= src_grid->cell_area[n];
+        src_centroid_lon[n] /= src_grid->cell_area[n];
       }
 
-  for ( n = 0; n < grid2_size; ++n )
-    if ( IS_NOT_EQUAL(rg->grid2_area[n], 0) )
+  for ( n = 0; n < tgt_grid_size; ++n )
+    if ( IS_NOT_EQUAL(tgt_grid->cell_area[n], 0) )
       {
-        grid2_centroid_lat[n] /= rg->grid2_area[n];
-        grid2_centroid_lon[n] /= rg->grid2_area[n];
+        tgt_centroid_lat[n] /= tgt_grid->cell_area[n];
+        tgt_centroid_lon[n] /= tgt_grid->cell_area[n];
       }
 
   /* 2010-10-08 Uwe Schulzweida: remove all links with weights < 0 */
@@ -5165,8 +5143,8 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 		  rv->wts[3*i+1] = rv->wts[3*(i+nd)+1];
 		  rv->wts[3*i+2] = rv->wts[3*(i+nd)+2];
 		  
-		  rv->grid1_add[i] = rv->grid1_add[i+nd];
-		  rv->grid2_add[i] = rv->grid2_add[i+nd];
+		  rv->src_grid_add[i] = rv->src_grid_add[i+nd];
+		  rv->tgt_grid_add[i] = rv->tgt_grid_add[i+nd];
 		}
 	    }
 	}
@@ -5188,23 +5166,23 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 #endif
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(num_links, rv, rg, grid1_centroid_lat, grid1_centroid_lon)		\
-  private(n, n3, grid1_add, grid2_add, weights, norm_factor)
+  shared(num_links, rv, tgt_grid, src_centroid_lat, src_centroid_lon)		\
+  private(n, n3, src_grid_add, tgt_grid_add, weights, norm_factor)
 #endif
       for ( n = 0; n < num_links; ++n )
 	{
 	  n3 = n*3;
-	  grid1_add = rv->grid1_add[n]; grid2_add = rv->grid2_add[n];
+	  src_grid_add = rv->src_grid_add[n]; tgt_grid_add = rv->tgt_grid_add[n];
 	  weights[0] = rv->wts[n3]; weights[1] = rv->wts[n3+1]; weights[2] = rv->wts[n3+2];
 
-          if ( IS_NOT_EQUAL(rg->grid2_area[grid2_add], 0) )
-	    norm_factor = ONE/rg->grid2_area[grid2_add];
+          if ( IS_NOT_EQUAL(tgt_grid->cell_area[tgt_grid_add], 0) )
+	    norm_factor = ONE/tgt_grid->cell_area[tgt_grid_add];
           else
             norm_factor = ZERO;
 
 	  rv->wts[n3  ] =  weights[0]*norm_factor;
-	  rv->wts[n3+1] = (weights[1] - weights[0]*grid1_centroid_lat[grid1_add])*norm_factor;
-	  rv->wts[n3+2] = (weights[2] - weights[0]*grid1_centroid_lon[grid1_add])*norm_factor;
+	  rv->wts[n3+1] = (weights[1] - weights[0]*src_centroid_lat[src_grid_add])*norm_factor;
+	  rv->wts[n3+2] = (weights[2] - weights[0]*src_centroid_lon[src_grid_add])*norm_factor;
 	}
     }
   else if ( rv->norm_opt == NORM_OPT_FRACAREA )
@@ -5214,23 +5192,23 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 #endif
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(num_links, rv, rg, grid1_centroid_lat, grid1_centroid_lon)		\
-  private(n, n3, grid1_add, grid2_add, weights, norm_factor)
+  shared(num_links, rv, tgt_grid, src_centroid_lat, src_centroid_lon)		\
+  private(n, n3, src_grid_add, tgt_grid_add, weights, norm_factor)
 #endif
       for ( n = 0; n < num_links; ++n )
 	{
 	  n3 = n*3;
-	  grid1_add = rv->grid1_add[n]; grid2_add = rv->grid2_add[n];
+	  src_grid_add = rv->src_grid_add[n]; tgt_grid_add = rv->tgt_grid_add[n];
 	  weights[0] = rv->wts[n3]; weights[1] = rv->wts[n3+1]; weights[2] = rv->wts[n3+2];
 
-          if ( IS_NOT_EQUAL(rg->grid2_frac[grid2_add], 0) )
-	    norm_factor = ONE/rg->grid2_frac[grid2_add];
+          if ( IS_NOT_EQUAL(tgt_grid->cell_frac[tgt_grid_add], 0) )
+	    norm_factor = ONE/tgt_grid->cell_frac[tgt_grid_add];
           else
             norm_factor = ZERO;
 
 	  rv->wts[n3  ] =  weights[0]*norm_factor;
-	  rv->wts[n3+1] = (weights[1] - weights[0]*grid1_centroid_lat[grid1_add])*norm_factor;
-	  rv->wts[n3+2] = (weights[2] - weights[0]*grid1_centroid_lon[grid1_add])*norm_factor;
+	  rv->wts[n3+1] = (weights[1] - weights[0]*src_centroid_lat[src_grid_add])*norm_factor;
+	  rv->wts[n3+2] = (weights[2] - weights[0]*src_centroid_lon[src_grid_add])*norm_factor;
 	}
     }
   else if ( rv->norm_opt == NORM_OPT_NONE )
@@ -5240,100 +5218,100 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 #endif
 #if defined(_OPENMP)
 #pragma omp parallel for default(none) \
-  shared(num_links, rv, rg, grid1_centroid_lat, grid1_centroid_lon)	\
-  private(n, n3, grid1_add, grid2_add, weights, norm_factor)
+  shared(num_links, rv, tgt_grid, src_centroid_lat, src_centroid_lon)	\
+  private(n, n3, src_grid_add, tgt_grid_add, weights, norm_factor)
 #endif
       for ( n = 0; n < num_links; ++n )
 	{
 	  n3 = n*3;
-	  grid1_add = rv->grid1_add[n]; grid2_add = rv->grid2_add[n];
+	  src_grid_add = rv->src_grid_add[n]; tgt_grid_add = rv->tgt_grid_add[n];
 	  weights[0] = rv->wts[n3]; weights[1] = rv->wts[n3+1]; weights[2] = rv->wts[n3+2];
 
           norm_factor = ONE;
 
 	  rv->wts[n3  ] =  weights[0]*norm_factor;
-	  rv->wts[n3+1] = (weights[1] - weights[0]*grid1_centroid_lat[grid1_add])*norm_factor;
-	  rv->wts[n3+2] = (weights[2] - weights[0]*grid1_centroid_lon[grid1_add])*norm_factor;
+	  rv->wts[n3+1] = (weights[1] - weights[0]*src_centroid_lat[src_grid_add])*norm_factor;
+	  rv->wts[n3+2] = (weights[2] - weights[0]*src_centroid_lon[src_grid_add])*norm_factor;
 	}
     }
 
   if ( cdoVerbose )
     cdoPrint("Total number of links = %ld", rv->num_links);
 
-  for ( n = 0; n < grid1_size; ++n )
-    if ( IS_NOT_EQUAL(rg->grid1_area[n], 0) ) rg->grid1_frac[n] /= rg->grid1_area[n];
+  for ( n = 0; n < src_grid_size; ++n )
+    if ( IS_NOT_EQUAL(src_grid->cell_area[n], 0) ) src_grid->cell_frac[n] /= src_grid->cell_area[n];
 
-  for ( n = 0; n < grid2_size; ++n )
-    if ( IS_NOT_EQUAL(rg->grid2_area[n], 0) ) rg->grid2_frac[n] /= rg->grid2_area[n];
+  for ( n = 0; n < tgt_grid_size; ++n )
+    if ( IS_NOT_EQUAL(tgt_grid->cell_area[n], 0) ) tgt_grid->cell_frac[n] /= tgt_grid->cell_area[n];
 
   /* Perform some error checking on final weights  */
 
   if ( lcheck )
     {
-      for ( n = 0; n < grid1_size; ++n )
+      for ( n = 0; n < src_grid_size; ++n )
 	{
-	  if ( rg->grid1_area[n] < -.01 )
-	    cdoPrint("Grid 1 area error: %d %g", n, rg->grid1_area[n]);
+	  if ( src_grid->cell_area[n] < -.01 )
+	    cdoPrint("Source grid area error: %d %g", n, src_grid->cell_area[n]);
 
-	  if ( grid1_centroid_lat[n] < -PIH-.01 || grid1_centroid_lat[n] > PIH+.01 )
-	    cdoPrint("Grid 1 centroid lat error: %d %g", n, grid1_centroid_lat[n]);
+	  if ( src_centroid_lat[n] < -PIH-.01 || src_centroid_lat[n] > PIH+.01 )
+	    cdoPrint("Source grid centroid lat error: %d %g", n, src_centroid_lat[n]);
 
-	  grid1_centroid_lat[n] = 0;
-	  grid1_centroid_lon[n] = 0;
+	  src_centroid_lat[n] = 0;
+	  src_centroid_lon[n] = 0;
 	}
 
-      for ( n = 0; n < grid2_size; ++n )
+      for ( n = 0; n < tgt_grid_size; ++n )
 	{
-	  if ( rg->grid2_area[n] < -.01 )
-	    cdoPrint("Grid 2 area error: %d %g", n, rg->grid2_area[n]);
-	  if ( grid2_centroid_lat[n] < -PIH-.01 || grid2_centroid_lat[n] > PIH+.01 )
-	    cdoPrint("Grid 2 centroid lat error: %d %g", n, grid2_centroid_lat[n]);
+	  if ( tgt_grid->cell_area[n] < -.01 )
+	    cdoPrint("Target grid area error: %d %g", n, tgt_grid->cell_area[n]);
+	  if ( tgt_centroid_lat[n] < -PIH-.01 || tgt_centroid_lat[n] > PIH+.01 )
+	    cdoPrint("Target grid centroid lat error: %d %g", n, tgt_centroid_lat[n]);
 
-	  grid2_centroid_lat[n] = 0;
-	  grid2_centroid_lon[n] = 0;
+	  tgt_centroid_lat[n] = 0;
+	  tgt_centroid_lon[n] = 0;
 	}
 
       for ( n = 0; n < num_links; ++n )
 	{
-	  grid1_add = rv->grid1_add[n];
-	  grid2_add = rv->grid2_add[n];
+	  src_grid_add = rv->src_grid_add[n];
+	  tgt_grid_add = rv->tgt_grid_add[n];
 
 	  if ( rv->wts[3*n] < -0.01 )
-	    cdoPrint("Map 1 weight < 0! grid1idx=%d grid2idx=%d nlink=%d wts=%g",
-		     grid1_add, grid2_add, n, rv->wts[3*n]);
+	    cdoPrint("Map weight < 0! grid1idx=%d grid2idx=%d nlink=%d wts=%g",
+		     src_grid_add, tgt_grid_add, n, rv->wts[3*n]);
 
 	  if ( rv->norm_opt != NORM_OPT_NONE && rv->wts[3*n] > 1.01 )
-	    cdoPrint("Map 1 weight > 1! grid1idx=%d grid2idx=%d nlink=%d wts=%g",
-		     grid1_add, grid2_add, n, rv->wts[3*n]);
+	    cdoPrint("Map weight > 1! grid1idx=%d grid2idx=%d nlink=%d wts=%g",
+		     src_grid_add, tgt_grid_add, n, rv->wts[3*n]);
 	}
 
       for ( n = 0; n < num_links; ++n )
 	{
-	  grid2_add = rv->grid2_add[n];
-	  grid2_centroid_lat[grid2_add] += rv->wts[3*n];
+	  tgt_grid_add = rv->tgt_grid_add[n];
+	  tgt_centroid_lat[tgt_grid_add] += rv->wts[3*n];
 	}
 
-      /* 2012-01-24 Uwe Schulzweida: changed [grid2_add] to [n] (bug fix) */
-      for ( n = 0; n < grid2_size; ++n )
+      /* 2012-01-24 Uwe Schulzweida: changed [tgt_grid_add] to [n] (bug fix) */
+      for ( n = 0; n < tgt_grid_size; ++n )
 	{
 	  if ( rv->norm_opt == NORM_OPT_DESTAREA )
-	    norm_factor = rg->grid2_frac[n];
+	    norm_factor = tgt_grid->cell_frac[n];
 	  else if ( rv->norm_opt == NORM_OPT_FRACAREA )
 	    norm_factor = ONE;
 	  else if ( rv->norm_opt == NORM_OPT_NONE )
-	    norm_factor = rg->grid2_area[n];
+	    norm_factor = tgt_grid->cell_area[n];
 	    
-	  if ( grid2_centroid_lat[n] > 0 && fabs(grid2_centroid_lat[n] - norm_factor) > .01 )
-	    cdoPrint("Error: sum of wts for map1 %d %g %g", n, grid2_centroid_lat[n], norm_factor);
+	  if ( tgt_centroid_lat[n] > 0 && fabs(tgt_centroid_lat[n] - norm_factor) > .01 )
+	    cdoPrint("Error: sum of wts for map1 %d %g %g", n, tgt_centroid_lat[n], norm_factor);
 	}
     } // lcheck
 
-  free(grid1_centroid_lat);
-  free(grid1_centroid_lon);
-  free(grid2_centroid_lat);
-  free(grid2_centroid_lon);
+  free(src_centroid_lat);
+  free(src_centroid_lon);
+  free(tgt_centroid_lat);
+  free(tgt_centroid_lon);
 
-  if ( ! rg->store_link_fast )
+  if ( ! remap_store_link_fast )
     {
       free(link_add1[0]);
       free(link_add1[1]);
@@ -5345,14 +5323,792 @@ void remap_conserv(remapgrid_t *rg, remapvars_t *rv)
 
 } /* remap_conserv */
 
+/*
+  -----------------------------------------------------------------------
+
+  -----------------------------------------------------------------------
+*/
+static
+void restrict_boundbox(const double *restrict grid_bound_box, double *restrict bound_box)
+{
+  if ( bound_box[0] < grid_bound_box[0] && bound_box[1] > grid_bound_box[0] ) bound_box[0] = grid_bound_box[0];
+  if ( bound_box[1] > grid_bound_box[1] && bound_box[0] < grid_bound_box[1] ) bound_box[1] = grid_bound_box[1];
+
+  if ( bound_box[2] >= grid_bound_box[3] && (bound_box[3]-2*M_PI) > grid_bound_box[2] ) { bound_box[2] -= 2*M_PI; bound_box[3] -= 2*M_PI; }
+  if ( bound_box[3] <= grid_bound_box[2] && (bound_box[2]-2*M_PI) < grid_bound_box[3] ) { bound_box[2] += 2*M_PI; bound_box[3] += 2*M_PI; }
+  //  if ( bound_box[2] < grid_bound_box[2] && bound_box[3] > grid_bound_box[2] ) bound_box[2] = grid_bound_box[2];
+  //  if ( bound_box[3] > grid_bound_box[3] && bound_box[2] < grid_bound_box[3] ) bound_box[3] = grid_bound_box[3];
+}
+
+static
+void boundbox_from_corners_reg2d(long grid_add, const int *restrict grid_dims, const double *restrict corner_lon,
+				 const double *restrict corner_lat, double *restrict bound_box)
+{
+  long nx = grid_dims[0];
+  long ix, iy;
+  double clat1, clat2;
+
+  iy = grid_add/nx;
+  ix = grid_add - iy*nx;
+
+  clat1 = corner_lat[iy  ];
+  clat2 = corner_lat[iy+1];
+
+  if ( clat2 > clat1 )
+    {
+      bound_box[0] = clat1;
+      bound_box[1] = clat2;
+    }
+  else
+    {
+      bound_box[0] = clat2;
+      bound_box[1] = clat1;
+    }
+
+  bound_box[2] = corner_lon[ix  ];
+  bound_box[3] = corner_lon[ix+1];
+}
+
+static
+void boundbox_from_corners1(long ic, long nc, const double *restrict corner_lon,
+			    const double *restrict corner_lat, double *restrict bound_box)
+{
+  long inc, j;
+  double clon, clat;
+
+  inc = ic*nc;
+
+  clat = corner_lat[inc];
+  clon = corner_lon[inc];
+
+  bound_box[0] = clat;
+  bound_box[1] = clat;
+  bound_box[2] = clon;
+  bound_box[3] = clon;
+
+  for ( j = 1; j < nc; ++j )
+    {
+      clat = corner_lat[inc+j];
+      clon = corner_lon[inc+j];
+
+      if ( clat < bound_box[0] ) bound_box[0] = clat;
+      if ( clat > bound_box[1] ) bound_box[1] = clat;
+      if ( clon < bound_box[2] ) bound_box[2] = clon;
+      if ( clon > bound_box[3] ) bound_box[3] = clon;
+    }
+
+  if ( fabs(bound_box[3] - bound_box[2]) > PI )
+    {
+      bound_box[2] = 0;
+      bound_box[3] = PI2;
+    }
+
+  /*
+  double dlon = fabs(bound_box[3] - bound_box[2]);
+
+  if ( dlon > PI )
+    {
+      if ( bound_box[3] > bound_box[2] && (bound_box[3]-PI2) < 0. )
+	{
+	  double tmp = bound_box[2];
+	  bound_box[2] = bound_box[3] - PI2;
+	  bound_box[3] = tmp;
+	}
+      else
+	{
+	  bound_box[2] = 0;
+	  bound_box[3] = PI2;
+	}
+    }
+  */
+}
+
+static
+void boundbox_from_corners1r(long ic, long nc, const double *restrict corner_lon,
+			     const double *restrict corner_lat, restr_t *restrict bound_box)
+{
+  long inc, j;
+  restr_t clon, clat;
+
+  inc = ic*nc;
+
+  clat = RESTR_SCALE(corner_lat[inc]);
+  clon = RESTR_SCALE(corner_lon[inc]);
+
+  bound_box[0] = clat;
+  bound_box[1] = clat;
+  bound_box[2] = clon;
+  bound_box[3] = clon;
+
+  for ( j = 1; j < nc; ++j )
+    {
+      clat = RESTR_SCALE(corner_lat[inc+j]);
+      clon = RESTR_SCALE(corner_lon[inc+j]);
+
+      if ( clat < bound_box[0] ) bound_box[0] = clat;
+      if ( clat > bound_box[1] ) bound_box[1] = clat;
+      if ( clon < bound_box[2] ) bound_box[2] = clon;
+      if ( clon > bound_box[3] ) bound_box[3] = clon;
+    }
+
+  if ( fabs(bound_box[3] - bound_box[2]) > RESTR_SCALE(PI) )
+    {
+      bound_box[2] = 0;
+      bound_box[3] = RESTR_SCALE(PI2);
+    }
+  /*
+  if ( RESTR_ABS(bound_box[3] - bound_box[2]) > RESTR_SCALE(PI) )
+    {
+      if ( bound_box[3] > bound_box[2] && (bound_box[3]-RESTR_SCALE(PI2)) < RESTR_SCALE(0.) )
+	{
+	  restr_t tmp = bound_box[2];
+	  bound_box[2] = bound_box[3] - RESTR_SCALE(PI2);
+	  bound_box[3] = tmp;
+	}
+    }
+  */
+}
+
+//#if defined(HAVE_LIBYAC)
+#include "clipping/clipping.h"
+#include "clipping/area.h"
+
+static
+void cdo_compute_overlap_areas(unsigned N,
+			       struct grid_cell *overlap_buffer,
+			       struct grid_cell *source_cells,
+			       struct grid_cell  target_cell,
+			       double *partial_areas)
+{
+  for ( unsigned n = 0; n < N; n++ )
+    {
+      overlap_buffer[n].num_corners   = 0;
+      overlap_buffer[n].edge_type     = NULL;
+      overlap_buffer[n].coordinates_x = NULL;
+      overlap_buffer[n].coordinates_y = NULL;
+    }
+
+  /* Do the clipping and get the cell for the overlapping area */
+
+  cell_clipping(N, source_cells, target_cell, overlap_buffer);
+
+  /* Get the partial areas for the overlapping regions */
+
+  for ( unsigned n = 0; n < N; n++ )
+    {
+      partial_areas[n] = huiliers_area(overlap_buffer[n]);
+
+      if ( overlap_buffer[n].coordinates_x != NULL ) free(overlap_buffer[n].coordinates_x);
+      if ( overlap_buffer[n].coordinates_y != NULL ) free(overlap_buffer[n].coordinates_y);
+      if ( overlap_buffer[n].edge_type     != NULL ) free(overlap_buffer[n].edge_type);
+    }
+
+#ifdef VERBOSE
+  for ( unsigned n = 0; n < N; n++ )
+    printf("overlap area : %lf\n", partial_areas[n]);
+#endif
+}
+//#endif
+
+static
+int get_lonlat_circle_index(remapgrid_t *remap_grid)
+{
+  int lonlat_circle_index = -1;
+
+  if ( remap_grid->num_cell_corners == 4 )
+    {
+      if ( remap_grid->remap_grid_type == REMAP_GRID_TYPE_REG2D )
+	{
+	  lonlat_circle_index = 1;
+ 	}
+      else
+	{
+	  const double* cell_corner_lon = remap_grid->cell_corner_lon;
+	  const double* cell_corner_lat = remap_grid->cell_corner_lat;
+	  int gridsize = remap_grid->size;
+	  int num_i = 0, num_eq0 = 0, num_eq1 = 0;
+	  int iadd = gridsize/3-1;
+
+	  if ( iadd == 0 ) iadd++;
+
+	  for ( int i = 0; i < gridsize; i += iadd )
+	    {
+	      num_i++;
+
+	      if ( IS_EQUAL(cell_corner_lon[i*4+1], cell_corner_lon[i*4+2]) &&
+		   IS_EQUAL(cell_corner_lon[i*4+3], cell_corner_lon[i*4+0]) &&
+		   IS_EQUAL(cell_corner_lat[i*4+0], cell_corner_lat[i*4+1]) &&
+		   IS_EQUAL(cell_corner_lat[i*4+2], cell_corner_lat[i*4+3]) )
+		{  
+		  num_eq1++;
+		}
+	      else if ( IS_EQUAL(cell_corner_lon[i*4+0], cell_corner_lon[i*4+1]) &&
+			IS_EQUAL(cell_corner_lon[i*4+2], cell_corner_lon[i*4+3]) &&
+			IS_EQUAL(cell_corner_lat[i*4+1], cell_corner_lat[i*4+2]) &&
+			IS_EQUAL(cell_corner_lat[i*4+3], cell_corner_lat[i*4+0]) )
+		{
+		  num_eq0++;
+		}
+	    }
+
+	  if ( num_i == num_eq1 ) lonlat_circle_index = 1;
+	  if ( num_i == num_eq0 ) lonlat_circle_index = 0;	      
+	}
+    }
+
+  //printf("lonlat_circle_index %d\n", lonlat_circle_index);
+
+  return(lonlat_circle_index);
+}
+
+
+void remap_consphere(remapgrid_t *src_grid, remapgrid_t *tgt_grid, remapvars_t *rv)
+{
+  /* local variables */
+
+  int    lcheck = TRUE;
+
+  long   ioffset;
+  long   src_grid_size;
+  long   tgt_grid_size;
+  long   src_num_cell_corners;
+  long   tgt_num_cell_corners;
+  long   src_grid_add;       /* current linear address for source grid cell   */
+  long   tgt_grid_add;       /* current linear address for target grid cell   */
+  long   n, k;               /* generic counters                        */
+  long   nbins, num_links;
+  double norm_factor = 0;    /* factor for normalizing wts */
+  long   num_wts;
+  long   max_srch_cells;     /* num cells in restricted search arrays  */
+  long   num_srch_cells;     /* num cells in restricted search arrays  */
+  long   srch_corners;       /* num of corners of srch cells           */
+  int*   srch_add;           /* global address of cells in srch arrays */
+  int    ompthID, i;
+
+  /* Variables necessary if segment manages to hit pole */
+  grid_store_t *grid_store = NULL;
+  double findex = 0;
+  long num_weights = 0;
+  long nx = 0, ny = 0;
+  int src_remap_grid_type = src_grid->remap_grid_type;
+  int tgt_remap_grid_type = tgt_grid->remap_grid_type;
+  double src_grid_bound_box[4];
+  int lyac = FALSE;
+
+  progressInit();
+
+  nbins = src_grid->num_srch_bins;
+  num_wts = rv->num_wts;
+
+  if ( remap_store_link_fast )
+    {
+      grid_store = malloc(sizeof(grid_store_t));
+      grid_store_init(grid_store, tgt_grid->size);
+    }
+
+  if ( cdoTimer ) timer_start(timer_remap_con);
+
+  src_grid_size = src_grid->size;
+  tgt_grid_size = tgt_grid->size;
+
+  src_num_cell_corners = src_grid->num_cell_corners;
+  tgt_num_cell_corners = tgt_grid->num_cell_corners;
+
+  enum edge_type great_circle_type[] = {GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE, GREAT_CIRCLE};
+  enum edge_type lonlat_circle_type[] = {LON_CIRCLE, LAT_CIRCLE, LON_CIRCLE, LAT_CIRCLE, LON_CIRCLE, LAT_CIRCLE, LON_CIRCLE, LAT_CIRCLE, LON_CIRCLE};
+
+  enum edge_type *src_edge_type = great_circle_type;
+  enum edge_type *tgt_edge_type = great_circle_type;
+
+  if ( src_num_cell_corners == 4 )
+    {
+      int lonlat_circle_index = get_lonlat_circle_index(src_grid);
+      if ( lonlat_circle_index >= 0 ) src_edge_type = &lonlat_circle_type[lonlat_circle_index];
+    }
+
+  if ( tgt_num_cell_corners == 4 )
+    {
+      int lonlat_circle_index = get_lonlat_circle_index(tgt_grid);
+      if ( lonlat_circle_index >= 0 ) tgt_edge_type = &lonlat_circle_type[lonlat_circle_index];
+    }
+
+  double tgt_area;
+
+  struct grid_cell* tgt_grid_cell;
+  struct grid_cell* tgt_grid_cell2[ompNumThreads];  
+  for ( i = 0; i < ompNumThreads; ++i )
+    {
+      tgt_grid_cell2[i] = malloc(sizeof(struct grid_cell));
+      tgt_grid_cell2[i]->num_corners   = tgt_num_cell_corners;
+      tgt_grid_cell2[i]->edge_type     = tgt_edge_type;
+      tgt_grid_cell2[i]->coordinates_x = malloc(tgt_num_cell_corners*sizeof(double));
+      tgt_grid_cell2[i]->coordinates_y = malloc(tgt_num_cell_corners*sizeof(double));
+    }
+
+  struct grid_cell* src_grid_cells;
+  struct grid_cell* overlap_buffer;
+  struct grid_cell* src_grid_cells2[ompNumThreads];
+  struct grid_cell* overlap_buffer2[ompNumThreads];
+  for ( i = 0; i < ompNumThreads; ++i )
+    {
+      src_grid_cells2[i] = NULL;
+      overlap_buffer2[i] = NULL;
+    }
+
+  double* partial_areas;
+  double* partial_weights;
+  double* partial_areas2[ompNumThreads];
+  double* partial_weights2[ompNumThreads];
+  for ( i = 0; i < ompNumThreads; ++i )
+    {
+      partial_areas2[i]   = NULL;
+      partial_weights2[i] = NULL;
+    }
+
+  long max_srch_cells2[ompNumThreads];
+  for ( i = 0; i < ompNumThreads; ++i )
+    max_srch_cells2[i] = 0;
+
+  int* srch_add2[ompNumThreads];
+  for ( i = 0; i < ompNumThreads; ++i )
+    srch_add2[i] = malloc(src_grid_size*sizeof(int));
+
+  srch_corners = src_num_cell_corners;
+
+  if ( src_remap_grid_type == REMAP_GRID_TYPE_REG2D )
+    {
+      nx = src_grid->dims[0];
+      ny = src_grid->dims[1];
+     
+      src_grid_bound_box[0] = src_grid->reg2d_corner_lat[0];
+      src_grid_bound_box[1] = src_grid->reg2d_corner_lat[ny];
+      if ( src_grid_bound_box[0] > src_grid_bound_box[1] )
+	{
+	  src_grid_bound_box[0] = src_grid->reg2d_corner_lat[ny];
+	  src_grid_bound_box[1] = src_grid->reg2d_corner_lat[0];
+	}
+      src_grid_bound_box[2] = src_grid->reg2d_corner_lon[0];
+      src_grid_bound_box[3] = src_grid->reg2d_corner_lon[nx];
+      //printf("src_grid   lon: %g %g lat: %g %g\n", RAD2DEG*src_grid_bound_box[2],RAD2DEG*src_grid_bound_box[3],RAD2DEG*src_grid_bound_box[0],RAD2DEG*src_grid_bound_box[1] );
+    }
+
+  if ( cdoTimer ) timer_start(timer_remap_con_l2);
+
+  findex = 0;
+
+  int sum_srch_cells = 0;
+  int sum_srch_cells2 = 0;
+
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) \
+  shared(ompNumThreads, cdoTimer, lyac, nbins, num_wts, nx, src_remap_grid_type, tgt_remap_grid_type, src_grid_bound_box,	\
+	 src_edge_type, tgt_edge_type, partial_areas2, partial_weights2,  \
+         remap_store_link_fast, grid_store, rv, cdoVerbose, max_srch_cells2, \
+	 tgt_num_cell_corners, srch_corners, src_grid, tgt_grid, tgt_grid_size, src_grid_size, \
+	 overlap_buffer2, src_grid_cells2, srch_add2, tgt_grid_cell2, findex, sum_srch_cells, sum_srch_cells2) \
+  private(ompthID, srch_add, tgt_grid_cell, tgt_area, n, k, num_weights, num_srch_cells, max_srch_cells,  \
+	  partial_areas, partial_weights, overlap_buffer, src_grid_cells, src_grid_add, tgt_grid_add, ioffset)
+#endif
+  for ( tgt_grid_add = 0; tgt_grid_add < tgt_grid_size; ++tgt_grid_add )
+    {
+#if defined(_OPENMP)
+      ompthID = omp_get_thread_num();
+#else
+      ompthID = 0;
+#endif
+
+      int lprogress = 1;
+      if ( ompthID != 0 ) lprogress = 0;
+
+#if defined(_OPENMP)
+#pragma omp atomic
+#endif
+      findex++;
+      if ( lprogress ) progressStatus(0, 1, findex/tgt_grid_size);
+
+      srch_add = srch_add2[ompthID];
+      tgt_grid_cell = tgt_grid_cell2[ompthID];
+
+      /* Get search cells */
+
+      if ( src_remap_grid_type == REMAP_GRID_TYPE_REG2D && tgt_remap_grid_type == REMAP_GRID_TYPE_REG2D )
+	{
+	  double tgt_cell_bound_box[4];
+	  boundbox_from_corners_reg2d(tgt_grid_add, tgt_grid->dims, tgt_grid->reg2d_corner_lon, tgt_grid->reg2d_corner_lat, tgt_cell_bound_box);
+	  restrict_boundbox(src_grid_bound_box, tgt_cell_bound_box);
+	  if ( cdoVerbose )
+	    printf("bound_box %ld  lon: %g %g lat: %g %g\n",
+		   tgt_grid_add, RAD2DEG*tgt_cell_bound_box[2],RAD2DEG*tgt_cell_bound_box[3],RAD2DEG*tgt_cell_bound_box[0],RAD2DEG*tgt_cell_bound_box[1] );
+	  num_srch_cells = get_srch_cells_reg2d(src_grid->dims, src_grid->reg2d_corner_lat, src_grid->reg2d_corner_lon,
+						tgt_cell_bound_box, srch_add);
+	}
+      else if ( src_remap_grid_type == REMAP_GRID_TYPE_REG2D )
+	{
+	  double tgt_cell_bound_box[4];
+	  boundbox_from_corners1(tgt_grid_add, tgt_num_cell_corners, tgt_grid->cell_corner_lon, tgt_grid->cell_corner_lat, tgt_cell_bound_box);
+	  restrict_boundbox(src_grid_bound_box, tgt_cell_bound_box);
+	  if ( cdoVerbose )
+	    printf("bound_box %ld  lon: %g %g lat: %g %g\n",
+		   tgt_grid_add, RAD2DEG*tgt_cell_bound_box[2],RAD2DEG*tgt_cell_bound_box[3],RAD2DEG*tgt_cell_bound_box[0],RAD2DEG*tgt_cell_bound_box[1] );
+	  num_srch_cells = get_srch_cells_reg2d(src_grid->dims, src_grid->reg2d_corner_lat, src_grid->reg2d_corner_lon,
+						tgt_cell_bound_box, srch_add);
+	}
+      else
+	{
+	  restr_t tgt_cell_bound_box_r[4];
+	  boundbox_from_corners1r(tgt_grid_add, tgt_num_cell_corners, tgt_grid->cell_corner_lon, tgt_grid->cell_corner_lat, tgt_cell_bound_box_r);
+
+	  num_srch_cells = get_srch_cells(tgt_grid_add, nbins, tgt_grid->bin_addr, src_grid->bin_addr,
+					  tgt_cell_bound_box_r, src_grid->cell_bound_box, src_grid_size, srch_add);
+	}
+
+      sum_srch_cells += num_srch_cells;
+
+      if ( cdoVerbose )
+	printf("tgt_grid_add %ld  num_srch_cells %ld\n", tgt_grid_add, num_srch_cells);
+
+      if ( num_srch_cells == 0 ) continue;
+
+      if ( tgt_remap_grid_type == REMAP_GRID_TYPE_REG2D )
+	{
+	  long nx = tgt_grid->dims[0];
+	  long ix, iy;
+
+	  iy = tgt_grid_add/nx;
+	  ix = tgt_grid_add - iy*nx;
+
+	  tgt_grid_cell->coordinates_x[0] = tgt_grid->reg2d_corner_lon[ix  ];
+	  tgt_grid_cell->coordinates_y[0] = tgt_grid->reg2d_corner_lat[iy  ];
+	  tgt_grid_cell->coordinates_x[1] = tgt_grid->reg2d_corner_lon[ix+1];
+	  tgt_grid_cell->coordinates_y[1] = tgt_grid->reg2d_corner_lat[iy  ];
+	  tgt_grid_cell->coordinates_x[2] = tgt_grid->reg2d_corner_lon[ix+1];
+	  tgt_grid_cell->coordinates_y[2] = tgt_grid->reg2d_corner_lat[iy+1];
+	  tgt_grid_cell->coordinates_x[3] = tgt_grid->reg2d_corner_lon[ix  ];
+	  tgt_grid_cell->coordinates_y[3] = tgt_grid->reg2d_corner_lat[iy+1];
+	}
+      else
+	{
+	  for ( int ic = 0; ic < tgt_num_cell_corners; ++ic )
+	    {
+	      tgt_grid_cell->coordinates_x[ic] = tgt_grid->cell_corner_lon[tgt_grid_add*tgt_num_cell_corners+ic];
+	      tgt_grid_cell->coordinates_y[ic] = tgt_grid->cell_corner_lat[tgt_grid_add*tgt_num_cell_corners+ic];
+	    }
+	}
+
+      //printf("target: %ld\n", tgt_grid_add);
+      if ( lyac )
+	// if ( tgt_grid_add == 682 )
+	for ( int n = 0; n < tgt_num_cell_corners; ++n )
+	  {
+	    printf("  TargetCell.coordinates_x[%d] = %g*rad;\n", n, tgt_grid_cell->coordinates_x[n]/DEG2RAD);
+	    printf("  TargetCell.coordinates_y[%d] = %g*rad;\n", n, tgt_grid_cell->coordinates_y[n]/DEG2RAD);
+	  }
+      
+      /* Create search arrays */
+
+      max_srch_cells  = max_srch_cells2[ompthID];
+      partial_areas   = partial_areas2[ompthID];
+      partial_weights = partial_weights2[ompthID];
+      overlap_buffer  = overlap_buffer2[ompthID];
+      src_grid_cells  = src_grid_cells2[ompthID];
+
+      if ( num_srch_cells > max_srch_cells )
+	{
+	  partial_areas   = realloc(partial_areas,   num_srch_cells*sizeof(double));
+	  partial_weights = realloc(partial_weights, num_srch_cells*sizeof(double));
+
+	  overlap_buffer = realloc(overlap_buffer, num_srch_cells*sizeof(struct grid_cell));
+	  src_grid_cells = realloc(src_grid_cells, num_srch_cells*sizeof(struct grid_cell));
+
+	  for ( n = max_srch_cells; n < num_srch_cells; ++n )
+	    {
+	      overlap_buffer[n].num_corners   = 0;
+	      overlap_buffer[n].edge_type     = NULL;
+	      overlap_buffer[n].coordinates_x = NULL;
+	      overlap_buffer[n].coordinates_y = NULL;
+	    }
+
+	  for ( n = max_srch_cells; n < num_srch_cells; ++n )
+	    {
+	      src_grid_cells[n].num_corners   = srch_corners;
+	      src_grid_cells[n].edge_type     = src_edge_type;
+	      src_grid_cells[n].coordinates_x = malloc(srch_corners*sizeof(double));
+	      src_grid_cells[n].coordinates_y = malloc(srch_corners*sizeof(double));
+	    }
+
+	  max_srch_cells = num_srch_cells;
+
+	  max_srch_cells2[ompthID]  = max_srch_cells;
+	  partial_areas2[ompthID]   = partial_areas;
+	  partial_weights2[ompthID] = partial_weights;
+	  overlap_buffer2[ompthID]  = overlap_buffer;
+	  src_grid_cells2[ompthID]  = src_grid_cells;
+	}
+
+      // printf("  int ii = 0;\n");
+      for ( n = 0; n < num_srch_cells; ++n )
+	{
+	  src_grid_add = srch_add[n];
+
+	  if ( src_remap_grid_type == REMAP_GRID_TYPE_REG2D )
+	    {
+	      int ix, iy;
+
+	      iy = src_grid_add/nx;
+	      ix = src_grid_add - iy*nx;
+
+	      src_grid_cells[n].coordinates_x[0] = src_grid->reg2d_corner_lon[ix  ];
+	      src_grid_cells[n].coordinates_y[0] = src_grid->reg2d_corner_lat[iy  ];
+	      src_grid_cells[n].coordinates_x[1] = src_grid->reg2d_corner_lon[ix+1];
+	      src_grid_cells[n].coordinates_y[1] = src_grid->reg2d_corner_lat[iy  ];
+	      src_grid_cells[n].coordinates_x[2] = src_grid->reg2d_corner_lon[ix+1];
+	      src_grid_cells[n].coordinates_y[2] = src_grid->reg2d_corner_lat[iy+1];
+	      src_grid_cells[n].coordinates_x[3] = src_grid->reg2d_corner_lon[ix  ];
+	      src_grid_cells[n].coordinates_y[3] = src_grid->reg2d_corner_lat[iy+1];
+	      /*
+	      printf("source1: %ld %ld", num_srch_cells, n);
+	      for ( k = 0; k < srch_corners; ++k )
+		printf(" %g %g", src_grid_cells[n].coordinates_x[k]/DEG2RAD, src_grid_cells[n].coordinates_y[k]/DEG2RAD);
+	      printf("\n");
+	      */
+	    }
+	  else
+	    {
+	      ioffset = src_grid_add*srch_corners;
+
+	      for ( k = 0; k < srch_corners; ++k )
+		{
+		  src_grid_cells[n].coordinates_x[k] = src_grid->cell_corner_lon[ioffset+k];
+		  src_grid_cells[n].coordinates_y[k] = src_grid->cell_corner_lat[ioffset+k];
+		}
+	      /*
+	      printf("source2: %ld %ld", num_srch_cells, n);
+	      for ( k = 0; k < srch_corners; ++k )
+		printf(" %g %g", src_grid_cells[n].coordinates_x[k]/DEG2RAD, src_grid_cells[n].coordinates_y[k]/DEG2RAD);
+	      printf("\n");
+	      */
+	    }
+
+	  if ( lyac )
+	    //  if ( tgt_grid_add == 682 )
+	    {
+	      printf("n %d\n", (int)n);
+	      for ( k = 0; k < srch_corners; ++k )
+		{
+		  printf("  SourceCell[ii].coordinates_x[%ld] = %g*rad;\n", k, src_grid_cells[n].coordinates_x[k]/DEG2RAD);
+		  printf("  SourceCell[ii].coordinates_y[%ld] = %g*rad;\n", k, src_grid_cells[n].coordinates_y[k]/DEG2RAD);
+		}
+	      printf("  ii++;\n");
+	    }
+	}
+
+      cdo_compute_overlap_areas(num_srch_cells, overlap_buffer, src_grid_cells, *tgt_grid_cell, partial_areas);
+
+      tgt_area = huiliers_area(*tgt_grid_cell);
+      // tgt_area = cell_area(tgt_grid_cell);
+
+      for ( num_weights = 0, n = 0; n < num_srch_cells; ++n )
+	{
+	  if ( partial_areas[n] > 0 )
+	    {
+	      //printf(">>>>   %d %d %g %g\n", (int)tgt_grid_add, srch_add[n], tgt_area, partial_areas[n]);
+	      partial_areas[num_weights] = partial_areas[n];
+	      srch_add[num_weights] = srch_add[n];
+	      num_weights++;
+	    }
+	}
+
+      sum_srch_cells2 += num_weights;
+
+      for ( n = 0; n < num_weights; ++n )
+	partial_weights[n] = partial_areas[n] / tgt_area;
+
+      correct_weights(num_weights, partial_weights);
+      //#endif
+
+      for ( n = 0; n < num_weights; ++n )
+	{
+	  src_grid_add = srch_add[n];
+
+	  if ( cdoVerbose )
+	    printf("tgt_grid_add %ld, src_grid_add %ld,  partial_weights[n] %g, tgt_area  %g\n", tgt_grid_add, src_grid_add, partial_weights[n], tgt_area);
+
+	  // src_grid_add = n;
+	  if ( partial_weights[n] <= 0. ) src_grid_add = -1;
+
+	  /*
+	    Store the appropriate addresses and weights. 
+	    Also add contributions to cell areas.
+	    The source grid mask is the master mask
+	  */
+	  if ( src_grid_add != -1 )
+	    {
+	      if ( src_grid->mask[src_grid_add] )
+		{
+
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+		  {
+		    store_link_cnsrv_fast(rv, src_grid_add, tgt_grid_add, num_wts, &partial_weights[n], grid_store);
+
+		    src_grid->cell_frac[src_grid_add] += partial_weights[n];
+		  }
+		  tgt_grid->cell_frac[tgt_grid_add] += partial_weights[n];
+		}
+#if defined(_OPENMP)
+#pragma omp critical
+#endif
+	      {
+		src_grid->cell_area[src_grid_add] += partial_weights[n];
+	      }
+	    }
+
+	  tgt_grid->cell_area[tgt_grid_add] += partial_weights[n];
+	}
+    }
+
+  if ( cdoVerbose )
+    {
+      printf("sum_srch_cells : %d\n", sum_srch_cells);
+      printf("sum_srch_cells2: %d\n", sum_srch_cells2);
+    }
+
+  if ( cdoTimer ) timer_stop(timer_remap_con_l2);
+
+  /* Finished with all cells: deallocate search arrays */
+
+  for ( i = 0; i < ompNumThreads; ++i )
+    {
+      for ( n = 0; n < max_srch_cells2[i]; n++ )
+	{
+	  free(src_grid_cells2[i][n].coordinates_x);
+	  free(src_grid_cells2[i][n].coordinates_y);
+	}
+      free(src_grid_cells2[i]);
+      free(overlap_buffer2[i]);
+
+      free(partial_areas2[i]);
+      free(partial_weights2[i]);
+
+      free(tgt_grid_cell2[i]->coordinates_x);
+      free(tgt_grid_cell2[i]->coordinates_y);
+      free(tgt_grid_cell2[i]);
+
+      free(srch_add2[i]);
+    }
+
+  if ( remap_store_link_fast )
+    {
+      grid_store_delete(grid_store);
+      free(grid_store);
+    }
+
+
+  /* Normalize using destination area if requested */
+
+  num_links = rv->num_links;
+
+  if ( rv->norm_opt == NORM_OPT_DESTAREA )
+    {
+#if defined(SX)
+#pragma vdir nodep
+#endif
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) \
+  shared(num_wts, num_links, rv, tgt_grid)	\
+  private(n, tgt_grid_add, norm_factor)
+#endif
+      for ( n = 0; n < num_links; ++n )
+	{
+	  tgt_grid_add = rv->tgt_grid_add[n];
+
+          if ( IS_NOT_EQUAL(tgt_grid->cell_area[tgt_grid_add], 0) )
+	    norm_factor = ONE/tgt_grid->cell_area[tgt_grid_add];
+          else
+            norm_factor = ZERO;
+
+	  rv->wts[n*num_wts] *= norm_factor;
+	}
+    }
+  else if ( rv->norm_opt == NORM_OPT_FRACAREA )
+    {
+#if defined(SX)
+#pragma vdir nodep
+#endif
+#if defined(_OPENMP)
+#pragma omp parallel for default(none) \
+  shared(num_wts, num_links, rv, tgt_grid)	\
+  private(n, tgt_grid_add, norm_factor)
+#endif
+      for ( n = 0; n < num_links; ++n )
+	{
+	  tgt_grid_add = rv->tgt_grid_add[n];
+
+          if ( IS_NOT_EQUAL(tgt_grid->cell_frac[tgt_grid_add], 0) )
+	    norm_factor = ONE/tgt_grid->cell_frac[tgt_grid_add];
+          else
+            norm_factor = ZERO;
+
+	  rv->wts[n*num_wts] *= norm_factor;
+	}
+    }
+  else if ( rv->norm_opt == NORM_OPT_NONE )
+    {
+    }
+
+  if ( cdoVerbose )
+    cdoPrint("Total number of links = %ld", rv->num_links);
+
+  for ( n = 0; n < src_grid_size; ++n )
+    if ( IS_NOT_EQUAL(src_grid->cell_area[n], 0) ) src_grid->cell_frac[n] /= src_grid->cell_area[n];
+
+  for ( n = 0; n < tgt_grid_size; ++n )
+    if ( IS_NOT_EQUAL(tgt_grid->cell_area[n], 0) ) tgt_grid->cell_frac[n] /= tgt_grid->cell_area[n];
+
+  /* Perform some error checking on final weights  */
+
+  if ( lcheck )
+    {
+      for ( n = 0; n < src_grid_size; ++n )
+	{
+	  if ( src_grid->cell_area[n] < -.01 )
+	    cdoPrint("Source grid area error: %d %g", n, src_grid->cell_area[n]);
+	}
+
+      for ( n = 0; n < tgt_grid_size; ++n )
+	{
+	  if ( tgt_grid->cell_area[n] < -.01 )
+	    cdoPrint("Target grid area error: %d %g", n, tgt_grid->cell_area[n]);
+	}
+
+      for ( n = 0; n < num_links; ++n )
+	{
+	  src_grid_add = rv->src_grid_add[n];
+	  tgt_grid_add = rv->tgt_grid_add[n];
+
+	  if ( rv->wts[n*num_wts] < -0.01 )
+	    cdoPrint("Map weight < 0! grid1idx=%d grid2idx=%d nlink=%d wts=%g",
+		     src_grid_add, tgt_grid_add, n, rv->wts[n*num_wts]);
+
+	  if ( rv->norm_opt != NORM_OPT_NONE && rv->wts[n*num_wts] > 1.01 )
+	    cdoPrint("Map weight > 1! grid1idx=%d grid2idx=%d nlink=%d wts=%g",
+		     src_grid_add, tgt_grid_add, n, rv->wts[n*num_wts]);
+	}
+    } // lcheck
+
+  if ( cdoTimer ) timer_stop(timer_remap_con);
+
+} /* remap_consphere */
+
 /*****************************************************************************/
 
-void remap_stat(int remap_order, remapgrid_t rg, remapvars_t rv, const double *restrict array1, 
+void remap_stat(int remap_order, remapgrid_t src_grid, remapgrid_t tgt_grid, remapvars_t rv, const double *restrict array1, 
 		const double *restrict array2, double missval)
 {
   long n, ns, i;
   long idiff, imax, imin, icount;
-  int *grid2_count;
+  int *tgt_count;
   double minval, maxval, sum;
 	  
   if ( remap_order == 2 )
@@ -5365,7 +6121,7 @@ void remap_stat(int remap_order, remapgrid_t rg, remapvars_t rv, const double *r
   sum = 0;
   minval =  DBL_MAX;
   maxval = -DBL_MAX;
-  for ( n = 0; n < rg.grid1_size; ++n )
+  for ( n = 0; n < src_grid.size; ++n )
     {
       if ( !DBL_IS_EQUAL(array1[n], missval) )
 	{
@@ -5382,7 +6138,7 @@ void remap_stat(int remap_order, remapgrid_t rg, remapvars_t rv, const double *r
   sum = 0;
   minval =  DBL_MAX;
   maxval = -DBL_MAX;
-  for ( n = 0; n < rg.grid2_size; ++n )
+  for ( n = 0; n < tgt_grid.size; ++n )
     {
       if ( !DBL_IS_EQUAL(array2[n], missval) )
 	{
@@ -5397,53 +6153,53 @@ void remap_stat(int remap_order, remapgrid_t rg, remapvars_t rv, const double *r
 
   /* Conservation Test */
 
-  if ( rg.grid1_area )
+  if ( src_grid.cell_area )
     {
       cdoPrint("Conservation:");
       sum = 0;
-      for ( n = 0; n < rg.grid1_size; ++n )
+      for ( n = 0; n < src_grid.size; ++n )
 	if ( !DBL_IS_EQUAL(array1[n], missval) )
-	  sum += array1[n]*rg.grid1_area[n]*rg.grid1_frac[n];
+	  sum += array1[n]*src_grid.cell_area[n]*src_grid.cell_frac[n];
       cdoPrint("Grid1 Integral = %g", sum);
 
       sum = 0;
-      for ( n = 0; n < rg.grid2_size; ++n )
+      for ( n = 0; n < tgt_grid.size; ++n )
 	if ( !DBL_IS_EQUAL(array2[n], missval) )
-	  sum += array2[n]*rg.grid2_area[n]*rg.grid2_frac[n];
+	  sum += array2[n]*tgt_grid.cell_area[n]*tgt_grid.cell_frac[n];
       cdoPrint("Grid2 Integral = %g", sum);
       /*
-      for ( n = 0; n < rg.grid1_size; n++ )
-       fprintf(stderr, "1 %d %g %g %g\n", n, array1[n], rg.grid1_area[n], rg.grid1_frac[n]);
-      for ( n = 0; n < rg.grid2_size; n++ )
-	fprintf(stderr, "2 %d %g %g %g\n", n, array2[n], rg.grid2_area[n], rg.grid2_frac[n]);
+      for ( n = 0; n < src_grid.size; n++ )
+       fprintf(stderr, "1 %d %g %g %g\n", n, array1[n], src_grid.cell_area[n], src_grid.cell_frac[n]);
+      for ( n = 0; n < tgt_grid.size; n++ )
+	fprintf(stderr, "2 %d %g %g %g\n", n, array2[n], tgt_grid.cell_area[n], tgt_grid.cell_frac[n]);
       */
     }
 
   cdoPrint("number of sparse matrix entries %d", rv.num_links);
-  cdoPrint("total number of dest cells %d", rg.grid2_size);
+  cdoPrint("total number of dest cells %d", tgt_grid.size);
 
-  grid2_count = (int *) malloc(rg.grid2_size*sizeof(int));
+  tgt_count = malloc(tgt_grid.size*sizeof(int));
 
-  for ( n = 0; n < rg.grid2_size; ++n ) grid2_count[n] = 0;
+  for ( n = 0; n < tgt_grid.size; ++n ) tgt_count[n] = 0;
 
 #if defined(SX)
 #pragma vdir nodep
 #endif
-  for ( n = 0; n < rv.num_links; ++n ) grid2_count[rv.grid2_add[n]]++;
+  for ( n = 0; n < rv.num_links; ++n ) tgt_count[rv.tgt_grid_add[n]]++;
 
   imin = INT_MAX;
   imax = INT_MIN;
-  for ( n = 0; n < rg.grid2_size; ++n )
+  for ( n = 0; n < tgt_grid.size; ++n )
     {
-      if ( grid2_count[n] > 0 )
-	if ( grid2_count[n] < imin ) imin = grid2_count[n];
-      if ( grid2_count[n] > imax ) imax = grid2_count[n];
+      if ( tgt_count[n] > 0 )
+	if ( tgt_count[n] < imin ) imin = tgt_count[n];
+      if ( tgt_count[n] > imax ) imax = tgt_count[n];
     }
 
   idiff =  (imax - imin)/10 + 1;
   icount = 0;
-  for ( i = 0; i < rg.grid2_size; ++i )
-    if ( grid2_count[i] > 0 ) icount++;
+  for ( i = 0; i < tgt_grid.size; ++i )
+    if ( tgt_count[i] > 0 ) icount++;
 
   cdoPrint("number of cells participating in remap %d", icount);
 
@@ -5456,8 +6212,8 @@ void remap_stat(int remap_order, remapgrid_t rg, remapvars_t rv, const double *r
       for ( n = 0; n < 10; ++n )
 	{
 	  icount = 0;
-	  for ( i = 0; i < rg.grid2_size; ++i )
-	    if ( grid2_count[i] >= imin && grid2_count[i] < imax ) icount++;
+	  for ( i = 0; i < tgt_grid.size; ++i )
+	    if ( tgt_count[i] >= imin && tgt_count[i] < imax ) icount++;
 
 	  if ( icount )
 	    cdoPrint("num of rows with entries between %d - %d  %d", imin, imax-1, icount);
@@ -5467,39 +6223,42 @@ void remap_stat(int remap_order, remapgrid_t rg, remapvars_t rv, const double *r
 	}
     }
 
-  free(grid2_count);
+  free(tgt_count);
+
+  if ( rv.sort_add )
+    cdoPrint("Sparse matrix entries are explicitly sorted.");
 
 } /* remap_stat */
 
 /*****************************************************************************/
 
-void remap_gradients(remapgrid_t rg, const double *restrict array, double *restrict grad1_lat,
-		     double *restrict grad1_lon, double *restrict grad1_latlon)
+void remap_gradients(remapgrid_t grid, const double *restrict array, double *restrict grad_lat,
+		     double *restrict grad_lon, double *restrict grad_latlon)
 {
-  long n, nx, ny, grid1_size;
+  long n, nx, ny, grid_size;
   long i, j, ip1, im1, jp1, jm1, in, is, ie, iw, ine, inw, ise, isw;
   double delew, delns;
-  double grad1_lat_zero, grad1_lon_zero;
+  double grad_lat_zero, grad_lon_zero;
 
-  if ( rg.grid1_rank != 2 )
-    cdoAbort("Internal problem (remap_gradients), grid1 rank = %d!", rg.grid1_rank);
+  if ( grid.rank != 2 )
+    cdoAbort("Internal problem (remap_gradients), grid rank = %d!", grid.rank);
 
-  grid1_size = rg.grid1_size;
-  nx = rg.grid1_dims[0];
-  ny = rg.grid1_dims[1];
+  grid_size = grid.size;
+  nx = grid.dims[0];
+  ny = grid.dims[1];
 
 #if defined(_OPENMP)
 #pragma omp parallel for default(none)        \
-  shared(grid1_size, grad1_lat, grad1_lon, grad1_latlon, rg, nx, ny, array) \
-  private(n, i, j, ip1, im1, jp1, jm1, in, is, ie, iw, ine, inw, ise, isw, delew, delns, grad1_lat_zero, grad1_lon_zero)
+  shared(grid_size, grad_lat, grad_lon, grad_latlon, grid, nx, ny, array) \
+  private(n, i, j, ip1, im1, jp1, jm1, in, is, ie, iw, ine, inw, ise, isw, delew, delns, grad_lat_zero, grad_lon_zero)
 #endif
-  for ( n = 0; n < grid1_size; ++n )
+  for ( n = 0; n < grid_size; ++n )
     {
-      grad1_lat[n] = ZERO;
-      grad1_lon[n] = ZERO;
-      grad1_latlon[n] = ZERO;
+      grad_lat[n] = ZERO;
+      grad_lon[n] = ZERO;
+      grad_latlon[n] = ZERO;
 
-      if ( rg.grid1_mask[n] )
+      if ( grid.mask[n] )
 	{
 	  delew = HALF;
 	  delns = HALF;
@@ -5537,33 +6296,33 @@ void remap_gradients(remapgrid_t rg, const double *restrict array, double *restr
 
 	  /* Compute i-gradient */
 
-	  if ( ! rg.grid1_mask[ie] )
+	  if ( ! grid.mask[ie] )
 	    {
               ie = n;
               delew = ONE;
             }
-	  if ( ! rg.grid1_mask[iw] )
+	  if ( ! grid.mask[iw] )
 	    {
               iw = n;
               delew = ONE;
             }
  
-	  grad1_lat[n] = delew*(array[ie] - array[iw]);
+	  grad_lat[n] = delew*(array[ie] - array[iw]);
 
 	  /* Compute j-gradient */
 
-	  if ( ! rg.grid1_mask[in] )
+	  if ( ! grid.mask[in] )
 	    {
               in = n;
               delns = ONE;
             }
-	  if ( ! rg.grid1_mask[is] )
+	  if ( ! grid.mask[is] )
 	    {
               is = n;
               delns = ONE;
             }
  
-	  grad1_lon[n] = delns*(array[in] - array[is]);
+	  grad_lon[n] = delns*(array[in] - array[is]);
 
 	  /* Compute ij-gradient */
 
@@ -5573,7 +6332,7 @@ void remap_gradients(remapgrid_t rg, const double *restrict array, double *restr
 	  else 
 	    delns = HALF;
 
-	  if ( ! rg.grid1_mask[ine] )
+	  if ( ! grid.mask[ine] )
 	    {
               if ( in != n )
 		{
@@ -5596,7 +6355,7 @@ void remap_gradients(remapgrid_t rg, const double *restrict array, double *restr
 		}
 	    }
 
-	  if ( ! rg.grid1_mask[inw] )
+	  if ( ! grid.mask[inw] )
 	    {
               if ( in != n )
 		{
@@ -5619,9 +6378,9 @@ void remap_gradients(remapgrid_t rg, const double *restrict array, double *restr
 		}
 	    }
 
-	  grad1_lat_zero = delew*(array[ine] - array[inw]);
+	  grad_lat_zero = delew*(array[ine] - array[inw]);
 
-	  if ( ! rg.grid1_mask[ise] )
+	  if ( ! grid.mask[ise] )
 	    {
               if ( is != n )
 		{
@@ -5644,7 +6403,7 @@ void remap_gradients(remapgrid_t rg, const double *restrict array, double *restr
 		}
 	    }
 
-	  if ( ! rg.grid1_mask[isw] )
+	  if ( ! grid.mask[isw] )
 	    {
               if ( is != n )
 		{
@@ -5667,9 +6426,9 @@ void remap_gradients(remapgrid_t rg, const double *restrict array, double *restr
 		}
 	    }
 
-	  grad1_lon_zero = delew*(array[ise] - array[isw]);
+	  grad_lon_zero = delew*(array[ise] - array[isw]);
 
-	  grad1_latlon[n] = delns*(grad1_lat_zero - grad1_lon_zero);
+	  grad_latlon[n] = delns*(grad_lat_zero - grad_lon_zero);
 	}
     }
 } /* remap_gradients */
@@ -5694,13 +6453,13 @@ void reorder_links(remapvars_t *rv)
   lastval = -1;
   for ( n = 0; n < num_links; n++ )
     {
-      if ( rv->grid2_add[n] == lastval ) nval++;
+      if ( rv->tgt_grid_add[n] == lastval ) nval++;
       else
 	{
 	  if ( nval > num_blks ) num_blks = nval;
 	  nval = 1;
 	  max_links++;
-	  lastval = rv->grid2_add[n];
+	  lastval = rv->tgt_grid_add[n];
 	}
     }
 
@@ -5711,17 +6470,17 @@ void reorder_links(remapvars_t *rv)
 
       printf("num_links %ld  max_links %ld  num_blks %ld\n", rv->num_links, max_links, num_blks);
 
-      rv->links.num_links = (int *)  malloc(num_blks*sizeof(int));
-      rv->links.dst_add   = (int **) malloc(num_blks*sizeof(int *));
-      rv->links.src_add   = (int **) malloc(num_blks*sizeof(int *));
-      rv->links.w_index   = (int **) malloc(num_blks*sizeof(int *));
+      rv->links.num_links = malloc(num_blks*sizeof(int));
+      rv->links.dst_add   = malloc(num_blks*sizeof(int *));
+      rv->links.src_add   = malloc(num_blks*sizeof(int *));
+      rv->links.w_index   = malloc(num_blks*sizeof(int *));
     }
 
   for ( j = 0; j < num_blks; j++ )
     {
-      rv->links.dst_add[j] = (int *) malloc(max_links*sizeof(int));
-      rv->links.src_add[j] = (int *) malloc(max_links*sizeof(int));
-      rv->links.w_index[j] = (int *) malloc(max_links*sizeof(int));
+      rv->links.dst_add[j] = malloc(max_links*sizeof(int));
+      rv->links.src_add[j] = malloc(max_links*sizeof(int));
+      rv->links.w_index[j] = malloc(max_links*sizeof(int));
     }
 
   for ( j = 0; j < num_blks; j++ )
@@ -5732,17 +6491,17 @@ void reorder_links(remapvars_t *rv)
 
       for ( n = 0; n < num_links; n++ )
 	{
-	  if ( rv->grid2_add[n] == lastval ) nval++;
+	  if ( rv->tgt_grid_add[n] == lastval ) nval++;
 	  else
 	    {
 	      nval = 1;
-	      lastval = rv->grid2_add[n];
+	      lastval = rv->tgt_grid_add[n];
 	    }
 	  
 	  if ( nval == j+1 )
 	    {
-	      rv->links.dst_add[j][nlinks] = rv->grid2_add[n];
-	      rv->links.src_add[j][nlinks] = rv->grid1_add[n];
+	      rv->links.dst_add[j][nlinks] = rv->tgt_grid_add[n];
+	      rv->links.src_add[j][nlinks] = rv->src_grid_add[n];
 	      rv->links.w_index[j][nlinks] = n;
 	      nlinks++;
 	    }
diff --git a/src/remapsort.c b/src/remapsort.c
index 8defb29..646b2d3 100644
--- a/src/remapsort.c
+++ b/src/remapsort.c
@@ -287,12 +287,12 @@ void sort_add(long num_links, long num_wts, int *restrict add1, int *restrict ad
 
   if ( num_links <= 1 ) return;
 
-  idx = (int *) malloc(num_links*sizeof(int));
+  idx = malloc(num_links*sizeof(int));
   for ( i = 0; i < num_links; ++i ) idx[i] = i;
 
   remap_heapsort(num_links, add1, add2, idx);
 
-  wgt_tmp = (double*) malloc(num_wts*num_links*sizeof(double));
+  wgt_tmp = malloc(num_wts*num_links*sizeof(double));
   memcpy(wgt_tmp, weights, num_wts*num_links*sizeof(double));
 
   for ( i = 0; i < num_links; ++i )
@@ -620,7 +620,7 @@ void sort_par(long num_links, long num_wts, int *restrict add1, int *restrict ad
       exit(-1);
     }
 
-  idx = (long *) malloc(num_links*sizeof(long));
+  idx = malloc(num_links*sizeof(long));
 
   /* SPLIT AND SORT THE DATA FRAGMENTS */
   /*
@@ -675,7 +675,7 @@ void sort_par(long num_links, long num_wts, int *restrict add1, int *restrict ad
       //	       who_am_i,parent,my_depth,omp_get_thread_num()+1,omp_get_num_threads());
 #endif
             
-      wgttmp = (double *) malloc(num_wts*nl[i]*sizeof(double));
+      wgttmp = malloc(num_wts*nl[i]*sizeof(double));
        
       for ( m = 0; m < nl[i]; m++ )
 	for ( n = 0; n < num_wts; n++ )                      
@@ -698,7 +698,7 @@ void sort_par(long num_links, long num_wts, int *restrict add1, int *restrict ad
                                                               /* ********************** */
   merge_lists(nl,add1s[0],add2s[0],add1s[1],add2s[1], idx);   /* MERGE THE SEGMENTS     */
                                                               /* ********************** */
-  tmp = (int *) malloc(num_links*sizeof(int));
+  tmp = malloc(num_links*sizeof(int));
   
 #if defined(_OPENMP)
 #pragma omp parallel for if ( depth < par_depth ) private(i) num_threads(2)
@@ -724,7 +724,7 @@ void sort_par(long num_links, long num_wts, int *restrict add1, int *restrict ad
   free(tmp);
   tmp = NULL;
   
-  tmp2 = (double *) malloc(num_links*num_wts*sizeof(double) );
+  tmp2 = malloc(num_links*num_wts*sizeof(double) );
   
 #if defined(_OPENMP)
 #pragma omp parallel for if ( depth < par_depth ) private(i,n) num_threads(2)
diff --git a/src/specspace.c b/src/specspace.c
index b089e15..fa24b55 100644
--- a/src/specspace.c
+++ b/src/specspace.c
@@ -5,14 +5,9 @@
 #include <cdi.h>
 #include "cdo.h"
 #include "cdo_int.h"
-#ifndef _DMEMORY_H
-#  include "dmemory.h"
-#endif
-
-#ifndef _ERROR_H
-#  include "error.h"
-#endif
 #include "specspace.h"
+#include "error.h"
+#include "grid.h"
 
 
 #define  SQUARE_RADIUS   (-PlanetRadius * PlanetRadius)
@@ -60,16 +55,16 @@ void legini_old(int ntr, int nlat, double *poli, double *pold,
   dimsp = (ntr + 1) * (ntr + 2);
   pdim  = dimsp / 2 * nlat;
 
-  gmu  = (double *) malloc(nlat * sizeof(double));
-  gwt  = (double *) malloc(nlat * sizeof(double));
+  gmu  = malloc(nlat * sizeof(double));
+  gwt  = malloc(nlat * sizeof(double));
 
   gaussaw(gmu, gwt, nlat);
 
 #if ! defined(_OPENMP)
-  pnm    = (double *) malloc(dimsp * sizeof(double));
-  hnm    = (double *) malloc(dimsp * sizeof(double));
-  ztemp1 = (double *) malloc((waves<<1) * sizeof(double));
-  ztemp2 = (double *) malloc((waves<<1) * sizeof(double));
+  pnm    = malloc(dimsp * sizeof(double));
+  hnm    = malloc(dimsp * sizeof(double));
+  ztemp1 = malloc((waves<<1) * sizeof(double));
+  ztemp2 = malloc((waves<<1) * sizeof(double));
 #endif
 
 #if defined(_OPENMP)
@@ -78,10 +73,10 @@ void legini_old(int ntr, int nlat, double *poli, double *pold,
   for ( jgl = 0; jgl < nlat; jgl++ )
     {
 #if defined(_OPENMP)
-      pnm    = (double *) malloc(dimsp * sizeof(double));
-      hnm    = (double *) malloc(dimsp * sizeof(double));
-      ztemp1 = (double *) malloc((waves<<1) * sizeof(double));
-      ztemp2 = (double *) malloc((waves<<1) * sizeof(double));
+      pnm    = malloc(dimsp * sizeof(double));
+      hnm    = malloc(dimsp * sizeof(double));
+      ztemp1 = malloc((waves<<1) * sizeof(double));
+      ztemp2 = malloc((waves<<1) * sizeof(double));
 #endif
       gmusq = 1.0 - gmu[jgl]*gmu[jgl];
       coslat[jgl] =  sqrt(gmusq);
@@ -131,10 +126,10 @@ void legini(int ntr, int nlat, double *poli, double *pold, double *rcoslat)
   dimsp  = (ntr + 1)*(ntr + 2);
   dimpnm = (ntr + 1)*(ntr + 4)/2;
 
-  gmu  = (double *) malloc(nlat * sizeof(double));
-  gwt  = (double *) malloc(nlat * sizeof(double));
-  pnm  = (double *) malloc(dimpnm * sizeof(double));
-  work = (double *) malloc(3*waves * sizeof(double));
+  gmu  = malloc(nlat * sizeof(double));
+  gwt  = malloc(nlat * sizeof(double));
+  pnm  = malloc(dimpnm * sizeof(double));
+  work = malloc(3*waves * sizeof(double));
 
   gaussaw(gmu, gwt, nlat);
   for ( jgl = 0; jgl < nlat; jgl++ ) gwt[jgl] *= 0.5;
@@ -189,7 +184,7 @@ void grid2spec(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, d
   waves = ntr + 1;
   nfc   = waves * 2;
 
-  fpwork = (double *) malloc(nlat*nfc*nlev*sizeof(double));
+  fpwork = malloc(nlat*nfc*nlev*sizeof(double));
 
   gp2fc(sptrans->trig, sptrans->ifax, arrayIn, fpwork, nlat, nlon, nlev, nfc);
   fc2sp(fpwork, arrayOut, sptrans->pold, nlev, nlat, nfc, ntr);
@@ -212,7 +207,7 @@ void spec2grid(SPTRANS *sptrans, int gridIDin, double *arrayIn, int gridIDout, d
   waves = ntr + 1;
   nfc   = waves * 2;
 
-  fpwork = (double *) malloc(nlat*nfc*nlev*sizeof(double));
+  fpwork = malloc(nlat*nfc*nlev*sizeof(double));
 
   sp2fc(arrayIn, fpwork, sptrans->poli, nlev, nlat, nfc, ntr);
   fc2gp(sptrans->trig, sptrans->ifax, fpwork, arrayOut, nlat, nlon, nlev, nfc);
@@ -314,7 +309,7 @@ SPTRANS *sptrans_new(int nlon, int nlat, int ntr, int flag)
   SPTRANS *sptrans;
   int nsp;
 
-  sptrans = (SPTRANS *) malloc(sizeof(SPTRANS));
+  sptrans = malloc(sizeof(SPTRANS));
 
   sptrans->nlon = nlon;
   sptrans->nlat = nlat;
@@ -323,15 +318,15 @@ SPTRANS *sptrans_new(int nlon, int nlat, int ntr, int flag)
   nsp = (ntr + 1)*(ntr + 2);
   sptrans->poldim = nsp / 2 * nlat;
 
-  sptrans->trig = (double *) malloc(nlon * sizeof(double));
+  sptrans->trig = malloc(nlon * sizeof(double));
   fft_set(sptrans->trig, sptrans->ifax, nlon);
 
-  sptrans->poli = (double *) malloc(sptrans->poldim * sizeof(double));
-  sptrans->pold = (double *) malloc(sptrans->poldim * sizeof(double));
+  sptrans->poli = malloc(sptrans->poldim * sizeof(double));
+  sptrans->pold = malloc(sptrans->poldim * sizeof(double));
   if ( flag )
     {
-      sptrans->pol2 = (double *) malloc(sptrans->poldim * sizeof(double));
-      sptrans->pol3 = (double *) malloc(sptrans->poldim * sizeof(double));
+      sptrans->pol2 = malloc(sptrans->poldim * sizeof(double));
+      sptrans->pol3 = malloc(sptrans->poldim * sizeof(double));
     }
   else
     {
@@ -339,8 +334,8 @@ SPTRANS *sptrans_new(int nlon, int nlat, int ntr, int flag)
       sptrans->pol3 = NULL;
     }
 
-  sptrans->coslat  = (double *) malloc(nlat * sizeof(double));
-  sptrans->rcoslat = (double *) malloc(nlat * sizeof(double));
+  sptrans->coslat  = malloc(nlat * sizeof(double));
+  sptrans->rcoslat = malloc(nlat * sizeof(double));
 
   if ( flag )
     legini_old(ntr, nlat, sptrans->poli, sptrans->pold,
@@ -374,15 +369,15 @@ DVTRANS *dvtrans_new(int ntr)
   DVTRANS *dvtrans;
   int dimsp;
 
-  dvtrans = (DVTRANS *) malloc(sizeof(DVTRANS));
+  dvtrans = malloc(sizeof(DVTRANS));
 
   dvtrans->ntr = ntr;
 
   dimsp = (ntr + 1)*(ntr + 2);
   dvtrans->fdim = dimsp / 2;
 
-  dvtrans->f1 = (double *) malloc(dvtrans->fdim * sizeof(double));
-  dvtrans->f2 = (double *) malloc(dvtrans->fdim * sizeof(double));
+  dvtrans->f1 = malloc(dvtrans->fdim * sizeof(double));
+  dvtrans->f2 = malloc(dvtrans->fdim * sizeof(double));
 
   geninx(ntr, dvtrans->f1, dvtrans->f2);
 
@@ -628,8 +623,8 @@ void trans_uv2dv(SPTRANS *sptrans, int nlev,
   waves = ntr + 1;
   nfc   = waves * 2;
 
-  fpwork1 = (double *) malloc(nlat*nfc*nlev*sizeof(double));
-  fpwork2 = (double *) malloc(nlat*nfc*nlev*sizeof(double));
+  fpwork1 = malloc(nlat*nfc*nlev*sizeof(double));
+  fpwork2 = malloc(nlat*nfc*nlev*sizeof(double));
 
   gp2fc(sptrans->trig, sptrans->ifax, gu, fpwork1, nlat, nlon, nlev, nfc);
   gp2fc(sptrans->trig, sptrans->ifax, gv, fpwork2, nlat, nlon, nlev, nfc);
@@ -674,7 +669,7 @@ void trans_dv2uv(SPTRANS *sptrans, DVTRANS *dvtrans, int nlev,
 
   dv2uv(sd, svo, su, sv, dvtrans->f1, dvtrans->f2, ntr, dimsp, nlev);
 
-  fpwork = (double *) malloc(nlat*nfc*nlev*sizeof(double));
+  fpwork = malloc(nlat*nfc*nlev*sizeof(double));
 
   sp2fc(su, fpwork, sptrans->poli, nlev, nlat, nfc, ntr);
   scaluv(fpwork, sptrans->rcoslat, nlat, nfc*nlev);
diff --git a/src/statistic.c b/src/statistic.c
index 6d99994..4007511 100644
--- a/src/statistic.c
+++ b/src/statistic.c
@@ -72,7 +72,7 @@ void eigen_solution_of_symmetric_matrix (double **a, double *eig_val,
   int i, j;
   double temp;
   
-  e = (double *) malloc (n * sizeof (double));
+  e = malloc (n * sizeof (double));
   
   make_symmetric_matrix_triangular (a, n, eig_val, e, prompt);
   
@@ -366,7 +366,7 @@ int solution_of_linear_equation (double **a, double *b, int n)
   int sign;
   int not_singular;
   
-  index = (int *) malloc (n * sizeof (int));
+  index = malloc (n * sizeof (int));
   
   not_singular = lu_decomposition (a, n, index, &sign);
   
@@ -387,8 +387,8 @@ int inverse_of_matrix (double **a, double **b, int n)
   int not_singular;
   double *col;
   
-  index = (int *) malloc (n * sizeof (int));
-  col = (double *) malloc (n * sizeof (double));
+  index = malloc (n * sizeof (int));
+  col = malloc (n * sizeof (double));
   
   not_singular = lu_decomposition (a, n, index, &sign);
   
@@ -418,7 +418,7 @@ int lu_decomposition (double **a, int n, int *index, int *sign)
   double big, sum, temp;
   double *v;
   
-  v = (double *) malloc (n * sizeof (double));
+  v = malloc (n * sizeof (double));
   *sign = 1;
   for (i = 0; i < n; i++)
     {
@@ -577,12 +577,12 @@ void ft (double *real, double *imag, int n, int sign)
   
   if (!work_r)
     {
-      work_r = (double *) malloc (n * sizeof (double));
+      work_r = malloc (n * sizeof (double));
       /* free_at_exit (work_r); */
     }
   if (!work_i)
     {
-      work_i = (double *) malloc (n * sizeof (double));
+      work_i = malloc (n * sizeof (double));
       /* free_at_exit (work_i); */
     }
   
diff --git a/src/stdnametable.c b/src/stdnametable.c
new file mode 100644
index 0000000..840882a
--- /dev/null
+++ b/src/stdnametable.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "stdnametable.h"
+
+
+typedef struct
+{
+  int   varid;
+  int   echamcode;
+  char *name;
+  char *stdname;     /* Standard name */
+  char *units;       /* Units         */
+}
+stdnametable_t;
+
+
+const stdnametable_t stdnametable[] = {
+  /* varid                       code    name                standard name                 units */
+  { surface_geopotential,         129,  "geosp",            "surface_geopotential",       "m2 s-2" },
+  { air_temperature,              130,  "ta",               "air_temperature",            "K" },
+  { specific_humidity,            133,  "hus",              "specific_humidity",          "1" },
+  { surface_air_pressure,         134,  "aps",              "surface_air_pressure",       "Pa" },
+  { air_pressure_at_sea_level,    151,  "psl",              "air_pressure_at_sea_level",  "Pa" },
+  { geopotential_height,          156,  "zg",               "geopotential_height",        "m" },
+};
+
+
+static int stdnametable_idx(int varid)
+{
+  int idx;
+  int num_entries = (int) (sizeof(stdnametable)/sizeof(stdnametable_t));
+
+  for ( idx = 0; idx < num_entries; ++idx )
+    if ( stdnametable[idx].varid == varid ) break;
+
+  assert( idx < num_entries );
+
+  return (idx);
+}
+
+
+int var_echamcode(int varid)
+{
+  return (stdnametable[stdnametable_idx(varid)].echamcode);
+}
+
+const char* var_name(int varid)
+{
+  return (stdnametable[stdnametable_idx(varid)].name);
+}
+
+const char* var_stdname(int varid)
+{
+  return (stdnametable[stdnametable_idx(varid)].stdname);
+}
+
+const char* var_units(int varid)
+{
+  return (stdnametable[stdnametable_idx(varid)].units);
+}
+
+int echamcode_from_stdname(const char* stdname)
+{
+  int code = -1;
+
+  if      ( strcmp(stdname, var_stdname(surface_geopotential))      == 0 ) code = 129;
+  else if ( strcmp(stdname, "geopotential")                         == 0 ) code = 129;
+  else if ( strcmp(stdname, var_stdname(air_temperature))           == 0 ) code = 130;
+  else if ( strcmp(stdname, var_stdname(specific_humidity))         == 0 ) code = 133;
+  else if ( strcmp(stdname, var_stdname(surface_air_pressure))      == 0 ) code = 134;
+  else if ( strcmp(stdname, var_stdname(air_pressure_at_sea_level)) == 0 ) code = 151;
+  else if ( strcmp(stdname, var_stdname(geopotential_height))       == 0 ) code = 156;
+
+  return (code);
+}
diff --git a/src/stdnametable.h b/src/stdnametable.h
new file mode 100644
index 0000000..14e4968
--- /dev/null
+++ b/src/stdnametable.h
@@ -0,0 +1,18 @@
+#ifndef _STDNAMETABLE_H
+#define _STDNAMETABLE_H
+
+enum stdnameid {surface_geopotential,
+		air_temperature,
+                specific_humidity,
+		surface_air_pressure,
+		air_pressure_at_sea_level,
+		geopotential_height};
+
+int         var_echamcode(int varid);
+const char* var_name(int varid);
+const char* var_stdname(int varid);
+const char* var_units(int varid);
+
+int echamcode_from_stdname(const char* stdname);
+
+#endif
diff --git a/src/table.c b/src/table.c
index 639a246..c4395e3 100644
--- a/src/table.c
+++ b/src/table.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -47,7 +47,7 @@ int defineTable(char *tablearg)
 	{
 	  char *tablefile = NULL;
 	  int len = sizeof(tablepath) + sizeof(tablename) + 3;
-	  tablefile = (char *) malloc(len);
+	  tablefile = malloc(len);
 	  strcpy(tablefile, tablepath);
 	  strcat(tablefile, "/");
 	  strcat(tablefile, tablename);
diff --git a/src/timer.c b/src/timer.c
index 2783b68..9eb3b36 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/userlog.c b/src/userlog.c
index 18250b5..bb0e460 100644
--- a/src/userlog.c
+++ b/src/userlog.c
@@ -495,7 +495,7 @@ void dumplogs(const char *logfilename)
 
   if ( bufsize > 0 )
     {
-      buffer = (unsigned char *) malloc(bufsize);
+      buffer = malloc(bufsize);
 
       status = (int) read(logfileno, buffer, bufsize);
 
@@ -568,7 +568,7 @@ void daylogs(const char *logfilename)
 
   if ( bufsize > 0 )
     {
-      buffer = (unsigned char *) malloc(bufsize);
+      buffer = malloc(bufsize);
 
       status = (int) read(logfileno, buffer, bufsize);
 
@@ -640,7 +640,7 @@ void monlogs(const char *logfilename)
 
   if ( bufsize > 0 )
     {
-      buffer = (unsigned char *) malloc(bufsize);
+      buffer = malloc(bufsize);
 
       status = (int) read(logfileno, buffer, bufsize);
 
@@ -769,7 +769,7 @@ void cdologo(int noper)
   bufsize = (size_t) filestat.st_size;
 
   newbufsize = bufsize + noper*logsize;
-  buffer = (unsigned char *) malloc(newbufsize);
+  buffer = malloc(newbufsize);
   if ( bufsize > 0 )
     status = (int) read(logfileno, buffer, bufsize);
 
@@ -846,14 +846,14 @@ typedef struct
   double   perc;
   char     name[128];
 }
-LogInfo;
+loginfo_t;
 
 static
 int cmplognocc(const void *s1, const void *s2)
 {
   int cmp = 0;
-  LogInfo *x = (LogInfo *) s1;
-  LogInfo *y = (LogInfo *) s2;
+  const loginfo_t *x = s1;
+  const loginfo_t *y = s2;
 
   if      ( x->nocc < y->nocc ) cmp =  1;
   else if ( x->nocc > y->nocc ) cmp = -1;
@@ -865,8 +865,8 @@ static
 int cmplognvals(const void *s1, const void *s2)
 {
   int cmp = 0;
-  LogInfo *x = (LogInfo *) s1;
-  LogInfo *y = (LogInfo *) s2;
+  const loginfo_t *x = s1;
+  const loginfo_t *y = s2;
 
   if      ( x->nvals < y->nvals ) cmp =  1;
   else if ( x->nvals > y->nvals ) cmp = -1;
@@ -878,8 +878,8 @@ static
 int cmplogtime(const void *s1, const void *s2)
 {
   int cmp = 0;
-  LogInfo *x = (LogInfo *) s1;
-  LogInfo *y = (LogInfo *) s2;
+  const loginfo_t *x = s1;
+  const loginfo_t *y = s2;
 
   if      ( x->time < y->time ) cmp =  1;
   else if ( x->time > y->time ) cmp = -1;
@@ -891,8 +891,8 @@ static
 int cmplogperc(const void *s1, const void *s2)
 {
   int cmp = 0;
-  LogInfo *x = (LogInfo *) s1;
-  LogInfo *y = (LogInfo *) s2;
+  const loginfo_t *x = s1;
+  const loginfo_t *y = s2;
 
   if      ( x->perc < y->perc ) cmp =  1;
   else if ( x->perc > y->perc ) cmp = -1;
@@ -903,8 +903,8 @@ int cmplogperc(const void *s1, const void *s2)
 static
 int cmplogname(const void *s1, const void *s2)
 {
-  LogInfo *x = (LogInfo *) s1;
-  LogInfo *y = (LogInfo *) s2;
+  const loginfo_t *x = s1;
+  const loginfo_t *y = s2;
 
   return (strcmp(x->name, y->name));
 }
@@ -933,7 +933,7 @@ void dumplogo(const char *logfilename, int dumptype)
   size_t bufsize;
   struct flock mylock;
   struct stat filestat;
-  LogInfo **logInfo;
+  loginfo_t **logInfo;
 
   errno = 0;
   logfileno = open(logfilename, O_RDONLY);
@@ -957,14 +957,14 @@ void dumplogo(const char *logfilename, int dumptype)
   if ( bufsize > 0 )
     {
       fprintf(stdout, "# num name                     call        mem [GB]    time [h]     perc [s]\n");
-      buffer = (unsigned char *) malloc(bufsize);
+      buffer = malloc(bufsize);
 
       status = (int) read(logfileno, buffer, bufsize);
 
       nlogs = bufsize / logsize;
 
-      logInfo    = (LogInfo **) malloc(nlogs*sizeof(LogInfo *));
-      logInfo[0] = (LogInfo *) malloc(nlogs*sizeof(LogInfo));
+      logInfo    = malloc(nlogs*sizeof(loginfo_t *));
+      logInfo[0] = malloc(nlogs*sizeof(loginfo_t));
       for ( i = 1; i < nlogs; i++ ) logInfo[i] = logInfo[0] + i;
 
       for ( i = 0; i < nlogs; i++ )
@@ -983,15 +983,15 @@ void dumplogo(const char *logfilename, int dumptype)
 	}
 
       if      ( dumptype == 1 )
-	qsort(logInfo[0], nlogs, sizeof(LogInfo), cmplogname);
+	qsort(logInfo[0], nlogs, sizeof(loginfo_t), cmplogname);
       else if ( dumptype == 2 )
-	qsort(logInfo[0], nlogs, sizeof(LogInfo), cmplognocc);
+	qsort(logInfo[0], nlogs, sizeof(loginfo_t), cmplognocc);
       else if ( dumptype == 3 )
-	qsort(logInfo[0], nlogs, sizeof(LogInfo), cmplognvals);
+	qsort(logInfo[0], nlogs, sizeof(loginfo_t), cmplognvals);
       else if ( dumptype == 4 )
-	qsort(logInfo[0], nlogs, sizeof(LogInfo), cmplogtime);
+	qsort(logInfo[0], nlogs, sizeof(loginfo_t), cmplogtime);
       else if ( dumptype == 5 )
-	qsort(logInfo[0], nlogs, sizeof(LogInfo), cmplogperc);
+	qsort(logInfo[0], nlogs, sizeof(loginfo_t), cmplogperc);
 
       for ( i = 0; i < nlogs; i++ )
 	{
diff --git a/src/util.c b/src/util.c
index bf10e52..96b78d6 100644
--- a/src/util.c
+++ b/src/util.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -52,7 +52,7 @@ char *getOperator(const char *argument)
     {
       len = 1 + strlen(argument);
 
-      operatorArg = (char *) malloc(len);
+      operatorArg = malloc(len);
 
       memcpy(operatorArg, argument, len);
     }
@@ -79,7 +79,7 @@ char *getOperatorName(const char *operatorArg)
       else
 	len = strlen(operatorArg);
 
-      operatorName = (char *) malloc(len+1);
+      operatorName = malloc(len+1);
 
       memcpy(operatorName, operatorArg, len);
       operatorName[len] = '\0';
@@ -94,10 +94,10 @@ argument_t *file_argument_new(const char *filename)
 {
   argument_t *argument;
 
-  argument = (argument_t *) calloc(1, sizeof(argument_t));
+  argument = calloc(1, sizeof(argument_t));
 
   argument->argc = 1;
-  argument->argv = (char **) calloc(1, sizeof(char *));
+  argument->argv = calloc(1, sizeof(char *));
   argument->argv[0] = (char *) filename;
   argument->args = (char *) filename;
 
@@ -123,16 +123,16 @@ argument_t *argument_new(size_t argc, size_t len)
 {
   argument_t *argument;
 
-  argument = (argument_t *) calloc(1, sizeof(argument_t));
+  argument = calloc(1, sizeof(argument_t));
 
   if ( argc > 0 )
     {
       argument->argc = argc;
-      argument->argv = (char **) calloc(argc, sizeof(char *));
+      argument->argv = calloc(argc, sizeof(char *));
     }
 
   if ( len > 0 )
-    argument->args = (char *) calloc(len, sizeof(char));
+    argument->args = calloc(len, sizeof(char));
 
   return (argument);
 }
@@ -195,7 +195,7 @@ char *getFileArg(char *argument)
 	{
 	  parg = blankpos + 1;
 	  len = strlen(parg);
-	  fileArg = (char *) malloc(len+1);
+	  fileArg = malloc(len+1);
 	  strcpy(fileArg, parg);
 	}
     }
@@ -331,7 +331,7 @@ int ps_cval  = -1;
 void progressInit(void)
 {
   ps_lhead = FALSE;
-  ps_nch   = 0;;
+  ps_nch   = 0;
   ps_cval  = -1;
 }
 
@@ -427,3 +427,29 @@ int str2datatype(const char *datatypestr)
 
   return (datatype);
 }
+
+
+off_t filesize(const char *filename)
+{
+  FILE *fp;
+  off_t pos = 0;
+
+  if ( filename[0] == '(' && filename[1] == 'p' )
+    {
+    }
+  else
+    {
+      fp = fopen(filename, "r");
+      if ( fp == NULL )
+	{
+	  fprintf(stderr, "Open failed on %s\n", filename);
+	}
+      else
+	{
+	  fseek(fp, 0L, SEEK_END);
+	  pos = ftello(fp);
+	}
+    }
+  
+  return pos;
+}
diff --git a/src/util.h b/src/util.h
index 9200f65..4042a56 100644
--- a/src/util.h
+++ b/src/util.h
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
diff --git a/src/vinterp.c b/src/vinterp.c
index 884410b..ce3cbb3 100644
--- a/src/vinterp.c
+++ b/src/vinterp.c
@@ -253,6 +253,7 @@ double extra_Z(double pres, double halfp, double fullp, double geop, double temp
   double alpha, tstar, tmsl, zalp, zalpal;
   double zrg;
   double zlapse = 0.0065;
+  double ztlim = 290.5;
 
   zrg   = 1.0 / Grav;
   alpha = RD * zlapse * zrg;
@@ -262,13 +263,13 @@ double extra_Z(double pres, double halfp, double fullp, double geop, double temp
 
   tmsl = tstar + zlapse * zrg * geop;
 
-  if ( tmsl > 290.5 && tstar > 290.5 )
+  if ( tmsl > ztlim && tstar > ztlim )
     {
-      tstar = 0.5 * (290.5 + tstar);
+      tstar = 0.5 * (ztlim + tstar);
       tmsl  = tstar;
     }
 
-  if ( tmsl > 290.5 && tstar <= 290.5 ) tmsl = 290.5;
+  if ( tmsl > ztlim && tstar <= ztlim ) tmsl = ztlim;
 
   if ( tmsl-tstar < 0.000001 && tstar-tmsl < 0.000001 )
     alpha = 0.0;
@@ -279,7 +280,6 @@ double extra_Z(double pres, double halfp, double fullp, double geop, double temp
   zalpal = zalp * alpha;
 
   return ((geop - RD*tstar*zalp*(1.0 + zalpal*(0.5 + zalpal/6.0)))*zrg);
-
 }  /* extra_Z */
 
 
diff --git a/src/zaxis.c b/src/zaxis.c
index 6adc691..41f0fe1 100644
--- a/src/zaxis.c
+++ b/src/zaxis.c
@@ -2,7 +2,7 @@
   This file is part of CDO. CDO is a collection of Operators to
   manipulate and analyse Climate model Data.
 
-  Copyright (C) 2003-2013 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
+  Copyright (C) 2003-2014 Uwe Schulzweida, Uwe.Schulzweida at zmaw.de
   See COPYING file for copying and redistribution conditions.
 
   This program is free software; you can redistribute it and/or modify
@@ -237,7 +237,7 @@ int zaxisFromFile(FILE *gfp, const char *dname)
 	    {
 	      pline = skipSeparator(pline + 6);
 	  
-	      zaxis.vals = (double *) malloc(zaxis.size*sizeof(double));
+	      zaxis.vals = malloc(zaxis.size*sizeof(double));
 	      for ( i = 0; i < zaxis.size; i++ )
 		{
 		  pline = skipSeparator(pline);
@@ -271,7 +271,7 @@ int zaxisFromFile(FILE *gfp, const char *dname)
 	    {
 	      pline = skipSeparator(pline + 3);
 	  
-	      zaxis.vct = (double *) malloc(zaxis.vctsize*sizeof(double));
+	      zaxis.vct = malloc(zaxis.vctsize*sizeof(double));
 	      for ( i = 0; i < zaxis.vctsize; i++ )
 		{
 		  pline = skipSeparator(pline);
@@ -305,7 +305,7 @@ int zaxisFromFile(FILE *gfp, const char *dname)
 	    {
 	      pline = skipSeparator(pline + 7);
 	  
-	      zaxis.lbounds = (double *) malloc(zaxis.size*sizeof(double));
+	      zaxis.lbounds = malloc(zaxis.size*sizeof(double));
 	      for ( i = 0; i < zaxis.size; i++ )
 		{
 		  pline = skipSeparator(pline);
@@ -339,7 +339,7 @@ int zaxisFromFile(FILE *gfp, const char *dname)
 	    {
 	      pline = skipSeparator(pline + 7);
 	  
-	      zaxis.ubounds = (double *) malloc(zaxis.size*sizeof(double));
+	      zaxis.ubounds = malloc(zaxis.size*sizeof(double));
 	      for ( i = 0; i < zaxis.size; i++ )
 		{
 		  pline = skipSeparator(pline);
@@ -387,7 +387,7 @@ int zaxisFromName(const char *zaxisname)
     {
       zaxis.type = ZAXIS_SURFACE;
       zaxis.size = 1;
-      zaxis.vals = (double *) malloc(zaxis.size*sizeof(double));
+      zaxis.vals = malloc(zaxis.size*sizeof(double));
       zaxis.vals[0] = 0;
     }
 
diff --git a/test/Makefile.am b/test/Makefile.am
index df43eeb..104f3eb 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -3,11 +3,13 @@ CLEANFILES =
 export
 
 TESTS = $(top_srcdir)/test/test_Gridarea.sh \
-        $(top_srcdir)/test/test_Remap.sh \
+        $(top_srcdir)/test/test_Cat.sh \
         $(top_srcdir)/test/test_Spectral.sh \
         $(top_srcdir)/test/test_Timstat.sh \
+        $(top_srcdir)/test/test_Select.sh \
         $(top_srcdir)/test/test_Vertint.sh
 
+#        $(top_srcdir)/test/test_Remap.sh \
 #       $(top_srcdir)/test/test_info.py
 #	$(top_srcdir)/test/test_diff.py
 #	$(top_srcdir)/test/test_Arith.py
diff --git a/test/Makefile.in b/test/Makefile.in
index 6c7e84c..7074e2f 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -252,12 +252,14 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 CLEANFILES = `ls *.pyc`
 TESTS = $(top_srcdir)/test/test_Gridarea.sh \
-        $(top_srcdir)/test/test_Remap.sh \
+        $(top_srcdir)/test/test_Cat.sh \
         $(top_srcdir)/test/test_Spectral.sh \
         $(top_srcdir)/test/test_Timstat.sh \
+        $(top_srcdir)/test/test_Select.sh \
         $(top_srcdir)/test/test_Vertint.sh
 
 
+#        $(top_srcdir)/test/test_Remap.sh \
 #       $(top_srcdir)/test/test_info.py
 #	$(top_srcdir)/test/test_diff.py
 #	$(top_srcdir)/test/test_Arith.py
diff --git a/test/data/Makefile.am b/test/data/Makefile.am
index 081892b..80ada6c 100644
--- a/test/data/Makefile.am
+++ b/test/data/Makefile.am
@@ -1,8 +1,9 @@
-INPUTDATA = ts_mm_5years hl_l19.grb t21_geosp_tsurf.grb bathy4.grb
+INPUTDATA = ts_mm_5years hl_l19.grb t21_geosp_tsurf.grb bathy4.grb pl_data.grb
 
 TIMSTAT_REF  = timmin_ref timmax_ref timsum_ref timavg_ref timmean_ref timstd_ref timstd1_ref timvar_ref timvar1_ref
 SPECTRAL_REF = sp2gp_ref sp2gpl_ref gp2sp_ref gp2spl_ref
 VERTINT_REF  = ml2pl_ref
 REMAP_REF    = n16_bic_ref n16_bil_ref n16_con_ref n16_laf_ref n16_nn_ref  n32_bic_ref n32_bil_ref n32_con_ref n32_laf_ref n32_nn_ref
+SELECT_REF   = select1_ref select2_ref select3_ref select4_ref select5_ref
 
-EXTRA_DIST = $(INPUTDATA) $(TIMSTAT_REF) $(SPECTRAL_REF) $(VERTINT_REF) $(REMAP_REF)
+EXTRA_DIST = $(INPUTDATA) $(TIMSTAT_REF) $(SPECTRAL_REF) $(VERTINT_REF) $(REMAP_REF) $(SELECT_REF)
diff --git a/test/data/Makefile.in b/test/data/Makefile.in
index b491ffa..deff0ee 100644
--- a/test/data/Makefile.in
+++ b/test/data/Makefile.in
@@ -235,12 +235,13 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-INPUTDATA = ts_mm_5years hl_l19.grb t21_geosp_tsurf.grb bathy4.grb
+INPUTDATA = ts_mm_5years hl_l19.grb t21_geosp_tsurf.grb bathy4.grb pl_data.grb
 TIMSTAT_REF = timmin_ref timmax_ref timsum_ref timavg_ref timmean_ref timstd_ref timstd1_ref timvar_ref timvar1_ref
 SPECTRAL_REF = sp2gp_ref sp2gpl_ref gp2sp_ref gp2spl_ref
 VERTINT_REF = ml2pl_ref
 REMAP_REF = n16_bic_ref n16_bil_ref n16_con_ref n16_laf_ref n16_nn_ref  n32_bic_ref n32_bil_ref n32_con_ref n32_laf_ref n32_nn_ref
-EXTRA_DIST = $(INPUTDATA) $(TIMSTAT_REF) $(SPECTRAL_REF) $(VERTINT_REF) $(REMAP_REF)
+SELECT_REF = select1_ref select2_ref select3_ref select4_ref select5_ref
+EXTRA_DIST = $(INPUTDATA) $(TIMSTAT_REF) $(SPECTRAL_REF) $(VERTINT_REF) $(REMAP_REF) $(SELECT_REF)
 all: all-am
 
 .SUFFIXES:
diff --git a/test/data/hl_l19.grb b/test/data/hl_l19.grb
index 2f4b2d7..3234f1c 100644
Binary files a/test/data/hl_l19.grb and b/test/data/hl_l19.grb differ
diff --git a/test/data/ml2pl_ref b/test/data/ml2pl_ref
index f4d572c..c96fb2f 100644
Binary files a/test/data/ml2pl_ref and b/test/data/ml2pl_ref differ
diff --git a/test/data/pl_data.grb b/test/data/pl_data.grb
new file mode 100644
index 0000000..73cfaa7
Binary files /dev/null and b/test/data/pl_data.grb differ
diff --git a/test/data/select1_ref b/test/data/select1_ref
new file mode 100644
index 0000000..6a33f8c
Binary files /dev/null and b/test/data/select1_ref differ
diff --git a/test/data/select2_ref b/test/data/select2_ref
new file mode 100644
index 0000000..74bafdd
Binary files /dev/null and b/test/data/select2_ref differ
diff --git a/test/data/select3_ref b/test/data/select3_ref
new file mode 100644
index 0000000..1c39cef
Binary files /dev/null and b/test/data/select3_ref differ
diff --git a/test/data/select4_ref b/test/data/select4_ref
new file mode 100644
index 0000000..c1c2b87
Binary files /dev/null and b/test/data/select4_ref differ
diff --git a/test/data/select5_ref b/test/data/select5_ref
new file mode 100644
index 0000000..98fdf9a
Binary files /dev/null and b/test/data/select5_ref differ
diff --git a/test/test_Cat.sh b/test/test_Cat.sh
new file mode 100755
index 0000000..66ea80a
--- /dev/null
+++ b/test/test_Cat.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+#CDO=cdo
+#DATAPATH=data
+#
+CDODEBUG=0
+#
+if [ "$CDO_TEST_DEBUG" = 1 ]; then CDODEBUG=1; fi
+#
+if [ "$CDODEBUG" = 0 ]; then CDO="$CDO -s"; fi
+CDOOUT=cout
+CDOERR=cerr
+FORMAT="-f srv -b 32"
+RSTAT=0;
+#
+IFILE=$DATAPATH/t21_geosp_tsurf.grb
+#
+RFILE=catdata_ref
+OFILE=catdata
+#
+cp $IFILE ${RFILE}
+chmod u+w ${RFILE}
+cat $IFILE >> ${RFILE}
+#
+rm -f ${OFILE}
+$CDO cat $IFILE ${OFILE}
+$CDO cat $IFILE ${OFILE}
+#
+$CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
+if [ $? != 0 ]    ; then RSTAT=`expr $RSTAT + 1`; fi
+if [ -s $CDOOUT ] ; then RSTAT=`expr $RSTAT + 1`; fi
+if [ -s $CDOERR ] ; then RSTAT=`expr $RSTAT + 1`; fi
+if [ "$CDODEBUG" = 1 ]; then cat $CDOOUT $CDOERR; fi
+rm -f $OFILE $RFILE
+#
+rm -f $CDOOUT $CDOERR
+#
+if [ "$CDODEBUG" = 1 ]; then
+  echo "rstat: $RSTAT"
+fi
+#
+exit $RSTAT
diff --git a/test/test_Remap.sh b/test/test_Remap.sh
deleted file mode 100755
index 499e779..0000000
--- a/test/test_Remap.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-#
-#CDO=cdo
-#DATAPATH=data
-#
-CDODEBUG=0
-#
-if [ "$CDODEBUG" = 0 ]; then CDO="$CDO -s"; fi
-CDOOUT=cout
-CDOERR=cerr
-FORMAT="-f srv -b 32"
-GRIDS="n16 n32"
-RSTAT=0;
-#
-IFILE=$DATAPATH/bathy4.grb
-#
-for GRIDTYPE in " " "-setgridtype,curvilinear" "-setgridtype,unstructured"; do
-  for GRID in $GRIDS; do
-# remaplaf: sort could give different results"
-    RMODS="bil bic nn con"
-    if [ "$GRIDTYPE" = "-setgridtype,unstructured" ]; then RMODS="nn con"; fi
-    for RMOD in $RMODS; do
-      OFILE=${GRID}_${RMOD}
-      RFILE=$DATAPATH/${OFILE}_ref
-      $CDO $FORMAT remap${RMOD},$GRID $GRIDTYPE $IFILE ${OFILE} > $CDOOUT 2> $CDOERR
-      if [ $? != 0 ]    ; then RSTAT=`expr $RSTAT + 1`; fi
-      if [ "$CDODEBUG" = 1 ]; then cat $CDOOUT $CDOERR; fi
-      $CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
-      if [ $? != 0 ]    ; then RSTAT=`expr $RSTAT + 1`; fi
-      if [ -s $CDOOUT ] ; then RSTAT=`expr $RSTAT + 1`; fi
-      if [ "$CDODEBUG" = 1 ]; then cat $CDOOUT $CDOERR; fi
-      rm -f $OFILE
-    done
-  done
-done
-#
-rm -f $CDOOUT $CDOERR
-#
-if [ "$CDODEBUG" = 1 ]; then
-  echo "rstat: $RSTAT"
-fi
-#
-exit $RSTAT
diff --git a/test/test_Select.sh b/test/test_Select.sh
new file mode 100755
index 0000000..f31e866
--- /dev/null
+++ b/test/test_Select.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+#
+CDODEBUG=0
+#
+if [ "$CDODEBUG" = 0 ]; then CDO="$CDO -s"; fi
+CDOOUT=cout
+CDOERR=cerr
+FORMAT="-f srv -b 32"
+RSTAT=0;
+#
+IFILE=$DATAPATH/pl_data.grb
+#
+TNUM=0
+#
+for SELECT in "code=130,152" "code=130,152,level=9000,90" "code=130,152,level=9000,90,timestep=2,3,5" "code=130" "level=90000"; do
+  TNUM=`expr $TNUM + 1`
+
+  RFILE=$DATAPATH/select${TNUM}_ref
+  OFILE=select${TNUM}_res
+  $CDO select,${SELECT} $IFILE $OFILE > $CDOOUT 2> $CDOERR
+  if [ $? != 0 ]    ; then RSTAT=`expr $RSTAT + 1`; fi
+  if [ "$CDODEBUG" = 1 ]; then cat $CDOOUT $CDOERR; fi
+  $CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
+  if [ $? != 0 ]    ; then RSTAT=`expr $RSTAT + 1`; fi
+  if [ -s $CDOOUT ] ; then RSTAT=`expr $RSTAT + 1`; fi
+  if [ "$CDODEBUG" = 1 ]; then cat $CDOOUT $CDOERR; fi
+  rm -f $OFILE
+#
+  rm -f $CDOOUT $CDOERR
+done
+#
+TNUM=0
+#
+for DELETE in "code=129" "code=129,130,level=90000,900" "code=129,130,level=90000,900,timestep=1,4"; do
+  TNUM=`expr $TNUM + 1`
+
+  RFILE=$DATAPATH/select${TNUM}_ref
+  OFILE=delete${TNUM}_res
+  $CDO delete,${DELETE} $IFILE $OFILE > $CDOOUT 2> $CDOERR
+  if [ $? != 0 ]    ; then RSTAT=`expr $RSTAT + 1`; fi
+  if [ "$CDODEBUG" = 1 ]; then cat $CDOOUT $CDOERR; fi
+  $CDO diff $OFILE $RFILE > $CDOOUT 2> $CDOERR
+  if [ $? != 0 ]    ; then RSTAT=`expr $RSTAT + 1`; fi
+  if [ -s $CDOOUT ] ; then RSTAT=`expr $RSTAT + 1`; fi
+  if [ "$CDODEBUG" = 1 ]; then cat $CDOOUT $CDOERR; fi
+  rm -f $OFILE
+#
+  rm -f $CDOOUT $CDOERR
+done
+#
+if [ "$CDODEBUG" = 1 ]; then
+  echo "rstat: $RSTAT"
+fi
+#
+exit $RSTAT

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



More information about the debian-science-commits mailing list