[med-svn] [mia] 01/08: Imported Upstream version 2.2.0

Gert Wollny gert-guest at moszumanska.debian.org
Fri Sep 5 09:59:03 UTC 2014


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

gert-guest pushed a commit to branch master
in repository mia.

commit 8f32053bed40d33d5a45ed47dd235e76ae41c0c1
Author: Gert Wollny <gw.fossdev at gmail.com>
Date:   Wed Sep 3 13:51:42 2014 +0200

    Imported Upstream version 2.2.0
---
 .gitignore                                         |   6 +
 CMakeLists.txt                                     |  24 +-
 ChangeLog                                          |  80 ++-
 addons/CMakeLists.txt                              |  20 +-
 addons/dicom/CMakeLists.txt                        |   2 +-
 addons/dicom/dcm2d.cc                              |   6 +-
 addons/dicom/dcm2d.hh                              |   4 +-
 addons/dicom/dcm3d.cc                              |  22 +-
 addons/dicom/dcm3d.hh                              |   4 +-
 addons/dicom/dicom4mia.cc                          | 312 ++++++++-
 addons/dicom/dicom4mia.hh                          |  11 +-
 addons/dicom/getset.hh                             |   2 +-
 addons/dicom/test_dcm2d.cc                         |  49 +-
 addons/dicom/test_dcm3d.cc                         |  56 +-
 addons/dicom/test_dicom4mia.cc                     |  10 +-
 addons/hdf5/CMakeLists.txt                         |  47 ++
 addons/hdf5/hdf5_3dimage.cc                        | 247 +++++++
 addons/hdf5/hdf5_3dimage.hh                        |  40 ++
 addons/hdf5/hdf5a_mia.cc                           | 360 +++++++++++
 addons/hdf5/hdf5a_mia.hh                           |  75 +++
 addons/hdf5/hdf5mia.cc                             | 473 ++++++++++++++
 addons/hdf5/hdf5mia.hh                             | 317 +++++++++
 addons/hdf5/test_hdf5_3dimage.cc                   | 118 ++++
 addons/hdf5/test_hdf5mia.cc                        | 371 +++++++++++
 addons/jpg/CMakeLists.txt                          |   2 +-
 addons/jpg/jpg-gray.cc                             |   2 +-
 addons/jpg/jpg-rgb.cc                              |   2 +-
 addons/nifti/CMakeLists.txt                        |  68 ++
 addons/nifti/niftiimage.cc                         | 440 +++++++++++++
 addons/nifti/niftiimage.hh                         |  41 ++
 addons/nifti/test_niftiimage.cc                    | 110 ++++
 addons/nlopt/CMakeLists.txt                        |   2 +-
 addons/nlopt/nlopt.cc                              |   4 +-
 addons/nlopt/nlopt.hh                              |   2 +-
 addons/nlopt/test_nlopt.cc                         |   2 +-
 addons/openexr/2dimgexr.cc                         |   2 +-
 addons/openexr/2dvfexr.cc                          |   2 +-
 addons/openexr/CMakeLists.txt                      |   2 +-
 addons/openexr/test_openexr.cc                     |   2 +-
 addons/png/CMakeLists.txt                          |   2 +-
 addons/png/png-gray.cc                             |   2 +-
 addons/png/png-rgb.cc                              |   2 +-
 addons/tiff/CMakeLists.txt                         |   2 +-
 addons/tiff/tiff.cc                                |  18 +-
 addons/vistaio/2dtrans.cc                          |  21 +-
 addons/vistaio/2dtrans.hh                          |  41 ++
 addons/vistaio/2dvfvistaio.cc                      |   4 +-
 addons/vistaio/2dvistaio.cc                        |  10 +-
 addons/vistaio/2dvistaio.hh                        |   4 +-
 addons/vistaio/3dtrans.cc                          |  32 +-
 addons/vistaio/3dtrans.hh                          |  41 ++
 addons/vistaio/3dvfvistaio.cc                      |  12 +-
 addons/vistaio/3dvistaio.cc                        |  11 +-
 addons/vistaio/3dvistaio.hh                        |   4 +-
 addons/vistaio/CMakeLists.txt                      |   9 +-
 addons/vistaio/test_2dtrans.cc                     |  78 +++
 addons/vistaio/test_2dvistaio.cc                   |   2 +-
 addons/vistaio/test_3dtrans.cc                     |  77 +++
 addons/vistaio/test_3dvistaio.cc                   |   6 +-
 addons/vistaio/test_vista4mia.cc                   | 123 +---
 addons/vistaio/vista4mia.cc                        |   9 +-
 addons/vistaio/vista4mia.hh                        |   6 +-
 addons/vistaio/vistamesh.cc                        |   2 +-
 addons/vtk/CMakeLists.txt                          |   2 +-
 addons/vtk/test_vtkimage.cc                        |  68 +-
 addons/vtk/test_vtkmesh.cc                         |   2 +-
 addons/vtk/test_vtkvf.cc                           |   2 +-
 addons/vtk/vtkimage.cc                             | 152 ++++-
 addons/vtk/vtkimage.hh                             |   2 +-
 addons/vtk/vtkmesh.cc                              |   8 +-
 addons/vtk/vtkmesh.hh                              |   2 +-
 addons/vtk/vtkvf.cc                                |  14 +-
 addons/vtk/vtkvf.hh                                |   2 +-
 cmake/CMakeLists.txt                               |   2 +-
 cmake/checkSSEAttributeVectorCanUseSubscript.cmake |  40 ++
 cmake/macros.cmake                                 |   2 +-
 cmake/pluginmacro.cmake                            |  46 +-
 doc/CMakeLists.txt                                 |   2 +-
 doc/mainpage.doc                                   |   2 +-
 doc/miamyosegmentset.xsd                           |  88 ++-
 doc/miareadxml.py                                  |  51 +-
 doc/reference.dox.cmake                            |   2 -
 examples/2d/CMakeLists.txt                         |   2 +-
 examples/2d/filter/CMakeLists.txt                  |   2 +-
 examples/2d/filter/simple.cc                       |   2 +-
 examples/2d/filter/simple.hh                       |   2 +-
 examples/2d/filter/test_simple.cc                  |   2 +-
 examples/CMakeLists.txt                            |   2 +-
 gsl++/CMakeLists.txt                               |   2 +-
 gsl++/gsldefines.hh                                |   2 +-
 gsl++/matrix.cc                                    |   2 +-
 gsl++/matrix.hh                                    |   2 +-
 gsl++/multimin.cc                                  |   2 +-
 gsl++/multimin.hh                                  |   2 +-
 gsl++/test_matrix.cc                               |   2 +-
 gsl++/test_multimin.cc                             |   2 +-
 gsl++/test_vector.cc                               |   2 +-
 gsl++/vector.cc                                    |   2 +-
 gsl++/vector.hh                                    |   2 +-
 gsl++/vector_dispatch.hh                           |   2 +-
 gsl++/vector_template.cxx                          |   2 +-
 gsl++/vector_template.hh                           |   2 +-
 gsl++/wavelet.cc                                   |   2 +-
 gsl++/wavelet.hh                                   |   2 +-
 mia.hh                                             |   2 +-
 mia/2d.hh                                          |   3 +-
 mia/2d/BoundingBox.cc                              | 135 ----
 mia/2d/BoundingBox.hh                              |  98 ---
 mia/2d/CMakeLists.txt                              |  66 +-
 mia/2d/SegFrame.cc                                 | 362 -----------
 mia/2d/SegFrame.hh                                 | 221 -------
 mia/2d/SegPoint.cc                                 | 120 ----
 mia/2d/SegPoint.hh                                 | 106 ---
 mia/2d/SegSection.cc                               | 208 ------
 mia/2d/SegSection.hh                               | 138 ----
 mia/2d/SegSet.cc                                   | 254 --------
 mia/2d/SegSet.hh                                   | 159 -----
 mia/2d/SegSetWithImages.cc                         | 174 -----
 mia/2d/SegSetWithImages.hh                         |  76 ---
 mia/2d/SegStar.cc                                  | 179 -----
 mia/2d/SegStar.hh                                  | 101 ---
 mia/2d/angle.cc                                    |   2 +-
 mia/2d/angle.hh                                    |   2 +-
 mia/2d/boundingbox.cc                              | 135 ++++
 mia/2d/boundingbox.hh                              |  98 +++
 mia/2d/combiner/CMakeLists.txt                     |   2 +-
 mia/2d/combiner/ops.cc                             |   2 +-
 mia/2d/combiner/ops.hh                             |   2 +-
 mia/2d/combiner/plugin.hh                          |   2 +-
 mia/2d/combiner/test_ops.cc                        |   2 +-
 mia/2d/correlation_weight.cc                       |   2 +-
 mia/2d/correlation_weight.hh                       |   2 +-
 mia/2d/cost.cc                                     |  21 +-
 mia/2d/cost.hh                                     |  13 +-
 mia/2d/cost/CMakeLists.txt                         |   4 +-
 mia/2d/cost/lncc.cc                                | 209 ++++++
 mia/2d/cost/lncc.hh                                |  52 ++
 mia/2d/cost/lsd.cc                                 |   2 +-
 mia/2d/cost/lsd.hh                                 |   2 +-
 mia/2d/cost/mi.cc                                  |   2 +-
 mia/2d/cost/mi.hh                                  |   2 +-
 mia/2d/cost/ncc.cc                                 | 171 +++++
 mia/2d/cost/ncc.hh                                 |  51 ++
 mia/2d/cost/ngf.cc                                 |  32 +-
 mia/2d/cost/ngf.hh                                 |   7 +-
 mia/2d/cost/ssd-automask.cc                        |  51 ++
 mia/2d/cost/ssd-automask.hh                        |  36 ++
 mia/2d/cost/ssd.cc                                 |   2 +-
 mia/2d/cost/ssd.hh                                 |   2 +-
 mia/2d/cost/ssd2.cc                                |   2 +-
 mia/2d/cost/ssd2.hh                                |   2 +-
 mia/2d/cost/ssddf.cc                               |   2 +-
 mia/2d/cost/test_divcurl.cc                        |   2 +-
 mia/2d/cost/test_lncc.cc                           | 105 +++
 mia/2d/cost/test_lsd.cc                            |   2 +-
 mia/2d/cost/test_mi.cc                             |   4 +-
 mia/2d/cost/test_ncc.cc                            | 104 +++
 mia/2d/cost/test_ngf.cc                            |   3 +-
 mia/2d/cost/test_ssd-automask.cc                   |  64 ++
 mia/2d/cost/test_ssd.cc                            |   4 +-
 mia/2d/cost/test_ssd2.cc                           |   2 +-
 mia/2d/creator.cc                                  |   2 +-
 mia/2d/creator.hh                                  |   2 +-
 mia/2d/creator/CMakeLists.txt                      |   2 +-
 mia/2d/creator/circle.cc                           |   2 +-
 mia/2d/cstkernel.cc                                |  11 +-
 mia/2d/cstkernel.hh                                |  30 +-
 mia/2d/datafield.cc                                |   8 +-
 mia/2d/datafield.cxx                               |   5 +-
 mia/2d/datafield.hh                                |   6 +-
 mia/2d/defines2d.hh                                |   2 +-
 mia/2d/deformer.hh                                 |   2 +-
 mia/2d/distance.cc                                 |   2 +-
 mia/2d/distance.hh                                 |   2 +-
 mia/2d/distances.cc                                |   2 +-
 mia/2d/fft/CMakeLists.txt                          |   4 +-
 mia/2d/fftkernel.cc                                |   2 +-
 mia/2d/fftkernel.hh                                |   2 +-
 mia/2d/filter.cc                                   |  39 +-
 mia/2d/filter.hh                                   |  45 +-
 mia/2d/filter/CMakeLists.txt                       |   3 +-
 mia/2d/filter/adaptmed.cc                          |   2 +-
 mia/2d/filter/adaptmed.hh                          |   2 +-
 mia/2d/filter/admean.cc                            |   2 +-
 mia/2d/filter/admean.hh                            |   2 +-
 mia/2d/filter/aniso.cc                             |   2 +-
 mia/2d/filter/aniso.hh                             |   2 +-
 mia/2d/filter/bandpass.cc                          |   2 +-
 mia/2d/filter/bandpass.hh                          |   2 +-
 mia/2d/filter/binarize.cc                          |   2 +-
 mia/2d/filter/binarize.hh                          |   2 +-
 mia/2d/filter/classmap.cc                          |   2 +-
 mia/2d/filter/combiner.cc                          |  36 ++
 mia/2d/filter/combiner.hh                          |  38 ++
 mia/2d/filter/convert.cc                           |   2 +-
 mia/2d/filter/convert.hh                           |   2 +-
 mia/2d/filter/crop.cc                              |   2 +-
 mia/2d/filter/crop.hh                              |   2 +-
 mia/2d/filter/cst.cc                               |   2 +-
 mia/2d/filter/cst.hh                               |   2 +-
 mia/2d/filter/distance.cc                          |   2 +-
 mia/2d/filter/distance.hh                          |   2 +-
 mia/2d/filter/downscale.cc                         |   8 +-
 mia/2d/filter/downscale.hh                         |   2 +-
 mia/2d/filter/fft.cc                               |   2 +-
 mia/2d/filter/fft.hh                               |   2 +-
 mia/2d/filter/frequency.cc                         |   2 +-
 mia/2d/filter/gradnorm.cc                          |   2 +-
 mia/2d/filter/gradnorm.hh                          |   2 +-
 mia/2d/filter/harmmean.cc                          |   2 +-
 mia/2d/filter/ianiso.cc                            |   2 +-
 mia/2d/filter/invert.cc                            |   2 +-
 mia/2d/filter/invert.hh                            |   2 +-
 mia/2d/filter/kmeans.cc                            |   2 +-
 mia/2d/filter/kmeans.hh                            |   2 +-
 mia/2d/filter/kuwahara.cc                          |   2 +-
 mia/2d/filter/label.cc                             |   2 +-
 mia/2d/filter/label.hh                             |   2 +-
 mia/2d/filter/labelmap.cc                          |   4 +-
 mia/2d/filter/labelmap.hh                          |   2 +-
 mia/2d/filter/lnfft.cc                             |   2 +-
 mia/2d/filter/load.cc                              |   4 +-
 mia/2d/filter/load.hh                              |   2 +-
 mia/2d/filter/mask.cc                              |   7 +-
 mia/2d/filter/mask.hh                              |   2 +-
 mia/2d/filter/mean.cc                              |   2 +-
 mia/2d/filter/mean.hh                              |   2 +-
 mia/2d/filter/median.cc                            |   2 +-
 mia/2d/filter/median.hh                            |   2 +-
 mia/2d/filter/midpoint.cc                          |   2 +-
 mia/2d/filter/mlv.cc                               |   2 +-
 mia/2d/filter/mlv.hh                               |   2 +-
 mia/2d/filter/morphological.cc                     |   2 +-
 mia/2d/filter/morphological.hh                     |   2 +-
 mia/2d/filter/ngfnorm.cc                           |   2 +-
 mia/2d/filter/ngfnorm.hh                           |   2 +-
 mia/2d/filter/noise.cc                             |   2 +-
 mia/2d/filter/noise.hh                             |   2 +-
 mia/2d/filter/regiongrow.cc                        |   4 +-
 mia/2d/filter/regiongrow.hh                        |   2 +-
 mia/2d/filter/rgg.cc                               |   2 +-
 mia/2d/filter/scale.cc                             |   2 +-
 mia/2d/filter/scale.hh                             |   2 +-
 mia/2d/filter/seededwatershed.cc                   |   2 +-
 mia/2d/filter/seededwatershed.hh                   |   2 +-
 mia/2d/filter/selectbig.cc                         |   2 +-
 mia/2d/filter/selectbig.hh                         |   2 +-
 mia/2d/filter/sepconv.cc                           |   2 +-
 mia/2d/filter/sepconv.hh                           |   2 +-
 mia/2d/filter/shaped_mean.cc                       |   2 +-
 mia/2d/filter/shaped_mean.hh                       |   2 +-
 mia/2d/filter/sortlabel.cc                         |   2 +-
 mia/2d/filter/sortlabel.hh                         |   2 +-
 mia/2d/filter/tee.cc                               |   4 +-
 mia/2d/filter/tee.hh                               |   2 +-
 mia/2d/filter/test_adaptmed.cc                     |   2 +-
 mia/2d/filter/test_admean.cc                       |   2 +-
 mia/2d/filter/test_aniso.cc                        |   2 +-
 mia/2d/filter/test_bandpass.cc                     |   2 +-
 mia/2d/filter/test_binarize.cc                     |   2 +-
 mia/2d/filter/test_combiner.cc                     | 110 ++++
 mia/2d/filter/test_convert.cc                      |   2 +-
 mia/2d/filter/test_crop.cc                         |   2 +-
 mia/2d/filter/test_cst.cc                          |   2 +-
 mia/2d/filter/test_distance.cc                     |   2 +-
 mia/2d/filter/test_downscale.cc                    |   5 +-
 mia/2d/filter/test_fft.cc                          |   2 +-
 mia/2d/filter/test_gradnorm.cc                     |   2 +-
 mia/2d/filter/test_invert.cc                       |   2 +-
 mia/2d/filter/test_kmeans.cc                       |   2 +-
 mia/2d/filter/test_label.cc                        |   2 +-
 mia/2d/filter/test_labelmap.cc                     |   2 +-
 mia/2d/filter/test_load.cc                         |   3 +-
 mia/2d/filter/test_mask.cc                         |   2 +-
 mia/2d/filter/test_mean.cc                         |   2 +-
 mia/2d/filter/test_median.cc                       |   2 +-
 mia/2d/filter/test_mlv.cc                          |   2 +-
 mia/2d/filter/test_morphological.cc                |   4 +-
 mia/2d/filter/test_ngfnorm.cc                      |   2 +-
 mia/2d/filter/test_noise.cc                        |   4 +-
 mia/2d/filter/test_regiongrow.cc                   |   4 +-
 mia/2d/filter/test_scale.cc                        |   4 +-
 mia/2d/filter/test_seededwatershed.cc              |   4 +-
 mia/2d/filter/test_selectbig.cc                    |   2 +-
 mia/2d/filter/test_sepconv.cc                      |   4 +-
 mia/2d/filter/test_shaped_mean.cc                  |   4 +-
 mia/2d/filter/test_sortlabel.cc                    |   2 +-
 mia/2d/filter/test_tee.cc                          |   2 +-
 mia/2d/filter/test_thinning.cc                     |   2 +-
 mia/2d/filter/test_thresh.cc                       |   4 +-
 mia/2d/filter/test_transform.cc                    |   5 +-
 mia/2d/filter/test_watershed.cc                    |   3 +-
 mia/2d/filter/thinning.cc                          |   2 +-
 mia/2d/filter/thinning.hh                          |   2 +-
 mia/2d/filter/thresh.cc                            |   2 +-
 mia/2d/filter/thresh.hh                            |   2 +-
 mia/2d/filter/transform.cc                         |   4 +-
 mia/2d/filter/transform.hh                         |   2 +-
 mia/2d/filter/variation.cc                         |   2 +-
 mia/2d/filter/watershed.cc                         |   2 +-
 mia/2d/filter/watershed.hh                         |   2 +-
 mia/2d/filter/wmean.cc                             |   2 +-
 mia/2d/filter/ws.cc                                |   2 +-
 mia/2d/filterchain.cc                              |   2 +-
 mia/2d/filterchain.hh                              |   2 +-
 mia/2d/filtertest.cc                               |   2 +-
 mia/2d/filtertest.hh                               |   2 +-
 mia/2d/fullcost.cc                                 |   8 +-
 mia/2d/fullcost.hh                                 |  14 +-
 mia/2d/fullcost/CMakeLists.txt                     |   4 +-
 mia/2d/fullcost/divcurl.cc                         |  39 --
 mia/2d/fullcost/divcurl.hh                         |  34 -
 mia/2d/fullcost/image.cc                           |   6 +-
 mia/2d/fullcost/image.hh                           |   2 +-
 mia/2d/fullcost/maskedimage.cc                     | 320 +++++++++
 mia/2d/fullcost/maskedimage.hh                     |  80 +++
 mia/2d/fullcost/test_divcurl.cc                    |  83 ---
 mia/2d/fullcost/test_image.cc                      |  28 +-
 mia/2d/fullcost/test_maskedimage.cc                | 196 ++++++
 mia/2d/fuzzyClusterSolverCG.cc                     | 332 ----------
 mia/2d/fuzzyClusterSolverCG.hh                     | 179 -----
 mia/2d/fuzzyClusterSolverSOR.cc                    |  85 ---
 mia/2d/fuzzyClusterSolverSOR.hh                    |  70 --
 mia/2d/fuzzyclustersolver_cg.cc                    | 332 ++++++++++
 mia/2d/fuzzyclustersolver_cg.hh                    | 179 +++++
 mia/2d/fuzzyclustersolver_sor.cc                   |  86 +++
 mia/2d/fuzzyclustersolver_sor.hh                   |  70 ++
 mia/2d/fuzzyseg.cc                                 |  43 +-
 mia/2d/fuzzyseg.hh                                 |   2 +-
 mia/2d/ground_truth_evaluator.cc                   |   2 +-
 mia/2d/ground_truth_evaluator.hh                   |   2 +-
 mia/2d/groundtruthproblem.cc                       |   2 +-
 mia/2d/groundtruthproblem.hh                       |   2 +-
 mia/2d/ica.cc                                      |   2 +-
 mia/2d/ica.hh                                      |   2 +-
 mia/2d/image.cc                                    |   4 +-
 mia/2d/image.hh                                    |   9 +-
 mia/2d/imageio.cc                                  |  23 +-
 mia/2d/imageio.hh                                  |  37 +-
 mia/2d/imageiotest.cc                              |   2 +-
 mia/2d/imageiotest.hh                              |   2 +-
 mia/2d/imagetest.cc                                |   2 +-
 mia/2d/imagetest.hh                                |   2 +-
 mia/2d/inittesthandlers.cc                         |  50 --
 mia/2d/inittesthandlers.hh                         |  54 --
 mia/2d/interpolator.cc                             |  10 +-
 mia/2d/interpolator.cxx                            |   6 +-
 mia/2d/interpolator.hh                             |   2 +-
 mia/2d/io/CMakeLists.txt                           |   9 +-
 mia/2d/io/bmp.cc                                   |   4 +-
 mia/2d/io/raw.cc                                   |   2 +-
 mia/2d/io/test_xml.cc                              | 193 ++++++
 mia/2d/io/xml.cc                                   |  97 +++
 mia/2d/io/xml.hh                                   |  36 ++
 mia/2d/iterator.cxx                                | 160 ++++-
 mia/2d/iterator.hh                                 | 197 +++++-
 mia/2d/kernel/CMakeLists.txt                       |   2 +-
 mia/2d/kernel/curv.cc                              |   2 +-
 mia/2d/maskedcost.cc                               |  45 ++
 mia/2d/maskedcost.hh                               |  62 ++
 mia/2d/maskedcost/CMakeLists.txt                   |  35 +
 mia/2d/maskedcost/lncc.cc                          | 231 +++++++
 mia/2d/maskedcost/lncc.hh                          |  55 ++
 mia/2d/maskedcost/mi.cc                            |  38 ++
 mia/2d/maskedcost/mi.hh                            |  37 ++
 mia/2d/maskedcost/ncc.cc                           | 185 ++++++
 mia/2d/maskedcost/ncc.hh                           |  52 ++
 mia/2d/maskedcost/ssd.cc                           |  38 ++
 mia/2d/maskedcost/ssd.hh                           |  37 ++
 mia/2d/maskedcost/test_lncc.cc                     | 112 ++++
 mia/2d/maskedcost/test_mi.cc                       | 160 +++++
 mia/2d/maskedcost/test_ncc.cc                      | 169 +++++
 mia/2d/maskedcost/test_ssd.cc                      | 153 +++++
 mia/2d/matrix.hh                                   |   2 +-
 mia/2d/model.cc                                    |   2 +-
 mia/2d/model.hh                                    |  12 +-
 mia/2d/model/CMakeLists.txt                        |   2 +-
 mia/2d/model/identity.cc                           |   2 +-
 mia/2d/model/identity.hh                           |   2 +-
 mia/2d/model/navier.cc                             |   2 +-
 mia/2d/model/navier.hh                             |   2 +-
 mia/2d/model/naviera.cc                            |   3 +-
 mia/2d/model/naviera.hh                            |   2 +-
 mia/2d/model/test_identity.cc                      |   2 +-
 mia/2d/model/test_navier.cc                        |   2 +-
 mia/2d/model/test_naviera.cc                       |   2 +-
 mia/2d/modelsolverreg.cc                           |   2 +-
 mia/2d/modelsolverreg.hh                           |   2 +-
 mia/2d/morphshape.cc                               |   2 +-
 mia/2d/morphshape.hh                               |   2 +-
 mia/2d/multicost.cc                                |   2 +-
 mia/2d/multicost.hh                                |   2 +-
 mia/2d/nfg.cc                                      |   2 +-
 mia/2d/nfg.hh                                      |   2 +-
 mia/2d/nonrigidregister.cc                         |   2 +-
 mia/2d/nonrigidregister.hh                         |   2 +-
 mia/2d/perfusion.cc                                |  47 +-
 mia/2d/perfusion.hh                                |  11 +-
 mia/2d/polygon.cc                                  |   2 +-
 mia/2d/polygon.hh                                  |   2 +-
 mia/2d/ppmatrix.cc                                 |   2 +-
 mia/2d/ppmatrix.hh                                 |   2 +-
 mia/2d/register.cc                                 |   2 +-
 mia/2d/register.hh                                 |   2 +-
 mia/2d/rgbimageio.cc                               |   2 +-
 mia/2d/rgbimageio.hh                               |   4 +-
 mia/2d/rgbio/CMakeLists.txt                        |   2 +-
 mia/2d/rgbio/bmp.cc                                |   2 +-
 mia/2d/rigidregister.cc                            |   2 +-
 mia/2d/rigidregister.hh                            |   2 +-
 mia/2d/segframe.cc                                 | 377 +++++++++++
 mia/2d/segframe.hh                                 | 240 +++++++
 mia/2d/segpoint.cc                                 | 120 ++++
 mia/2d/segpoint.hh                                 | 106 +++
 mia/2d/segsection.cc                               | 208 ++++++
 mia/2d/segsection.hh                               | 138 ++++
 mia/2d/segset.cc                                   | 268 ++++++++
 mia/2d/segset.hh                                   | 162 +++++
 mia/2d/segsetwithimages.cc                         | 226 +++++++
 mia/2d/segsetwithimages.hh                         | 116 ++++
 mia/2d/segstar.cc                                  | 179 +++++
 mia/2d/segstar.hh                                  | 101 +++
 mia/2d/shape.cc                                    |  10 +-
 mia/2d/shape.hh                                    |  25 +-
 mia/2d/shapes/CMakeLists.txt                       |   2 +-
 mia/2d/shapes/basic_shapes.cc                      |   2 +-
 mia/2d/shapes/basic_shapes.hh                      |   2 +-
 mia/2d/shapes/rect.cc                              |   2 +-
 mia/2d/shapes/rect.hh                              |   2 +-
 mia/2d/shapes/sphere.cc                            |   2 +-
 mia/2d/shapes/sphere.hh                            |   2 +-
 mia/2d/shapes/test_basic_shapes.cc                 |   2 +-
 mia/2d/shapes/test_rect.cc                         |   2 +-
 mia/2d/shapes/test_sphere.cc                       |   2 +-
 mia/2d/similarity_profile.cc                       |   2 +-
 mia/2d/similarity_profile.hh                       |   2 +-
 mia/2d/sparse_image_solver.cc                      |  11 +-
 mia/2d/sparse_image_solver.hh                      |  14 +-
 mia/2d/splinepenalty/CMakeLists.txt                |   2 +-
 mia/2d/splinepenalty/divcurl.cc                    |  12 +-
 mia/2d/splinepenalty/divcurl.hh                    |   6 +-
 mia/2d/splinepenalty/test_divcurl.cc               |  12 +-
 mia/2d/splinetransformpenalty.cc                   |  28 +-
 mia/2d/splinetransformpenalty.hh                   |  15 +-
 mia/2d/test_2d.cc                                  |   2 +-
 mia/2d/test_angle.cc                               |   2 +-
 mia/2d/test_boundingbox.cc                         |   4 +-
 mia/2d/test_combiner.cc                            |   2 +-
 mia/2d/test_correlation_weight.cc                  |   2 +-
 mia/2d/test_cost.cc                                |  18 +-
 mia/2d/test_datafield.cc                           |   2 +-
 mia/2d/test_distance.cc                            |   2 +-
 mia/2d/test_divcurlmatrix.cc                       |   2 +-
 mia/2d/test_filter.cc                              |  34 +-
 mia/2d/test_filter_cast.cc                         |   2 +-
 mia/2d/test_fullcost.cc                            |   6 +-
 mia/2d/test_fullcost_mi_spline.cc                  |   6 +-
 mia/2d/test_groundtruthproblem.cc                  |   3 +-
 mia/2d/test_ica.cc                                 |   2 +-
 mia/2d/test_image.cc                               |   2 +-
 mia/2d/test_imagecostbase.cc                       |   2 +-
 mia/2d/test_imageio.cc                             |   5 +-
 mia/2d/test_interpol.cc                            |   4 +-
 mia/2d/test_iterator.cc                            |  97 ++-
 mia/2d/test_matrix.cc                              |   2 +-
 mia/2d/test_modelsolverreg.cc                      |   4 +-
 mia/2d/test_morphshape.cc                          |   2 +-
 mia/2d/test_nfg.cc                                 |   2 +-
 mia/2d/test_nonrigidregister.cc                    |   2 +-
 mia/2d/test_oldnewintegrate.cc                     |   4 +-
 mia/2d/test_param.cc                               |   2 +-
 mia/2d/test_perfusion.cc                           |   2 +-
 mia/2d/test_polygon.cc                             |   2 +-
 mia/2d/test_ppmatrix.cc                            |   4 +-
 mia/2d/test_register.cc                            |   2 +-
 mia/2d/test_regplugins.cc                          |   2 +-
 mia/2d/test_rigidregister.cc                       |   4 +-
 mia/2d/test_segframe.cc                            |  12 +-
 mia/2d/test_segmentation.cc                        |  12 +-
 mia/2d/test_segpoint.cc                            |  11 +-
 mia/2d/test_shape.cc                               |   4 +-
 mia/2d/test_similarity_profile.cc                  |  22 +-
 mia/2d/test_sparse_image_solver.cc                 |   2 +-
 mia/2d/test_splinetransformpenalty.cc              |  50 +-
 mia/2d/test_trackpoint.cc                          |   7 +-
 mia/2d/test_transform.cc                           |   4 +-
 mia/2d/test_transformfactory.cc                    |  31 +-
 mia/2d/test_transio.cc                             |  28 +-
 mia/2d/test_vector.cc                              |  13 +-
 mia/2d/test_vectorfield_interpolator.cc            |   8 +-
 mia/2d/test_vfio.cc                                |   2 +-
 mia/2d/timestep.cc                                 |   2 +-
 mia/2d/timestep.hh                                 |   2 +-
 mia/2d/timestep/CMakeLists.txt                     |   2 +-
 mia/2d/timestep/direct.cc                          |   2 +-
 mia/2d/timestep/direct.hh                          |   2 +-
 mia/2d/timestep/fluid.cc                           |   2 +-
 mia/2d/timestep/fluid.hh                           |   2 +-
 mia/2d/timestep/test_direct.cc                     |   4 +-
 mia/2d/timestep/test_fluid.cc                      |   4 +-
 mia/2d/trackpoint.cc                               |   2 +-
 mia/2d/trackpoint.hh                               |   2 +-
 mia/2d/trait.hh                                    |   2 +-
 mia/2d/transform.cc                                |  19 +-
 mia/2d/transform.hh                                |  38 +-
 mia/2d/transform/CMakeLists.txt                    |   7 +-
 mia/2d/transform/affine.cc                         |  35 +-
 mia/2d/transform/affine.hh                         |   8 +-
 mia/2d/transform/rigid.cc                          |  36 +-
 mia/2d/transform/rigid.hh                          |   8 +-
 mia/2d/transform/rotation.cc                       |  35 +-
 mia/2d/transform/rotation.hh                       |   8 +-
 mia/2d/transform/spline.cc                         |  78 +--
 mia/2d/transform/spline.hh                         |  24 +-
 mia/2d/transform/test_affine.cc                    |  15 +-
 mia/2d/transform/test_nonlinear.cc                 |  25 +
 mia/2d/transform/test_rigid.cc                     |  14 +-
 mia/2d/transform/test_rotation.cc                  |   6 +-
 mia/2d/transform/test_spline.cc                    |   5 +-
 mia/2d/transform/test_translate.cc                 |   4 +-
 mia/2d/transform/test_vectorfield.cc               | 185 +-----
 mia/2d/transform/translate.cc                      |  33 +-
 mia/2d/transform/translate.hh                      |   8 +-
 mia/2d/transform/vectorfield.cc                    | 230 +------
 mia/2d/transform/vectorfield.hh                    |  43 +-
 mia/2d/transformfactory.cc                         |   2 +-
 mia/2d/transformfactory.hh                         |   2 +-
 mia/2d/transformio.cc                              |  12 +-
 mia/2d/transformio.hh                              |  16 +-
 mia/2d/transformmock.cc                            |   2 +-
 mia/2d/transformmock.hh                            |   2 +-
 mia/2d/transio/CMakeLists.txt                      |   2 +-
 mia/2d/transio/bbs.cc                              |   2 +-
 mia/2d/transio/pbs.cc                              |   2 +-
 mia/2d/transio/serialization.hh                    |  18 +-
 mia/2d/transio/xml.cc                              |   2 +-
 mia/2d/vector.hh                                   |  23 +-
 mia/2d/vectorfield.cc                              |  75 ++-
 mia/2d/vectorfield.hh                              |  25 +-
 mia/2d/vfio.cc                                     |   5 +-
 mia/2d/vfio.hh                                     |  16 +-
 mia/2d/vfiotest.cc                                 |   2 +-
 mia/3d.hh                                          |   4 +-
 mia/3d/2dimagefifofilter.cc                        |   2 +-
 mia/3d/2dimagefifofilter.hh                        |   2 +-
 mia/3d/CMakeLists.txt                              |  41 +-
 mia/3d/affine_matrix.cc                            | 394 +++++++++++
 mia/3d/affine_matrix.hh                            | 163 +++++
 mia/3d/camera.cc                                   |   2 +-
 mia/3d/camera.hh                                   |   2 +-
 mia/3d/combiner/CMakeLists.txt                     |   4 +-
 mia/3d/combiner/labelxmap.cc                       |   2 +-
 mia/3d/combiner/labelxmap.hh                       |   2 +-
 mia/3d/combiner/ops.cc                             |  23 +-
 mia/3d/combiner/ops.hh                             |  43 +-
 mia/3d/combiner/plugin.hh                          |   2 +-
 mia/3d/combiner/test_labelxmap.cc                  |   2 +-
 mia/3d/combiner/test_ops.cc                        |  16 +-
 mia/3d/cost.cc                                     |  19 +-
 mia/3d/cost.hh                                     |  14 +-
 mia/3d/cost/CMakeLists.txt                         |   5 +-
 mia/3d/cost/lncc.cc                                | 219 +++++++
 mia/3d/cost/lncc.hh                                |  53 ++
 mia/3d/cost/mi.cc                                  |   2 +-
 mia/3d/cost/mi.hh                                  |   2 +-
 mia/3d/cost/ncc.cc                                 | 171 +++++
 mia/3d/cost/ncc.hh                                 |  51 ++
 mia/3d/cost/ngf.cc                                 |  50 +-
 mia/3d/cost/ngf.hh                                 |  16 +-
 mia/3d/cost/ssd-automask.cc                        |  51 ++
 mia/3d/cost/ssd-automask.hh                        |  36 ++
 mia/3d/cost/ssd.cc                                 |   2 +-
 mia/3d/cost/ssd.hh                                 |   2 +-
 mia/3d/cost/test_lncc.cc                           | 188 ++++++
 mia/3d/cost/test_mi.cc                             |   4 +-
 mia/3d/cost/test_ncc.cc                            | 105 +++
 mia/3d/cost/test_ngf.cc                            |  20 +-
 mia/3d/cost/test_ssd-automask.cc                   |  70 ++
 mia/3d/cost/test_ssd.cc                            |   6 +-
 mia/3d/cost/test_ssdautomask.cc                    |  63 ++
 mia/3d/creator.cc                                  |   2 +-
 mia/3d/creator.hh                                  |   2 +-
 mia/3d/creator/CMakeLists.txt                      |   2 +-
 mia/3d/creator/lattic.cc                           |   2 +-
 mia/3d/creator/lattic.hh                           |   2 +-
 mia/3d/creator/sphere.cc                           |   2 +-
 mia/3d/creator/sphere.hh                           |   2 +-
 mia/3d/creator/test_lattic.cc                      |   4 +-
 mia/3d/creator/test_sphere.cc                      |   2 +-
 mia/3d/critical_point.cc                           |  37 +-
 mia/3d/critical_point.hh                           |   2 +-
 mia/3d/datafield.cc                                |   6 +-
 mia/3d/datafield.cxx                               |  10 +-
 mia/3d/datafield.hh                                |  17 +-
 mia/3d/defines3d.hh                                |   3 +-
 mia/3d/deformer.hh                                 |   2 +-
 mia/3d/distance.cc                                 |   2 +-
 mia/3d/distance.hh                                 |   2 +-
 mia/3d/fifof/CMakeLists.txt                        |   2 +-
 mia/3d/fifof/byslice.cc                            |   2 +-
 mia/3d/fifof/byslice.hh                            |   2 +-
 mia/3d/fifof/gauss.cc                              |   2 +-
 mia/3d/fifof/gauss.hh                              |   2 +-
 mia/3d/fifof/label.cc                              |   4 +-
 mia/3d/fifof/label.hh                              |   2 +-
 mia/3d/fifof/median.cc                             |   2 +-
 mia/3d/fifof/median.hh                             |   2 +-
 mia/3d/fifof/mlv.cc                                |   2 +-
 mia/3d/fifof/mlv.hh                                |   2 +-
 mia/3d/fifof/morphological.cc                      |   2 +-
 mia/3d/fifof/morphological.hh                      |   2 +-
 mia/3d/fifof/regiongrow.cc                         |   4 +-
 mia/3d/fifof/regiongrow.hh                         |   2 +-
 mia/3d/fifof/rgg.cc                                |   4 +-
 mia/3d/fifof/rgg2pass.cc                           |   2 +-
 mia/3d/fifof/test_byslice.cc                       |  21 +-
 mia/3d/fifof/test_gauss.cc                         |  19 +-
 mia/3d/fifof/test_label.cc                         |   7 +-
 mia/3d/fifof/test_median.cc                        |   2 +-
 mia/3d/fifof/test_mlv.cc                           |   3 +-
 mia/3d/fifof/test_morphological.cc                 |   2 +-
 mia/3d/fifof/test_regiongrow.cc                    |   2 +-
 mia/3d/fifotestfixture.cc                          |   2 +-
 mia/3d/fifotestfixture.hh                          |   2 +-
 mia/3d/filter.cc                                   |  45 +-
 mia/3d/filter.hh                                   |  41 +-
 mia/3d/filter/CMakeLists.txt                       |  13 +-
 mia/3d/filter/aniso.cc                             |   2 +-
 mia/3d/filter/bandpass.cc                          |   2 +-
 mia/3d/filter/bandpass.hh                          |   2 +-
 mia/3d/filter/binarize.cc                          |   2 +-
 mia/3d/filter/binarize.hh                          |   2 +-
 mia/3d/filter/combiner.cc                          |  36 ++
 mia/3d/filter/combiner.hh                          |  38 ++
 mia/3d/filter/convert.cc                           |   2 +-
 mia/3d/filter/convert.hh                           |   2 +-
 mia/3d/filter/crop.cc                              |   2 +-
 mia/3d/filter/crop.hh                              |   2 +-
 mia/3d/filter/distance.cc                          |  96 +++
 mia/3d/filter/distance.hh                          |  44 ++
 mia/3d/filter/downscale.cc                         |  13 +-
 mia/3d/filter/downscale.hh                         |   2 +-
 mia/3d/filter/gradnorm.cc                          |  10 +-
 mia/3d/filter/gradnorm.hh                          |   2 +-
 mia/3d/filter/growmask.cc                          |   5 +-
 mia/3d/filter/growmask.hh                          |   2 +-
 mia/3d/filter/invert.cc                            |   2 +-
 mia/3d/filter/invert.hh                            |   2 +-
 mia/3d/filter/kmeans.cc                            |   2 +-
 mia/3d/filter/kmeans.hh                            |   2 +-
 mia/3d/filter/label.cc                             |   2 +-
 mia/3d/filter/label.hh                             |   2 +-
 mia/3d/filter/load.cc                              |   4 +-
 mia/3d/filter/load.hh                              |   2 +-
 mia/3d/filter/lvdownscale.cc                       | 158 +++++
 mia/3d/filter/lvdownscale.hh                       |  54 ++
 mia/3d/filter/mask.cc                              |   4 +-
 mia/3d/filter/mask.hh                              |   2 +-
 mia/3d/filter/mean.cc                              | 256 ++++++++
 mia/3d/filter/mean.hh                              |  86 +++
 mia/3d/filter/median.cc                            |   2 +-
 mia/3d/filter/median.hh                            |   2 +-
 mia/3d/filter/mlv.cc                               |   2 +-
 mia/3d/filter/mlv.hh                               |   2 +-
 mia/3d/filter/morphological.cc                     |  96 +--
 mia/3d/filter/morphological.hh                     |   2 +-
 mia/3d/filter/msnormalizer.cc                      | 173 +++++
 mia/3d/filter/msnormalizer.hh                      |  57 ++
 mia/3d/filter/reorient.cc                          |   2 +-
 mia/3d/filter/reorient.hh                          |   2 +-
 mia/3d/filter/resize.cc                            |   2 +-
 mia/3d/filter/resize.hh                            |   2 +-
 mia/3d/filter/scale.cc                             |   2 +-
 mia/3d/filter/scale.hh                             |   2 +-
 mia/3d/filter/seededwatershed.cc                   |   2 +-
 mia/3d/filter/seededwatershed.hh                   |   2 +-
 mia/3d/filter/selectbig.cc                         |   2 +-
 mia/3d/filter/selectbig.hh                         |   2 +-
 mia/3d/filter/sepconv.cc                           |   2 +-
 mia/3d/filter/sepconv.hh                           |   2 +-
 mia/3d/filter/tee.cc                               |   4 +-
 mia/3d/filter/tee.hh                               |   2 +-
 mia/3d/filter/test_bandpass.cc                     |   2 +-
 mia/3d/filter/test_binarize.cc                     |   2 +-
 mia/3d/filter/test_combiner.cc                     | 110 ++++
 mia/3d/filter/test_convert.cc                      |   2 +-
 mia/3d/filter/test_crop.cc                         |   4 +-
 mia/3d/filter/test_distance.cc                     | 104 +++
 mia/3d/filter/test_downscale.cc                    |   5 +-
 mia/3d/filter/test_gradnorm.cc                     |   2 +-
 mia/3d/filter/test_growmask.cc                     |   4 +-
 mia/3d/filter/test_invert.cc                       |   2 +-
 mia/3d/filter/test_kmeans.cc                       |   2 +-
 mia/3d/filter/test_label.cc                        |   5 +-
 mia/3d/filter/test_load.cc                         |   2 +-
 mia/3d/filter/test_lvdownscale.cc                  | 132 ++++
 mia/3d/filter/test_mask.cc                         |   2 +-
 mia/3d/filter/test_mean.cc                         | 129 ++++
 mia/3d/filter/test_median.cc                       |   2 +-
 mia/3d/filter/test_mlv.cc                          |   2 +-
 mia/3d/filter/test_morphological.cc                |   2 +-
 mia/3d/filter/test_msnormalizer.cc                 |  87 +++
 mia/3d/filter/test_reorient.cc                     |   2 +-
 mia/3d/filter/test_resize.cc                       |   2 +-
 mia/3d/filter/test_scale.cc                        |   4 +-
 mia/3d/filter/test_seededwatershed.cc              |   5 +-
 mia/3d/filter/test_selectbig.cc                    |   2 +-
 mia/3d/filter/test_sepconv.cc                      |   7 +-
 mia/3d/filter/test_tee.cc                          |   2 +-
 mia/3d/filter/test_thinning.cc                     |   2 +-
 mia/3d/filter/test_transform.cc                    |   4 +-
 mia/3d/filter/test_watershed.cc                    |   5 +-
 mia/3d/filter/thinning.cc                          |   2 +-
 mia/3d/filter/thinning.hh                          |   2 +-
 mia/3d/filter/transform.cc                         |  38 +-
 mia/3d/filter/transform.hh                         |   9 +-
 mia/3d/filter/watershed.cc                         |   2 +-
 mia/3d/filter/watershed.hh                         |   2 +-
 mia/3d/fullcost.cc                                 |   2 +-
 mia/3d/fullcost.hh                                 |   2 +-
 mia/3d/fullcost/CMakeLists.txt                     |   4 +-
 mia/3d/fullcost/divcurl.cc                         |  37 --
 mia/3d/fullcost/divcurl.hh                         |  34 -
 mia/3d/fullcost/image.cc                           |  15 +-
 mia/3d/fullcost/image.hh                           |   4 +-
 mia/3d/fullcost/maskedimage.cc                     | 343 ++++++++++
 mia/3d/fullcost/maskedimage.hh                     |  87 +++
 mia/3d/fullcost/taggedssd.cc                       |  23 +-
 mia/3d/fullcost/taggedssd.hh                       |   2 +-
 mia/3d/fullcost/test_divcurl.cc                    |  84 ---
 mia/3d/fullcost/test_image.cc                      |   5 +-
 mia/3d/fullcost/test_maskedimage.cc                | 221 +++++++
 mia/3d/fullcost/test_taggedssd.cc                  |   9 +-
 mia/3d/fuzzyClusterSolverCG.cc                     | 366 -----------
 mia/3d/fuzzyClusterSolverCG.hh                     | 183 ------
 mia/3d/fuzzyclustersolver_cg.cc                    | 366 +++++++++++
 mia/3d/fuzzyclustersolver_cg.hh                    | 183 ++++++
 mia/3d/fuzzyseg.cc                                 |   4 +-
 mia/3d/fuzzyseg.hh                                 |   2 +-
 mia/3d/ica.cc                                      |   2 +-
 mia/3d/ica.hh                                      |   2 +-
 mia/3d/image.cc                                    | 134 ++--
 mia/3d/image.hh                                    | 110 +---
 mia/3d/imagecollect.cc                             |   2 +-
 mia/3d/imagecollect.hh                             |   2 +-
 mia/3d/imageio.cc                                  |  11 +-
 mia/3d/imageio.hh                                  |  18 +-
 mia/3d/imageiotest.cc                              |   2 +-
 mia/3d/imageiotest.hh                              |   2 +-
 mia/3d/imagetest.cc                                |  95 +++
 mia/3d/imagetest.hh                                |  45 ++
 mia/3d/interpolator.cc                             |  14 +-
 mia/3d/interpolator.cxx                            |   6 +-
 mia/3d/interpolator.hh                             |   2 +-
 mia/3d/io/CMakeLists.txt                           |   2 +-
 mia/3d/io/analyze.cc                               | 116 ++--
 mia/3d/io/analyze.hh                               |   5 +-
 mia/3d/io/inria.cc                                 |   6 +-
 mia/3d/io/vff.cc                                   |   2 +-
 mia/3d/iterator.cxx                                | 224 +++++--
 mia/3d/iterator.hh                                 | 241 ++++++-
 mia/3d/landmark.cc                                 |   2 +-
 mia/3d/landmark.hh                                 |   2 +-
 mia/3d/landmarklist.cc                             |   2 +-
 mia/3d/landmarklist.hh                             |   2 +-
 mia/3d/landmarklistio.cc                           |  10 +-
 mia/3d/landmarklistio.hh                           |  12 +-
 mia/3d/linear_transform.cc                         |   2 +-
 mia/3d/linear_transform.hh                         |   2 +-
 mia/3d/lmio/CMakeLists.txt                         |   2 +-
 mia/3d/lmio/lmx.cc                                 |   2 +-
 mia/3d/maskedcost.cc                               |  45 ++
 mia/3d/maskedcost.hh                               |  60 ++
 mia/3d/maskedcost/CMakeLists.txt                   |  35 +
 mia/3d/maskedcost/lncc.cc                          | 246 +++++++
 mia/3d/maskedcost/lncc.hh                          |  54 ++
 mia/3d/maskedcost/mi.cc                            |  38 ++
 mia/3d/maskedcost/mi.hh                            |  37 ++
 mia/3d/maskedcost/ncc.cc                           | 185 ++++++
 mia/3d/maskedcost/ncc.hh                           |  52 ++
 mia/3d/maskedcost/ssd.cc                           |  38 ++
 mia/3d/maskedcost/ssd.hh                           |  37 ++
 mia/3d/maskedcost/test_lncc.cc                     | 194 ++++++
 mia/3d/maskedcost/test_mi.cc                       | 170 +++++
 mia/3d/maskedcost/test_ncc.cc                      | 172 +++++
 mia/3d/maskedcost/test_ssd.cc                      | 154 +++++
 mia/3d/matrix.cc                                   | 236 +++++++
 mia/3d/matrix.hh                                   | 325 ++--------
 mia/3d/model.cc                                    |   2 +-
 mia/3d/model.hh                                    |   7 +-
 mia/3d/multicost.cc                                |   2 +-
 mia/3d/multicost.hh                                |   2 +-
 mia/3d/multireg.cc                                 |   2 +-
 mia/3d/multireg.hh                                 |   2 +-
 mia/3d/nfg.cc                                      |   2 +-
 mia/3d/nfg.hh                                      |   2 +-
 mia/3d/nonrigidregister.cc                         |   2 +-
 mia/3d/nonrigidregister.hh                         |   2 +-
 mia/3d/orientation.cc                              | 289 +++++++--
 mia/3d/orientation.hh                              | 163 ++++-
 mia/3d/ppmatrix.cc                                 |   2 +-
 mia/3d/ppmatrix.hh                                 |   2 +-
 mia/3d/quaternion.cc                               | 161 ++++-
 mia/3d/quaternion.hh                               |  36 +-
 mia/3d/reg3d/CMakeLists.txt                        |   2 +-
 mia/3d/reg3d/direct.cc                             |   2 +-
 mia/3d/reg3d/fluid.cc                              |   2 +-
 mia/3d/reg3d/navier.cc                             |   3 +-
 mia/3d/reg3d/naviera.cc                            |   3 +-
 mia/3d/reg3d/navierasse.cc                         |   3 +-
 mia/3d/reg3d/navierpsse.cc                         |   3 +-
 mia/3d/register.cc                                 |   2 +-
 mia/3d/register.hh                                 |   2 +-
 mia/3d/rigidregister.cc                            |   2 +-
 mia/3d/rigidregister.hh                            |   2 +-
 mia/3d/rot.cc                                      | 305 +++++++++
 mia/3d/rot.hh                                      |  78 +++
 mia/3d/shape.cc                                    |  15 +-
 mia/3d/shape.hh                                    |  16 +-
 mia/3d/shapes/CMakeLists.txt                       |   2 +-
 mia/3d/shapes/basic_shapes.cc                      |   2 +-
 mia/3d/shapes/sphere.cc                            |   2 +-
 mia/3d/shapes/sphere.hh                            |   2 +-
 mia/3d/similarity_profile.cc                       |   2 +-
 mia/3d/similarity_profile.hh                       |   2 +-
 mia/3d/splinepenalty/CMakeLists.txt                |   2 +-
 mia/3d/splinepenalty/divcurl.cc                    |  12 +-
 mia/3d/splinepenalty/divcurl.hh                    |   6 +-
 mia/3d/splinepenalty/test_divcurl.cc               |   4 +-
 mia/3d/splinetransformpenalty.cc                   |  28 +-
 mia/3d/splinetransformpenalty.hh                   |  13 +-
 mia/3d/stackdisttrans.cc                           |   2 +-
 mia/3d/stackdisttrans.hh                           |   2 +-
 mia/3d/test_2dimagefifofilter.cc                   |   2 +-
 mia/3d/test_3d.cc                                  |  40 +-
 mia/3d/test_affine_matrix.cc                       | 719 +++++++++++++++++++++
 mia/3d/test_combiner.cc                            |   2 +-
 mia/3d/test_cost.cc                                |   6 +-
 mia/3d/test_datafield.cc                           |  28 +-
 mia/3d/test_deform.cc                              |   4 +-
 mia/3d/test_distance.cc                            |   2 +-
 mia/3d/test_filter.cc                              |  88 ---
 mia/3d/test_fullcost.cc                            |   3 +-
 mia/3d/test_ica.cc                                 |   2 +-
 mia/3d/test_image.cc                               |  27 +-
 mia/3d/test_imagecollect.cc                        |   2 +-
 mia/3d/test_imageio.cc                             |  99 ---
 mia/3d/test_interpol.cc                            | 124 +---
 mia/3d/test_iterator.cc                            |  77 ++-
 mia/3d/test_landmark.cc                            |   2 +-
 mia/3d/test_landmarklistio.cc                      |   4 +-
 mia/3d/test_matrix.cc                              |  10 +-
 mia/3d/test_nfg.cc                                 |   2 +-
 mia/3d/test_nonrigidregister.cc                    |   2 +-
 mia/3d/test_orientation.cc                         | 321 ++++++++-
 mia/3d/test_ppmatrix.cc                            |  67 +-
 mia/3d/test_quaternion.cc                          | 249 ++++++-
 mia/3d/test_regplugins.cc                          |   2 +-
 mia/3d/test_rigidregister.cc                       |   4 +-
 mia/3d/test_rot.cc                                 | 167 +++++
 mia/3d/test_shape.cc                               |   2 +-
 mia/3d/test_similarity_profile.cc                  |  21 +-
 mia/3d/test_splinetransformpenalty.cc              |  49 +-
 mia/3d/test_stackdisttrans.cc                      |   2 +-
 mia/3d/test_trackpoint.cc                          |   5 +-
 mia/3d/test_transform.cc                           |  56 +-
 mia/3d/test_transformfactory.cc                    |   8 +-
 mia/3d/test_transio.cc                             |  10 +-
 mia/3d/test_vector.cc                              |  30 +-
 mia/3d/test_vectorfield.cc                         |   2 +-
 mia/3d/test_vfio.cc                                |   2 +-
 mia/3d/timestep.cc                                 |   3 +-
 mia/3d/timestep.hh                                 |   2 +-
 mia/3d/trackpoint.cc                               |   2 +-
 mia/3d/trackpoint.hh                               |   2 +-
 mia/3d/trait.hh                                    |   2 +-
 mia/3d/transform.cc                                |  34 +-
 mia/3d/transform.hh                                |  45 +-
 mia/3d/transform/CMakeLists.txt                    |   7 +-
 mia/3d/transform/affine.cc                         |  37 +-
 mia/3d/transform/affine.hh                         |  10 +-
 mia/3d/transform/axisrot.cc                        | 345 ++++++++++
 mia/3d/transform/axisrot.hh                        | 128 ++++
 mia/3d/transform/raffine.cc                        | 357 ++++++++++
 mia/3d/transform/raffine.hh                        | 127 ++++
 mia/3d/transform/rigid.cc                          |  41 +-
 mia/3d/transform/rigid.hh                          |   8 +-
 mia/3d/transform/rotation.cc                       |  39 +-
 mia/3d/transform/rotation.hh                       |   8 +-
 mia/3d/transform/rotbend.cc                        | 334 ++++++++++
 mia/3d/transform/rotbend.hh                        | 120 ++++
 mia/3d/transform/spline.cc                         |  48 +-
 mia/3d/transform/spline.hh                         |   7 +-
 mia/3d/transform/test_affine.cc                    |   4 +-
 mia/3d/transform/test_axisrot.cc                   | 173 +++++
 mia/3d/transform/test_nonlinear.cc                 |  25 +
 mia/3d/transform/test_raffine.cc                   | 231 +++++++
 mia/3d/transform/test_rigid.cc                     |   5 +-
 mia/3d/transform/test_rotation.cc                  |   5 +-
 mia/3d/transform/test_rotbend.cc                   | 178 +++++
 mia/3d/transform/test_spline.cc                    |  28 +-
 mia/3d/transform/test_translate.cc                 |   4 +-
 mia/3d/transform/test_vectorfield.cc               |   5 +-
 mia/3d/transform/translate.cc                      |  33 +-
 mia/3d/transform/translate.hh                      |   8 +-
 mia/3d/transform/vectorfield.cc                    |  18 +-
 mia/3d/transform/vectorfield.hh                    |   5 +-
 mia/3d/transformfactory.cc                         |  10 +-
 mia/3d/transformfactory.hh                         |  17 +-
 mia/3d/transformio.cc                              |  13 +-
 mia/3d/transformio.hh                              |  16 +-
 mia/3d/transformmock.cc                            |   2 +-
 mia/3d/transformmock.hh                            |   2 +-
 mia/3d/transio/CMakeLists.txt                      |   2 +-
 mia/3d/transio/bbs.cc                              |   2 +-
 mia/3d/transio/serialization.hh                    |  19 +-
 mia/3d/transio/xml.cc                              |   2 +-
 mia/3d/valueattributetranslator.hh                 | 111 ++++
 mia/3d/vector.hh                                   |  25 +-
 mia/3d/vectorfield.cc                              |  14 +-
 mia/3d/vectorfield.hh                              |  46 +-
 mia/3d/vfio.cc                                     |   3 +-
 mia/3d/vfio.hh                                     |   8 +-
 mia/3d/vfiotest.cc                                 |   2 +-
 mia/3d/vfiotest.hh                                 |   2 +-
 mia/CMakeLists.txt                                 |   2 +-
 mia/core.hh                                        |   4 +-
 mia/core/CMakeLists.txt                            |  16 +-
 mia/core/attribute_names.cc                        |  66 ++
 mia/core/attribute_names.hh                        |  71 ++
 mia/core/attributes.cc                             |  31 +-
 mia/core/attributes.hh                             | 151 +++--
 mia/core/attributetype.hh                          | 101 +++
 mia/core/bfsv23dispatch.hh                         |   2 +-
 mia/core/boundary_conditions.cc                    |  10 +-
 mia/core/boundary_conditions.hh                    |  19 +-
 mia/core/callback.cc                               |   2 +-
 mia/core/callback.hh                               |   2 +-
 mia/core/cmdbooloption.cc                          |   2 +-
 mia/core/cmdbooloption.hh                          |   2 +-
 mia/core/cmdlineparser.cc                          |  34 +-
 mia/core/cmdlineparser.hh                          |  52 +-
 mia/core/cmdoption.cc                              |  81 ++-
 mia/core/cmdoption.hh                              |  28 +-
 mia/core/cmdoptionflags.hh                         |  77 +++
 mia/core/cmdstringoption.cc                        |  13 +-
 mia/core/cmdstringoption.hh                        |   6 +-
 mia/core/combiner.cc                               |   2 +-
 mia/core/combiner.hh                               |   2 +-
 mia/core/cost.cc                                   |   4 +-
 mia/core/cost.cxx                                  |   2 +-
 mia/core/cost.hh                                   |   3 +-
 mia/core/creator.cc                                |   2 +-
 mia/core/creator.hh                                |   2 +-
 mia/core/cstplan.hh                                |   2 +-
 mia/core/datapool.cc                               |   2 +-
 mia/core/datapool.hh                               |   2 +-
 mia/core/defines.hh                                |   3 +-
 mia/core/delayedparameter.hh                       |  10 +-
 mia/core/dictmap.hh                                |   2 +-
 mia/core/distance.cc                               |   2 +-
 mia/core/distance.hh                               |   2 +-
 mia/core/dlloader.cc                               |   2 +-
 mia/core/dlloader.hh                               |   2 +-
 mia/core/dummyhandler.cc                           |   4 +-
 mia/core/dummyhandler.hh                           |   5 +-
 mia/core/errormacro.hh                             |   2 +-
 mia/core/export_handler.hh                         |   2 +-
 mia/core/factory.hh                                | 116 +++-
 mia/core/factory_trait.hh                          |   2 +-
 mia/core/fft1d_r2c.cc                              |   2 +-
 mia/core/fft1d_r2c.hh                              |   2 +-
 mia/core/fftslopeclassifier.cc                     |   2 +-
 mia/core/fftslopeclassifier.hh                     |   2 +-
 mia/core/fifofilter.cxx                            |   2 +-
 mia/core/fifofilter.hh                             |   2 +-
 mia/core/file.cc                                   |   8 +-
 mia/core/file.hh                                   |   2 +-
 mia/core/filetools.cc                              |   2 +-
 mia/core/filetools.hh                              |   2 +-
 mia/core/filter.cc                                 |   2 +-
 mia/core/filter.hh                                 |  88 ++-
 mia/core/fixedwidthoutput.cc                       |   2 +-
 mia/core/fixedwidthoutput.hh                       |   2 +-
 mia/core/flagstring.cc                             |   2 +-
 mia/core/flagstring.hh                             |   2 +-
 mia/core/fullstats.cc                              |   2 +-
 mia/core/fullstats.hh                              |   2 +-
 mia/core/handler.cxx                               |   2 +-
 mia/core/handler.hh                                |   2 +-
 mia/core/handlerbase.cc                            |  13 +-
 mia/core/handlerbase.hh                            |  26 +-
 mia/core/histogram.hh                              |   2 +-
 mia/core/history.cc                                |   2 +-
 mia/core/history.hh                                |   2 +-
 mia/core/ica.cc                                    |   2 +-
 mia/core/ica.hh                                    |   2 +-
 mia/core/ica_template.cxx                          |   2 +-
 mia/core/ica_template.hh                           |   2 +-
 mia/core/import_handler.hh                         |   2 +-
 mia/core/index.cc                                  |   2 +-
 mia/core/index.hh                                  |   2 +-
 mia/core/info.cc                                   |   4 +-
 mia/core/interpolator1d.cc                         |   2 +-
 mia/core/interpolator1d.cxx                        |   2 +-
 mia/core/interpolator1d.hh                         |   2 +-
 mia/core/iodata.cc                                 |   2 +-
 mia/core/iodata.hh                                 |   2 +-
 mia/core/iohandler.cxx                             |  14 +-
 mia/core/iohandler.hh                              |  11 +-
 mia/core/ioplugin.cc                               |   3 +-
 mia/core/ioplugin.cxx                              |   6 +-
 mia/core/ioplugin.hh                               |   7 +-
 mia/core/kmeans.cc                                 |   2 +-
 mia/core/kmeans.hh                                 |   2 +-
 mia/core/labelmap.cc                               |   2 +-
 mia/core/labelmap.hh                               |   2 +-
 mia/core/meanvar.hh                                |   2 +-
 mia/core/minimizer.cc                              |   2 +-
 mia/core/minimizer.hh                              |   2 +-
 mia/core/minimizer/CMakeLists.txt                  |   5 +-
 mia/core/minimizer/gdas.cc                         | 182 ++++++
 mia/core/minimizer/gdas.hh                         |  61 ++
 mia/core/minimizer/gdsq.cc                         |   2 +-
 mia/core/minimizer/gdsq.hh                         |   2 +-
 mia/core/minimizer/gsl.cc                          |   2 +-
 mia/core/minimizer/gsl.hh                          |   2 +-
 mia/core/minimizer/test_gdas.cc                    | 109 ++++
 mia/core/minimizer/test_gdsq.cc                    |   2 +-
 mia/core/minimizer/test_gsl.cc                     |   2 +-
 mia/core/mitestimages.cc                           |   2 +-
 mia/core/mitestimages.hh                           |   2 +-
 mia/core/module.cc                                 |   2 +-
 mia/core/module.hh                                 |   2 +-
 mia/core/msgstream.cc                              |   7 +-
 mia/core/msgstream.hh                              |  64 +-
 mia/core/nccsum.cc                                 | 195 ++++++
 mia/core/nccsum.hh                                 | 162 +++++
 mia/core/noise/CMakeLists.txt                      |   2 +-
 mia/core/noise/gauss.cc                            |   2 +-
 mia/core/noise/gauss.hh                            |   2 +-
 mia/core/noise/test_gauss.cc                       |   2 +-
 mia/core/noise/test_uniform.cc                     |   2 +-
 mia/core/noise/uniform.cc                          |   2 +-
 mia/core/noise/uniform.hh                          |   2 +-
 mia/core/noisegen.cc                               |   9 +-
 mia/core/noisegen.hh                               |  12 +-
 mia/core/optionparser.cc                           |   4 +-
 mia/core/optionparser.hh                           |   5 +-
 mia/core/optparam.cc                               |   2 +-
 mia/core/optparam.hh                               |   2 +-
 mia/core/parameter.cc                              |  21 +-
 mia/core/parameter.cxx                             |  37 +-
 mia/core/parameter.hh                              |  10 +-
 mia/core/paramoption.cc                            |   4 +-
 mia/core/paramoption.hh                            |   2 +-
 mia/core/pixeltype.cc                              |   2 +-
 mia/core/pixeltype.hh                              |   2 +-
 mia/core/plugin_base.cc                            |   9 +-
 mia/core/plugin_base.cxx                           |   2 +-
 mia/core/plugin_base.hh                            |  13 +-
 mia/core/plugin_test.cc                            |   2 +-
 mia/core/probmap.cc                                |   2 +-
 mia/core/probmap.hh                                |   2 +-
 mia/core/product_base.cc                           |   2 +-
 mia/core/product_base.hh                           |   2 +-
 mia/core/productcache.cc                           |   2 +-
 mia/core/productcache.hh                           |   2 +-
 mia/core/property_flags.cc                         |   2 +-
 mia/core/property_flags.hh                         |   2 +-
 mia/core/pwh.cc                                    |   2 +-
 mia/core/pwh.hh                                    |   2 +-
 mia/core/refholder.hh                              |   6 +-
 mia/core/regmodel.cc                               |   2 +-
 mia/core/regmodel.hh                               |   2 +-
 mia/core/revision.cc                               |   2 +-
 mia/core/scaler1d.cc                               |   2 +-
 mia/core/scaler1d.hh                               |   2 +-
 mia/core/seriesstats.cc                            |   2 +-
 mia/core/seriesstats.hh                            |   2 +-
 mia/core/shape.cc                                  |   2 +-
 mia/core/shape.cxx                                 |   2 +-
 mia/core/shape.hh                                  |   2 +-
 mia/core/simpson.hh                                |   2 +-
 mia/core/singular_refobj.hh                        | 194 ++++++
 mia/core/slopeclassifier.cc                        |   2 +-
 mia/core/slopeclassifier.hh                        |   2 +-
 mia/core/slopestatistics.cc                        |  29 +-
 mia/core/slopestatistics.hh                        |   6 +-
 mia/core/slopevector.hh                            |   2 +-
 mia/core/spacial_kernel.cc                         |  11 +-
 mia/core/spacial_kernel.hh                         |  13 +-
 mia/core/spacialkernel/CMakeLists.txt              |   2 +-
 mia/core/spacialkernel/gauss.cc                    |   2 +-
 mia/core/spacialkernel/gauss.hh                    |   2 +-
 mia/core/spacialkernel/test_gauss.cc               |   2 +-
 mia/core/sparse_solver.hh                          |   2 +-
 mia/core/splinebc/CMakeLists.txt                   |   2 +-
 mia/core/splinebc/bc.cc                            |   2 +-
 mia/core/splinebc/bc.hh                            |   2 +-
 mia/core/splinebc/test_bc.cc                       |   4 +-
 mia/core/splinekernel.cc                           |  12 +-
 mia/core/splinekernel.hh                           |  12 +-
 mia/core/splinekernel/CMakeLists.txt               |   2 +-
 mia/core/splinekernel/bspline.cc                   |   2 +-
 mia/core/splinekernel/bspline.hh                   |   2 +-
 mia/core/splinekernel/test_bspline.cc              |   4 +-
 mia/core/splineparzenmi.cc                         |   2 +-
 mia/core/splineparzenmi.hh                         | 160 ++++-
 mia/core/sqmin.cc                                  |   2 +-
 mia/core/sqmin.hh                                  |   2 +-
 mia/core/statistics.hh                             |   2 +-
 mia/core/streamredir.cc                            |   2 +-
 mia/core/streamredir.hh                            |   2 +-
 mia/core/svector.hh                                |  93 +++
 mia/core/test_Vector.cc                            |   2 +-
 mia/core/test_attributes.cc                        |  63 +-
 mia/core/test_boundary_conditions.cc               |   4 +-
 mia/core/test_callback.cc                          |   2 +-
 mia/core/test_cmdlineparser.cc                     |   6 +-
 mia/core/test_cmdoptionflags.cc                    |  47 ++
 mia/core/test_core.cc                              |   2 +-
 mia/core/test_cost.cc                              |   2 +-
 mia/core/test_cstplan.cc                           |   2 +-
 mia/core/test_datapool.cc                          |   2 +-
 mia/core/test_delayedparameter.cc                  |   2 +-
 mia/core/test_dictmap.cc                           |   2 +-
 mia/core/test_distance.cc                          |   2 +-
 mia/core/test_factoryoption.cc                     |  24 +-
 mia/core/test_fft1d.cc                             |   2 +-
 mia/core/test_fftslopeclassifier.cc                |   2 +-
 mia/core/test_fifofilter.cc                        |   2 +-
 mia/core/test_filetools.cc                         |   2 +-
 mia/core/test_filter.cc                            |   2 +-
 mia/core/test_fixedwidthoutput.cc                  |   2 +-
 mia/core/test_flagstring.cc                        |   2 +-
 mia/core/test_fullstats.cc                         |   2 +-
 mia/core/test_handler.cc                           |   5 +-
 mia/core/test_helpers.hh                           |   2 +-
 mia/core/test_histogram.cc                         |   4 +-
 mia/core/test_history.cc                           |   2 +-
 mia/core/test_ica.cc                               |   2 +-
 mia/core/test_index.cc                             |   2 +-
 mia/core/test_interpol.cc                          |   2 +-
 mia/core/test_interpolator1d.cc                    |  12 +-
 mia/core/test_iohandler.cc                         |  16 +-
 mia/core/test_kernels.cc                           |   2 +-
 mia/core/test_kmeans.cc                            |   2 +-
 mia/core/test_labelmap.cc                          |   2 +-
 mia/core/test_meanvar.cc                           |   2 +-
 mia/core/test_minimizer.cc                         |   5 +-
 mia/core/test_nccsum.cc                            | 174 +++++
 mia/core/test_noisegen.cc                          |   2 +-
 mia/core/test_optionparser.cc                      |  40 +-
 mia/core/test_optparam.cc                          |   9 +-
 mia/core/test_parameter.cc                         |  19 +-
 mia/core/test_parseroutput.cc                      |   2 +-
 mia/core/test_pixeltype.cc                         |   2 +-
 mia/core/test_probmap.cc                           |   2 +-
 mia/core/test_productcache.cc                      |   2 +-
 mia/core/test_property_flags.cc                    |   2 +-
 mia/core/test_pwh.cc                               |   2 +-
 mia/core/test_register.cc                          |   2 +-
 mia/core/test_scaler1d.cc                          |   7 +-
 mia/core/test_seriesstats.cc                       |   2 +-
 mia/core/test_shape.cc                             |   2 +-
 mia/core/test_simpson.cc                           |   2 +-
 mia/core/test_singular_refobj.cc                   |  66 ++
 mia/core/test_slopeclassifier.cc                   |   2 +-
 mia/core/test_slopestatistics.cc                   |   2 +-
 mia/core/test_sparse_solver.cc                     |   2 +-
 mia/core/test_splinekernel.cc                      |   5 +-
 mia/core/test_splineparzenmi.cc                    |   9 +-
 mia/core/test_sqmin.cc                             |   2 +-
 mia/core/test_statistics.cc                        |   2 +-
 mia/core/test_streamredir.cc                       |   2 +-
 mia/core/test_streamvector.cc                      | 100 +++
 mia/core/test_threadedmsg.cc                       |   2 +-
 mia/core/test_tools.cc                             |   2 +-
 mia/core/test_utils.cc                             |   2 +-
 mia/core/test_watch.cc                             |   2 +-
 mia/core/test_waveletslopeclassifier.cc            |   8 +-
 mia/core/testplug/CMakeLists.txt                   |   2 +-
 mia/core/testplug/dummy1.cc                        |   2 +-
 mia/core/testplug/dummy2.cc                        |   2 +-
 mia/core/testplug/lala.cc                          |   7 +-
 mia/core/testplug/lolo.cc                          |   2 +-
 mia/core/testplugin.cc                             |   3 +-
 mia/core/testplugin.hh                             |  14 +-
 mia/core/threadedmsg.cc                            |   2 +-
 mia/core/threadedmsg.hh                            |   2 +-
 mia/core/tools.hh                                  |   2 +-
 mia/core/traits.hh                                 |   2 +-
 mia/core/transformation.hh                         |  15 +-
 mia/core/type_traits.hh                            |   2 +-
 mia/core/typedescr.cc                              |   2 +-
 mia/core/typedescr.hh                              |   2 +-
 mia/core/utils.cc                                  |   2 +-
 mia/core/utils.hh                                  |  12 +-
 mia/core/vector.hh                                 |  14 +-
 mia/core/watch.cc                                  |   2 +-
 mia/core/watch.hh                                  |   2 +-
 mia/core/waveletslopeclassifier.cc                 |  59 +-
 mia/core/waveletslopeclassifier.hh                 |   7 +-
 mia/internal/autotest.hh                           |  17 +-
 mia/internal/main.hh                               |   2 +-
 mia/internal/pluginsettest.hh                      |   2 +-
 mia/internal/plugintester.hh                       |   5 +-
 mia/mesh.hh                                        |   2 +-
 mia/mesh/CMakeLists.txt                            |   2 +-
 mia/mesh/clist.hh                                  |   2 +-
 mia/mesh/filter.cc                                 |  11 +-
 mia/mesh/filter.hh                                 |  11 +-
 mia/mesh/filter/CMakeLists.txt                     |   2 +-
 mia/mesh/filter/scale.cc                           |   2 +-
 mia/mesh/filter/scale.hh                           |   2 +-
 mia/mesh/filter/test_scale.cc                      |   2 +-
 mia/mesh/filter/test_vtxsort.cc                    |   2 +-
 mia/mesh/filter/vtxsort.cc                         |   2 +-
 mia/mesh/filter/vtxsort.hh                         |   2 +-
 mia/mesh/io/CMakeLists.txt                         |   2 +-
 mia/mesh/io/gts.cc                                 |   2 +-
 mia/mesh/io/off.cc                                 |   2 +-
 mia/mesh/io/ply.cc                                 |   2 +-
 mia/mesh/io/stl.cc                                 |   2 +-
 mia/mesh/test_triangulate.cc                       |   2 +-
 mia/mesh/triangularMesh.cc                         |   2 +-
 mia/mesh/triangularMesh.hh                         |   2 +-
 mia/mesh/triangulate.hh                            |   2 +-
 mia/template/CMakeLists.txt                        |   7 +-
 mia/template/bandpass.cxx                          |   2 +-
 mia/template/bandpass.hh                           |   2 +-
 mia/template/binarize.cxx                          |   2 +-
 mia/template/binarize.hh                           |   2 +-
 mia/template/combiner.cxx                          |  30 +
 mia/template/combiner.hh                           |  56 ++
 mia/template/combiner_filter.hh                    | 110 ++++
 mia/template/convert.cxx                           |   2 +-
 mia/template/convert.hh                            |   2 +-
 mia/template/cvd_io_trait.hh                       |   2 +-
 mia/template/dimtrait.hh                           |   2 +-
 mia/template/divcurl.cxx                           |   2 +-
 mia/template/divcurl.hh                            |   2 +-
 mia/template/filter_chain.hh                       |   2 +-
 mia/template/filtertest.hh                         |   2 +-
 mia/template/fullcost.cxx                          |   2 +-
 mia/template/fullcost.hh                           |   2 +-
 mia/template/invert.cxx                            |   2 +-
 mia/template/invert.hh                             |   2 +-
 mia/template/lsd.hh                                |   2 +-
 mia/template/masked_cost.cxx                       |  55 ++
 mia/template/masked_cost.hh                        | 126 ++++
 mia/template/mi.hh                                 |   2 +-
 mia/template/mi_masked.cxx                         | 161 +++++
 mia/template/mi_masked.hh                          |  71 ++
 mia/template/multicost.cxx                         |   2 +-
 mia/template/multicost.hh                          |   2 +-
 mia/template/nonrigidregister.cxx                  |  20 +-
 mia/template/nonrigidregister.hh                   |   2 +-
 mia/template/normalize.hh                          |   2 +-
 mia/template/seededwatershed.hh                    |   4 +-
 mia/template/similarity_profile.cxx                |  48 +-
 mia/template/similarity_profile.hh                 |  15 +-
 mia/template/ssd-automask.cxx                      | 190 ++++++
 mia/template/ssd-automask.hh                       |  73 +++
 mia/template/ssd.hh                                |  95 ++-
 mia/template/ssd_masked.cxx                        | 163 +++++
 mia/template/ssd_masked.hh                         |  65 ++
 mia/template/trackpoint.cxx                        |   2 +-
 mia/template/trackpoint.hh                         |   2 +-
 mia/template/transformfactory.cxx                  |   2 +-
 mia/template/transformfactory.hh                   |   2 +-
 mia/template/watershed.hh                          |   2 +-
 mia/test/testhelpers.hh                            |   2 +-
 mia3d.pc.cmake                                     |   2 +-
 miaconfig.h.cmake                                  |   4 +
 miacore.pc.cmake                                   |   4 +-
 octave/CMakeLists.txt                              |   2 +-
 octave/miaoct.cc                                   |   2 +-
 src/2davgmasked.cc                                 |   8 +-
 src/2dbinarycombine.cc                             |  13 +-
 src/2dcost.cc                                      |   2 +-
 src/2ddeform.cc                                    |   8 +-
 src/2ddistance.cc                                  |   6 +-
 src/2deval-transformquantity.cc                    |   8 +-
 src/2dforce.cc                                     |  11 +-
 src/2dfuzzysegment.cc                              |  12 +-
 src/2dgrayimage-combine-to-rgb.cc                  |  10 +-
 src/2dgroundtruthreg.cc                            |  14 +-
 src/2dimagecombine-dice.cc                         |   8 +-
 src/2dimagecombiner.cc                             |   8 +-
 src/2dimagecreator.cc                              |   6 +-
 src/2dimagefilter.cc                               |   6 +-
 src/2dimagefilterstack.cc                          |   8 +-
 src/2dimagefullstats.cc                            |   4 +-
 src/2dimageregistration.cc                         |  15 +-
 src/2dimageselect.cc                               |   6 +-
 src/2dimageseries-maximum-intensity-projection.cc  | 111 ++++
 src/2dimagestats.cc                                |   4 +-
 src/2dlerp.cc                                      |  12 +-
 src/2dmany2one-nonrigid.cc                         |   8 +-
 src/2dmulti-force.cc                               |   4 +-
 src/2dmulti-nrreg.cc                               |   2 +-
 src/2dmultiimageto3d.cc                            |   8 +-
 src/2dmultiimagevar.cc                             |   5 +-
 src/2dmyocard-ica.cc                               |   4 +-
 src/2dmyocard-icaseries.cc                         |   6 +-
 src/2dmyocard-segment.cc                           |  12 +-
 src/2dmyocard-upsloap.cc                           |   8 +-
 src/2dmyoica-full.cc                               | 664 +++++++++++++++++++
 src/2dmyoica-nonrigid-parallel.cc                  |  72 ++-
 src/2dmyoica-nonrigid.cc                           |  77 ++-
 src/2dmyoica-nonrigid2.cc                          |  18 +-
 src/2dmyoicapgt.cc                                 | 629 ++++++++++++++++++
 src/2dmyomilles.cc                                 | 116 +++-
 src/2dmyoperiodic-nonrigid.cc                      |  47 +-
 src/2dmyopgt-nonrigid.cc                           |   8 +-
 src/2dmyoserial-nonrigid.cc                        |   8 +-
 src/2dmyoseries-compdice.cc                        |   8 +-
 src/2dmyoseries-dice.cc                            |   6 +-
 src/2dmyoset-all2one-nonrigid.cc                   |   8 +-
 src/2dnrreg.cc                                     |   2 +-
 src/2dsegcompare.cc                                |   8 +-
 src/2dseghausdorff.cc                              |   8 +-
 src/2dsegment-ahmed.cc                             |   6 +-
 src/2dsegment-fuzzyw.cc                            |  17 +-
 src/2dsegmentcropbox.cc                            |   8 +-
 src/2dsegseriesstats.cc                            |  35 +-
 src/2dsegshift.cc                                  |  11 +-
 src/2dsegshiftperslice.cc                          |  10 +-
 src/2dseries-mincorr.cc                            |   8 +-
 src/2dseries-sectionmask.cc                        |   8 +-
 src/2dseries-segdistance.cc                        |   8 +-
 src/2dseries2dordermedian.cc                       |   8 +-
 src/2dseries2sets.cc                               |   7 +-
 src/2dseriescorr.cc                                |  10 +-
 src/2dseriesgradMAD.cc                             |   8 +-
 src/2dseriesgradvariation.cc                       |   8 +-
 src/2dserieshausdorff.cc                           |   8 +-
 src/2dseriessmoothgradMAD.cc                       |   8 +-
 src/2dseriestovolume.cc                            |  10 +-
 src/2dstackfilter.cc                               |   8 +-
 src/2dto3dimage.cc                                 |  10 +-
 src/2dto3dimageb.cc                                |   4 +-
 src/2dtrackpixelmovement.cc                        |   8 +-
 src/2dtransform.cc                                 |   8 +-
 src/2dtransformation-to-strain.cc                  |   7 +-
 src/3dbinarycombine.cc                             |  10 +-
 src/3dbrainextractT1.cc                            |   6 +-
 src/3dcombine-mr-segmentations.cc                  |   6 +-
 src/3dcost-translatedgrad.cc                       |  12 +-
 src/3dcost.cc                                      |   2 +-
 src/3dcrispsegment.cc                              |   6 +-
 src/3ddeform.cc                                    |   8 +-
 src/3ddistance-stats.cc                            | 225 +++++++
 src/3ddistance.cc                                  |  11 +-
 src/3deval-transformquantity.cc                    |   8 +-
 src/3dfield2norm.cc                                |   6 +-
 src/3dforce.cc                                     |   8 +-
 src/3dfuzzysegment.cc                              |  16 +-
 src/3dgetsize.cc                                   |   4 +-
 src/3dgetslice.cc                                  |   6 +-
 src/3dimageaddattributes.cc                        |   8 +-
 src/3dimagecombine.cc                              |  23 +-
 src/3dimagecreator.cc                              |   4 +-
 src/3dimagefilter.cc                               |   6 +-
 src/3dimagefilterstack.cc                          |  11 +-
 src/3dimageselect.cc                               |   6 +-
 src/3dimagestats.cc                                |   4 +-
 src/3dlandmarks-distances.cc                       |   6 +-
 src/3dlandmarks-transform.cc                       |   8 +-
 src/3dlerp.cc                                      |  11 +-
 src/3dmany2one-nonrigid.cc                         |  10 +-
 src/3dmaskseeded.cc                                |   6 +-
 src/3dmotioncompica-nonrigid.cc                    |  11 +-
 src/3dmulti-nrreg.cc                               |   4 +-
 src/3dnonrigidreg-alt.cc                           |   4 +-
 src/3dnonrigidreg.cc                               |  10 +-
 src/3dnrreg.cc                                     |  10 +-
 src/3dprealign-nonrigid.cc                         |  36 +-
 src/3drigidreg.cc                                  |  16 +-
 src/3dsegment-ahmed.cc                             |   6 +-
 src/3dserial-nonrigid.cc                           |   6 +-
 src/3dseries-track-intensity.cc                    |   4 +-
 src/3dtrackpixelmovement.cc                        |   8 +-
 src/3dtransform.cc                                 |  17 +-
 src/3dtransform2vf.cc                              |   6 +-
 src/3dvectorfieldcreate.cc                         |   4 +-
 src/3dvf2transform.cc                              |   6 +-
 src/3dvfcompare.cc                                 |   6 +-
 src/CMakeLists.txt                                 |   9 +-
 src/cmeans.cc                                      |  12 +-
 src/distance-mesh2mask.cc                          |   8 +-
 src/filenumberpattern.cc                           |   5 +-
 src/fluid2d/CMakeLists.txt                         |   2 +-
 src/fluid2d/NR2DMatrix.hh                          |   2 +-
 src/fluid2d/Pixel.hh                               |   2 +-
 src/fluid2d/elast.cc                               |   2 +-
 src/fluid2d/elast.hh                               |   2 +-
 src/fluid2d/helpers.cc                             |   2 +-
 src/fluid2d/helpers.hh                             |   2 +-
 src/fluid2d/main.cc                                |  14 +-
 src/fluid2d/types.hh                               |   2 +-
 src/fluid2d/vfluid.cc                              |   2 +-
 src/fluid2d/vfluid.hh                              |   2 +-
 src/fluid3d/CMakeLists.txt                         |   2 +-
 src/fluid3d/eqn_solver.cc                          |   2 +-
 src/fluid3d/eqn_solver.hh                          |   2 +-
 src/fluid3d/main.cc                                |  10 +-
 src/fluid3d/sor_solver.cc                          |   2 +-
 src/fluid3d/sor_solver.hh                          |   2 +-
 src/fluid3d/typedefs.hh                            |   2 +-
 src/fluid3d/vfluid.cc                              |   2 +-
 src/fluid3d/vfluid.hh                              |   2 +-
 src/isosurface/CMakeLists.txt                      |   2 +-
 src/isosurface/iso.cc                              |   6 +-
 src/isosurface/iso_backend.cc                      |   2 +-
 src/isosurface/iso_from_slices.cc                  |   6 +-
 src/isosurface/mesh_convert.cc                     |   2 +-
 src/labelsort.cc                                   |   6 +-
 src/meshdistance-to-stackmask.cc                   |   8 +-
 src/meshfilter.cc                                  |   6 +-
 src/multihist.cc                                   |   8 +-
 src/myowavelettest.cc                              |   7 +-
 src/plugin-help.cc                                 |   5 +-
 src/raw2image.cc                                   |   8 +-
 src/raw2volume.cc                                  |   8 +-
 src/test_plugins_as_installed.cc                   |  26 +-
 src/wavelettrans.cc                                |  12 +-
 test/CMakeLists.txt                                |   2 +-
 test/test_ioplugins.cc                             |   5 +-
 test/test_minimizer.cc                             |   7 +-
 testdata/CMakeLists.txt                            |   2 +-
 testhelpers/3d-mean-variance-test.ods              | Bin 0 -> 27091 bytes
 testhelpers/test_lncc.ods                          | Bin 0 -> 80113 bytes
 1435 files changed, 31238 insertions(+), 9526 deletions(-)

diff --git a/.gitignore b/.gitignore
index a60785a..3a1fc93 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,9 @@ GSYMS
 GTAGS
 build*
 
+.buildroot
+.\#*
+
+CMakeLists.txt.user
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5268763..6396709 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -40,10 +40,10 @@ include(CheckCXXSourceCompiles)
 SET(VENDOR "Gert Wollny")
 SET(PACKAGE_NAME "mia")
 SET(MAJOR_VERSION 2)
-SET(MINOR_VERSION 0)
-SET(MICRO_VERSION 13)
-SET(INTERFACE_AGE 5)
-SET(BINARY_AGE    5)
+SET(MINOR_VERSION 2)
+SET(MICRO_VERSION 0)
+SET(INTERFACE_AGE 0)
+SET(BINARY_AGE    0)
 
 SET(PACKAGE_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}")
 SET(VERSION "${MAJOR_VERSION}.${MINOR_VERSION}")
@@ -63,6 +63,7 @@ SET(LIBRARY_VERSION_INFO "${MIA_CURRENT}.${MIA_AGE}.${MIA_REVISION}")
 OPTION(STRICT_DEPENDECIES "require that all requested optinal dependencies are availabe" FALSE)
 OPTION(ALWAYS_CREATE_DOC "Create all documentation during the normal build process (normally you need to run 'make doc')" TRUE)
 OPTION(BUILD_EXAMPLES "Build example plug-ins and programs" FALSE)
+OPTION(ENABLE_DEBUG_MESSAGES "Enable debug and trace outputs" TRUE)
 
 INCLUDE(GNUInstallDirs)
 
@@ -74,7 +75,6 @@ INCLUDE (CheckTypeSize)
 
 include(CheckCXXCompilerFlag)
 
-MESSAGE("CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}")
 IF(UNIX)
   CHECK_CXX_COMPILER_FLAG("-std=c++11" HAS_GNU_CXX11_FLAG)
   IF(HAS_GNU_CXX11_FLAG)
@@ -93,6 +93,8 @@ ENDIF(UNIX)
 
 INCLUDE (${CMAKE_CURRENT_SOURCE_DIR}/cmake/checkCpp0xAuto.cmake)
 INCLUDE (${CMAKE_CURRENT_SOURCE_DIR}/cmake/checkCpp0xLambda.cmake)
+INCLUDE (${CMAKE_CURRENT_SOURCE_DIR}/cmake/checkSSEAttributeVectorCanUseSubscript.cmake)
+
 
 IF(NOT "${CXX_HAS_CXX_0X_AUTO}" OR NOT CXX_HAS_CXX_0X_LAMBDA)
   MESSAGE(FATAL_ERROR 
@@ -268,6 +270,11 @@ INCLUDE_DIRECTORIES(${GSL_INCLUDE_DIRS})
 LINK_DIRECTORIES(${GSL_LIBRARY_DIRS})
 
 
+PKG_CHECK_MODULES(EIGEN3 REQUIRED eigen3)
+INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS})
+LINK_DIRECTORIES(${EIGEN3_LIBRARY_DIRS})
+
+
 ################################################################################
 # 
 # search for some blas
@@ -447,12 +454,13 @@ ENDIF(PYTHONINTERP_FOUND)
 # 
 
 DEFINE_PLUGIN_NAMES( 1d  "spacialkernel;splinebc;splinekernel" ${PLUGIN_INSTALL_PATH})
-DEFINE_PLUGIN_NAMES( 2dimage  "combiner;cost;creator;filter;fullcost;io;model;shape;timestep;transform" ${PLUGIN_INSTALL_PATH})
+DEFINE_PLUGIN_NAMES( 2dimage  "combiner;cost;creator;filter;fullcost;io;maskedcost;model;shape;timestep;transform" ${PLUGIN_INSTALL_PATH})
+DEFINE_PLUGIN_NAMES( 2dmyocardsegset "io" ${PLUGIN_INSTALL_PATH})
 DEFINE_PLUGIN_NAMES( 2dsplinepenalty  "transform" ${PLUGIN_INSTALL_PATH})
 DEFINE_PLUGIN_NAMES( 2dstack  "filter" ${PLUGIN_INSTALL_PATH})
 DEFINE_PLUGIN_NAMES( 2dtransform  "io;splinepenalty" ${PLUGIN_INSTALL_PATH})
 DEFINE_PLUGIN_NAMES( 2dvf  "io" ${PLUGIN_INSTALL_PATH})
-DEFINE_PLUGIN_NAMES( 3dimage  "combiner;cost;creator;filter;fullcost;io;model;shape;timestep;transform" ${PLUGIN_INSTALL_PATH})
+DEFINE_PLUGIN_NAMES( 3dimage  "combiner;cost;creator;filter;fullcost;io;maskedcost;model;shape;timestep;transform" ${PLUGIN_INSTALL_PATH})
 DEFINE_PLUGIN_NAMES( 3dlandmarklist "io"  ${PLUGIN_INSTALL_PATH})
 DEFINE_PLUGIN_NAMES( 3dtransform  "io;splinepenalty" ${PLUGIN_INSTALL_PATH})
 DEFINE_PLUGIN_NAMES( 3dvf "io"  ${PLUGIN_INSTALL_PATH})
diff --git a/ChangeLog b/ChangeLog
index dc4f3d7..3093872 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,79 @@
+2.2.0
+
+  New features: 
+  
+  * Major ABI changes 
+  * Add support for HDF5 and NIFTI1 IO 
+  * Support for masked cost functions in voxel based image registration 
+  * Use Eigen3 for  the 3D matrix eigenvalue/eigenvector evaluation
+  * More C++11, minimal requirement is now g++ >= 4.7 
+  * Keep track of orientations 
+  * Add perfusion motion eompensation programs that are specifically designed to use a global 
+    reference even if the algorithm doesn't dictate this 
+  * automatically set C++11 compiler flag by cmake 
+
+  Fixes for tracked issues:
+
+ * #4 add 2D/3D filters that actually run a combiner, 
+ * #12 add basic support for loading and stroring nifti 
+ * #14 load and store ImageOrientationPatient and ImagePositionPatient related
+ * #19 Add positional information to C3DTransform::const_iterator
+ * #49 Parallize the 3D scale filter
+ * #57 Add parameter type that can take a vector of coma separated values.
+ * #76 Remove the old divcurl penalty interface in 2D Closes
+ * #90 Add voxel/pixel size attribute to vector field
+ * #100 Make the 3D image combiner similar to the 2D combiner
+ * #108 
+ * #117 Add support to query minimal image size for transformations
+ * #123 Correct handling of ica instance when RV/LV classification fails in all cases,
+ * #124 Add attribute to indicate the pixel size is from the imager 
+ * #125 Make slicelocation and slicespacing non-obligatory
+ * #126 Correct plug-in file suffix mapping for 2D and 3D images.
+ * #127 Correct documentation and output to refer to 2D data.
+ * #128 Add program to convert multi-record 2D image to 3D image
+
+ * #129 Move plug-ins that are configurable to the addons source tree
+ * #132 add 2D normalized local cross correaltion, see
+ * #135 Read from created file name instead of in_filename.
+ * #136 Add a normalization parameter to the spline penalty,
+ * #138 Handle compressed file extension properly when selecting the IO plugin.
+ * #139 Do not throw when opening the HDF5 file fails
+ * #140 add property flag for IO piping
+ * #141 Add attribute IO to the available 2d/3d transform IO backends
+ * #143 Fix zero boundary condition handling
+ * #144 Parallelize the prefiltering in the 3D interpolator
+ * #145 make sure the interpolator output range always includes zero
+
+ * #147 Add function to override interpolator once. 
+ * #152 add 3 label-voting downscale filter
+ * #153 Add traits for the range iterators
+ * #156 add additional flags to to the XML document creation CStringParameter, 
+ * #157 split range iterator in version with and without boundary flags.
+ * #158 Consistently implement the lncc metric for masked and unmasked images
+ * #159 Add option to chain filters into one entity.
+ * #160 Add a new gradient descent implementation with some step adjustment
+
+ Additional fixes:
+
+  * make all source files lowercase
+  * correct compilation with visibility=hidden 
+  * handles signed and unsigned pixel values in DICOM 
+  * let the xml-help write to a file instead of stdout 
+  * Correct default suffix for 2D transforms.
+  * add attributes to boost::serialization transform IO
+  * Add the _1 quaternion that corresponds to no rotation
+  * Add printing of CAttributedData for testing
+  * Add an affine matrix with OpenGL like layout 
+  * add a program to evaluate the pixel wise maximum intensity of  number of images
+  * add support for setting the minimum number of digits in the output file names.
+  * Add SSD cost function with automasking baswed on intensity thresholds.
+  * Add xz to the possible compressors/decompressors that can be invoked on the fly.
+  * Add a 3D distance transform filter
+  * add label distance evaluation program
+  * add a min-frequency parameter to the classifier in the ICA perfusion analysis
+  * update to use supprt VTK >= 6.0 
+  * add photometric interpretation and correct acquisition time saving in DICOM 
+   	
 2.0.13
 
   Fixes for tracked bugs:
@@ -6,11 +82,11 @@
   * #143 Fix zero-fill boundary condition handling
   * #144 Parallelize the prefiltering in the 3D interpolator
 
-  Additional fixes:
+
 
   * 2dimageregistration: Exit if no cost functions are given
   * 3dgetimage: add support for setting the minimum number of
-	        digits in the output file names.
+                digits in the output file names.
   * factoryplugins: throw error if a factory plugin is not found
   * make the basic interpolator operator in 3D thread save
 
diff --git a/addons/CMakeLists.txt b/addons/CMakeLists.txt
index 0ca878b..e012ccb 100644
--- a/addons/CMakeLists.txt
+++ b/addons/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,11 +18,13 @@
 
 INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}")
 
-ADD_SUBDIRECTORY(dicom   )
-ADD_SUBDIRECTORY(jpg )
-ADD_SUBDIRECTORY(openexr )
-ADD_SUBDIRECTORY(nlopt )
-ADD_SUBDIRECTORY(png )
-ADD_SUBDIRECTORY(tiff )
-ADD_SUBDIRECTORY(vtk   )
-ADD_SUBDIRECTORY(vistaio )
+ADD_SUBDIRECTORY( dicom )
+ADD_SUBDIRECTORY( jpg )
+ADD_SUBDIRECTORY( hdf5 )
+ADD_SUBDIRECTORY( openexr )
+ADD_SUBDIRECTORY( nifti )
+ADD_SUBDIRECTORY( nlopt )
+ADD_SUBDIRECTORY( png )
+ADD_SUBDIRECTORY( tiff )
+ADD_SUBDIRECTORY( vtk   )
+ADD_SUBDIRECTORY( vistaio )
diff --git a/addons/dicom/CMakeLists.txt b/addons/dicom/CMakeLists.txt
index 1e591ff..3ad10a8 100644
--- a/addons/dicom/CMakeLists.txt
+++ b/addons/dicom/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/addons/dicom/dcm2d.cc b/addons/dicom/dcm2d.cc
index b52c516..0743de9 100644
--- a/addons/dicom/dcm2d.cc
+++ b/addons/dicom/dcm2d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,8 +38,10 @@ CDicom2DImageIOPlugin::CDicom2DImageIOPlugin():
 	C2DImageIOPlugin("dicom")
 {
 	add_supported_type(it_ushort);
+	add_supported_type(it_sshort);
 
 	TTranslator<float>::register_for("SliceLocation");
+	TTranslator<double>::register_for("AcquisitionTime"); 
 	TTranslator<int>::register_for("SeriesNumber");
 	TTranslator<int>::register_for("AcquisitionNumber");
 	TTranslator<int>::register_for("InstanceNumber");
@@ -81,7 +83,7 @@ const string CDicom2DImageIOPlugin::do_get_descr() const
 	return "2D image io for DICOM";
 }
 
-std::string CDicom2DImageIOPlugin::do_get_preferred_suffix() const
+const std::string CDicom2DImageIOPlugin::do_get_preferred_suffix() const
 {
 	return "dcm"; 
 }
diff --git a/addons/dicom/dcm2d.hh b/addons/dicom/dcm2d.hh
index 43302bd..b7264e4 100644
--- a/addons/dicom/dcm2d.hh
+++ b/addons/dicom/dcm2d.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@ private:
 	PData do_load(const std::string& fname) const;
 	bool do_save(const std::string& fname, const Data& data) const;
 	const std::string do_get_descr() const;
-	std::string do_get_preferred_suffix() const; 
+	const std::string do_get_preferred_suffix() const; 
 };
 
 NS_END
diff --git a/addons/dicom/dcm3d.cc b/addons/dicom/dcm3d.cc
index 784a706..1ecba2a 100644
--- a/addons/dicom/dcm3d.cc
+++ b/addons/dicom/dcm3d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -47,8 +47,10 @@ CDicom3DImageIOPlugin::CDicom3DImageIOPlugin():
 	C3DImageIOPlugin("dicom")
 {
 	add_supported_type(it_ushort);
+	add_supported_type(it_sshort);
 
 	TTranslator<float>::register_for("SliceLocation");
+	TTranslator<double>::register_for("AcquisitionTime"); 
 	TTranslator<int>::register_for("SeriesNumber");
 	TTranslator<int>::register_for("AcquisitionNumber");
 	TTranslator<int>::register_for("InstanceNumber");
@@ -164,7 +166,7 @@ static P3DImage get_3dimage(CImageInstances& slices)
 	return creator.get_image();
 }
 
-std::string CDicom3DImageIOPlugin::do_get_preferred_suffix() const
+const std::string CDicom3DImageIOPlugin::do_get_preferred_suffix() const
 {
 	return "dcm"; 
 }
@@ -316,10 +318,18 @@ bool CSliceSaver::operator () ( const T3DImage<T>& image) const
 
 	C3DFVector voxel = image.get_voxel_size();
 	C2DFVector pixel(voxel.x, voxel.y);
-
-
+	
+	auto origin = image.get_origin();
+	auto rotation = image.get_rotation();
+	
 	T2DImage<T> slice = image.get_data_plane_xy(m_slice);
+	slice.set_attributes(image.begin_attributes(), image.end_attributes()); 
 	slice.set_pixel_size(pixel);
+	slice.set_attribute("rotation3d", PAttribute(new C3DRotationAttribute(rotation)));
+
+	
+	C3DFVector new_origin = C3DFVector(rotation.as_matrix_3x3() * C3DDVector(0,0,m_slice)) + origin;
+	slice.set_attribute("origin3d", PAttribute(new CVoxelAttribute(new_origin))); 
 
 	slice.set_attribute(IDInstanceNumber, PAttribute(new CIntAttribute(m_slice + 1)));
 	slice.set_attribute(IDSliceLocation,  PAttribute(new CFloatAttribute(m_location)));
@@ -328,8 +338,8 @@ bool CSliceSaver::operator () ( const T3DImage<T>& image) const
 	if (!slice.has_attribute(IDSeriesNumber))
 		slice.set_attribute(IDSeriesNumber, PAttribute(new CIntAttribute(m_series + 1)));
 
-	CDicomWriter weiter(slice);
-	return weiter.write(fname.str().c_str());
+	CDicomWriter writer(slice);
+	return writer.write(fname.str().c_str());
 }
 
 bool CDicom3DImageIOPlugin::do_save(const string& fname, const Data& data) const
diff --git a/addons/dicom/dcm3d.hh b/addons/dicom/dcm3d.hh
index caf4875..d0d0ef0 100644
--- a/addons/dicom/dcm3d.hh
+++ b/addons/dicom/dcm3d.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@ private:
 	PData do_load(const std::string& fname) const;
 	bool do_save(const std::string& fname, const Data& data) const;
 	const std::string do_get_descr() const;
-	std::string do_get_preferred_suffix() const; 
+	const std::string do_get_preferred_suffix() const; 
 };
 
 NS_END
diff --git a/addons/dicom/dicom4mia.cc b/addons/dicom/dicom4mia.cc
index aeee4bd..19c5f0c 100644
--- a/addons/dicom/dicom4mia.cc
+++ b/addons/dicom/dicom4mia.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,9 +18,17 @@
  *
  */
 
+#define VSTREAM_DOMAIN "DCMTK4MIA"
+
 #include <mia/core/errormacro.hh>
 #include <map>
 #include <algorithm>
+#include <cassert>
+#include <iomanip>
+
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
 
 #include <dicom/dicom4mia.hh>
 
@@ -70,12 +78,25 @@ const SLookupInit lookup_init[] = {
 	{IDStudyID, DCM_StudyID, false, tr_no, NULL},
 	{IDImageType, DCM_ImageType, false, tr_no, NULL},
 	{IDSliceLocation, DCM_SliceLocation, false, tr_no, NULL},
+	{IDSliceThickness, DCM_SliceThickness, false, tr_no, NULL},
 	{IDPatientOrientation, DCM_PatientOrientation, false, tr_no, NULL},
 	{IDMediaStorageSOPClassUID, DCM_MediaStorageSOPClassUID, true, tr_no, NULL},
 	{IDSOPClassUID, DCM_SOPClassUID, false, tr_no, NULL},
 	{IDProtocolName, DCM_ProtocolName, false, tr_no, NULL},
 	{IDTestValue, DcmTagKey(), false, tr_no, NULL},
 	{IDPatientPosition, DCM_PatientPosition, false, tr_no, NULL}, 
+//	{IDAcquisitionTime, DCM_AcquisitionTime, false, tr_no, NULL}, 
+
+	{IDPositionerPrimaryAngle, DCM_PositionerPrimaryAngle, false, tr_no, NULL}, 
+	{IDPositionerSecondaryAngle, DCM_PositionerSecondaryAngle, false, tr_no, NULL}, 
+	{IDImagerPixelSpacing, DCM_ImagerPixelSpacing, false, tr_no, NULL},
+	{IDDistanceSourceToDetector, DCM_DistanceSourceToDetector, false, tr_no, NULL},
+	{IDDistanceSourceToPatient, DCM_DistanceSourceToPatient, false, tr_no, NULL},
+	{IDPixelIntensityRelationship, DCM_PixelIntensityRelationship, false, tr_no, NULL},
+	{IDPositionerPrimaryAngleIncrement, DCM_PositionerPrimaryAngleIncrement, false, tr_no, NULL},
+	{IDPositionerSecondaryAngleIncrement, DCM_PositionerSecondaryAngleIncrement, false, tr_no, NULL},
+	{IDPhotometricInterpretation, DCM_PhotometricInterpretation, false, tr_yes_defaulted, "MONOCHROME2"},
+	
 	{NULL, DcmTagKey(), false, tr_no, NULL}
 };
 
@@ -107,7 +128,8 @@ struct CDicomReaderData {
 	Sint32 getSint32(const DcmTagKey &tagKey, bool required, Sint32 default_value = 0);
 	float getFloat32(const DcmTagKey &tagKey, bool required, float default_value = 0);
 	float getFloat64(const DcmTagKey &tagKey, bool required, double default_value = 0);
-
+	bool getFloat64ArrayFromString(const DcmTagKey &tagKey, vector<double>& values, const string& msg);
+	
 	string getAttribute(const string& key, bool required, const char *default_value = "");
 	string getAttribute(const DcmTagKey &tagKey, bool required, const char *default_value = "");
 
@@ -119,11 +141,14 @@ struct CDicomReaderData {
 	template <typename I>
 	void getPixelData_LittleEndianExplicitTransfer(I out_begin, size_t size);
 
+	void getAcquisitionTimeIfAvailable(CAttributedData& image); 
 
 	C2DFVector getPixelSize();
 
 	C2DFVector getImagePixelSpacing(); 
-
+	
+	C3DDMatrix getImageOrientationPatient(); 
+	C3DFVector getImagePositionPatient(); 
 
 };
 
@@ -216,10 +241,18 @@ P2DImage CDicomReader::load_image()const
 
 	// get pixel data
 	impl->getPixelData(result->begin(), result->size());
+	impl->getAcquisitionTimeIfAvailable(*result); 
+	
+	auto psize = get_pixel_size(); 
+	if (psize.x < 0) {
+		psize.x = -psize.x; 
+		result->set_attribute(IDAttrPixelSizeIsImager, PAttribute(new TAttribute<int>(1)));
+	}
 
-	result->set_pixel_size(get_pixel_size());
-
-
+	result->set_pixel_size(psize);
+	result->set_attribute("rotation3d", PAttribute(new C3DRotationAttribute(this->impl->getImageOrientationPatient()))); 
+	result->set_attribute("origin3d", PAttribute(new CVoxelAttribute(this->impl->getImagePositionPatient())));
+	
 	const SLookupInit *attr_table = lookup_init;
 	while (attr_table->skey) {
 		// copy some attributes
@@ -247,8 +280,16 @@ P3DImage CDicomReader::load_image3d()const
 	// get pixel data
 	impl->getPixelData(result->begin(), result->size());
 
-	result->set_voxel_size(this->get_voxel_size(true));
 
+	auto vsize = this->get_voxel_size(true); 
+	if (vsize.x < 0) {
+		vsize.x = -vsize.x; 
+		result->set_attribute(IDAttrPixelSizeIsImager, PAttribute(new TAttribute<int>(1)));
+	}
+	result->set_voxel_size(vsize);
+
+	result->set_rotation(this->impl->getImageOrientationPatient()); 
+	result->set_origin(this->impl->getImagePositionPatient()); 
 
 	const SLookupInit *attr_table = lookup_init;
 	while (attr_table->skey) {
@@ -278,10 +319,13 @@ P2DImage CDicomReader::get_image() const
 
 
 	if (bbpa == 16) {
-		if (pixel_signed) 
+		if (pixel_signed) {
+			cvdebug() << "Load signed short\n"; 
 			return load_image<signed short>();
-		else
+		} else {
+			cvdebug() << "Load unsigned short\n"; 
 			return load_image<unsigned short>();
+		}
 	}
 
 	throw create_exception<invalid_argument>( "CDicomReader: '", m_filename, 
@@ -377,6 +421,29 @@ float CDicomReaderData::getFloat32(const DcmTagKey &tagKey, bool required, float
 	return value;
 }
 
+void CDicomReaderData::getAcquisitionTimeIfAvailable(CAttributedData& image)
+{
+	DcmElement *element; 
+	OFCondition success = dcm.getDataset()->findAndGetElement(DCM_AcquisitionTime, element); 
+	
+	if (!success.good()) 
+		return; 
+
+	DcmTime *dcm_time  = dynamic_cast<DcmTime *>(element); 
+	if (!dcm_time) {
+		cverr() << "CDicomReader: Element with tag "<<IDAcquisitionTime<< " not a DcmTime as expected\n"; 
+		return; 
+	}
+	
+	OFTime of_time; 
+	success = dcm_time->getOFTime(of_time); 
+	if (!success.good()) {
+		cverr() << "CDicomReader: Could not retrive OFTime string from DcmTime Element\n";
+		return; 
+	}
+	image.set_attribute(IDAcquisitionTime, of_time.getTimeInSeconds()); 
+}						
+
 float CDicomReaderData::getFloat64(const DcmTagKey &tagKey, bool required, double default_value)
 {
 	Float64 value = default_value;
@@ -389,6 +456,62 @@ float CDicomReaderData::getFloat64(const DcmTagKey &tagKey, bool required, doubl
 	return value;
 }
 
+bool CDicomReaderData::getFloat64ArrayFromString(const DcmTagKey &tagKey, vector<double>& values, const string& msg)
+{
+	if (!dcm.getDataset()->tagExistsWithValue(tagKey)) {
+		cvinfo() << msg << " tag empty or not available.\n"; 
+		return false; 
+	}
+	OFString help;
+	OFCondition success = dcm.getDataset()->findAndGetOFStringArray(tagKey, help);	
+	if (success.bad()) {
+		cvinfo() << msg << " available but is not a string.\n";
+		return false; 
+	}
+
+        vector<string> tockens; 
+	string svalues(help.begin(), help.end()); 
+        boost::split(tockens, svalues ,boost::is_any_of("\\"));
+
+	if (tockens.size() != values.size()) {
+		cvwarn() << "Bogus " << msg << " attribute of " << tockens.size() 
+			 << " elements (expect "<< values.size() << ")."; 
+		return false; 
+	}
+	for (unsigned i = 0; i < tockens.size(); ++i) {
+		istringstream iss(tockens[i]); 
+                iss >> values[i]; 
+                if (iss.bad()) {
+                        cvwarn() << "unable to read double value from '" << tockens[i] << "'\n"; 
+			return false;
+		}
+        }
+	return true; 
+
+}
+
+C3DDMatrix CDicomReaderData::getImageOrientationPatient()
+{
+	vector<double> v(6); 
+	
+	if (!getFloat64ArrayFromString(DCM_ImageOrientationPatient, v, "ImageOrientationPatient")) 
+		return C3DDMatrix::_1; 
+	
+	
+	const C3DDVector cx(v[0], v[1], v[2]); 
+	const C3DDVector cy(v[3], v[4], v[5]); 
+	const C3DDVector cz = cross(cx,cy); 
+	
+	return C3DDMatrix(cx, cy, cz); 
+}
+
+C3DFVector CDicomReaderData::getImagePositionPatient()
+{
+	vector<double> v(3); 
+	if (!getFloat64ArrayFromString(DCM_ImagePositionPatient, v, "ImagePositionPatient")) 
+		return C3DFVector::_0; 
+	return C3DFVector(v[0], v[1], v[2]); 
+}
 
 string CDicomReaderData::getAttribute(const DcmTagKey &tagKey, bool required, const char *default_value)
 {
@@ -424,13 +547,13 @@ string CDicomReaderData::getAttribute(const string& key, bool required, const ch
 void CDicomReaderData::add_attribute(CAttributedData& image, const char *key, ETagRequirement  required, const char *default_value)
 {
 	string value = getAttribute(key, required == tr_yes);
-	if (!value.empty())
+	if (!value.empty()) {
 		image.set_attribute(key, value);
+	}
 	else if (required == tr_yes_defaulted) 
 		image.set_attribute(key, string(default_value));
 }
 
-
 template <typename I>
 void CDicomReaderData::getPixelData_LittleEndianExplicitTransfer(I out_begin, size_t size)
 {
@@ -438,18 +561,17 @@ void CDicomReaderData::getPixelData_LittleEndianExplicitTransfer(I out_begin, si
 	if (status.bad()) {
 		throw create_exception<runtime_error>( "DICOM: error loading pixel data:", status.text());
 	}
-
 	const Uint16 *values;
 	long unsigned int count;
 	OFCondition cnd = dcm.getDataset()->findAndGetUint16Array(DCM_PixelData, values, &count, false);
 	if (cnd.good()) {
 		if (size != count) {
 			throw create_exception<runtime_error>( "bogus file, expect ", size, " pixels, ", 
-						     "but got data for ", count, " pixels");
+							       "but got data for ", count, " pixels");
 		}
 		copy(values, values+count, out_begin);
 	}else {
-		throw create_exception<runtime_error>( "DICOM: required value PixelData:", status.text());
+		throw create_exception<runtime_error>( "DICOM: required value PixelData:", cnd.text());
 	}
 }
 
@@ -470,12 +592,43 @@ void CDicomReaderData::getPixelData(I out_begin, size_t size)
 	getPixelData_LittleEndianExplicitTransfer(out_begin, size);
 }
 
+C2DFVector CDicomReaderData::getImagePixelSpacing()
+{
+	OFString help;
+	OFCondition success = dcm.getDataset()->findAndGetOFString(DCM_ImagerPixelSpacing, help, 0);
+	if (success.bad()) {
+		throw create_exception<runtime_error>( "Neither 'PixelSpacing' nor 'ImagerPixelSpacing' found!"
+						       " As a workaround to can add either of them by using 'dcmodify'");
+	}
+	C2DFVector result;
+
+	istringstream swidth(help.data());
+	swidth >> result.x;
+
+	success = dcm.getDataset()->findAndGetOFString(DCM_ImagerPixelSpacing, help, 1);
+	if (success.bad()) {
+		throw create_exception<runtime_error>( "Second value in 'ImagerPixelSpacing' not found!"
+						       " As a workaround to can add either of them by using 'dcmodify'");
+	}
+	istringstream sheight(help.data());
+	sheight >> result.y;
+
+	cvinfo() << "The image contained no 'PixelSpacing' tag, only 'ImagerPixelSpacing' that corresponds to the " 
+		 << "detector pixel spacing. If you can not assume that the rays are parallel, then your object "
+		 << "pixel spacing might have to be scaled."; 
+
+	// indicate that this is not physical pixel size but imager pixel size 
+	result.x = -result.x; 
+	return result;
+	
+}
+
 C2DFVector CDicomReaderData::getPixelSize()
 {
 	OFString help;
 	OFCondition success = dcm.getDataset()->findAndGetOFString(DCM_PixelSpacing, help, 0);
 	if (success.bad()) {
-		throw create_exception<runtime_error>( "Required attribute 'PixelSpacing' not found");
+		return getImagePixelSpacing(); 
 	}
 	C2DFVector result;
 
@@ -501,7 +654,9 @@ private:
 	void setValueString(const string& key, const string& value);
 	void setValueString(const DcmTagKey& key, const string& value, bool meta);
 	void setSize(const C2DBounds& size);
-	void setPixelSpacing(const C2DFVector& value);
+	void setPixelSpacing(const DcmTagKey& key, const C2DFVector& value);
+	void setAcquisitionTime(double time_seconds); 
+	void setFloatArrayAsString(const DcmTagKey& key, const vector<double>& values); 
 	void setValueStringIfKeyExists(const CAttributeMap::value_type& value);
 	friend struct CDicomImageSaver;
 };
@@ -526,6 +681,7 @@ template <typename T>
 struct pixel_trait {
 	enum { AllocSize = 8 * sizeof(T)};
 	enum { UseSize = 8 * sizeof(T)};
+	enum { PixelRepn = 0};
 	enum { supported = 0 };
 	static void copy_pixel_data(DcmDataset& /*dataset*/, const T2DImage<T>& /*image*/) {
 		assert(!"There is no code here");
@@ -536,12 +692,27 @@ template <>
 struct pixel_trait<unsigned short> {
 	enum { AllocSize = 16};
 	enum { UseSize = 16};
+	enum { PixelRepn = 0};
 	enum { supported = 1};
 	static void copy_pixel_data(DcmDataset& dataset, const C2DUSImage& image) {
 		dataset.putAndInsertUint16Array(DCM_PixelData, (const Uint16*)&image(0,0), image.size());
 	}
 };
 
+template <>
+struct pixel_trait<signed short> {
+	enum { AllocSize = 16};
+	enum { UseSize = 16};
+	enum { PixelRepn = 1};
+	enum { supported = 1};
+	static void copy_pixel_data(DcmDataset& dataset, const C2DSSImage& image) {
+		OFCondition cnd = dataset.putAndInsertUint16Array(DCM_PixelData, (const Uint16*)&image(0,0), image.size());
+		if (!cnd.good()) {
+			throw create_exception<runtime_error>( "DICOM: unable to set signed short array to PixelData:", cnd.text());
+		}
+	}
+};
+
 template <typename T>
 CDicomImageSaver::result_type CDicomImageSaver::operator ()(const T2DImage<T>& image)const
 {
@@ -550,7 +721,9 @@ CDicomImageSaver::result_type CDicomImageSaver::operator ()(const T2DImage<T>& i
 
 	parent->setValueUint16(DCM_BitsAllocated, pixel_trait<T>::AllocSize);
 	parent->setValueUint16(DCM_BitsStored, pixel_trait<T>::UseSize);
-
+	parent->setValueUint16(DCM_HighBit, pixel_trait<T>::UseSize - 1);
+	parent->setValueUint16(DCM_PixelRepresentation, pixel_trait<T>::PixelRepn);
+	
 	auto  minmax = minmax_element(image.begin(), image.end());
 
 
@@ -561,14 +734,81 @@ CDicomImageSaver::result_type CDicomImageSaver::operator ()(const T2DImage<T>& i
 	return true;
 }
 
+void CDicomWriterData::setFloatArrayAsString(const DcmTagKey& key, const vector<double>& values)
+{
+	
+	if (values.empty()) {
+		cvwarn() << "Try to set " << key << " from empty array\n"; 
+		return; 
+	}
+
+	ostringstream value_str; 
+	value_str << setprecision(8)<< values[0]; 
+	for (unsigned i = 1; i < values.size(); ++i) 
+		value_str << '\\' << setprecision(8)<< values[i];
+	
+	setValueString(key, value_str.str(), false); 
+}
+
 CDicomWriterData::CDicomWriterData(const C2DImage& image)
 {
 	setValueUint16(DCM_SamplesPerPixel, 1);
 	setSize(image.get_size());
-	setPixelSpacing(image.get_pixel_size());
+	
+	setPixelSpacing(image.has_attribute(IDAttrPixelSizeIsImager) ? 
+			DCM_ImagerPixelSpacing : DCM_PixelSpacing, 
+			image.get_pixel_size());
+	
+	// special treatment for the acquistion time
+	if (image.has_attribute(IDAcquisitionTime)) {
+		const double time = image.get_attribute_as<double>(IDAcquisitionTime); 
+		cvdebug() << "CDicomWriterData: save" << IDAcquisitionTime << ": " << setw(10) << setprecision(20) << time << "s\n"; 
+		setAcquisitionTime(time); 
+	}
 
-	for(auto i = image.begin_attributes(); i != image.end_attributes(); ++i)
+	for(auto i = image.begin_attributes(); i != image.end_attributes(); ++i) {
 		setValueStringIfKeyExists(*i);
+	}
+
+	auto rot = C3DDMatrix::_1; 
+	// set position and orientation 
+	auto prot_attr = image.get_attribute("rotation3d"); 
+	if (prot_attr) {
+		auto prot_attr_pointer = dynamic_cast<const C3DRotationAttribute*>(prot_attr.get()); 
+		if (prot_attr_pointer) {
+			C3DRotation rot_attr = *prot_attr_pointer; 
+			rot = rot_attr.as_matrix_3x3();
+		}else{
+			cvwarn() << "image has a 'rotation3d' attribute, but not of type C3DRotationAttribute, ignoring\n"; 
+		}
+	}else{
+		cvdebug()  << "image has no 'rotation3d' attribute, default to unity matrix\n"; 
+	}
+	
+	const vector<double> ovalues{rot.x.x, rot.x.y, rot.x.z, rot.y.x, rot.y.y, rot.y.z}; 
+	setFloatArrayAsString(DCM_ImageOrientationPatient, ovalues); 
+	
+	C3DFVector pos = C3DFVector::_0; 
+
+	auto porigin_attr = image.get_attribute("origin3d");
+	if (porigin_attr) {
+		auto porigin_attr_pointer = dynamic_cast<const CVoxelAttribute*>(porigin_attr.get()); 
+		if (porigin_attr_pointer) {
+			pos = *porigin_attr_pointer; 
+		} else {
+			cvwarn() << "image has a 'origin3d' attribute of value '"
+				 << porigin_attr->as_string() 
+				 <<"', not of type CVoxelAttribute ("
+				 << typeid(CVoxelAttribute).name() << ") but "
+				 << typeid(*porigin_attr).name() 
+				 <<" , ignoring\n"; 
+		}
+	}else {
+		cvdebug()  << "image has no 'origin3d' attribute, default to (0,0,0)\n"; 
+	}
+	
+	const vector<double>  pvalues{pos.x, pos.y, pos.z}; 
+	setFloatArrayAsString(DCM_ImagePositionPatient, pvalues); 
 
 	if (!image.has_attribute(IDMediaStorageSOPClassUID))
 		setValueString(IDMediaStorageSOPClassUID, "1.2.840.10008.5.1.4.1.1.4");
@@ -606,13 +846,33 @@ void CDicomWriterData::setSize(const C2DBounds& size)
 	setValueUint16(DCM_Columns, size.x);
 }
 
-void CDicomWriterData::setPixelSpacing(const C2DFVector& value)
+void CDicomWriterData::setPixelSpacing(const DcmTagKey& key, const C2DFVector& value)
 {
 	stringstream pixelspacing;
 	pixelspacing << value.x << "\\" << value.y;
-	setValueString(DCM_PixelSpacing, pixelspacing.str(), false);
+	setValueString(key, pixelspacing.str(), false);
 }
 
+void CDicomWriterData::setAcquisitionTime(double time_seconds)
+{
+	
+	OFTime of_time; 
+	of_time.setTimeInSeconds(time_seconds); 
+
+	DcmTime *dcm_time = new DcmTime(DCM_AcquisitionTime); 	
+	
+	OFString dicomTime; 
+	OFCondition status = DcmTime::getDicomTimeFromOFTime(of_time, dicomTime, OFTrue, OFTrue); 
+	if (!status.good() ) {
+		cvwarn() << "CDicomWriter: error setting acquisition time: " << status.text() << "\n"; 
+		return ;
+	}
+	// well, that is stupid, but DcmTime doesn't support to set the fraction flag in SetOFTime
+	dcm_time->putString (dicomTime.c_str()); 
+	dcm.getDataset()->insert(dcm_time, OFTrue); 
+}
+
+
 void CDicomWriterData::setValueStringIfKeyExists(const CAttributeMap::value_type& value)
 {
 	if (LookupMap::instance().has_key(value.first))
@@ -684,14 +944,4 @@ CDicomReader EXPORT_DICOM ugly_trick_writer_dcm_to_reader_dcm(CDicomWriter& writ
 	return CDicomReader(new CDicomReaderData(writer.impl->dcm));
 }
 
-EXPORT_DICOM const char * IDMediaStorageSOPClassUID= "MediaStorageSOPClassUID";
-EXPORT_DICOM const char * IDStudyDescription = "StudyDescription";
-EXPORT_DICOM const char * IDSamplesPerPixel = "IDSamplesPerPixel";
-EXPORT_DICOM const char * IDSeriesDescription = "SeriesDescription";
-
-EXPORT_DICOM const char * IDTestValue = "TestValue";
-EXPORT_DICOM const char * IDTransferSyntaxUID = "TransferSyntaxUID";
-EXPORT_DICOM const char * IDSOPClassUID = "SOPClassUID";
-
-
 NS_MIA_END
diff --git a/addons/dicom/dicom4mia.hh b/addons/dicom/dicom4mia.hh
index 3aeae60..4ff491b 100644
--- a/addons/dicom/dicom4mia.hh
+++ b/addons/dicom/dicom4mia.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
 #define dicom4mia_hh
 
 #include <mia/core/attributes.hh>
+#include <mia/core/attribute_names.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/2d/image.hh>
 #include <mia/3d/image.hh>
@@ -34,14 +35,6 @@
 
 NS_MIA_BEGIN
 
-extern EXPORT_DICOM const char * IDMediaStorageSOPClassUID;
-extern EXPORT_DICOM const char * IDStudyDescription;
-extern EXPORT_DICOM const char * IDSeriesDescription;
-extern EXPORT_DICOM const char * IDSamplesPerPixel;
-extern EXPORT_DICOM const char * IDTestValue;
-extern EXPORT_DICOM const char * IDSOPClassUID;
-
-
 class EXPORT_DICOM CDicomReader {
 public:
 	CDicomReader(const char *filename);
diff --git a/addons/dicom/getset.hh b/addons/dicom/getset.hh
index c423f9d..742b6eb 100644
--- a/addons/dicom/getset.hh
+++ b/addons/dicom/getset.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/dicom/test_dcm2d.cc b/addons/dicom/test_dcm2d.cc
index 68db031..3f908f0 100644
--- a/addons/dicom/test_dcm2d.cc
+++ b/addons/dicom/test_dcm2d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -120,17 +120,20 @@ BOOST_FIXTURE_TEST_CASE( test_dicom_load, DicomLoaderFixture )
 	BOOST_CHECK_EQUAL(image(128,114), 135);
 }
 
+
+template  <typename T> 
 struct DicomSaveLoadFixture {
 	DicomSaveLoadFixture();
 	CDicom2DImageIOPlugin plugin;
 protected:
 	void fill_attributes();
 	C2DBounds size;
-	C2DUSImage *org_image;
+	T2DImage<T> *org_image;
 	P2DImage porg_image;
 };
 
-void DicomSaveLoadFixture::fill_attributes()
+template  <typename T> 
+void DicomSaveLoadFixture<T>::fill_attributes()
 {
 	org_image->set_attribute(IDMediaStorageSOPClassUID,  "somevalue");
 	org_image->set_attribute(IDSOPClassUID,  "othervalue");
@@ -154,28 +157,54 @@ void DicomSaveLoadFixture::fill_attributes()
 
 }
 
-DicomSaveLoadFixture::DicomSaveLoadFixture():
+template  <typename T> 
+DicomSaveLoadFixture<T>::DicomSaveLoadFixture():
 	size(10,12)
 {
-	org_image = new C2DUSImage(size);
+	org_image = new T2DImage<T>(size);
 	short k = 0;
-	for (C2DUSImage::iterator i = org_image->begin(); i != org_image->end(); ++i, ++k)
+	for (auto i = org_image->begin(); i != org_image->end(); ++i, ++k)
 		*i = k;
 
 	porg_image.reset(org_image);
 }
 
 
-BOOST_FIXTURE_TEST_CASE( test_dicom_save_load, DicomSaveLoadFixture )
+BOOST_FIXTURE_TEST_CASE( test_dicom_ss_save_load, DicomSaveLoadFixture<signed short> )
+{
+
+	fill_attributes();
+
+	CDicom2DImageIOPlugin::Data imagelist;
+	imagelist.push_back(porg_image);
+	BOOST_REQUIRE(plugin.save("testsave-ss.dcm", imagelist));
+
+	CDicom2DImageIOPlugin::PData images = plugin.load("testsave-ss.dcm");
+	BOOST_REQUIRE(images);
+	BOOST_REQUIRE(images->size() == 1);
+	P2DImage pimage = *images->begin();
+	BOOST_REQUIRE(pimage);
+
+	BOOST_CHECK(*pimage ==  *org_image);
+
+	const C2DSSImage& load_image = dynamic_cast<const C2DSSImage&>(*pimage);
+
+	BOOST_CHECK_EQUAL(load_image.get_size(), size);
+
+	BOOST_CHECK(equal(load_image.begin(), load_image.end(), org_image->begin()));
+
+}
+
+BOOST_FIXTURE_TEST_CASE( test_dicom_us_save_load, DicomSaveLoadFixture<unsigned short> )
 {
 
 	fill_attributes();
 
 	CDicom2DImageIOPlugin::Data imagelist;
 	imagelist.push_back(porg_image);
-	BOOST_REQUIRE(plugin.save("testsave.dcm", imagelist));
+	BOOST_REQUIRE(plugin.save("testsave-us.dcm", imagelist));
 
-	CDicom2DImageIOPlugin::PData images = plugin.load("testsave.dcm");
+	CDicom2DImageIOPlugin::PData images = plugin.load("testsave-us.dcm");
 	BOOST_REQUIRE(images);
 	BOOST_REQUIRE(images->size() == 1);
 	P2DImage pimage = *images->begin();
@@ -191,7 +220,7 @@ BOOST_FIXTURE_TEST_CASE( test_dicom_save_load, DicomSaveLoadFixture )
 
 }
 
-BOOST_FIXTURE_TEST_CASE( test_dicom_load_nothing, DicomSaveLoadFixture )
+BOOST_FIXTURE_TEST_CASE( test_dicom_load_nothing, DicomSaveLoadFixture<signed short> )
 {
 	CDicom2DImageIOPlugin plugin;
 	CDicom2DImageIOPlugin::PData images = plugin.load("nonexistence.dcm");
diff --git a/addons/dicom/test_dcm3d.cc b/addons/dicom/test_dcm3d.cc
index 6857435..d763a90 100644
--- a/addons/dicom/test_dcm3d.cc
+++ b/addons/dicom/test_dcm3d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -57,12 +57,13 @@ struct DicomLoaderFixture {
 	CDicom3DImageIOPlugin plugin;
 };
 
+template <typename T> 
 struct DicomSaveLoadFixture : public DicomLoaderFixture {
 	DicomSaveLoadFixture();
 	void fill_attributes();
 
 	C3DBounds size;
-	C3DUSImage *org_image;
+	T3DImage<T> *org_image;
 	P3DImage porg_image;
 };
 
@@ -107,11 +108,14 @@ void DicomLoaderFixture::check_attribute(const C3DImage& image, const char *name
 	BOOST_CHECK_EQUAL(attr_val, svalue);
 }
 
-void DicomSaveLoadFixture::fill_attributes()
+template <typename T> 
+void DicomSaveLoadFixture<T>::fill_attributes()
 {
 	org_image->set_attribute("MediaStorageSOPClassUID",  "somevalue");
 	org_image->set_attribute(IDSOPClassUID,  "othervalue");
 	org_image->set_voxel_size(C3DFVector(1.45, 2.34, 3));
+	org_image->set_origin(C3DFVector(2.45, 2.0, 3.1));
+	org_image->set_rotation(Quaternion(0.1, 0.7, 0.5, 0.5).get_rotation_matrix());
 
 
 	org_image->set_attribute("Modality", "MR");
@@ -121,21 +125,22 @@ void DicomSaveLoadFixture::fill_attributes()
 	org_image->set_attribute("StudyDescription", "PROST");
 	org_image->set_attribute("AcquisitionDate","20090909");
 	org_image->set_attribute("PatientPosition", "HFP");
-	org_image->set_attribute("StudyID", "888899");
+	org_image->set_attribute("StudyID", typeid(T).name());
 	org_image->set_attribute("ImageType", "ORIGINAL\\PRIMARY\\M\\ND\\RETRO");
 	org_image->set_attribute(IDSmallestImagePixelValue,"1");
 	org_image->set_attribute(IDLargestImagePixelValue,"20");
+	org_image->set_attribute(IDPhotometricInterpretation,"MONOCHROME2");
 
 }
 
 
-BOOST_FIXTURE_TEST_CASE( test_dicom_save_load, DicomSaveLoadFixture )
+BOOST_FIXTURE_TEST_CASE( test_dicom_us_save_load, DicomSaveLoadFixture<unsigned short> )
 {
 	CDicom3DImageIOPlugin::Data imagelist;
 	imagelist.push_back(porg_image);
-	BOOST_REQUIRE(plugin.save("testsave3d.dcm", imagelist));
+	BOOST_REQUIRE(plugin.save("testsave3d-us.dcm", imagelist));
 
-	CDicom3DImageIOPlugin::PData images = plugin.load("testsave3d0001_0001.dcm");
+	CDicom3DImageIOPlugin::PData images = plugin.load("testsave3d-us0001_0001.dcm");
 	BOOST_REQUIRE(images);
 	BOOST_REQUIRE(images->size() == 1);
 	P3DImage pimage = *images->begin();
@@ -159,15 +164,46 @@ BOOST_FIXTURE_TEST_CASE( test_dicom_save_load, DicomSaveLoadFixture )
 
 }
 
+BOOST_FIXTURE_TEST_CASE( test_dicom_ss_save_load, DicomSaveLoadFixture<signed short> )
+{
+	CDicom3DImageIOPlugin::Data imagelist;
+	imagelist.push_back(porg_image);
+	BOOST_REQUIRE(plugin.save("testsave3d-ss.dcm", imagelist));
+
+	CDicom3DImageIOPlugin::PData images = plugin.load("testsave3d-ss0001_0001.dcm");
+	BOOST_REQUIRE(images);
+	BOOST_REQUIRE(images->size() == 1);
+	P3DImage pimage = *images->begin();
+	BOOST_REQUIRE(pimage);
+
+	const C3DSSImage& load_image = dynamic_cast<const C3DSSImage&>(*pimage);
+
+	BOOST_CHECK_EQUAL(load_image.get_size(), size);
+
+	if (!equal(load_image.begin(), load_image.end(), org_image->begin()))  {
+		for(size_t z = 0; z < load_image.get_size().z; ++z)
+			for(size_t y = 0; y < load_image.get_size().y; ++y)
+				for(size_t x = 0; x < load_image.get_size().x; ++x) {
+					BOOST_CHECK_EQUAL(load_image(x,y,z),
+							  (*org_image)(x,y,z));
+				}
+	}
+
+	BOOST_CHECK_EQUAL(load_image.get_voxel_size(), org_image->get_voxel_size());
+	BOOST_CHECK(load_image ==  *org_image);
+
+}
+
 
-DicomSaveLoadFixture::DicomSaveLoadFixture():
+template <typename T> 
+DicomSaveLoadFixture<T>::DicomSaveLoadFixture():
 	size(4,5,6)
 {
-	org_image = new C3DUSImage(size);
+	org_image = new T3DImage<T>(size);
 	porg_image.reset( org_image );
 
 	short k = 1;
-	for (C3DUSImage::iterator i = org_image->begin(); i != org_image->end(); ++i, ++k)
+	for (auto i = org_image->begin(); i != org_image->end(); ++i, ++k)
 		*i = k;
 	fill_attributes();
 }
diff --git a/addons/dicom/test_dicom4mia.cc b/addons/dicom/test_dicom4mia.cc
index cf7799e..c7ff0e6 100644
--- a/addons/dicom/test_dicom4mia.cc
+++ b/addons/dicom/test_dicom4mia.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -67,9 +67,10 @@ BOOST_AUTO_TEST_CASE(test_read_dicom_attributes)
 	BOOST_CHECK_EQUAL(reader.get_attribute(IDMediaStorageSOPClassUID, true),"1.2.840.10008.5.1.4.1.1.4");
 	BOOST_CHECK_EQUAL(reader.get_attribute(IDSmallestImagePixelValue, true),"7");
 	BOOST_CHECK_EQUAL(reader.get_attribute(IDLargestImagePixelValue, true),"1548");
-
 	BOOST_CHECK_EQUAL(reader.get_pixel_size(), C2DFVector(1.484375,1.484375));
 
+	auto pimage = reader.get_image(); 
+	BOOST_CHECK_EQUAL(pimage->get_attribute_as<double>(IDAcquisitionTime), 32742.072496); 
 }
 
 struct DicomFixture {
@@ -94,6 +95,7 @@ struct DicomFixture {
 
 		const TAttribute<T>& pattr = dynamic_cast<const TAttribute<T>&>(*attr);
 		T attr_val = pattr;
+		cvdebug() << "Attribute value = " << attr_val <<  "\n"; 
 		BOOST_CHECK_EQUAL(attr_val, value);
 	}
 
@@ -127,6 +129,8 @@ BOOST_FIXTURE_TEST_CASE(test_read_dicom_pixels, DicomFixture)
 	check_attribute(*image, IDImageType, "ORIGINAL\\PRIMARY\\M\\ND\\RETRO");
 	check_attribute(*image, IDSliceLocation, 15.088232007086f);
 	check_attribute(*image, IDMediaStorageSOPClassUID,"1.2.840.10008.5.1.4.1.1.4");
+	
+	check_attribute<double>(*image, IDAcquisitionTime,32742.072496);
 
 	const C2DUSImage& img = dynamic_cast<const C2DUSImage&>(*image);
 
@@ -172,6 +176,7 @@ BOOST_FIXTURE_TEST_CASE(test_create_dicom, DicomFixture)
 	image.set_attribute(IDSmallestImagePixelValue, "10");
 	image.set_attribute(IDLargestImagePixelValue, "2000");
 	image.set_attribute(IDProtocolName, "My Protocol");
+	image.set_attribute(IDAcquisitionTime, "12312.121");
 
 	CDicomWriter writer(image);
 
@@ -190,6 +195,7 @@ DicomFixture::DicomFixture()
 	TTranslator<int>::register_for(IDSeriesNumber);
 	TTranslator<int>::register_for(IDAcquisitionNumber);
 	TTranslator<int>::register_for(IDInstanceNumber);
+	TTranslator<double>::register_for(IDAcquisitionTime); 
 }
 
 void DicomFixture::check_attribute(const C2DImage& image, const char *name, const char *value)
diff --git a/addons/hdf5/CMakeLists.txt b/addons/hdf5/CMakeLists.txt
new file mode 100644
index 0000000..d5ec769
--- /dev/null
+++ b/addons/hdf5/CMakeLists.txt
@@ -0,0 +1,47 @@
+#
+# This file is part of MIA - a toolbox for medical image analysis 
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+#
+# MIA is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+
+OPTION(USE_HDF5 "use hdf5 for data UI" TRUE)
+
+
+IF (USE_HDF5)
+  if (STRICT_DEPENDECIES)
+    find_package(HDF5 REQUIRED)
+  else (STRICT_DEPENDECIES)
+    find_package(HDF5)
+  endif (STRICT_DEPENDECIES)
+  
+  IF(HDF5_FOUND)
+    DEFINE_PROPERTY(GLOBAL PROPERTY HAVE_HDF5_PROP BRIEF_DOCS "yeah" FULL_DOCS "yeah")
+    INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIRS})
+    LINK_DIRECTORIES(${HDF5_LIBRARY_DIRS})
+    SET(HDF5IO_SRC hdf5mia.cc hdf5a_mia.cc)
+    SET(HDF5MIALIBS miacore ${HDF5_LIBRARIES})
+    MIA_ADD_LIBRARY(miahdf5 "${HDF5IO_SRC}" "${HDF5MIALIBS}")
+    SET(INSTALL_TARGETS miahdf5)	
+    INSTALL_BASE("${INSTALL_TARGETS}")
+
+
+    NEW_TEST(hdf5mia miahdf5)
+    SET(DEPS3D miahdf5 mia3d)
+
+    PLUGIN_WITH_TEST_AND_PREFIX2("3dimage" "io" hdf5_3dimage  "${DEPS3D}")
+
+  ENDIF(HDF5_FOUND)
+  
+ENDIF(USE_HDF5)
diff --git a/addons/hdf5/hdf5_3dimage.cc b/addons/hdf5/hdf5_3dimage.cc
new file mode 100644
index 0000000..65da7d1
--- /dev/null
+++ b/addons/hdf5/hdf5_3dimage.cc
@@ -0,0 +1,247 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/filter.hh>
+
+#include <addons/hdf5/hdf5a_mia.hh>
+#include <addons/hdf5/hdf5_3dimage.hh>
+
+NS_BEGIN(hdf5_3dimage)
+using namespace mia; 
+
+using std::string; 
+using std::vector; 
+using std::stringstream; 
+
+
+
+
+CHDF53DImageIOPlugin::CHDF53DImageIOPlugin():
+        C3DImageIOPlugin("hdf5")
+{
+        add_supported_type(it_bit);
+        add_supported_type(it_sbyte);
+        add_supported_type(it_ubyte);
+	add_supported_type(it_sshort);
+	add_supported_type(it_ushort);
+	add_supported_type(it_sint);
+	add_supported_type(it_uint);
+#ifdef LONG_64BIT
+	add_supported_type(it_slong);
+	add_supported_type(it_ulong);
+#endif 
+	add_supported_type(it_float);
+	add_supported_type(it_double);
+
+	add_suffix(".h5");
+	add_suffix(".H5");
+
+	add_property(io_plugin_property_multi_record);
+	add_property(io_plugin_property_has_attributes);
+
+        // enable some translators for post-conversion
+	CVoxelAttributeTranslator::register_for("voxel");
+	C3DIntAttributeTranslator::register_for("ca");
+	C3DIntAttributeTranslator::register_for("cp");
+
+}
+
+struct HDF5ReadCallbackdata { 
+	CHDF53DImageIOPlugin::Data& result; 
+	string path;
+        H5Base& id; 
+}; 
+
+herr_t hdf5_walk (hid_t loc_id, const char *name, const H5L_info_t *MIA_PARAM_UNUSED(info),
+                  void *operator_data)
+{
+        H5O_info_t      infobuf;
+
+        HDF5ReadCallbackdata *cbd = reinterpret_cast<HDF5ReadCallbackdata *>(operator_data); 
+        herr_t status = H5Oget_info_by_name (loc_id, name, &infobuf, H5P_DEFAULT);
+	if (status < 0) {
+		cvdebug() << "hdf5_walk: H5Oget_info_by_name returned " << status 
+			  << " for '" << name << "' with current path '"  << cbd->path << "'\n"; 
+	}
+
+        string path = cbd->path + string("/") + string(name); 
+	
+        switch (infobuf.type) {
+        case H5O_TYPE_GROUP: { // recursion 
+		cvdebug() << "Open group '" << name << "'\n"; 
+		string sname(name);
+		H5Base group =  H5Group::open(cbd->id, sname);
+                HDF5ReadCallbackdata rec_cbd = {cbd->result, path, group};
+                status = H5Literate (group, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, hdf5_walk, &rec_cbd);
+		cvdebug() << "hdf5_walk:H5Literate returned with status " << status << "\n"; 
+        }break; 
+                
+        case H5O_TYPE_DATASET: 
+        case H5O_TYPE_NAMED_DATATYPE: {
+		cvdebug() << "Found data set\n"; 
+		auto dataset = H5Dataset::open(cbd->id, name);
+		auto size = dataset.get_size(); 
+		if (size.size() != 3) {
+			cvdebug() << "HDF5 (3dimage): found " << size.size() << " data set, ignoring\n"; 
+			break; 
+		}
+		C3DBounds bsize(size[2], size[1], size[0]); 
+		H5Type file_type(H5Dget_type(dataset)); 
+		H5Type mem_type = file_type.get_native_type(); 
+		int type_id = mem_type.get_mia_type_id(); 
+		P3DImage new_image; 
+		switch (type_id) {
+		case EAttributeType::attr_bool: 
+			new_image = read_image<C3DBitImage>(bsize, dataset); 
+			break; 
+		case EAttributeType::attr_uchar: 
+			new_image = read_image<C3DUBImage>(bsize, dataset); 
+			break; 
+		case EAttributeType::attr_schar:
+			new_image = read_image<C3DSBImage>(bsize, dataset); 
+			break; 
+		case EAttributeType::attr_ushort:
+			new_image = read_image<C3DUSImage>(bsize, dataset); 
+			break; 
+		case EAttributeType::attr_sshort:
+			new_image = read_image<C3DSSImage>(bsize, dataset); 
+			break; 
+		case EAttributeType::attr_uint:
+			new_image = read_image<C3DUIImage>(bsize, dataset); 
+			break; 
+		case EAttributeType::attr_sint:
+			new_image = read_image<C3DSIImage>(bsize, dataset); 
+			break; 
+#ifdef LONG_64BIT
+		case EAttributeType::attr_ulong:
+			new_image = read_image<C3DULImage>(bsize, dataset); 
+			break; 
+		case EAttributeType::attr_slong:
+			new_image = read_image<C3DSLImage>(bsize, dataset); 
+			break; 
+#endif
+		case EAttributeType::attr_float:
+			new_image = read_image<C3DFImage>(bsize, dataset); 
+			break; 
+		case EAttributeType::attr_double:
+			new_image = read_image<C3DDImage>(bsize, dataset); 
+			break; 
+		default: 
+			cverr() << "HDF5 (3dimage): Found unsupported image pixel type " << type_id << ", skipping.\n"; 
+			return 0; 
+		}
+		new_image->set_attribute("path", path); 
+		cbd->result.push_back(new_image); 
+        }break; 
+        default: 
+                cvdebug() << "HDF5 read: ignoring unknown '" << name << "'\n"; 
+        }; 
+        return 0; 
+}
+
+
+CHDF53DImageIOPlugin::PData CHDF53DImageIOPlugin::do_load(const string&  filename) const
+{
+        PData result(new Data); 
+        
+        H5File file = H5File::open(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); 
+	if (file < 0) {
+		// either the file doesn't exist or it is not a HDF5 file
+		return PData(); 
+	}
+        
+        HDF5ReadCallbackdata cbd = {*result, "", file}; 
+
+	auto status = H5Literate (file, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, hdf5_walk, &cbd);
+	cvdebug() << "CHDF53DImageIOPlugin::do_load: H5Literate returned with status " 
+		  << status << "\n"; 
+	
+	return result; 
+}
+
+class FHDF5Saver:public TFilter<void> {
+public: 
+        FHDF5Saver(H5File& file):m_file(file), m_id(0){}
+        
+        template <typename T> 
+        void operator ()( const T3DImage<T>& image); 
+private: 
+        H5File& m_file; 
+        int m_id; 
+
+}; 
+
+template <typename T> 
+void FHDF5Saver::operator ()( const T3DImage<T>& image)
+{
+        vector<hsize_t> dims = {image.get_size().z, image.get_size().y, image.get_size().x}; 
+        
+        auto space = H5Space::create(dims); 
+        
+        auto file_type = Mia_to_h5_types<T>::file_datatype(); 
+        
+        stringstream path_str; 
+        path_str << "/mia/" << m_id++; 
+        auto path = path_str.str(); 
+        if (image.has_attribute("hdf5-path")) {
+                auto stored_path = image.get_attribute("hdf5-path");
+                if (stored_path->type_id() == EAttributeType::attr_string) {
+                        string s = stored_path->as_string(); 
+                        if (s[0] == '/') {
+                                path = s; 
+                        }else{
+                                cvwarn() << "HDF5 save: image has path " << s << " without leading '/', ignoring"; 
+                        }
+                }
+        }
+	cvdebug() << "Add image to '" << path << "'\n"; 
+        auto dataset = H5Dataset::create(m_file, path.c_str(), file_type, space);
+        dataset.write(image.begin(), image.end()); 
+        translate_to_hdf5_attributes(dataset, image); 
+}
+
+
+const std::string CHDF53DImageIOPlugin::do_get_preferred_suffix() const
+{
+	return "h5"; 
+}
+
+bool CHDF53DImageIOPlugin::do_save(const string& fname, const Data& data) const
+{
+        H5File file = H5File::create(fname.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+        FHDF5Saver saver(file); 
+        for (auto i = data.begin(); i != data.end(); ++i) 
+                mia::accumulate(saver, **i); 
+        return true; 
+}
+
+const std::string CHDF53DImageIOPlugin::do_get_descr() const
+{
+        return "HDF5 3D image IO"; 
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+
+	return new CHDF53DImageIOPlugin; 
+}
+
+
+NS_END
diff --git a/addons/hdf5/hdf5_3dimage.hh b/addons/hdf5/hdf5_3dimage.hh
new file mode 100644
index 0000000..e7b54a5
--- /dev/null
+++ b/addons/hdf5/hdf5_3dimage.hh
@@ -0,0 +1,40 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef addons_hdf5_3fimage_hh
+#define addons_hdf5_3fimage_hh
+
+#include <mia/3d/imageio.hh>
+
+namespace hdf5_3dimage {
+
+class CHDF53DImageIOPlugin : public mia::C3DImageIOPlugin {
+public:
+	CHDF53DImageIOPlugin();
+private:
+	const std::string do_get_preferred_suffix() const; 
+        virtual PData do_load(const std::string&  filename) const;
+	virtual bool do_save(const std::string& fname, const Data& data) const;
+	virtual const std::string do_get_descr() const;
+};
+
+}
+
+#endif
diff --git a/addons/hdf5/hdf5a_mia.cc b/addons/hdf5/hdf5a_mia.cc
new file mode 100644
index 0000000..6a6367a
--- /dev/null
+++ b/addons/hdf5/hdf5a_mia.cc
@@ -0,0 +1,360 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#define VSTREAM_DOMAIN "HDF5"
+#include <addons/hdf5/hdf5a_mia.hh>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/for_each.hpp>
+
+
+NS_MIA_BEGIN
+
+using std::vector; 
+using std::string; 
+using std::invalid_argument; 
+using std::runtime_error; 
+
+
+typedef boost::mpl::vector<signed char,
+			   unsigned char,
+			   signed short,
+			   unsigned short,
+			   signed int,
+			   float,
+			   unsigned int,
+#ifdef LONG_64BIT
+			   signed long,
+			   unsigned long,
+#endif
+
+			   double
+			   > HDF5BasicPixelTypes;
+
+template <typename I> 
+static void check_id(hid_t id, const char *domain, const char *action, I info) 
+{
+	if (id < 0) {
+		throw create_exception<invalid_argument>(domain, ": error in ", action, ":", info);  
+	}
+}
+
+
+H5Attribute::H5Attribute(hid_t id, const H5Space& space):
+	H5Base(H5AttributeHandle(id)), 
+	m_space(space)
+{
+}
+
+H5Attribute H5Attribute::write(const H5Base& parent, const char *name, const CAttribute& attr)
+{
+	return H5AttributeTranslatorMap::instance().translate(parent, name, attr); 
+}
+
+std::vector <hsize_t> H5Attribute::get_size() const
+{
+	return m_space.get_size(); 
+}
+
+H5Space H5Attribute::get_space()const
+{
+	return m_space;
+}
+
+H5Type H5Attribute::get_type() const
+{
+	H5Type file_type(H5Aget_type(*this)); 
+	return file_type.get_native_type(); 
+}
+
+PAttribute H5Attribute::read(const H5Base& parent, const char *name)
+{
+	auto id = H5Aopen(parent, name, H5P_DEFAULT); 
+	check_id(id, "H5Attribute", "open", name);
+
+	
+	auto space_id = H5Aget_space(id); 
+	check_id(space_id, "H5Attribute", "get_space", name);
+	H5Space space(space_id); 
+	H5Attribute attr(id, space); 
+
+	return 	H5AttributeTranslatorMap::instance().translate(name, attr); 
+}
+
+
+template <typename T> 
+class H5TAttributeTranslator: public H5AttributeTranslator {
+	H5Attribute apply(const H5Base& parent, const char *name, const CAttribute& attr) const; 
+	virtual PAttribute apply(const char *name, const H5Attribute& attr ) const; 
+}; 
+
+template <typename T> 
+struct  __dispatch_H5TAttributeTranslator {
+	static H5Attribute apply(const H5Base& parent, const char *name, const TAttribute<T>& attr);
+}; 
+
+template <typename T> 
+struct  __dispatch_H5TAttributeTranslator<vector<T>> {
+	static H5Attribute apply(const H5Base& parent, const char *name, const TAttribute<vector<T>>& attr);
+}; 
+
+
+template <typename T> 
+H5Attribute  __dispatch_H5TAttributeTranslator<T>::apply(const H5Base& parent, const char *name, const TAttribute<T>& attr)
+{
+	auto file_datatype = Mia_to_h5_types<T>::file_datatype();      
+	auto mem_datatype = Mia_to_h5_types<T>::mem_datatype();
+
+	T value = attr;
+	auto space = H5Space::create();
+	
+	auto id = H5Acreate(parent, name, file_datatype, space, H5P_DEFAULT, H5P_DEFAULT);
+	check_id(id, "H5Attribute", "translate", name);
+	H5Attribute result(id, space);
+
+	H5Awrite(result, mem_datatype, &value);
+	result.set_parent(parent); 
+	return result; 
+}
+
+template <typename T> 
+H5Attribute  __dispatch_H5TAttributeTranslator<vector<T>>::apply(const H5Base& parent, const char *name, 
+								 const TAttribute<vector<T>>& attr) 
+{
+	auto file_datatype = Mia_to_h5_types<T>::file_datatype();      
+	auto mem_datatype = Mia_to_h5_types<T>::mem_datatype();
+
+	const std::vector<T>& value = attr;
+	auto space = H5Space::create(value.size());
+	
+	auto id = H5Acreate(parent, name, file_datatype, space, H5P_DEFAULT, H5P_DEFAULT);
+	check_id(id, "H5Attribute", "translate", name);
+	H5Attribute result(id, space);
+
+	H5Awrite(result, mem_datatype, &value[0]);
+	result.set_parent(parent); 
+	return result; 
+}
+
+template <typename T> 
+H5Attribute H5TAttributeTranslator<T>::apply(const H5Base& parent, const char *name, const CAttribute& __attr) const
+{
+	auto type_id = __attr.type_id(); 
+	if (EAttributeType::is_vector(type_id)) {
+		auto& attr = dynamic_cast<const TAttribute<vector<T>>&>(__attr);
+		return __dispatch_H5TAttributeTranslator<vector<T>>::apply(parent, name, attr); 
+	}else {
+		auto& attr = dynamic_cast<const TAttribute<T>&>(__attr);
+		return __dispatch_H5TAttributeTranslator<T>::apply(parent, name, attr); 
+	}
+}
+
+template <typename T> 
+PAttribute H5TAttributeTranslator<T>::apply(const char *name, const H5Attribute& attr) const
+{
+	auto dim = attr.get_size(); 
+	if (dim.empty()) {
+		T result_value; 
+		H5Aread(attr, Mia_to_h5_types<T>::mem_datatype(), &result_value); 
+		return PAttribute(new TAttribute<T>(result_value)); 
+	}else if (dim.size() == 1) {
+		vector<T> data(dim[0]); 
+		H5Aread(attr, Mia_to_h5_types<T>::mem_datatype(), &data[0]);
+		return PAttribute(new TAttribute<vector<T>>(data));
+	}else {
+		throw create_exception<runtime_error>("H5TAttributeTranslator: attribute(", name, "): with ", dim.size(), 
+						      " not supported not supported by translator"); 
+	}
+}
+
+class H5TAttributeStringTranslator: public H5AttributeTranslator {
+	H5Attribute apply(const H5Base& parent, const char *name, const CAttribute& attr) const; 
+	virtual PAttribute apply(const char *name, const H5Attribute& attr ) const; 
+	
+	H5Attribute generic_apply(const H5Base& parent, const char *name, const CAttribute& attr) const; 
+	H5Attribute apply(const H5Base& parent, const char *name, const CVStringAttribute& attr) const; 
+
+};
+
+H5Attribute H5TAttributeStringTranslator::generic_apply(const H5Base& parent, const char *name, const CAttribute& attr) const
+{
+	const string value = attr.as_string(); 
+	cvdebug() << "Write string attribute '" << attr << "'\n"; 
+
+	H5Type stype(H5Tcopy (H5T_C_S1));
+	H5Tset_size(stype, H5T_VARIABLE);
+
+	vector<hsize_t> size(1, 1); 
+	auto space = H5Space::create(size);
+
+	auto id = H5Acreate(parent, name, stype, space, H5P_DEFAULT, H5P_DEFAULT);
+	check_id(id, "H5Attribute", "translate string", name);
+	H5Attribute result(id, space);
+
+	const char *s = value.c_str(); 
+	if (H5Awrite(result, stype, &s) < 0) 
+		cvwarn() << "error writing attribute '"<< name << "'\n"; 
+	
+	result.set_parent(parent); 
+	cvdebug() << "done with '" << attr << "'\n"; 
+	return result; 
+
+}
+
+H5Attribute H5TAttributeStringTranslator::apply(const H5Base& parent, const char *name, const CVStringAttribute& attr) const
+{
+	const vector<string> value = attr;
+	vector<hsize_t> dims(1,value.size()); 
+	
+	H5Type stype(H5Tcopy (H5T_C_S1));
+	H5Tset_size(stype, H5T_VARIABLE); 
+	
+	
+	H5Space space = H5Space::create(dims);
+
+	auto id = H5Acreate(parent, name, stype, space, H5P_DEFAULT, H5P_DEFAULT);
+	check_id(id, "H5Attribute", "translate string vector", name);
+	H5Attribute result(id, space);
+
+	vector<const char *> wstrings(value.size());
+	transform(value.begin(), value.end(), wstrings.begin(), 
+		  [](const string& s){return s.c_str();}); 
+	
+	if (H5Awrite(result, stype, &wstrings[0]) < 0) 
+		cvwarn() << "error writing vector<string> attribute '"<< name << "'\n"; 
+	result.set_parent(parent); 
+	return result; 
+}
+
+H5Attribute H5TAttributeStringTranslator::apply(const H5Base& parent, const char *name, const CAttribute& __attr) const
+{
+	if (EAttributeType::is_vector(__attr.type_id())) {
+		return apply(parent, name, dynamic_cast<const CVStringAttribute&>(__attr)); 
+	} else {
+		return generic_apply(parent, name, __attr); 
+	}
+}
+
+PAttribute H5TAttributeStringTranslator::apply(const char *name, const H5Attribute& attr ) const
+{
+	PAttribute result; 
+	auto size = attr.get_size(); 
+	auto space = attr.get_space(); 
+	
+	if (size.size() > 1) {
+		cvwarn() << "Support for " << size.size() << "-dimensional string attributes not implemented."
+			 <<" Reading only first dimension.\n"; 
+	}
+	
+	H5Type memtype(H5Tcopy (H5T_C_S1));
+	H5Tset_size (memtype, H5T_VARIABLE);
+
+	if (size.empty() || size[0] == 1) { 
+		vector<char *> rdata(1);
+		auto status = H5Aread (attr, memtype, &rdata[0]);
+		if (status < 0) {
+			cvwarn() << "Error reading string attribute\n"; 
+			return PAttribute(); 
+		}
+		cvdebug() << "post-convert '" << name << "' from '" << rdata[0] << "'\n"; 
+		result = CStringAttrTranslatorMap::instance().to_attr(name, string(rdata[0])); 
+		H5Dvlen_reclaim (memtype, space, H5P_DEFAULT, &rdata[0]); 
+	}else { 
+		vector<char *> rdata(size[0]);
+		auto status = H5Aread (attr, memtype, &rdata[0]);
+		if (status < 0) {
+			cvwarn() << "Error reading vector<string> attribute\n"; 
+			return PAttribute(); 
+		}
+		vector<string> result_value; 
+		for (size_t i = 0; i < size[0]; ++i) {
+			result_value.push_back(string(rdata[i])); 
+		}
+		result.reset(new CVStringAttribute(result_value)); 
+		H5Dvlen_reclaim (memtype, space, H5P_DEFAULT, &rdata[0]); 
+	}
+	return result; 
+}
+
+struct translator_append {
+	translator_append(H5AttributeTranslatorMap& map):m_map(map){}; 
+	template <typename T> 
+	void operator () (T& MIA_PARAM_UNUSED(dummy)) {
+		m_map.register_translator(attribute_type<T>::value, 
+					  PH5AttributeTranslator(new H5TAttributeTranslator<T>)); 
+	}
+	H5AttributeTranslatorMap& m_map; 
+};
+
+H5AttributeTranslatorMap::H5AttributeTranslatorMap()
+{
+	boost::mpl::for_each<HDF5BasicPixelTypes>(translator_append(*this)); 
+
+	register_translator(attribute_type<string>::value, 
+			    PH5AttributeTranslator(new H5TAttributeStringTranslator()));
+}
+
+H5AttributeTranslatorMap& H5AttributeTranslatorMap::instance()
+{
+	static H5AttributeTranslatorMap map; 
+	return map; 
+
+}
+
+void H5AttributeTranslatorMap::register_translator(int type_id, PH5AttributeTranslator translator)
+{
+	assert(m_map.find(type_id) == m_map.end()); 
+	m_map[type_id] = translator; 	
+}
+
+const H5AttributeTranslator& H5AttributeTranslatorMap::get_translator(int type_id) const
+{
+	auto itranslator = m_map.find(type_id); 
+	if (itranslator != m_map.end()) {
+		return *itranslator->second; 
+	}else{
+		auto scalar_type_id = EAttributeType::scalar_type(type_id); 
+		auto itranslator = m_map.find(scalar_type_id); 
+		if (itranslator == m_map.end()) {
+			auto tid = attribute_type<string>::value; 
+			itranslator = m_map.find(tid); 
+			assert(itranslator != m_map.end()); 
+		}
+		return *itranslator->second; 
+	}
+}
+
+PAttribute  H5AttributeTranslatorMap::translate(const char *name, const H5Attribute& attr)
+{
+	return get_translator(attr.get_type().get_mia_type_id()).apply(name, attr); 
+}
+
+H5Attribute H5AttributeTranslatorMap::translate(const H5Base& parent, const char *name, const CAttribute& attr)
+{
+	return get_translator(attr.type_id()).apply(parent, name, attr); 
+}
+
+void translate_to_hdf5_attributes(const H5Base& target, const CAttributedData& data)
+{
+	for( auto a = data.begin_attributes(); a != data.end_attributes(); ++a)
+		H5AttributeTranslatorMap::instance().translate(target, a->first.c_str(), *a->second); 
+}
+
+NS_MIA_END
diff --git a/addons/hdf5/hdf5a_mia.hh b/addons/hdf5/hdf5a_mia.hh
new file mode 100644
index 0000000..fb1dbd3
--- /dev/null
+++ b/addons/hdf5/hdf5a_mia.hh
@@ -0,0 +1,75 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef addon_hdf5_hdf5mia_hh
+#define addon_hdf5_hdf5mia_hh
+
+#include <addons/hdf5/hdf5mia.hh>
+
+NS_MIA_BEGIN
+
+class HDF54MIA_EXPORT H5Attribute: public H5Base {
+public: 
+	H5Attribute(hid_t id, const H5Space& space); 
+	H5Attribute() = default; 
+	
+	static H5Attribute write(const H5Base& parent, const char *name, const CAttribute& attr);
+	static PAttribute read(const H5Base& parent, const char *name);
+
+	H5Type get_type() const; 
+	std::vector <hsize_t> get_size() const; 
+
+	H5Space get_space()const; 
+private: 
+	PAttribute read_scalar();
+	PAttribute read_vector();
+	
+	H5Space m_space; 
+}; 
+
+class HDF54MIA_EXPORT H5AttributeTranslator {
+public: 
+	virtual H5Attribute apply(const H5Base& parent, const char *name, const CAttribute& attr) const = 0; 
+	virtual PAttribute apply(const char *name, const H5Attribute& attr ) const = 0; 
+}; 
+typedef std::shared_ptr<H5AttributeTranslator> PH5AttributeTranslator; 
+
+
+class HDF54MIA_EXPORT H5AttributeTranslatorMap {
+	H5AttributeTranslatorMap(); 
+
+	H5AttributeTranslatorMap(const H5AttributeTranslatorMap& other) = delete; 
+	H5AttributeTranslatorMap& operator = (const H5AttributeTranslatorMap& other) = delete; 
+public: 
+	static H5AttributeTranslatorMap& instance(); 
+	void register_translator(int type_id, PH5AttributeTranslator translator);
+	H5Attribute translate(const H5Base& parent, const char *name, const CAttribute& attr);
+	PAttribute  translate(const char *name, const H5Attribute& parent);
+private: 
+	const H5AttributeTranslator& get_translator(int type_id) const; 
+	typedef std::map<int,  PH5AttributeTranslator> TranslatorMap; 
+	TranslatorMap m_map;
+}; 
+
+void HDF54MIA_EXPORT translate_to_hdf5_attributes(const H5Base& target, const CAttributedData& data); 
+
+NS_MIA_END
+
+#endif 
diff --git a/addons/hdf5/hdf5mia.cc b/addons/hdf5/hdf5mia.cc
new file mode 100644
index 0000000..d815a49
--- /dev/null
+++ b/addons/hdf5/hdf5mia.cc
@@ -0,0 +1,473 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#define VSTREAM_DOMAIN "HDF5"
+
+#include <addons/hdf5/hdf5a_mia.hh>
+#include <stack>
+NS_MIA_BEGIN
+
+using std::vector; 
+using std::string; 
+using std::stack; 
+using std::invalid_argument; 
+using std::runtime_error; 
+
+
+
+H5Handle::H5Handle(hid_t hid, const TSingleReferencedObject<hid_t>::Destructor& d):
+	TSingleReferencedObject<hid_t>(hid, d)
+{
+}
+
+void H5Handle::set_parent(const H5Handle& parent)
+{
+	m_parent = parent; 
+}
+
+#define H5Destructor(TYPE, CALL)					\
+	struct TYPE : public TSingleReferencedObject<hid_t>::Destructor {				\
+		TYPE(){};						\
+		virtual void operator ()(hid_t& handle)const {		\
+			if (handle >= 0) {				\
+				herr_t err = CALL(handle);		\
+				if (err != 0) {				\
+					throw std::runtime_error(#TYPE ": error closing handle."); \
+				}					\
+			}						\
+		}							\
+	};								\
+	static const TYPE TYPE;						\
+
+H5Destructor(H5GroupDestructor, H5Gclose);
+H5Destructor(H5SpaceDestructor, H5Sclose);
+H5Destructor(H5DatasetDestructor, H5Dclose);
+H5Destructor(H5FileDestructor, H5Fclose);
+H5Destructor(H5AttributeDestructor, H5Aclose);
+H5Destructor(H5PropertyDestructor, H5Pclose); 
+H5Destructor(H5TypeDestructor, H5Tclose); 
+
+H5SpaceHandle::H5SpaceHandle(hid_t hid):
+	H5Handle(hid, H5SpaceDestructor)
+{
+}
+
+H5TypeHandle::H5TypeHandle(hid_t hid):
+	H5Handle(hid, H5TypeDestructor)
+{
+}
+
+
+H5GroupHandle::H5GroupHandle(hid_t hid):
+	H5Handle(hid, H5GroupDestructor)
+{
+}
+
+H5DatasetHandle::H5DatasetHandle(hid_t hid):
+	H5Handle(hid, H5DatasetDestructor)
+{
+}
+
+H5AttributeHandle::H5AttributeHandle(hid_t hid):
+	H5Handle(hid, H5AttributeDestructor)
+{
+}
+
+H5PropertyHandle::H5PropertyHandle(hid_t hid):
+	H5Handle(hid, H5PropertyDestructor)
+{
+}	
+
+H5FileHandle::H5FileHandle(hid_t hid):
+	H5Handle(hid, H5FileDestructor)
+{
+}
+
+H5Base::H5Base(const H5Handle& handle):
+	m_handle(handle)
+{
+}
+
+void H5Base::set_parent(const H5Base& parent)
+{
+	m_handle.set_parent(parent.get_handle()); 
+}
+
+const H5Handle& H5Base::get_handle() const
+{
+	return m_handle; 
+}
+
+struct SIterateData {
+	CAttributedData& list; 
+	const H5Base& locator_id; 
+}; 
+
+
+static herr_t convert_attribute_cb(hid_t MIA_PARAM_UNUSED(location_id), const char *attr_name, 
+			    const H5A_info_t *MIA_PARAM_UNUSED(ainfo), void *op_data)
+{
+	SIterateData& iter_data = *reinterpret_cast<SIterateData *>(op_data); 
+	cvdebug() << "convert_attribute_cb: read '" << attr_name << "'\n"; 
+	auto pattr = H5Attribute::read(iter_data.locator_id, attr_name); 
+	if (pattr) 
+		iter_data.list.set_attribute(attr_name, pattr); 
+	
+	return 0; 
+}
+
+CAttributedData H5Base::read_attributes() const
+{
+	CAttributedData result; 
+	read_and_append_attributes(result); 
+	return result; 
+}
+
+void  H5Base::read_and_append_attributes(CAttributedData& target) const
+{
+	SIterateData id = {target, *this}; 
+	H5Aiterate2(*this, H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, NULL, convert_attribute_cb, &id);
+}
+
+H5Base::operator hid_t() const
+{
+	return m_handle; 
+}
+
+template <typename I> 
+static void check_id(hid_t id, const char *domain, const char *action, I info) 
+{
+	if (id < 0) {
+		throw create_exception<invalid_argument>(domain, ": error in ", action, ":", info);  
+	}
+}
+
+H5Property::H5Property(hid_t id):
+	H5Base(H5PropertyHandle(id))
+{
+}
+
+H5Property H5Property::create(hid_t cls)
+{
+	auto id = H5Pcreate(cls); 
+	check_id(id, "H5Property", "Create", cls); 
+	return H5Property(id); 
+}
+
+
+H5File::H5File(hid_t id):
+	H5Base(H5FileHandle(id))
+{
+}
+
+H5File H5File::create(const char *name, unsigned flags, hid_t  creation_prop, hid_t access_prop)
+{
+	return H5File(H5Fcreate(name, flags, creation_prop, access_prop)); 
+}
+	
+H5File H5File::open(const char *name, unsigned flags, hid_t access_prop)
+{
+	return H5File(H5Fopen(name, flags, access_prop)); 
+}
+
+
+H5Space::H5Space (hid_t id):
+	H5Base(H5SpaceHandle(id))
+{
+}
+	
+H5Space H5Space::create() 
+{
+	return H5Space(H5Screate(H5S_SCALAR)); 
+}
+
+H5Space H5Space::create(hsize_t dim1)
+{
+	auto id = H5Screate_simple(1, &dim1, NULL); 
+	check_id(id, "H5Space", "create_simple 1d", dim1);
+	return H5Space(id);
+}
+
+H5Space H5Space::create(unsigned rank, const hsize_t *dims)
+{
+	auto id = H5Screate_simple(rank, dims, NULL); 
+	check_id(id, "H5Space", "create_simple", rank);
+	return H5Space(id); 
+}
+
+H5Space H5Space::create(const std::vector<hsize_t>& dims)
+{
+	return create(dims.size(), &dims[0]); 
+}
+
+std::vector<hsize_t> H5Space::get_size() const
+{
+	int  dims = H5Sget_simple_extent_ndims(*this);
+	if (dims < 0) 
+		throw create_exception<runtime_error>("H5Dataset::get_size: error reading dimensions");
+	
+	vector <hsize_t> result(dims); 
+	if (dims > 0) {
+		auto status = H5Sget_simple_extent_dims(*this,  &result[0], NULL);
+		if (status < 0) 
+			throw create_exception<runtime_error>("H5Dataset::get_size: error reading dimensions");
+	}
+	return result; 
+}
+
+H5Group::H5Group (hid_t id):
+	H5Base(H5GroupHandle(id))
+{
+}
+
+
+struct SilenceH5Errors {
+	SilenceH5Errors();
+	~SilenceH5Errors(); 
+private:
+	H5E_auto2_t  old_func;
+	void *old_client_data;
+}; 
+
+SilenceH5Errors::SilenceH5Errors()
+{
+	H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data);
+	H5Eset_auto(H5E_DEFAULT, NULL, NULL); 
+}
+
+SilenceH5Errors::~SilenceH5Errors()
+{
+	H5Eset_auto(H5E_DEFAULT, old_func, old_client_data);
+}
+
+
+H5Base H5Group::open(const H5Base& parent, const std::string& name)
+{
+	
+	assert(name.find_last_of('/') == string::npos); 
+	auto id = H5Gopen(parent, name.c_str(), H5P_DEFAULT); 
+	assert(id >= 0); 
+	return H5Group(id); 
+}
+
+
+H5Base H5Group::create_or_open_hierarchy(const H5Base& parent, string& relative_name, bool create)
+{
+	H5Base pp = parent; 
+	// only deal with fully qualified names
+	assert(relative_name[0] == '/'); 
+
+	size_t last_slash = relative_name.find_last_of('/'); 
+	
+	// only root group required no need to do anything 
+	if (last_slash > 0)  {
+		SilenceH5Errors err; 
+		string base = relative_name.substr(0, last_slash); 
+		cvdebug() << "Base: " << base << "\n"; 
+		
+		relative_name = relative_name.substr(last_slash+1);
+		
+		stack<string> path; 
+		last_slash = base.find_last_of('/'); 
+		while (last_slash > 0)  {
+			auto tail = base.substr(last_slash+1); 
+
+			path.push(base.substr(last_slash+1)); 
+			base = base.substr(0, last_slash); 
+			cvdebug() << "tail:" << tail << " "
+				  << "base:" << base << "\n"; 
+			last_slash = base.find_last_of('/'); 
+		}
+		path.push(base.substr(1)); 
+		
+		
+		while (!path.empty()) {
+
+			auto name = path.top(); 
+			path.pop(); 
+
+			cvdebug() << "do group '" << name <<"'\n";
+			// it needs to be tested whether multiple slashes are to be merged
+			if (name.empty())
+				continue; 
+			auto id = H5Gopen(parent, name.c_str(), H5P_DEFAULT); 
+			if (id < 0 && create)
+				id = H5Gcreate(parent, name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); 
+			
+			H5Group p(id); 
+			p.set_parent(pp); 
+			pp = p; 
+		}
+	}
+	return pp; 
+}
+
+H5Type::H5Type (hid_t id):
+	H5Base(H5TypeHandle(id))
+{
+}
+
+H5Type H5Type::get_native_type() const
+{
+	auto id = H5Tget_native_type(*this, H5T_DIR_ASCEND);
+	if (id < 0) {
+		throw runtime_error("H5Type::get_native_type, Unable to deduct mem_type for reading data");
+	}
+	return H5Type(id); 
+}
+
+int H5Type::get_mia_type_id() const
+{
+	H5T_class_t cls =  H5Tget_class(*this); 
+	size_t size = H5Tget_size(*this); 
+
+	switch (cls) {
+	case H5T_INTEGER: 
+		switch (size) {
+		case 1: return 2 | H5Tget_sign(*this ); 
+		case 2: return 4 | H5Tget_sign(*this ); 
+		case 4: return 6 | H5Tget_sign(*this ); 
+		case 8: return 8 | H5Tget_sign(*this ); 			
+		default: 
+			return EAttributeType::attr_unknown;
+		}
+			
+	case H5T_FLOAT: 
+		if (size == 4) 
+			return EAttributeType::attr_float; 
+		else if (size == 8) 
+			return EAttributeType::attr_double; 
+		else 
+			return EAttributeType::attr_unknown;
+	case H5T_STRING:
+		return EAttributeType::attr_string; 
+		
+	case H5T_BITFIELD:
+		if (size == 1) 
+			return EAttributeType::attr_bool; 
+		else {
+			cvwarn() << "HDF5: bitfield type of size " << size << " not supported in MIA\n"; 
+		}
+	default: 
+		return do_get_mia_type_id(); 
+	}
+}
+
+int H5Type::do_get_mia_type_id() const
+{
+//	cvwarn() << "HDF5: type class " << cls << " of size " << size << " not supported in MIA\n";
+	return EAttributeType::attr_unknown;
+}
+
+H5Dataset::H5Dataset (hid_t id, const H5Space& space, const char *name):
+	H5Base(H5DatasetHandle(id)), 
+	m_space(space), 
+	m_name(name)
+{
+}
+
+
+static bool can_gzip() 
+{
+	if (!H5Zfilter_avail(H5Z_FILTER_DEFLATE)) 
+		return false; 
+
+	unsigned int filter_info; 
+	H5Zget_filter_info (H5Z_FILTER_DEFLATE, &filter_info);
+	
+	return ((filter_info & H5Z_FILTER_CONFIG_ENCODE_ENABLED) && 
+		(filter_info & H5Z_FILTER_CONFIG_DECODE_ENABLED)); 
+
+}
+
+H5Dataset H5Dataset::create(const H5Base& parent, const char *name, hid_t type_id, const H5Space& space)
+{
+	string relative_name(name); 
+	H5Base p = H5Group::create_or_open_hierarchy(parent, relative_name, true); 
+
+	hid_t id; 
+
+	if (can_gzip()) {
+		auto dcpl = H5Property::create (H5P_DATASET_CREATE);
+		auto status =  H5Pset_deflate (dcpl, 9);
+		if (status < 0) {
+			cvwarn() << "HDF5 gzip should be supported, but failed, store uncompressed\n"; 
+			id =  H5Dcreate(p, relative_name.c_str(), type_id, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+		}
+		// we compress the whole data in one chunk
+		auto chunk_size = space.get_size(); 
+		status = H5Pset_chunk (dcpl, chunk_size.size(), &chunk_size[0]);
+		id = H5Dcreate (p, relative_name.c_str(), type_id, space, H5P_DEFAULT, dcpl,
+				H5P_DEFAULT);
+		cvdebug() << "HDF5: Dataset '"<< name <<"' created with gzip compression enabled\n"; 
+	}else {
+		id =  H5Dcreate(p, relative_name.c_str(), type_id, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
+	}
+	
+	check_id(id, "H5Dataset", "create", relative_name);
+	H5Dataset set(id, space, name); 
+	set.set_parent(p);
+	return set;
+}
+
+H5Dataset H5Dataset::open(const H5Base& parent, const char *name)
+{
+	
+	string relative_name(name); 
+	H5Base p = parent; 
+	if (relative_name.find_last_of('/') != string::npos)
+		p = H5Group::create_or_open_hierarchy(parent, relative_name, false); 
+
+	auto id =  H5Dopen(p, relative_name.c_str(), H5P_DEFAULT);
+	check_id(id, "H5Dataset", "open", relative_name);
+
+	int space_id = H5Dget_space(id); 
+	check_id(space_id, "H5Dataset", "get space", name);
+	H5Space space(space_id); 
+	
+
+	H5Dataset set(id, space, name); 
+	set.set_parent(p);
+	return set;
+}
+
+void  H5Dataset::write( hid_t type_id, const void *data)
+{
+	auto err =  H5Dwrite(*this, type_id, m_space,  H5S_ALL, H5P_DEFAULT, data);
+	if (err < 0) {
+		throw create_exception<runtime_error>("H5Dataset::write: error writing data set '", m_name, "'"); 
+	}
+}
+
+void  H5Dataset::read( hid_t type_id, void *data) const 
+{
+	auto err =  H5Dread(*this, type_id, m_space,  H5S_ALL, H5P_DEFAULT, data);
+	if (err < 0) {
+		throw create_exception<runtime_error>("H5Dataset::read: error reading data set  '", m_name, "'"); 
+	}
+}
+
+vector <hsize_t> H5Dataset::get_size() const
+{
+	return m_space.get_size(); 
+}
+
+NS_MIA_END
diff --git a/addons/hdf5/hdf5mia.hh b/addons/hdf5/hdf5mia.hh
new file mode 100644
index 0000000..44563d6
--- /dev/null
+++ b/addons/hdf5/hdf5mia.hh
@@ -0,0 +1,317 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+/**
+   This file defines the helper classes needed to translate between HDF5 
+   and MIA data sets. 
+
+   This code is currently very messy. 
+
+   The H5 classes encapsulate the HDF5 C interface, because the C++ interface is not thread save, and therefore 
+   not installed in GNU/Debian. 
+
+*/
+
+#ifndef addons_hdf5_hdf5mia_hh
+#define addons_hdf5_hdf5mia_hh
+
+#include <mia/core/attributes.hh> 
+#include <mia/core/singular_refobj.hh> 
+#include <miaconfig.h> 
+#include <hdf5.h>
+
+
+#ifdef WIN32
+#ifdef hdf54mia_EXPORTS
+#define HDF54MIA_EXPORT __declspec(dllexport)
+#else
+#define HDF54MIA_EXPORT __declspec(dllimport)
+#endif
+#else
+#ifdef __GNUC__
+#    define HDF54MIA_EXPORT __attribute__((visibility("default")))
+#else 
+#    define HDF54MIA_EXPORT
+#endif
+#endif
+
+NS_MIA_BEGIN
+
+/**
+   This is the excapsulation of the basic HDF5 handle id. All handles need to be 
+   freed with H5Xclose, but it is not well documented whether the handles are 
+   ref-counted internally. Therefore, we ref-count each created handle, reference 
+   its parent, and destroy it only if noone is referencing it anymore. 
+   On top of that 'X' is different for each type of HDF5 object which makes it necessary to 
+   keep the specific close function with the handle. On top of  that there are default 
+   handles that don't need to be destroyed with makes the  whole thing a bit inconsistent, 
+   i.e. sometimes the here defined intefaces accept plain HDF5 types and sometimes the 
+   wrapper is needed. However, the wrapper also provides an automatic conversion to the handle type. 
+*/
+struct HDF54MIA_EXPORT H5Handle: public  TSingleReferencedObject<hid_t> {
+	H5Handle() = default; 
+	H5Handle(hid_t hid, const Destructor& d); 
+	void set_parent(const H5Handle& parent); 
+
+private: 
+	TSingleReferencedObject<hid_t> m_parent;
+}; 
+
+struct HDF54MIA_EXPORT H5SpaceHandle: public H5Handle {
+        H5SpaceHandle(hid_t hid);
+};
+
+struct HDF54MIA_EXPORT H5TypeHandle: public H5Handle {
+        H5TypeHandle(hid_t hid);
+};
+
+
+struct HDF54MIA_EXPORT H5GroupHandle: public H5Handle {
+        H5GroupHandle(hid_t hid);
+};
+
+struct HDF54MIA_EXPORT H5DatasetHandle: public H5Handle {
+        H5DatasetHandle(hid_t hid);
+};
+
+struct HDF54MIA_EXPORT H5AttributeHandle: public H5Handle {
+        H5AttributeHandle(hid_t hid);
+};
+
+struct HDF54MIA_EXPORT H5FileHandle: public H5Handle {
+        H5FileHandle(hid_t hid);
+};
+
+struct HDF54MIA_EXPORT H5PropertyHandle: public H5Handle {
+        H5PropertyHandle(hid_t hid);
+};
+
+
+class HDF54MIA_EXPORT H5Base {
+protected: 
+	H5Base(const H5Handle& handle); 
+public:
+	H5Base() = default; 
+	void set_parent(const H5Base& parent); 
+
+	const H5Handle& get_handle() const;
+	
+	operator hid_t() const; 
+	
+	CAttributedData read_attributes() const; 
+
+	void  read_and_append_attributes(CAttributedData& target) const; 
+private: 
+	H5Handle m_handle; 
+}; 
+
+
+class HDF54MIA_EXPORT H5Property: public H5Base {
+	H5Property (hid_t id); 
+public: 
+	H5Property() = default; 
+	static H5Property create(hid_t cls);
+}; 
+
+
+class HDF54MIA_EXPORT H5File: public H5Base {
+	H5File(hid_t id); 
+public: 
+	H5File() = default; 
+	
+	static H5File create(const char *name, unsigned flags, hid_t creation_prop, hid_t access_prop);
+	static H5File open(const char *name, unsigned flags, hid_t access_prop);
+}; 
+
+class HDF54MIA_EXPORT H5Space: public H5Base {
+public: 
+	explicit H5Space (hid_t id); 
+	H5Space() = default; 
+	static H5Space create();
+	static H5Space create(hsize_t dim1);
+	static H5Space create(unsigned rank, const hsize_t *dims);
+	static H5Space create(const std::vector<hsize_t>& dims);
+	
+	std::vector<hsize_t> get_size() const; 
+}; 
+
+class HDF54MIA_EXPORT H5Group: public H5Base {
+public: 
+	explicit H5Group (hid_t id); 
+	H5Group() = default;
+	static H5Base create_or_open_hierarchy(const H5Base& parent, std::string& relative_name, bool create); 
+
+	static H5Base open(const H5Base& parent, const std::string& relative_name); 
+}; 
+
+
+class HDF54MIA_EXPORT H5Type: public H5Base {
+public: 
+	explicit H5Type (hid_t id); 
+	H5Type() = default; 
+	
+	H5Type get_native_type() const;
+
+	int get_mia_type_id() const; 
+private:
+	int do_get_mia_type_id() const;
+}; 
+
+class HDF54MIA_EXPORT H5Dataset: public H5Base {
+	H5Dataset (hid_t id, const H5Space& space, const char *name); 
+public: 
+	H5Dataset() = default; 
+	static H5Dataset create(const H5Base& parent, const char *name, hid_t type_id, const H5Space& space);
+
+	static H5Dataset open(const H5Base& parent, const char *name);
+
+	template <typename Iterator> 
+	void  write(Iterator begin, Iterator end);
+	
+	template <typename Iterator> 
+	void  read(Iterator begin, Iterator end) const;
+
+	std::vector <hsize_t> get_size() const; 
+	
+private: 
+
+	template <typename Iterator, typename T> 
+	friend struct __dispatch_h5dataset_rw; 
+	
+	void  write( hid_t type_id, const void *data);
+	void  read( hid_t type_id, void *data) const;
+
+	H5Space m_space; 
+	std::string m_name; 
+}; 
+
+
+
+template <typename T>
+struct Mia_to_h5_types {
+        static hid_t file_datatype() {
+		static_assert(sizeof(T) == 0, "Mia_to_h5_types needs to be specialized for T"); 
+		return -1; 
+	}
+        static hid_t mem_datatype(){
+		static_assert(sizeof(T) == 0, "Mia_to_h5_types needs to be specialized for T"); 
+		return -1; 
+	}
+};
+
+#define MIA_TO_H5_TYPE(T, FILE_TYPE, MEM_TYPE)                          \
+        template <>                                                     \
+        struct Mia_to_h5_types<T> {                                     \
+		static hid_t file_datatype(){ return FILE_TYPE;}	\
+                static hid_t mem_datatype(){ return MEM_TYPE;}		\
+        };                                                              \
+
+MIA_TO_H5_TYPE(bool,           H5T_STD_B8LE, H5T_NATIVE_B8); 
+MIA_TO_H5_TYPE(signed char,    H5T_STD_I8LE, H5T_NATIVE_SCHAR); 
+MIA_TO_H5_TYPE(unsigned char,  H5T_STD_U8LE, H5T_NATIVE_UCHAR); 
+MIA_TO_H5_TYPE(signed short,   H5T_STD_I16LE, H5T_NATIVE_SHORT); 
+MIA_TO_H5_TYPE(unsigned short, H5T_STD_U16LE, H5T_NATIVE_USHORT); 
+MIA_TO_H5_TYPE(signed int,     H5T_STD_I32LE, H5T_NATIVE_INT); 
+MIA_TO_H5_TYPE(unsigned int,   H5T_STD_U32LE, H5T_NATIVE_UINT); 
+#ifdef LONG_64BIT
+MIA_TO_H5_TYPE(signed long,   H5T_STD_I64LE, H5T_NATIVE_LONG); 
+MIA_TO_H5_TYPE(unsigned long, H5T_STD_U64LE, H5T_NATIVE_ULONG); 
+#endif        
+MIA_TO_H5_TYPE(float,  H5T_IEEE_F32LE,  H5T_NATIVE_FLOAT); 
+MIA_TO_H5_TYPE(double, H5T_IEEE_F64LE,  H5T_NATIVE_DOUBLE);
+
+#undef MIA_TO_H5_TYPE
+
+template <typename T>
+struct Mia_to_h5_types<std::vector<T>>  {
+        static hid_t file_datatype() {
+		return Mia_to_h5_types<T>::file_datatype(); 
+	}
+        static hid_t mem_datatype(){
+		return Mia_to_h5_types<T>::mem_datatype(); 
+	}
+};
+
+
+template <typename Image> 
+typename Image::Pointer read_image(typename Image::dimsize_type& size, const H5Dataset& dataset)
+{
+//	typedef typename Image::dimsize_type Bounds; 
+//	typedef typename Image::value_type value_type; 
+
+	Image *result = new Image(size); 
+	typename Image::Pointer presult(result); 
+	
+	dataset.read_and_append_attributes(*result);
+	dataset.read(result->begin(), result->end());
+	
+	return presult; 
+}
+
+template <typename Iterator, typename T> 
+struct __dispatch_h5dataset_rw {
+	static void apply_write(H5Dataset& id, Iterator begin, Iterator MIA_PARAM_UNUSED(end)) {
+		TRACE_FUNCTION; 
+		id.write(Mia_to_h5_types<T>::mem_datatype(), &begin[0]); 
+	}
+	static void apply_read(const H5Dataset& id, Iterator begin, Iterator MIA_PARAM_UNUSED(end)) {
+		TRACE_FUNCTION; 
+		id.read(Mia_to_h5_types<T>::mem_datatype(), &begin[0]); 
+	}
+}; 
+
+template <typename Iterator> 
+struct __dispatch_h5dataset_rw<Iterator, bool> {
+	static void apply_write(H5Dataset& id, Iterator begin, Iterator end) {
+		TRACE_FUNCTION; 
+		std::vector<char> help(std::distance( begin, end)); 
+		copy(begin, end, help.begin()); 
+		id.write(Mia_to_h5_types<bool>::mem_datatype(), &help[0]); 
+		
+	}
+	static void apply_read(const H5Dataset& id, Iterator begin, Iterator end) {
+		TRACE_FUNCTION; 
+		std::vector<char> help(std::distance(begin, end)); 
+		id.read(Mia_to_h5_types<bool>::mem_datatype(), &help[0]); 
+		copy(help.begin(), help.end(), begin);
+	}
+}; 
+
+
+template <typename Iterator> 
+void  H5Dataset::write(Iterator begin, Iterator end)
+{
+	typedef __dispatch_h5dataset_rw<Iterator, typename Iterator::value_type> h5dataset_rw; 
+	h5dataset_rw::apply_write(*this, begin, end); 
+}
+
+template <typename Iterator> 
+void  H5Dataset::read(Iterator begin, Iterator end)const
+{
+	typedef __dispatch_h5dataset_rw<Iterator, typename Iterator::value_type> h5dataset_rw; 
+	h5dataset_rw::apply_read(*this, begin, end); 
+}
+
+
+
+NS_MIA_END
+
+#endif 
diff --git a/addons/hdf5/test_hdf5_3dimage.cc b/addons/hdf5/test_hdf5_3dimage.cc
new file mode 100644
index 0000000..e00e373
--- /dev/null
+++ b/addons/hdf5/test_hdf5_3dimage.cc
@@ -0,0 +1,118 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#define VSTREAM_DOMAIN "test-HDF5-3dimage"
+#include <mia/internal/autotest.hh>
+
+#include <boost/mpl/vector.hpp>
+#include <boost/test/test_case_template.hpp>
+
+#include <addons/hdf5/hdf5_3dimage.hh>
+
+using namespace std; 
+using namespace mia; 
+using namespace hdf5_3dimage; 
+
+template <typename T> 
+struct __fill_image {
+	static void apply(T3DImage<T>& image) {
+		int v = 1; 
+		for (auto i = image.begin(); i != image.end(); ++i) 
+			*i = v++; 
+	}
+}; 
+
+template <> 
+struct __fill_image<bool> {
+	static void apply(C3DBitImage& image) {
+		bool v = false; 
+		for (auto i = image.begin(); i != image.end(); ++i) {
+			*i = v; 
+			v = !v; 
+		}
+	}
+}; 
+
+
+typedef boost::mpl::vector<
+	bool, 
+	signed char,  
+	unsigned char,
+	signed short,
+	unsigned short,
+	signed int,
+	unsigned int,
+#ifdef LONG_64BIT
+	signed long, 
+	unsigned long, 
+#endif
+	float,
+	double
+	> test_pixeltypes;
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE( test_simple_write_read, T, test_pixeltypes ) 
+{
+	C3DBounds size (2,3,4); 
+	T3DImage<T> *image = new T3DImage<T>(size); 
+	image->set_attribute("int", PAttribute(new CIntAttribute(2))); 
+	const C3DFVector voxel_size(2,2.5,2.5); 
+	image->set_voxel_size(voxel_size); 
+
+	__fill_image<T>::apply(*image); 
+	
+	CHDF53DImageIOPlugin io; 
+        CHDF53DImageIOPlugin::Data images;
+        images.push_back(P3DImage(image)); 
+	
+	stringstream filename; 
+	filename << "testimage-" << __type_descr<T>::value << ".h5"; 
+
+	cvdebug() << "test with " << filename.str() << "\n"; 
+
+	BOOST_REQUIRE(io.save(filename.str(), images)); 
+	
+	auto loaded = io.load(filename.str()); 
+	BOOST_REQUIRE(loaded); 
+	
+	BOOST_REQUIRE(loaded->size() == 1u); 
+        const auto& ploaded = dynamic_cast<const T3DImage<T>&>(*(*loaded)[0]); 	
+	auto iv = image->begin(); 
+	auto ev = image->end(); 
+
+
+	auto il = ploaded.begin(); 
+	
+	while (iv != ev) {
+		BOOST_CHECK_EQUAL(*il, *iv); 
+		++iv; 
+		++il; 
+	}
+	BOOST_CHECK_EQUAL(ploaded.get_voxel_size(), voxel_size); 
+	
+	auto int_attr = ploaded.template get_attribute_as<int>("int"); 
+	BOOST_CHECK_EQUAL(int_attr, 2); 
+
+        unlink(filename.str().c_str()); 
+
+}
+
+
diff --git a/addons/hdf5/test_hdf5mia.cc b/addons/hdf5/test_hdf5mia.cc
new file mode 100644
index 0000000..04989e0
--- /dev/null
+++ b/addons/hdf5/test_hdf5mia.cc
@@ -0,0 +1,371 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define VSTREAM_DOMAIN "test-HDF5MIA"
+
+#include <mia/internal/autotest.hh>
+
+#include <boost/mpl/vector.hpp>
+#include <boost/test/test_case_template.hpp>
+#include <boost/mpl/insert_range.hpp>
+
+#include <addons/hdf5/hdf5a_mia.hh> 
+
+NS_MIA_USE
+using namespace std;
+
+typedef boost::mpl::vector<signed char,
+			   unsigned char,
+			   signed short,
+			   unsigned short,
+			   signed int,
+			   unsigned int,
+#ifdef LONG_64BIT
+			   signed long,
+			   unsigned long,
+#endif
+			   float,
+			   double
+			   > test_pixel_types;
+
+
+class HDF5CoreFileFixture {
+	
+protected: 
+	HDF5CoreFileFixture(); 
+	~HDF5CoreFileFixture(); 
+
+	const H5File& get_file() const;
+private: 
+	H5Property access_plist;
+	H5File  m_core_file; 
+
+}; 
+
+
+
+HDF5CoreFileFixture::HDF5CoreFileFixture()
+{
+	access_plist = H5Property::create(H5P_FILE_ACCESS);
+	H5Pset_fapl_core (access_plist, 1024, 0); 
+
+	m_core_file = H5File::create("core.h5", H5F_ACC_TRUNC, H5P_DEFAULT, access_plist); 
+}
+
+HDF5CoreFileFixture::~HDF5CoreFileFixture()
+{
+	
+	
+}
+
+
+const H5File& HDF5CoreFileFixture::get_file() const
+{
+	return m_core_file; 
+}
+
+
+
+
+BOOST_FIXTURE_TEST_CASE(test_core_hdf5_io_driver,  HDF5CoreFileFixture)
+{
+	
+}
+
+BOOST_FIXTURE_TEST_CASE(test_simple_dataset,  HDF5CoreFileFixture)
+{
+	hsize_t dims[2] = {2,3}; 
+	vector<int> data = {1,2,3,4,5,6}; 
+	auto mem_type_in = Mia_to_h5_types<int>::mem_datatype(); 
+
+	// write the data set 
+	{
+		
+		auto file_type = Mia_to_h5_types<int>::file_datatype(); 
+
+		
+		auto space = H5Space::create(2, dims); 
+		auto dataset = H5Dataset::create(get_file(), "/testset", file_type, space);
+		
+		dataset.write(data.begin(), data.end());
+	}
+	// close data set automatically, and now reopen it 
+	{
+		auto dataset = H5Dataset::open(get_file(), "/testset");
+		auto size = dataset.get_size(); 
+		BOOST_CHECK_EQUAL(size.size(), 2u); 
+		BOOST_CHECK_EQUAL(size[0],2u);
+		BOOST_CHECK_EQUAL(size[1],3u); 
+
+		H5Type file_type(H5Dget_type(dataset)); 
+		H5Type mem_type = file_type.get_native_type(); 
+
+		BOOST_CHECK(H5Tequal( mem_type, mem_type_in ) > 0); 
+
+		vector<int> read_data(6);
+		
+		dataset.read(read_data.begin(), read_data.end()); 
+
+		for (int i = 0; i < 6; ++i)
+			BOOST_CHECK_EQUAL(read_data[i], data[i]); 
+	}
+	
+}
+
+
+BOOST_FIXTURE_TEST_CASE(test_bool_dataset,  HDF5CoreFileFixture)
+{
+	hsize_t dims[2] = {2,3}; 
+	vector<bool> data {false, true, true, false, false, true}; 
+	auto mem_type_in = Mia_to_h5_types<bool>::mem_datatype(); 
+
+	// write the data set 
+	{
+		
+		auto file_type = Mia_to_h5_types<bool>::file_datatype(); 
+
+		
+		auto space = H5Space::create(2, dims); 
+		auto dataset = H5Dataset::create(get_file(), "/testset", file_type, space);
+		
+		dataset.write(data.begin(), data.end());
+	}
+	// close data set automatically, and now reopen it 
+	{
+		auto dataset = H5Dataset::open(get_file(), "/testset");
+		auto size = dataset.get_size(); 
+		BOOST_CHECK_EQUAL(size.size(), 2u); 
+		BOOST_CHECK_EQUAL(size[0],2u);
+		BOOST_CHECK_EQUAL(size[1],3u); 
+
+		H5Type file_type(H5Dget_type(dataset)); 
+		H5Type mem_type = file_type.get_native_type(); 
+
+		BOOST_CHECK(H5Tequal( mem_type, mem_type_in ) > 0); 
+
+		vector<bool> read_data(6); 
+		
+		dataset.read(read_data.begin(), read_data.end()); 
+
+		for (int i = 0; i < 6; ++i)
+			BOOST_CHECK_EQUAL(read_data[i], data[i]); 
+	}
+	
+}
+
+template <typename T> 
+class TestDatasetFixture : public HDF5CoreFileFixture {
+	
+protected:
+	void test(const string& path, const std::vector<hsize_t>& size, const std::vector<T>& data); 
+private: 
+	void save(const string& path, const std::vector<hsize_t>& size, const std::vector<T>& data); 
+	void read_and_test(const string& path, const std::vector<hsize_t>& test_size, const std::vector<T>& test_data); 
+
+}; 
+
+template <typename T> 
+void TestDatasetFixture<T>::test(const string& path, const std::vector<hsize_t>& size, const std::vector<T>& data)
+{
+	save(path, size, data); 
+	read_and_test(path, size, data);
+}
+
+
+template <typename T> 
+void TestDatasetFixture<T>::save(const string& path, const std::vector<hsize_t>& size, const std::vector<T>& data)
+{
+	auto file_type = Mia_to_h5_types<T>::file_datatype(); 
+	
+	
+	auto space = H5Space::create(size); 
+	auto dataset = H5Dataset::create(get_file(), path.c_str(), file_type, space);
+	dataset.write(data.begin(), data.end());
+}
+
+template <typename T> 
+void TestDatasetFixture<T>::read_and_test(const string& path, const std::vector<hsize_t>& test_size, 
+					  const std::vector<T>& test_data)
+{
+	auto dataset = H5Dataset::open(get_file(), path.c_str());
+	auto size = dataset.get_size(); 
+	BOOST_CHECK_EQUAL(size.size(), test_size.size()); 
+	BOOST_REQUIRE(size.size()== test_size.size()); 
+
+	size_t length = 1; 
+	for (size_t i = 0; i < size.size(); ++i) {
+		BOOST_CHECK_EQUAL(size[i],test_size[i]);
+		length *= test_size[i]; 
+	}
+	
+	H5Type file_type(H5Dget_type(dataset)); 
+	H5Type mem_type = file_type.get_native_type(); 
+
+	BOOST_REQUIRE(H5Tequal( mem_type, Mia_to_h5_types<T>::mem_datatype() ) > 0); 
+	
+	std::vector<T> read_data(length); 
+	
+	dataset.read(read_data.begin(), read_data.end()); 
+		
+	for (size_t i = 0; i < length; ++i)
+		BOOST_CHECK_EQUAL(read_data[i], test_data[i]); 
+}
+
+template <typename T> 
+class TestDatasetIOInGroupFixture : public TestDatasetFixture<T> {
+public:
+	void run(); 
+
+}; 
+
+
+template <typename T> 
+void TestDatasetIOInGroupFixture<T>::run() 
+{
+	vector<hsize_t> dims = {2,3}; 
+	vector<T>  data = {1,2,3,4,5,6}; 
+	const char path[] = "/group1/group2/testset"; 
+	this->test(path, dims, data); 
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE( test_dataset_io, T , test_pixel_types )
+{
+	TestDatasetIOInGroupFixture<T>().run(); 
+}
+
+
+template <typename T>
+class TestAttrfixture : public HDF5CoreFileFixture {
+public: 
+	void run(); 
+}; 
+
+template <typename T>
+void TestAttrfixture<T>::run() 
+{
+	const T value = 10; 
+	PAttribute attr(new TAttribute<T>(value));
+	auto h5attr = H5AttributeTranslatorMap::instance().translate(get_file(), "attr", *attr); 
+
+	auto pattr = H5AttributeTranslatorMap::instance().translate("attr", h5attr); 
+	int test_type = attribute_type<T>::value; 
+	BOOST_CHECK_EQUAL(pattr->type_id(), test_type); 
+
+	auto& rattr = dynamic_cast<const TAttribute<T>&>(*pattr); 
+	
+	BOOST_CHECK_EQUAL(rattr, value); 
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE( test_attributes , T , test_pixel_types )
+{
+	TestAttrfixture<T>().run(); 
+}
+
+
+
+template <typename T>
+class TestVectorAttrfixture : public HDF5CoreFileFixture {
+public: 
+	void run(); 
+}; 
+
+template <typename T>
+void TestVectorAttrfixture<T>::run() 
+{
+	const vector<T> value = {10, 20, 30}; 
+	PAttribute attr(new TAttribute<vector<T>>(value));
+	auto h5attr = H5AttributeTranslatorMap::instance().translate(get_file(), "attr", *attr); 
+
+	auto pattr = H5AttributeTranslatorMap::instance().translate("attr", h5attr); 
+	int test_type = attribute_type<vector<T>>::value; 
+	BOOST_CHECK_EQUAL(pattr->type_id(), test_type); 
+
+	auto& rattr = dynamic_cast<const TAttribute<vector<T>>&>(*pattr); 
+	const vector<T> rvalue = rattr; 
+
+	BOOST_CHECK_EQUAL(rvalue.size(), value.size()); 
+	BOOST_REQUIRE(rvalue.size() == value.size()); 
+	for (auto r = rvalue.begin(), v = value.begin(); r != rvalue.end(); ++r, ++v){
+		BOOST_CHECK_EQUAL(*r, *v); 
+	}
+}
+
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE( test_vector_attributes , T , test_pixel_types )
+{
+	TestVectorAttrfixture<T>().run(); 
+}
+
+
+BOOST_FIXTURE_TEST_CASE (test_string_attribute, HDF5CoreFileFixture) 
+{
+	string value("a test string"); 
+	PAttribute attr(new TAttribute<string>(value));
+	
+	auto h5attr = H5AttributeTranslatorMap::instance().translate(get_file(), "attr", *attr); 
+
+	auto pattr = H5AttributeTranslatorMap::instance().translate("attr", h5attr); 
+	BOOST_REQUIRE(pattr); 
+
+	int test_type = attribute_type<string>::value; 
+	BOOST_CHECK_EQUAL(pattr->type_id(), test_type);
+	
+	auto& rattr = dynamic_cast<const TAttribute<string>&>(*pattr); 
+	const string rvalue = rattr; 
+	BOOST_CHECK_EQUAL(rvalue, value); 
+}; 
+
+BOOST_FIXTURE_TEST_CASE (test_vstring_attribute, HDF5CoreFileFixture) 
+{
+	const vector<string> value= {"a test string", "another test string"}; 
+	PAttribute attr(new TAttribute<vector<string>>(value));
+	
+	auto h5attr = H5AttributeTranslatorMap::instance().translate(get_file(), "attr", *attr); 
+
+	auto pattr = H5AttributeTranslatorMap::instance().translate("attr", h5attr); 
+	BOOST_REQUIRE(pattr); 
+
+	int test_type = attribute_type<vector<string>>::value; 
+	BOOST_CHECK_EQUAL(pattr->type_id(), test_type);
+	
+	auto& rattr = dynamic_cast<const TAttribute<vector<string>>&>(*pattr); 
+	const vector<string> rvalue = rattr; 
+	BOOST_CHECK_EQUAL(rvalue.size(), value.size());
+	
+	for (auto r = rvalue.begin(), v = value.begin(); r != rvalue.end(); ++r, ++v){
+		BOOST_CHECK_EQUAL(*r, *v); 
+	}
+}; 
+
+BOOST_FIXTURE_TEST_CASE (test_attribute_list, HDF5CoreFileFixture) 
+{
+	CAttributedData original_data; 
+
+	original_data.set_attribute("string", PAttribute(new CStringAttribute("some string"))); 
+	original_data.set_attribute("int", PAttribute(new CIntAttribute(10))); 
+	original_data.set_attribute("vfloat", PAttribute(new CVFloatAttribute({1.0, 2.3, 3.4}))); 
+
+	translate_to_hdf5_attributes(get_file(), original_data); 
+	
+	CAttributedData loaded_data = get_file().read_attributes(); 
+	
+	BOOST_CHECK_EQUAL(loaded_data, original_data); 
+}
diff --git a/addons/jpg/CMakeLists.txt b/addons/jpg/CMakeLists.txt
index 016bad2..81da4af 100644
--- a/addons/jpg/CMakeLists.txt
+++ b/addons/jpg/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/addons/jpg/jpg-gray.cc b/addons/jpg/jpg-gray.cc
index becf71c..1e93d60 100644
--- a/addons/jpg/jpg-gray.cc
+++ b/addons/jpg/jpg-gray.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/jpg/jpg-rgb.cc b/addons/jpg/jpg-rgb.cc
index ea4834c..9efae2a 100644
--- a/addons/jpg/jpg-rgb.cc
+++ b/addons/jpg/jpg-rgb.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/nifti/CMakeLists.txt b/addons/nifti/CMakeLists.txt
new file mode 100644
index 0000000..7ea8dfd
--- /dev/null
+++ b/addons/nifti/CMakeLists.txt
@@ -0,0 +1,68 @@
+#
+# This file is part of MIA - a toolbox for medical image analysis 
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+#
+# MIA is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+
+OPTION(USE_NIFTI "Use nifti-1 3D image file format" TRUE)
+
+IF (USE_NIFTI)
+  SET(NIFTI_FOUND FALSE)
+  
+  # zlib is required for nifti to function 
+  FIND_PACKAGE(ZLIB)
+  IF(ZLIB_FOUND) 
+    # check that nifti header is available 
+    FIND_PATH( NIFTI_INCLUDE_DIR nifti1_io.h
+      /usr/include 
+      /usr/include/nifti
+      /usr/local/include
+      /usr/local/include/nifti 
+      )
+    
+    FIND_LIBRARY(NIFTIIO_LIBRARY
+      NAMES
+      niftiio 
+      ) 
+
+    FIND_LIBRARY(NIFTIZNZ_LIBRARY
+      NAMES
+      znz 
+      ) 
+    IF( NIFTIIO_LIBRARY AND NIFTIZNZ_LIBRARY AND NIFTI_INCLUDE_DIR) 
+      SET(NIFTI_FOUND TRUE)
+      SET(NIFTIIO_LIBRARIES 
+        ${NIFTIIO_LIBRARY}
+        ${NIFTIZNZ_LIBRARY}
+        ${LIBZ_LIBRARIES}
+        m)
+    ENDIF()
+    
+  ENDIF(ZLIB_FOUND) 
+      
+
+
+  if (NOT NIFTI_FOUND AND STRICT_DEPENDECIES)
+    MESSAGE(FATAL_ERROR "NIFTI includes and or libraries not found and strict dependencies enabled")
+  endif (NOT NIFTI_FOUND AND STRICT_DEPENDECIES)
+
+  INCLUDE_DIRECTORIES(${NIFTI_INCLUDE_DIR})
+  INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
+
+  SET(imageio_path "${PLUGIN_INSTALL_PATH}/3dimage/io")
+  SET(NIFTI_LINK_LIBS_3D ${NIFTIIO_LIBRARIES} mia3d)
+  PLUGIN_WITH_TEST_AND_PREFIX2("3dimage" "io" niftiimage "${NIFTI_LINK_LIBS_3D}")
+  
+ENDIF (USE_NIFTI)
diff --git a/addons/nifti/niftiimage.cc b/addons/nifti/niftiimage.cc
new file mode 100644
index 0000000..41213cb
--- /dev/null
+++ b/addons/nifti/niftiimage.cc
@@ -0,0 +1,440 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <addons/nifti/niftiimage.hh>
+#include <nifti1_io.h>
+
+
+using namespace mia; 
+using namespace std; 
+
+NS_BEGIN(niftiimage)
+
+static const char *AttrID_nifti_sform = "nifti-sform"; 
+static const char *AttrID_nifti_sform_code = "nifti-sform-code"; 
+static const char *AttrID_nifti_qform_code = "nifti-qform-code"; 
+static const char *AttrID_nifti_intent_code = "nifti-intent-code"; 
+static const char *AttrID_nifti_intent_name = "nifti-intent-name"; 
+static const char *AttrID_nifti_intent_p1 = "nifti-intent_p1"; 
+static const char *AttrID_nifti_intent_p2 = "nifti-intent_p2"; 
+static const char *AttrID_nifti_intent_p3 = "nifti-intent_p3"; 
+
+static const char *AttrID_nifti_toffset = "nifti-toffset";       // float 
+static const char *AttrID_nifti_xyz_units = "nifti-xyz_units";   // int 
+static const char *AttrID_nifti_time_units = "nifti-time_units"; // int 
+
+
+CNifti3DImageIOPlugin::CNifti3DImageIOPlugin():
+C3DImageIOPlugin("nifti")
+{
+        add_supported_type(it_sbyte);
+	add_supported_type(it_ubyte);
+	add_supported_type(it_sshort);
+	add_supported_type(it_ushort);
+	add_supported_type(it_sint);
+	add_supported_type(it_uint);
+
+#ifdef LONG_64BIT
+	add_supported_type(it_slong);
+	add_supported_type(it_ulong);
+#endif 
+
+	add_supported_type(it_float);
+	add_supported_type(it_double);
+
+	add_suffix(".nii");
+	add_suffix(".NII");
+
+        CVFloatTranslator::register_for(AttrID_nifti_sform); 
+        CSSTranslator::register_for(AttrID_nifti_sform_code); 
+        CSSTranslator::register_for(AttrID_nifti_qform_code);
+        CSSTranslator::register_for(AttrID_nifti_intent_code); 
+	
+	CFloatTranslator::register_for("nifti-intent_p1"); 
+	CFloatTranslator::register_for("nifti-intent_p2"); 
+	CFloatTranslator::register_for("nifti-intent_p3"); 
+
+        CFloatTranslator::register_for(AttrID_nifti_toffset); 
+	CSITranslator::register_for(AttrID_nifti_xyz_units);
+	CSITranslator::register_for(AttrID_nifti_time_units);
+
+}
+
+struct NiftiDeallocator {
+	void operator () (nifti_image *image) {
+		nifti_image_free(image); 
+	}
+}; 
+
+void copy_attributes(C3DImage& image, const nifti_image& ni)
+{
+        // set position and orientation 
+        if (ni.qform_code == 0) { // method 1
+                image.set_orientation(ior_default);
+                image.set_voxel_size(C3DFVector(ni.dx,  ni.dy, ni.dz)); 
+        } else { // Method 2 
+                image.set_orientation(ni.qfac == 1 ? ior_xyz : ior_xyz_flipped);
+                image.set_voxel_size(C3DFVector(ni.dx,  ni.dy, ni.dz)); 
+                image.set_origin(C3DFVector(ni.qoffset_x, ni.qoffset_y, ni.qoffset_z)); 
+                double qa = sqrt(1.0 - (ni.quatern_b * ni.quatern_b + 
+                                        ni.quatern_c * ni.quatern_c + 
+                                        ni.quatern_d * ni.quatern_d)); 
+                image.set_rotation(Quaternion(qa, ni.quatern_b, ni.quatern_c, ni.quatern_d));
+                image.set_attribute(AttrID_nifti_qform_code, ni.qform_code); 
+        }
+        
+        if (ni.sform_code > 0) { // method 3
+                vector<float> am = {ni.sto_xyz.m[0][0], ni.sto_xyz.m[0][1], ni.sto_xyz.m[0][2], ni.sto_xyz.m[0][3], 
+                                     ni.sto_xyz.m[1][0], ni.sto_xyz.m[1][1], ni.sto_xyz.m[1][2], ni.sto_xyz.m[1][3],
+                                     ni.sto_xyz.m[2][0], ni.sto_xyz.m[2][1], ni.sto_xyz.m[2][2], ni.sto_xyz.m[2][3],
+                                     ni.sto_xyz.m[3][0], ni.sto_xyz.m[3][1], ni.sto_xyz.m[3][2], ni.sto_xyz.m[3][3]}; 
+                
+                image.set_attribute(AttrID_nifti_sform, am);
+                image.set_attribute(AttrID_nifti_sform_code, ni.sform_code); 
+        }
+        
+
+	image.set_attribute(AttrID_nifti_toffset, ni.toffset);
+	image.set_attribute(AttrID_nifti_xyz_units, ni.xyz_units);
+	image.set_attribute(AttrID_nifti_time_units, ni.time_units);
+	image.set_attribute(AttrID_nifti_intent_code, ni.intent_code);
+	image.set_attribute(AttrID_nifti_intent_p1, ni.intent_p1);
+	image.set_attribute(AttrID_nifti_intent_p2, ni.intent_p2);
+	image.set_attribute(AttrID_nifti_intent_p3, ni.intent_p3);
+	image.set_attribute(AttrID_nifti_intent_name, string(ni.intent_name)); 
+}
+
+
+template <typename Image> 
+CNifti3DImageIOPlugin::PData read_images(const C3DBounds& size, const nifti_image& ni)
+{
+        int timesteps = 1; 
+	if (ni.ndim == 4) 
+		timesteps = ni.nt; 
+
+	CNifti3DImageIOPlugin::PData result(new C3DImageVector); 
+	result->reserve(timesteps); 
+	
+	typedef typename Image::value_type TInPixel;
+	const TInPixel *in_data = reinterpret_cast<const TInPixel *>(ni.data);
+	
+	size_t stride = size.product(); 
+	for (int i = 0; i < timesteps; ++i, in_data += stride) {
+		Image *img = new Image(size); 
+                copy_attributes(*img, ni); 
+		copy(in_data, in_data + img->size(), img->begin()); 
+		result->push_back(P3DImage(img)); 
+	}
+	return result; 
+        
+}
+
+template <typename OutImage, typename InPixel> 
+CNifti3DImageIOPlugin::PData read_images(const C3DBounds& size, const nifti_image& ni)
+{
+        int timesteps = 1; 
+	if (ni.ndim == 4) 
+		timesteps = ni.nt; 
+
+	CNifti3DImageIOPlugin::PData result(new C3DImageVector); 
+	result->reserve(timesteps); 
+	
+	const InPixel *in_data = reinterpret_cast<const InPixel *>(ni.data);
+	
+	size_t stride = size.product(); 
+        
+        const double scale = ni.scl_slope; 
+        const double shift = ni.scl_inter; 
+        
+	for (int i = 0; i < timesteps; ++i, in_data += stride) {
+		auto *img = new OutImage(size); 
+                copy_attributes(*img, ni); 
+		transform(in_data, in_data + img->size(), img->begin(), 
+                          [scale, shift](InPixel x){return scale * x + shift;}); 
+		result->push_back(P3DImage(img)); 
+	}
+	return result; 
+        
+}
+
+CNifti3DImageIOPlugin::PData CNifti3DImageIOPlugin::do_load(const std::string&  filename) const
+{
+        if (!is_nifti_file(filename.c_str()))
+		return PData();
+
+	unique_ptr<nifti_image, NiftiDeallocator> image(nifti_image_read(filename.c_str(), 1)); 
+        
+	if (!image) {
+		cvdebug() << "File '"<<  filename << "' not a NIFTI file"; 
+                return PData(); 
+        }
+ 
+        switch (image->intent_code) {
+        case 0: // no specific intent, assume image data 
+        case NIFTI_INTENT_DIMLESS: 
+                break; 
+        default: 
+                throw create_exception<invalid_argument>("Found a NIFTI-1 file with intent ", 
+                                                         image->intent_code, " that is not supported by MIA."); 
+        }
+
+	
+
+	
+        if (image->ndim < 3 || image->ndim > 4)
+		throw create_exception<invalid_argument>("Nifti: 3D(+t) image expected but ", 
+							 image->ndim, " dimensions available in '", filename); 
+        
+        C3DBounds size(image->nx, image->ny, image->nz);
+
+        if (image->scl_slope != 0.0) { // data must be scaled
+                switch (image->datatype) {
+                case DT_UINT8:  return read_images<C3DFImage, unsigned char>(size, *image); 
+                case DT_INT16:  return read_images<C3DFImage, signed short>(size, *image); 
+                case DT_INT32:  return read_images<C3DDImage, signed int>(size, *image); 
+                case DT_FLOAT32:return read_images<C3DFImage, float>(size,  *image); 
+                case DT_FLOAT64:return read_images<C3DDImage, double>(size,  *image); 
+                case DT_INT8:   return read_images<C3DFImage, signed char>(size, *image); 
+                case DT_UINT16: return read_images<C3DFImage, unsigned short>(size, *image); 
+                case DT_UINT32: return read_images<C3DDImage, unsigned int>(size, *image); 
+#ifdef LONG_64BIT
+                case DT_INT64:  return read_images<C3DDImage, signed long>(size, *image); 
+                case DT_UINT64: return read_images<C3DDImage, unsigned short>(size, *image); 
+#endif
+                default:
+                        throw create_exception<invalid_argument>("NIFTI: input format ", image->datatype, " not supported"); 
+                }
+        } else {  // the true pixel values are stored
+                switch (image->datatype) {
+                case DT_UINT8:  return read_images<C3DUBImage>(size, *image); 
+                case DT_INT16:  return read_images<C3DSSImage>(size, *image); 
+                case DT_INT32:  return read_images<C3DSIImage>(size, *image); 
+                case DT_FLOAT32:return read_images<C3DFImage>(size,  *image); 
+                case DT_FLOAT64:return read_images<C3DDImage>(size,  *image); 
+                case DT_INT8:   return read_images<C3DSBImage>(size, *image); 
+                case DT_UINT16: return read_images<C3DUSImage>(size, *image); 
+                case DT_UINT32: return read_images<C3DUIImage>(size, *image); 
+#ifdef LONG_64BIT
+                case DT_INT64:  return read_images<C3DSLImage>(size, *image); 
+                case DT_UINT64: return read_images<C3DULImage>(size, *image); 
+#endif
+                default:
+                        throw create_exception<invalid_argument>("NIFTI: input format ", image->datatype, " not supported");
+                }
+        }
+	
+}
+
+static int datatype_to_nifti(EPixelType ptype)
+{
+        switch (ptype) {
+        case it_sbyte: return DT_INT8; 
+        case it_ubyte: return DT_UINT8; 
+        case it_sshort: return DT_INT16; 
+        case it_ushort: return DT_UINT16; 
+        case it_sint: return DT_INT32; 
+        case it_uint: return DT_UINT32; 
+#ifdef LONG_64BIT
+        case it_slong: return DT_INT64; 
+        case it_ulong: return DT_UINT64; 
+#endif
+        case it_float: return DT_FLOAT32; 
+        case it_double: return DT_FLOAT64; 
+        default: 
+                throw create_exception<invalid_argument>("NIFTI-1 ImageIO: Trying to save pixel type '", 
+                                                         CPixelTypeDict.get_name(ptype), 
+                                                         "' that is not supported by nifti"); 
+        }
+}
+
+
+class FCopyImageDataToNifti : public TFilter <void> {
+public:
+        FCopyImageDataToNifti(nifti_image& ni, EPixelType pt):
+                m_ni(ni),
+                m_pt(pt),
+                m_npixels_written(0)
+        {
+        }
+
+        template <typename T>
+        void operator () (const T3DImage<T>& image)
+        {
+                // sanity type check for multi-images
+                if (m_pt != image.get_pixel_type()){
+                        throw create_exception<invalid_argument>("NIFTI-IO: image series containing images of varying pixel types is not supported");
+                }
+
+                T *out_data = reinterpret_cast<T *>(m_ni.data);
+                copy(image.begin(), image.end(), out_data + m_npixels_written);
+                m_npixels_written += image.size();
+        }
+private:
+        nifti_image& m_ni;
+        EPixelType m_pt;
+        long m_npixels_written;
+};
+
+
+
+bool CNifti3DImageIOPlugin::do_save(const std::string& fname, const Data& data) const
+{
+        assert(!data.empty()); 
+        
+	const C3DImage& image = *data[0]; 
+        int dims[8] = {3,1,1,1,1,1,1,1};
+
+        C3DBounds size = image.get_size();
+        dims[1] = size.x; 
+        dims[2] = size.y; 
+        dims[3] = size.z; 
+        auto pixel_type = image.get_pixel_type(); 
+        int datatype = datatype_to_nifti(pixel_type);
+        
+        if (data.size() > 1) {
+                dims[0] = 4; 
+                dims[4] = data.size(); 
+        }
+	
+        // create the output image
+
+        unique_ptr<nifti_image, NiftiDeallocator> output(nifti_make_new_nim(dims, datatype, 1));
+	if (!output) {
+		throw create_exception<runtime_error>("NIFTI-imageio: Unable to create output image of size [", 
+						      size, "]x[", data.size(), "]"); 
+	}
+	
+	output->pixdim[0] = dims[0]; 
+	auto scale = image.get_voxel_size(); 
+	output->dx = output->pixdim[1] = scale.x;
+	output->dy = output->pixdim[2] = scale.y;
+	output->dz = output->pixdim[3] = scale.z;
+	
+	// it would make sense to add this next one as an attribute 
+	output->dt = output->pixdim[4] = 1;
+
+	// not supported 
+	output->du = output->pixdim[5] = 1;
+	output->dv = output->pixdim[6] = 1;
+	output->dw = output->pixdim[7] = 1;
+	
+	// we don't do scaling 
+	output->scl_slope = 0.0f;
+	output->scl_inter = 0.0f;
+
+	// need to see whether to support this 
+	output->cal_min = 0.0f;
+	output->cal_max = 0.0f ;
+	
+	// here starts the orientation insanity 
+	// todo: re-check how this qfac is actually used
+	output->qfac = 1; 
+	switch (image.get_orientation()) {
+	case ior_xyz_flipped: output->qfac = -1; 
+	case ior_undefined:
+	case ior_xyz: {
+		output->qform_code = 1; 
+		auto org = image.get_origin(); 
+		output->qoffset_x = org.x; 
+		output->qoffset_y = org.y; 
+		output->qoffset_z = org.z; 
+		auto rot = image.get_rotation().as_quaternion();
+		output->quatern_b = rot.x(); 
+		output->quatern_c = rot.y(); 
+		output->quatern_d = rot.z();
+	} break; 
+	default: 
+		cvwarn() << __FUNCTION__ << "FIXME:manual set orientation detected, but ignored\n";  
+	}
+	
+	// copy s-form if available 
+	if (image.has_attribute(AttrID_nifti_sform_code)) {
+		output->sform_code = image.get_attribute_as<int>(AttrID_nifti_sform_code); 
+		auto am = image.get_attribute_as<vector<float>>(AttrID_nifti_sform);
+		output->sto_xyz.m[0][0] = am[0]; 
+		output->sto_xyz.m[0][1] = am[1]; 
+		output->sto_xyz.m[0][2] = am[2]; 
+		output->sto_xyz.m[0][3] = am[3]; 
+
+		output->sto_xyz.m[1][0] = am[4]; 
+		output->sto_xyz.m[1][1] = am[5]; 
+		output->sto_xyz.m[1][2] = am[6]; 
+		output->sto_xyz.m[1][3] = am[7]; 
+
+		output->sto_xyz.m[1][0] = am[8]; 
+		output->sto_xyz.m[1][1] = am[9]; 
+		output->sto_xyz.m[1][2] = am[10]; 
+		output->sto_xyz.m[1][3] = am[11]; 
+
+		output->sto_xyz.m[1][0] = am[12]; 
+		output->sto_xyz.m[1][1] = am[13]; 
+		output->sto_xyz.m[1][2] = am[14]; 
+		output->sto_xyz.m[1][3] = am[15]; 
+
+	
+	}
+	output->toffset = image.get_attribute_as<float>(AttrID_nifti_toffset, 0.0f);
+	output->xyz_units  = image.get_attribute_as<int>(AttrID_nifti_xyz_units, NIFTI_UNITS_MM);
+	output->time_units = image.get_attribute_as<int>(AttrID_nifti_time_units, NIFTI_UNITS_SEC);
+
+	output->intent_code = image.get_attribute_as<int>(AttrID_nifti_intent_code, 0);
+	output->intent_p1 = image.get_attribute_as<int>(AttrID_nifti_intent_p1, 0);
+	output->intent_p2 = image.get_attribute_as<int>(AttrID_nifti_intent_p2, 0);
+	output->intent_p3 = image.get_attribute_as<int>(AttrID_nifti_intent_p3, 0);
+	string intent_name = image.get_attribute_as<string>(AttrID_nifti_intent_name, ""); 
+	if (!intent_name.empty()) {
+		strncpy(output->intent_name, intent_name.c_str(),  14);
+	}
+	output->num_ext = 0; 
+
+        // set the data
+        FCopyImageDataToNifti nsave(*output, image.get_pixel_type());
+
+        for (auto i = data.begin(); i!= data.end(); ++i){
+                ::mia::accumulate(nsave, **i);
+
+        }
+
+	// it could be that this needs the file name without extension 
+        if (nifti_set_filenames(output.get(), fname.c_str(), 1, 0) != 0) {
+		throw create_exception<runtime_error>("NIFTI-imageio: Something went wrong with setting the filename to '", 
+						      fname, "'"); 
+	}
+	auto resultfile = nifti_image_write_hdr_img(output.get(), 1, "wb"); 
+        return resultfile ? false : true;
+	
+}
+
+const std::string CNifti3DImageIOPlugin::do_get_descr() const
+{
+        return "NIFTI-1 3D image IO"; 
+}
+
+const std::string CNifti3DImageIOPlugin::do_get_preferred_suffix() const
+{
+        return "nii"; 
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new CNifti3DImageIOPlugin();
+}
+
+NS_END
diff --git a/addons/nifti/niftiimage.hh b/addons/nifti/niftiimage.hh
new file mode 100644
index 0000000..71ac69c
--- /dev/null
+++ b/addons/nifti/niftiimage.hh
@@ -0,0 +1,41 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef addons_niftiimage_hh
+#define addons_niftiimage_hh
+
+#include <mia/3d/imageio.hh>
+
+namespace niftiimage {
+
+class CNifti3DImageIOPlugin : public mia::C3DImageIOPlugin {
+public:
+	CNifti3DImageIOPlugin();
+private:
+
+        virtual PData do_load(const std::string&  filename) const;
+	virtual bool do_save(const std::string& fname, const Data& data) const;
+	virtual const std::string do_get_descr() const;
+	const std::string do_get_preferred_suffix() const; 
+};
+
+}
+
+#endif 
diff --git a/addons/nifti/test_niftiimage.cc b/addons/nifti/test_niftiimage.cc
new file mode 100644
index 0000000..a427453
--- /dev/null
+++ b/addons/nifti/test_niftiimage.cc
@@ -0,0 +1,110 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define VSTREAM_DOMAIN "NiftiImageIOtest"
+
+#include <mia/internal/autotest.hh>
+
+#include <boost/mpl/vector.hpp>
+#include <boost/test/test_case_template.hpp>
+
+
+#include <nifti/niftiimage.hh>
+#include <unistd.h>
+
+using namespace mia; 
+using namespace std; 
+using namespace niftiimage; 
+namespace bmpl=boost::mpl;
+
+
+typedef bmpl::vector<
+	unsigned char,
+	signed short,
+	unsigned short,
+	signed int,
+	unsigned int,
+	float,
+	double
+#ifdef LONG_64BIT
+	,long, unsigned long
+#endif
+		     > type;
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE( test_simple_write_read, T, type ) 
+{
+        C3DBounds size(2,3,4);
+	T3DImage<T> *image = new T3DImage<T>(size); 
+        P3DImage pimage(image); 
+
+	C3DFVector voxel(2.0,3.0,4.0); 
+        C3DFVector origin(10,20,30);
+        Quaternion rot(0.5, 0.1, 0.5, 0.7);
+        auto iv = image->begin(); 
+	auto ev = image->end();
+        int i = 0; 
+
+	while (iv != ev)
+		*iv++ = i++;
+	pimage->set_voxel_size(voxel); 
+	pimage->set_origin(origin); 
+        pimage->set_rotation(rot); 
+
+	CNifti3DImageIOPlugin io; 
+        CNifti3DImageIOPlugin::Data images;
+        images.push_back(pimage); 
+
+	stringstream filename; 
+	filename << "testimage-" << __type_descr<T>::value << ".nii"; 
+
+	cvdebug() << "test with " << filename.str() << "\n"; 
+
+	BOOST_REQUIRE(io.save(filename.str(), images)); 
+	
+	auto loaded = io.load(filename.str()); 
+	BOOST_REQUIRE(loaded); 
+	
+	BOOST_REQUIRE(loaded->size() == 1u); 
+        const auto& ploaded = dynamic_cast<const T3DImage<T>&>(*(*loaded)[0]); 	
+	iv = image->begin(); 
+
+
+	auto il = ploaded.begin(); 
+	
+	while (iv != ev) {
+		BOOST_CHECK_EQUAL(*il, *iv); 
+		++iv; 
+		++il; 
+	}
+
+	BOOST_CHECK_EQUAL(ploaded.get_voxel_size(), voxel); 
+	BOOST_CHECK_EQUAL(ploaded.get_origin(), origin); 
+        auto qloaded = ploaded.get_rotation().as_quaternion();
+
+        BOOST_CHECK_CLOSE(qloaded.x(), rot.x(), 0.001);
+        BOOST_CHECK_CLOSE(qloaded.y(), rot.y(), 0.001);
+        BOOST_CHECK_CLOSE(qloaded.z(), rot.z(), 0.001);
+        BOOST_CHECK_CLOSE(qloaded.w(), rot.w(), 0.001);
+
+        unlink(filename.str().c_str()); 
+}
+
+
diff --git a/addons/nlopt/CMakeLists.txt b/addons/nlopt/CMakeLists.txt
index 3ada9ae..621e7fb 100644
--- a/addons/nlopt/CMakeLists.txt
+++ b/addons/nlopt/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/addons/nlopt/nlopt.cc b/addons/nlopt/nlopt.cc
index 935f084..9106078 100644
--- a/addons/nlopt/nlopt.cc
+++ b/addons/nlopt/nlopt.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -250,7 +250,7 @@ void CNLOptFDFMinimizer::do_set_problem()
 
 	if (m_options.max_boundary != HUGE_VAL) {
 		cvinfo() << "Set higher boundary to " << m_options.max_boundary << "\n"; 
-		nlopt_set_lower_bounds1(m_opt, m_options.max_boundary); 
+		nlopt_set_upper_bounds1(m_opt, m_options.max_boundary); 
 	}
 	
 	if (m_options.step > 0.0)
diff --git a/addons/nlopt/nlopt.hh b/addons/nlopt/nlopt.hh
index 29e0a01..6b1e369 100644
--- a/addons/nlopt/nlopt.hh
+++ b/addons/nlopt/nlopt.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/nlopt/test_nlopt.cc b/addons/nlopt/test_nlopt.cc
index f7f946f..47a544d 100644
--- a/addons/nlopt/test_nlopt.cc
+++ b/addons/nlopt/test_nlopt.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/openexr/2dimgexr.cc b/addons/openexr/2dimgexr.cc
index 73f926e..133522c 100644
--- a/addons/openexr/2dimgexr.cc
+++ b/addons/openexr/2dimgexr.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/openexr/2dvfexr.cc b/addons/openexr/2dvfexr.cc
index b5df707..935778c 100644
--- a/addons/openexr/2dvfexr.cc
+++ b/addons/openexr/2dvfexr.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/openexr/CMakeLists.txt b/addons/openexr/CMakeLists.txt
index abc2d7a..42d8341 100644
--- a/addons/openexr/CMakeLists.txt
+++ b/addons/openexr/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/addons/openexr/test_openexr.cc b/addons/openexr/test_openexr.cc
index 9d5a237..2b102e5 100644
--- a/addons/openexr/test_openexr.cc
+++ b/addons/openexr/test_openexr.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/png/CMakeLists.txt b/addons/png/CMakeLists.txt
index 30b878a..b7c1897 100644
--- a/addons/png/CMakeLists.txt
+++ b/addons/png/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/addons/png/png-gray.cc b/addons/png/png-gray.cc
index 38dbdf0..6873b7e 100644
--- a/addons/png/png-gray.cc
+++ b/addons/png/png-gray.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/png/png-rgb.cc b/addons/png/png-rgb.cc
index e98ab33..6352f5a 100644
--- a/addons/png/png-rgb.cc
+++ b/addons/png/png-rgb.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/tiff/CMakeLists.txt b/addons/tiff/CMakeLists.txt
index c14a48a..1faafb9 100644
--- a/addons/tiff/CMakeLists.txt
+++ b/addons/tiff/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/addons/tiff/tiff.cc b/addons/tiff/tiff.cc
index a31fde3..0a43b03 100644
--- a/addons/tiff/tiff.cc
+++ b/addons/tiff/tiff.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -263,16 +263,24 @@ CTiff2DImageIO::PData CTiff2DImageIO::do_load(string const& filename)const
 
 	do {
 
-		TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
+		if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height)){
+			throw create_exception<runtime_error>("TIFF: No image height found in '", filename, "'"); 
+		}
 		cvdebug() << "TIFFTAG_IMAGELENGTH:" << height << "\n";
 
-		TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
+		if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width)){
+			throw create_exception<runtime_error>("TIFF: No image width found in '", filename, "'"); 
+		}
 		cvdebug() << "TIFFTAG_IMAGEWIDTH:" << width << "\n";
 
-		TIFFGetField(tif,TIFFTAG_BITSPERSAMPLE, &bbs);
+		    if (!TIFFGetField(tif,TIFFTAG_BITSPERSAMPLE, &bbs)){
+			throw create_exception<runtime_error>("TIFF: Bits per samples not given in '", filename, "'"); 
+		}
 		cvdebug() << "TIFFTAG_BITSPERSAMPLE:" << bbs << "\n";
 
-		TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
+		if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &spp)) {
+			throw create_exception<runtime_error>("TIFF: Samples per pixel not given in '", filename, "'"); 
+		}
 		cvdebug() << "TIFFTAG_SAMPLESPERPIXEL:" << spp << "\n";
 
 		TIFFGetField(tif, TIFFTAG_XRESOLUTION, &resolution.x);
diff --git a/addons/vistaio/2dtrans.cc b/addons/vistaio/2dtrans.cc
index 90c7690..29410e5 100644
--- a/addons/vistaio/2dtrans.cc
+++ b/addons/vistaio/2dtrans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,6 +41,7 @@ private:
 	virtual PData do_load(const std::string& fname) const;
 	virtual bool do_save(const std::string& fname, const C2DTransformation& data) const;
 	const string do_get_descr() const;
+	const std::string do_get_preferred_suffix() const; 
 }; 
 
 
@@ -48,8 +49,15 @@ C2DVistaTransformationIO::C2DVistaTransformationIO():
 	C2DTransformationIO("vista")
 {
 	add_suffix(".v2dt");
+	add_standard_vistaio_properties(*this); 
 }
 
+const std::string C2DVistaTransformationIO::do_get_preferred_suffix() const
+{
+	return "v2dt"; 
+}
+
+
 P2DTransformation C2DVistaTransformationIO::do_load(const std::string& fname) const
 {
 	CInputFile f(fname);
@@ -90,8 +98,13 @@ P2DTransformation C2DVistaTransformationIO::do_load(const std::string& fname) co
 	{
 		auto creator = mia::C2DTransformCreatorHandler::instance().produce(init_string);  
 		auto t = creator->create(C2DBounds(sx, sy)); 
+
+		VistaIOAttrList attributes = nullptr; 
+		if (VistaIOGetAttr (vlist, "attributes", NULL, VistaIOAttrListRepn, &attributes) == VistaIOAttrFound) {
+			copy_attr_list(*t, attributes);
+		}
+
 		auto params = t->get_parameters(); 
-		
 		if ((long)params.size() != VistaIOImageNPixels(blob)){
 			errmsg << fname << ":Bogus input, expected number of parameters differs from provided one"; 
 			goto fail; 
@@ -125,6 +138,10 @@ bool C2DVistaTransformationIO::do_save(const std::string& fname, const C2DTransf
 	VistaIOSetAttr (vlist, "size_y", NULL, VistaIOLongRepn, data.get_size().y); 
 	VistaIOSetAttr (vlist, "init-string", NULL, VistaIOStringRepn, data.get_creator_string().c_str()); 
 	VistaIOSetAttr (vlist, "parameters", NULL, VistaIOImageRepn, out_field);
+	VistaIOAttrList attributes = VistaIOCreateAttrList();
+	copy_attr_list(attributes, data);
+	VistaIOSetAttr (vlist, "attributes", NULL, VistaIOAttrListRepn, attributes);
+
 
 	bool result = VistaIOWriteFile(f,vlist);
 	VistaIODestroyAttrList(vlist);
diff --git a/addons/vistaio/2dtrans.hh b/addons/vistaio/2dtrans.hh
new file mode 100644
index 0000000..0dfff0c
--- /dev/null
+++ b/addons/vistaio/2dtrans.hh
@@ -0,0 +1,41 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef addons_vistaio_2dtrans_hh
+#define addons_vistaio_2dtrans_hh
+
+#include <mia/2d/transformio.hh>
+
+NS_BEGIN(vista_2dtrans_io)
+
+class C2DVistaTransformationIO: public mia::C2DTransformationIO {
+public: 	
+	C2DVistaTransformationIO(); 
+private: 
+	virtual PData do_load(const std::string& fname) const;
+	virtual bool do_save(const std::string& fname, const mia::C2DTransformation& data) const;
+	const std::string do_get_descr() const;
+	const std::string do_get_preferred_suffix() const; 
+}; 
+
+
+NS_END
+
+#endif 
diff --git a/addons/vistaio/2dvfvistaio.cc b/addons/vistaio/2dvfvistaio.cc
index 866e370..6ecfffe 100644
--- a/addons/vistaio/2dvfvistaio.cc
+++ b/addons/vistaio/2dvfvistaio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -52,6 +52,8 @@ CVista2DVFIOPlugin::CVista2DVFIOPlugin():
 	add_suffix(".vf");
 	add_suffix(".V");
 	add_suffix(".VF");
+	
+	add_standard_vistaio_properties(*this); 
 
 }
 
diff --git a/addons/vistaio/2dvistaio.cc b/addons/vistaio/2dvistaio.cc
index 40615a4..838d7a9 100644
--- a/addons/vistaio/2dvistaio.cc
+++ b/addons/vistaio/2dvistaio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
 #include <mia/core/file.hh>
 #include <mia/core/filter.hh>
 #include <mia/core/msgstream.hh>
+#include <mia/core/attribute_names.hh>
 #include <mia/2d/imageio.hh>
 
 #include <vistaio/vista4mia.hh>
@@ -42,7 +43,7 @@ private:
 	PData do_load(const string& fname) const;
 	bool do_save(const string& fname, const Data& data) const;
 	const string do_get_descr() const;
-	std::string do_get_preferred_suffix() const; 
+	const std::string do_get_preferred_suffix() const; 
 };
 
 CVista2DImageIOPlugin::CVista2DImageIOPlugin():
@@ -57,7 +58,8 @@ CVista2DImageIOPlugin::CVista2DImageIOPlugin():
 	add_supported_type(it_uint);
 	add_supported_type(it_float);
 	add_supported_type(it_double);
-	add_property(io_plugin_property_multi_record);
+
+	add_standard_vistaio_properties(*this); 
 
 	add_suffix(".v");
 	add_suffix(".V");
@@ -192,7 +194,7 @@ const string CVista2DImageIOPlugin::do_get_descr() const
 	return "a 2dimage io plugin for vista images";
 }
 
-std::string CVista2DImageIOPlugin::do_get_preferred_suffix() const
+const std::string CVista2DImageIOPlugin::do_get_preferred_suffix() const
 {
 	return "v"; 
 }
diff --git a/addons/vistaio/2dvistaio.hh b/addons/vistaio/2dvistaio.hh
index 8af6ffb..23e8759 100644
--- a/addons/vistaio/2dvistaio.hh
+++ b/addons/vistaio/2dvistaio.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@ private:
         PData do_load(const std::string& fname) const;
 	bool do_save(const std::string& fname, const Data& data) const;
 	const std::string do_get_descr() const;
-	std::string do_get_preferred_suffix() const; 
+	const std::string do_get_preferred_suffix() const; 
 };
 
 NS_END
diff --git a/addons/vistaio/3dtrans.cc b/addons/vistaio/3dtrans.cc
index 7b88b9e..c1ea240 100644
--- a/addons/vistaio/3dtrans.cc
+++ b/addons/vistaio/3dtrans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,36 +24,27 @@
 #include <mia/core/file.hh>
 #include <mia/core/filter.hh>
 #include <mia/core/msgstream.hh>
-#include <mia/3d/transformio.hh>
 #include <mia/3d/transformfactory.hh>
 
 #include <vistaio/vista4mia.hh>
 
+#include <vistaio/3dtrans.hh>
+
 NS_BEGIN(vista_3dtrans_io)
 
 NS_MIA_USE
 using namespace std; 
 
-class C3DVistaTransformationIO: public C3DTransformationIO {
-public: 	
-	C3DVistaTransformationIO(); 
-private: 
-	virtual PData do_load(const std::string& fname) const;
-	virtual bool do_save(const std::string& fname, const C3DTransformation& data) const;
-	const string do_get_descr() const;
-	std::string do_get_preferred_suffix() const; 
-}; 
-
 
 C3DVistaTransformationIO::C3DVistaTransformationIO():
 	C3DTransformationIO("vista")
 {
 	add_suffix(".v3dt");
 	add_suffix(".v");
-
+	add_standard_vistaio_properties(*this);
 }
 
-std::string C3DVistaTransformationIO::do_get_preferred_suffix() const
+const std::string C3DVistaTransformationIO::do_get_preferred_suffix() const
 {
 	return "v3dt"; 
 }
@@ -95,6 +86,7 @@ P3DTransformation C3DVistaTransformationIO::do_load(const std::string& fname) co
 		goto fail; 
 	}
 	
+	
 	// get the data from the image 
 	if (VistaIOPixelRepn(blob) != VistaIODoubleRepn) {
 		errmsg << fname << ":Bogus input, parameters not if type double"; 
@@ -104,6 +96,12 @@ P3DTransformation C3DVistaTransformationIO::do_load(const std::string& fname) co
 	{
 		auto creator = mia::C3DTransformCreatorHandler::instance().produce(init_string);  
 		auto t = creator->create(C3DBounds(sx, sy, sz)); 
+
+		VistaIOAttrList attributes = nullptr; 
+		if (VistaIOGetAttr (vlist, "attributes", NULL, VistaIOAttrListRepn, &attributes) == VistaIOAttrFound) {
+			copy_attr_list(*t, attributes);
+		}
+		
 		auto params = t->get_parameters(); 
 		
 		if ((long)params.size() != VistaIOImageNPixels(blob)){
@@ -141,7 +139,11 @@ bool C3DVistaTransformationIO::do_save(const std::string& fname, const C3DTransf
 	VistaIOSetAttr (vlist, "size_z", NULL, VistaIOLongRepn, data.get_size().z); 
 	VistaIOSetAttr (vlist, "init-string", NULL, VistaIOStringRepn, data.get_creator_string().c_str()); 
 	VistaIOSetAttr (vlist, "parameters", NULL, VistaIOImageRepn, out_field);
-
+	
+	VistaIOAttrList attributes = VistaIOCreateAttrList();
+	copy_attr_list(attributes, data);
+	VistaIOSetAttr (vlist, "attributes", NULL, VistaIOAttrListRepn, attributes);
+	
 	bool result = VistaIOWriteFile(f,vlist);
 	VistaIODestroyAttrList(vlist);
 
diff --git a/addons/vistaio/3dtrans.hh b/addons/vistaio/3dtrans.hh
new file mode 100644
index 0000000..4eb30ec
--- /dev/null
+++ b/addons/vistaio/3dtrans.hh
@@ -0,0 +1,41 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef addons_vistaio_3dtrans_hh
+#define addons_vistaio_3dtrans_hh
+
+#include <mia/3d/transformio.hh>
+
+NS_BEGIN(vista_3dtrans_io)
+
+class C3DVistaTransformationIO: public mia::C3DTransformationIO {
+public: 	
+	C3DVistaTransformationIO(); 
+private: 
+	virtual PData do_load(const std::string& fname) const;
+	virtual bool do_save(const std::string& fname, const mia::C3DTransformation& data) const;
+	const std::string do_get_descr() const;
+	const std::string do_get_preferred_suffix() const; 
+}; 
+
+
+NS_END
+
+#endif 
diff --git a/addons/vistaio/3dvfvistaio.cc b/addons/vistaio/3dvfvistaio.cc
index 1870ca6..43da611 100644
--- a/addons/vistaio/3dvfvistaio.cc
+++ b/addons/vistaio/3dvfvistaio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -42,7 +42,7 @@ public:
 private:
 	PData do_load(const string& fname) const;
 	bool do_save(const string& fname, const Data& data) const;
-	std::string do_get_preferred_suffix() const; 
+	const std::string do_get_preferred_suffix() const; 
 	const string do_get_descr() const;
 };
 
@@ -54,9 +54,11 @@ CVista3DVFIOPlugin::CVista3DVFIOPlugin():
 	add_suffix(".vf");
 	add_suffix(".V");
 	add_suffix(".VF");
+	
+	add_standard_vistaio_properties(*this); 
 }
 
-std::string CVista3DVFIOPlugin::do_get_preferred_suffix() const
+const std::string CVista3DVFIOPlugin::do_get_preferred_suffix() const
 {
 	return "vf"; 
 }
@@ -138,7 +140,7 @@ public:
 private:
 	PData do_load(const string& fname) const;
 	bool do_save(const string& fname, const Data& data) const;
-	std::string do_get_preferred_suffix() const; 
+	const std::string do_get_preferred_suffix() const; 
 	const string do_get_descr() const;
 	template <typename T>
 	CScaled3DVFIOPlugin::PData read_compressed(const T3DVector<VistaIOLong>& _size, const C3DFVector& scale, 
@@ -173,7 +175,7 @@ CScaled3DVFIOPlugin::PData CScaled3DVFIOPlugin::read_compressed(const T3DVector<
 	return result; 
 }
 
-std::string CScaled3DVFIOPlugin::do_get_preferred_suffix() const
+const std::string CScaled3DVFIOPlugin::do_get_preferred_suffix() const
 {
 	return "cvf"; 
 }
diff --git a/addons/vistaio/3dvistaio.cc b/addons/vistaio/3dvistaio.cc
index f48e887..f946c8c 100644
--- a/addons/vistaio/3dvistaio.cc
+++ b/addons/vistaio/3dvistaio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -52,8 +52,9 @@ CVista3DImageIOPlugin::CVista3DImageIOPlugin():
 	add_supported_type(it_uint);
 	add_supported_type(it_float);
 	add_supported_type(it_double);
-	add_property(io_plugin_property_multi_record);
-	add_property(io_plugin_property_has_attributes);
+	
+	add_standard_vistaio_properties(*this); 
+	
 	add_suffix(".v");
 	add_suffix(".V");
 	add_suffix(".vista");
@@ -183,7 +184,7 @@ const string CVista3DImageIOPlugin::do_get_descr() const
 	return "Vista 3D";
 }
 
-std::string CVista3DImageIOPlugin::do_get_preferred_suffix() const
+const std::string CVista3DImageIOPlugin::do_get_preferred_suffix() const
 {
 	return "v"; 
 }
@@ -192,6 +193,8 @@ std::string CVista3DImageIOPlugin::do_get_preferred_suffix() const
 extern "C" EXPORT  CPluginBase *get_plugin_interface()
 {
 	CVoxelAttributeTranslator::register_for("voxel");
+	CVoxelAttributeTranslator::register_for("origin3d");
+	C3DRotationAttributeTranslate::register_for("rotation3d");
 	C3DIntAttributeTranslator::register_for("ca");
 	C3DIntAttributeTranslator::register_for("cp");
 	return new CVista3DImageIOPlugin();
diff --git a/addons/vistaio/3dvistaio.hh b/addons/vistaio/3dvistaio.hh
index df536ce..855201b 100644
--- a/addons/vistaio/3dvistaio.hh
+++ b/addons/vistaio/3dvistaio.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@ private:
         PData do_load(const std::string& fname) const;
 	bool do_save(const std::string& fname, const Data& data) const;
 	const std::string do_get_descr() const;
-	std::string do_get_preferred_suffix() const; 
+	const std::string do_get_preferred_suffix() const; 
 };
 
 NS_END
diff --git a/addons/vistaio/CMakeLists.txt b/addons/vistaio/CMakeLists.txt
index 2e825da..fa964a4 100644
--- a/addons/vistaio/CMakeLists.txt
+++ b/addons/vistaio/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -41,12 +41,13 @@ IF (USE_VISTAIO)
 
     PLUGIN_WITH_TEST_AND_PREFIX2("2dimage" "io" 2dvistaio "${DEPS2D}")
     PLUGIN_WITH_TEST_AND_PREFIX2("3dimage" "io" 3dvistaio  "${DEPS3D}")
-    
+
+   
     PLUGIN_WITH_PREFIX2("2dvf" "io" 2dvfvistaio "${DEPS2D}")
     PLUGIN_WITH_PREFIX2("3dvf" "io" 3dvfvistaio "${DEPS3D}")
     PLUGIN_WITH_PREFIX2("mesh" "io" vistamesh "${DEPSMESH}")
-    PLUGIN_WITH_PREFIX2("2dtransform" "io" 2dtrans "${DEPS2D}")
-    PLUGIN_WITH_PREFIX2("3dtransform" "io" 3dtrans "${DEPS3D}")
+    PLUGIN_WITH_TEST_AND_PREFIX2("2dtransform" "io" 2dtrans "${DEPS2D}" TESTLIBS mia2dtest)
+    PLUGIN_WITH_TEST_AND_PREFIX2("3dtransform" "io" 3dtrans "${DEPS3D}" )
     
   
     ADD_EXECUTABLE(test-vista4mia  test_vista4mia.cc)
diff --git a/addons/vistaio/test_2dtrans.cc b/addons/vistaio/test_2dtrans.cc
new file mode 100644
index 0000000..33834dc
--- /dev/null
+++ b/addons/vistaio/test_2dtrans.cc
@@ -0,0 +1,78 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <vistaio/2dtrans.hh>
+#include <mia/2d/transformfactory.hh>
+
+
+using namespace std; 
+using namespace mia; 
+using namespace vista_2dtrans_io; 
+
+BOOST_AUTO_TEST_CASE(test_simple_io) 
+{
+	C2DTransformationIOPluginHandler::instance(); 
+
+        C2DBounds size(4,5); 
+        auto tf =  produce_2dtransform_factory("affine");
+        auto t = tf->create(size); 
+
+        auto params = t->get_parameters(); 
+        int i = 0; 
+        for (auto ip = params.begin(); ip != params.end(); ++ip) {
+                *ip = i++; 
+        }
+        
+        t->set_parameters(params); 
+        
+        t->set_attribute("string_attr", "string"); 
+        t->set_attribute(C2DTransformation::input_spacing_attr, PAttribute(new TAttribute<C2DFVector>(C2DFVector(2,3)))); 
+        t->set_attribute(C2DTransformation::output_spacing_attr, PAttribute(new TAttribute<C2DFVector>(C2DFVector(1.1f,1)))); 
+        
+        C2DVistaTransformationIO io; 
+        
+        io.save("transform.v2dt", *t); 
+        
+        auto t_loaded = io.load("transform.v2dt"); 
+        
+        auto loaded_params = t_loaded->get_parameters(); 
+
+        BOOST_REQUIRE(t_loaded->degrees_of_freedom() == 6u); 
+        BOOST_CHECK_EQUAL(t_loaded->get_size(), size); 
+        
+        i = 0; 
+        for (auto ip = loaded_params.begin(); ip != loaded_params.end(); ++ip) {
+                BOOST_CHECK_EQUAL(*ip, i++); 
+        }
+        
+        BOOST_REQUIRE(t_loaded->has_attribute("string_attr")); 
+        BOOST_REQUIRE(t_loaded->has_attribute(C2DTransformation::output_spacing_attr));
+        BOOST_REQUIRE(t_loaded->has_attribute(C2DTransformation::input_spacing_attr));
+        
+        BOOST_CHECK_EQUAL(t_loaded->get_attribute_as<string>("string_attr"), "string"); 
+
+        BOOST_CHECK_EQUAL(t_loaded->get_attribute_as<C2DFVector>(C2DTransformation::input_spacing_attr), C2DFVector(2,3)); 
+
+        BOOST_CHECK_EQUAL(t_loaded->get_attribute_as<C2DFVector>(C2DTransformation::output_spacing_attr), C2DFVector(1.1f,1)); 
+        
+}
+
+
diff --git a/addons/vistaio/test_2dvistaio.cc b/addons/vistaio/test_2dvistaio.cc
index 1803ad5..fb6956a 100644
--- a/addons/vistaio/test_2dvistaio.cc
+++ b/addons/vistaio/test_2dvistaio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/vistaio/test_3dtrans.cc b/addons/vistaio/test_3dtrans.cc
new file mode 100644
index 0000000..fa98c28
--- /dev/null
+++ b/addons/vistaio/test_3dtrans.cc
@@ -0,0 +1,77 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <vistaio/3dtrans.hh>
+#include <mia/3d/transformfactory.hh>
+
+using namespace std; 
+using namespace mia; 
+using namespace vista_3dtrans_io; 
+
+BOOST_AUTO_TEST_CASE(test_simple_io) 
+{
+	C3DTransformationIOPluginHandler::instance(); 
+
+        C3DBounds size(4,5,6); 
+        auto tf =  produce_3dtransform_factory("affine");
+        auto t = tf->create(size); 
+
+        auto params = t->get_parameters(); 
+        int i = 0; 
+        for (auto ip = params.begin(); ip != params.end(); ++ip) {
+                *ip = i++; 
+        }
+        
+        t->set_parameters(params); 
+        
+        t->set_attribute("string_attr", "string"); 
+        t->set_attribute(C3DTransformation::input_spacing_attr, PAttribute(new TAttribute<C3DFVector>(C3DFVector(2,3,4)))); 
+        t->set_attribute(C3DTransformation::output_spacing_attr, PAttribute(new TAttribute<C3DFVector>(C3DFVector(1.1f,1,2)))); 
+        
+        C3DVistaTransformationIO io; 
+        
+        io.save("transform.v3dt", *t); 
+        
+        auto t_loaded = io.load("transform.v3dt"); 
+        
+        auto loaded_params = t_loaded->get_parameters(); 
+
+        BOOST_REQUIRE(t_loaded->degrees_of_freedom() == 12u); 
+        BOOST_CHECK_EQUAL(t_loaded->get_size(), size); 
+        
+        i = 0; 
+        for (auto ip = loaded_params.begin(); ip != loaded_params.end(); ++ip) {
+                BOOST_CHECK_EQUAL(*ip, i++); 
+        }
+        
+        BOOST_REQUIRE(t_loaded->has_attribute("string_attr")); 
+        BOOST_REQUIRE(t_loaded->has_attribute(C3DTransformation::output_spacing_attr));
+        BOOST_REQUIRE(t_loaded->has_attribute(C3DTransformation::input_spacing_attr));
+        
+        BOOST_CHECK_EQUAL(t_loaded->get_attribute_as<string>("string_attr"), "string"); 
+
+        BOOST_CHECK_EQUAL(t_loaded->get_attribute_as<C3DFVector>(C3DTransformation::input_spacing_attr), C3DFVector(2,3,4)); 
+
+        BOOST_CHECK_EQUAL(t_loaded->get_attribute_as<C3DFVector>(C3DTransformation::output_spacing_attr), C3DFVector(1.1f,1,2)); 
+        
+}
+
+
diff --git a/addons/vistaio/test_3dvistaio.cc b/addons/vistaio/test_3dvistaio.cc
index e085904..b58093b 100644
--- a/addons/vistaio/test_3dvistaio.cc
+++ b/addons/vistaio/test_3dvistaio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,6 +50,10 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_simple_write_read, T, type )
 {
         C3DBounds size(2,3,4);
 	T3DImage<T> *image = new T3DImage<T>(size); 
+	image->set_voxel_size(C3DFVector(10,20,30)); 
+	image->set_origin(C3DFVector(20,30,40)); 
+	image->set_rotation(C3DRotation(Quaternion(0.5, 0.1, 0.7, 0.5))); 
+	
         P3DImage pimage(image); 
 
         auto iv = image->begin(); 
diff --git a/addons/vistaio/test_vista4mia.cc b/addons/vistaio/test_vista4mia.cc
index 0f8e907..0a56c4e 100644
--- a/addons/vistaio/test_vista4mia.cc
+++ b/addons/vistaio/test_vista4mia.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,14 +19,8 @@
  */
 
 #include <climits>
-#define BOOST_TEST_DYN_LINK
-
-#include <boost/filesystem/convenience.hpp>
-#include <boost/filesystem/path.hpp>
-
-#include <boost/test/unit_test_suite.hpp>
-#include <boost/test/unit_test.hpp>
 
+#include <mia/internal/autotest.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/imageiotest.hh>
 
@@ -34,8 +28,6 @@
 #include <mia/2d/transformio.hh>
 #include <mia/2d/transformfactory.hh>
 
-#include <mia/2d/inittesthandlers.hh>
-
 #include <mia/3d/transformio.hh>
 #include <mia/3d/transformfactory.hh>
 
@@ -55,12 +47,6 @@ using namespace boost;
 using namespace boost::unit_test;
 namespace bfs = ::boost::filesystem;
 
-CSplineBoundaryConditionTestPath sbc_test_path; 
-CSplineKernelTestPath init_path; 
-
-C2DTransformCreatorHandlerTestPath trans2dcreate_path; 
-C3DTransformCreatorHandlerTestPath trans3dcreate_path; 
-
 template <typename T>
 void check_value(const CAttributedData& attr_map, const string& key,  T value)
 {
@@ -100,7 +86,7 @@ void check_vattr_value(VistaIOAttrList list, const string& key,  const string va
 	BOOST_CHECK(string(lvalue) == value);
 }
 
-void check_translation()
+BOOST_AUTO_TEST_CASE( check_translation)
 {
 	VistaIOAttrList vista_list1 = VistaIOCreateAttrList();
 
@@ -162,64 +148,7 @@ void check_translation()
 	VistaIODestroyAttrList(vista_list2);
 }
 
-static void handler_setup()
-{
-	CPathNameArray searchpath;
-	searchpath.push_back(bfs::path("."));
-
-	C2DImageIOPluginHandler::set_search_path(searchpath);
-	C3DImageIOPluginHandler::set_search_path(searchpath);
-
-	C2DVFIOPluginHandler::set_search_path(searchpath);
-	C3DVFIOPluginHandler::set_search_path(searchpath);
-
-	C2DTransformationIOPluginHandler::set_search_path(searchpath);
-	C3DTransformationIOPluginHandler::set_search_path(searchpath);
-
-}
-
-
-
-static void test_3dimage_plugin_handler()
-{
-	const C3DImageIOPluginHandler::Instance& handler = C3DImageIOPluginHandler::instance();
-	BOOST_CHECK_EQUAL(handler.size(), 2u);
-	BOOST_CHECK_EQUAL(handler.get_plugin_names(),  "datapool vista ");
-}
-
-
-
-static void test_2dimage_plugin_handler()
-{
-	const C2DImageIOPluginHandler::Instance& handler = C2DImageIOPluginHandler::instance();
-	BOOST_CHECK_EQUAL(handler.size(), 2u);
-	BOOST_CHECK_EQUAL(handler.get_plugin_names(), "datapool vista ");
-}
-
-static void test_3dvf_plugin_handler()
-{
-	const C3DVFIOPluginHandler::Instance& handler = C3DVFIOPluginHandler::instance();
-	BOOST_CHECK_EQUAL(handler.size(), 3u);
-	BOOST_CHECK_EQUAL(handler.get_plugin_names(), "cvista datapool vista ");
-}
-
-
-static void test_2dvf_plugin_handler()
-{
-	const C2DVFIOPluginHandler::Instance& handler = C2DVFIOPluginHandler::instance();
-	BOOST_CHECK_EQUAL(handler.size(), 2u);
-	BOOST_CHECK_EQUAL(handler.get_plugin_names(), "datapool vista ");
-}
-
-
-static void test_2dtransform_plugin_handler()
-{
-	const C2DTransformationIOPluginHandler::Instance& handler = C2DTransformationIOPluginHandler::instance();
-	BOOST_CHECK_EQUAL(handler.size(), 2u);
-	BOOST_CHECK_EQUAL(handler.get_plugin_names(), "datapool vista ");
-}
-
-static void test_2dtransform_io()
+BOOST_AUTO_TEST_CASE(test_2dtransform_io)
 {
 	C2DBounds size( 20, 20); 
 	
@@ -263,7 +192,7 @@ static void test_2dtransform_io()
 }
 
 
-static void test_3dtransform_io()
+BOOST_AUTO_TEST_CASE(test_3dtransform_io)
 {
 	C3DBounds size( 20, 20, 10); 
 	
@@ -308,45 +237,3 @@ static void test_3dtransform_io()
 }
 
 
-bool init_unit_test_suite( )
-{
-
-	handler_setup();
-
-	test_suite *suite = &framework::master_test_suite();
-
-	suite->add( BOOST_TEST_CASE( &check_translation));
-	suite->add( BOOST_TEST_CASE( &test_2dimage_plugin_handler));
-	suite->add( BOOST_TEST_CASE( &test_2dimageio_plugins));
-
-	suite->add( BOOST_TEST_CASE( &test_3dimage_plugin_handler));
-	add_3dimageio_plugin_tests( suite );
-
-	suite->add( BOOST_TEST_CASE( &test_3dvf_plugin_handler ));
-	suite->add( BOOST_TEST_CASE( &test_2dvf_plugin_handler ));
-
-	suite->add( BOOST_TEST_CASE( &test_2dtransform_plugin_handler ));
-	suite->add( BOOST_TEST_CASE( &test_2dtransform_io ));
-	suite->add( BOOST_TEST_CASE( &test_3dtransform_io ));
-
-	add_2dvfio_tests( suite );
-
-	return true;
-}
-
-const SProgramDescription description = {
-        {pdi_group, "Tests"}, 
-	{pdi_short, "Vista tests"}, 
-	{pdi_description, "This program runs a set of tests."}
-};
-
-int BOOST_TEST_CALL_DECL
-do_main( int argc, char* argv[] )
-{
-	if (CCmdOptionList(description).parse(argc, argv) != CCmdOptionList::hr_no)
-		return 0; 
-	return ::boost::unit_test::unit_test_main( &init_unit_test_suite, argc, argv );
-}
-
-#include <mia/internal/main.hh>
-MIA_MAIN(do_main);
diff --git a/addons/vistaio/vista4mia.cc b/addons/vistaio/vista4mia.cc
index 893681b..ec3b7f8 100644
--- a/addons/vistaio/vista4mia.cc
+++ b/addons/vistaio/vista4mia.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,6 +41,13 @@ void vistaio_add_attribute(CAttributedData& attr, const string& name, VistaIOBit
 	attr.set_attribute(name, PAttribute(new TAttribute<bool>(value))); 
 }
 
+VISTA4MIA_EXPORT void add_standard_vistaio_properties(CPluginBase& plugin)
+{
+	plugin.add_property(io_plugin_property_multi_record); 
+	plugin.add_property(io_plugin_property_history_split);
+	plugin.add_property(io_plugin_property_has_attributes);
+	plugin.add_property(io_plugin_property_can_pipe);
+}
 
 
 VISTA4MIA_EXPORT void copy_attr_list(CAttributedData& attributes, const VistaIOAttrList in_list)
diff --git a/addons/vistaio/vista4mia.hh b/addons/vistaio/vista4mia.hh
index dff2416..7bc6fda 100644
--- a/addons/vistaio/vista4mia.hh
+++ b/addons/vistaio/vista4mia.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -141,7 +141,7 @@ struct dispatch_creat_vimage<I, void> {
 NS_MIA_BEGIN
 
 VISTA4MIA_EXPORT void copy_attr_list(VistaIOAttrList target, const mia::CAttributedData& attributes);
-VISTA4MIA_EXPORT void copy_attr_list(mia::CAttributedData& attributes, const VistaIOAttrList target);
+VISTA4MIA_EXPORT void copy_attr_list(mia::CAttributedData& attributes, const VistaIOAttrList source);
 
 /**
    Helper class to indice atomatic destruction of vista attribute lists. 
@@ -159,6 +159,8 @@ private:
 		
 }; 
 
+VISTA4MIA_EXPORT void add_standard_vistaio_properties(CPluginBase& plugin); 
+
 NS_MIA_END
 
 
diff --git a/addons/vistaio/vistamesh.cc b/addons/vistaio/vistamesh.cc
index f8faa3d..7d792bb 100644
--- a/addons/vistaio/vistamesh.cc
+++ b/addons/vistaio/vistamesh.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/vtk/CMakeLists.txt b/addons/vtk/CMakeLists.txt
index 103ba0c..a11c159 100644
--- a/addons/vtk/CMakeLists.txt
+++ b/addons/vtk/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/addons/vtk/test_vtkimage.cc b/addons/vtk/test_vtkimage.cc
index 431bb11..ca29ccf 100644
--- a/addons/vtk/test_vtkimage.cc
+++ b/addons/vtk/test_vtkimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -60,13 +60,15 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_simple_write_read, T, type )
 	T3DImage<T> *image = new T3DImage<T>(size); 
         P3DImage pimage(image); 
 
+	C3DFVector voxel(2.0,3.0,4.0); 
         auto iv = image->begin(); 
 	auto ev = image->end();
         int i = 0; 
 
 	while (iv != ev)
 		*iv++ = i++;
-       
+	pimage->set_voxel_size(voxel); 
+	pimage->set_origin(C3DFVector(10,20,30)); 
 
 	CVtk3DImageIOPlugin io; 
         CVtk3DImageIOPlugin::Data images;
@@ -94,6 +96,8 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_simple_write_read, T, type )
 		++iv; 
 		++il; 
 	}
+
+	BOOST_CHECK_EQUAL(ploaded.get_voxel_size(), voxel); 
         unlink(filename.str().c_str()); 
 }
 
@@ -123,7 +127,11 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_xml_write_read, T, type_xml )
 
 	while (iv != ev)
 		*iv++ = i++;
-       
+	
+	C3DFVector voxel(2.0,3.0,4.0); 
+	pimage->set_voxel_size(voxel); 
+
+	pimage->set_origin(C3DFVector(10,20,30)); 
 
 	CVtkXML3DImageIOPlugin io; 
         CVtkXML3DImageIOPlugin::Data images;
@@ -151,6 +159,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_xml_write_read, T, type_xml )
 		++iv; 
 		++il; 
 	}
+	BOOST_CHECK_EQUAL(ploaded.get_voxel_size(), voxel); 
         unlink(filename.str().c_str()); 
 }
 
@@ -181,8 +190,12 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_mhd_write_read, T, type_mhd )
 
 	while (iv != ev)
 		*iv++ = i++;
-       
 
+	C3DFVector voxel(2.0,3.0,4.0); 
+	pimage->set_voxel_size(voxel); 
+       
+	pimage->set_origin(C3DFVector(10,20,30)); 
+	
 	CMhd3DImageIOPlugin io; 
         CMhd3DImageIOPlugin::Data images;
         images.push_back(pimage); 
@@ -216,6 +229,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_mhd_write_read, T, type_mhd )
 		++iv; 
 		++il; 
 	}
+	BOOST_CHECK_EQUAL(ploaded.get_voxel_size(), voxel); 
         unlink(filename.str().c_str()); 
         unlink(rawfilename.str().c_str()); 
         unlink(zrawfilename.str().c_str()); 
@@ -225,3 +239,49 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_mhd_write_read, T, type_mhd )
 
 
 
+
+BOOST_AUTO_TEST_CASE( test_simple_write_read_bool ) 
+{
+        C3DBounds size(2,3,4);
+	C3DBitImage *image = new C3DBitImage(size); 
+        P3DImage pimage(image); 
+
+	C3DFVector voxel(2.0,3.0,4.0); 
+        auto iv = image->begin(); 
+	auto ev = image->end();
+        int i = 0; 
+
+	while (iv != ev)
+		*iv++ = i++ & 1;
+	pimage->set_voxel_size(voxel); 
+
+	CVtk3DImageIOPlugin io; 
+        CVtk3DImageIOPlugin::Data images;
+        images.push_back(pimage); 
+
+	stringstream filename; 
+	filename << "testimage-" << __type_descr<bool>::value << ".vtk"; 
+
+	cvdebug() << "test with " << filename.str() << "\n"; 
+
+	BOOST_REQUIRE(io.save(filename.str(), images)); 
+	
+	auto loaded = io.load(filename.str()); 
+	BOOST_REQUIRE(loaded); 
+	
+	BOOST_REQUIRE(loaded->size() == 1u); 
+        const auto& ploaded = dynamic_cast<const C3DBitImage&>(*(*loaded)[0]); 	
+	iv = image->begin(); 
+
+
+	auto il = ploaded.begin(); 
+	
+	while (iv != ev) {
+		BOOST_CHECK_EQUAL(*il, *iv); 
+		++iv; 
+		++il; 
+	}
+
+	BOOST_CHECK_EQUAL(ploaded.get_voxel_size(), voxel); 
+//        unlink(filename.str().c_str()); 
+}
diff --git a/addons/vtk/test_vtkmesh.cc b/addons/vtk/test_vtkmesh.cc
index d91e68d..5086042 100644
--- a/addons/vtk/test_vtkmesh.cc
+++ b/addons/vtk/test_vtkmesh.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/vtk/test_vtkvf.cc b/addons/vtk/test_vtkvf.cc
index a5b8754..77f770d 100644
--- a/addons/vtk/test_vtkvf.cc
+++ b/addons/vtk/test_vtkvf.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/vtk/vtkimage.cc b/addons/vtk/vtkimage.cc
index 523f7f9..76b9ac9 100644
--- a/addons/vtk/vtkimage.cc
+++ b/addons/vtk/vtkimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -76,7 +76,7 @@ struct __vtk_data_array {
 
 
 VTK_ARRAY_TRANSLATE(bool, vtkBitArray, VTK_BIT); 
-VTK_ARRAY_TRANSLATE(signed char, vtkSignedCharArray, VTK_SIGNED_CHAR); 
+ VTK_ARRAY_TRANSLATE(signed char, vtkSignedCharArray, VTK_SIGNED_CHAR); 
 VTK_ARRAY_TRANSLATE(unsigned char, vtkUnsignedCharArray, VTK_UNSIGNED_CHAR); 
 VTK_ARRAY_TRANSLATE(signed short, vtkShortArray, VTK_SHORT); 
 VTK_ARRAY_TRANSLATE(unsigned short, vtkUnsignedShortArray, VTK_UNSIGNED_SHORT); 
@@ -93,21 +93,50 @@ VTK_ARRAY_TRANSLATE(double, vtkDoubleArray, VTK_DOUBLE);
 
 
 template <typename T> 
-C3DImage *read_image(const C3DBounds& size, void *scalars) 
-{
-	cvdebug() << "VTK/MetaIO read image of type " <<  __type_descr<T>::value << "\n"; 
-
-	typedef typename __vtk_data_array<T>::type myDataArray; 
-	
-	const T *my_scalars = reinterpret_cast<const T *>(scalars); 
-	if (!my_scalars) 
-		throw create_exception<logic_error>("CVtk3DImageIOPlugin::load: input image scalar type bogus"); 
-	
-	T3DImage<T> *result = new  T3DImage<T>(size); 
-	copy(my_scalars, my_scalars + result->size(), result->begin()); 
+struct read_image {
+	static C3DImage *apply(const C3DBounds& size, void *scalars)  {
+		cvdebug() << "VTK/MetaIO read image of type " <<  __type_descr<T>::value << "\n"; 
+		
+		
+		const T *my_scalars = reinterpret_cast<const T *>(scalars); 
+		if (!my_scalars) 
+			throw create_exception<logic_error>("CVtk3DImageIOPlugin::load: input image scalar type bogus"); 
+		
+		T3DImage<T> *result = new  T3DImage<T>(size); 
+		copy(my_scalars, my_scalars + result->size(), result->begin()); 
+		
+		
+		return result; 
+	}
+}; 
 
-	return result; 
-}
+template <> 
+struct read_image<bool> {
+	static C3DImage *apply(const C3DBounds& size, void *scalars)  {
+		cvdebug() << "VTK/MetaIO read image of type " <<  __type_descr<bool>::value << "\n"; 
+		
+		
+		const unsigned char *my_scalars = reinterpret_cast<const unsigned char *>(scalars); 
+		if (!my_scalars) 
+			throw create_exception<logic_error>("CVtk3DImageIOPlugin::load: input image scalar type bogus"); 
+		
+		T3DImage<bool> *result = new  T3DImage<bool>(size); 
+		
+		
+		auto i = result->begin();
+		auto e = result->end();
+			
+		while (i != e) {
+			unsigned char obyte = *my_scalars++;
+			unsigned char mask = 0x80;
+			for (int pos = 0; pos < 8 && i != e; ++i, ++pos, mask >>= 1) {
+				if (obyte & mask) 
+					*i = true; 
+			}
+		}
+		return result; 
+	}
+}; 
 
 static C3DImage *image_vtk_to_mia(vtkImageData *vtk_image, const string& fname) 
 {
@@ -129,24 +158,31 @@ static C3DImage *image_vtk_to_mia(vtkImageData *vtk_image, const string& fname)
 
 	C3DImage *result_image = nullptr; 
 	switch 	 (vtk_image->GetScalarType()) {
-	case VTK_BIT:            result_image=read_image<bool>(size, array); break; 
-	case VTK_SIGNED_CHAR:    result_image=read_image<signed char>(size, array); break; 
-	case VTK_UNSIGNED_CHAR:  result_image=read_image<unsigned char>(size, array); break; 
-	case VTK_SHORT:          result_image=read_image<signed short>(size, array); break; 
-	case VTK_UNSIGNED_SHORT: result_image=read_image<unsigned short>(size, array); break; 
-	case VTK_INT:            result_image=read_image<signed int>(size, array); break;  
-	case VTK_UNSIGNED_INT:   result_image=read_image<unsigned int>(size, array); break; 
+	case VTK_BIT:            result_image=read_image<bool>::apply(size, array); break; 
+	case VTK_SIGNED_CHAR:    result_image=read_image<signed char>::apply(size, array); break; 
+	case VTK_UNSIGNED_CHAR:  result_image=read_image<unsigned char>::apply(size, array); break; 
+	case VTK_SHORT:          result_image=read_image<signed short>::apply(size, array); break; 
+	case VTK_UNSIGNED_SHORT: result_image=read_image<unsigned short>::apply(size, array); break; 
+	case VTK_INT:            result_image=read_image<signed int>::apply(size, array); break;  
+	case VTK_UNSIGNED_INT:   result_image=read_image<unsigned int>::apply(size, array); break; 
 #ifdef LONG_64BIT
-	case VTK_LONG:           result_image=read_image<signed long>(size, array); break; 
-	case VTK_UNSIGNED_LONG:  result_image=read_image<unsigned long>(size, array); break; 
+	case VTK_LONG:           result_image=read_image<signed long>::apply(size, array); break; 
+	case VTK_UNSIGNED_LONG:  result_image=read_image<unsigned long>::apply(size, array); break; 
 #endif 
-	case VTK_FLOAT:          result_image=read_image<float>(size, array); break; 
-	case VTK_DOUBLE:         result_image=read_image<double>(size, array); break;  
+	case VTK_FLOAT:          result_image=read_image<float>::apply(size, array); break; 
+	case VTK_DOUBLE:         result_image=read_image<double>::apply(size, array); break;  
 	default:
 		throw create_exception<invalid_argument>("3D Vtk/MetaImageIO load (", fname ,"): "
 							 "data type ", vtk_image->GetScalarTypeAsString(), 
 							 "(", vtk_image->GetScalarType(), ") not supported"); 
 	}
+	double sp[3]; 
+	vtk_image->GetSpacing (sp); 
+	result_image->set_voxel_size(C3DFVector(sp[0], sp[1], sp[2])); 
+	
+	vtk_image->GetOrigin (sp); 
+	result_image->set_origin(C3DFVector(sp[0], sp[1], sp[2])); 
+	
 	return result_image; 
 }
 
@@ -164,14 +200,56 @@ struct __dispatch_convert<T, __true_type> {
 	static void  apply (vtkImageData *output, const T3DImage<T>& input)  {
 		
 		cvdebug() << "Input is an image of pixel type " << __type_descr<T>::value << "\n"; 
+#if  VTK_MAJOR_VERSION < 6 
 		output->SetScalarType(__vtk_data_array<T>::value); 
-		output->SetNumberOfScalarComponents(1); 
+		output->SetNumberOfScalarComponents(1);
 		output->AllocateScalars(); 
+#else 
+		output->AllocateScalars(__vtk_data_array<T>::value, 1); 
+#endif 
 		T *out_ptr =  reinterpret_cast<T*>(output->GetScalarPointer()); 
 		copy(input.begin(), input.end(), out_ptr); 
 	}
 }; 
 
+template <> 
+struct __dispatch_convert<bool, __true_type> {
+	static void  apply (vtkImageData *output, const T3DImage<bool>& input)  {
+		
+		cvdebug() << "Input is an image of pixel type bool\n"; 
+#if  VTK_MAJOR_VERSION < 6 
+		output->SetScalarType(__vtk_data_array<bool>::value); 
+		output->SetNumberOfScalarComponents(1);
+		output->AllocateScalars(); 
+#else 
+		output->AllocateScalars(__vtk_data_array<bool>::value, 1); 
+#endif 
+		unsigned char *out_ptr =  reinterpret_cast<unsigned char *>(output->GetScalarPointer()); 
+		
+		auto i = input.begin();
+		auto e = input.end();
+		int pos = 0; 
+		unsigned char mask = 0x80;
+		unsigned char obyte = 0;
+		while (i != e) {
+			if (*i) 
+				obyte |= mask; 
+			++pos; 
+			mask >>= 1; 
+			if (pos == 8) {
+				*out_ptr++ = obyte; 
+				obyte = 0; 
+				mask = 0x80;
+				pos = 0; 
+			}
+			++i; 
+		}
+		if ( pos > 0) {
+			*out_ptr = obyte; 
+		}
+	}
+}; 
+
 
 class FSetArray: public TFilter<void>  {
 public: 
@@ -190,7 +268,9 @@ private:
 static vtkSmartPointer<vtkImageData> image_mia_to_vtk(const C3DImage& mia_image) 
 {
 	auto outimage = vtkSmartPointer<vtkImageData>::New();
-	outimage->SetOrigin(0,0,0); 
+	auto origin = mia_image.get_origin(); 
+
+	outimage->SetOrigin(origin.x,origin.y,origin.z); 
 	auto dx = mia_image.get_voxel_size(); 
 	outimage->SetSpacing(dx.x, dx.y, dx.z); 
 	outimage->SetDimensions(mia_image.get_size().x, mia_image.get_size().y, mia_image.get_size().z); 
@@ -206,6 +286,7 @@ CVtk3DImageIOPlugin::CVtk3DImageIOPlugin():
 	C3DImageIOPlugin("vtk")
 {
 	// indicate support for all pixel types available (only scalar types are possible)
+	add_supported_type(it_bit);
 	add_supported_type(it_sbyte);
 	add_supported_type(it_ubyte);
 	add_supported_type(it_sshort);
@@ -266,7 +347,11 @@ bool CVtk3DImageIOPlugin::do_save(const string& fname, const Data& data) const
 	
 	// add writing of the image
 	auto writer = vtkSmartPointer<vtkDataSetWriter>::New(); 
+#if  VTK_MAJOR_VERSION < 6 
 	writer->SetInput(outimage); 
+#else 
+	writer->SetInputData(outimage); 
+#endif 
 	writer->SetFileTypeToBinary();
 	writer->SetFileName(fname.c_str()); 
 	writer->Write();
@@ -339,7 +424,11 @@ bool CVtkXML3DImageIOPlugin::do_save(const string& fname, const Data& data) cons
 	
 	// add writing of the image
 	auto writer = vtkSmartPointer<vtkXMLImageDataWriter>::New(); 
+#if  VTK_MAJOR_VERSION == 5 
 	writer->SetInput(outimage); 
+#else 
+	writer->SetInputData(outimage); 
+#endif 
 	writer->SetFileName(fname.c_str()); 
 	writer->Write();
 
@@ -418,8 +507,13 @@ bool CMhd3DImageIOPlugin::do_save(const std::string& fname, const Data& data) co
 
 	// add writing of the image
 	auto writer = vtkSmartPointer<vtkMetaImageWriter>::New(); 
+#if  VTK_MAJOR_VERSION < 6 
 	writer->SetInput(outimage); 
+#else 
+	writer->SetInputData(outimage); 
+#endif 
 	writer->SetFileName(fname.c_str()); 
+
 	// seems that compression is broken for (un)signed char. 
 	writer->SetCompression(false); 
 	writer->Write();
diff --git a/addons/vtk/vtkimage.hh b/addons/vtk/vtkimage.hh
index 4c7bacf..cf79c6b 100644
--- a/addons/vtk/vtkimage.hh
+++ b/addons/vtk/vtkimage.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/vtk/vtkmesh.cc b/addons/vtk/vtkmesh.cc
index aed23d3..df01403 100644
--- a/addons/vtk/vtkmesh.cc
+++ b/addons/vtk/vtkmesh.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -217,11 +217,11 @@ PTriangleMesh CVtkMeshIO::do_load(string const &  filename) const
 	
 	auto reader = vtkSmartPointer<vtkPolyDataReader>::New();
 	reader->SetFileName(filename.c_str());
+	reader->Update(); 
 	auto mesh = reader->GetOutput(); 
 	if (!mesh)
 		return PTriangleMesh(); 
 
-	mesh->Update(); 
 	
 	auto vertices = read_vertices(*mesh); 
 	auto triangles = read_triangles(*vertices, *mesh); 
@@ -293,7 +293,11 @@ bool CVtkMeshIO::do_save(string const &  filename, const CTriangleMesh& mesh) co
 	auto writer = vtkSmartPointer<vtkPolyDataWriter>::New();
 	writer->SetFileName(filename.c_str());
 	writer->SetFileTypeToBinary(); 
+#if  VTK_MAJOR_VERSION < 6 
 	writer->SetInput(data); 
+#else 
+	writer->SetInputData(data); 
+#endif 
 	return writer->Write(); 
 }
 
diff --git a/addons/vtk/vtkmesh.hh b/addons/vtk/vtkmesh.hh
index d7287be..ff8da16 100644
--- a/addons/vtk/vtkmesh.hh
+++ b/addons/vtk/vtkmesh.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/addons/vtk/vtkvf.cc b/addons/vtk/vtkvf.cc
index 989b9b3..9a0c874 100644
--- a/addons/vtk/vtkvf.cc
+++ b/addons/vtk/vtkvf.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -61,10 +61,11 @@ CVtk3DVFIOPlugin::PData CVtk3DVFIOPlugin::do_load(const string&  filename) const
 {
 	auto reader = vtkSmartPointer<vtkStructuredPointsReader>::New(); 
 	reader->SetFileName(filename.c_str()); 
+	reader->Update(); 
 	auto iovf = reader->GetOutput(); 
 	if (!iovf)
 		return PData(); 
-	iovf->Update(); 
+
 	
 	int dim = iovf->GetDataDimension();
 	if (dim != 3) {
@@ -103,10 +104,13 @@ bool CVtk3DVFIOPlugin::do_save(const string& fname, const C3DIOVectorfield& data
 	outfield->SetOrigin(0,0,0); 
 	outfield->SetSpacing(1.0, 1.0, 1.0); 
 	outfield->SetDimensions(data.get_size().x, data.get_size().y, data.get_size().z); 
-
+#if  VTK_MAJOR_VERSION < 6 
 	outfield->SetScalarType(VTK_FLOAT); 
 	outfield->SetNumberOfScalarComponents(3);
 	outfield->AllocateScalars(); 
+#else 
+	outfield->AllocateScalars(VTK_FLOAT, 3); 
+#endif 
 	
 	float *out_ptr =  reinterpret_cast<float*>(outfield->GetScalarPointer()); 
 	copy(&data[0].x, &data[0].x + data.size() * 3, out_ptr); 
@@ -114,7 +118,11 @@ bool CVtk3DVFIOPlugin::do_save(const string& fname, const C3DIOVectorfield& data
 	auto writer = vtkSmartPointer<vtkStructuredPointsWriter>::New(); 
 	writer->SetFileName(fname.c_str()); 
 	writer->SetFileTypeToBinary();
+#if  VTK_MAJOR_VERSION < 6 
 	writer->SetInput(outfield); 
+#else 
+	writer->SetInputData(outfield); 
+#endif 
 	return writer->Write();
 }
 
diff --git a/addons/vtk/vtkvf.hh b/addons/vtk/vtkvf.hh
index 2b5cea2..16e4ee5 100644
--- a/addons/vtk/vtkvf.hh
+++ b/addons/vtk/vtkvf.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index 58aea92..82a1ce2 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/cmake/checkSSEAttributeVectorCanUseSubscript.cmake b/cmake/checkSSEAttributeVectorCanUseSubscript.cmake
new file mode 100644
index 0000000..f8710b1
--- /dev/null
+++ b/cmake/checkSSEAttributeVectorCanUseSubscript.cmake
@@ -0,0 +1,40 @@
+#
+# Copyright (c) Leipzig, Madrid 1999-2011 Gert Wollny
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+#
+#
+
+#
+# check support for SSE support from the build system
+#
+
+CHECK_CXX_SOURCE_COMPILES(
+"
+#ifdef __SSE2__
+#include <emmintrin.h>
+#endif
+
+typedef double v2df __attribute__ ((vector_size (16)));
+
+int main(int argc, char *args[]) 
+{
+       v2df x; 
+       x[0] = 1.0; 
+       x[1] = 2.0; 
+       return 0; 
+}
+" BUILD_SSE_ATTRIBUTE_VECTOR_CAN_USE_SUBSCRIPT)
diff --git a/cmake/macros.cmake b/cmake/macros.cmake
index 3d3508a..8c495d7 100644
--- a/cmake/macros.cmake
+++ b/cmake/macros.cmake
@@ -124,7 +124,7 @@ MACRO(CREATE_EXE_DOCU name)
   
   ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}/doc/mia-${name}.xml
     COMMAND MIA_PLUGIN_TESTPATH=${PLUGIN_TEST_ROOT}/${PLUGIN_INSTALL_PATH} 
-    ./mia-${name} --help-xml >${CMAKE_BINARY_DIR}/doc/mia-${name}.xml
+    ./mia-${name} --help-xml ${CMAKE_BINARY_DIR}/doc/mia-${name}.xml
     COMMAND rm -f ${CMAKE_SOURCE_DIR}/doc/userref.stamp
     DEPENDS mia-${name} plugin_test_links )
     
diff --git a/cmake/pluginmacro.cmake b/cmake/pluginmacro.cmake
index 3410074..e813bb2 100644
--- a/cmake/pluginmacro.cmake
+++ b/cmake/pluginmacro.cmake
@@ -94,7 +94,7 @@ MACRO(PLUGIN_WITH_TEST plugname file libs)
   CREATE_PLUGIN_COMMON(${plugname} ${file} "${libs}")
   CREATE_PLUGIN_MODULE(${plugname})
   CREATE_PLUGIN_TEST(${plugname} test_${file} TESTLIBS "${PLUGIN_TESTLIBS}")
-ENDMACRO(PLUGIN_WITH_TEST  plugname file libs)
+ENDMACRO(PLUGIN_WITH_TEST plugname file libs)
 
 MACRO(PLUGIN_WITH_TEST_AND_PREFIX_NOINST prefix plugname libs)
   PARSE_ARGUMENTS(PLUGIN "TESTLIBS" "" ${ARGN})
@@ -168,3 +168,47 @@ MACRO(PLUGINGROUP_WITH_TEST_AND_PREFIX2 type data plugins libs)
 ENDMACRO(PLUGINGROUP_WITH_TEST_AND_PREFIX2)
 
 
+MACRO(PLUGIN_WITH_TEST_MULTISOURCE name type data src libs) 
+  PARSE_ARGUMENTS(PLUGIN "TESTLIBS" "" ${ARGN})
+  TEST_PREFIX(${type} ${data})
+  SET(install_path ${${type}_${data}_dir})
+  SET(plugname ${${type}_${data}_prefix}-${name})
+
+  # create common library 
+  ADD_LIBRARY(${plugname}-common STATIC ${src})
+  IF(NOT WIN32)
+	set_source_files_properties(${src}  PROPERTIES COMPILE_FLAGS "-fPIC")
+	set_target_properties(${plugname}-common  PROPERTIES COMPILE_FLAGS -DVSTREAM_DOMAIN='"${plugname}"') 
+  ENDIF(NOT WIN32)
+  TARGET_LINK_LIBRARIES(${plugname}-common ${libs})
+
+  # create module 
+  ADD_LIBRARY(${plugname} MODULE ${CMAKE_SOURCE_DIR}/mia/core/silence_cmake_missing_source_file_warning.c)
+  SET_TARGET_PROPERTIES(${plugname} PROPERTIES  PREFIX "" SUFFIX ${PLUGSUFFIX})
+  IF(NOT WIN32)
+    SET_TARGET_PROPERTIES(${plugname} PROPERTIES LINK_FLAGS "-Wl,--no-gc-sections -Wl,--undefined,get_plugin_interface")
+  ENDIF(NOT WIN32)
+  TARGET_LINK_LIBRARIES(${plugname} ${plugname}-common)
+  
+  # create tests
+  PARSE_ARGUMENTS(PLUGIN "TESTLIBS" "" ${ARGN})
+
+  add_executable(test-${plugname} test_${name}.cc)
+  IF(NOT WIN32)
+    set_target_properties(test-${plugname} PROPERTIES 
+      COMPILE_FLAGS -DVSTREAM_DOMAIN='"${plugname}"' 
+      COMPILE_FLAGS -DBOOST_TEST_DYN_LINK)
+  ELSE(NOT WIN32)
+    set_target_properties(test-${plugname} PROPERTIES
+      COMPILE_FLAGS -DBOOST_TEST_DYN_LINK)
+  ENDIF(NOT WIN32)
+  target_link_libraries(test-${plugname} ${plugname}-common)
+  target_link_libraries(test-${plugname} ${BOOST_UNITTEST} "${PLUGIN_TESTLIBS}")
+  add_test(${plugname} test-${plugname})
+  
+  ADD_CUSTOM_TARGET(${plugname}_test_link ln -sf "${CMAKE_CURRENT_BINARY_DIR}/${plugname}.mia" 
+    ${PLUGIN_TEST_ROOT}/${install_path}/ DEPENDS ${type}_${data}_testdir ${plugname})
+  ADD_DEPENDENCIES(plugin_test_links ${plugname}_test_link)
+  INSTALL(TARGETS ${plugname} LIBRARY DESTINATION ${install_path})
+ENDMACRO(PLUGIN_WITH_TEST_MULTISOURCE) 
+
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 94ba14d..8df7b73 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/doc/mainpage.doc b/doc/mainpage.doc
index 94d250a..f77fe13 100644
--- a/doc/mainpage.doc
+++ b/doc/mainpage.doc
@@ -31,7 +31,7 @@
   Classes and structures that start with two underscores, like __type_descr are traits, or other classes that are used 
   for template meta programming, i.e. the type based dispaching of function class.
 
-  \section naming_sec File names
+  \section naming_sec_files File names
   
   C++ Header files use the suffix ".hh",  C++ implementation files use ".cc". 
   For specific template implementations are only included for explicit template instanciations, the 
diff --git a/doc/miamyosegmentset.xsd b/doc/miamyosegmentset.xsd
index 0b95df6..c0a7b5f 100644
--- a/doc/miamyosegmentset.xsd
+++ b/doc/miamyosegmentset.xsd
@@ -3,7 +3,7 @@
      This is the scheme describing the storing of 
      manual segmentations of the myocardial perfusion series. 
      
-     Copyright (c) Leipzig, Madrid 1999-2012 Gert Wollny
+     Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
      
      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
@@ -36,6 +36,13 @@
   <xs:attribute name="open" type="xs:boolean"/>
   
   <!-- complex elements -->
+
+  <!-- The 2D point used for the lines  
+       Attributes:
+       x,y: coordinates 
+       size: reported size of the touch event. When using a mouse 
+             or a stylus this will should be set to zero. 
+  --> 
   <xs:element name="point">
     <xs:complexType>
       <xs:attribute ref="x" use="required"/>
@@ -43,7 +50,20 @@
       <xs:attribute ref="size"/>
     </xs:complexType>
   </xs:element>
-  
+
+  <!-- The star describing a simple approximation of the myocardium and 
+       its separation into equal sized parts. 
+       
+       Attributes: 
+       x,y: coordinates of the center 
+       r: radius of the enclosing circle
+       
+       Elements are:
+       3 points that define directions of six rays starting from the circle center, three 
+       rays in the directions indicated by the points and three in the opposite direction.
+       Of importance is te first ray as its intersection with the circle is set to indicate 
+       the location of the RV-LV insertion point. 
+  --> 
   <xs:element name="star">
     <xs:complexType>
       <xs:sequence>
@@ -54,7 +74,18 @@
       <xs:attribute ref="r" use="required"/>
     </xs:complexType>
   </xs:element>
-  
+
+  <!--
+      A segmented image area. 
+      
+      Attributes: 
+      color: the line color 
+      open: true if the line is not closed, false if the line is closed. 
+      
+      Elements: 
+      points that define the line. depending on the attribute "open" the last point 
+      should or not should be connected to the first point when interpreting the line 
+  -->  
   <xs:element name="section">
     <xs:complexType>
       <xs:sequence>
@@ -64,7 +95,25 @@
       <xs:attribute ref="open"/>
     </xs:complexType>
   </xs:element>
-  
+
+  <!--
+      A frame in a series of 2D images including its segmentation. 
+      
+      Attributes: 
+      image: the name of the corresponding image file 
+      quality: a subjective image quality rating
+      brightness: brightness adjustment used for better visualization of the image 
+      contrast; contrast  adjustment used for better visualization of the image 
+      
+      Elements: 
+      star: the circle defined above describing the an approximation of the LV endocardium. 
+      section: an abitraty number of segmented components. If two sections overlap, or
+      one section is completely enclosed by another, then the proper approach to interpret the 
+      segmentation is to combine the enclosed area by the XOR operation to obtain the full segmentation.
+      
+      Todo: 
+      An interpretation attribute should probably be added to make the segmentations usable for other data. 
+  -->
   <xs:element name="frame">
     <xs:complexType>
       <xs:sequence>
@@ -77,19 +126,35 @@
       <xs:attribute ref="contrast"/>
     </xs:complexType>
   </xs:element>
-
+  <!-- An element to indicate the right ventricle peak enhancement frame in a perfusion series 
+       
+       Attributes: 
+       value: the index of the frame (0 = first frame) 
+  -->   
   <xs:element name="RVpeak">
     <xs:complexType>
       <xs:attribute ref="value"/>
     </xs:complexType>
   </xs:element>
-  
+
+  <!-- An element to indicate the left ventricle peak enhancement frame in a perfusion series 
+       
+       Attributes: 
+       value: the index of the frame (0 = first frame) 
+  -->   
   <xs:element name="LVpeak">
     <xs:complexType>
       <xs:attribute ref="value"/>
     </xs:complexType>
   </xs:element>
-  
+
+  <!-- A description of the set 
+       
+       Elements: 
+       RVpeak: see above 
+       LVpeak: see above 
+       PreferedRef: preferred reference frame for perfusion analysis
+  -->   
   <xs:element name="description">
     <xs:complexType>
       <xs:sequence>
@@ -100,6 +165,15 @@
     </xs:complexType>
   </xs:element>
   
+  <!-- The complete series 
+       
+       Attributes: 
+       version: available for future reference
+       
+       Elements: 
+       description: see above 
+       frame:  an abitrary number of segmentation frames
+  -->
   <xs:element name="workset">
     <xs:complexType>
       <xs:sequence>
diff --git a/doc/miareadxml.py b/doc/miareadxml.py
index 1f95ebe..feef71e 100644
--- a/doc/miareadxml.py
+++ b/doc/miareadxml.py
@@ -17,6 +17,7 @@
 #
 
 
+import string
 from lxml import etree
 import re
 
@@ -35,6 +36,8 @@ xmlns = "{%s}" % xml_namespace
 #                tag required: 1 if required argument 
 #                tag default: default option value
 #                text: help 
+#          flags
+#                test; flags 
 #       dict          
 #  Example       text: example descripton 
 #    Code        text: example text without program name 
@@ -81,7 +84,15 @@ class CTextNode:
             raise ValueError("expected '%s' got '%s'" % (expect, node.tag))
 
         self.entry = node.tag
-        self.text  = node.text 
+        self.flags = []
+        self.text  = ""
+        if node.text is not None:
+            self.text = self.text + node.text
+
+        for child in node.iter("flags"):
+            self.flags = self.flags + string.split(child.text)
+            if child.tail is not None:
+                self.text = self.text + child.tail
 
 class COption(CTextNode):
     def __init__(self, node):
@@ -97,10 +108,13 @@ class COption(CTextNode):
         if len(self.short) > 0:
             short = "\-" + self.short
         else:
-            short = "  "; 
+            short = "  ";
 
-        if self.required:
-            print ".IP \"%s \-\-%s=(required)\""% (short, self.long)
+        if len(self.flags) > 0:
+            flagstring = self.flags[0]
+            for f in self.flags[1:]:
+                flagstring = flagstring + ',' + f
+            print ".IP \"%s \-\-%s=(%s)\""% (short, self.long, flagstring)
         else:
             if not self.type == "bool":
                 print ".IP \"%s \-\-%s=%s\""% (short, self.long, escape_dash(self.default))
@@ -119,8 +133,12 @@ class COption(CTextNode):
         if len(self.short) > 0: 
             termtext = termtext + self.short + ", -"
         termtext = termtext + "-" + self.long
-        if self.required: 
-            termtext = termtext + "=(required)"
+
+        if len(self.flags) > 0:
+            termtext = termtext + "=(" + self.flags[0]
+            for f in self.flags[1:]:
+                termtext = termtext + ',' + f
+            termtext = termtext + ")"
         elif self.type != "bool":
             termtext = termtext + "="
             if len(self.default)>0:
@@ -250,6 +268,12 @@ class CParam:
         self.default = node.get("default")
         self.required = int(node.get("required")) 
         self.text = node.text
+        self.flags = []
+
+        for child in node.iter("flags"):
+            self.flags = self.flags + string.split(child.text)
+            if child.tail is not None:
+                self.text = self.text + child.tail
 
         m = re.search('[,=:]', self.default) 
             # if there is a ',' in the text make clean that it needs to be escaped  
@@ -259,7 +283,13 @@ class CParam:
     def print_man(self):
         print ".I"
         print self.name
-        if self.required:
+        if len(self.flags) > 0:
+            termtext = "=(" + self.flags[0]
+            for f in self.flags[1:]:
+                termtext = termtext + ',' + f
+            termtext = termtext + ", %s)"
+            print termtext % (self.type)
+        elif self.required:
             print "= (required, %s) " % (self.type)
         else:
             print "= %s (%s) " % (escape_dash(self.default), self.type)
@@ -278,7 +308,12 @@ class CParam:
         e = etree.SubElement(row, "entry", align="center", valign="top")
         e.text = self.type
         e = etree.SubElement(row, "entry", align="center", valign="top")
-        if self.required: 
+        if len(self.flags) > 0:
+            e.text = "(" + self.flags[0]
+            for f in self.flags[1:]:
+                e.text = e.text + ',' + f
+            e.text = e.text + ')'
+        elif self.required: 
             e.text = "(required)"
         else:
             e.text = self.default
diff --git a/doc/reference.dox.cmake b/doc/reference.dox.cmake
index 9e5254c..a43c94d 100644
--- a/doc/reference.dox.cmake
+++ b/doc/reference.dox.cmake
@@ -113,8 +113,6 @@ MAN_EXTENSION          =
 MAN_LINKS              = NO
 GENERATE_XML           = NO
 XML_OUTPUT             = xml
-XML_SCHEMA             = 
-XML_DTD                = 
 GENERATE_AUTOGEN_DEF   = NO
 GENERATE_PERLMOD       = NO
 PERLMOD_LATEX          = NO
diff --git a/examples/2d/CMakeLists.txt b/examples/2d/CMakeLists.txt
index 5c592f3..782a0a3 100644
--- a/examples/2d/CMakeLists.txt
+++ b/examples/2d/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/examples/2d/filter/CMakeLists.txt b/examples/2d/filter/CMakeLists.txt
index 2b720b6..231e698 100644
--- a/examples/2d/filter/CMakeLists.txt
+++ b/examples/2d/filter/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/examples/2d/filter/simple.cc b/examples/2d/filter/simple.cc
index f6e5004..68c4a7c 100644
--- a/examples/2d/filter/simple.cc
+++ b/examples/2d/filter/simple.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/examples/2d/filter/simple.hh b/examples/2d/filter/simple.hh
index 7396a12..3e05076 100644
--- a/examples/2d/filter/simple.hh
+++ b/examples/2d/filter/simple.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/examples/2d/filter/test_simple.cc b/examples/2d/filter/test_simple.cc
index 2a044b5..d29335f 100644
--- a/examples/2d/filter/test_simple.cc
+++ b/examples/2d/filter/test_simple.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 03b2ef8..a799b0c 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/gsl++/CMakeLists.txt b/gsl++/CMakeLists.txt
index 47e7520..d5bdfe8 100644
--- a/gsl++/CMakeLists.txt
+++ b/gsl++/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/gsl++/gsldefines.hh b/gsl++/gsldefines.hh
index 55d29e6..69600b5 100644
--- a/gsl++/gsldefines.hh
+++ b/gsl++/gsldefines.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/matrix.cc b/gsl++/matrix.cc
index 4e8720a..924bde0 100644
--- a/gsl++/matrix.cc
+++ b/gsl++/matrix.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/matrix.hh b/gsl++/matrix.hh
index 736cdf7..3053b81 100644
--- a/gsl++/matrix.hh
+++ b/gsl++/matrix.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/multimin.cc b/gsl++/multimin.cc
index 296d18f..fc424e2 100644
--- a/gsl++/multimin.cc
+++ b/gsl++/multimin.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/multimin.hh b/gsl++/multimin.hh
index ed9a2bd..76258b9 100644
--- a/gsl++/multimin.hh
+++ b/gsl++/multimin.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/test_matrix.cc b/gsl++/test_matrix.cc
index 164f0a3..062a44a 100644
--- a/gsl++/test_matrix.cc
+++ b/gsl++/test_matrix.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/test_multimin.cc b/gsl++/test_multimin.cc
index 674ff47..390e942 100644
--- a/gsl++/test_multimin.cc
+++ b/gsl++/test_multimin.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/test_vector.cc b/gsl++/test_vector.cc
index 7ca16db..c7c96d9 100644
--- a/gsl++/test_vector.cc
+++ b/gsl++/test_vector.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/vector.cc b/gsl++/vector.cc
index 3bcbc3a..09e0a17 100644
--- a/gsl++/vector.cc
+++ b/gsl++/vector.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/vector.hh b/gsl++/vector.hh
index d255b3b..b026d40 100644
--- a/gsl++/vector.hh
+++ b/gsl++/vector.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/vector_dispatch.hh b/gsl++/vector_dispatch.hh
index 2cbd849..ec81cca 100644
--- a/gsl++/vector_dispatch.hh
+++ b/gsl++/vector_dispatch.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/vector_template.cxx b/gsl++/vector_template.cxx
index c58b62c..136a168 100644
--- a/gsl++/vector_template.cxx
+++ b/gsl++/vector_template.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/vector_template.hh b/gsl++/vector_template.hh
index 9de0bbe..6fe2020 100644
--- a/gsl++/vector_template.hh
+++ b/gsl++/vector_template.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/wavelet.cc b/gsl++/wavelet.cc
index 4faea8f..c6135d6 100644
--- a/gsl++/wavelet.cc
+++ b/gsl++/wavelet.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gsl++/wavelet.hh b/gsl++/wavelet.hh
index 55acb16..0887f9e 100644
--- a/gsl++/wavelet.hh
+++ b/gsl++/wavelet.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia.hh b/mia.hh
index 8a2f9b5..fde305c 100644
--- a/mia.hh
+++ b/mia.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d.hh b/mia/2d.hh
index 6d88f19..3236a60 100644
--- a/mia/2d.hh
+++ b/mia/2d.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,6 +32,7 @@
 #include <mia/2d/transformfactory.hh>
 #include <mia/2d/transformio.hh>
 #include <mia/2d/shape.hh>
+#include <mia/2d/maskedcost.hh>
 #include <mia/2d/model.hh>
 #include <mia/2d/timestep.hh>
 #include <mia/2d/nonrigidregister.hh>
diff --git a/mia/2d/BoundingBox.cc b/mia/2d/BoundingBox.cc
deleted file mode 100644
index da0abec..0000000
--- a/mia/2d/BoundingBox.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <mia/2d/BoundingBox.hh>
-
-
-NS_MIA_BEGIN
-
-C2DBoundingBox::C2DBoundingBox():
-	m_empty(true)
-{
-}
-
-C2DBoundingBox::C2DBoundingBox(const C2DFVector& begin, const C2DFVector& end):
-	m_empty(false),
-	m_begin(begin),
-	m_end(end)
-{
-	assert(m_begin.x <= m_end.x);
-	assert(m_begin.y <= m_end.y);
-}
-
-void C2DBoundingBox::unite(const C2DBoundingBox& other)
-{
-	if (m_empty) {
-		if (other.m_empty)
-			return;
-		*this = other;
-	}
-	if (other.m_begin.x < m_begin.x)
-		m_begin.x = other.m_begin.x;
-
-	if (other.m_begin.y < m_begin.y)
-		m_begin.y = other.m_begin.y;
-
-	if (other.m_end.x > m_end.x)
-		m_end.x = other.m_end.x;
-
-	if (other.m_end.y > m_end.y)
-		m_end.y = other.m_end.y;
-}
-
-C2DFVector C2DBoundingBox::get_begin() const
-{
-	assert(!m_empty);
-	return m_begin;
-}
-
-C2DFVector C2DBoundingBox::get_end() const
-{
-	assert(!m_empty);
-	return m_end;
-}
-
-C2DFVector C2DBoundingBox::get_size() const
-{
-	assert(!m_empty);
-	return m_end - m_begin;
-}
-
-C2DIVector C2DBoundingBox::get_grid_begin() const
-{
-	assert(!m_empty);
-	return C2DIVector((int)floor(m_begin.x),
-			  (int)floor(m_begin.y));
-}
-
-C2DIVector C2DBoundingBox::get_grid_end() const
-{
-	assert(!m_empty);
- 	return C2DIVector((int)ceil(m_end.x),
-			  (int)ceil(m_end.y));
-
-}
-
-C2DBounds C2DBoundingBox::get_grid_size() const
-{
-	assert(!m_empty);
-	return C2DBounds(get_grid_end() - get_grid_begin());
-}
-
-void C2DBoundingBox::add(const C2DFVector& point)
-{
-	if (m_empty) {
-		m_begin = m_end = point;
-		m_empty = false;
-		return;
-	}
-	if (point.x < m_begin.x)
-		m_begin.x = point.x;
-
-	if (point.y < m_begin.y)
-		m_begin.y = point.y;
-
-	if (point.x > m_end.x)
-		m_end.x = point.x;
-
-	if (point.y > m_end.y)
-		m_end.y = point.y;
-
-}
-
-void C2DBoundingBox::enlarge(float boundary)
-{
-	m_end.y += boundary;
-	m_end.x += boundary;
-	m_begin.y -= boundary;
-	m_begin.x -= boundary;
-
-}
-
-bool C2DBoundingBox::empty() const
-{
-	return m_empty;
-}
-
-NS_MIA_END
-
diff --git a/mia/2d/BoundingBox.hh b/mia/2d/BoundingBox.hh
deleted file mode 100644
index bed082a..0000000
--- a/mia/2d/BoundingBox.hh
+++ /dev/null
@@ -1,98 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef __mia_2d_boundingbox_hh
-#define __mia_2d_boundingbox_hh
-
-#include <mia/2d/vector.hh>
-#include <mia/2d/defines2d.hh>
-
-
-NS_MIA_BEGIN
-
-/// a 2D int vector 
-typedef T2DVector<int> C2DIVector;
-
-
-/**
-   @ingroup perf 
-   \brief 2D axis orthothogonal bounding box. 
- */
-class  EXPORT_2D C2DBoundingBox {
-public:
-	C2DBoundingBox();
-
-	/**
-	   Construct a new bounding box with 
-	   @param begin left lower corner 
-	   @param end right upper corner 
-	 */
-	C2DBoundingBox(const C2DFVector& begin, const C2DFVector& end);
-
-	/**
-	   Combine two bounding boxes 
-	   @param other box
-	 */
-	void unite(const C2DBoundingBox& other);
-
-	/**
-	   Change the box to include the given point 
-	   @param point 
-	 */
-	void add(const C2DFVector& point);
-
-
-	/// @returns left lower grid point 
-	C2DIVector get_grid_begin() const;
-	
-	/// @returns right upper grid point 
-	C2DIVector get_grid_end() const;
-
-	/// @returns size of bounding box in the grid  
-	C2DBounds get_grid_size() const;
-
-	/// @returns left lower bounding box point 
-	C2DFVector get_begin() const;
-	
-	/// @returns right upper  bounding box point 
-	C2DFVector get_end() const;
-
-	/// @returns size of bounding box 
-	C2DFVector get_size() const;
-
-
-	/** enlarge the bounding box by a given amount 
-	    @param boundary 
-	*/
-	void enlarge(float boundary);
-
-
-	/// @returns true if the box is not empty 
-	bool empty() const;
-
-private:
-	bool m_empty;
-	C2DFVector m_begin;
-	C2DFVector m_end;
-};
-
-NS_MIA_END
-
-#endif
diff --git a/mia/2d/CMakeLists.txt b/mia/2d/CMakeLists.txt
index 828145b..1b3f30c 100644
--- a/mia/2d/CMakeLists.txt
+++ b/mia/2d/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,28 +18,25 @@
 
 SET(MIA2D_SRC_BASE
   angle.cc
-  datafield.cc
-  vectorfield.cc
-  filter.cc
-  image.cc
-  imageio.cc
-  vfio.cc
-  BoundingBox.cc
-  cost.cc
+  boundingbox.cc
   correlation_weight.cc 
+  cost.cc
   creator.cc
   cstkernel.cc 
+  datafield.cc
   distance.cc
+  filter.cc
+  image.cc
+  imageio.cc
   interpolator.cc 
-#  fatcost.cc
+  filterchain.cc
   fftkernel.cc
   fuzzyseg.cc
-  fuzzyClusterSolverSOR.cc
-  fuzzyClusterSolverCG.cc
+  fuzzyclustersolver_sor.cc
+  fuzzyclustersolver_cg.cc
   fullcost.cc
-  filterchain.cc
+  maskedcost.cc 
   model.cc
-#  modelsolverreg.cc
   morphshape.cc
   multicost.cc
   nfg.cc
@@ -48,8 +45,8 @@ SET(MIA2D_SRC_BASE
   ppmatrix.cc
   rgbimageio.cc
   rigidregister.cc
-  similarity_profile.cc
   shape.cc
+  similarity_profile.cc
   sparse_image_solver.cc
   splinetransformpenalty.cc
   timestep.cc
@@ -57,24 +54,26 @@ SET(MIA2D_SRC_BASE
   transform.cc
   transformio.cc
   transformfactory.cc
+  vectorfield.cc
+  vfio.cc
   )
 
 
 SET(SEG_SRC 
-  SegPoint.cc 
-  SegStar.cc 
-  SegSection.cc 
-  SegFrame.cc 
-  SegSet.cc
-  SegSetWithImages.cc
+  segframe.cc 
+  segpoint.cc 
+  segsection.cc 
+  segset.cc
+  segsetwithimages.cc
+  segstar.cc 
   )
 SET(SEG_HEADER 
-  SegPoint.hh
-  SegStar.hh
-  SegSection.hh
-  SegFrame.hh
-  SegSet.hh
-  SegSetWithImages.hh
+  segpoint.hh
+  segstar.hh
+  segsection.hh
+  segframe.hh
+  segset.hh
+  segsetwithimages.hh
   )
 
 IF(ITPP_FOUND)
@@ -100,7 +99,7 @@ SET(MIA2D_HEADERS_BASE
   vector.hh
   vectorfield.hh
   vfio.hh
-  BoundingBox.hh
+  boundingbox.hh
   cost.hh
   correlation_weight.hh 
   creator.hh
@@ -108,21 +107,20 @@ SET(MIA2D_HEADERS_BASE
   defines2d.hh
   deformer.hh
   distance.hh
-#  fatcost.hh
   fullcost.hh
   filterchain.hh
   fftkernel.hh
   fuzzyseg.hh
-  fuzzyClusterSolverSOR.hh
-  fuzzyClusterSolverCG.hh
+  fuzzyclustersolver_sor.hh
+  fuzzyclustersolver_cg.hh
   ground_truth_evaluator.hh
   groundtruthproblem.hh
   interpolator.hh
   iterator.hh
   iterator.cxx
   matrix.hh
+  maskedcost.hh 
   model.hh
-#  modelsolverreg.hh
   morphshape.hh
   multicost.hh
   nonrigidregister.hh
@@ -165,7 +163,6 @@ SET(MIA2DLIBS mia2d  ${LIBS})
 # symbols, and in Windows, this is not supported# 
 SET(mia2dtestsrc 
   imageiotest.cc 
-  inittesthandlers.cc 
   vfiotest.cc 
   imagetest.cc
   transformmock.cc
@@ -197,7 +194,6 @@ TEST_2DMIA(distance mia2dtest)
 TEST_2DMIA(fullcost mia2dtest)
 TEST_2DMIA(interpol mia2dtest)
 TEST_2DMIA(matrix mia2dtest)
-#TEST_2DMIA(modelsolverreg mia2dtest)
 TEST_2DMIA(nfg mia2dtest)
 TEST_2DMIA(cost mia2dtest)
 TEST_2DMIA(iterator mia2dtest)
@@ -218,7 +214,6 @@ TEST_2DMIA(imageio mia2dtest)
 TEST_2DMIA(sparse_image_solver mia2dtest)
 TEST_2DMIA(filter_cast mia2d)
 TEST_2DMIA(splinetransformpenalty mia2d)
-#TEST_2DMIA(fullcost_mi_spline  mia2dtest)
 TEST_2DMIA(trackpoint mia2dtest)
 
 IF(CMAKE_BUILD_TYPE)
@@ -283,6 +278,7 @@ ADD_SUBDIRECTORY(fft       )
 ADD_SUBDIRECTORY(fullcost  )
 ADD_SUBDIRECTORY(kernel    )
 ADD_SUBDIRECTORY(model     )
+ADD_SUBDIRECTORY(maskedcost)
 ADD_SUBDIRECTORY(rgbio     )
 ADD_SUBDIRECTORY(shapes    )
 #ADD_SUBDIRECTORY(sparseimgsolver )
diff --git a/mia/2d/SegFrame.cc b/mia/2d/SegFrame.cc
deleted file mode 100644
index c5899b7..0000000
--- a/mia/2d/SegFrame.cc
+++ /dev/null
@@ -1,362 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdexcept>
-#include <string>
-#include <mia/2d/SegFrame.hh>
-#include <mia/core/msgstream.hh>
-#include <mia/core/errormacro.hh>
-#include <mia/core/bfsv23dispatch.hh>
-#include <mia/2d/imageio.hh>
-#include <mia/2d/angle.hh>
-
-#include <libxml++/libxml++.h>
-#include <boost/filesystem.hpp> 
-
-
-
-NS_MIA_BEGIN
-using namespace std; 
-using namespace xmlpp; 
-
-namespace bfs=boost::filesystem; 
-
-CSegFrame::CSegFrame():
-	m_has_star(false), 
-	m_version(0)
-{
-}
-
-CSegFrame::CSegFrame(const string& image, const CSegStar& star, const Sections& sections):
-	m_has_star(true),
-	m_star(star), 
-	m_sections(sections),  
-	m_filename(image), 
-	m_quality(0),
-	m_brightness(0), 
-	m_contrast(0), 
-	m_version(0)
-
-{
-}
-
-
-CSegFrame::CSegFrame(const Node& node, int version):
-	m_has_star(false), 
-	m_quality(0),
-	m_brightness(0), 
-	m_contrast(0), 
-	m_version(version)
-{
-	TRACE("CSegFrame::CSegFrame"); 
-	const Element& elm = dynamic_cast<const Element&>(node); 
-		
-	if (elm.get_name() != "frame")
-		throw invalid_argument(string("CSegFrame: unexpected node type: ") + elm.get_name()); 
-	
-	const Attribute *attr = elm.get_attribute("image"); 
-	if (!attr) {
-		throw invalid_argument("CSegFrame: image attribute not found"); 
-	}
-	m_filename = attr->get_value(); 
-	
-	Node::NodeList nodes = elm.get_children(); 
-	
-	for (auto i = nodes.begin(); i != nodes.end(); ++i) {
-
-		if ((*i)->get_name() == "star") {
-			m_star = CSegStar(**i); 
-			m_has_star = true; 
-		}
-		else if ((*i)->get_name() == "section") {
-			m_sections.push_back(CSegSection(**i, version)); 
-		}else {
-			cvinfo() << "ignoring unsuported element '" << (*i)->get_name() << "'\n"; 
-		}
-	}
-	
-	if (version > 1) {
-		if (version == 2 && m_sections.size() > 2)
-			cvwarn() << "CSegFrame: gor a version 2 segmentation, but more then two sections, this may be bogus\n";
-			
-		read_attribute_from_node(elm, "quality", m_quality);  
-		read_attribute_from_node(elm, "brightness", m_brightness);  
-		read_attribute_from_node(elm, "contrast", m_contrast);  
-	}
-}
-
-const std::string& CSegFrame::get_imagename() const
-{
-	return m_filename; 
-}
-
-void CSegFrame::set_imagename(const std::string& name)
-{
-	m_filename = name; 
-}
-
-void CSegFrame::rename_base(const std::string& new_base)
-{
-	bfs::path filename(m_filename); 
-	string suffix = __bfs_get_extension(filename); 
-	string name = __bfs_get_stem(filename);
-	auto i = name.rbegin();
-	int k = 0; 
-	while (i != name.rend() && isdigit(*i) ) {
-		++i; 
-		++k; 
-	}
-	string number(name.end() - k, name.end()); 
-	m_filename = new_base + number + suffix; 
-}
-
-const CSegFrame::Sections& CSegFrame::get_sections()const
-{
-	return m_sections; 
-}
-
-
-const CSegStar& CSegFrame::get_star() const
-{
-	if (!m_has_star) 
-		cvwarn() << "CSegFrame::get_star(): returing fake star"; 
-	return m_star; 
-}
-
-
-void CSegFrame::write(Node& node, int version) const
-{
-	Element* self = node.add_child("frame"); 
-	self->set_attribute("image", m_filename); 	
-
-	if (version > 1) {
-		self->set_attribute("quality", to_string<float>(m_quality)); 	
-		self->set_attribute("brightness", to_string<float>(m_brightness)); 	
-		self->set_attribute("contrast", to_string<float>(m_contrast)); 	
-	}
-	
-	if (m_has_star) 
-		m_star.write(*self);
-	for (auto i = m_sections.begin(); 
-	     i != m_sections.end(); ++i) {
-		i->write(*self, version); 
-	}
-}
-
-const C2DBoundingBox CSegFrame::get_boundingbox() const
-{
-	C2DBoundingBox result; 
-	for (auto i = m_sections.begin(); 
-	     i != m_sections.end(); ++i) {
-		result.unite(i->get_boundingbox()); 
-	}
-	return result; 
-}
-
-void CSegFrame::shift(const C2DFVector& delta, const std::string& cropped_file)
-{
-	if (m_has_star) 
-		m_star.shift(delta); 
-	for (auto i = m_sections.begin(); 
-	     i != m_sections.end(); ++i)
-		i->shift(delta); 
-	m_filename = cropped_file; 
-}
-
-void CSegFrame::transform(const C2DTransformation& t)
-{
-	if (m_has_star) 
-		m_star.transform(t); 
-	for (auto i = m_sections.begin(); 
-	     i != m_sections.end(); ++i)
-		i->transform(t); 
-}
-
-void CSegFrame::set_image(P2DImage image)
-{
-	m_image = image; 
-}
-
-
-void CSegFrame::inv_transform(const C2DTransformation& t)
-{
-	if (m_has_star) 
-		m_star.inv_transform(t); 
-	for (auto i = m_sections.begin(); i != m_sections.end(); ++i)
-		i->inv_transform(t); 
-}
-
-
-float CSegFrame::get_hausdorff_distance(const CSegFrame& other) const
-{
-	C2DPolygon p1; 
-	for(auto s = m_sections.begin(); 
-	    s != m_sections.end(); ++s) 
-		s->append_to(p1); 
-
-
-	C2DPolygon p2; 
-	for(auto s = other.m_sections.begin(); 
-	    s != other.m_sections.end(); ++s) 
-		s->append_to(p2); 
-
-	return p1.get_hausdorff_distance(p2); 
-}
-
-
-C2DUBImage CSegFrame::get_section_masks(const C2DBounds& size) const 
-{
-	C2DUBImage result(size); 
-	if (m_version == 2) {
-		// in version 2 all sections are xor-ed,
-		for (auto i = m_sections.begin(); 
-		     i != m_sections.end(); ++i)
-			i->draw_xor(result); 
-	}else {
-		unsigned char idx = 1; 
-		for (auto i = m_sections.begin(); 
-		     i != m_sections.end(); ++i, ++idx)
-			i->draw(result, idx); 
-	}
-	return result; 
-}
-
-void CSegFrame::load_image() const
-{
-	m_image = load_image2d(m_filename); 
-	if (!m_image) 
-		throw create_exception<runtime_error>( "unable to find image file '", m_filename, "'");
-}
-
-C2DUBImage CSegFrame::get_section_masks() const
-{
-	if (!m_image)
-                load_image(); 
-	return get_section_masks(m_image->get_size()); 
-}
-
-C2DUBImage CSegFrame::get_section_masks(size_t n_sections) const
-{
-	if (!m_image) 		
-		load_image(); 
-	C2DUBImage result = get_section_masks(m_image->get_size()); 
-	if (n_sections != 0 && n_sections != m_sections.size()) {
-		const C2DFVector ray_a = m_star.m_directions[0]; 
-		
-		const double scale = n_sections / (2 * M_PI); 
-		
-		// make a mask and re-run 
-		auto i = result.begin(); 
-		for (size_t y = 0; y < result.get_size().y; ++y)  {
-			for (size_t x = 0; x < result.get_size().x; ++x, ++i)  {
-				if (*i) {
-					const C2DFVector ray_b(static_cast<float>(x) - m_star.m_center.x, 
-							       static_cast<float>(y) - m_star.m_center.y); 
-					double a = scale * angle(ray_a, ray_b);
-					if (a >= n_sections) 
-						a -= n_sections; 
-					*i = (unsigned char) (a + 1.0); 
-				}
-			}
-		}
-	}
-	return result; 
-}
-
-struct EvalMaskStat: public TFilter<CSegFrame::SectionsStats> {
-
-	EvalMaskStat(const C2DUBImage& mask):
-		m_mask(mask) {
-		max_idx = *max_element(mask.begin(), mask.end());
-	}; 
-	
-	template <typename T> 
-	CSegFrame::SectionsStats operator ()(const T2DImage<T>& image) const {
-		CSegFrame::SectionsStats result(max_idx); 
-		vector<size_t> size(max_idx, 0); 
-		auto k = image.begin();
-		for(auto m=m_mask.begin(); m != m_mask.end(); ++k, ++m) {
-			const double v = *k;
-			if (*m) {
-				result[*m-1].first  += v; 
-				result[*m-1].second += v * v; 
-				++size[*m-1]; 
-			}
-		}
-		auto n=size.begin();
-		for (auto i = result.begin(); i != result.end(); ++i, ++n) {
-			if (*n) 
-				i->first /= *n; 
-			if (*n > 1) 
-				i->second = sqrt( (i->second - i->first * i->first * *n)/ (*n - 1)); 
-		}
-		return result; 
-	}
-private: 
-	const C2DUBImage& m_mask; 
-	unsigned char max_idx; 
-}; 
-
-CSegFrame::SectionsStats CSegFrame::get_stats(const C2DUBImage& mask) const
-{
-	if (!m_image)
-		load_image(); 
-	if (mask.get_size() != m_image->get_size()) 
-		throw create_exception<invalid_argument>( "Mask image ",mask.get_size(), " and data image ", 
-						m_image->get_size(), " are of different size");
-	
-	return ::mia::filter(EvalMaskStat(mask), *m_image);  
-
-
-}
-
-CSegFrame::SectionsStats CSegFrame::get_stats(size_t n_sections) const
-{
-	if (!m_image) {
-		m_image = load_image2d(m_filename); 
-		if (!m_image) 
-			throw create_exception<runtime_error>( "unable to find image file '", m_filename, "'");
-	}
-	C2DUBImage mask = get_section_masks(n_sections); 
-	return get_stats(mask); 
-}
-
-size_t CSegFrame::get_nsections() const
-{
-	return m_sections.size(); 
-}
-
-float CSegFrame::get_quality() const
-{
-	return m_quality; 
-}
-
-float CSegFrame::get_brightness() const
-{
-	return m_brightness; 
-}
-
-float CSegFrame::get_contrast() const
-{
-	return m_contrast; 
-}
-
-
-NS_MIA_END
diff --git a/mia/2d/SegFrame.hh b/mia/2d/SegFrame.hh
deleted file mode 100644
index d305889..0000000
--- a/mia/2d/SegFrame.hh
+++ /dev/null
@@ -1,221 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef SegFrame_h
-#define SegFrame_h
-
-#include <vector>
-#include <mia/2d/SegStar.hh>
-#include <mia/2d/SegSection.hh>
-#include <mia/2d/image.hh>
-
-NS_MIA_BEGIN
-
-/**
-   @ingroup perf 
-   \brief A class to represent one segmented frame in a heart perfusion series 
-   
-   This class implements the frame of a myocardial segmentation consisting of 
-   six sections CSegsection, the segmentation helper CSegStar, and the name of the 
-   corresponding image file.  
-*/
-class  EXPORT_2D CSegFrame {
-public:
-	/// convenience typedef for the sections 
-	typedef std::vector<CSegSection> Sections;
-	
-	/** convenience typedef for the statistics values  
-	    @remark maybe a type with more meaningful elements would be better 
-	 */ 
-	typedef std::pair<float, float> Statistics; 
-	
-	/// convenience typedef for the section statistics vector 
-	typedef std::vector<Statistics> SectionsStats; 
-	
-	
-	CSegFrame();
-
-	/**
-	   Construct the segmentation frame from 
-	   \param image image file name 
-	   \param star CSegStar 
-	   \param sections the segmentation sections 
-	 */
-	CSegFrame(const std::string& image, const CSegStar& star, const Sections& sections);
-
-	/**
-	   Construct the segmentation frame from a XML root node
-	   \param node
-	   \param version segmentation set version the node stems from. 
-	 */
-	CSegFrame(const xmlpp::Node& node, int version);
-
-	/// \returns the file name of the corresponding image 
-	const std::string& get_imagename() const;
-
-	/** set the file name of the corresponding image 
-	    \param name 
-	 */
-	void set_imagename(const std::string& name);
-
-	/** rename the file name base of the image according to 
-	    sed -e "s/.*[^0-9]\([0-9]*\..*\)/$new_base\1/"
-	    \param new_base
-	 */
-	void rename_base(const std::string& new_base); 
-
-	/// \returns a read-only reference to the segmentation sections 
-	const Sections& get_sections() const;
-
-	/**
-	   Set the image corresponding to the segmentation frame 
-	   @param image 
-	 */
-	void set_image(P2DImage image); 
-
-	/**
-	   @returns the star of the LV contained in this frame 
-	 */
-	const CSegStar& get_star() const;
-
-	/// @returns the bounding box enclosing all segmentation sections belonging to thie frame 
-	const C2DBoundingBox get_boundingbox() const;
-
-
-	/**
-	   Append the segmentation frame to a XML node 
-	   @param node parent node to append the frame description to 
-	   @param version segmentation set file version that should be used to save the data
-	 */
-	void write(xmlpp::Node& node, int version) const;
-
-	/**
-	   Shift the segmentation frame and change the file name to the new name 
-	   corresponding to the shifted image 
-	   @param delta translation 
-	   @param cropped_file new image file name 
-	*/
-	void shift(const C2DFVector& delta, const std::string& cropped_file);
-
-
-	/**
-	   transform the frame segmentation by a given transformation 
-	   @param t 
-	 */
-	void transform(const C2DTransformation& t);
-
-	/**
-	   transform the frame segmentation by the inverse of the given transformation 
-	   @param t 
-	 */
-	void inv_transform(const C2DTransformation& t);
-
-	/**
-	   Evaluate the Hausdorff distance of this segmentation frame to another 
-	   @param other 
-	   @returns Hausdorff distance
-	 */
-	float get_hausdorff_distance(const CSegFrame& other) const;
-
-
-	/**
-	   Evaluate a mask image based on the segmented sections
-	   @param size size of the output image 
-	   @returns an image containing the masks for each section  numbered in the storage 
-	   order of the sections
-	   @remark If overlap exists between the sections the masks with a higher index overwrite 
-	   the masks with a lower index. 
-	 */
-	C2DUBImage get_section_masks(const C2DBounds& size) const; 
-
-	/**
-	   Create the section masks by using the size of the image corresponding to the frame 
-	   @returns the mask image, for details see get_section_masks(const C2DBounds& size). 
-	 */
-	C2DUBImage get_section_masks() const; 
-
-	/**
-	   Create the section masks by using the size of the image corresponding to the frame. 
-	   If the number of requested sections is equal to the number of sections stored, this 
-	   call is equal to get_section_masks(), 
-           Otherwiese, instead of using the sections as defined, evaluate the union of all the sections 
-	   and then split this union evenly in \a n_sections starting by the first directional ray 
-	   and moving clockwiese with the star center as the angular point. 
-	   @param n_sections number of target sections 
-	   @returns the mask image, for details see get_section_masks(const C2DBounds& size). 
-	 */
-	C2DUBImage get_section_masks(size_t n_sections) const; 
-
-
-	/**
-	   Evaluate inetnsity mean and variation of the image data for the registions  
-	   defined by the given mask image. 
-	   @param mask 
-	   @returns the statustics 
-	 */
-	SectionsStats get_stats(const C2DUBImage& mask) const; 
-	
-	/**
-	   Evaluate inetnsity mean and variation of the image data for the registions  
-	   defined the get_section_masks(size_t n_sections) method. 
-	   @param n_sections 
-	   @returns the statustics 
-	 */
-	SectionsStats get_stats(size_t n_sections) const; 
-
-	/**
-	   \returns number of segmented sections 
-	 */
-	size_t get_nsections() const; 
-
-	/**
-	   \returns slice quality rating 
-	 */
-	float get_quality() const; 
-
-	/**
-	   \returns proposed brightness correction 
-	 */
-	float get_brightness() const; 
-	
-         /**
-	    \returns proposed contrast correction 
-	 */
-	float get_contrast() const; 
-	
-private:
-	void load_image() const; 
-
-	bool m_has_star;
-	CSegStar m_star;
-	Sections m_sections;
-	std::string m_filename;
-	mutable P2DImage m_image; 
-
-	float m_quality; 
-	float m_brightness; 
-	float m_contrast; 
-	int m_version; 
-};
-
-NS_MIA_END
-
-#endif
-
diff --git a/mia/2d/SegPoint.cc b/mia/2d/SegPoint.cc
deleted file mode 100644
index f6f4632..0000000
--- a/mia/2d/SegPoint.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <sstream>
-#include <stdexcept>
-#include <cassert>
-#include <mia/2d/SegPoint.hh>
-#include <mia/core/tools.hh>
-#include <libxml++/libxml++.h>
-
-NS_MIA_BEGIN
-
-using namespace xmlpp;
-using namespace std;
-
-void read_attribute_from_node(const Element& elm, const std::string& key, bool& out_value, bool required)
-{
-	auto attr = elm.get_attribute(key);
-	if (!attr) {
-		if (required) 
-			throw create_exception<runtime_error>( elm.get_name(), ":required attribute '", key, "' not found"); 
-		else
-			return; 
-	}
-	
-	if (attr->get_value() == string("false")) 
-		out_value = false; 
-	else if (attr->get_value() == string("true")) 
-		out_value = true; 
-	else 
-		throw create_exception<runtime_error>( elm.get_name(), ":attribute '", key, "' has bogus value '", 
-						       attr->get_value(), "'");
-}
-
-CSegPoint2D::CSegPoint2D()
-{
-}
-
-CSegPoint2D::CSegPoint2D(const C2DFVector& org): C2DFVector(org)
-{
-}
-
-	
-CSegPoint2D& CSegPoint2D::operator = (const C2DFVector& org)
-{
-	C2DFVector::operator =(org); 
-	return *this; 
-}
-
-
-CSegPoint2D::CSegPoint2D(float x, float y):
-	C2DFVector(x,y)
-{
-}
-
-CSegPoint2D::CSegPoint2D(const Node& node)
-{
-	const Element& elm = dynamic_cast<const Element&>(node);
-	Attribute *ax = elm.get_attribute ("x");
-	Attribute *ay = elm.get_attribute ("y");
-	if (!ax || !ay)
-		throw runtime_error("SegSection:Point attribute x or y not found");
-	
-	if (!from_string(ax->get_value(), x)) 
-		throw create_exception<runtime_error>( "CSegPoint2D: x attribute '", 
-					     ax->get_value(), "' is not a floating point value"); 
-
-	if (!from_string(ay->get_value(), y)) 
-		throw create_exception<runtime_error>( "CSegPoint2D: y attribute '", 
-					     ay->get_value(), "' is not a floating point value");
-}
-
-void CSegPoint2D::write(Node& node) const
-{
-	Element* point = node.add_child("point");
-	point->set_attribute("y", to_string<float>(y));
-	point->set_attribute("x", to_string<float>(x));
-}
-
-void CSegPoint2D::transform(const C2DTransformation& t)
-{
-	const C2DFVector r =  t(*this); 
-	x = r.x; 
-	y = r.y;
-}
-
-void CSegPoint2D::inv_transform(const C2DTransformation& t)
-{
-	C2DFVector r(x,y); 
-	cvdebug() << r << "\n"; 
-	int niter = 0; 
-	C2DFVector delta = t(r) - *this; 
-	while (delta.norm2() > 0.000001 && niter++ < 100) {
-		r -= 0.1 * delta; 
-		delta = t(r) - *this; 
-		cvdebug() << r << delta << "\n"; 
-	}
-	x = r.x; 
-	y = r.y; 
-}
-
-
-NS_MIA_END
diff --git a/mia/2d/SegPoint.hh b/mia/2d/SegPoint.hh
deleted file mode 100644
index e095f81..0000000
--- a/mia/2d/SegPoint.hh
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef mia_2d_SegPoint_hh
-#define mia_2d_SegPoint_hh
-
-namespace xmlpp {
-	class Node;
-};
-
-#include <mia/2d/vector.hh>
-#include <mia/2d/defines2d.hh>
-#include <mia/2d/transform.hh>
-
-NS_MIA_BEGIN
-
-/**
-   @ingroup perf 
-   \brief a point in a 2D segmentation shape 
-
-   Point of a segmentation shape. In addition to be a 2D point it can be 
-   read from and written to a XML tree and supports its own tranformation. 
-*/
-
-class  EXPORT_2D CSegPoint2D: public C2DFVector {
-public:
-	CSegPoint2D();
-
-	/// copy constructor 
-	CSegPoint2D(const C2DFVector& org);
-
-	/// assignment operator 
-	CSegPoint2D& operator = (const C2DFVector& org);
-
-	/**
-	   Construct the point with the given coordinates
-	   \param x
-	   \param y
-	 */
-	CSegPoint2D(float x, float y);
-
-	/**
-	   Construct the point from a XML node
-	   \param node
-	 */
-	CSegPoint2D(const xmlpp::Node& node);
-
-	/** Write the point as child-node to a given XML tree
-	    \param node 
-	*/
-	void write(xmlpp::Node& node) const;
-
-	/**
-	   Tranform the point according to the given tranformation 
-	   \param t 
-	 */
-	void transform(const C2DTransformation& t); 
-	
-	/**
-	   Evaluate an approximation of the inverse of the given transform of the point
-	   \param t 
-
-	 */
-	void inv_transform(const C2DTransformation& t); 
-};
-
-
-template <typename T>
-void read_attribute_from_node(const xmlpp::Element& elm, const std::string& key, T& out_value, bool required = false)
-{
-	auto attr = elm.get_attribute(key);
-	if (!attr) {
-		if (required) 
-			throw create_exception<std::runtime_error>( elm.get_name(), ":required attribute '", key, "' not found"); 
-		else 
-			return; 
-	}
-	
-	if (!from_string(attr->get_value(), out_value)) 
-		throw create_exception<std::runtime_error>( elm.get_name(), ":attribute '", key, "' has bogus value '", 
-						       attr->get_value(), "'");
-}
-
-
-void read_attribute_from_node(const xmlpp::Element& elm, const std::string& key, bool& out_value, bool required = false); 
-
-NS_MIA_END
-
-#endif
diff --git a/mia/2d/SegSection.cc b/mia/2d/SegSection.cc
deleted file mode 100644
index 988c747..0000000
--- a/mia/2d/SegSection.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#define VSTREAM_DOMAIN "SegSection"
-#include <stdexcept>
-#include <mia/core/msgstream.hh>
-#include <mia/2d/SegSection.hh>
-#include <libxml++/libxml++.h>
-
-
-NS_MIA_BEGIN
-using namespace std;
-
-CSegSection::CSegSection():
-	m_is_open(false)
-{
-}
-
-CSegSection::CSegSection(const string& id, const Points& points, bool is_open):
-	m_id(id),
-	m_points(points), 
-	m_is_open(is_open)
-{
-}
-
-CSegSection::CSegSection(xmlpp::Node& node, int version):
-	m_is_open(false)
-{
-	TRACE("CSegSection::CSegSection");
-
-	xmlpp::Element& elm = dynamic_cast<xmlpp::Element&>(node);
-	xmlpp::Attribute *id = elm.get_attribute ("color");
-
-	if (!id)
-		throw invalid_argument("CSegSection::CSegSection: node without id");
-	m_id = id->get_value();
-
-	xmlpp::Node::NodeList points = node.get_children("point");
-
-	for (auto i = points.begin(); i != points.end(); ++i)
-		m_points.push_back(CSegPoint2D(**i));
-
-	if (version > 1) {
-		read_attribute_from_node(elm, "open", m_is_open);  
-	}
-}
-
-const string& CSegSection::get_id() const
-{
-	return m_id;
-}
-
-const CSegSection::Points& CSegSection::get_points()const
-{
-	return m_points;
-}
-
-void CSegSection::shift(const C2DFVector& delta)
-{
-	Points::iterator ip = m_points.begin();
-	Points::iterator ep = m_points.end();
-
-	while (ip != ep) {
-		*ip -= delta;
-		++ip;
-	}
-}
-
-void CSegSection::transform(const C2DTransformation& t)
-{
-	for(auto i = m_points.begin(); i != m_points.end(); ++i) 
-		i->transform(t);
-}
-
-
-void CSegSection::inv_transform(const C2DTransformation& t)
-{
-	for(auto i = m_points.begin(); i != m_points.end(); ++i) 
-		i->inv_transform(t);
-}
-
-
-void CSegSection::write(xmlpp::Node& node, int version) const
-{
-	xmlpp::Element* nodeChild = node.add_child("section");
-	nodeChild->set_attribute("color", m_id);
-
-	if (version > 1) {
-		nodeChild->set_attribute("open", m_is_open ? "true" : "false");
-	}
-
-	Points::const_iterator ip = m_points.begin();
-	Points::const_iterator ep = m_points.end();
-
-	while (ip != ep) {
-		ip->write(*nodeChild);
-		++ip;
-	}
-}
-
-const C2DBoundingBox CSegSection::get_boundingbox() const
-{
-
-	C2DBoundingBox result;
-
-	Points::const_iterator ip = m_points.begin();
-	Points::const_iterator ep = m_points.end();
-
-	while (ip != ep) {
-		result.add(*ip++);
-	}
-	return result;
-}
-
-void CSegSection::append_to(C2DPolygon& polygon)const
-{
-	typedef std::vector<CSegPoint2D>::const_iterator point_iterator;
-	for(point_iterator i = m_points.begin(); i != m_points.end(); ++i)
-		polygon.append(*i);
-
-}
-
-float CSegSection::get_hausdorff_distance(const CSegSection& other) const
-{
-
-	C2DPolygon p1;
-	append_to(p1);
-
-	C2DPolygon p2;
-	other.append_to(p2);
-
-	return p1.get_hausdorff_distance(p2);
-}
-
-template <typename FDrawOperator> 
-void draw_private(C2DUBImage& mask, const CSegSection::Points& points,  const FDrawOperator& op)
-{
-	for (size_t y=0; y < mask.get_size().y; y++) {
-		vector<int> nodeX; 
-		int j=points.size()-1;
-		for (size_t i=0; i<points.size(); i++) {
-			if ((points[i].y <= y && points[j].y > y) || 
-			    (points[j].y <= y && points[i].y > y) ) {
-				nodeX.push_back( (int) (points[i].x + 
-						       ( y - points[i].y)/(points[j].y-points[i].y)
-							*(points[j].x - points[i].x)) + 0.5); 
-			}
-			j=i; 
-		}
-		
-		sort(nodeX.begin(), nodeX.end()); 
-		
-		//  Fill the pixels between node pairs.
-		for (size_t i=0; i<nodeX.size(); i+=2) {
-			if   (nodeX[i  ]>=(int)mask.get_size().x) 
-				break;
-			if   (nodeX[i+1]> 0 ) {
-				if (nodeX[i  ] < 0 ) 
-					nodeX[i  ]=0;
-				if (nodeX[i+1] > (int)mask.get_size().x) 
-					nodeX[i+1]=mask.get_size().x;
-				for (int j=nodeX[i]; j<nodeX[i+1]; j++) 
-					op(mask(j,y));
-			}
-		}
-	}
-	
-}
-
-void CSegSection::draw_xor(C2DUBImage& mask)const
-{
-	if (m_is_open) 
-		throw invalid_argument("CSegSection: Section not closed, hence no filled polygon can be drawn"); 
-	auto xor_draw = [](unsigned char& pixel) { pixel ^= 1 ;}; 
-	draw_private(mask, m_points, xor_draw); 
-}
-
-void CSegSection::draw(C2DUBImage& mask, unsigned char color)const
-{
-	if (m_is_open) 
-		throw invalid_argument("CSegSection: Section not closed, hence no filled polygon can be drawn"); 
-	auto color_draw = [color](unsigned char& pixel) { pixel = color;};
-	draw_private(mask, m_points, color_draw); 
-}
-
-bool CSegSection::is_open() const
-{
-	return m_is_open; 
-}
-
-NS_MIA_END
diff --git a/mia/2d/SegSection.hh b/mia/2d/SegSection.hh
deleted file mode 100644
index 1fa26da..0000000
--- a/mia/2d/SegSection.hh
+++ /dev/null
@@ -1,138 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef SegSection_h
-#define SegSection_h
-
-#include <vector>
-#include <string>
-
-#include <mia/2d/SegPoint.hh>
-#include <mia/2d/BoundingBox.hh>
-#include <mia/2d/polygon.hh>
-
-NS_MIA_BEGIN
-
-/**
-   @ingroup perf 
-   \brief Segmentation class to represent a section of the LV myocardium 
-
-   Structure to save the segmentation of a section of the myocardium. 
-   In theory this can be used for any king of segmentation that uses 
-   a polynom to approximate a segmented 2D shape. 
-*/
-
-
-class  EXPORT_2D CSegSection {
-public:
-	/// convenicence typedef for the points defining the section 
-	typedef std::vector<CSegPoint2D> Points;
-	
-	/// default constructor 
-	CSegSection();
-
-	/**
-	   Constructor to create a segmentation shape and naming it 
-	   @param id ID of the section (and color identifier) 
-	   @param points the points that define a closed polynom representing the shape 
-	   @param is_open describes if points should be interpreted as polygon 
-	   (i.e. the last point connects to the first), or as poly-line only.
-	 */
-	CSegSection(const std::string& id, const Points& points, bool is_open);
-
-	/**
-	   Constructor to create a segmentation shape based on a XML sub tree 
-	   @param node root of the XML sub tree 
-	   \param version segmentation set version the node stems from. 
-	*/
-	CSegSection(xmlpp::Node& node, int version);
-
-	/**
-	   Store the segmented section into a XML sub-tree 
-	   @param node parent node to which the subtree should be added 
-	   \param version segmentation set version the node stems from. 
-	*/
-	void write(xmlpp::Node& node, int version) const;
-
-	/// \returns the ID of the section 
-	const std::string& get_id() const;
-
-	/// \returns the list of the points defining the section shape 
-	const Points& get_points()const;
-
-	/// \returns the orthogonal bounding box enclosing the shape 
-	const C2DBoundingBox get_boundingbox() const;
-
-	/**
-	   translate the segmentation by a given shift 
-	   @param delta 
-	 */
-	void shift(const C2DFVector& delta);
-
-	/**
-	   Evaluate the Hausdorff distance between this shape and another one 
-	   @param other 
-	   @returns the Hausdorff distance
-	 */
-	float get_hausdorff_distance(const CSegSection& other) const;
-
-	/**
-	   Append this shape to another shape, a very crude version of a logical or 
-	   @param polygon to add the shape to 
-	*/
-	void append_to(C2DPolygon& polygon)const;
-
-	/**
-	   transform the shape by transforming its individual points 
-	   @param t the transformation to be applied 
-	 */
-	void transform(const C2DTransformation& t); 
-
-	/**
-	   transform the shape by transforming its individual points 
-	   @param t the inverse of the transformation to be applied 
-	 */
-	void inv_transform(const C2DTransformation& t); 
-
-	/**
-	   Draw the shape to a 2D image with a given color 
-	   @param output image to draw to 
-	   @param color color to use 
-	 */
-	void draw(C2DUBImage& output, unsigned char color)const; 
-
-	/**
-	   Draw the binary shape to a 2D image by xor-ing with what is already in there 
-	   @param output image to draw to 
-	*/
-	void draw_xor(C2DUBImage& output)const; 
-
-	/// \returns whether the curve is open (true) or closed (false). 
-	bool is_open() const; 
-
-private:
-	std::string m_id;
-	Points m_points;
-	bool m_is_open; 
-};
-
-NS_MIA_END
-
-#endif
diff --git a/mia/2d/SegSet.cc b/mia/2d/SegSet.cc
deleted file mode 100644
index 890824a..0000000
--- a/mia/2d/SegSet.cc
+++ /dev/null
@@ -1,254 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <libxml++/libxml++.h>
-#include <mia/2d/SegSet.hh>
-#include <mia/core/msgstream.hh>
-#include <mia/core/filetools.hh>
-#include <mia/core/tools.hh>
-
-
-
-NS_MIA_BEGIN
-using namespace std;
-using namespace xmlpp;
-
-
-CSegSet::CSegSet():
-	m_RV_peak(-1),
-	m_LV_peak(-1), 
-	m_preferred_reference(-1), 
-	m_version(1)
-{
-}
-
-CSegSet::CSegSet(const std::string& src_filename):
-	m_RV_peak(-1),
-	m_LV_peak(-1),
-	m_preferred_reference(-1), 
-	m_version(1)
-{
-	DomParser parser;
-	parser.set_substitute_entities(); //We just want the text to be resolved/unescaped automatically.
-	parser.parse_file(src_filename);
-
-	if (!parser)
-		throw runtime_error(string("CSegSet: Unable to parse input file:") + src_filename);
-
-	read(*parser.get_document());
-
-}
-
-CSegSet::CSegSet(const xmlpp::Document& doc):
-	m_RV_peak(-1),
-	m_LV_peak(-1), 
-	m_preferred_reference(-1), 
-	m_version(1)
-{
-	TRACE("CSegSet::CSegSet");
-	read(doc);
-}
-
-void CSegSet::add_frame(const CSegFrame& frame)
-{
-	m_frames.push_back(frame);
-}
-
-const CSegSet::Frames& CSegSet::get_frames() const
-{
-	return m_frames;
-}
-
-CSegSet::Frames& CSegSet::get_frames()
-{
-	return m_frames;
-}
-
-void CSegSet::rename_base(const std::string& new_base)
-{
-	for (auto i = m_frames.begin(); i != m_frames.end(); ++i) 
-		i->rename_base(new_base);
-}
-
-const C2DBoundingBox CSegSet::get_boundingbox() const
-{
-	C2DBoundingBox result;
-
-	for(Frames::const_iterator i = m_frames.begin(); i != m_frames.end(); ++i)
-		result.unite(i->get_boundingbox());
-
-	return result;
-}
-
-xmlpp::Document *CSegSet::write() const
-{
-	xmlpp::Document *doc = new xmlpp::Document;
-	xmlpp::Element* nodeRoot = doc->create_root_node("workset");
-
-	if (m_version > 1) {
-		nodeRoot->set_attribute("version", to_string<int>(m_version));
-	}
-
-	Element* description = nodeRoot->add_child("description"); 
-	Element* RVPeak = description->add_child("RVpeak"); 
-	RVPeak->set_attribute("value", to_string<int>(m_RV_peak));
-	Element* LVPeak = description->add_child("LVpeak"); 
-	LVPeak->set_attribute("value", to_string<int>(m_LV_peak));
-	Element* PreferedRef = description->add_child("PreferedRef"); 
-	PreferedRef->set_attribute("value", to_string<int>(m_preferred_reference));
-
-
-	for(Frames::const_iterator i = m_frames.begin(); i != m_frames.end(); ++i) {
-		i->write(*nodeRoot, m_version);
-	}
-
-	return doc;
-}
-
-void CSegSet::read(const xmlpp::Document& node)
-{
-	const xmlpp::Element *root = node.get_root_node ();
-	if (root->get_name() != "workset") {
-		throw invalid_argument(string("CSegSet: Document root node: expected 'workset', but got ") +
-				       root->get_name());
-	}
-
-	// without attribute its version 1, otherwise read the version. 
-	const Attribute *attr = root->get_attribute("version"); 
-	if (attr) {
-		if (!from_string(attr->get_value(), m_version)) 
-			throw create_exception<invalid_argument>("bogus version '", 
-								 attr->get_value(), 
-								 "' in segmentation set"); 
-	}
-
-	auto frames = root->get_children("frame");
-	auto i = frames.begin();
-	auto e = frames.end();
-
-	while (i != e) {
-		m_frames.push_back(CSegFrame(**i, m_version));
-		++i;
-	}
-
-	auto descr = root->get_children("description");
-	if (!descr.empty()) 
-		descr = (*descr.begin())->get_children();
-	for(auto i = descr.begin(); i != descr.end(); ++i) {
-		cvdebug() << "description element '" << (*i)->get_name() << "'\n"; 
-		if ((*i)->get_name() == "RVpeak") {
-			const Element& elm = dynamic_cast<const Element&>(**i); 
-			const Attribute *attr = elm.get_attribute("value"); 
-			if (!attr)
-				cvwarn() << "CSegFrame: LVpeak without attribute"; 
-			else 
-				if (!from_string(attr->get_value(), m_RV_peak)) {
-					cvwarn() << "Could't convert RV_peak attribute '" << attr->get_value() 
-						 <<"' to an integer; ignoring\n"; 
-					m_RV_peak = -1; 
-				}
-		} else if ((*i)->get_name() == "LVpeak") {
-			const Element& elm = dynamic_cast<const Element&>(**i); 
-			const Attribute *attr = elm.get_attribute("value"); 
-			if (!attr)
-				cvwarn() << "CSegFrame: LVpeak without attribute"; 
-			else 	
-				if (!from_string(attr->get_value(), m_LV_peak)) {
-					cvwarn() << "Could't convert LV_peak attribute '" << attr->get_value() 
-						 <<"' to an integer; ignoring\n"; 
-					m_LV_peak = -1; 
-				}
-		} else if ((*i)->get_name() == "PreferedRef") {
-			const Element& elm = dynamic_cast<const Element&>(**i); 
-			const Attribute *attr = elm.get_attribute("value"); 
-			if (!attr)
-				cvwarn() << "CSegFrame: PreferedRef without attribute"; 
-			else 	
-				if (!from_string(attr->get_value(), m_preferred_reference)) {
-					cvwarn() << "Could't convert PreferedRef attribute '" << attr->get_value() 
-						 <<"' to an integer; ignoring\n"; 
-					m_preferred_reference = -1; 
-				}
-		}
-		else {
-			cvinfo() << "Ignoring unknown element '" << (*i)->get_name() << "'\n"; 
-		}
-	}
-}
-
-CSegSet  CSegSet::shift_and_rename(size_t skip, const C2DFVector&  shift, const std::string& new_filename_base) const
-{
-	CSegSet result(*this);
-	auto iframe = result.get_frames().begin();
-	auto eframe = result.get_frames().end();
-
-	while (skip-- && iframe != eframe)
-		++iframe;
-
-	while (iframe != eframe ) {
-		string base, suffix, number;
-		split_filename_number_pattern(iframe->get_imagename(), base, suffix, number);
-		stringstream fname;
-		fname << new_filename_base << number << suffix;
-		CSegFrame& rframe = *iframe;
-		rframe.shift(shift, fname.str());
-		++iframe;
-	}
-	return result;
-}
-
-void CSegSet::transform(const C2DTransformation& t)
-{
-	for (auto i = get_frames().begin(); i != get_frames().end(); ++i) 
-		i->transform(t); 
-}
-
-void CSegSet::set_RV_peak(int peak)
-{
-	m_RV_peak = peak; 
-}
-
-int CSegSet::get_RV_peak() const
-{
-	return m_RV_peak; 
-}
-
-
-void CSegSet::set_LV_peak(int peak)
-{
-	m_LV_peak = peak; 
-}
-
-int CSegSet::get_LV_peak() const
-{
-	return m_LV_peak; 
-}
-
-int CSegSet::get_preferred_reference() const
-{
-	return m_preferred_reference; 
-}
-
-void  CSegSet::set_preferred_reference(int value)
-{
-	m_preferred_reference = value; 
-}
-
-NS_MIA_END
diff --git a/mia/2d/SegSet.hh b/mia/2d/SegSet.hh
deleted file mode 100644
index bac5b15..0000000
--- a/mia/2d/SegSet.hh
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef SegSet_h
-#define SegSet_h
-
-#include <mia/2d/SegFrame.hh>
-#include <mia/2d/BoundingBox.hh>
-
-namespace xmlpp {
-	class Document;
-};
-
-NS_MIA_BEGIN
-
-/**
-   @ingroup perf 
-   \brief A set of segmentation of a 2D series of perfusion images 
-   
-   A set of slices containing segmentation information specifically designed for 
-   myocardial perfusion image series. 
-*/
-class EXPORT_2D CSegSet {
-public:
-	/// convenience typedef for the frames comprising a segmentation set 
-	typedef std::vector<CSegFrame> Frames;
-
-	/// Standard constructor 
-	CSegSet();
-	/**
-	   Construct the segmentation set by reading from a file 
-	   \param src_filename file name to read set from 
-	 */
-	CSegSet(const std::string& src_filename);
-
-	/**
-	   Construct a segmentation set by reading from a XML document
-	   \param node the root node of the XML document 
-	 */
-	CSegSet(const xmlpp::Document& node);
-
-	/**
-	   Append a segmentation frame 
-	   \param frame 
-	 */
-	void add_frame(const CSegFrame& frame);
-
-	/**
-	   Write the segmentation information to an XML tree 
-	   \returns root node of xml tree. 
-	 */
-	xmlpp::Document *write() const;
-
-
-	/// \returns read-only vector of the segmentation frames 
-	const Frames& get_frames()const;
-
-	/** 
-	    \returns a reference to the read-write vector of the segmentation frames 
-	    Changing this vector changes the segmentation set 
-	*/ 
-	Frames& get_frames();
-
-	/**
-	   \returns the box of minimal size that includes the segmentation 
-	 */
-	const C2DBoundingBox get_boundingbox() const;
-
-	/**
-	   Rename the base of the image file names for all frames on a frame by frame basis. 
-	   \param new_base new base name 
-	*/
-	void rename_base(const std::string& new_base); 
-
-
-	/**
-	   This function renames the images files, shifts the origin of the segmentation and 
-	   removes frames from the beginning of the set 
-	   \param skip number of frames to skipü at the beginning 
-	   \param shift new origin of segmentation 
-	   \param  new_filename_base new file name base
-	   \remark This function does too many things at once. 
-	 */
-	CSegSet  shift_and_rename(size_t skip, const C2DFVector&  shift, const std::string& new_filename_base)const;
-
-	/**
-	   Transform the segmentations slice wise by using the given transformation 
-	   Wroks in-place. 
-	   \param t tranformation 
-	 */
-	void transform(const C2DTransformation& t);
-
-
-	/**
-	   Set the frame number of the RV peak enhancement
-	   \param peak 
-	*/
-	void set_RV_peak(int peak); 
-	
-	/**
-	   \\returns the frame number of the RV peak enhancement (-1 if not set)
-	*/
-	int get_RV_peak() const; 
-
-	/**
-	   Set the frame number of the LV peak enhancement
-	   \param peak 
-	*/
-	void set_LV_peak(int peak); 
-
-	/**
-	   \\returns the frame number of the LV peak enhancement (-1 if not set)
-	*/
-	int get_LV_peak() const; 
-
-	/**
-	   \\returns the frame number of the image that should be used as reference frame 
-	   for time-intensity analysis after motion compensation - if the used motion compensation 
-	   algorithm provides some (like quasiperiodic, one2many, or serial do). Returns -1 if no values is given. 
-	*/
-	int get_preferred_reference() const; 
-
-
-	/**
-	   Set the preferred reference frame for this segmentation set. 
-	   \param value 
-	 */
-	void  set_preferred_reference(int value); 
-
-private:
-	void read(const xmlpp::Document& node);
-	Frames m_frames;
-	int m_RV_peak; 
-	int m_LV_peak; 
-	int m_preferred_reference; 
-	int m_version; 
-};
-
-
-NS_MIA_END
-
-#endif
diff --git a/mia/2d/SegSetWithImages.cc b/mia/2d/SegSetWithImages.cc
deleted file mode 100644
index 74bbfa4..0000000
--- a/mia/2d/SegSetWithImages.cc
+++ /dev/null
@@ -1,174 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <stdexcept>
-#include <boost/filesystem.hpp>
-#include <mia/core/errormacro.hh>
-#include <mia/2d/SegSetWithImages.hh>
-#include <mia/2d/imageio.hh>
-#include <mia/2d/filter.hh>
-
-
-
-namespace bfs=boost::filesystem;
-
-NS_MIA_BEGIN
-using namespace std;
-
-CSegSetWithImages::CSegSetWithImages()
-{
-}
-
-CSegSetWithImages::CSegSetWithImages(const string& filename, bool ignore_path):
-	CSegSet(filename)
-{
-	string src_path;
-	if (ignore_path) {
-		bfs::path src_path_(filename);
-		src_path_.remove_filename();
-		src_path = src_path_.string();
-		cvdebug() << "Segmentation path" << src_path << "\n";
-	}
-
-
-	auto iframe = get_frames().begin();
-	auto eframe = get_frames().end();
-
-	while (iframe != eframe) {
-		string input_image = iframe->get_imagename();
-		string iimage = bfs::path(input_image).string();
-		if (ignore_path) {
-			input_image = (src_path / bfs::path(iimage) ).string();
-			iframe->set_imagename(iimage);
-		}
-		P2DImage image = load_image2d(input_image); 
-		m_images.push_back(image);
-		iframe->set_image(image); 
-		++iframe;
-	}
-}
-
-// sets the image series 
-void CSegSetWithImages::set_images(const C2DImageSeries& series)
-{
-	if (series.size() != get_frames().size()) 
-		throw create_exception<invalid_argument>("image set size (", series.size(), 
-					       ") and number of segmentation frames ",
-					       get_frames().size(), "must have same number of images"); 
-	m_images = series; 
-}
-
-void CSegSetWithImages::save_images(const string& filename) const
-{
-	bfs::path src_path(filename);
-	src_path.remove_filename();
-	
-	auto iframe = get_frames().begin();
-	auto eframe = get_frames().end();
-	auto iimage = m_images.begin();
-
-	while (iframe != eframe) {
-		string image_name = iframe->get_imagename();
-		string filename = (image_name[0] == '/') ? 
-			image_name : (src_path / bfs::path(image_name)).string(); 
-                        
-		if (!save_image(filename, *iimage))
-			throw create_exception<runtime_error>("CSegSetWithImages:unable to save image to '",image_name, "'" ); 
-		++iframe; 
-		++iimage; 
-	}
-}
-
-const C2DImageSeries& CSegSetWithImages::get_images()const
-{
-	return m_images;
-}
-
-struct 	CSegFrameCropper {
-	CSegFrameCropper(const C2DIVector& shift,
-			 P2DFilter filter,
-			 const string& image_name);
-
-	CSegFrame operator()(const CSegFrame& frame, const C2DImage& image) const;
-
-private:
-	C2DIVector m_shift;
-	P2DFilter m_filter;
-	bfs::path m_image_outpath;
-};
-
-
-CSegSetWithImages CSegSetWithImages::crop(const C2DIVector&  start, const C2DIVector&  end,
-	const string& crop_filename_base)
-{
-	CSegSetWithImages result;
-
-	stringstream mask_lv;
-	mask_lv << "crop:start=[" << start
-		<< "],end=[" << end << "]";
-	cvinfo() << "crop region = '" << mask_lv.str() << "'\n";
-	auto image_cropper = C2DFilterPluginHandler::instance().produce(mask_lv.str().c_str());
-
-	CSegFrameCropper frame_cropper(start, image_cropper, crop_filename_base);
-
-	Frames::const_iterator iframe = get_frames().begin();
-	Frames::const_iterator eframe = get_frames().end();
-	C2DImageSeries::const_iterator iimages = get_images().begin();
-
-	size_t i = 0;
-	while (iframe != eframe) {
-		cvinfo() << "Crop Frame " << i++ << "\n";
-
-		result.add_frame(frame_cropper(*iframe, **iimages));
-		++iframe;
-		++iimages;
-	}
-	return result;
-}
-
-
-CSegFrameCropper::CSegFrameCropper(const C2DIVector& shift,
-				   P2DFilter filter,
-				   const string& image_name):
-	m_shift(shift),
-	m_filter(filter),
-	m_image_outpath(image_name)
-{
-	m_image_outpath.remove_filename();
-
-}
-
-
-CSegFrame CSegFrameCropper::operator()(const CSegFrame& frame, const C2DImage& image) const
-{
-	P2DImage cropped = m_filter->filter(image);
-	const string out_filename = (m_image_outpath.string() / bfs::path(frame.get_imagename())).string();
-
-	if (!save_image(out_filename, cropped))
-		cvwarn() << "Could not write cropped file '" << out_filename << "'\n";
-
-	CSegFrame result = frame;
-	result.shift(m_shift, frame.get_imagename());
-	return result;
-
-}
-
-
-NS_MIA_END
diff --git a/mia/2d/SegSetWithImages.hh b/mia/2d/SegSetWithImages.hh
deleted file mode 100644
index b606a82..0000000
--- a/mia/2d/SegSetWithImages.hh
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef mia_2d_SegSetWithImages_hh
-#define mia_2d_SegSetWithImages_hh
-
-#include <mia/2d/SegSet.hh>
-#include <mia/2d/image.hh>
-
-namespace xmlpp {
-	class Document;
-};
-
-NS_MIA_BEGIN
-
-/**
-   @ingroup perf 
-   \brief A set of images and its segmentations, related to heart perfusion analysis  
-   
-   A set of slices containing segmentationinformation as well as the images. 
- */
-class EXPORT_2D CSegSetWithImages: public CSegSet {
-public:
-	
-	
-	CSegSetWithImages();
-
-	/**
-	   Read the segmentation set and load the images 
-	   \param filename segmentation set 
-	   \param ignore_path if \a true the image reader will ignore the path 
-	   assosiated with the images, and use the base directory of the segmentation set.  
-	 */
-	CSegSetWithImages(const std::string& filename, bool ignore_path);
-
-	/// \returns a vector of the images 
-	const C2DImageSeries& get_images()const;
-
-	/// sets the image series @param series 
-	void set_images(const C2DImageSeries& series); 
-	
-	/// save the images to their give file names with the given directory as root @param root 
-	void save_images(const std::string& root) const; 
-	
-	/** Run acropping on the inout images and correct the segmentation information accordingly 
-	    \param start upper left corner of the cropping reagion 
-	    \param end lower right corner  of the cropping reagion 
-	    \param crop_filename_base new file name base for the cropped images 
-	    \returns a new segmentation set with the cropped images and the corrected segmentation information
-	*/
-	CSegSetWithImages crop(const C2DIVector&  start, const C2DIVector&  end,
-			       const std::string& crop_filename_base);
-private:
-	C2DImageSeries m_images;
-};
-
-NS_MIA_END
-
-#endif
diff --git a/mia/2d/SegStar.cc b/mia/2d/SegStar.cc
deleted file mode 100644
index 5eaa82f..0000000
--- a/mia/2d/SegStar.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <sstream>
-#include <stdexcept>
-#include <cassert>
-#include <mia/core/msgstream.hh>
-#include <mia/core/tools.hh>
-
-#include <mia/2d/SegStar.hh>
-#include <libxml++/libxml++.h>
-
-
-NS_MIA_BEGIN
-using namespace std;
-
-CSegStar::CSegStar():
-	m_radius(0.0)
-{
-}
-
-CSegStar::CSegStar(const CSegPoint2D& center, float r, const CSegPoint2D& d1, 
-		   const CSegPoint2D& d2, const CSegPoint2D& d3):
-	m_center(center),
-	m_radius(r)
-{
-	m_directions[0] = d1;
-	m_directions[1] = d2;
-	m_directions[2] = d3;
-}
-
-
-CSegStar::CSegStar(const xmlpp::Node& n)
-{
-	TRACE("CSegStar::CSegStar");
-
-	if (n.get_name() != "star")
-		throw create_exception<runtime_error>("CSegStar: expect node of type 'star', but got '", n.get_name(), "'");
-
-	const xmlpp::Element& node = dynamic_cast<const xmlpp::Element&>(n);
-
-
-	m_center = CSegPoint2D(node);
-	xmlpp::Attribute *rx = node.get_attribute ("r");
-	if (!rx)
-		throw runtime_error("CSegStar: attribute r not found");
-
-	if (!from_string(rx->get_value(), m_radius)) 
-		throw create_exception<runtime_error>("CSegStar: radius attribute '", rx->get_value(), "' is not a floating point value"); 
-
-	cvdebug() << "Got star center (" << m_center.x << ", " << m_center.y << " @ " << m_radius << ")\n";
-
-	xmlpp::Node::NodeList points = node.get_children("point");
-	size_t npoints  = points.size();
-
-	if (npoints != 3)
-		throw invalid_argument("Bogus: Star should have 3 direction points");
-
-	size_t k = 0;
-	for (xmlpp::Node::NodeList::const_iterator i = points.begin();
-	     i != points.end(); ++i, ++k) {
-		xmlpp::Element& node = dynamic_cast<xmlpp::Element&>(**i);
-		m_directions[k] = CSegPoint2D(node);
-	}
-}
-
-void CSegStar::shift(const C2DFVector& delta)
-{
-	m_center -= delta;
-}
-
-void CSegStar::transform(const C2DTransformation& t)
-{
-	cvdebug() << "CSegStar::transform: " << m_center << "@" << m_radius << "\n"; 
-	for (size_t i = 0; i < 3; ++i) {
-		cvdebug() << "CSegStar::transform:" << i << ":" << m_center + m_radius * m_directions[i] << "\n"; 
-		m_directions[i] = t(m_center + m_radius * m_directions[i]);
-		cvdebug() << "CSegStar::transform:" << i << ":" << m_directions[i] << "\n"; 
-	}
-	recenter_rays(); 
-}
-
-inline double  __calc_bc(double a, double b, double c)
-{
-	return a * a *( b * b + c * c - a *a ); 
-}
-		
-
-// re-evaluate the center after a transformation has been applied 
-// since the transformation may be non-rigid, base this evaluation on the 
-// points located at the circumfence 
-void CSegStar::reeval_center() 
-{
-	double a = (m_directions[1] - m_directions[2]).norm(); 
-	double b = (m_directions[2] - m_directions[0]).norm(); 
-	double c = (m_directions[0] - m_directions[1]).norm(); 
-	
-	vector<double> x(3); 
-	x[0] = __calc_bc(a, b, c); 
-	x[1] = __calc_bc(b, c, a); 
-	x[2] = __calc_bc(c, a, b); 
-	
-        double sum = x[0] + x[1] + x[2]; 
-        for (size_t i = 0; i < 3; ++i) {
-		x[i] /= sum; 
-	}
-	C2DFVector result(0,0); 
-	
-	for (size_t i = 0; i < 3; ++i) 
-		result += x[i] * m_directions[i]; 
-        m_center = result; 
-}
-
-
-
-void CSegStar::recenter_rays()
-{
-	reeval_center(); 
-	m_directions[0] -= m_center; 
-	float n = m_directions[0].norm(); 
-	m_radius = n; 
-	m_directions[0] /= n; 
-
-        float c = -0.5; 
-        float s = sqrt(0.75); 
-
-	m_directions[1] = C2DFVector(  c * m_directions[0].x +  s * m_directions[0].y,  
-				       c * m_directions[0].y -  s * m_directions[0].x); 
-	if (m_directions[1].x < 0) 
-		m_directions[1] *= -1; 
-	
-	m_directions[2] = C2DFVector(  c * m_directions[0].x -  s * m_directions[0].y,  
-				       c * m_directions[0].y +  s * m_directions[0].x); 
-	
-	if (m_directions[2].x > 0) 
-		m_directions[2] *= -1; 
-	
-
-}
-
-void CSegStar::inv_transform(const C2DTransformation& t)
-{
-	for (size_t i = 0; i < 3; ++i) {
-		m_directions[i] = m_center + m_radius * m_directions[i];
-		m_directions[i].inv_transform(t);
-	}
-	recenter_rays();
-}
-
-void CSegStar::write(xmlpp::Node& node) const
-{
-	xmlpp::Element* nodeChild = node.add_child("star");
-
-	nodeChild->set_attribute("y", to_string<float>(m_center.y));
-	nodeChild->set_attribute("x", to_string<float>(m_center.x));
-	nodeChild->set_attribute("r", to_string<float>(m_radius));
-
-	for (size_t i = 0; i < 3; ++i)
-		m_directions[i].write(*nodeChild);
-}
-
-NS_MIA_END
diff --git a/mia/2d/SegStar.hh b/mia/2d/SegStar.hh
deleted file mode 100644
index 312850d..0000000
--- a/mia/2d/SegStar.hh
+++ /dev/null
@@ -1,101 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef SegStar_h
-#define SegStar_h
-
-#include <mia/2d/SegPoint.hh>
-#include <vector>
-
-NS_MIA_BEGIN
-
-/**
-   @ingroup perf 
-   \brief Helper class for the segmentation of the left heart ventricle myocardium 
-
-   This class implements the segmentation helper that defines the
-   center of a circle, six rays and the circle. 
-   It is used to help the (manual) segmentation of the left heart myocardium.
- */
-
-class  EXPORT_2D CSegStar {
-public:
-	/** Standard constructor */
-	CSegStar();
-
-	/**
-	   Constructor to create the CSegStar from given data 
-	   @param center center of the circle appoximating the outer wall of the myocardium 
-	   @param r radius of the circle appoximating the outer wall of the myocardium 
-	   @param d1 first ray, its intersection should coinceede with the right ventricle 
-	   insertion point 
-	   @param d2 second ray direction vector  
-	   @param d3 third ray  direction vector 
-	 */
-	CSegStar(const CSegPoint2D& center, float r, 
-		 const CSegPoint2D& d1, const CSegPoint2D& d2, const CSegPoint2D& d3);
-	
-	/**
-	   Constructor to create a CSegStar from a XML sub tree
-	   @param node root of the sub tree 
-	 */
-	CSegStar(const xmlpp::Node& node);
-
-	/**
-	   write the CSegStar info to a XML node 
-	   @param node root node to add the info to 
-	 */
-	void write(xmlpp::Node& node) const;
-
-	/**
-	   Shift the segmentation data 
-	   @param delta
-	 */
-	void shift(const C2DFVector& delta);
-
-	/**
-	   Transform the star by transforming the intersections between the rays and the circle
-	   and then re-evaluating the center and the circle radius 
-	   \param t transformation to be applied 
-	 */
-	void transform(const C2DTransformation& t);
-
-	/**
-	   Transform the star by transforming the intersections between the rays and the circle
-	   and then re-evaluating the center and the circle radius 
-	   \param t inverse of the transformation to be applied 
-	 */
-	void inv_transform(const C2DTransformation& t);
-
-	/// center of the circle approximating the outer wall of the LV myocardium 
-	CSegPoint2D m_center;
-	/// radius of the circle approximating the outer wall of the LV myocardium 
-	float m_radius;
-	/// the ray directions to define the star 
-	CSegPoint2D m_directions[3];
-private: 
-	void recenter_rays(); 
-	void reeval_center(); 
-};
-
-NS_MIA_END
-
-
-#endif
diff --git a/mia/2d/angle.cc b/mia/2d/angle.cc
index 7671fdc..3d0092d 100644
--- a/mia/2d/angle.cc
+++ b/mia/2d/angle.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/angle.hh b/mia/2d/angle.hh
index 5890d3b..0a075b4 100644
--- a/mia/2d/angle.hh
+++ b/mia/2d/angle.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/boundingbox.cc b/mia/2d/boundingbox.cc
new file mode 100644
index 0000000..0b95946
--- /dev/null
+++ b/mia/2d/boundingbox.cc
@@ -0,0 +1,135 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/boundingbox.hh>
+
+
+NS_MIA_BEGIN
+
+C2DBoundingBox::C2DBoundingBox():
+	m_empty(true)
+{
+}
+
+C2DBoundingBox::C2DBoundingBox(const C2DFVector& begin, const C2DFVector& end):
+	m_empty(false),
+	m_begin(begin),
+	m_end(end)
+{
+	assert(m_begin.x <= m_end.x);
+	assert(m_begin.y <= m_end.y);
+}
+
+void C2DBoundingBox::unite(const C2DBoundingBox& other)
+{
+	if (m_empty) {
+		if (other.m_empty)
+			return;
+		*this = other;
+	}
+	if (other.m_begin.x < m_begin.x)
+		m_begin.x = other.m_begin.x;
+
+	if (other.m_begin.y < m_begin.y)
+		m_begin.y = other.m_begin.y;
+
+	if (other.m_end.x > m_end.x)
+		m_end.x = other.m_end.x;
+
+	if (other.m_end.y > m_end.y)
+		m_end.y = other.m_end.y;
+}
+
+C2DFVector C2DBoundingBox::get_begin() const
+{
+	assert(!m_empty);
+	return m_begin;
+}
+
+C2DFVector C2DBoundingBox::get_end() const
+{
+	assert(!m_empty);
+	return m_end;
+}
+
+C2DFVector C2DBoundingBox::get_size() const
+{
+	assert(!m_empty);
+	return m_end - m_begin;
+}
+
+C2DIVector C2DBoundingBox::get_grid_begin() const
+{
+	assert(!m_empty);
+	return C2DIVector((int)floor(m_begin.x),
+			  (int)floor(m_begin.y));
+}
+
+C2DIVector C2DBoundingBox::get_grid_end() const
+{
+	assert(!m_empty);
+ 	return C2DIVector((int)ceil(m_end.x),
+			  (int)ceil(m_end.y));
+
+}
+
+C2DBounds C2DBoundingBox::get_grid_size() const
+{
+	assert(!m_empty);
+	return C2DBounds(get_grid_end() - get_grid_begin());
+}
+
+void C2DBoundingBox::add(const C2DFVector& point)
+{
+	if (m_empty) {
+		m_begin = m_end = point;
+		m_empty = false;
+		return;
+	}
+	if (point.x < m_begin.x)
+		m_begin.x = point.x;
+
+	if (point.y < m_begin.y)
+		m_begin.y = point.y;
+
+	if (point.x > m_end.x)
+		m_end.x = point.x;
+
+	if (point.y > m_end.y)
+		m_end.y = point.y;
+
+}
+
+void C2DBoundingBox::enlarge(float boundary)
+{
+	m_end.y += boundary;
+	m_end.x += boundary;
+	m_begin.y -= boundary;
+	m_begin.x -= boundary;
+
+}
+
+bool C2DBoundingBox::empty() const
+{
+	return m_empty;
+}
+
+NS_MIA_END
+
diff --git a/mia/2d/boundingbox.hh b/mia/2d/boundingbox.hh
new file mode 100644
index 0000000..db25c8c
--- /dev/null
+++ b/mia/2d/boundingbox.hh
@@ -0,0 +1,98 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __mia_2d_boundingbox_hh
+#define __mia_2d_boundingbox_hh
+
+#include <mia/2d/vector.hh>
+#include <mia/2d/defines2d.hh>
+
+
+NS_MIA_BEGIN
+
+/// a 2D int vector 
+typedef T2DVector<int> C2DIVector;
+
+
+/**
+   @ingroup perf 
+   \brief 2D axis orthothogonal bounding box. 
+ */
+class  EXPORT_2D C2DBoundingBox {
+public:
+	C2DBoundingBox();
+
+	/**
+	   Construct a new bounding box with 
+	   @param begin left lower corner 
+	   @param end right upper corner 
+	 */
+	C2DBoundingBox(const C2DFVector& begin, const C2DFVector& end);
+
+	/**
+	   Combine two bounding boxes 
+	   @param other box
+	 */
+	void unite(const C2DBoundingBox& other);
+
+	/**
+	   Change the box to include the given point 
+	   @param point 
+	 */
+	void add(const C2DFVector& point);
+
+
+	/// @returns left lower grid point 
+	C2DIVector get_grid_begin() const;
+	
+	/// @returns right upper grid point 
+	C2DIVector get_grid_end() const;
+
+	/// @returns size of bounding box in the grid  
+	C2DBounds get_grid_size() const;
+
+	/// @returns left lower bounding box point 
+	C2DFVector get_begin() const;
+	
+	/// @returns right upper  bounding box point 
+	C2DFVector get_end() const;
+
+	/// @returns size of bounding box 
+	C2DFVector get_size() const;
+
+
+	/** enlarge the bounding box by a given amount 
+	    @param boundary 
+	*/
+	void enlarge(float boundary);
+
+
+	/// @returns true if the box is not empty 
+	bool empty() const;
+
+private:
+	bool m_empty;
+	C2DFVector m_begin;
+	C2DFVector m_end;
+};
+
+NS_MIA_END
+
+#endif
diff --git a/mia/2d/combiner/CMakeLists.txt b/mia/2d/combiner/CMakeLists.txt
index 6847a5d..30fcb66 100644
--- a/mia/2d/combiner/CMakeLists.txt
+++ b/mia/2d/combiner/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/combiner/ops.cc b/mia/2d/combiner/ops.cc
index 69f0749..b0997e3 100644
--- a/mia/2d/combiner/ops.cc
+++ b/mia/2d/combiner/ops.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/combiner/ops.hh b/mia/2d/combiner/ops.hh
index e8c5ada..1dad524 100644
--- a/mia/2d/combiner/ops.hh
+++ b/mia/2d/combiner/ops.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/combiner/plugin.hh b/mia/2d/combiner/plugin.hh
index 2bdf280..51bb946 100644
--- a/mia/2d/combiner/plugin.hh
+++ b/mia/2d/combiner/plugin.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/combiner/test_ops.cc b/mia/2d/combiner/test_ops.cc
index 4809174..32699d6 100644
--- a/mia/2d/combiner/test_ops.cc
+++ b/mia/2d/combiner/test_ops.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/correlation_weight.cc b/mia/2d/correlation_weight.cc
index 7f90067..ae0004a 100644
--- a/mia/2d/correlation_weight.cc
+++ b/mia/2d/correlation_weight.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/correlation_weight.hh b/mia/2d/correlation_weight.hh
index 8e4fd1f..18adb2f 100644
--- a/mia/2d/correlation_weight.hh
+++ b/mia/2d/correlation_weight.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost.cc b/mia/2d/cost.cc
index 97baec4..95bfe9b 100644
--- a/mia/2d/cost.cc
+++ b/mia/2d/cost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,26 +19,21 @@
  */
 
 #include <mia/core/export_handler.hh>
+
 #include <mia/2d/cost.hh>
+#include <mia/core/cost.cxx>
 #include <mia/core/handler.cxx>
 #include <mia/core/plugin_base.cxx>
-#include <mia/core/cost.cxx>
 
 
-NS_MIA_BEGIN
-namespace bfs=::boost::filesystem; 
-
-template class EXPORT_HANDLER TCost<C2DImage, C2DFVectorfield>;
 
 
-C2DImageCostPluginHandlerTestPath::C2DImageCostPluginHandlerTestPath()
-{
-	CPathNameArray cost_kernel_plugpath({bfs::path("cost")});
-	C2DImageCostPluginHandler::set_search_path(cost_kernel_plugpath);
+NS_MIA_BEGIN
+namespace bfs=::boost::filesystem; 
 
-}
+template class TCost<C2DImage, C2DFVectorfield>;
 
-template <> const char *  const 
+template <> const char *  const
 TPluginHandler<TFactory<C2DImageCost>>::m_help =  
 	"2D image similarity kernels evaluate the according similarity measure between "
 	"two images. These kernels may be used standalone, like e.g. in linear registration, "
@@ -49,3 +44,5 @@ EXPLICIT_INSTANCE_HANDLER(C2DImageCost);
 
 NS_MIA_END
 
+
+
diff --git a/mia/2d/cost.hh b/mia/2d/cost.hh
index 22ce963..8da76ee 100644
--- a/mia/2d/cost.hh
+++ b/mia/2d/cost.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
 
 NS_MIA_BEGIN
 
+extern template class EXPORT_2D TCost<C2DImage, C2DFVectorfield>;
 /// the base class for simple 2D image cost functions 
 typedef TCost<C2DImage, C2DFVectorfield> C2DImageCost;
 
@@ -38,16 +39,6 @@ typedef THandlerSingleton<TFactoryPluginHandler<C2DImageCostPlugin> > C2DImageCo
 /// pointer type of simple 2D image cost functions 
 typedef std::shared_ptr<C2DImageCost > P2DImageCost;
 
-/** 
-    @cond INTERNAL  
-    \ingroup test 
-    \brief Class to initialiaze the plug-in search path fot testing without installing the plug-ins 
-*/
-struct EXPORT_2D C2DImageCostPluginHandlerTestPath {
-	C2DImageCostPluginHandlerTestPath(); 
-}; 
-/// @endcond 
-
 /// @cond NEVER 
 FACTORY_TRAIT(C2DImageCostPluginHandler);
 /// @endcond 
diff --git a/mia/2d/cost/CMakeLists.txt b/mia/2d/cost/CMakeLists.txt
index c55c6e6..92db5b8 100644
--- a/mia/2d/cost/CMakeLists.txt
+++ b/mia/2d/cost/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 
-SET(costplugins2d ssd mi ngf lsd)
+SET(costplugins2d ssd ssd-automask lncc lsd mi ncc ngf)
 PLUGINGROUP_WITH_TEST_AND_PREFIX2(2dimage cost  "${costplugins2d}" "${MIA2DLIBS}")
 
 
diff --git a/mia/2d/cost/lncc.cc b/mia/2d/cost/lncc.cc
new file mode 100644
index 0000000..d90482d
--- /dev/null
+++ b/mia/2d/cost/lncc.cc
@@ -0,0 +1,209 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/cost/lncc.hh>
+
+#include <mia/core/threadedmsg.hh>
+#include <mia/core/nccsum.hh>
+#include <tbb/parallel_reduce.h>
+#include <tbb/blocked_range.h>
+
+
+NS_BEGIN(NS)
+
+using namespace mia; 
+using std::vector; 
+using std::pair; 
+using std::make_pair; 
+
+CLNCC2DImageCost::CLNCC2DImageCost(int hw):
+m_hwidth(hw)
+{
+}
+
+inline pair<C2DBounds, C2DBounds> prepare_range(const C2DBounds& size, int cx, int cy, int hw) 
+{
+	int yb = cy - hw;
+	if (yb < 0) yb = 0; 
+	unsigned ye = cy + hw + 1; 
+	if (ye > size.y) ye = size.y; 
+	
+	int xb = cx - hw;
+	if (xb < 0) xb = 0; 
+	unsigned xe = cx + hw + 1; 
+	if (xe > size.x) xe = size.x; 
+	
+	return make_pair(C2DBounds(xb,yb), C2DBounds(xe,ye)); 
+}
+
+
+
+class FEvalCost : public TFilter<float> {
+	int m_hw;
+public:
+	FEvalCost(int hw):
+		m_hw(hw)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		auto evaluate_local_cost = [this, &mov, &ref](const tbb::blocked_range<size_t>& range, const pair<float, int>& result) -> pair<float, int> {
+			CThreadMsgStream msks; 
+			float lresult = 0.0; 
+			int count = 0; 
+			
+			for (auto y = range.begin(); y != range.end(); ++y) {
+				for (size_t x = 0; x < mov.get_size().x; ++x) {
+					
+					auto c_block = prepare_range(mov.get_size(), x, y, m_hw); 
+					auto ia = mov.begin_range(c_block.first,c_block.second); 
+					auto ea = mov.end_range(c_block.first,c_block.second); 
+					auto ib = ref.begin_range(c_block.first,c_block.second); 
+					
+					auto delta_size = c_block.second - c_block.first; 
+					auto n = delta_size.product(); 
+					
+					if (n > 1) {
+						
+						NCCSums sum; 
+						
+						while (ia != ea) {
+							sum.add(*ia, *ib); 
+							++ia; ++ib; 
+						}
+						
+						lresult += sum.value(); 
+						++count; 
+					}				}
+			}
+			return make_pair(result.first + lresult, result.second + count); 
+		};
+		
+		pair<float,int> init{0, 0}; 
+		auto r = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), init, evaluate_local_cost, 
+					 [](const pair<float,int>& x, const pair<float,int>& y){
+						 return make_pair(x.first + y.first, x.second + y.second);
+					 });	
+		return r.second > 0 ? r.first / r.second : 0.0; 
+	}
+}; 
+
+
+double CLNCC2DImageCost::do_value(const Data& a, const Data& b) const
+{
+	FEvalCost ecost(m_hwidth); 
+	return mia::filter(ecost, a, b); 
+}
+
+
+class FEvalCostForce : public TFilter<float> {
+	int m_hw;
+	C2DFVectorfield& m_force; 
+public: 
+	FEvalCostForce(int hw, C2DFVectorfield& force):
+		m_hw(hw), 
+		m_force(force)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		auto ag = get_gradient(mov); 
+		auto evaluate_local_cost_force = [this, &mov, &ref, &ag](const tbb::blocked_range<size_t>& range, 
+									 const pair<float, int>& result) -> pair<float, int> {
+			
+			CThreadMsgStream msks; 		
+			float lresult = 0.0; 
+			int count = 0; 
+			for (auto y = range.begin(); y != range.end(); ++y) {
+                        
+				auto iforce = m_force.begin_at(0,y);
+				auto ig = ag.begin_at(0,y);
+				auto imov = mov.begin_at(0,y);
+				auto iref = ref.begin_at(0,y);
+                        
+				for (size_t x = 0; x < mov.get_size().x; ++x, ++iforce, ++ig, ++iref, ++imov) {
+					auto c_block = prepare_range(mov.get_size(), x, y, m_hw); 
+					auto ia = mov.begin_range(c_block.first,c_block.second); 
+					auto ea = mov.end_range(c_block.first,c_block.second); 
+					auto ib = ref.begin_range(c_block.first,c_block.second); 
+					
+					auto delta_size = c_block.second - c_block.first; 
+					auto n = delta_size.product(); 
+					
+					if (n > 1) {
+						NCCSums sum; 
+						
+						while (ia != ea) {
+							sum.add(*ia, *ib); 
+							++ia; ++ib; 
+						}
+						
+						auto res = sum.get_grad_helper(); 
+						lresult += res.first;
+						*iforce = res.second.get_gradient_scale(*imov, *iref) * *ig; 
+						++count; 
+					}
+				}
+			}
+			return make_pair(result.first + lresult, result.second + count); 
+		};
+		pair<float,int> init{0, 0}; 		
+		auto r = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), init, evaluate_local_cost_force, 
+					 [](const pair<float,int>& x, const pair<float,int>& y){
+						 return make_pair(x.first + y.first, x.second + y.second);
+					 });
+		
+		return r.second > 0 ? r.first / r.second : 0.0; 
+	}
+	
+};
+
+double CLNCC2DImageCost::do_evaluate_force(const Data& a, const Data& b, Force& force) const
+{
+	FEvalCostForce ecostforce(m_hwidth, force); 
+	return mia::filter(ecostforce, a, b); 
+}
+
+
+CLNCC2DImageCostPlugin::CLNCC2DImageCostPlugin():
+        C2DImageCostPlugin("lncc"), 
+	m_hw(5)
+{
+	this->add_parameter("w", new CUIntParameter(m_hw, 1, 256, false, 
+						    "half width of the window used for evaluating the localized cross correlation")); 
+}
+
+C2DImageCost *CLNCC2DImageCostPlugin::do_create() const
+{
+	return new CLNCC2DImageCost(m_hw);
+}
+
+const std::string CLNCC2DImageCostPlugin::do_get_descr() const
+{
+	return "local normalized cross correlation with masking support."; 
+}
+
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new CLNCC2DImageCostPlugin();
+}
+
+NS_END
diff --git a/mia/2d/cost/lncc.hh b/mia/2d/cost/lncc.hh
new file mode 100644
index 0000000..0dbf491
--- /dev/null
+++ b/mia/2d/cost/lncc.hh
@@ -0,0 +1,52 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_2d_maskedcost_lncc_hh
+#define mia_2d_maskedcost_lncc_hh
+
+#include <mia/2d/cost.hh>
+
+#define NS mia_2d_lncc
+
+NS_BEGIN(NS)
+
+class CLNCC2DImageCost: public mia::C2DImageCost {
+public: 	
+	typedef mia::C2DImageCost::Data Data; 
+
+	CLNCC2DImageCost(int hw);
+private: 
+	virtual double do_value(const Data& a, const Data& b) const; 
+	virtual double do_evaluate_force(const Data& a, const Data& b, Force& force) const; 
+        int m_hwidth; 
+};
+
+class CLNCC2DImageCostPlugin: public mia::C2DImageCostPlugin {
+public: 
+	CLNCC2DImageCostPlugin();
+	mia::C2DImageCost *do_create() const;
+private: 
+	const std::string do_get_descr() const; 
+        unsigned int m_hw; 
+};
+
+NS_END
+
+#endif 
diff --git a/mia/2d/cost/lsd.cc b/mia/2d/cost/lsd.cc
index 15edeed..827ee02 100644
--- a/mia/2d/cost/lsd.cc
+++ b/mia/2d/cost/lsd.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost/lsd.hh b/mia/2d/cost/lsd.hh
index a9979f7..257d4c4 100644
--- a/mia/2d/cost/lsd.hh
+++ b/mia/2d/cost/lsd.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost/mi.cc b/mia/2d/cost/mi.cc
index 08f14be..09265ee 100644
--- a/mia/2d/cost/mi.cc
+++ b/mia/2d/cost/mi.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost/mi.hh b/mia/2d/cost/mi.hh
index 2629edf..9c89c44 100644
--- a/mia/2d/cost/mi.hh
+++ b/mia/2d/cost/mi.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost/ncc.cc b/mia/2d/cost/ncc.cc
new file mode 100644
index 0000000..0fba54c
--- /dev/null
+++ b/mia/2d/cost/ncc.cc
@@ -0,0 +1,171 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/cost/ncc.hh>
+
+#include <mia/core/threadedmsg.hh>
+#include <mia/core/nccsum.hh> 
+#include <tbb/parallel_reduce.h>
+#include <tbb/parallel_for.h>
+#include <tbb/blocked_range.h>
+
+
+NS_BEGIN(NS)
+
+using namespace mia; 
+
+
+CNCC2DImageCost::CNCC2DImageCost()
+{
+}
+
+template <typename T, typename S> 
+struct FEvaluateNCCSum {
+	FEvaluateNCCSum(const T& mov, const S& ref); 
+	NCCSums operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const; 
+private: 
+	T m_mov; 
+	S m_ref; 
+};
+
+
+template <typename T, typename S> 
+FEvaluateNCCSum<T,S>::FEvaluateNCCSum(const T& mov, const S& ref):
+	m_mov(mov), m_ref(ref) 
+{
+	
+}
+
+template <typename T, typename S> 
+NCCSums FEvaluateNCCSum<T,S>::operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const
+{
+	CThreadMsgStream msks; 
+	
+	NCCSums sum;
+	for (auto y = range.begin(); y != range.end(); ++y) {
+		auto ia = m_mov.begin_at(0,y); 
+		auto ib = m_ref.begin_at(0,y); 
+		auto eb = m_ref.begin_at(0,y + 1); 
+		
+		while (ib != eb) {
+			sum.add(*ia, *ib); 
+			++ia; ++ib; 
+		}
+	}
+	return sum + sumacc; 
+};
+
+
+class FEvalCost : public TFilter<float> {
+public:
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+
+		FEvaluateNCCSum<T,R> ev(mov, ref); 
+		NCCSums sum; 
+		sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), sum, ev, 
+				      [](const NCCSums& x, const NCCSums& y){
+					      return x + y;
+				      });
+		return sum.value(); 
+	}
+}; 
+
+
+double CNCC2DImageCost::do_value(const Data& a, const Data& b) const
+{
+	FEvalCost ecost; 
+	return mia::filter(ecost, a, b); 
+}
+
+
+class FEvalCostForce : public TFilter<float> {
+	C2DFVectorfield& m_force; 
+public: 
+	FEvalCostForce(C2DFVectorfield& force):
+		m_force(force)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		CThreadMsgStream msks;
+		
+		NCCSums sum; 
+		FEvaluateNCCSum<T,R> ev(mov, ref); 
+		sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), sum, ev, 
+					 [](const NCCSums& x, const NCCSums& y){
+					      return x + y;
+				      });
+		
+		auto geval = sum.get_grad_helper(); 
+
+		auto grad = get_gradient(mov); 
+		auto grad_eval = [this, &mov, &ref, &grad, &geval](const tbb::blocked_range<size_t>& range) {
+			for (auto y = range.begin(); y != range.end(); ++y) {
+				auto ig = grad.begin_at(0,y); 
+				auto iforce = m_force.begin_at(0,y); 
+				auto ia = mov.begin_at(0,y); 
+				auto ib = ref.begin_at(0,y); 
+				auto eb = ref.begin_at(0,y+1); 
+				
+				while (ib != eb) {
+					*iforce = geval.second.get_gradient_scale(*ia, *ib) * *ig; 
+					++ig; 
+					++iforce; 
+					++ia; ++ib;
+				}
+			}; 
+		}; 
+		
+		parallel_for(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), grad_eval); 
+
+		return geval.first; 
+	}
+	
+};
+
+double CNCC2DImageCost::do_evaluate_force(const Data& a, const Data& b, Force& force) const
+{
+	FEvalCostForce ecostforce(force); 
+	return mia::filter(ecostforce, a, b); 
+}
+
+
+CNCC2DImageCostPlugin::CNCC2DImageCostPlugin():
+C2DImageCostPlugin("ncc")
+{
+}
+
+C2DImageCost *CNCC2DImageCostPlugin::do_create() const
+{
+	return new CNCC2DImageCost();
+}
+
+const std::string CNCC2DImageCostPlugin::do_get_descr() const
+{
+	return "normalized cross correlation."; 
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new CNCC2DImageCostPlugin();
+}
+
+NS_END
diff --git a/mia/2d/cost/ncc.hh b/mia/2d/cost/ncc.hh
new file mode 100644
index 0000000..d2be379
--- /dev/null
+++ b/mia/2d/cost/ncc.hh
@@ -0,0 +1,51 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_2d_cost_ncc_hh
+#define mia_2d_cost_ncc_hh
+
+#include <mia/2d/cost.hh>
+
+#define NS mia_2d_ncc
+
+NS_BEGIN(NS)
+
+class CNCC2DImageCost: public mia::C2DImageCost {
+public: 	
+	typedef mia::C2DImageCost::Data Data; 
+	typedef mia::C2DImageCost::Force Force; 
+
+	CNCC2DImageCost();
+private: 
+	virtual double do_value(const Data& a, const Data& b) const; 
+	virtual double do_evaluate_force(const Data& a, const Data& b, Force& force) const; 
+};
+
+class CNCC2DImageCostPlugin: public mia::C2DImageCostPlugin {
+public: 
+	CNCC2DImageCostPlugin();
+	mia::C2DImageCost *do_create() const;
+private: 
+	const std::string do_get_descr() const; 
+};
+
+NS_END
+
+#endif 
diff --git a/mia/2d/cost/ngf.cc b/mia/2d/cost/ngf.cc
index 5bf7918..e7bf5c5 100644
--- a/mia/2d/cost/ngf.cc
+++ b/mia/2d/cost/ngf.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -220,40 +220,42 @@ double C2DNFGImageCost::do_evaluate_force(const mia::C2DImage& a,
 	return 0.5 * sum / ng_a.size();
 }
 
+const TDictMap<C2DNFGImageCostPlugin::ESubTypes>::Table lut[] = {
+	{"sq", C2DNFGImageCostPlugin::st_delta, "square of difference"},
+	{"ds", C2DNFGImageCostPlugin::st_delta_scalar, "square of scaled difference"},
+	{"dot", C2DNFGImageCostPlugin::st_scalar, "scalar product kernel"},
+	{"cross", C2DNFGImageCostPlugin::st_cross, "cross product kernel"},
+	{0, C2DNFGImageCostPlugin::st_unknown, ""}
+	};
+const TDictMap<C2DNFGImageCostPlugin::ESubTypes> subtypemap(lut);
+
+
 C2DNFGImageCostPlugin::C2DNFGImageCostPlugin():
 	C2DImageCostPlugin("ngf"),
-	m_kernel("ds")
+	m_kernel(st_delta_scalar)
 {
+
+	
 	TRACE("C2DNFGImageCostPlugin::C2DNFGImageCostPlugin()");
-	add_parameter("eval",
-		      new CStringParameter(m_kernel, false, "plugin subtype (sq, ds,dot,cross)"));
+	add_parameter("eval", new CDictParameter<ESubTypes>(m_kernel, subtypemap, "plugin subtype"));
 
 }
 
-enum ESubTypes {st_unknown, st_delta, st_delta_scalar, st_scalar, st_cross};
 
 C2DImageCost *C2DNFGImageCostPlugin::do_create()const
 {
 	TRACE("C2DNFGImageCostPlugin::do_create");
 
-	const TDictMap<ESubTypes>::Table lut[] = {
-		{"sq", st_delta, "square of difference"},
-		{"ds", st_delta_scalar, "square of scaled difference"},
-		{"dot", st_scalar, "scalar product kernel"},
-		{"cross", st_cross, "cross product kernel"},
-		{0, st_unknown, ""}
-	};
-	const TDictMap<ESubTypes> subtypemap(lut);
 
 	PEvaluator eval;
-	switch (subtypemap.get_value(m_kernel.c_str())) {
+	switch (m_kernel) {
 	case st_delta: eval.reset(new CCostEvaluatorSQDelta()); break;
 	case st_delta_scalar: eval.reset(new CCostEvaluatorDeltaScalar()); break;
 	case st_scalar: eval.reset(new CCostEvaluatorScalar()); break;
 	case st_cross: eval.reset(new CCostEvaluatorCross()); break;
 	default:
 		throw invalid_argument(string("C2DNFGImageCostPlugin: unknown cost sub-type '")
-				       +m_kernel+"'");
+				       +subtypemap.get_name(m_kernel)+"'");
 	}
 	return new C2DNFGImageCost(eval);
 }
diff --git a/mia/2d/cost/ngf.hh b/mia/2d/cost/ngf.hh
index cb767fd..e5c70ef 100644
--- a/mia/2d/cost/ngf.hh
+++ b/mia/2d/cost/ngf.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -106,12 +106,15 @@ private:
 
 class C2DNFGImageCostPlugin: public mia::C2DImageCostPlugin {
 public:
+	enum ESubTypes {st_unknown, st_delta, st_delta_scalar, st_scalar, st_cross};
+
 	C2DNFGImageCostPlugin();
 private:
+
 	virtual mia::C2DImageCost *do_create()const;
 
 	const std::string do_get_descr()const;
-	std::string m_kernel;
+	ESubTypes m_kernel;
 };
 
 NS_END
diff --git a/mia/2d/cost/ssd-automask.cc b/mia/2d/cost/ssd-automask.cc
new file mode 100644
index 0000000..fb7e642
--- /dev/null
+++ b/mia/2d/cost/ssd-automask.cc
@@ -0,0 +1,51 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/cost.hh>
+
+#define NS ssdautomask_2dimage_cost
+#include <mia/2d/cost/ssd-automask.hh>
+#include <mia/template/ssd-automask.cxx>
+
+NS_BEGIN(NS)
+
+
+NS_MIA_USE;
+using namespace std;
+using namespace boost;
+
+
+template class TSSDAutomaskCost<C2DImageCost>;
+
+
+const string C2DSSDAutomaskCostPlugin::do_get_descr()const
+{
+	return "2D image cost: sum of squared differences, with automasking based on given thresholds";
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C2DSSDAutomaskCostPlugin();
+}
+
+
+NS_END
+
+
diff --git a/mia/2d/cost/ssd-automask.hh b/mia/2d/cost/ssd-automask.hh
new file mode 100644
index 0000000..d325f8a
--- /dev/null
+++ b/mia/2d/cost/ssd-automask.hh
@@ -0,0 +1,36 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/cost.hh>
+
+#define NS ssdautomask_2dimage_cost
+#include <mia/template/ssd-automask.hh>
+
+NS_BEGIN(NS);
+
+
+typedef TSSDAutomaskCost<mia::C2DImageCost> C2DSSDAutomaskCost;
+
+class C2DSSDAutomaskCostPlugin: public TSSDAutomaskCostPlugin<mia::C2DImageCostPlugin, C2DSSDAutomaskCost> {
+private:
+	virtual const std::string do_get_descr()const;
+};
+
+NS_END
diff --git a/mia/2d/cost/ssd.cc b/mia/2d/cost/ssd.cc
index be6acfa..7ec3925 100644
--- a/mia/2d/cost/ssd.cc
+++ b/mia/2d/cost/ssd.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost/ssd.hh b/mia/2d/cost/ssd.hh
index 28f5603..1d1e307 100644
--- a/mia/2d/cost/ssd.hh
+++ b/mia/2d/cost/ssd.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost/ssd2.cc b/mia/2d/cost/ssd2.cc
index f581fa3..d57102d 100644
--- a/mia/2d/cost/ssd2.cc
+++ b/mia/2d/cost/ssd2.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost/ssd2.hh b/mia/2d/cost/ssd2.hh
index e66fd0a..f5f11e5 100644
--- a/mia/2d/cost/ssd2.hh
+++ b/mia/2d/cost/ssd2.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost/ssddf.cc b/mia/2d/cost/ssddf.cc
index c8660e7..a2074e2 100644
--- a/mia/2d/cost/ssddf.cc
+++ b/mia/2d/cost/ssddf.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost/test_divcurl.cc b/mia/2d/cost/test_divcurl.cc
index ec33776..7497e5b 100644
--- a/mia/2d/cost/test_divcurl.cc
+++ b/mia/2d/cost/test_divcurl.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost/test_lncc.cc b/mia/2d/cost/test_lncc.cc
new file mode 100644
index 0000000..0442c90
--- /dev/null
+++ b/mia/2d/cost/test_lncc.cc
@@ -0,0 +1,105 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <mia/internal/plugintester.hh>
+#include <mia/2d/cost/lncc.hh>
+
+using namespace NS; 
+using namespace mia; 
+
+
+
+
+BOOST_AUTO_TEST_CASE( test_lncc_1 ) 
+{
+        C2DBounds size(4,4); 
+        auto lncc = BOOST_TEST_create_from_plugin<CLNCC2DImageCostPlugin>("lncc:w=1");
+
+	const float src_data[16] = {           /*   0  1  2  3  4  5  6  7  8  9     */    
+		1, 1, 2, 2, 
+		2, 3, 4, 4,        /*1                                 0 */
+		4, 4, 3, 3, 
+		2, 2, 2, 1,        /*2     1  2  1  1     1            6 */
+	};                                     /*      5  9  9  8  2  7  5  3        */
+	
+	const float ref_data[16] = {
+		1, 2, 1, 5, 
+		1, 1, 1, 1, 
+		2, 2, 2, 7,
+		4, 3, 2, 2,
+	};
+
+        
+	C2DFImage src_f(size, src_data); 
+        C2DFImage ref_f(size, ref_data); 
+
+        
+        lncc->set_reference(ref_f); 
+        BOOST_CHECK_SMALL(lncc->value(ref_f), 1e-5);
+        
+        auto v = lncc->value(src_f); 
+        BOOST_CHECK_CLOSE(v, 1.0-0.202097048, 0.1); 
+        
+	C2DFVectorfield zero_force(size); 
+	v = lncc->evaluate_force(ref_f, zero_force); 
+	BOOST_CHECK_SMALL(v, 1e-5);
+
+	for (auto iv = zero_force.begin(); iv != zero_force.end();  ++iv) {
+		BOOST_CHECK_SMALL(iv->x, 1e-8f); 
+		BOOST_CHECK_SMALL(iv->y, 1e-8f); 
+	}
+	
+	C2DFVectorfield force(size); 
+
+	v = lncc->evaluate_force(src_f, force); 
+	BOOST_CHECK_CLOSE(v, 1.0-0.202097048, 0.1); 
+        
+	
+	float gradx[] = {
+		0,0.1299226651,-0.0565096061,0, 
+		0,0.0481481481,-0.0110429448,0, 
+		0,-0.0263397503,0.0032142857,0, 
+		0,0,-0.0148760331,0
+	};
+
+	float grady[] = {
+		0,0,0,0, 
+		0.1329639889,0.0722222222,-0.0110429448,-0.0253807107, 
+		0,-0.0263397503,0.0064285714,-0.1171571544, 
+		0,0,0,0
+	}; 
+	
+	auto igx = gradx; 
+	auto igy = grady; 
+
+	for (auto iv = force.begin(); iv != force.end();  ++iv, ++igx, ++igy) {
+		if (*igx == 0.0) 
+			BOOST_CHECK_SMALL(iv->x, 1e-8f); 
+		else 
+			BOOST_CHECK_CLOSE(iv->x, *igx, 0.1); 
+
+		if (*igy == 0.0) 
+			BOOST_CHECK_SMALL(iv->y, 1e-8f); 
+		else 
+			BOOST_CHECK_CLOSE(iv->y, *igy, 0.1); 
+		
+	}
+}
diff --git a/mia/2d/cost/test_lsd.cc b/mia/2d/cost/test_lsd.cc
index b490f5c..4d66be6 100644
--- a/mia/2d/cost/test_lsd.cc
+++ b/mia/2d/cost/test_lsd.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cost/test_mi.cc b/mia/2d/cost/test_mi.cc
index 32fe248..2cbbed9 100644
--- a/mia/2d/cost/test_mi.cc
+++ b/mia/2d/cost/test_mi.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,8 +29,6 @@ using namespace std;
 using namespace ::boost::unit_test;
 using namespace mia_2dcost_mi;
 
-CSplineKernelTestPath spline_kernel_init_path; 
-
 class MIFixture {
 protected: 
 	MIFixture(); 
diff --git a/mia/2d/cost/test_ncc.cc b/mia/2d/cost/test_ncc.cc
new file mode 100644
index 0000000..8bbad0c
--- /dev/null
+++ b/mia/2d/cost/test_ncc.cc
@@ -0,0 +1,104 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+#include <mia/2d/cost/ncc.hh>
+#include <mia/core/nccsum.hh>
+
+using namespace NS; 
+using namespace mia; 
+
+
+
+
+BOOST_AUTO_TEST_CASE( test_ncc_zero ) 
+{
+        C2DBounds size(4,4); 
+        auto ncc = BOOST_TEST_create_from_plugin<CNCC2DImageCostPlugin>("ncc");
+        
+        C2DFImage a(size); 
+        C2DFImage b(size); 
+        
+        auto ia = a.begin_range(C2DBounds::_0, size); 
+        auto ib = b.begin_range(C2DBounds::_0, size); 
+        auto ea = a.end_range(C2DBounds::_0, size); 
+
+        while (ia != ea) {
+                *ia = ia.pos().x + ia.pos().y; 
+                *ib = 2* *ia; 
+                ++ib; ++ia; 
+        }
+
+        ncc->set_reference(b); 
+        BOOST_CHECK_SMALL(ncc->value(b), 1e-7); 
+
+        BOOST_CHECK_SMALL(ncc->value(a), 1e-7); 
+        
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_ncc_nonzero ) 
+{
+        C2DBounds size(4,4); 
+        auto ncc = BOOST_TEST_create_from_plugin<CNCC2DImageCostPlugin>("ncc");
+        
+        C2DFImage a(size); 
+        C2DFImage b(size); 
+
+       
+        auto ia = a.begin_range(C2DBounds::_0, size); 
+        auto ib = b.begin_range(C2DBounds::_0, size); 
+        auto ea = a.end_range(C2DBounds::_0, size); 
+
+        NCCSums sum; 
+
+        while (ia != ea) {
+                *ia = ia.pos().x + ia.pos().y; 
+                *ib = ia.pos().x * ia.pos().y; 
+                sum.add(*ia, *ib); 
+                ++ib; ++ia; 
+        }
+
+        ncc->set_reference(b); 
+        BOOST_CHECK_CLOSE(ncc->value(a), sum.value(), 0.1); 
+        
+        C2DFVectorfield grad(size); 
+
+        BOOST_CHECK_CLOSE(ncc->evaluate_force(a, grad), sum.value(), 0.01);
+
+
+	auto ag = get_gradient(a); 
+	
+	auto iag = ag.begin(); 
+	auto ia2 = a.begin(); 
+	auto ib2 = b.begin(); 
+	auto iforce = grad.begin(); 
+	auto eforce = grad.end(); 
+
+	auto gs = sum.get_grad_helper().second; 
+	while (iforce != eforce) {
+		auto expect = *iag * gs.get_gradient_scale(*ia2, *ib2); 
+		BOOST_CHECK_CLOSE(iforce->x, expect.x, 0.01); 
+		BOOST_CHECK_CLOSE(iforce->y, expect.y, 0.01); 
+		++iag; ++ia2; ++ib2; ++iforce;
+	}
+}
+
+
diff --git a/mia/2d/cost/test_ngf.cc b/mia/2d/cost/test_ngf.cc
index 565fd6d..01c70d2 100644
--- a/mia/2d/cost/test_ngf.cc
+++ b/mia/2d/cost/test_ngf.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +30,6 @@ using namespace std;
 using namespace ::boost::unit_test;
 using namespace nfg_2dimage_cost;
 
-CSplineKernelTestPath spline_kernel_path_init; 
 
 const size_t g_nx = 4;
 const size_t g_ny = 3;
diff --git a/mia/2d/cost/test_ssd-automask.cc b/mia/2d/cost/test_ssd-automask.cc
new file mode 100644
index 0000000..ea8121a
--- /dev/null
+++ b/mia/2d/cost/test_ssd-automask.cc
@@ -0,0 +1,64 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <mia/2d/cost/ssd-automask.hh>
+
+
+using namespace std;
+using namespace boost;
+namespace bfs=::boost::filesystem;
+using namespace mia;
+using namespace NS;
+
+BOOST_AUTO_TEST_CASE( test_SSD_2D_autmask )
+{
+	float src_data[25] = { 2, 3, 2, 3, 4,  
+			       1, 4, 2, 3, 4, 
+			       6, 7, 4, 2, 3,
+			       1, 4, 5, 7, 3, 
+			       1, 3, 6, 7, 8 };
+
+	float ref_data[25] = { 6, 7, 2, 1, 2,  
+			       2, 3, 2, 6, 7, 
+			       8, 9, 9, 7, 6, 
+			       5, 1, 2, 3, 4, 
+			       6, 8, 3, 2, 3 };
+
+ 
+  	C2DFImage *fsrc = new C2DFImage(C2DBounds(5,5), src_data );
+	C2DFImage *fref = new C2DFImage(C2DBounds(5,5), ref_data );
+	std::shared_ptr<C2DImage > src(fsrc);
+	std::shared_ptr<C2DImage > ref(fref);
+
+	C2DSSDAutomaskCost cost(2, 1);
+	cost.set_reference(*ref); 
+	BOOST_CHECK_CLOSE(cost.value(*src),  0.5 * 245.0 / 22.0, 0.1);
+
+	C2DFVectorfield force(C2DBounds(5,5));
+
+	BOOST_CHECK_CLOSE(cost.evaluate_force(*src, force),  0.5 * 245.0 / 22.0, 0.1);
+
+	auto f = force(1,1); 
+	BOOST_CHECK_CLOSE(f.x,  0.5/ 22.0, 0.01); 
+	BOOST_CHECK_CLOSE(f.y,  2.0/ 22.0, 0.01); 
+
+}
+
diff --git a/mia/2d/cost/test_ssd.cc b/mia/2d/cost/test_ssd.cc
index 6fb9d58..98a69bd 100644
--- a/mia/2d/cost/test_ssd.cc
+++ b/mia/2d/cost/test_ssd.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE( test_SSD_2D )
 	P2DImage src(new C2DFImage(C2DBounds(4,4), src_data ));
 	P2DImage ref(new C2DFImage(C2DBounds(4,4), ref_data ));
 
-	C2DSSDCost cost(true);
+	C2DSSDCost cost(true, 0.0f);
 	cost.set_reference(*ref); 
 	double cost_value = cost.value(*src);
 	BOOST_CHECK_CLOSE(cost_value, 0.5 * 55.0 / 16.0, 0.1);
diff --git a/mia/2d/cost/test_ssd2.cc b/mia/2d/cost/test_ssd2.cc
index a7acd68..ab440e7 100644
--- a/mia/2d/cost/test_ssd2.cc
+++ b/mia/2d/cost/test_ssd2.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/creator.cc b/mia/2d/creator.cc
index 4d08ee3..fd98655 100644
--- a/mia/2d/creator.cc
+++ b/mia/2d/creator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/creator.hh b/mia/2d/creator.hh
index 79a6bfd..4dc300c 100644
--- a/mia/2d/creator.hh
+++ b/mia/2d/creator.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/creator/CMakeLists.txt b/mia/2d/creator/CMakeLists.txt
index 4c6edf2..7c2aae3 100644
--- a/mia/2d/creator/CMakeLists.txt
+++ b/mia/2d/creator/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/creator/circle.cc b/mia/2d/creator/circle.cc
index 8ab14f1..dbd5d5e 100644
--- a/mia/2d/creator/circle.cc
+++ b/mia/2d/creator/circle.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/cstkernel.cc b/mia/2d/cstkernel.cc
index de516e8..97e9db7 100644
--- a/mia/2d/cstkernel.cc
+++ b/mia/2d/cstkernel.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -73,11 +73,6 @@ void TCST2DKernel<T>::prepare(const C2DBounds& s)
 }
 
 
-
-template class TCST2DKernel<C2DFVectorfield>;
-template class TCST2DKernel<C2DFImage>;
-
-
 template <> const char *  const 
 TPluginHandler<TFactory<CCST2DImageKernel>>::m_help =  "These plug-ins define kernels for 2D processing of images "
 							"in the Cosine transformed space.";
@@ -86,6 +81,10 @@ template <> const char *  const
 TPluginHandler<TFactory<CCST2DVectorKernel>>::m_help =  "These plug-ins define kernels for 2D processing of vector fields "
 							"in the Cosine transformed space.";
 
+template class TCST2DKernel<C2DFVectorfield>;
+template class TCST2DKernel<C2DFImage>;
+
+
 EXPLICIT_INSTANCE_HANDLER(CCST2DVectorKernel);
 EXPLICIT_INSTANCE_HANDLER(CCST2DImageKernel);
 
diff --git a/mia/2d/cstkernel.hh b/mia/2d/cstkernel.hh
index 29cbcb3..1c2ea49 100644
--- a/mia/2d/cstkernel.hh
+++ b/mia/2d/cstkernel.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -94,18 +94,36 @@ private:
 /**
   \cond NEEDS_REHAUL 
 */
-
 typedef TCST2DKernel<C2DFVectorfield> CCST2DVectorKernel;
 typedef TCST2DKernel<C2DFImage>       CCST2DImageKernel;
 
-typedef  std::shared_ptr<CCST2DImageKernel > PCST2DImageKernel;
-typedef  std::shared_ptr<CCST2DVectorKernel > PCST2DVectorKernel;
+typedef std::shared_ptr<CCST2DImageKernel > PCST2DImageKernel;
+typedef std::shared_ptr<CCST2DVectorKernel > PCST2DVectorKernel;
 
 typedef TFactory<CCST2DVectorKernel> CCST2DVectorKernelPlugin;
-typedef THandlerSingleton<TFactoryPluginHandler<CCST2DVectorKernelPlugin> > CCST2DVectorKernelPluginHandler;
-
 typedef TFactory<CCST2DImageKernel> CCST2DImgKernelPlugin;
+
+typedef THandlerSingleton<TFactoryPluginHandler<CCST2DVectorKernelPlugin> > CCST2DVectorKernelPluginHandler;
 typedef THandlerSingleton<TFactoryPluginHandler<CCST2DImgKernelPlugin> > CCST2DImgKernelPluginHandler;
+
+template <> const char *  const 
+TPluginHandler<TFactory<CCST2DImageKernel>>::m_help;
+
+template <> const char *  const 
+TPluginHandler<TFactory<CCST2DVectorKernel>>::m_help;
+
+
+extern template class EXPORT_2D TCST2DKernel<C2DFVectorfield>; 
+extern template class EXPORT_2D TFactory<CCST2DVectorKernel>; 
+extern template class EXPORT_2D TFactoryPluginHandler<CCST2DVectorKernelPlugin>; 
+extern template class EXPORT_2D THandlerSingleton<TFactoryPluginHandler<CCST2DVectorKernelPlugin> >; 
+
+
+extern template class EXPORT_2D TCST2DKernel<C2DFImage>;
+extern template class EXPORT_2D TFactory<CCST2DImageKernel>; 
+extern template class EXPORT_2D TFactoryPluginHandler<CCST2DImgKernelPlugin>; 
+extern template class EXPORT_2D THandlerSingleton<TFactoryPluginHandler<CCST2DImgKernelPlugin> >; 
+
 /// \endcond 
 
 NS_MIA_END
diff --git a/mia/2d/datafield.cc b/mia/2d/datafield.cc
index a97a158..b2cf4a5 100644
--- a/mia/2d/datafield.cc
+++ b/mia/2d/datafield.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
  *
  */
 
+#include <mia/2d/defines2d.hh>
 #include <mia/2d/datafield.cxx>
 #include <mia/2d/iterator.cxx>
 #include <mia/core/parameter.cxx>
@@ -27,7 +28,10 @@ NS_MIA_BEGIN
 #define INSTANCIATE(TYPE) \
 	template class  EXPORT_2D T2DDatafield<TYPE>;			\
 	template class  EXPORT_2D range2d_iterator<T2DDatafield<TYPE>::iterator>; \
-	template class  EXPORT_2D range2d_iterator<T2DDatafield<TYPE>::const_iterator>;
+	template class  EXPORT_2D range2d_iterator<T2DDatafield<TYPE>::const_iterator>; \
+	template class  EXPORT_2D range2d_iterator_with_boundary_flag<T2DDatafield<TYPE>::iterator>; \
+	template class  EXPORT_2D range2d_iterator_with_boundary_flag<T2DDatafield<TYPE>::const_iterator>;
+
 
 
 INSTANCIATE(float); 
diff --git a/mia/2d/datafield.cxx b/mia/2d/datafield.cxx
index bb62824..19aaf19 100644
--- a/mia/2d/datafield.cxx
+++ b/mia/2d/datafield.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
  *
  */
 
+#undef mia_2d_datafield_cxx
 #ifndef mia_2d_datafield_cxx
 #define mia_2d_datafield_cxx
 
@@ -81,7 +82,7 @@ void T2DDatafield<T>::make_single_ref()
 }
 
 template <class T> 
-typename T2DDatafield<T>::size_type T2DDatafield<T>::size()const
+typename T2DDatafield<T>::size_type T2DDatafield<T>::size() const
 {
 	return m_data->size(); 
 }
diff --git a/mia/2d/datafield.hh b/mia/2d/datafield.hh
index 9e8b573..d414566 100644
--- a/mia/2d/datafield.hh
+++ b/mia/2d/datafield.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -71,6 +71,10 @@ public:
 	typedef typename data_array::size_type size_type;
 	typedef range2d_iterator<iterator> range_iterator; 
 	typedef range2d_iterator<const_iterator> const_range_iterator; 
+	typedef range2d_iterator_with_boundary_flag<iterator> range_iterator_with_boundary_flag; 
+	typedef range2d_iterator_with_boundary_flag<const_iterator> const_range_iterator_with_boundary_flag; 
+
+
 
 	typedef C2DBounds dimsize_type;
 	typedef C2DFVector coord_type;
diff --git a/mia/2d/defines2d.hh b/mia/2d/defines2d.hh
index 1d55a73..66f96fa 100644
--- a/mia/2d/defines2d.hh
+++ b/mia/2d/defines2d.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/deformer.hh b/mia/2d/deformer.hh
index f2d5121..793bfed 100644
--- a/mia/2d/deformer.hh
+++ b/mia/2d/deformer.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/distance.cc b/mia/2d/distance.cc
index ffa80d2..da212b2 100644
--- a/mia/2d/distance.cc
+++ b/mia/2d/distance.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/distance.hh b/mia/2d/distance.hh
index 45e4d2f..ae5dd6e 100644
--- a/mia/2d/distance.hh
+++ b/mia/2d/distance.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/distances.cc b/mia/2d/distances.cc
index 0154952..3e06864 100644
--- a/mia/2d/distances.cc
+++ b/mia/2d/distances.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/fft/CMakeLists.txt b/mia/2d/fft/CMakeLists.txt
index d3c21a6..b457f31 100644
--- a/mia/2d/fft/CMakeLists.txt
+++ b/mia/2d/fft/CMakeLists.txt
@@ -1,5 +1,5 @@
 #
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # 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
@@ -19,7 +19,7 @@
 #
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/fftkernel.cc b/mia/2d/fftkernel.cc
index 6c26827..dba8f3c 100644
--- a/mia/2d/fftkernel.cc
+++ b/mia/2d/fftkernel.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/fftkernel.hh b/mia/2d/fftkernel.hh
index 735f3a5..49c1409 100644
--- a/mia/2d/fftkernel.hh
+++ b/mia/2d/fftkernel.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter.cc b/mia/2d/filter.cc
index a9a56a4..1edadab 100644
--- a/mia/2d/filter.cc
+++ b/mia/2d/filter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,19 +26,13 @@
 #include <mia/core/handler.cxx>
 #include <mia/2d/shape.hh>
 
+#include <mia/template/combiner.hh>
+#include <mia/template/combiner.cxx>
+
 NS_MIA_BEGIN
 using namespace boost;
 using std::invalid_argument; 
 
-C2DImageCombiner::~C2DImageCombiner()
-{
-}
-
-C2DImageCombiner::result_type C2DImageCombiner::combine( const C2DImage& a, const C2DImage& b) const
-{
-	return do_combine(a,b);
-}
-
 P2DImage  EXPORT_2D run_filter_chain(P2DImage image, size_t nfilters, const char *filters[])
 {
 	const C2DFilterPluginHandler::Instance& ff = C2DFilterPluginHandler::instance();
@@ -71,21 +65,16 @@ P2DImage  EXPORT_2D run_filter(const C2DImage& image, const char *filter)
 	return f->filter(image);
 }
 
-using boost::filesystem::path; 
-C2DFilterPluginHandlerTestPath::C2DFilterPluginHandlerTestPath()
-{
-	C2DShapePluginHandlerTestPath filter_test_path;
-	CPathNameArray sksearchpath({path(MIA_BUILD_ROOT"/mia/2d/filter")});
-	C2DFilterPluginHandler::set_search_path(sksearchpath); 
-}
-
-
-
 template<> const  char * const 
 TPluginHandler<C2DFilterPlugin>::m_help = 
-   "These plug-ins provide 2D image filters. Unless otherwise noted, "
-   "they take a gray scale image of abitrary pixel type as input, "
-   "process it and hand it to the next filter in the pipeline." 
+	"These plug-ins provide 2D image filters. Unless otherwise noted, "
+	"they take a gray scale image of abitrary pixel type as input, "
+	"process it and return the result as newly created image. " 
+	"Filters can be chained by specifying more then one filter description "
+	"concated with the '+' sign. for example \n"
+	"   bandpass:min=10,max=20+median:w=3+convert:repn=ushort:map=copy'\n"
+	"will create a filter chain that first runs a bandpass, then a median "
+	"filter and a conversion to unsigned short values by a plain copy."
 ; 
 
 template<> const  char * const 
@@ -101,9 +90,7 @@ template class TFactoryPluginHandler<C2DFilterPlugin>;
 template class TPluginHandler<C2DFilterPlugin>;
 template class TFilterChain<C2DFilterPluginHandler>; 
 
-
-
-
+template class TImageCombiner<C2DImage>; 
 EXPLICIT_INSTANCE_HANDLER(C2DImageCombiner);
 
 NS_MIA_END
diff --git a/mia/2d/filter.hh b/mia/2d/filter.hh
index f3d7f69..99a5e7a 100644
--- a/mia/2d/filter.hh
+++ b/mia/2d/filter.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
 #include <mia/core/factory.hh>
 #include <mia/core/filter.hh>
 #include <mia/template/filter_chain.hh>
+#include <mia/template/combiner.hh>
 
 NS_MIA_BEGIN
 
@@ -52,15 +53,6 @@ typedef std::shared_ptr<C2DFilter > P2DFilter;
 */
 typedef THandlerSingleton<TFactoryPluginHandler<C2DFilterPlugin> > C2DFilterPluginHandler;
 
-/** @cond INTERNAL  
-    \ingroup test 
-    \brief Class to initialiaze the plug-in search path fot testing without installing the plug-ins 
-*/
-struct EXPORT_2D C2DFilterPluginHandlerTestPath {
-	C2DFilterPluginHandlerTestPath(); 
-}; 
-/// @endcond 
-
 /// @cond NEVER 
 FACTORY_TRAIT(C2DFilterPluginHandler); 
 /// @endcond 
@@ -129,31 +121,8 @@ inline P2DImage  EXPORT_2D run_filter(P2DImage image, const char *filter)
    
    A class to provides the base for operations that combine two images to create a new image
  */
-class EXPORT_2D C2DImageCombiner : public TFilter< P2DImage > ,
-				   public CProductBase {
-public:
-	/// data type for plug-in serachpath component 
-	typedef C2DImage plugin_data; 
-	/// plug-in type for plug-in serachpath component 
-	typedef combiner_type plugin_type; 
-	
-	virtual ~C2DImageCombiner();
-	/**
-	   Combine two images by a given operator 
-	   @param a 
-	   @param b 
-	   @returns combined image 
-	   
-	 */
-	result_type combine( const C2DImage& a, const C2DImage& b) const;
-private:
-	virtual result_type do_combine( const C2DImage& a, const C2DImage& b) const = 0;
-};
-
-
-
-/// Base class for image combiners 
-
+typedef TImageCombiner< C2DImage > C2DImageCombiner; 
+typedef std::shared_ptr<C2DImageCombiner> P2DImageCombiner; 
 typedef TFactory<C2DImageCombiner> C2DImageCombinerPlugin;
 
 /// Plugin handler for image combiner plugins 
@@ -161,6 +130,12 @@ typedef THandlerSingleton<TFactoryPluginHandler<C2DImageCombinerPlugin> >
         C2DImageCombinerPluginHandler;
 FACTORY_TRAIT(C2DImageCombinerPluginHandler); 
 
+class EXPORT_2D C2DCombinerPluginHandlerTestPath {
+public: 
+	C2DCombinerPluginHandlerTestPath(); 
+}; 
+
+
 NS_MIA_END
 
 
diff --git a/mia/2d/filter/CMakeLists.txt b/mia/2d/filter/CMakeLists.txt
index 8da31bf..932d36f 100644
--- a/mia/2d/filter/CMakeLists.txt
+++ b/mia/2d/filter/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -42,6 +42,7 @@ SET(filters2dNew_base
   aniso
   bandpass
   binarize
+  combiner
   convert
   crop
   distance
diff --git a/mia/2d/filter/adaptmed.cc b/mia/2d/filter/adaptmed.cc
index 8a34b5d..704b9f8 100644
--- a/mia/2d/filter/adaptmed.cc
+++ b/mia/2d/filter/adaptmed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/adaptmed.hh b/mia/2d/filter/adaptmed.hh
index e7e45ae..256cc15 100644
--- a/mia/2d/filter/adaptmed.hh
+++ b/mia/2d/filter/adaptmed.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/admean.cc b/mia/2d/filter/admean.cc
index 8bf1d66..29ef545 100644
--- a/mia/2d/filter/admean.cc
+++ b/mia/2d/filter/admean.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/admean.hh b/mia/2d/filter/admean.hh
index 944ce15..1f90b50 100644
--- a/mia/2d/filter/admean.hh
+++ b/mia/2d/filter/admean.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/aniso.cc b/mia/2d/filter/aniso.cc
index d56c31d..bc7c0e8 100644
--- a/mia/2d/filter/aniso.cc
+++ b/mia/2d/filter/aniso.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/aniso.hh b/mia/2d/filter/aniso.hh
index 98fc3e2..6ffe744 100644
--- a/mia/2d/filter/aniso.hh
+++ b/mia/2d/filter/aniso.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/bandpass.cc b/mia/2d/filter/bandpass.cc
index 5e7c370..06d884b 100644
--- a/mia/2d/filter/bandpass.cc
+++ b/mia/2d/filter/bandpass.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/bandpass.hh b/mia/2d/filter/bandpass.hh
index 8c0cb98..b5c2092 100644
--- a/mia/2d/filter/bandpass.hh
+++ b/mia/2d/filter/bandpass.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/binarize.cc b/mia/2d/filter/binarize.cc
index b182272..a336001 100644
--- a/mia/2d/filter/binarize.cc
+++ b/mia/2d/filter/binarize.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/binarize.hh b/mia/2d/filter/binarize.hh
index 273f384..0c6affe 100644
--- a/mia/2d/filter/binarize.hh
+++ b/mia/2d/filter/binarize.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/classmap.cc b/mia/2d/filter/classmap.cc
index 057d448..24017a0 100644
--- a/mia/2d/filter/classmap.cc
+++ b/mia/2d/filter/classmap.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/combiner.cc b/mia/2d/filter/combiner.cc
new file mode 100644
index 0000000..81fce58
--- /dev/null
+++ b/mia/2d/filter/combiner.cc
@@ -0,0 +1,36 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/filter/combiner.hh>
+#include <mia/2d/imageio.hh>
+
+NS_MIA_BEGIN
+
+template class  TImageCombinerFilter<C2DImage>; 
+template class  TImageCombinerFilterPlugin<C2DImage>; 
+
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+        return new C2DImageCombinerFilterPlugin; 
+}
+
+NS_MIA_END
+
diff --git a/mia/2d/filter/combiner.hh b/mia/2d/filter/combiner.hh
new file mode 100644
index 0000000..70040ca
--- /dev/null
+++ b/mia/2d/filter/combiner.hh
@@ -0,0 +1,38 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/filter.hh>
+#include <mia/2d/image.hh>
+#include <mia/template/combiner_filter.hh>
+
+
+#ifndef mia_2d_filter_combiner_hh
+#define mia_2d_filter_combiner_hh
+
+NS_MIA_BEGIN
+
+typedef TImageCombinerFilter<C2DImage> C2DImageCombinerFilter; 
+typedef TImageCombinerFilterPlugin<C2DImage> C2DImageCombinerFilterPlugin; 
+
+NS_MIA_END
+
+#endif 
+
+
diff --git a/mia/2d/filter/convert.cc b/mia/2d/filter/convert.cc
index bbd4c26..8005ced 100644
--- a/mia/2d/filter/convert.cc
+++ b/mia/2d/filter/convert.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/convert.hh b/mia/2d/filter/convert.hh
index 8a0fdf3..d8166f6 100644
--- a/mia/2d/filter/convert.hh
+++ b/mia/2d/filter/convert.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/crop.cc b/mia/2d/filter/crop.cc
index 33aced3..b34f6e1 100644
--- a/mia/2d/filter/crop.cc
+++ b/mia/2d/filter/crop.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/crop.hh b/mia/2d/filter/crop.hh
index 177b00c..d95e59c 100644
--- a/mia/2d/filter/crop.hh
+++ b/mia/2d/filter/crop.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/cst.cc b/mia/2d/filter/cst.cc
index 0920bef..3fea92a 100644
--- a/mia/2d/filter/cst.cc
+++ b/mia/2d/filter/cst.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/cst.hh b/mia/2d/filter/cst.hh
index fbb6407..0a70195 100644
--- a/mia/2d/filter/cst.hh
+++ b/mia/2d/filter/cst.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/distance.cc b/mia/2d/filter/distance.cc
index 716a7f4..d9c7006 100644
--- a/mia/2d/filter/distance.cc
+++ b/mia/2d/filter/distance.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/distance.hh b/mia/2d/filter/distance.hh
index ed1c7fa..a76b35b 100644
--- a/mia/2d/filter/distance.hh
+++ b/mia/2d/filter/distance.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/downscale.cc b/mia/2d/filter/downscale.cc
index cbf1305..38877f5 100644
--- a/mia/2d/filter/downscale.cc
+++ b/mia/2d/filter/downscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -98,7 +98,7 @@ CDownscale::result_type CDownscale::do_filter(const C2DImage& image) const
 
 C2DDownscaleFilterPlugin::C2DDownscaleFilterPlugin():
 	C2DFilterPlugin("downscale"),
-	m_b(1,1),
+	m_b(1,1), 
 	m_filter("gauss")
 {
 	add_parameter("bx", new CUIntParameter(m_b.x, 1,
@@ -111,10 +111,10 @@ C2DDownscaleFilterPlugin::C2DDownscaleFilterPlugin():
 
 	add_parameter("b", new C2DBoundsParameter(m_b, false, "blocksize"));
 
-	add_parameter("kernel", new CStringParameter(m_filter, false,
+	add_parameter("kernel", new CStringParameter(m_filter, CCmdOptionFlags::none, 
 						     "smoothing filter kernel to be applied, the "
 						     "size of the filter is estimated based on the blocksize.", 
-						     &C1DSpacialKernelPluginHandler::instance()));
+						     &C1DSpacialKernelPluginHandler::instance())); 
 }
 
 C2DFilter *C2DDownscaleFilterPlugin::do_create()const
diff --git a/mia/2d/filter/downscale.hh b/mia/2d/filter/downscale.hh
index 5523b7d..964f890 100644
--- a/mia/2d/filter/downscale.hh
+++ b/mia/2d/filter/downscale.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/fft.cc b/mia/2d/filter/fft.cc
index ffaa91d..8641b1b 100644
--- a/mia/2d/filter/fft.cc
+++ b/mia/2d/filter/fft.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/fft.hh b/mia/2d/filter/fft.hh
index 60ad4c1..bd3262f 100644
--- a/mia/2d/filter/fft.hh
+++ b/mia/2d/filter/fft.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/frequency.cc b/mia/2d/filter/frequency.cc
index 3f76e66..ca35ff7 100644
--- a/mia/2d/filter/frequency.cc
+++ b/mia/2d/filter/frequency.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/gradnorm.cc b/mia/2d/filter/gradnorm.cc
index efb46e3..83f124a 100644
--- a/mia/2d/filter/gradnorm.cc
+++ b/mia/2d/filter/gradnorm.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/gradnorm.hh b/mia/2d/filter/gradnorm.hh
index 2abc0f0..be28a04 100644
--- a/mia/2d/filter/gradnorm.hh
+++ b/mia/2d/filter/gradnorm.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/harmmean.cc b/mia/2d/filter/harmmean.cc
index 75cbcb7..e9fe6d5 100644
--- a/mia/2d/filter/harmmean.cc
+++ b/mia/2d/filter/harmmean.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/ianiso.cc b/mia/2d/filter/ianiso.cc
index f19c2a0..913ca34 100644
--- a/mia/2d/filter/ianiso.cc
+++ b/mia/2d/filter/ianiso.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/invert.cc b/mia/2d/filter/invert.cc
index fc792d2..b145d4e 100644
--- a/mia/2d/filter/invert.cc
+++ b/mia/2d/filter/invert.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/invert.hh b/mia/2d/filter/invert.hh
index 573ec4a..0e23c74 100644
--- a/mia/2d/filter/invert.hh
+++ b/mia/2d/filter/invert.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/kmeans.cc b/mia/2d/filter/kmeans.cc
index a787ea3..7ad03be 100644
--- a/mia/2d/filter/kmeans.cc
+++ b/mia/2d/filter/kmeans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/kmeans.hh b/mia/2d/filter/kmeans.hh
index 854b6c8..c5345f2 100644
--- a/mia/2d/filter/kmeans.hh
+++ b/mia/2d/filter/kmeans.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/kuwahara.cc b/mia/2d/filter/kuwahara.cc
index dacc594..3364675 100644
--- a/mia/2d/filter/kuwahara.cc
+++ b/mia/2d/filter/kuwahara.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/label.cc b/mia/2d/filter/label.cc
index e98fe73..aed7ef3 100644
--- a/mia/2d/filter/label.cc
+++ b/mia/2d/filter/label.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/label.hh b/mia/2d/filter/label.hh
index 3a04a54..8c26324 100644
--- a/mia/2d/filter/label.hh
+++ b/mia/2d/filter/label.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/labelmap.cc b/mia/2d/filter/labelmap.cc
index c3082d4..ad8c29a 100644
--- a/mia/2d/filter/labelmap.cc
+++ b/mia/2d/filter/labelmap.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -72,7 +72,7 @@ typename C2DLabelMapFilter::result_type C2DLabelMapFilter::operator () (const Da
 C2DLabelMapFilterPlugin::C2DLabelMapFilterPlugin():
 	C2DFilterPlugin("labelmap")
 {
-	add_parameter("map", new CStringParameter(m_map, true, "Label mapping file")) ;
+	add_parameter("map", new CStringParameter(m_map, CCmdOptionFlags::required_input, "Label mapping file")) ;
 }
 
 
diff --git a/mia/2d/filter/labelmap.hh b/mia/2d/filter/labelmap.hh
index 14c07a1..9d7ad63 100644
--- a/mia/2d/filter/labelmap.hh
+++ b/mia/2d/filter/labelmap.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/lnfft.cc b/mia/2d/filter/lnfft.cc
index 9183100..50bc807 100644
--- a/mia/2d/filter/lnfft.cc
+++ b/mia/2d/filter/lnfft.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/load.cc b/mia/2d/filter/load.cc
index b9371a6..01208c4 100644
--- a/mia/2d/filter/load.cc
+++ b/mia/2d/filter/load.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -39,7 +39,7 @@ mia::P2DImage C2DLoad::do_filter(const mia::C2DImage& MIA_PARAM_UNUSED(image)) c
 C2DLoadFilterPluginFactory::C2DLoadFilterPluginFactory(): 
 	C2DFilterPlugin("load")
 {
-	add_parameter("file", new CStringParameter(m_filename, true,
+	add_parameter("file", new CStringParameter(m_filename, CCmdOptionFlags::required_input,
 						   "name of the input file to load from.", 
 						   &C2DImageIOPluginHandler::instance()));
 }
diff --git a/mia/2d/filter/load.hh b/mia/2d/filter/load.hh
index d606d16..e68959e 100644
--- a/mia/2d/filter/load.hh
+++ b/mia/2d/filter/load.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/mask.cc b/mia/2d/filter/mask.cc
index ace88e9..feb4174 100644
--- a/mia/2d/filter/mask.cc
+++ b/mia/2d/filter/mask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -134,8 +134,9 @@ C2DMaskImageFilterFactory::C2DMaskImageFilterFactory():
 	m_fill(C2DMask::f_min), 
 	m_inverse(false)
 {
-	add_parameter("input", new CStringParameter(m_mask_filename, true, "second input image file name", 
-			      &C2DImageIOPluginHandler::instance()));
+	add_parameter("input", new CStringParameter(m_mask_filename, CCmdOptionFlags::required_input, 
+						    "second input image file name", 
+						    &C2DImageIOPluginHandler::instance()));
 	add_parameter("fill", new CDictParameter<C2DMask::EFill>(m_fill, TDictMap<C2DMask::EFill>( FillStyleTable), 
 								 "fill style for pixels outside of the mask"));
 	add_parameter("inverse", new CBoolParameter(m_inverse, false, "set to true to use the inverse of the mask for masking"));
diff --git a/mia/2d/filter/mask.hh b/mia/2d/filter/mask.hh
index 7b562d7..7cce737 100644
--- a/mia/2d/filter/mask.hh
+++ b/mia/2d/filter/mask.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/mean.cc b/mia/2d/filter/mean.cc
index 9960002..4d541e9 100644
--- a/mia/2d/filter/mean.cc
+++ b/mia/2d/filter/mean.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/mean.hh b/mia/2d/filter/mean.hh
index 3bfad76..93273dd 100644
--- a/mia/2d/filter/mean.hh
+++ b/mia/2d/filter/mean.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/median.cc b/mia/2d/filter/median.cc
index 1bd769c..e4111fe 100644
--- a/mia/2d/filter/median.cc
+++ b/mia/2d/filter/median.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/median.hh b/mia/2d/filter/median.hh
index 3ae5314..4e92dc1 100644
--- a/mia/2d/filter/median.hh
+++ b/mia/2d/filter/median.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/midpoint.cc b/mia/2d/filter/midpoint.cc
index 607266d..65c9252 100644
--- a/mia/2d/filter/midpoint.cc
+++ b/mia/2d/filter/midpoint.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/mlv.cc b/mia/2d/filter/mlv.cc
index 3971fca..65a3a41 100644
--- a/mia/2d/filter/mlv.cc
+++ b/mia/2d/filter/mlv.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/mlv.hh b/mia/2d/filter/mlv.hh
index 680afd0..2be2048 100644
--- a/mia/2d/filter/mlv.hh
+++ b/mia/2d/filter/mlv.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/morphological.cc b/mia/2d/filter/morphological.cc
index 6ae3c5f..f302019 100644
--- a/mia/2d/filter/morphological.cc
+++ b/mia/2d/filter/morphological.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/morphological.hh b/mia/2d/filter/morphological.hh
index 4f252df..f74d9db 100644
--- a/mia/2d/filter/morphological.hh
+++ b/mia/2d/filter/morphological.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/ngfnorm.cc b/mia/2d/filter/ngfnorm.cc
index 024d1c9..38406ec 100644
--- a/mia/2d/filter/ngfnorm.cc
+++ b/mia/2d/filter/ngfnorm.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/ngfnorm.hh b/mia/2d/filter/ngfnorm.hh
index 83eb57d..724435e 100644
--- a/mia/2d/filter/ngfnorm.hh
+++ b/mia/2d/filter/ngfnorm.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/noise.cc b/mia/2d/filter/noise.cc
index 3c707f9..ac9d4c6 100644
--- a/mia/2d/filter/noise.cc
+++ b/mia/2d/filter/noise.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/noise.hh b/mia/2d/filter/noise.hh
index 6e3f26c..a760d2f 100644
--- a/mia/2d/filter/noise.hh
+++ b/mia/2d/filter/noise.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/regiongrow.cc b/mia/2d/filter/regiongrow.cc
index 51683fe..a919ec6 100644
--- a/mia/2d/filter/regiongrow.cc
+++ b/mia/2d/filter/regiongrow.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -118,7 +118,7 @@ C2DRegiongrowFilter::result_type C2DRegiongrowFilter::do_filter(const mia::C2DIm
 C2DRegiongrowFilterPlugin::C2DRegiongrowFilterPlugin(): 
 	mia::C2DFilterPlugin("regiongrow")
 {
-	add_parameter("seed", new CStringParameter(m_seed_image, true, "seed image (bit valued)", 
+	add_parameter("seed", new CStringParameter(m_seed_image, CCmdOptionFlags::required_input, "seed image (bit valued)", 
 						   &C2DImageIOPluginHandler::instance()));
 	add_parameter("n", make_param(m_neighborhood, "8n", false, "Neighborhood shape"));
 }
diff --git a/mia/2d/filter/regiongrow.hh b/mia/2d/filter/regiongrow.hh
index a9ad236..c3c1d22 100644
--- a/mia/2d/filter/regiongrow.hh
+++ b/mia/2d/filter/regiongrow.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/rgg.cc b/mia/2d/filter/rgg.cc
index 29040a4..8b1fd9a 100644
--- a/mia/2d/filter/rgg.cc
+++ b/mia/2d/filter/rgg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/scale.cc b/mia/2d/filter/scale.cc
index f350980..1136d3e 100644
--- a/mia/2d/filter/scale.cc
+++ b/mia/2d/filter/scale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/scale.hh b/mia/2d/filter/scale.hh
index 52a3660..25a3d10 100644
--- a/mia/2d/filter/scale.hh
+++ b/mia/2d/filter/scale.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/seededwatershed.cc b/mia/2d/filter/seededwatershed.cc
index ee045c2..0f865cc 100644
--- a/mia/2d/filter/seededwatershed.cc
+++ b/mia/2d/filter/seededwatershed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/seededwatershed.hh b/mia/2d/filter/seededwatershed.hh
index 9aa3296..61716fa 100644
--- a/mia/2d/filter/seededwatershed.hh
+++ b/mia/2d/filter/seededwatershed.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/selectbig.cc b/mia/2d/filter/selectbig.cc
index 8f5d3d8..ad0f404 100644
--- a/mia/2d/filter/selectbig.cc
+++ b/mia/2d/filter/selectbig.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/selectbig.hh b/mia/2d/filter/selectbig.hh
index ce08fc4..06365c4 100644
--- a/mia/2d/filter/selectbig.hh
+++ b/mia/2d/filter/selectbig.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/sepconv.cc b/mia/2d/filter/sepconv.cc
index c0de4b9..1caea0c 100644
--- a/mia/2d/filter/sepconv.cc
+++ b/mia/2d/filter/sepconv.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/sepconv.hh b/mia/2d/filter/sepconv.hh
index addd157..db41ae4 100644
--- a/mia/2d/filter/sepconv.hh
+++ b/mia/2d/filter/sepconv.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/shaped_mean.cc b/mia/2d/filter/shaped_mean.cc
index 1792eb3..3935092 100644
--- a/mia/2d/filter/shaped_mean.cc
+++ b/mia/2d/filter/shaped_mean.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/shaped_mean.hh b/mia/2d/filter/shaped_mean.hh
index 0998b8b..7e31411 100644
--- a/mia/2d/filter/shaped_mean.hh
+++ b/mia/2d/filter/shaped_mean.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/sortlabel.cc b/mia/2d/filter/sortlabel.cc
index 1eb5d94..bd5841d 100644
--- a/mia/2d/filter/sortlabel.cc
+++ b/mia/2d/filter/sortlabel.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/sortlabel.hh b/mia/2d/filter/sortlabel.hh
index d754e9f..b890ca6 100644
--- a/mia/2d/filter/sortlabel.hh
+++ b/mia/2d/filter/sortlabel.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/tee.cc b/mia/2d/filter/tee.cc
index 96dcfe6..bc4a872 100644
--- a/mia/2d/filter/tee.cc
+++ b/mia/2d/filter/tee.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@ mia::P2DImage C2DTee::do_filter(mia::P2DImage image) const
 C2DTeeFilterPluginFactory::C2DTeeFilterPluginFactory(): 
 	C2DFilterPlugin("tee")
 {
-	add_parameter("file", new CStringParameter(m_filename, true,
+	add_parameter("file", new CStringParameter(m_filename, CCmdOptionFlags::required_output,
 						   "name of the output file to save the image too.", 
 						   &C2DImageIOPluginHandler::instance()));
 }
diff --git a/mia/2d/filter/tee.hh b/mia/2d/filter/tee.hh
index 6384a92..d06c27d 100644
--- a/mia/2d/filter/tee.hh
+++ b/mia/2d/filter/tee.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_adaptmed.cc b/mia/2d/filter/test_adaptmed.cc
index 434ca2f..0ad2440 100644
--- a/mia/2d/filter/test_adaptmed.cc
+++ b/mia/2d/filter/test_adaptmed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_admean.cc b/mia/2d/filter/test_admean.cc
index 1e87be1..76edbed 100644
--- a/mia/2d/filter/test_admean.cc
+++ b/mia/2d/filter/test_admean.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_aniso.cc b/mia/2d/filter/test_aniso.cc
index 44c4465..f44bd8c 100644
--- a/mia/2d/filter/test_aniso.cc
+++ b/mia/2d/filter/test_aniso.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_bandpass.cc b/mia/2d/filter/test_bandpass.cc
index 020243a..560145c 100644
--- a/mia/2d/filter/test_bandpass.cc
+++ b/mia/2d/filter/test_bandpass.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_binarize.cc b/mia/2d/filter/test_binarize.cc
index 6032852..6364065 100644
--- a/mia/2d/filter/test_binarize.cc
+++ b/mia/2d/filter/test_binarize.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_combiner.cc b/mia/2d/filter/test_combiner.cc
new file mode 100644
index 0000000..a450dea
--- /dev/null
+++ b/mia/2d/filter/test_combiner.cc
@@ -0,0 +1,110 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+#include <mia/2d/filter/combiner.hh>
+
+#include <mia/core/datapool.hh>
+#include <mia/2d/imageio.hh>
+#include <mia/2d/imagetest.hh>
+
+NS_MIA_USE
+
+struct Combiner2DFilterFixture {
+
+        Combiner2DFilterFixture(); 
+        ~Combiner2DFilterFixture();        
+        C2DFImage *image1; 
+        C2DFImage *image2; 
+        
+        P2DImage pimage1;
+        P2DImage pimage2; 
+        C2DBounds size; 
+};
+
+
+BOOST_FIXTURE_TEST_CASE(test_sub_default, Combiner2DFilterFixture) 
+{
+        auto c = BOOST_TEST_create_from_plugin<C2DImageCombinerFilterPlugin>("combiner:image=other.@,op=sub");
+
+
+        auto result = c->filter(pimage1); 
+        BOOST_REQUIRE(result); 
+
+        C2DFImage expect(size); 
+        transform(image1->begin(), image1->end(), image2->begin(), expect.begin(), 
+                  [](float a, float b){return a-b;}); 
+
+
+        test_image_equal(*result, expect);
+
+}
+
+BOOST_FIXTURE_TEST_CASE(test_sub_reverse, Combiner2DFilterFixture) 
+{
+        auto c = BOOST_TEST_create_from_plugin<C2DImageCombinerFilterPlugin>("combiner:image=other.@,op=sub,reverse=1");
+
+        auto result = c->filter(pimage1); 
+        BOOST_REQUIRE(result); 
+
+        C2DFImage expect(size); 
+        transform(image2->begin(), image2->end(), image1->begin(), expect.begin(), 
+                  [](float a, float b){return a-b;}); 
+
+        test_image_equal(*result, expect);
+}
+
+Combiner2DFilterFixture::Combiner2DFilterFixture():
+        size(3,4)
+{
+        image2 = new  C2DFImage(size); 
+        pimage2.reset(image2); 
+
+        float x = 0.1; 
+        for (auto i = image2->begin(); i != image2->end(); ++i, x += 0.2)
+                *i = x; 
+
+        image1 = new  C2DFImage(size); 
+        pimage1.reset(image1); 
+
+        x = 0.2; 
+        for (auto i = image1->begin(); i != image1->end(); ++i, x += 0.3)
+                *i = x; 
+
+
+        save_image("other.@", pimage2); 
+
+}
+
+Combiner2DFilterFixture::~Combiner2DFilterFixture()
+{
+        boost::any dummy = CDatapool::instance().get_and_remove("other.@");
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mia/2d/filter/test_convert.cc b/mia/2d/filter/test_convert.cc
index c9a03ed..e7c967a 100644
--- a/mia/2d/filter/test_convert.cc
+++ b/mia/2d/filter/test_convert.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_crop.cc b/mia/2d/filter/test_crop.cc
index e2f1871..ac48278 100644
--- a/mia/2d/filter/test_crop.cc
+++ b/mia/2d/filter/test_crop.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_cst.cc b/mia/2d/filter/test_cst.cc
index 659f668..3add0b6 100644
--- a/mia/2d/filter/test_cst.cc
+++ b/mia/2d/filter/test_cst.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_distance.cc b/mia/2d/filter/test_distance.cc
index 2504e7a..65f601e 100644
--- a/mia/2d/filter/test_distance.cc
+++ b/mia/2d/filter/test_distance.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_downscale.cc b/mia/2d/filter/test_downscale.cc
index 7b6a69c..11b02fe 100644
--- a/mia/2d/filter/test_downscale.cc
+++ b/mia/2d/filter/test_downscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,9 +29,6 @@ using namespace ::boost::unit_test;
 using namespace downscale_2dimage_filter;
 namespace bfs=::boost::filesystem;
 
-C1DSpacialKernelPluginHandlerTestPath spacial_kernel_test_path; 
-C2DFilterPluginHandlerTestPath filter_test_path; 
-
 
 BOOST_AUTO_TEST_CASE( test_downscale )
 {
diff --git a/mia/2d/filter/test_fft.cc b/mia/2d/filter/test_fft.cc
index 26cb952..47a299f 100644
--- a/mia/2d/filter/test_fft.cc
+++ b/mia/2d/filter/test_fft.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_gradnorm.cc b/mia/2d/filter/test_gradnorm.cc
index b965323..c3406ee 100644
--- a/mia/2d/filter/test_gradnorm.cc
+++ b/mia/2d/filter/test_gradnorm.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_invert.cc b/mia/2d/filter/test_invert.cc
index b4da5f0..214284f 100644
--- a/mia/2d/filter/test_invert.cc
+++ b/mia/2d/filter/test_invert.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_kmeans.cc b/mia/2d/filter/test_kmeans.cc
index c9d9b1b..e8d3d0f 100644
--- a/mia/2d/filter/test_kmeans.cc
+++ b/mia/2d/filter/test_kmeans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_label.cc b/mia/2d/filter/test_label.cc
index d763503..850908a 100644
--- a/mia/2d/filter/test_label.cc
+++ b/mia/2d/filter/test_label.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_labelmap.cc b/mia/2d/filter/test_labelmap.cc
index c8582a1..04be97f 100644
--- a/mia/2d/filter/test_labelmap.cc
+++ b/mia/2d/filter/test_labelmap.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_load.cc b/mia/2d/filter/test_load.cc
index 39f2c74..edeb489 100644
--- a/mia/2d/filter/test_load.cc
+++ b/mia/2d/filter/test_load.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
  *
  */
 
+
 #include <mia/internal/plugintester.hh>
 #include <mia/2d/filter/load.hh>
 #include <mia/core/datapool.hh>
diff --git a/mia/2d/filter/test_mask.cc b/mia/2d/filter/test_mask.cc
index 42d574f..eabd55c 100644
--- a/mia/2d/filter/test_mask.cc
+++ b/mia/2d/filter/test_mask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_mean.cc b/mia/2d/filter/test_mean.cc
index 52bd353..d9b47d8 100644
--- a/mia/2d/filter/test_mean.cc
+++ b/mia/2d/filter/test_mean.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_median.cc b/mia/2d/filter/test_median.cc
index cebbb1f..d6c5acf 100644
--- a/mia/2d/filter/test_median.cc
+++ b/mia/2d/filter/test_median.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_mlv.cc b/mia/2d/filter/test_mlv.cc
index 7435c3d..56275ce 100644
--- a/mia/2d/filter/test_mlv.cc
+++ b/mia/2d/filter/test_mlv.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_morphological.cc b/mia/2d/filter/test_morphological.cc
index 80f6a34..a7418c2 100644
--- a/mia/2d/filter/test_morphological.cc
+++ b/mia/2d/filter/test_morphological.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,8 +31,6 @@ using namespace ::boost;
 using namespace ::boost::unit_test;
 using namespace morphological_2dimage_filter;
 
-C2DShapePluginHandlerTestPath shape_test_path; 
-
 struct CTestShape: public C2DShape {
 	CTestShape() {
 		insert(C2DShape::Flat::value_type( 0, 0));
diff --git a/mia/2d/filter/test_ngfnorm.cc b/mia/2d/filter/test_ngfnorm.cc
index 01c728c..6fc7777 100644
--- a/mia/2d/filter/test_ngfnorm.cc
+++ b/mia/2d/filter/test_ngfnorm.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_noise.cc b/mia/2d/filter/test_noise.cc
index 055c928..9dce243 100644
--- a/mia/2d/filter/test_noise.cc
+++ b/mia/2d/filter/test_noise.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,8 +28,6 @@ using namespace ::boost::unit_test;
 using namespace noise_2dimage_filter;
 
 
-CNoiseGeneratorPluginHandlerTestPath noise_gen_test_path; 
-
 struct CTestNoiseGenerator: public  CNoiseGenerator {
 	CTestNoiseGenerator () :CNoiseGenerator(1){}
 
diff --git a/mia/2d/filter/test_regiongrow.cc b/mia/2d/filter/test_regiongrow.cc
index 14eade1..9448a08 100644
--- a/mia/2d/filter/test_regiongrow.cc
+++ b/mia/2d/filter/test_regiongrow.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,8 +25,6 @@
 using namespace mia;
 using namespace regiongrow_2d_filter;
 
-C2DShapePluginHandlerTestPath shape_plugin_path; 
-
 BOOST_AUTO_TEST_CASE ( test_regiongrow ) 
 {
 	const C2DBounds size(11, 10); 
diff --git a/mia/2d/filter/test_scale.cc b/mia/2d/filter/test_scale.cc
index 00d2bb4..3d723a0 100644
--- a/mia/2d/filter/test_scale.cc
+++ b/mia/2d/filter/test_scale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,8 +27,6 @@ using namespace ::boost;
 using namespace ::boost::unit_test;
 using namespace scale_2dimage_filter;
 
-CSplineKernelTestPath init_path; 
-
 BOOST_AUTO_TEST_CASE( test_downscale )
 {
 
diff --git a/mia/2d/filter/test_seededwatershed.cc b/mia/2d/filter/test_seededwatershed.cc
index 2b5c5fe..42c579e 100644
--- a/mia/2d/filter/test_seededwatershed.cc
+++ b/mia/2d/filter/test_seededwatershed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,8 +26,6 @@
 using namespace mia; 
 using namespace std; 
 
-C2DFilterPluginHandlerTestPath filter_test_path; 
-
 const unsigned char  seed[72] = {
 	1, 0, 0, 0, 0, 0, 0, 0, 4,
 	0, 0, 0, 0, 0, 0, 0, 0, 0,
diff --git a/mia/2d/filter/test_selectbig.cc b/mia/2d/filter/test_selectbig.cc
index 613a72a..696132f 100644
--- a/mia/2d/filter/test_selectbig.cc
+++ b/mia/2d/filter/test_selectbig.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_sepconv.cc b/mia/2d/filter/test_sepconv.cc
index bfc3beb..7968336 100644
--- a/mia/2d/filter/test_sepconv.cc
+++ b/mia/2d/filter/test_sepconv.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,8 +29,6 @@ using namespace ::boost::unit_test;
 namespace bfs=::boost::filesystem;
 using namespace SeparableConvolute_2dimage_filter;
 
-C1DSpacialKernelPluginHandlerTestPath spacial_kernel_test_path; 
-
 struct  SepconvTextFixture {
 	SepconvTextFixture(); 
 	
diff --git a/mia/2d/filter/test_shaped_mean.cc b/mia/2d/filter/test_shaped_mean.cc
index 4ecce13..3c2a432 100644
--- a/mia/2d/filter/test_shaped_mean.cc
+++ b/mia/2d/filter/test_shaped_mean.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,8 +27,6 @@ using namespace ::boost;
 using namespace ::boost::unit_test;
 using namespace shapedmean_2dimage_filter;
 
-C2DShapePluginHandlerTestPath shape_plugin_path; 
-
 BOOST_AUTO_TEST_CASE( test_2dfilter_mean_float_8n )
 {
 	const size_t size_x = 7;
diff --git a/mia/2d/filter/test_sortlabel.cc b/mia/2d/filter/test_sortlabel.cc
index fae8db2..3603fc9 100644
--- a/mia/2d/filter/test_sortlabel.cc
+++ b/mia/2d/filter/test_sortlabel.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_tee.cc b/mia/2d/filter/test_tee.cc
index 1278ba1..1531ca6 100644
--- a/mia/2d/filter/test_tee.cc
+++ b/mia/2d/filter/test_tee.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_thinning.cc b/mia/2d/filter/test_thinning.cc
index ad37d01..bd7637a 100644
--- a/mia/2d/filter/test_thinning.cc
+++ b/mia/2d/filter/test_thinning.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/test_thresh.cc b/mia/2d/filter/test_thresh.cc
index d37f892..8a63792 100644
--- a/mia/2d/filter/test_thresh.cc
+++ b/mia/2d/filter/test_thresh.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,8 +27,6 @@ using namespace ::boost;
 using namespace ::boost::unit_test;
 using namespace thresh_2dimage_filter;
 
-C2DShapePluginHandlerTestPath shape_test_path; 
-
 struct ThreshFixture {
 
 	ThreshFixture(); 
diff --git a/mia/2d/filter/test_transform.cc b/mia/2d/filter/test_transform.cc
index c07589a..481924e 100644
--- a/mia/2d/filter/test_transform.cc
+++ b/mia/2d/filter/test_transform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,7 +22,6 @@
 
 #include <mia/core/datapool.hh>
 #include <mia/2d/transformfactory.hh>
-#include <mia/2d/inittesthandlers.hh>
 #include <mia/2d/transformio.hh>
 #include <mia/2d/filter/transform.hh>
 
@@ -30,8 +29,6 @@
 using namespace transform_2dimage_filter; 
 using namespace mia; 
 
-C2DTransformCreatorHandlerTestPath transformhandler_init_path; 
-
 struct TransformFixture {
 
 	TransformFixture();
diff --git a/mia/2d/filter/test_watershed.cc b/mia/2d/filter/test_watershed.cc
index 98790a5..d8841f1 100644
--- a/mia/2d/filter/test_watershed.cc
+++ b/mia/2d/filter/test_watershed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,7 +26,6 @@
 using namespace mia; 
 using namespace std; 
 
-C2DFilterPluginHandlerTestPath filter_test_path; 
 
 BOOST_AUTO_TEST_CASE ( test_seeded_watershead ) 
 {
diff --git a/mia/2d/filter/thinning.cc b/mia/2d/filter/thinning.cc
index b4387a0..b340398 100644
--- a/mia/2d/filter/thinning.cc
+++ b/mia/2d/filter/thinning.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/thinning.hh b/mia/2d/filter/thinning.hh
index e8db72d..998bc04 100644
--- a/mia/2d/filter/thinning.hh
+++ b/mia/2d/filter/thinning.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/thresh.cc b/mia/2d/filter/thresh.cc
index f99697b..4e26425 100644
--- a/mia/2d/filter/thresh.cc
+++ b/mia/2d/filter/thresh.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/thresh.hh b/mia/2d/filter/thresh.hh
index 55ffc4e..2cbdcf5 100644
--- a/mia/2d/filter/thresh.hh
+++ b/mia/2d/filter/thresh.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/transform.cc b/mia/2d/filter/transform.cc
index d9fa4f4..b1495b9 100644
--- a/mia/2d/filter/transform.cc
+++ b/mia/2d/filter/transform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -40,7 +40,7 @@ mia::P2DImage C2DTransform::do_filter(const mia::C2DImage& image) const
 C2DTransformFilterPluginFactory::C2DTransformFilterPluginFactory(): 
 	C2DFilterPlugin("transform")
 {
-	add_parameter("file", new CStringParameter(m_filename, true,
+	add_parameter("file", new CStringParameter(m_filename, CCmdOptionFlags::required_input,
 						   "Name of the file containing the transformation.", 
 						   &C2DTransformationIOPluginHandler::instance()));
 }
diff --git a/mia/2d/filter/transform.hh b/mia/2d/filter/transform.hh
index cbc0224..8f15f5f 100644
--- a/mia/2d/filter/transform.hh
+++ b/mia/2d/filter/transform.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/variation.cc b/mia/2d/filter/variation.cc
index 05a2b21..22a42b9 100644
--- a/mia/2d/filter/variation.cc
+++ b/mia/2d/filter/variation.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/watershed.cc b/mia/2d/filter/watershed.cc
index 7e080b5..35d6269 100644
--- a/mia/2d/filter/watershed.cc
+++ b/mia/2d/filter/watershed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/watershed.hh b/mia/2d/filter/watershed.hh
index a86c972..300b970 100644
--- a/mia/2d/filter/watershed.hh
+++ b/mia/2d/filter/watershed.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/wmean.cc b/mia/2d/filter/wmean.cc
index 1e6cf77..541c6ad 100644
--- a/mia/2d/filter/wmean.cc
+++ b/mia/2d/filter/wmean.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filter/ws.cc b/mia/2d/filter/ws.cc
index 5ce1874..19f6d7c 100644
--- a/mia/2d/filter/ws.cc
+++ b/mia/2d/filter/ws.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filterchain.cc b/mia/2d/filterchain.cc
index 9a5dff0..880d42b 100644
--- a/mia/2d/filterchain.cc
+++ b/mia/2d/filterchain.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filterchain.hh b/mia/2d/filterchain.hh
index 3f92f12..af1a622 100644
--- a/mia/2d/filterchain.hh
+++ b/mia/2d/filterchain.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filtertest.cc b/mia/2d/filtertest.cc
index fdec844..1a03c80 100644
--- a/mia/2d/filtertest.cc
+++ b/mia/2d/filtertest.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/filtertest.hh b/mia/2d/filtertest.hh
index c22b2dd..02ea88a 100644
--- a/mia/2d/filtertest.hh
+++ b/mia/2d/filtertest.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/fullcost.cc b/mia/2d/fullcost.cc
index eed1976..579606d 100644
--- a/mia/2d/fullcost.cc
+++ b/mia/2d/fullcost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,12 +32,6 @@ namespace bfs=::boost::filesystem;
 template class TFullCostPlugin<C2DTransformation>; 
 template class TFullCost<C2DTransformation>; 
 
-C2DFullCostPluginHandlerTestPath::C2DFullCostPluginHandlerTestPath()
-{
-	CPathNameArray cost_plugpath({bfs::path("fullcost")});
-	C2DFullCostPluginHandler::set_search_path(cost_plugpath);
-}
-
 template <> const char *  const 
 TPluginHandler<C2DFullCostPlugin>::m_help =  
 	"This class of cost functions evaluates the cost resulting from the "
diff --git a/mia/2d/fullcost.hh b/mia/2d/fullcost.hh
index 93d0c93..a2867ba 100644
--- a/mia/2d/fullcost.hh
+++ b/mia/2d/fullcost.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,18 +56,6 @@ inline P2DFullCost produce_2dfullcost(const std::string& descr)
 	return C2DFullCostPluginHandler::instance().produce(descr); 
 }
 
-/** 
-    @cond INTERNAL  
-    \ingroup test 
-    \brief Class to initialiaze the plug-in search path fot testing without installing the plug-ins 
-*/
-struct EXPORT_2D C2DFullCostPluginHandlerTestPath {
-	C2DFullCostPluginHandlerTestPath(); 
-private: 
-	C2DImageCostPluginHandlerTestPath cost_path_init; 
-};
-/// @endcond 
-
 
 /// @cond NEVER 
 FACTORY_TRAIT(C2DFullCostPluginHandler); 
diff --git a/mia/2d/fullcost/CMakeLists.txt b/mia/2d/fullcost/CMakeLists.txt
index 5abeb29..bd832f5 100644
--- a/mia/2d/fullcost/CMakeLists.txt
+++ b/mia/2d/fullcost/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,5 +16,5 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 
-SET(fullcost image divcurl)
+SET(fullcost image maskedimage)
 PLUGINGROUP_WITH_TEST_AND_PREFIX2("2dimage" "fullcost" "${fullcost}" mia2dtest )
diff --git a/mia/2d/fullcost/divcurl.cc b/mia/2d/fullcost/divcurl.cc
deleted file mode 100644
index d04a8de..0000000
--- a/mia/2d/fullcost/divcurl.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <limits>
-#include <algorithm>
-#include <mia/2d/fullcost/divcurl.hh>
-
-#include <mia/template/divcurl.cxx>
-NS_MIA_BEGIN
-
-template class TDivcurlFullCostPlugin<C2DTransformation>; 
-template class  TDivCurlFullCost<C2DTransformation>; 
-
-extern "C" EXPORT CPluginBase *get_plugin_interface()
-{
-	return new C2DDivCurlFullCostPlugin();
-}
-
-NS_MIA_END
-
-
-
diff --git a/mia/2d/fullcost/divcurl.hh b/mia/2d/fullcost/divcurl.hh
deleted file mode 100644
index 4408bcf..0000000
--- a/mia/2d/fullcost/divcurl.hh
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef mia_2d_divcurl_hh
-#define mia_2d_divcurl_hh
-
-
-#include <mia/2d/fullcost.hh>
-#include <mia/template/divcurl.hh>
-
-
-NS_MIA_BEGIN
-typedef TDivcurlFullCostPlugin<C2DTransformation> C2DDivCurlFullCostPlugin; 
-typedef TDivCurlFullCost<C2DTransformation> C2DDivCurlFullCost; 
-NS_MIA_END
-
-#endif
diff --git a/mia/2d/fullcost/image.cc b/mia/2d/fullcost/image.cc
index bdc39fb..ed35e29 100644
--- a/mia/2d/fullcost/image.cc
+++ b/mia/2d/fullcost/image.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -186,9 +186,9 @@ C2DImageFullCostPlugin::C2DImageFullCostPlugin():
 	m_ref_name("ref.@"), 
 	m_debug(false)
 {
-	add_parameter("src", new CStringParameter(m_src_name, false, "Study image", 
+	add_parameter("src", new CStringParameter(m_src_name, CCmdOptionFlags::input, "Study image", 
 			      &C2DImageIOPluginHandler::instance()));
-	add_parameter("ref", new CStringParameter(m_ref_name, false, "Reference image", 
+	add_parameter("ref", new CStringParameter(m_ref_name, CCmdOptionFlags::input, "Reference image", 
 			      &C2DImageIOPluginHandler::instance()));
 	add_parameter("cost", make_param(m_cost_kernel, "ssd", false, "Cost function kernel"));
 	add_parameter("debug", new CBoolParameter(m_debug, false, "Save intermediate resuts for debugging")); 
diff --git a/mia/2d/fullcost/image.hh b/mia/2d/fullcost/image.hh
index f98535a..4a56a3d 100644
--- a/mia/2d/fullcost/image.hh
+++ b/mia/2d/fullcost/image.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/fullcost/maskedimage.cc b/mia/2d/fullcost/maskedimage.cc
new file mode 100644
index 0000000..0994c18
--- /dev/null
+++ b/mia/2d/fullcost/maskedimage.cc
@@ -0,0 +1,320 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/fullcost/maskedimage.hh>
+#include <mia/2d/filter.hh>
+
+NS_MIA_BEGIN
+
+using namespace std; 
+
+C2DMaskedImageFullCost::C2DMaskedImageFullCost(const std::string& src, 
+				   const std::string& ref, 
+                                   const std::string& src_mask, 
+				   const std::string& ref_mask, 
+				   P2DMaskedImageCost cost, 
+				   double weight):
+	C2DFullCost(weight), 
+	m_src_key(C2DImageIOPluginHandler::instance().load_to_pool(src)), 
+	m_ref_key(C2DImageIOPluginHandler::instance().load_to_pool(ref)),
+        m_ref_mask_bit(nullptr), 
+	m_ref_mask_scaled_bit(nullptr), 
+	m_cost_kernel(cost)
+{
+	assert(m_cost_kernel); 
+
+        if (!src_mask.empty()) 
+                m_src_mask_key = C2DImageIOPluginHandler::instance().load_to_pool(src_mask); 
+        
+        if (!ref_mask.empty()) 
+                m_ref_mask_key = C2DImageIOPluginHandler::instance().load_to_pool(ref_mask); 
+
+        if (src_mask.empty() && ref_mask.empty()) {
+                throw invalid_argument("C2DMaskedImageFullCost: No masks give, you should used "
+                                       "the plain image cost instead"); 
+        }
+}
+
+bool C2DMaskedImageFullCost::do_has(const char *property) const
+{
+	return m_cost_kernel->has(property); 
+}
+
+/* 
+   This functions combines the moving and the fixed masks to a singular mask for cost function evaluation. 
+   - if no transformation is given then the original masks will be or-combined. In this case 
+     the masks must be of the same size. 
+   - if a transformation is given then the moving mask is transformed and then combined with 
+     the reference image mask 
+*/
+P2DImage C2DMaskedImageFullCost::get_combined_mask(const C2DTransformation *t, C2DBitImage **combined_mask) const 
+{
+        P2DImage temp_mask; 
+        *combined_mask = m_ref_mask_scaled_bit; 
+        if (m_src_mask_scaled) {
+		cvdebug() << "Maskedimage: Start with moving mask\n"; 
+		if (t) 
+			temp_mask = (*t)(*m_src_mask_scaled); 
+		else 
+			temp_mask.reset(m_src_mask_scaled->clone()); 
+
+                *combined_mask = static_cast<C2DBitImage *>(temp_mask.get());
+                assert(*combined_mask); 
+                
+                if (m_ref_mask_scaled_bit) {
+			cvdebug() << "Maskedimage: Combine with reference mask\n"; 
+                        if ( (*combined_mask)->get_size() != m_ref_mask_scaled_bit->get_size()){
+                                assert(!t && "Bug: The transformation should have created a mask of "
+                                       "the same size like the reference image mask"); 
+                                
+                                throw create_exception<invalid_argument>
+                                        ("C2DMaskedImageFullCost: the masks to be combined are "
+                                         "of different size: moving=[", (*combined_mask)->get_size(), 
+                                         "], reference=[", m_ref_mask_scaled_bit->get_size(), "]");
+                        }
+
+                        // A parameter should define how the masks are combined 
+                        transform((*combined_mask)->begin(), (*combined_mask)->end(),
+                                  m_ref_mask_scaled_bit->begin(), (*combined_mask)->begin(),
+                                  [](bool a, bool b){ return a || b;});
+                        
+                        // here a penalty could be added e.g. to ensure that the moving mask is 
+                        // always inside the fixed mask. However, it is difficult to evaluate a 
+                        // force for this.
+                }
+        }else
+		cvdebug() << "Maskedimage: Only have reference mask\n"; 
+        return temp_mask; 
+}
+
+double C2DMaskedImageFullCost::do_value(const C2DTransformation& t) const
+{
+	TRACE_FUNCTION; 
+	assert(m_src_scaled  && "Bug: you must call 'reinit()' before calling value(transform)"); 
+	P2DImage temp  = t(*m_src_scaled);
+        
+        C2DBitImage *temp_mask_bit = nullptr;
+        P2DImage temp_mask  = get_combined_mask(&t, &temp_mask_bit);
+        assert(temp_mask_bit); 
+        
+	const double result = m_cost_kernel->value(*temp, *temp_mask_bit); 
+	cvdebug() << "C2DMaskedImageFullCost::value = " << result << "\n"; 
+	return result; 
+}
+
+double C2DMaskedImageFullCost::do_value() const
+{
+	TRACE_FUNCTION; 
+	assert(m_src_scaled  && "Bug: you must call 'reinit()' before calling value()"); 
+
+        C2DBitImage *temp_mask_bit = nullptr;
+        P2DImage temp_mask  = get_combined_mask(nullptr, &temp_mask_bit);
+        assert(temp_mask_bit); 
+
+	const double result = m_cost_kernel->value(*m_src_scaled, *temp_mask_bit); 
+	cvdebug() << "C2DMaskedImageFullCost::value = " << result << "\n"; 
+	return result; 
+}
+
+
+double C2DMaskedImageFullCost::do_evaluate(const C2DTransformation& t, CDoubleVector& gradient) const
+{
+	TRACE_FUNCTION; 
+	assert(m_src_scaled  && "Bug: you must call 'reinit()' before calling evauate(...)"); 
+	
+	P2DImage temp  = t(*m_src_scaled);
+
+        C2DBitImage *temp_mask_bit = nullptr;
+        P2DImage temp_mask  = get_combined_mask(&t, &temp_mask_bit);
+        assert(temp_mask_bit); 
+        
+	C2DFVectorfield force(get_current_size()); 
+ 	double result = m_cost_kernel->evaluate_force(*temp, *temp_mask_bit, force); 
+	t.translate(force, gradient); 
+	return result; 
+	
+}
+
+void C2DMaskedImageFullCost::do_set_size()
+{
+	TRACE_FUNCTION; 
+	assert(m_src); 
+	assert(m_ref); 
+
+	if (m_src_scaled->get_size() != get_current_size() ||
+	    m_ref_scaled->get_size() != get_current_size())
+	{
+		stringstream filter_descr; 
+		filter_descr << "scale:s=[" << get_current_size()<<"]"; 
+		auto scaler = C2DFilterPluginHandler::instance().produce(filter_descr.str()); 
+		assert(scaler); 
+		cvdebug() << "C2DMaskedImageFullCost:scale images to " << get_current_size() << 
+			" using '" << filter_descr.str() << "'\n"; 
+		m_src_scaled = scaler->filter(*m_src); 
+		m_ref_scaled = scaler->filter(*m_ref);
+		m_cost_kernel->set_reference(*m_ref_scaled); 
+
+                if (m_src_mask)  {
+                    m_src_mask_scaled  = scaler->filter(*m_src_mask);
+                }
+
+                if (m_ref_mask)  {
+                    m_ref_mask_scaled  = scaler->filter(*m_ref_mask);
+                    m_ref_mask_scaled_bit = static_cast<C2DBitImage*>(m_ref_mask_scaled.get());  
+                }
+                assert ((m_src_mask_scaled || m_ref_mask_scaled) && 
+                        "Bug: At this point at least one mask should be available"); 
+	}
+}
+
+bool C2DMaskedImageFullCost::do_get_full_size(C2DBounds& size) const
+{
+	TRACE_FUNCTION; 
+	assert(m_src && "Hint: call 'reinit()' before calling get_full_size()"); 
+	if (size == C2DBounds::_0) {
+		size = m_src->get_size(); 
+		return true; 
+	}else
+		return 	size == m_src->get_size(); 
+}
+
+void C2DMaskedImageFullCost::do_reinit()
+{
+	TRACE_FUNCTION; 
+	//cvmsg() << "C2DMaskedImageFullCost: read " << m_src_key << " and " << m_ref_key << "\n"; 
+	m_src_scaled = m_src = get_from_pool(m_src_key);
+	m_ref_scaled = m_ref = get_from_pool(m_ref_key);
+
+        if (m_src_mask_key.key_is_valid()) {
+                m_src_mask = get_from_pool(m_src_mask_key);
+                if (m_src->get_size() != m_src_mask->get_size()) {
+                        throw create_exception<runtime_error>("C2DMaskedImageFullCost: moving image has size [", 
+                                                              m_src->get_size(), "], but corresponding mask is of size [", 
+                                                              m_src_mask->get_size(), "]"); 
+                }
+                
+                if (m_src_mask->get_pixel_type() != it_bit) {
+                        // one could also add a binarize filter here, but  it's better to force 
+                        // the user to set the pixel type correctly 
+                        throw create_exception<invalid_argument>("C2DMaskedImageFullCost: moving mask image ", 
+								 m_src_mask_key.get_key(), 
+                                                                 " must be binary"); 
+                }
+		m_src_mask_scaled = m_src_mask; 
+        }
+
+        if (m_ref_mask_key.key_is_valid()) {
+                m_ref_mask = get_from_pool(m_ref_mask_key);
+                if (m_ref->get_size() != m_ref_mask->get_size()) {
+                        throw create_exception<runtime_error>("C2DMaskedImageFullCost: reference image has size [", 
+                                                              m_src->get_size(), "], but corresponding mask is of size [",
+                                                              m_src_mask->get_size(), "]"); 
+                }
+                m_ref_mask_scaled_bit = m_ref_mask_bit = dynamic_cast<C2DBitImage *>(m_ref_mask.get());
+                if (!m_ref_mask_scaled_bit)  {
+                        throw create_exception<invalid_argument>("C2DMaskedImageFullCost: reference mask image "
+                                                                 "must be binary");
+                }
+        }
+
+	if (m_src->get_size() != m_ref->get_size()) {
+                cvinfo() << "C2DMaskedImageFullCost: registering moving image of size [" << m_src->get_size() << "] " 
+                         << "to reference image of size [" << m_ref->get_size() << "]\n"; 
+        }
+
+        
+
+	if (m_src->get_pixel_size() != m_ref->get_pixel_size()) {
+		cvwarn() << "C2DMaskedImageFullCost: moving and reference image are of differnet pixel dimensions."
+                         << "unless you optimize a transformation that supports global scaling this might "
+                         << "not be what you want to do\n"; 
+	}
+	m_cost_kernel->set_reference(*m_ref_scaled); 
+}
+
+P2DImage C2DMaskedImageFullCost::get_from_pool(const C2DImageDataKey& key)
+{
+	C2DImageIOPlugin::PData in_image_list = key.get();
+		
+	if (!in_image_list || in_image_list->empty())
+		throw invalid_argument("C2DMaskedImageFullCost: no image available in data pool");
+
+	return (*in_image_list)[0];
+}
+
+
+// plugin implementation 
+class C2DMaskedImageFullCostPlugin: public C2DFullCostPlugin {
+public: 
+	C2DMaskedImageFullCostPlugin(); 
+private: 
+	C2DFullCost *do_create(float weight) const;
+	const std::string do_get_descr() const;
+	std::string m_src_name;
+	std::string m_ref_name;
+	std::string m_src_mask_name;
+	std::string m_ref_mask_name;
+
+	P2DMaskedImageCost m_cost_kernel;
+}; 
+
+C2DMaskedImageFullCostPlugin::C2DMaskedImageFullCostPlugin():
+	C2DFullCostPlugin("maskedimage"), 
+	m_src_name("src.@"), 
+	m_ref_name("ref.@")
+{
+	add_parameter("src", new CStringParameter(m_src_name, CCmdOptionFlags::input, "Study image", &C2DImageIOPluginHandler::instance()));
+	add_parameter("ref", new CStringParameter(m_ref_name, CCmdOptionFlags::input, "Reference image", &C2DImageIOPluginHandler::instance()));
+
+	add_parameter("src-mask", new CStringParameter(m_src_mask_name, CCmdOptionFlags::input, 
+                                                       "Study image mask (binary)", &C2DImageIOPluginHandler::instance()));
+	add_parameter("ref-mask", new CStringParameter(m_ref_mask_name, CCmdOptionFlags::input, 
+                                                       "Reference image mask  (binary)", &C2DImageIOPluginHandler::instance()));
+
+	add_parameter("cost", make_param(m_cost_kernel, "ssd", false, "Cost function kernel"));
+}
+
+C2DFullCost *C2DMaskedImageFullCostPlugin::do_create(float weight) const
+{
+	cvdebug() << "create C2DMaskedImageFullCostPlugin with weight= " << weight 
+		  << " src=" << m_src_name << " ref=" << m_ref_name 
+                  << " src-mask='" << m_src_mask_name << "' ref='" << m_ref_name 
+		  << "' cost=" << m_cost_kernel << "\n";
+
+	return new C2DMaskedImageFullCost(m_src_name, m_ref_name, 
+                                          m_src_mask_name, m_ref_mask_name, 
+                                          m_cost_kernel, weight); 
+}
+
+const std::string C2DMaskedImageFullCostPlugin::do_get_descr() const
+{
+	return "Generalized masked image similarity cost function that also handles multi-resolution processing. "
+                "The provided masks should be densly filled regions in multi-resolution procesing because "
+                "otherwise the mask information may get lost when downscaling the image. " 
+                "The reference mask and the transformed mask of the study image are combined by binary AND. "
+		"The actual similarity measure is given es extra parameter.";
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C2DMaskedImageFullCostPlugin();
+}
+
+NS_MIA_END
diff --git a/mia/2d/fullcost/maskedimage.hh b/mia/2d/fullcost/maskedimage.hh
new file mode 100644
index 0000000..f11bc81
--- /dev/null
+++ b/mia/2d/fullcost/maskedimage.hh
@@ -0,0 +1,80 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_2d_imagefullcost_hh
+#define mia_2d_imagefullcost_hh
+
+
+#include <mia/2d/fullcost.hh>
+#include <mia/2d/imageio.hh>
+#include <mia/2d/maskedcost.hh>
+
+NS_MIA_BEGIN
+
+class EXPORT C2DMaskedImageFullCost : public C2DFullCost {
+public: 
+	C2DMaskedImageFullCost(const std::string& src, 
+                               const std::string& ref, 
+                               const std::string& src_mask, 
+                               const std::string& ref_mask,
+                               P2DMaskedImageCost cost, 
+                               double weight); 
+private: 
+	double do_evaluate(const C2DTransformation& t, CDoubleVector& gradient) const;
+	void do_set_size(); 
+
+	static P2DImage get_from_pool(const C2DImageDataKey& key); 
+        
+        P2DImage get_combined_mask(const C2DTransformation *t, C2DBitImage **combined_mask) const __attribute__((warn_unused_result)); 
+
+	bool do_has(const char *property) const; 
+	double do_value(const C2DTransformation& t) const; 
+
+	double do_value() const; 
+	void do_reinit(); 
+	bool do_get_full_size(C2DBounds& size) const; 
+
+	C2DImageDataKey m_src_key;
+	C2DImageDataKey m_ref_key;
+
+	C2DImageDataKey m_src_mask_key;
+	C2DImageDataKey m_ref_mask_key;
+	
+	P2DImage m_src; 
+	P2DImage m_ref; 
+	P2DImage m_src_mask; 
+	P2DImage m_ref_mask; 
+	C2DBitImage *m_ref_mask_bit; 
+
+
+        P2DImage m_src_scaled; 
+	P2DImage m_ref_scaled;
+	P2DImage m_src_mask_scaled; 
+	P2DImage m_ref_mask_scaled; 
+
+	C2DBitImage *m_ref_mask_scaled_bit;
+
+	P2DMaskedImageCost m_cost_kernel; 
+	bool m_debug;
+}; 
+
+NS_MIA_END
+
+#endif
diff --git a/mia/2d/fullcost/test_divcurl.cc b/mia/2d/fullcost/test_divcurl.cc
deleted file mode 100644
index b292e1c..0000000
--- a/mia/2d/fullcost/test_divcurl.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <mia/2d/fullcost/image.hh>
-#include <mia/2d/transformmock.hh>
-
-#include <mia/internal/autotest.hh>
-#include <mia/2d/fullcost/divcurl.hh>
-#include <mia/2d/transformmock.hh>
-
-NS_MIA_USE
-namespace bfs=::boost::filesystem;
-
-CSplineKernelTestPath kernel_test_path; 
-
-BOOST_AUTO_TEST_CASE( test_divcurl_cost ) 
-{
-	C2DDivCurlFullCost  div(4.0, 6.0, 1.0); 
-
-	C2DBounds size(1,2); 
-	C2DTransformMock t(size); 
-	div.set_size(size); 
-
-	CDoubleVector gradient(t.degrees_of_freedom(), true); 
-	BOOST_CHECK_EQUAL(div.evaluate(t, gradient), 5.0); 
-	BOOST_CHECK_EQUAL(gradient[0], -2.0); 
-	BOOST_CHECK_EQUAL(gradient[1], -3.0); 
-}
-
-BOOST_AUTO_TEST_CASE( test_div_cost ) 
-{
-	C2DDivCurlFullCost  div(4.0, 0.0, 0.5); 
-
-	C2DBounds size(1,2); 
-	C2DTransformMock t(size); 
-	div.set_size(size); 
-
-	CDoubleVector gradient(t.degrees_of_freedom()); 
-	BOOST_CHECK_EQUAL(div.evaluate(t, gradient), 1.0); 
-	BOOST_CHECK_EQUAL(gradient[0], -1.0); 
-	BOOST_CHECK_EQUAL(gradient[1], 0.0); 
-}
-
-BOOST_AUTO_TEST_CASE( test_curl_cost ) 
-{
-	C2DDivCurlFullCost  div(0.0, 4.0, 2.0); 
-
-	C2DBounds size(1,2); 
-	C2DTransformMock t(size); 
-	div.set_size(size); 
-
-	CDoubleVector gradient(t.degrees_of_freedom()); 
-	BOOST_CHECK_EQUAL(div.evaluate(t, gradient), 4.0); 
-	BOOST_CHECK_EQUAL(gradient[0], 0.0); 
-	BOOST_CHECK_EQUAL(gradient[1], -4.0); 
-}
-
-BOOST_AUTO_TEST_CASE( test_curl_cost_notrans ) 
-{
-	C2DDivCurlFullCost  div(0.0, 4.0, 2.0); 
-
-	C2DBounds size(1,2); 
-	div.set_size(size); 
-
-	BOOST_CHECK_EQUAL(div.cost_value(), 0.0); 
-}
diff --git a/mia/2d/fullcost/test_image.cc b/mia/2d/fullcost/test_image.cc
index 2daf4b9..40e6fa0 100644
--- a/mia/2d/fullcost/test_image.cc
+++ b/mia/2d/fullcost/test_image.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,8 +19,8 @@
  */
 
 #include <mia/2d/fullcost/image.hh>
-#include <mia/2d/inittesthandlers.hh>
 #include <mia/2d/imageio.hh>
+#include <mia/2d/transformfactory.hh>
 #include <mia/2d/filter.hh>
 
 #include <mia/internal/autotest.hh>
@@ -35,30 +35,6 @@ struct ImagefullcostFixture {
 	P2DTransformationFactory tff; 
 }; 
 
-
-CSplineKernelTestPath init_splinekernel_path; 
-
-struct InitSplinekernelTestPath {
-	InitSplinekernelTestPath() {
-		CPathNameArray cost_plugpath;
-		cost_plugpath.push_back(bfs::path("../cost"));
-		C2DImageCostPluginHandler::set_search_path(cost_plugpath);
-		
-		CPathNameArray filter_plugpath;
-		filter_plugpath.push_back(bfs::path("../filter"));
-		C2DFilterPluginHandler::set_search_path(filter_plugpath);
-		
-		CPathNameArray io_plugpath;
-		io_plugpath.push_back(bfs::path("../io"));
-		C2DImageIOPluginHandler::set_search_path(io_plugpath);
-		
-	}
-}; 
-
-C2DTransformCreatorHandlerTestPath tfc_test_path; 
-
-InitSplinekernelTestPath init_path; 
-
 BOOST_FIXTURE_TEST_CASE( test_imagefullcost,  ImagefullcostFixture ) 
 {
 
diff --git a/mia/2d/fullcost/test_maskedimage.cc b/mia/2d/fullcost/test_maskedimage.cc
new file mode 100644
index 0000000..20b6c38
--- /dev/null
+++ b/mia/2d/fullcost/test_maskedimage.cc
@@ -0,0 +1,196 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define VSTREAM_DOMAIN "test-maskedimage" 
+#include <mia/2d/fullcost/maskedimage.hh>
+#include <mia/2d/transformfactory.hh>
+#include <mia/2d/imageio.hh>
+#include <mia/2d/filter.hh>
+
+#include <mia/internal/autotest.hh>
+
+NS_MIA_USE
+namespace bfs=::boost::filesystem;
+
+BOOST_AUTO_TEST_CASE( test_imagefullcost_src_mask)
+{
+
+	// create two images 
+	const unsigned char src_data[64] = {
+		0, 0, 0, 0,   0, 0, 0, 0,  
+		0, 0, 0, 0,   0, 0, 0, 0,
+ 		0, 0, 0, 0,   0, 0, 0, 0, 
+		0, 0, 0, 0,   0, 0, 0, 0,
+		
+ 		0, 0, 0,  0,   0,255,255, 0,  
+		0,255,255,0,   0, 128, 0, 0, 
+		0, 255, 0, 0,  0, 128,  0, 0,  
+		0, 0,  0, 0,   0, 0, 0, 0
+
+	};
+	const unsigned char ref_data[64] = {
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	};
+
+	const bool src_mask_data[64] = {
+		0, 0, 0, 0,   0,  0,  0, 0,  0, 0, 0, 0,   0, 0, 0, 0,
+		0, 0, 0, 0,   0,  0,  0, 0,  0, 0, 0, 0,   0, 0, 0, 0,
+		0, 0, 0, 0,   0,  1,  1, 0,  0, 1, 1, 0,   0, 0, 0, 0,
+		0, 0, 0, 0,   0,  0,  0, 0,  0, 0, 0, 0,   0, 0, 0, 0
+
+	};
+
+	C2DBounds size(8,8); 
+
+	P2DImage src(new C2DUBImage(size, src_data ));
+	P2DImage ref(new C2DUBImage(size, ref_data ));
+
+	P2DImage src_mask(new C2DBitImage(size, src_mask_data ));
+	
+	BOOST_REQUIRE(save_image("src.@", src)); 
+	BOOST_REQUIRE(save_image("ref.@", ref)); 
+	BOOST_REQUIRE(save_image("src-mask.@", src_mask)); 
+
+	C2DMaskedImageFullCost cost("src.@", "ref.@","src-mask.@", "" ,
+                                    C2DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0); 
+
+	cvdebug() << "prepare cost\n"; 
+	cost.reinit(); 
+	cvdebug() << "set size cost\n"; 
+	cost.set_size(size);
+	
+	auto tfactory = produce_2dtransform_factory("vf"); 
+	auto t = tfactory->create(size); 
+	auto tp = t->get_parameters(); 
+	std::fill(tp.begin(), tp.end(),0.0); 
+	t->set_parameters(tp); 
+	
+	CDoubleVector gradient(t->degrees_of_freedom()); 
+	double cost_value = cost.evaluate(*t, gradient);
+	BOOST_CHECK_EQUAL(gradient.size(), 2u * 64u); 
+
+	BOOST_CHECK_CLOSE(cost_value, 0.5 * 255 * 255.0/16.0 , 0.1);
+
+	double value = cost.cost_value(*t);
+
+	BOOST_CHECK_CLOSE(value, 0.5 * 255 * 255.0/16.0  , 0.1);
+	
+	BOOST_CHECK_CLOSE(gradient[74], -255 *255/128.0 , 0.1);
+	BOOST_CHECK_CLOSE(gradient[75], -255.0 , 0.1);
+	cvdebug() << gradient << "\n"; 	
+}
+
+BOOST_AUTO_TEST_CASE( test_imagefullcost_ref_mask)
+{
+
+	// create two images 
+	const unsigned char src_data[64] = {
+		0, 0, 0, 0,   0, 0, 0, 0,  
+		0, 0, 0, 0,   0, 0, 0, 0,
+ 		0, 0, 0, 0,   0, 0, 0, 0, 
+		0, 0, 0, 0,   0, 0, 0, 0,
+		
+ 		0, 0, 0,  0,   0,255,255, 0,  
+		0,255,255,0,   0, 128, 0, 0, 
+		0, 255, 0, 0,  0,128,  0, 0,  
+		0, 0,  0, 0,   0, 0, 0, 0
+
+	};
+	const unsigned char ref_data[64] = {
+		0, 0, 0, 0, 
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0
+
+	};
+
+	const bool src_mask_data[64] = {
+		0, 0, 0, 0,   0, 0, 0, 0,   
+		0, 0, 0, 0,   0, 0, 0, 0,
+		0, 0, 0, 0,   0, 0, 0, 0,   
+		0, 0, 0, 0,   0, 0, 0, 0,
+		
+		0, 0, 0, 0,   0, 1, 1, 0,   
+		0, 1, 1, 0,   0, 0, 0, 0,
+		0, 0, 0, 0,   0, 0, 0, 0,   
+		0, 0, 0, 0,   0, 0, 0, 0
+
+	};
+
+	C2DBounds size(8,8); 
+
+	P2DImage src(new C2DUBImage(size, src_data ));
+	P2DImage ref(new C2DUBImage(size, ref_data ));
+
+	P2DImage src_mask(new C2DBitImage(size, src_mask_data ));
+	
+	BOOST_REQUIRE(save_image("src.@", src)); 
+	BOOST_REQUIRE(save_image("ref.@", ref)); 
+	BOOST_REQUIRE(save_image("ref-mask.@", src_mask)); 
+
+        assert("at least one mask must be provided"); 
+	C2DMaskedImageFullCost cost("src.@", "ref.@","", "ref-mask.@",
+                                    C2DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0); 
+
+	cvdebug() << "prepare cost\n"; 
+	cost.reinit(); 
+	cvdebug() << "set size cost\n"; 
+	cost.set_size(size);
+	
+	auto tfactory = produce_2dtransform_factory("vf"); 
+	auto t = tfactory->create(size); 
+	auto tp = t->get_parameters(); 
+	std::fill(tp.begin(), tp.end(),0.0); 
+	t->set_parameters(tp); 
+
+	
+	CDoubleVector gradient(t->degrees_of_freedom()); 
+	double cost_value = cost.evaluate(*t, gradient);
+	BOOST_CHECK_EQUAL(gradient.size(), 2u * 64u); 
+
+	BOOST_CHECK_CLOSE(cost_value, 0.5 * 255 * 255.0/16.0 , 0.1);
+
+	double value = cost.cost_value(*t);
+
+	BOOST_CHECK_CLOSE(value, 0.5 * 255 * 255.0/16.0  , 0.1);
+	
+	BOOST_CHECK_CLOSE(gradient[74], -255 *255/128.0 , 0.1);
+	BOOST_CHECK_CLOSE(gradient[75], -255.0 , 0.1);
+
+	cvdebug() << gradient << "\n"; 
+}
diff --git a/mia/2d/fuzzyClusterSolverCG.cc b/mia/2d/fuzzyClusterSolverCG.cc
deleted file mode 100644
index f772d57..0000000
--- a/mia/2d/fuzzyClusterSolverCG.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <cstring>
-
-#include <mia/core/msgstream.hh>
-#include <mia/2d/fuzzyClusterSolverCG.hh>
-
-
-NS_MIA_BEGIN
-#warning this needs to be tested
-bool fborder (long index, long nx, long ny)
-{
-	const long x = index % nx;
-
-	if ( x < 2 || x > nx-3 )
-	     return true;
-
-	index /= nx;
-
-	const long y = index % ny;
-	if ( y < 2 || y > ny-3 )
-	     return true;
-
-	return false;
-
-}
-
-
-
-C2DSolveCG::C2DSolveCG (C2DFImage& w1, C2DFImage& f1, C2DFImage& gain_image, double l1, double l2, double r_res, double m_res):
-	m_lambda1(l1),
-	m_lambda2(l2),
-	m_iter(0),
-	m_nx(w1.get_size().x),
-	m_ny(w1.get_size().y),
-	m_count(m_nx*m_ny),
-	m_weight_imagePtr(&w1(0, 0)),
-	m_fptr(&f1(0, 0)),
-	m_gain_image_ptr(&gain_image(0, 0)),
-
-	m_b(m_count),
-	m_v(m_count),
-	m_r(m_count),
-
-	m_rho(m_count),   // p^(k)
-	m_g(m_count),
-	m_Ag(m_count),   // speichert A * p
-
-	m_scale(m_count),
-	m_scale2(m_count),
-	m_border(m_count),
-
-	m_r1rho1(0.0), 
-	m_r2rho2(0.0),
-	m_normr0(0.0),
-	m_q(0.0), 
-	m_e(0.0),
-	m_sprod(0.0),
-
-	m_min_res(m_res),
-	m_relres(r_res)
-
-{
-	TRACE_FUNCTION; 
-	init ();
-
-}
-
-
-C2DSolveCG::~C2DSolveCG()
-{
-}
-
-
-
-// Umweg, da keine Methoden parallel aufgerufen werden koennen
-void solver(C2DSolveCG *s, long *maxit, double *normr, double *firstnormr0)
-{
-    s->solvepar(maxit, normr, firstnormr0);
-}
-
-
-int C2DSolveCG::solve(long max_iterations, double *firstnormr0) {
-
-        double normr;
-
-#ifdef PARALLEL
-    	m_set_procs(NPROCS);
-    	m_fork((void (*)())solver, this, &max_iterations, &normr,firstnormr0);
-    	m_kill_procs();
-#else
-    	solver(this, &max_iterations, &normr,firstnormr0);
-#endif
-
-	return normr > 1;
-}
-
-
-// loest das Gleichungssystem mittels CG-Algorithmus
-void C2DSolveCG::solvepar(long *maxit, double *normr, double *firstnormr0) 
-{
-	TRACE_FUNCTION; 
-    // Prozessornummer
-    int me;
-
-    // Start und Ende fuer Vektoroperationen
-    long start;
-    long ende;
-
-    // Setze me, start und ende
-    me = 0;
-    start = 0;
-    ende = m_count;
-
-    // Initialisierung
-    cvmsg() << "mult = " << start << ", " << ende << "\n"; 
-    multA(m_v, m_r, start, ende);
-
-    // Berechnung normr0;
-    double tmp_normr0 = 0;
-    for(long i = start; i < ende; i++) {
-      m_r[i] += m_b[i];
-      double square = m_r[i]/m_scale[i];
-      tmp_normr0 += square*square;
-    }
-
-    m_normr0 = tmp_normr0;
-
-    if (me == 0)
-	    *normr = m_normr0 = sqrt(m_normr0);
-
-
-    if (*firstnormr0 == 1.0 && m_normr0 > 1.0)
-	    *firstnormr0 = m_normr0;
-
-
-    // Iterationen
-    while (*normr >= m_min_res && m_iter < *maxit && *normr / *firstnormr0 > m_relres){
-
-    	if (me == 0) {
-	  		m_iter++;
-			copy(m_r.begin(), m_r.end(), m_rho.begin()); 
-	  		m_r2rho2 = m_r1rho1;
-        }
-
-
-	// r1rho1 = r * rho
-	if (me == 0) m_r1rho1 = 0;
-
-	double tmp_r1rho1 = 0;
-	for(long i = start; i < ende; i++) {
-	  tmp_r1rho1 += m_r[i] * m_rho[i];
-	}
-
-	m_r1rho1 = tmp_r1rho1;
-
-	if (m_iter >= 2 && me == 0) m_e = m_r1rho1 / m_r2rho2; else m_e = 0;
-
-	for(long i = start; i < ende; i++) m_g[i] = -m_rho[i] + m_e * m_g[i];
-
-	multA(m_g, m_Ag, start, ende);
-
-	// q = r1rho1 / (g * Ag)
-	if (me == 0) m_sprod = 0;
-	double tmp_sprod = 0;
-
-	for(long i = start; i < ende; i++) tmp_sprod += m_g[i] * m_Ag[i];
-
-	m_sprod = tmp_sprod;
-
-	if (me == 0) m_q = m_r1rho1 / m_sprod;
-
-	// v = v1 + q * g, r = r1 + q * Ag
-	if (me == 0) *normr = 0;
-	double tmp_normr = 0;
-
-	for(long i = start; i < ende; i++) {
-
-	  m_v[i] += m_q * m_g[i];
-	  m_r[i] += m_q * m_Ag[i];
-	  tmp_normr += pow(m_r[i]/m_scale[i], 2);
-
-	}
-
-	*normr = tmp_normr;
-
-	if (me == 0)
-		*normr = sqrt(*normr);
-
-	//*\todo implement some progression alert here */
-
-    }
-
-    return;
- }
-
-
-// Vektor-Matrix-Multiplikation
-#define VALUE(o) (sc2[o] * x2[o])
-
-void C2DSolveCG::multA(vector<double>& x, vector<double>& result, long start, long ende) 
-{
-	assert(x.size() == result.size()); 
-	assert(x.size() == m_border.size()); 
-	assert(x.size() == m_scale2.size()); 
-	assert(x.size() == m_count); 
-
-	auto bord2 = m_border.begin(); 
-	auto res2 = result.begin(); 
-	auto x2 = x.begin(); 
-	auto sc2 = m_scale2.begin(); 
-	vector<double> help(x.size()); 
-	
-	transform(x.begin(), x.end(), m_scale2.begin(), help.begin(), 
-		  [](double x, double s) {return x * s; }); 
-
-	auto value = help.begin(); 
-	
-	for(int i = start; i < ende; i++, ++bord2, ++res2, ++x2, ++value, ++sc2) {
-		if (*bord2) {
-			*res2 = *x2;
-		}else {
-			
-			double s1= value[-m_nx      ] + value[-1] + value[+1] + value[+m_nx]; 
-			double s2= value[-m_nx   - 1] + value[-m_nx + 1]	+ value[+ m_nx -1]  + value[+m_nx + 1]; 
-			double s3= value[ - 2 * m_nx] + value[ - 2     ]  + value[+ 2]        + value[ + 2*m_nx];
-			
-			*res2 += ((s3 + 2*s2 - 8*s1) * m_lambda2 - m_lambda1 * s1) * *sc2;
-		}
-	}
-
-}
-
-
-#define VALUE2(o) ((bord2[o])?0:x2[o])
-
-void C2DSolveCG::multA_float(float *x, float *result) {
-
-	auto bord2 = m_border.begin(); 
-	float *x2, *res2;
-	
-	for(unsigned long i = 0; i < m_count; i++, ++bord2) {
-		
-		double s1, s2, s3;
-		
-		res2  = result + i;
-		x2    = x + i;
-		
-		if (*bord2) {
-			*res2 = (m_weight_imagePtr[i] + 4*m_lambda1 + 20*m_lambda2) * *x2;
-			continue;
-		}
-		
-		s1 = VALUE2(-m_nx)    + VALUE2(-1) + VALUE2(+1) + VALUE2(+m_nx);
-		
-		s2= VALUE2(-m_nx-1)     + VALUE2(-m_nx+1)	 + VALUE2(+m_nx-1)     + VALUE2(+m_nx+1);
-		
-		s3= VALUE2( - 2*m_nx) + VALUE2( - 2)	+ VALUE2( + 2) + VALUE2( + 2*m_nx);
-		
-		*res2 = (m_weight_imagePtr[i] + 4*m_lambda1+8*m_lambda2) * *x2  + ((s3 + 2*s2 - 12*s1) * m_lambda2 - m_lambda1 * s1);
-		
-	}
-}
-
-// loest die PDE  (w + m_lambda1 * H1 + m_lambda2 * H2)*m = f
-void C2DSolveCG::init()
-{
-	TRACE_FUNCTION; 
-	
-	// set b and scaling
-	for(unsigned long i = 0; i < m_count; i++) {
-		m_border[i] = (fborder(i, m_nx, m_ny)? 1 : 0);
-	}
-	
-	for(unsigned long i = 0; i < m_count; i++) {
-		// Wenn Element Randelement ist, setze b entsprechend
-		if (m_border[i]) {
-			m_b[i] = -m_gain_image_ptr[i];
-			m_scale[i] = 1.0;
-			m_scale2[i] = 0;
-			m_v[i] = m_gain_image_ptr[i] / m_scale[i];
-			continue;
-		}
-		
-		// set b[i]
-		m_b[i] = -m_fptr[i];
-		
-		// ziehe Anteile aus Randelementen ab
-		
-		// scaling
-		m_scale[i] = m_scale2[i] = 1.0 / sqrt(m_weight_imagePtr[i] + 4*m_lambda1 + 20*m_lambda2);
-		m_b[i] *= m_scale[i];
-		m_v[i] = m_gain_image_ptr[i] / m_scale[i];
-	}
-}
-
-
-void C2DSolveCG::get_solution(C2DFImage& m) {
-
-	C2DFImage::iterator m_gain_image_ptr = m.begin();
-	for(unsigned long i = 0; i < m_count; i++, ++m_gain_image_ptr)
-		*m_gain_image_ptr = (float)m_v[i] * m_scale[i];
-}
-
-
-void C2DSolveCG::add_to_solution(C2DFImage *e) {
-
-  C2DFImage::iterator eptr = e->begin();
-
-  for(unsigned long i = 0; i < m_count; i++)
-    m_v[i] += eptr[i] / m_scale[i];
-}
-
-NS_MIA_END
diff --git a/mia/2d/fuzzyClusterSolverCG.hh b/mia/2d/fuzzyClusterSolverCG.hh
deleted file mode 100644
index 117b0d2..0000000
--- a/mia/2d/fuzzyClusterSolverCG.hh
+++ /dev/null
@@ -1,179 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef __SOLVERCG_HH
-#define __SOLVERCG_HH
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <mia/2d.hh>
-#include <cstdio>
-#include <stdexcept>
-#include <string>
-
-
-
-NS_MIA_BEGIN
-
-using namespace std;
-
-
-
-/*! \brief function defining field borders
-
-    \param index  index running from 0 to NoOfPixels
-    \param nx     no of pixels in x
-    \param ny     no of pixels in y
-
-*/
-extern bool fborder (long index, long nx, long ny);
-
-/*! 
-  @ingroup filtering
-  \brief solve_sCG -- a class providing a CG solver
-
-	This contains basic solver functions based on CG schemes
-
-\author Stefan Burckhardt and Carsten Wolters, wolters at mis.mpg.de, 2004
-\remark adapted for libmona by Heike Jaenicke and Marc Tittgemeyer, tittge at cbs.mpg.de, 2004
-\remark adapted for mia2 by Gert Wollny, gw.fossdev at gmail.com 2011 
-*/
-
-
-class C2DSolveCG {
-
-  private:
-	double m_lambda1;
-	double m_lambda2;
-
-	// Dimension of images
-	long m_iter;
-	int  m_nx, m_ny;
-	unsigned long m_count;
-
-	// Pointer to Elements of w
-	float *m_weight_imagePtr;
-	float *m_fptr;
-	float *m_gain_image_ptr;
-
-
-
-	// b and x for solution of system
-	std::vector<double> m_b;
-	std::vector<double> m_v;
-
-	// counts iterations
-
-
-	// help pointers for one iteration cycle
-	std::vector<double> m_r;	   // r^(k)
-	std::vector<double> m_rho;     // p^(k)
-	std::vector<double> m_g;
-	std::vector<double> m_Ag;	   // speichert A * p
-	// Field of scaling factors
-	std::vector<double> m_scale;
-	std::vector<double> m_scale2;
-
-	// field for border voxels
-	std::vector<bool> m_border;
-
-
-	double m_r1rho1;   // speichert r1 * rho1
-	double m_r2rho2;   // speichert r2 * rho2
-	double m_normr0;
-	double m_q, m_e, m_sprod;
-
-	// minimal residuum
-	double m_min_res, m_relres;
-
-	/** function for initialising
-         */
-        void init();
-
-  public:
-	/** constructor
-	    \param w1
-	    \param f1
-	    \param g1
-	    \param l1
-	    \param l2
-	    \param r_res
-	    \param m_res
-	 */
-	C2DSolveCG (C2DFImage& w1, C2DFImage&  f1, C2DFImage& g1, double l1, double l2, double r_res, double m_res);
-
-	~C2DSolveCG();
-
-	/** Function to solve ...
-	    \param max_iterations Maximum number of iterations
-	    \param firstnormr0
-	    \returns
-	 */
-	int solve(long max_iterations, double *firstnormr0);
-
-	/** Function to get preset number of iterations
-	    \returns Number of iterations
-	 */
-	inline long get_iterations() {return m_iter;}
-
-	/** Multiplication of vector and matrix
-
-	TODO mit standard classe Austauschen
-
-	    \param x
-	    \param result
-	    \param start
-	    \param ende
-	 */
-	void multA(std::vector<double>& x, std::vector<double>& result, long start, long ende);
-
-	/** Multiplication
-
-	TODO mit standard classe Austauschen
-
-	    \param x Pointer at
-	    \param result Pointer at
-	 */
-	void multA_float(float *x, float *result);
-
-	/**
-	    \param gain Image with gain-field
-	 */
-	void get_solution(C2DFImage& gain);
-
-	/**
-	    \param e
-	 */
-	void add_to_solution(C2DFImage *e);
-
-	/** function for parallel solver
-	    @param max_iteration
-	    @param normr
-	    @param firstnormr0
-	 */
-	void solvepar(long *max_iteration, double *normr, double *firstnormr0);
-
-};
-
-NS_MIA_END
-
-#endif
diff --git a/mia/2d/fuzzyClusterSolverSOR.cc b/mia/2d/fuzzyClusterSolverSOR.cc
deleted file mode 100644
index ebc6b66..0000000
--- a/mia/2d/fuzzyClusterSolverSOR.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <mia/2d/fuzzyClusterSolverSOR.hh>
-#include <mia/core/msgstream.hh>
-
-
-NS_MIA_BEGIN
-C2DFuzzyClusterSolver::C2DFuzzyClusterSolver(const C2DFImage& weight, double lambda1, double lambda2, int max_iter):
-	m_weight(weight), 
-	m_lambda1(lambda1), 
-	m_lambda2(lambda2), 
-	m_max_iter(max_iter)
-{
-}
-
-void C2DFuzzyClusterSolver::solve(const C2DFImage& force, C2DFImage& gain)
-{
-	assert(force.get_size() == gain.get_size()); 
-	assert(m_weight.get_size() == gain.get_size()); 
-
-	const float lambda = 4 * m_lambda1 + 20 * m_lambda2; 
-	const float omega = 1.75; 
-	const float eps = 0.00001; 
-
-	auto size = m_weight.get_size(); 
-	const int dx = size.x; 
-	float n0 = 0.0; 
-	for (int i = 0; i < m_max_iter; ++i) {
-		float norm = 0.0; 
-		for(size_t y = 2; y < size.y - 2; ++y) {
-			auto igain = gain.begin_at(2, y); 
-			auto iforce = force.begin_at(2, y); 
-			auto iweight = m_weight.begin_at(2, y); 
-			
-			for(size_t x = 2; x < size.x - 2; ++x, ++igain, ++iforce, ++iweight) {
-				float d = *iweight + lambda; 
-				if ( fabs(d) < 1e-8) 
-					continue; 
-
-				float m1 = igain[-dx] + igain[-1] + igain[1] + igain[dx];  
-				float m2 = igain[-dx -1 ] + igain[-dx + 1]
-					+ igain[dx - 1] + igain[dx + 1];  
-				float m3 = igain[-2 * dx] + igain[-2] + igain[2] + igain[2 * dx];  
-
-				float h = m_lambda1 * m1 + 
-					m_lambda2 * (8 * m1 - 2 * m2 - m3); 
-				float r = omega * (d * *igain - h - *iforce) / d; 
-				norm += fabs(r); 
-				*igain -= r; 
-				
-			}
-		}
-		cvinfo() << "FuzzyComputeGain: [" << i << "] n=" << norm <<"\n"; 
-		if (i == 0) 
-			n0 = norm; 
-		else 
-			if (norm / n0 < eps || norm < 0.0001) 
-				break; 
-		
-	}
-}
-
-NS_MIA_END
diff --git a/mia/2d/fuzzyClusterSolverSOR.hh b/mia/2d/fuzzyClusterSolverSOR.hh
deleted file mode 100644
index 7271474..0000000
--- a/mia/2d/fuzzyClusterSolverSOR.hh
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef mia_2d_fuzzyclustersolver_sor_hh
-#define mia_2d_fuzzyclustersolver_sor_hh
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <mia/2d.hh>
-#include <cstdio>
-#include <stdexcept>
-#include <string>
-
-NS_MIA_BEGIN
-
-/**
-   \ingroup filtering
-   \brief A solver for the fuzzy segmentation smoothness constraint 
-   
-   This is a solver for the smoothness constraint of the fuzzy c-means algorithm 
-   described in: D.L. Pham and J.L.Prince, 
-   "An adaptive fuzzy C-means algorithm for image segmentation in the presence
-   of intensity inhomogeneities", Pat. Rec. Let., 20:57-68,1999
-*/
-class C2DFuzzyClusterSolver {
-public: 
-	/**
-	   Contructor 
-	   \param weight matrix 
-	   \param lambda1 Penalize magnitude of intensity inhomogeinity correction
-	   \param lambda2 Smoothness of intensity inhomogeinity correction
-	   \param max_iter maximum number of iterations 
-	*/
-	C2DFuzzyClusterSolver(const C2DFImage& weight, double lambda1, double lambda2, int max_iter); 
-
-	/**
-	   \param[in] force matrix to drive update of gain field 
-	   \param[in,out] gain filed to be updated 
-	*/
-	void solve(const C2DFImage& force, C2DFImage& gain); 
-private: 
-	
-	const C2DFImage& m_weight; 
-	double m_lambda1;
-	double m_lambda2; 
-	int m_max_iter; 
-}; 
-
-NS_MIA_END
-
-#endif
diff --git a/mia/2d/fuzzyclustersolver_cg.cc b/mia/2d/fuzzyclustersolver_cg.cc
new file mode 100644
index 0000000..5c97ab1
--- /dev/null
+++ b/mia/2d/fuzzyclustersolver_cg.cc
@@ -0,0 +1,332 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <cstring>
+
+#include <mia/core/msgstream.hh>
+#include <mia/2d/fuzzyclustersolver_cg.hh>
+
+
+NS_MIA_BEGIN
+// this needs to be tested
+bool fborder (long index, long nx, long ny)
+{
+	const long x = index % nx;
+
+	if ( x < 2 || x > nx-3 )
+	     return true;
+
+	index /= nx;
+
+	const long y = index % ny;
+	if ( y < 2 || y > ny-3 )
+	     return true;
+
+	return false;
+
+}
+
+
+
+C2DSolveCG::C2DSolveCG (C2DFImage& w1, C2DFImage& f1, C2DFImage& gain_image, double l1, double l2, double r_res, double m_res):
+	m_lambda1(l1),
+	m_lambda2(l2),
+	m_iter(0),
+	m_nx(w1.get_size().x),
+	m_ny(w1.get_size().y),
+	m_count(m_nx*m_ny),
+	m_weight_imagePtr(&w1(0, 0)),
+	m_fptr(&f1(0, 0)),
+	m_gain_image_ptr(&gain_image(0, 0)),
+
+	m_b(m_count),
+	m_v(m_count),
+	m_r(m_count),
+
+	m_rho(m_count),   // p^(k)
+	m_g(m_count),
+	m_Ag(m_count),   // speichert A * p
+
+	m_scale(m_count),
+	m_scale2(m_count),
+	m_border(m_count),
+
+	m_r1rho1(0.0), 
+	m_r2rho2(0.0),
+	m_normr0(0.0),
+	m_q(0.0), 
+	m_e(0.0),
+	m_sprod(0.0),
+
+	m_min_res(m_res),
+	m_relres(r_res)
+
+{
+	TRACE_FUNCTION; 
+	init ();
+
+}
+
+
+C2DSolveCG::~C2DSolveCG()
+{
+}
+
+
+
+// Umweg, da keine Methoden parallel aufgerufen werden koennen
+void solver(C2DSolveCG *s, long *maxit, double *normr, double *firstnormr0)
+{
+    s->solvepar(maxit, normr, firstnormr0);
+}
+
+
+int C2DSolveCG::solve(long max_iterations, double *firstnormr0) {
+
+        double normr;
+
+#ifdef PARALLEL
+    	m_set_procs(NPROCS);
+    	m_fork((void (*)())solver, this, &max_iterations, &normr,firstnormr0);
+    	m_kill_procs();
+#else
+    	solver(this, &max_iterations, &normr,firstnormr0);
+#endif
+
+	return normr > 1;
+}
+
+
+// loest das Gleichungssystem mittels CG-Algorithmus
+void C2DSolveCG::solvepar(long *maxit, double *normr, double *firstnormr0) 
+{
+	TRACE_FUNCTION; 
+    // Prozessornummer
+    int me;
+
+    // Start und Ende fuer Vektoroperationen
+    long start;
+    long ende;
+
+    // Setze me, start und ende
+    me = 0;
+    start = 0;
+    ende = m_count;
+
+    // Initialisierung
+    cvmsg() << "mult = " << start << ", " << ende << "\n"; 
+    multA(m_v, m_r, start, ende);
+
+    // Berechnung normr0;
+    double tmp_normr0 = 0;
+    for(long i = start; i < ende; i++) {
+      m_r[i] += m_b[i];
+      double square = m_r[i]/m_scale[i];
+      tmp_normr0 += square*square;
+    }
+
+    m_normr0 = tmp_normr0;
+
+    if (me == 0)
+	    *normr = m_normr0 = sqrt(m_normr0);
+
+
+    if (*firstnormr0 == 1.0 && m_normr0 > 1.0)
+	    *firstnormr0 = m_normr0;
+
+
+    // Iterationen
+    while (*normr >= m_min_res && m_iter < *maxit && *normr / *firstnormr0 > m_relres){
+
+    	if (me == 0) {
+	  		m_iter++;
+			copy(m_r.begin(), m_r.end(), m_rho.begin()); 
+	  		m_r2rho2 = m_r1rho1;
+        }
+
+
+	// r1rho1 = r * rho
+	if (me == 0) m_r1rho1 = 0;
+
+	double tmp_r1rho1 = 0;
+	for(long i = start; i < ende; i++) {
+	  tmp_r1rho1 += m_r[i] * m_rho[i];
+	}
+
+	m_r1rho1 = tmp_r1rho1;
+
+	if (m_iter >= 2 && me == 0) m_e = m_r1rho1 / m_r2rho2; else m_e = 0;
+
+	for(long i = start; i < ende; i++) m_g[i] = -m_rho[i] + m_e * m_g[i];
+
+	multA(m_g, m_Ag, start, ende);
+
+	// q = r1rho1 / (g * Ag)
+	if (me == 0) m_sprod = 0;
+	double tmp_sprod = 0;
+
+	for(long i = start; i < ende; i++) tmp_sprod += m_g[i] * m_Ag[i];
+
+	m_sprod = tmp_sprod;
+
+	if (me == 0) m_q = m_r1rho1 / m_sprod;
+
+	// v = v1 + q * g, r = r1 + q * Ag
+	if (me == 0) *normr = 0;
+	double tmp_normr = 0;
+
+	for(long i = start; i < ende; i++) {
+
+	  m_v[i] += m_q * m_g[i];
+	  m_r[i] += m_q * m_Ag[i];
+	  tmp_normr += pow(m_r[i]/m_scale[i], 2);
+
+	}
+
+	*normr = tmp_normr;
+
+	if (me == 0)
+		*normr = sqrt(*normr);
+
+	//*\todo implement some progression alert here */
+
+    }
+
+    return;
+ }
+
+
+// Vektor-Matrix-Multiplikation
+#define VALUE(o) (sc2[o] * x2[o])
+
+void C2DSolveCG::multA(vector<double>& x, vector<double>& result, long start, long ende) 
+{
+	assert(x.size() == result.size()); 
+	assert(x.size() == m_border.size()); 
+	assert(x.size() == m_scale2.size()); 
+	assert(x.size() == m_count); 
+
+	auto bord2 = m_border.begin(); 
+	auto res2 = result.begin(); 
+	auto x2 = x.begin(); 
+	auto sc2 = m_scale2.begin(); 
+	vector<double> help(x.size()); 
+	
+	transform(x.begin(), x.end(), m_scale2.begin(), help.begin(), 
+		  [](double x, double s) {return x * s; }); 
+
+	auto value = help.begin(); 
+	
+	for(int i = start; i < ende; i++, ++bord2, ++res2, ++x2, ++value, ++sc2) {
+		if (*bord2) {
+			*res2 = *x2;
+		}else {
+			
+			double s1= value[-m_nx      ] + value[-1] + value[+1] + value[+m_nx]; 
+			double s2= value[-m_nx   - 1] + value[-m_nx + 1]	+ value[+ m_nx -1]  + value[+m_nx + 1]; 
+			double s3= value[ - 2 * m_nx] + value[ - 2     ]  + value[+ 2]        + value[ + 2*m_nx];
+			
+			*res2 += ((s3 + 2*s2 - 8*s1) * m_lambda2 - m_lambda1 * s1) * *sc2;
+		}
+	}
+
+}
+
+
+#define VALUE2(o) ((bord2[o])?0:x2[o])
+
+void C2DSolveCG::multA_float(float *x, float *result) {
+
+	auto bord2 = m_border.begin(); 
+	float *x2, *res2;
+	
+	for(unsigned long i = 0; i < m_count; i++, ++bord2) {
+		
+		double s1, s2, s3;
+		
+		res2  = result + i;
+		x2    = x + i;
+		
+		if (*bord2) {
+			*res2 = (m_weight_imagePtr[i] + 4*m_lambda1 + 20*m_lambda2) * *x2;
+			continue;
+		}
+		
+		s1 = VALUE2(-m_nx)    + VALUE2(-1) + VALUE2(+1) + VALUE2(+m_nx);
+		
+		s2= VALUE2(-m_nx-1)     + VALUE2(-m_nx+1)	 + VALUE2(+m_nx-1)     + VALUE2(+m_nx+1);
+		
+		s3= VALUE2( - 2*m_nx) + VALUE2( - 2)	+ VALUE2( + 2) + VALUE2( + 2*m_nx);
+		
+		*res2 = (m_weight_imagePtr[i] + 4*m_lambda1+8*m_lambda2) * *x2  + ((s3 + 2*s2 - 12*s1) * m_lambda2 - m_lambda1 * s1);
+		
+	}
+}
+
+// loest die PDE  (w + m_lambda1 * H1 + m_lambda2 * H2)*m = f
+void C2DSolveCG::init()
+{
+	TRACE_FUNCTION; 
+	
+	// set b and scaling
+	for(unsigned long i = 0; i < m_count; i++) {
+		m_border[i] = (fborder(i, m_nx, m_ny)? 1 : 0);
+	}
+	
+	for(unsigned long i = 0; i < m_count; i++) {
+		// Wenn Element Randelement ist, setze b entsprechend
+		if (m_border[i]) {
+			m_b[i] = -m_gain_image_ptr[i];
+			m_scale[i] = 1.0;
+			m_scale2[i] = 0;
+			m_v[i] = m_gain_image_ptr[i] / m_scale[i];
+			continue;
+		}
+		
+		// set b[i]
+		m_b[i] = -m_fptr[i];
+		
+		// ziehe Anteile aus Randelementen ab
+		
+		// scaling
+		m_scale[i] = m_scale2[i] = 1.0 / sqrt(m_weight_imagePtr[i] + 4*m_lambda1 + 20*m_lambda2);
+		m_b[i] *= m_scale[i];
+		m_v[i] = m_gain_image_ptr[i] / m_scale[i];
+	}
+}
+
+
+void C2DSolveCG::get_solution(C2DFImage& m) {
+
+	C2DFImage::iterator m_gain_image_ptr = m.begin();
+	for(unsigned long i = 0; i < m_count; i++, ++m_gain_image_ptr)
+		*m_gain_image_ptr = (float)m_v[i] * m_scale[i];
+}
+
+
+void C2DSolveCG::add_to_solution(C2DFImage *e) {
+
+  C2DFImage::iterator eptr = e->begin();
+
+  for(unsigned long i = 0; i < m_count; i++)
+    m_v[i] += eptr[i] / m_scale[i];
+}
+
+NS_MIA_END
diff --git a/mia/2d/fuzzyclustersolver_cg.hh b/mia/2d/fuzzyclustersolver_cg.hh
new file mode 100644
index 0000000..0efaf31
--- /dev/null
+++ b/mia/2d/fuzzyclustersolver_cg.hh
@@ -0,0 +1,179 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __SOLVERCG_HH
+#define __SOLVERCG_HH
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <mia/2d.hh>
+#include <cstdio>
+#include <stdexcept>
+#include <string>
+
+
+
+NS_MIA_BEGIN
+
+using namespace std;
+
+
+
+/*! \brief function defining field borders
+
+    \param index  index running from 0 to NoOfPixels
+    \param nx     no of pixels in x
+    \param ny     no of pixels in y
+
+*/
+extern bool fborder (long index, long nx, long ny);
+
+/*! 
+  @ingroup filtering
+  \brief solve_sCG -- a class providing a CG solver
+
+	This contains basic solver functions based on CG schemes
+
+\author Stefan Burckhardt and Carsten Wolters, wolters at mis.mpg.de, 2004
+\remark adapted for libmona by Heike Jaenicke and Marc Tittgemeyer, tittge at cbs.mpg.de, 2004
+\remark adapted for mia2 by Gert Wollny, gw.fossdev at gmail.com 2011 
+*/
+
+
+class C2DSolveCG {
+
+  private:
+	double m_lambda1;
+	double m_lambda2;
+
+	// Dimension of images
+	long m_iter;
+	int  m_nx, m_ny;
+	unsigned long m_count;
+
+	// Pointer to Elements of w
+	float *m_weight_imagePtr;
+	float *m_fptr;
+	float *m_gain_image_ptr;
+
+
+
+	// b and x for solution of system
+	std::vector<double> m_b;
+	std::vector<double> m_v;
+
+	// counts iterations
+
+
+	// help pointers for one iteration cycle
+	std::vector<double> m_r;	   // r^(k)
+	std::vector<double> m_rho;     // p^(k)
+	std::vector<double> m_g;
+	std::vector<double> m_Ag;	   // speichert A * p
+	// Field of scaling factors
+	std::vector<double> m_scale;
+	std::vector<double> m_scale2;
+
+	// field for border voxels
+	std::vector<bool> m_border;
+
+
+	double m_r1rho1;   // speichert r1 * rho1
+	double m_r2rho2;   // speichert r2 * rho2
+	double m_normr0;
+	double m_q, m_e, m_sprod;
+
+	// minimal residuum
+	double m_min_res, m_relres;
+
+	/** function for initialising
+         */
+        void init();
+
+  public:
+	/** constructor
+	    \param w1
+	    \param f1
+	    \param g1
+	    \param l1
+	    \param l2
+	    \param r_res
+	    \param m_res
+	 */
+	C2DSolveCG (C2DFImage& w1, C2DFImage&  f1, C2DFImage& g1, double l1, double l2, double r_res, double m_res);
+
+	~C2DSolveCG();
+
+	/** Function to solve ...
+	    \param max_iterations Maximum number of iterations
+	    \param firstnormr0
+	    \returns
+	 */
+	int solve(long max_iterations, double *firstnormr0);
+
+	/** Function to get preset number of iterations
+	    \returns Number of iterations
+	 */
+	inline long get_iterations() {return m_iter;}
+
+	/** Multiplication of vector and matrix
+
+	TODO mit standard classe Austauschen
+
+	    \param x
+	    \param result
+	    \param start
+	    \param ende
+	 */
+	void multA(std::vector<double>& x, std::vector<double>& result, long start, long ende);
+
+	/** Multiplication
+
+	TODO mit standard classe Austauschen
+
+	    \param x Pointer at
+	    \param result Pointer at
+	 */
+	void multA_float(float *x, float *result);
+
+	/**
+	    \param gain Image with gain-field
+	 */
+	void get_solution(C2DFImage& gain);
+
+	/**
+	    \param e
+	 */
+	void add_to_solution(C2DFImage *e);
+
+	/** function for parallel solver
+	    @param max_iteration
+	    @param normr
+	    @param firstnormr0
+	 */
+	void solvepar(long *max_iteration, double *normr, double *firstnormr0);
+
+};
+
+NS_MIA_END
+
+#endif
diff --git a/mia/2d/fuzzyclustersolver_sor.cc b/mia/2d/fuzzyclustersolver_sor.cc
new file mode 100644
index 0000000..7a370fe
--- /dev/null
+++ b/mia/2d/fuzzyclustersolver_sor.cc
@@ -0,0 +1,86 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cmath> 
+#include <mia/2d/fuzzyclustersolver_sor.hh>
+#include <mia/core/msgstream.hh>
+
+
+NS_MIA_BEGIN
+C2DFuzzyClusterSolver::C2DFuzzyClusterSolver(const C2DFImage& weight, double lambda1, double lambda2, int max_iter):
+	m_weight(weight), 
+	m_lambda1(lambda1), 
+	m_lambda2(lambda2), 
+	m_max_iter(max_iter)
+{
+}
+
+void C2DFuzzyClusterSolver::solve(const C2DFImage& force, C2DFImage& gain)
+{
+	assert(force.get_size() == gain.get_size()); 
+	assert(m_weight.get_size() == gain.get_size()); 
+
+	const float lambda = 4 * m_lambda1 + 20 * m_lambda2; 
+	const float omega = 1.75; 
+	const float eps = 0.00001; 
+
+	auto size = m_weight.get_size(); 
+	const int dx = size.x; 
+	float n0 = 0.0; 
+	for (int i = 0; i < m_max_iter; ++i) {
+		float norm = 0.0; 
+		for(size_t y = 2; y < size.y - 2; ++y) {
+			auto igain = gain.begin_at(2, y); 
+			auto iforce = force.begin_at(2, y); 
+			auto iweight = m_weight.begin_at(2, y); 
+			
+			for(size_t x = 2; x < size.x - 2; ++x, ++igain, ++iforce, ++iweight) {
+				float d = *iweight + lambda; 
+				if ( fabsf(d) < 1e-8) 
+					continue; 
+
+				float m1 = igain[-dx] + igain[-1] + igain[1] + igain[dx];  
+				float m2 = igain[-dx -1 ] + igain[-dx + 1]
+					+ igain[dx - 1] + igain[dx + 1];  
+				float m3 = igain[-2 * dx] + igain[-2] + igain[2] + igain[2 * dx];  
+
+				float h = m_lambda1 * m1 + 
+					m_lambda2 * (8 * m1 - 2 * m2 - m3); 
+				float r = omega * (d * *igain - h - *iforce) / d; 
+				norm += fabsf(r); 
+				*igain -= r; 
+				
+			}
+		}
+		cvinfo() << "FuzzyComputeGain: [" << i << "] n=" << norm <<"\n"; 
+		if (i == 0) 
+			n0 = norm; 
+		else 
+			if (norm / n0 < eps || norm < 0.0001) 
+				break; 
+		
+	}
+}
+
+NS_MIA_END
diff --git a/mia/2d/fuzzyclustersolver_sor.hh b/mia/2d/fuzzyclustersolver_sor.hh
new file mode 100644
index 0000000..12d4653
--- /dev/null
+++ b/mia/2d/fuzzyclustersolver_sor.hh
@@ -0,0 +1,70 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_2d_fuzzyclustersolver_sor_hh
+#define mia_2d_fuzzyclustersolver_sor_hh
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <mia/2d.hh>
+#include <cstdio>
+#include <stdexcept>
+#include <string>
+
+NS_MIA_BEGIN
+
+/**
+   \ingroup filtering
+   \brief A solver for the fuzzy segmentation smoothness constraint 
+   
+   This is a solver for the smoothness constraint of the fuzzy c-means algorithm 
+   described in: D.L. Pham and J.L.Prince, 
+   "An adaptive fuzzy C-means algorithm for image segmentation in the presence
+   of intensity inhomogeneities", Pat. Rec. Let., 20:57-68,1999
+*/
+class C2DFuzzyClusterSolver {
+public: 
+	/**
+	   Contructor 
+	   \param weight matrix 
+	   \param lambda1 Penalize magnitude of intensity inhomogeinity correction
+	   \param lambda2 Smoothness of intensity inhomogeinity correction
+	   \param max_iter maximum number of iterations 
+	*/
+	C2DFuzzyClusterSolver(const C2DFImage& weight, double lambda1, double lambda2, int max_iter); 
+
+	/**
+	   \param[in] force matrix to drive update of gain field 
+	   \param[in,out] gain filed to be updated 
+	*/
+	void solve(const C2DFImage& force, C2DFImage& gain); 
+private: 
+	
+	const C2DFImage& m_weight; 
+	double m_lambda1;
+	double m_lambda2; 
+	int m_max_iter; 
+}; 
+
+NS_MIA_END
+
+#endif
diff --git a/mia/2d/fuzzyseg.cc b/mia/2d/fuzzyseg.cc
index f3f7c63..49ffe0c 100644
--- a/mia/2d/fuzzyseg.cc
+++ b/mia/2d/fuzzyseg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,8 +31,8 @@
 
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/histogram.hh>
-#include <mia/2d/fuzzyClusterSolverCG.hh>
-#include <mia/2d/fuzzyClusterSolverSOR.hh>
+#include <mia/2d/fuzzyclustersolver_cg.hh>
+#include <mia/2d/fuzzyclustersolver_sor.hh>
 #include <mia/2d/fuzzyseg.hh>
 
 NS_MIA_BEGIN
@@ -176,22 +176,15 @@ vector<double> Isodata2d (const Data2D& src_image, unsigned int nClasses, unsign
 
 
 // solves the PDE  (W + lambda1 * H1 + lambda2 * H2) = f
-void solvePDE (C2DFImage& weight_image, C2DFImage& force_image, C2DFImage& gain_image, const SFuzzySegParams& params, double *firstnormr0, double min_res)
+void solvePDE (C2DFImage& weight_image, C2DFImage& force_image, C2DFImage& gain_image, const SFuzzySegParams& params)
 {
-#if 0 
-
-	C2DSolveCG solver(weight_image, force_image, gain_image, lambda1, lambda2, relres, min_res);
-	solver.solve ( _MAX_ITER_PDE, firstnormr0);
-	solver.get_solution (gain_image);
-#else 
 	C2DFuzzyClusterSolver solver(weight_image,params.lambda1, params.lambda2, 1000);
 	solver.solve (force_image, gain_image);
-#endif 
 }
 
 template <class Data2D>
 int estimateGain (C2DFImage& gain_image, const Data2D& src_image, vector<C2DFImage*>& cls_image,
-		  vector<double> &clCenter, unsigned int classes, double * firstnormr0, const SFuzzySegParams& params)
+		  vector<double> &clCenter, unsigned int classes, const SFuzzySegParams& params)
 {
 
 	const unsigned int nx = src_image.get_size().x;
@@ -216,31 +209,13 @@ int estimateGain (C2DFImage& gain_image, const Data2D& src_image, vector<C2DFIma
 			};
 			
 			forcePixel *= src_image(x, y);
-#if 0 			
-			// korrigiere randbedingungen
-			long i = y*nx + x;
-			if (!border[i-nx])    forcePixel += _LAMBDA1 + 8 * _LAMBDA2;
-			if (!border[i-1])     forcePixel += _LAMBDA1 + 8 * _LAMBDA2;
-			if (!border[i+1])     forcePixel += _LAMBDA1 + 8 * _LAMBDA2;
-			if (!border[i+nx])    forcePixel += _LAMBDA1 + 8 * _LAMBDA2;
-		
-			if (!border[i-nx-1])       forcePixel -= 2 * _LAMBDA2;
-			if (!border[i-nx+1])       forcePixel -= 2 * _LAMBDA2;
-			if (!border[i+nx-1])       forcePixel -= 2 * _LAMBDA2;
-			if (!border[i+nx+1])       forcePixel -= 2 * _LAMBDA2;
-			
-			if (!border[i - 2*nx])    forcePixel -= _LAMBDA2;
-			if (!border[i - 2])       forcePixel -= _LAMBDA2;
-			if (!border[i + 2])       forcePixel -= _LAMBDA2;
-			if (!border[i + 2*nx])    forcePixel -= _LAMBDA2;
-#endif 			
 			force_image(x, y) = (float)(forcePixel);
 			weight_image(x, y) = (float)(weightPixel);
 		};
 	};
 	// C.Wolters:
 	// now solve system using scaled CG
-	solvePDE(weight_image, force_image, gain_image, params, firstnormr0,1);
+	solvePDE(weight_image, force_image, gain_image, params);
 
 	return t;
 
@@ -288,7 +263,6 @@ CSegment2d::result_type CSegment2d::operator () (const T2DImage<T>& data)
 	// Field to store the border
 	vector<char> border(noOfPixels);
 
-	double firstnormr0 = 1.0;
 	double nom, den, dist;
 
 	// get type of iterator
@@ -365,10 +339,7 @@ CSegment2d::result_type CSegment2d::operator () (const T2DImage<T>& data)
 		// Algorithm step 2:
 		// estimate gain field
 
-		estimateGain (gain_image, data, cls_image, clCenter, m_nClasses,
-			      &firstnormr0, m_params);
-		if (firstnormr0 < 1000)
-			firstnormr0 = 1.0;
+		estimateGain (gain_image, data, cls_image, clCenter, m_nClasses, m_params);
 
 		// Algorithm step 3:
 		// recompute class memberships
diff --git a/mia/2d/fuzzyseg.hh b/mia/2d/fuzzyseg.hh
index 1565a6b..22b2ba7 100644
--- a/mia/2d/fuzzyseg.hh
+++ b/mia/2d/fuzzyseg.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/ground_truth_evaluator.cc b/mia/2d/ground_truth_evaluator.cc
index 4290af7..3cb0247 100644
--- a/mia/2d/ground_truth_evaluator.cc
+++ b/mia/2d/ground_truth_evaluator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/ground_truth_evaluator.hh b/mia/2d/ground_truth_evaluator.hh
index f3999e5..fe2ef06 100644
--- a/mia/2d/ground_truth_evaluator.hh
+++ b/mia/2d/ground_truth_evaluator.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/groundtruthproblem.cc b/mia/2d/groundtruthproblem.cc
index 2bf8261..4907ebf 100644
--- a/mia/2d/groundtruthproblem.cc
+++ b/mia/2d/groundtruthproblem.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/groundtruthproblem.hh b/mia/2d/groundtruthproblem.hh
index 7483e55..7934e0b 100644
--- a/mia/2d/groundtruthproblem.hh
+++ b/mia/2d/groundtruthproblem.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/ica.cc b/mia/2d/ica.cc
index 12a2117..b0c9c04 100644
--- a/mia/2d/ica.cc
+++ b/mia/2d/ica.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/ica.hh b/mia/2d/ica.hh
index c157aa8..8e2de4e 100644
--- a/mia/2d/ica.hh
+++ b/mia/2d/ica.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/image.cc b/mia/2d/image.cc
index 0e27b15..2d3eb47 100644
--- a/mia/2d/image.cc
+++ b/mia/2d/image.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,6 +56,8 @@ const C2DBounds& C2DImage::get_size() const
 	return m_size;
 }
 
+
+
 C2DFVector C2DImage::get_pixel_size() const
 {
         const PAttribute attr = get_attribute("pixel");
diff --git a/mia/2d/image.hh b/mia/2d/image.hh
index abd6f4f..cb626f3 100644
--- a/mia/2d/image.hh
+++ b/mia/2d/image.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,6 +34,7 @@ NS_MIA_BEGIN
 
 #define ATTR_IMAGE_KMEANS_CLASSES "kmeans"
 
+
 /**
    \ingroup basic
    \brief This is the base class for 2D images that can hold generic pixel data
@@ -131,6 +132,10 @@ public:
 	typedef typename T2DDatafield<T>::size_type size_type;
 	typedef typename T2DDatafield<T>::range_iterator range_iterator; 
 	typedef typename T2DDatafield<T>::const_range_iterator const_range_iterator; 
+	typedef typename T2DDatafield<T>::range_iterator_with_boundary_flag range_iterator_with_boundary_flag; 
+	typedef typename T2DDatafield<T>::const_range_iterator_with_boundary_flag const_range_iterator_with_boundary_flag; 
+
+	typedef	typename T2DDatafield<T>::data_array data_array;
 
 	/// \endcond
 
@@ -146,7 +151,7 @@ public:
 	   \param size 
 	   \param init_data must at least be of size (size.x*size.y)
 	*/
-	T2DImage(const C2DBounds& size, const typename T2DDatafield<T>::data_array& init_data);
+	T2DImage(const C2DBounds& size, const data_array& init_data);
 	/**
 	   Create a 2D image with thegiven size and attach the given meta-data list. 
 	   \param size image size 
diff --git a/mia/2d/imageio.cc b/mia/2d/imageio.cc
index 76a70d6..a3ef66f 100644
--- a/mia/2d/imageio.cc
+++ b/mia/2d/imageio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
 #include <mia/core/iohandler.cxx>
 #include <mia/core/errormacro.hh>
 #include <mia/core/tools.hh>
+#include <mia/core/attribute_names.hh>
 
 NS_MIA_BEGIN
 
@@ -182,26 +183,6 @@ C2DImageGroupedSeries  EXPORT_2D load_image_series(const std::vector<std::string
 	return result; 
 }
 
-C2DImageIOPluginHandlerTestPath::C2DImageIOPluginHandlerTestPath()
-{
-	CPathNameArray searchpath({bfs::path(".")});
-	C2DImageIOPluginHandler::set_search_path(searchpath);
-}
-
-EXPORT_2D const char * IDAcquisitionDate =   "AcquisitionDate";
-EXPORT_2D const char * IDImageType =         "ImageType";
-EXPORT_2D const char * IDAcquisitionNumber = "AcquisitionNumber";
-EXPORT_2D const char * IDInstanceNumber =    "InstanceNumber";
-EXPORT_2D const char * IDSliceLocation = "SliceLocation";
-EXPORT_2D const char * IDSeriesNumber = "SeriesNumber";
-EXPORT_2D const char * IDModality =          "Modality";
-EXPORT_2D const char * IDPatientOrientation ="PatientOrientation";
-EXPORT_2D const char * IDPatientPosition = "PatientPosition";
-EXPORT_2D const char * IDSmallestImagePixelValue = "SmallestImagePixelValue";
-EXPORT_2D const char * IDLargestImagePixelValue = "LargestImagePixelValue";
-EXPORT_2D const char * IDStudyID = "StudyID";
-EXPORT_2D const char * IDProtocolName = "ProtocolName"; 
-
 template class TIOPlugin<io_2dimage_type>;
 template class THandlerSingleton<C2DImageIOPPH>;
 template class TIOPluginHandler<C2DImageIOPlugin>;
diff --git a/mia/2d/imageio.hh b/mia/2d/imageio.hh
index 494c776..df1afd4 100644
--- a/mia/2d/imageio.hh
+++ b/mia/2d/imageio.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -80,6 +80,12 @@ protected:
  */
 typedef THandlerSingleton< C2DImageIOPPH > C2DImageIOPluginHandler;
 
+template <> 
+struct IOHandler_of<C2DImage> {
+	typedef C2DImageIOPluginHandler type;
+}; 
+
+
 /** The type for virtual storage access for images 
     \sa CDatapool
  */
@@ -90,16 +96,6 @@ typedef C2DImageIOPluginHandler::Instance::DataKey C2DImageDataKey;
  */
 typedef C2DImageIOPluginHandler::Instance::PData P2DImageVector;
 
-/** 
-    @cond INTERNAL  
-    \ingroup test 
-    \brief Class to initialiaze the plug-in search path fot testing without installing the plug-ins 
-*/
-struct EXPORT_2D C2DImageIOPluginHandlerTestPath {
-	C2DImageIOPluginHandlerTestPath(); 
-}; 
-/// @endcond 
-
 /**
    \ingroup convenience 
    Convenience function to create a vector of images wrapping one image
@@ -168,25 +164,6 @@ C2DImageGroupedSeries EXPORT_2D load_image_series(const std::vector<std::string>
 						  CProgressCallback *cb = NULL); 
 
 
-/**
-   some DICOM tags that may be used 
-   \cond DICOM_TAGS 
- */
-extern EXPORT_2D const char * IDModality;
-extern EXPORT_2D const char * IDPatientOrientation;
-extern EXPORT_2D const char * IDPatientPosition;
-extern EXPORT_2D const char * IDAcquisitionDate;
-extern EXPORT_2D const char * IDAcquisitionNumber;
-extern EXPORT_2D const char * IDImageType;
-extern EXPORT_2D const char * IDInstanceNumber;
-
-extern EXPORT_2D const char * IDSeriesNumber;
-extern EXPORT_2D const char * IDSliceLocation;
-extern EXPORT_2D const char * IDStudyID;
-extern EXPORT_2D const char * IDSmallestImagePixelValue;
-extern EXPORT_2D const char * IDLargestImagePixelValue;
-extern EXPORT_2D const char * IDProtocolName; 
-/// @endcond 
 
 NS_MIA_END
 
diff --git a/mia/2d/imageiotest.cc b/mia/2d/imageiotest.cc
index bf4d611..ffb1f4e 100644
--- a/mia/2d/imageiotest.cc
+++ b/mia/2d/imageiotest.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/imageiotest.hh b/mia/2d/imageiotest.hh
index b0096fa..7ff2b5b 100644
--- a/mia/2d/imageiotest.hh
+++ b/mia/2d/imageiotest.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/imagetest.cc b/mia/2d/imagetest.cc
index bc18c14..884291f 100644
--- a/mia/2d/imagetest.cc
+++ b/mia/2d/imagetest.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/imagetest.hh b/mia/2d/imagetest.hh
index 1ceca73..b98ad1c 100644
--- a/mia/2d/imagetest.hh
+++ b/mia/2d/imagetest.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/inittesthandlers.cc b/mia/2d/inittesthandlers.cc
deleted file mode 100644
index 3b8a499..0000000
--- a/mia/2d/inittesthandlers.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <config.h> 
-
-#include <mia/2d/inittesthandlers.hh>
-
-
-NS_MIA_BEGIN
-namespace bfs = ::boost::filesystem;
-
-C2DVFIOPluginHandlerTestPath::C2DVFIOPluginHandlerTestPath()
-{
-	CPathNameArray kernelsearchpath({bfs::path(MIA_BUILD_ROOT"/mia/2d/io")});
-	C2DVFIOPluginHandler::set_search_path(kernelsearchpath);
-
-}
-
-C2DTransformCreatorHandlerTestPath::C2DTransformCreatorHandlerTestPath()
-{
-	CPathNameArray kernelsearchpath({bfs::path(MIA_BUILD_ROOT"/mia/2d/transform")});
-	C2DTransformCreatorHandler::set_search_path(kernelsearchpath);
-}
-
-C2DTransformationIOPluginHandlerTestPath::C2DTransformationIOPluginHandlerTestPath()
-{
-	CPathNameArray kernelsearchpath({bfs::path(MIA_BUILD_ROOT"/mia/2d/transio")});
-	C2DTransformationIOPluginHandler::set_search_path(kernelsearchpath);
-}
-
-
-
-NS_MIA_END
diff --git a/mia/2d/inittesthandlers.hh b/mia/2d/inittesthandlers.hh
deleted file mode 100644
index d3a0644..0000000
--- a/mia/2d/inittesthandlers.hh
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <mia/2d/vfio.hh>
-#include <mia/2d/transformio.hh>
-#include <mia/2d/transformfactory.hh>
-
-NS_MIA_BEGIN
-
-class C2DVFIOPluginHandlerTestPath {
-public: 
-	C2DVFIOPluginHandlerTestPath(); 
-}; 
-
-/** 
-    @cond INTERNAL  
-    \ingroup test 
-    \brief Class to initialiaze the plug-in search path fot testing without installing the plug-ins 
-*/
-struct EXPORT_2D C2DTransformCreatorHandlerTestPath {
-	C2DTransformCreatorHandlerTestPath(); 
-private: 
-	CSplineKernelTestPath spktp; 
-}; 
-
-
-class C2DTransformationIOPluginHandlerTestPath {
-public: 
-        C2DTransformationIOPluginHandlerTestPath(); 
-private: 
-        C2DTransformCreatorHandlerTestPath tch; 
-}; 
-
-
-/// @endcond 
-NS_MIA_END
-
diff --git a/mia/2d/interpolator.cc b/mia/2d/interpolator.cc
index 2bc81da..2a4f681 100644
--- a/mia/2d/interpolator.cc
+++ b/mia/2d/interpolator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -252,8 +252,8 @@ double add_2d_new<T2DDatafield< double >, 4>::value(const T2DDatafield< double >
 #endif
 
 #define INSTANCIATE_INTERPOLATORS(TYPE)			\
-	template class T2DInterpolator<TYPE>;		\
-	template class T2DConvoluteInterpolator<TYPE>
+	template class EXPORT_2D T2DInterpolator<TYPE>;		\
+	template class EXPORT_2D T2DConvoluteInterpolator<TYPE>
 
 INSTANCIATE_INTERPOLATORS(bool);
 INSTANCIATE_INTERPOLATORS(unsigned char);
@@ -272,8 +272,8 @@ INSTANCIATE_INTERPOLATORS(unsigned long);
 
 INSTANCIATE_INTERPOLATORS(C2DFVector);
 
-template class T1DInterpolator<C2DFVector>;
-template class T1DConvoluteInterpolator<C2DFVector>;
+template class EXPORT_2D T1DInterpolator<C2DFVector>;
+template class EXPORT_2D T1DConvoluteInterpolator<C2DFVector>;
 
 
 
diff --git a/mia/2d/interpolator.cxx b/mia/2d/interpolator.cxx
index 37dcfd1..8f51855 100644
--- a/mia/2d/interpolator.cxx
+++ b/mia/2d/interpolator.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -108,6 +108,10 @@ void T2DConvoluteInterpolator<T>::prefilter(const T2DDatafield<T>& image)
 
 
 	min_max<typename T2DDatafield<T>::const_iterator >::get(image.begin(), image.end(), m_min, m_max);
+	// always allow a zero value 
+	if (T() < m_min) 
+		m_min = T(); 
+
 	
 	// copy the data
 	__dispatch_copy<T2DDatafield<T>, TCoeff2D >::apply(image, m_coeff); 
diff --git a/mia/2d/interpolator.hh b/mia/2d/interpolator.hh
index 0d28de6..0eabec7 100644
--- a/mia/2d/interpolator.hh
+++ b/mia/2d/interpolator.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/io/CMakeLists.txt b/mia/2d/io/CMakeLists.txt
index b7d3822..b3a382e 100644
--- a/mia/2d/io/CMakeLists.txt
+++ b/mia/2d/io/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -27,6 +27,13 @@ PLUGIN_WITH_PREFIX2("2dimage" "io" bmp "${MIA2DLIBS}")
 PLUGIN_WITH_PREFIX2("2dimage" "io" raw "${MIA2DLIBS}")
 
 
+SET(segset2dio
+  xml)
+
+PLUGINGROUP_WITH_TEST_AND_PREFIX2("2dmyocardsegset" "io" "${segset2dio}" mia2dmyocardperf TESTLIBS  mia2dtest)
+
+
+
 
 
 
diff --git a/mia/2d/io/bmp.cc b/mia/2d/io/bmp.cc
index 6d9708a..7a3e011 100644
--- a/mia/2d/io/bmp.cc
+++ b/mia/2d/io/bmp.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -384,7 +384,7 @@ CBMP2DImageIO::PData CBMP2DImageIO::do_load(string const& filename)const
 	// the tainted variables. 
 	size_t h = info_header.height; 
 	size_t w = info_header.width; 
-	if (h > numeric_limits<int>::max() || w > numeric_limits<int>::max()) 
+	if (h > numeric_limits<size_t>::max() || w > numeric_limits<size_t>::max()) 
 		throw create_exception<runtime_error>("CBMP2DImageIO::load: Image has too big", 
 						      " width=", info_header.width, ", height=", 
 						      info_header.height);
diff --git a/mia/2d/io/raw.cc b/mia/2d/io/raw.cc
index eb6a408..00641e8 100644
--- a/mia/2d/io/raw.cc
+++ b/mia/2d/io/raw.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/io/test_xml.cc b/mia/2d/io/test_xml.cc
new file mode 100644
index 0000000..08e99c0
--- /dev/null
+++ b/mia/2d/io/test_xml.cc
@@ -0,0 +1,193 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+#include <mia/2d/io/xml.hh>
+#include <mia/2d/imageio.hh>
+
+#include <mia/internal/autotest.hh>
+
+NS_BEGIN(myosegset2d)
+
+using namespace myosegset2d; 
+using namespace mia; 
+using namespace std; 
+
+
+const char *testset_init = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<workset>"
+	"<description><RVpeak value=\"2\"/>"
+	"<LVpeak value=\"1\"/><PreferedRef value=\"0\"/></description>"
+	" <frame image=\"image.png\">"
+	"  <star y=\"118\" x=\"109\" r=\"21\">"
+	"   <point y=\"20\" x=\"10\"/>"
+	"   <point y=\"10\" x=\"20\"/>"
+	"   <point y=\"4\" x=\"0\"/>"
+	"  </star>"
+	" </frame>"
+	" <frame image=\"image2.png\">"
+	"  <star y=\"117\" x=\"119\" r=\"22\">"
+	"  <point y=\"21\" x=\"11\"/>"
+	"  <point y=\"11\" x=\"21\"/>"
+	"  <point y=\"5\" x=\"1\"/>"
+	"  </star>"
+	" </frame>"
+	"</workset>\n";
+
+
+BOOST_AUTO_TEST_CASE( test_read_simple ) 
+{
+	C2DUBImage img1(C2DBounds(2,3)); 
+	C2DUBImage img2(C2DBounds(2,3)); 
+
+	fill(img1.begin(), img1.end(), 0); 
+	fill(img2.begin(), img2.end(), 1);
+
+	save_image("image.png", img1); 
+	save_image("image2.png", img2);
+
+	ofstream testfile("segset.set"); 
+	testfile << testset_init; 
+	testfile.close(); 
+	
+	CXMLSegSetWithImagesIOPlugin io; 
+
+	// create a pipe to write the data to and read from it, 
+	auto inset = io.load("segset.set"); 
+	
+	BOOST_REQUIRE(inset);
+	BOOST_CHECK_EQUAL(inset->get_RV_peak(), 2); 
+	BOOST_CHECK_EQUAL(inset->get_LV_peak(), 1); 
+	BOOST_CHECK_EQUAL(inset->get_preferred_reference(), 0);
+
+
+	auto frames = inset->get_frames(); 
+	BOOST_CHECK_EQUAL(frames.size(), 2u);
+
+
+	unlink("segset.set"); 
+	unlink("image.png"); 
+	unlink("image2.png");
+	
+}
+
+
+void check_segpoint_close(const CSegPoint2D& h, const CSegPoint2D& e) 
+{
+	BOOST_CHECK_CLOSE(h.x, e.x, 0.01); 
+	BOOST_CHECK_CLOSE(h.y, e.y, 0.01);
+
+}
+
+void check_segstar_close(const CSegStar& have, const CSegStar& expect)
+{
+	check_segpoint_close(have.m_center, expect.m_center); 
+	for (int i = 0; i < 3; ++i) 
+		check_segpoint_close(have.m_directions[i], expect.m_directions[i]); 
+	
+	BOOST_CHECK_CLOSE(have.m_radius, expect.m_radius, 0.01); 
+}
+
+void check_section_close(const CSegSection& have, const CSegSection& expect)
+{
+	BOOST_CHECK_EQUAL(have.get_id(), expect.get_id()); 
+
+	auto hp = have.get_points(); 
+	auto ep = expect.get_points(); 
+	
+	BOOST_CHECK_EQUAL(hp.size(), ep.size());
+	BOOST_REQUIRE(hp.size() ==ep.size());
+
+	for (unsigned i = 0; i < hp.size(); ++i) {
+		check_segpoint_close(hp[i], ep[i]); 
+	}
+
+	BOOST_CHECK_EQUAL(have.is_open(), expect.is_open());
+	
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_write_simple ) 
+{
+	CSegSetWithImages set; 
+
+	set.set_RV_peak(2); 
+	set.set_LV_peak(1); 
+	set.set_preferred_reference(0);
+	
+	CSegStar in_star0(CSegPoint2D(1,2), 3, 
+			 CSegPoint2D(2,1), CSegPoint2D(0,1), CSegPoint2D(1,1)); 
+	
+	CSegFrame::Sections in_sections0; 
+	
+	CSegSection::Points s11p =  {{3,4},{5,6},{1,2}}; 
+	CSegSection s11("s11", s11p, true);
+	CSegSection s12("s12", s11p, false);
+	in_sections0.push_back(s11); 
+	in_sections0.push_back(s12); 
+	
+	CSegFrame in_frame0("image1.png", in_star0, in_sections0);
+	in_frame0.set_quality(3.3); 
+	in_frame0.set_brightness(1.0); 
+	in_frame0.set_contrast(-1.0);
+	
+
+	P2DImage img1(new C2DUBImage(C2DBounds(2,3))); 
+	set.add_frame(in_frame0, img1); 
+	
+	
+	CXMLSegSetWithImagesIOPlugin io; 
+
+	io.save("testsaveset.set", set); 
+	
+
+	auto inset = io.load("testsaveset.set"); 
+
+	BOOST_CHECK_EQUAL(inset->get_RV_peak(), 2); 
+	BOOST_CHECK_EQUAL(inset->get_LV_peak(), 1); 
+	BOOST_CHECK_EQUAL(inset->get_preferred_reference(), 0);
+	
+	auto inframes = inset->get_frames(); 
+	BOOST_CHECK_EQUAL(inframes.size(), 1u); 
+	
+	auto f0 = inframes[0]; 
+
+
+	BOOST_CHECK_CLOSE(f0.get_quality(), in_frame0.get_quality(), 0.01); 
+	BOOST_CHECK_CLOSE(f0.get_brightness(), in_frame0.get_brightness(), 0.01); 
+	BOOST_CHECK_CLOSE(f0.get_contrast(), in_frame0.get_contrast(), 0.01); 
+	
+	auto star0 = f0.get_star(); 
+	
+	check_segstar_close(star0, in_star0); 
+	
+	auto sections0 = f0.get_sections(); 
+	BOOST_CHECK_EQUAL(sections0.size(), 2u);
+	
+	for(int i = 0; i < 2; ++i) {
+		check_section_close(sections0[i], in_sections0[i]); 
+	}
+
+	unlink("testsaveset.set"); 
+	unlink("image1.png"); 
+			
+}
+
+NS_END
diff --git a/mia/2d/io/xml.cc b/mia/2d/io/xml.cc
new file mode 100644
index 0000000..e7b9e3f
--- /dev/null
+++ b/mia/2d/io/xml.cc
@@ -0,0 +1,97 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+
+#include <boost/filesystem.hpp>
+#include <libxml++/libxml++.h>
+#include <mia/core/tools.hh>
+#include <mia/2d/io/xml.hh>
+
+NS_BEGIN(myosegset2d)
+
+using namespace mia; 
+using std::string; 
+using std::ofstream; 
+using std::unique_ptr; 
+namespace bfs=boost::filesystem;
+
+CXMLSegSetWithImagesIOPlugin::CXMLSegSetWithImagesIOPlugin():
+	CSegSetWithImagesIOPlugin("xml") 
+{
+	add_suffix(".set");
+	add_suffix(".SET");
+}
+
+
+PSegSetWithImages CXMLSegSetWithImagesIOPlugin::do_load(const string& fname) const
+{
+	xmlpp::DomParser parser;
+	parser.set_substitute_entities(); //We just want the text to be resolved/unescaped automatically.
+	parser.parse_file(fname);
+
+	if (!parser){
+		cvdebug() << "CXMLSegSetWithImagesIOPlugin:'" << fname << "' is not a XML document\n"; 
+		return PSegSetWithImages(); 
+	}
+	
+	const auto *document = parser.get_document(); 
+	const auto *root = document->get_root_node ();
+	if (root->get_name() != "workset") {
+		cvdebug() << "CXMLSegSetWithImagesIOPlugin:'" << fname 
+			  << "' XML file is not a segmentation set\n"; 
+		return PSegSetWithImages();
+	}
+
+	bfs::path src_path_(fname);
+	src_path_.remove_filename();
+	auto src_path = src_path_.string();
+
+	return  PSegSetWithImages(new CSegSetWithImages(*document, src_path)); 
+}
+
+bool CXMLSegSetWithImagesIOPlugin::do_save(const string& fname, const CSegSetWithImages& data) const
+{
+	unique_ptr<xmlpp::Document> outset(data.write());
+	ofstream outfile(fname.c_str() );
+	if (outfile.good()) {
+		outfile << outset->write_to_string_formatted();
+		data.save_images(fname); 
+	}
+	return outfile.good();
+}
+
+const string CXMLSegSetWithImagesIOPlugin::do_get_descr() const
+{
+	return "Load and store segmentation sets as xml file and separate image files."; 
+}
+
+
+const string CXMLSegSetWithImagesIOPlugin::do_get_preferred_suffix() const
+{
+	return "set"; 
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new CXMLSegSetWithImagesIOPlugin();
+}
+
+NS_END
diff --git a/mia/2d/io/xml.hh b/mia/2d/io/xml.hh
new file mode 100644
index 0000000..f55c3b8
--- /dev/null
+++ b/mia/2d/io/xml.hh
@@ -0,0 +1,36 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/segsetwithimages.hh>
+
+
+NS_BEGIN(myosegset2d)
+
+class CXMLSegSetWithImagesIOPlugin: public mia::CSegSetWithImagesIOPlugin {
+public: 
+	CXMLSegSetWithImagesIOPlugin(); 
+private:
+	mia::PSegSetWithImages do_load(const std::string& fname) const;
+	bool do_save(const std::string& fname, const mia::CSegSetWithImages& data) const;
+	const std::string do_get_descr() const;
+	const std::string do_get_preferred_suffix() const; 
+}; 
+
+NS_END //myosegset2d
diff --git a/mia/2d/iterator.cxx b/mia/2d/iterator.cxx
index 20681a2..7e4dafe 100644
--- a/mia/2d/iterator.cxx
+++ b/mia/2d/iterator.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
 NS_MIA_BEGIN
 
 template <typename I> 
-range2d_iterator<I>::range2d_iterator():
+range2d_iterator_with_boundary_flag<I>::range2d_iterator_with_boundary_flag():
 	m_pos(0,0), 
 	m_size(0,0), 
 	m_begin(0,0), 
@@ -36,7 +36,7 @@ range2d_iterator<I>::range2d_iterator():
 }
 
 template <typename I> 
-range2d_iterator<I>::range2d_iterator(const C2DBounds& pos):
+range2d_iterator_with_boundary_flag<I>::range2d_iterator_with_boundary_flag(const C2DBounds& pos):
 	m_pos(pos), 
 	m_size(0,0), 
 	m_begin(0,0), 
@@ -47,7 +47,7 @@ range2d_iterator<I>::range2d_iterator(const C2DBounds& pos):
 }
 
 template <typename I> 
-range2d_iterator<I>::range2d_iterator(const C2DBounds& pos, const C2DBounds& size, 
+range2d_iterator_with_boundary_flag<I>::range2d_iterator_with_boundary_flag(const C2DBounds& pos, const C2DBounds& size, 
 				      const C2DBounds& begin, const C2DBounds& end, I iterator):
 	m_pos(pos), 
 	m_size(size), 
@@ -74,7 +74,7 @@ range2d_iterator<I>::range2d_iterator(const C2DBounds& pos, const C2DBounds& siz
 
 
 template <typename I> 
-range2d_iterator<I>& range2d_iterator<I>::operator = (const range2d_iterator<I>& other)
+range2d_iterator_with_boundary_flag<I>& range2d_iterator_with_boundary_flag<I>::operator = (const range2d_iterator_with_boundary_flag<I>& other)
 {
 	m_pos = other.m_pos; 
 	m_size = other.m_size;  
@@ -89,7 +89,7 @@ range2d_iterator<I>& range2d_iterator<I>::operator = (const range2d_iterator<I>&
 
 
 template <typename I> 
-range2d_iterator<I>::range2d_iterator(const range2d_iterator<I>& other):
+range2d_iterator_with_boundary_flag<I>::range2d_iterator_with_boundary_flag(const range2d_iterator_with_boundary_flag<I>& other):
 	m_pos(other.m_pos), 
 	m_size(other.m_size), 
 	m_begin(other.m_begin), 
@@ -101,9 +101,9 @@ range2d_iterator<I>::range2d_iterator(const range2d_iterator<I>& other):
 }	
 
 template <typename I> 
-range2d_iterator<I>& range2d_iterator<I>::operator ++()
+range2d_iterator_with_boundary_flag<I>& range2d_iterator_with_boundary_flag<I>::operator ++()
 {
-	DEBUG_ASSERT_RELEASE_THROW(m_pos.x < m_end.x, "range2d_iterator: trying to increment past end");
+	DEBUG_ASSERT_RELEASE_THROW(m_pos.x < m_end.x, "range2d_iterator_with_boundary_flag: trying to increment past end");
 	
 	++m_pos.x;
 	++m_iterator; 
@@ -119,7 +119,7 @@ range2d_iterator<I>& range2d_iterator<I>::operator ++()
 }
 
 template <typename I> 
-void range2d_iterator<I>::increment_y()
+void range2d_iterator_with_boundary_flag<I>::increment_y()
 {
 	if (m_pos.y < m_end.y - 1) {
 		m_pos.x = m_begin.x; 
@@ -135,30 +135,30 @@ void range2d_iterator<I>::increment_y()
 }
 
 template <typename I> 
-typename range2d_iterator<I>::internal_iterator 
-range2d_iterator<I>::get_point()
+typename range2d_iterator_with_boundary_flag<I>::internal_iterator 
+range2d_iterator_with_boundary_flag<I>::get_point()
 {
 	return m_iterator; 
 }
 
 template <typename I> 
-range2d_iterator<I> range2d_iterator<I>::operator ++(int)
+range2d_iterator_with_boundary_flag<I> range2d_iterator_with_boundary_flag<I>::operator ++(int)
 {
-	range2d_iterator result(*this); 
+	range2d_iterator_with_boundary_flag result(*this); 
 	++(*this); 
 	return result; 
 }
 
 template <typename I> 
-typename range2d_iterator<I>::reference range2d_iterator<I>::operator *() const
+typename range2d_iterator_with_boundary_flag<I>::reference range2d_iterator_with_boundary_flag<I>::operator *() const
 {
 	return *m_iterator; 
 }
 
 template <typename I> 
 struct __iterator2d_dispatch_operator_for_bool {
-	static typename range2d_iterator<I>::pointer 
-	apply(const typename range2d_iterator<I>::internal_iterator& it) {
+	static typename range2d_iterator_with_boundary_flag<I>::pointer 
+	apply(const typename range2d_iterator_with_boundary_flag<I>::internal_iterator& it) {
 		return it.operator->(); 
 	}
 }; 
@@ -179,6 +179,129 @@ struct __iterator2d_dispatch_operator_for_bool<std::vector<bool>::const_iterator
 			
 
 template <typename I> 
+typename range2d_iterator_with_boundary_flag<I>::pointer range2d_iterator_with_boundary_flag<I>::operator ->() const
+{
+	return __iterator2d_dispatch_operator_for_bool<internal_iterator>::apply(m_iterator);
+}
+
+template <typename I> 
+const C2DBounds& range2d_iterator_with_boundary_flag<I>::pos() const
+{
+	return m_pos; 
+}
+
+template <typename I> 
+int range2d_iterator_with_boundary_flag<I>::get_boundary_flags() const
+{
+	return m_boundary; 
+}
+
+template <typename I> 
+range2d_iterator<I>::range2d_iterator():
+	m_pos(0,0), 
+	m_size(0,0), 
+	m_begin(0,0), 
+	m_end(0,0), 
+	m_xstride(0)
+{
+}
+
+template <typename I> 
+range2d_iterator<I>::range2d_iterator(const C2DBounds& pos):
+	m_pos(pos), 
+	m_size(0,0), 
+	m_begin(0,0), 
+	m_end(0,0), 
+	m_xstride(0)
+{
+}
+
+template <typename I> 
+range2d_iterator<I>::range2d_iterator(const C2DBounds& pos, const C2DBounds& size, 
+				      const C2DBounds& begin, const C2DBounds& end, I iterator):
+	m_pos(pos), 
+	m_size(size), 
+	m_begin(begin), 
+	m_end(end),
+	m_xstride(m_size.x - (m_end.x - m_begin.x)),
+	m_iterator(iterator)
+{
+}
+
+
+template <typename I> 
+range2d_iterator<I>& range2d_iterator<I>::operator = (const range2d_iterator<I>& other)
+{
+	m_pos = other.m_pos; 
+	m_size = other.m_size;  
+	m_begin = other.m_begin; 
+	m_end = other.m_end; 
+	m_iterator = other.m_iterator; 
+	m_xstride = other.m_xstride; 
+	return *this; 
+}
+
+
+
+template <typename I> 
+range2d_iterator<I>::range2d_iterator(const range2d_iterator<I>& other):
+	m_pos(other.m_pos), 
+	m_size(other.m_size), 
+	m_begin(other.m_begin), 
+	m_end(other.m_end), 
+	m_xstride(other.m_xstride),
+	m_iterator(other.m_iterator)
+{
+}	
+
+template <typename I> 
+range2d_iterator<I>& range2d_iterator<I>::operator ++()
+{
+	DEBUG_ASSERT_RELEASE_THROW(m_pos.x < m_end.x, "range2d_iterator: trying to increment past end");
+	
+	++m_pos.x;
+	++m_iterator; 
+	if (m_pos.x == m_end.x)
+		increment_y(); 
+	
+	return *this; 
+}
+
+template <typename I> 
+void range2d_iterator<I>::increment_y()
+{
+	if (m_pos.y < m_end.y - 1) {
+		m_pos.x = m_begin.x; 
+		++m_pos.y; 
+		std::advance(m_iterator, m_xstride);
+	} else if (m_pos.y == m_end.y - 1) {
+		m_pos = m_end; 
+	}
+}
+
+template <typename I> 
+typename range2d_iterator<I>::internal_iterator 
+range2d_iterator<I>::get_point()
+{
+	return m_iterator; 
+}
+
+template <typename I> 
+range2d_iterator<I> range2d_iterator<I>::operator ++(int)
+{
+	range2d_iterator result(*this); 
+	++(*this); 
+	return result; 
+}
+
+template <typename I> 
+typename range2d_iterator<I>::reference range2d_iterator<I>::operator *() const
+{
+	return *m_iterator; 
+}
+
+
+template <typename I> 
 typename range2d_iterator<I>::pointer range2d_iterator<I>::operator ->() const
 {
 	return __iterator2d_dispatch_operator_for_bool<internal_iterator>::apply(m_iterator);
@@ -190,10 +313,11 @@ const C2DBounds& range2d_iterator<I>::pos() const
 	return m_pos; 
 }
 
+
 template <typename I> 
-int range2d_iterator<I>::get_boundary_flags() const
+range2d_iterator_with_boundary_flag<I> range2d_iterator<I>::with_boundary_flag() const
 {
-	return m_boundary; 
+	return range2d_iterator_with_boundary_flag<I>(m_pos, m_size, m_begin, m_end, m_iterator); 
 }
 
 NS_MIA_END
diff --git a/mia/2d/iterator.hh b/mia/2d/iterator.hh
index d395143..0b819ba 100644
--- a/mia/2d/iterator.hh
+++ b/mia/2d/iterator.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -39,7 +39,7 @@ NS_MIA_BEGIN
  */
 
 template <typename I> 
-class range2d_iterator: public std::forward_iterator_tag {
+class range2d_iterator_with_boundary_flag: public std::forward_iterator_tag {
 public: 
 	/// data type reference 
 	typedef typename I::reference reference; 
@@ -47,6 +47,8 @@ public:
 	typedef typename I::pointer pointer; 
 	/// data type for the real iterator in the background 
 	typedef I internal_iterator; 
+
+	typedef typename I::value_type value_type; 
 	
 	/**
 	   Enumerate to describe the various positions on the domain boundarys. 
@@ -68,6 +70,160 @@ public:
 
 	
 	/** standard constructor */
+	range2d_iterator_with_boundary_flag(); 
+
+	/**
+	   Full constructor of the range iterator 
+	   @param pos iterator position to initialize the iterator with 
+	   @param size size of the original data field 
+	   @param start start of the iterator range 
+	   @param end end of the iterator range 
+	   @param iterator the iterator of the underlying 2D data structure 
+	*/
+	range2d_iterator_with_boundary_flag(const C2DBounds& pos, const C2DBounds& size, 
+			 const C2DBounds& start, const C2DBounds& end, I iterator);
+	
+	/**
+	   End iterator, can't be dereferenced  
+	   This iterator is only there to define the end position of the range_iterator. 
+	   \param pos end position to set this iterator to. 
+	 */
+	range2d_iterator_with_boundary_flag(const C2DBounds& pos);
+
+	/// assignment operator 
+	range2d_iterator_with_boundary_flag<I>& operator = (const range2d_iterator_with_boundary_flag<I>& other); 
+	
+	/// copy constructore 
+	range2d_iterator_with_boundary_flag(const range2d_iterator_with_boundary_flag<I>& other); 
+
+	/// friend iterator type because we may want to copy a iterator to a const_iterator. 
+	template <typename AI> 
+	friend class range2d_iterator_with_boundary_flag; 
+	
+	/**
+	   Constructor to construct the iterator  from one that is based on another 
+	   iterator type. The usual idea is that a iterator may be converted  into it's const variant. 
+	   \tparam AI the other iterator type. Iterator type I must be copy-constructable from 
+	   type AI 
+	   \param other 
+	 */
+	template <typename AI>
+	range2d_iterator_with_boundary_flag(const range2d_iterator_with_boundary_flag<AI>& other); 
+
+
+	/**
+	   Assignment operator from another type of iterator 
+	   \tparam AI other iterator type. The assignment I b = a; with a of type AI must be defined.
+	   \param other 
+	 */
+	template <typename AI>
+	range2d_iterator_with_boundary_flag<I>& operator = (const range2d_iterator_with_boundary_flag<AI>& other); 
+
+	
+	/// prefix increment 
+	range2d_iterator_with_boundary_flag<I>& operator ++(); 
+	/// postfix increment 
+	range2d_iterator_with_boundary_flag<I> operator ++(int); 
+	
+	/// @returns current value the iterator points to 
+	reference  operator *() const;
+	
+	/// @returns pointer to the current value the iterator points to 
+	pointer    operator ->() const;
+
+	/** \returns the current position within the 2D grid with respect to the 
+	    full size of the grid. 
+	 */
+	const C2DBounds& pos() const; 
+
+	/// @cond NOFRIENDDOC
+	template <typename T> friend
+	bool operator == (const range2d_iterator_with_boundary_flag<T>& left, 
+			  const range2d_iterator_with_boundary_flag<T>& right); 
+
+	template <typename T> friend
+	bool operator != (const range2d_iterator_with_boundary_flag<T>& left, 
+			  const range2d_iterator_with_boundary_flag<T>& right); 
+	/// @endcond 
+
+	/**
+	   Return the internal iterator
+	 */
+	internal_iterator get_point(); 
+
+	/// \returns the flags describing whether the iterator is on a domain boundary. 
+	int get_boundary_flags() const; 
+
+private: 
+
+	void increment_y(); 
+	void increment_z(); 
+
+	C2DBounds m_pos; 
+	C2DBounds m_size; 
+	C2DBounds m_begin; 
+	C2DBounds m_end; 
+	int m_xstride; 
+	I m_iterator; 
+	int m_boundary; 
+}; 
+
+
+
+template <typename I> 
+template <typename AI>
+range2d_iterator_with_boundary_flag<I>& range2d_iterator_with_boundary_flag<I>::operator = (const range2d_iterator_with_boundary_flag<AI>& other)
+{
+	m_pos = other.m_pos; 
+	m_size = other.m_size;  
+	m_begin = other.m_begin; 
+	m_end = other.m_end; 
+	m_iterator = other.m_iterator; 
+	m_xstride = other.m_xstride; 
+	m_boundary = other.m_boundary; 
+	return *this; 
+}
+
+template <typename I> 
+template <typename AI>
+range2d_iterator_with_boundary_flag<I>::range2d_iterator_with_boundary_flag(const range2d_iterator_with_boundary_flag<AI>& other):
+	m_pos(other.m_pos), 
+	m_size(other.m_size), 
+	m_begin(other.m_begin), 
+	m_end(other.m_end), 
+	m_xstride(other.m_xstride),
+	m_iterator(other.m_iterator), 
+	m_boundary(other.m_boundary)
+{
+}	
+
+template <typename T> 
+bool operator == (const range2d_iterator_with_boundary_flag<T>& left, const range2d_iterator_with_boundary_flag<T>& right)
+{
+	return left.m_pos == right.m_pos; 
+}
+
+template <typename T> 
+bool operator != (const range2d_iterator_with_boundary_flag<T>& left, const range2d_iterator_with_boundary_flag<T>& right)
+{
+	return left.m_pos != right.m_pos; 
+}
+
+
+template <typename I> 
+class range2d_iterator: public  std::iterator<std::forward_iterator_tag, typename I::value_type>
+ {
+public: 
+	/// data type reference 
+	typedef typename I::reference reference; 
+	/// data type pointer  
+	typedef typename I::pointer pointer; 
+	/// data type for the real iterator in the background 
+	typedef I internal_iterator; 
+
+	typedef typename I::value_type value_type; 
+	
+	/** standard constructor */
 	range2d_iterator(); 
 
 	/**
@@ -144,9 +300,8 @@ public:
 	 */
 	internal_iterator get_point(); 
 
-	/// \returns the flags describing whether the iterator is on a domain boundary. 
-	int get_boundary_flags() const; 
-
+	
+	range2d_iterator_with_boundary_flag<I> with_boundary_flag() const; 
 private: 
 
 	void increment_y(); 
@@ -158,7 +313,6 @@ private:
 	C2DBounds m_end; 
 	int m_xstride; 
 	I m_iterator; 
-	int m_boundary; 
 }; 
 
 
@@ -173,7 +327,6 @@ range2d_iterator<I>& range2d_iterator<I>::operator = (const range2d_iterator<AI>
 	m_end = other.m_end; 
 	m_iterator = other.m_iterator; 
 	m_xstride = other.m_xstride; 
-	m_boundary = other.m_boundary; 
 	return *this; 
 }
 
@@ -185,12 +338,13 @@ range2d_iterator<I>::range2d_iterator(const range2d_iterator<AI>& other):
 	m_begin(other.m_begin), 
 	m_end(other.m_end), 
 	m_xstride(other.m_xstride),
-	m_iterator(other.m_iterator), 
-	m_boundary(other.m_boundary)
+	m_iterator(other.m_iterator)
 {
 }	
 
 
+
+
 /**
    Compare two range iterators. There equivalence is only decided based on the grid position. 
  */
@@ -218,4 +372,29 @@ bool operator != (const range2d_iterator<I>& a, const range2d_iterator<I>& b)
 
 NS_MIA_END
 
+
+namespace std {
+
+template <typename I>
+class iterator_traits< mia::range2d_iterator<I> > {
+public: 
+	typedef typename I::difference_type  difference_type; 
+	typedef typename I::value_type	value_type; 
+	typedef typename I::pointer	pointer; 
+	typedef typename I::reference	reference; 
+	typedef forward_iterator_tag	iterator_category; 
+}; 
+
+template <typename I>
+class iterator_traits< mia::range2d_iterator_with_boundary_flag<I> > {
+public: 
+	typedef typename I::difference_type  difference_type; 
+	typedef typename I::value_type	value_type; 
+	typedef typename I::pointer	pointer; 
+	typedef typename I::reference	reference; 
+	typedef forward_iterator_tag	iterator_category; 
+}; 
+
+}
+
 #endif
diff --git a/mia/2d/kernel/CMakeLists.txt b/mia/2d/kernel/CMakeLists.txt
index d9f08a6..e4a1da8 100644
--- a/mia/2d/kernel/CMakeLists.txt
+++ b/mia/2d/kernel/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/kernel/curv.cc b/mia/2d/kernel/curv.cc
index 5fc8304..8b09974 100644
--- a/mia/2d/kernel/curv.cc
+++ b/mia/2d/kernel/curv.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/maskedcost.cc b/mia/2d/maskedcost.cc
new file mode 100644
index 0000000..1cd27a6
--- /dev/null
+++ b/mia/2d/maskedcost.cc
@@ -0,0 +1,45 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/export_handler.hh>
+
+#include <mia/2d/maskedcost.hh>
+#include <mia/template/masked_cost.cxx>
+#include <mia/core/handler.cxx>
+#include <mia/core/plugin_base.cxx>
+
+NS_MIA_BEGIN
+
+template <> const char *  const 
+TPluginHandler<TFactory<C2DMaskedImageCost>>::m_help =  
+	"2D image similarity kernels evaluate the according similarity measure between "
+	"two images by using a mask. These kernels may be used standalone, like e.g. in "
+	"linear registration, or will be called from generalized image similarity cost "
+	"plug-ins that also take care of transforming and scaling the images during the "
+	"image registration process.";
+
+template class TMaskedCost<C2DImage, C2DBitImage, C2DFVectorfield>;
+template class TPlugin<C2DImage, masked_cost_type>;
+template class TFactory<C2DMaskedImageCost>;
+template class THandlerSingleton<TFactoryPluginHandler<C2DMaskedImageCostPlugin> >;
+template class TFactoryPluginHandler<C2DMaskedImageCostPlugin>;
+template class TPluginHandler<C2DMaskedImageCostPlugin>;
+
+NS_MIA_END
diff --git a/mia/2d/maskedcost.hh b/mia/2d/maskedcost.hh
new file mode 100644
index 0000000..2d4d546
--- /dev/null
+++ b/mia/2d/maskedcost.hh
@@ -0,0 +1,62 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_2d_masked_cost_hh
+#define mia_2d_masked_cost_hh
+
+#include <mia/template/masked_cost.hh>
+#include <mia/2d/image.hh>
+
+NS_MIA_BEGIN
+
+
+extern template class EXPORT_2D TMaskedCost<C2DImage, C2DBitImage, C2DFVectorfield>;
+/**
+   @ingroup registration 
+   @brief the image-to-image cost function base class 
+*/
+typedef TMaskedCost<C2DImage, C2DBitImage, C2DFVectorfield> C2DMaskedImageCost;
+
+/**
+   @ingroup registration 
+   @brief pointer type of the image-to-image cost function base class 
+*/
+typedef std::shared_ptr<C2DMaskedImageCost > P2DMaskedImageCost;
+
+/**
+   @ingroup registration 
+   @brief plug-in for the image-to-image cost function base class 
+*/
+typedef TFactory<C2DMaskedImageCost> C2DMaskedImageCostPlugin;
+
+/**
+   @ingroup registration 
+   @brief plug-in handler for the image-to-image cost function base class 
+*/
+typedef THandlerSingleton<TFactoryPluginHandler<C2DMaskedImageCostPlugin> > C2DMaskedImageCostPluginHandler;
+
+/// @cond NEVER 
+FACTORY_TRAIT(C2DMaskedImageCostPluginHandler);
+/// @endcond 
+
+NS_MIA_END
+
+
+#endif 
diff --git a/mia/2d/maskedcost/CMakeLists.txt b/mia/2d/maskedcost/CMakeLists.txt
new file mode 100644
index 0000000..2c03415
--- /dev/null
+++ b/mia/2d/maskedcost/CMakeLists.txt
@@ -0,0 +1,35 @@
+#
+# This file is part of MIA - a toolbox for medical image analysis 
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+#
+# MIA is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+
+SET(maskedcost2d
+  lncc
+  mi 
+  ncc 
+  ssd
+)
+
+PLUGINGROUP_WITH_TEST_AND_PREFIX2("2dimage" "maskedcost" "${maskedcost2d}" 
+  "${MIA2DLIBS}" )
+
+
+#SET(fatcost2d fatngf fatssd) 
+
+#PLUGINGROUP_WITH_TEST_AND_PREFIX(2d-fatcost "${fatcost2d}" 
+#  "${MIA2DLIBS}" "${PLUGIN_INSTALL_PATH}/2dimage/fatcost"
+#  )
+
diff --git a/mia/2d/maskedcost/lncc.cc b/mia/2d/maskedcost/lncc.cc
new file mode 100644
index 0000000..bab5fda
--- /dev/null
+++ b/mia/2d/maskedcost/lncc.cc
@@ -0,0 +1,231 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/maskedcost/lncc.hh>
+#include <mia/core/nccsum.hh> 
+#include <mia/core/threadedmsg.hh>
+#include <tbb/parallel_reduce.h>
+#include <tbb/blocked_range.h>
+
+
+NS_BEGIN(NS)
+
+using namespace mia; 
+using std::vector; 
+using std::pair; 
+using std::make_pair; 
+
+CLNCC2DImageCost::CLNCC2DImageCost(int hw):
+m_hwidth(hw)
+{
+}
+
+inline pair<C2DBounds, C2DBounds> prepare_range(const C2DBounds& size, int cx, int cy, int hw) 
+{
+	int yb = cy - hw;
+	if (yb < 0) yb = 0; 
+	unsigned ye = cy + hw + 1; 
+	if (ye > size.y) ye = size.y; 
+	
+	int xb = cx - hw;
+	if (xb < 0) xb = 0; 
+	unsigned xe = cx + hw + 1; 
+	if (xe > size.x) xe = size.x; 
+	
+	return make_pair(C2DBounds(xb,yb), C2DBounds(xe,ye)); 
+}
+
+
+
+class FEvalCost : public TFilter<float> {
+	int m_hw;
+	const C2DBitImage& m_mask; 
+public:
+	FEvalCost(int hw, const C2DBitImage& mask):
+		m_hw(hw), 
+		m_mask(mask)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		auto evaluate_local_cost = [this, &mov, &ref](const tbb::blocked_range<size_t>& range, const pair<float, int>& result) -> pair<float, int> {
+			CThreadMsgStream msks; 
+			float lresult = 0.0; 
+			int count = 0; 
+			const int max_length = 2 * m_hw +1; 
+			vector<float> a_buffer( max_length * max_length * max_length); 
+			vector<float> b_buffer( max_length * max_length * max_length); 
+			
+			for (auto y = range.begin(); y != range.end(); ++y) {
+				auto imask  = m_mask.begin_at(0,y);
+				for (size_t x = 0; x < mov.get_size().x; ++x, ++imask) {
+					if (!*imask) 
+						continue; 
+					
+					auto c_block = prepare_range(mov.get_size(), x, y, m_hw); 
+
+					NCCSums sum; 
+					for (unsigned iy = c_block.first.y; iy < c_block.second.y; ++iy) {
+						auto ia = mov.begin_at(0,iy); 
+						auto ib = ref.begin_at(0, iy); 
+						auto im = m_mask.begin_at(0, iy); 
+						for (unsigned ix = c_block.first.x; ix < c_block.second.x; ++ix) {
+							
+							// make a local copy 
+							if (im[ix]) {
+								sum.add(ia[ix], ib[ix]);
+							}
+						}
+					}
+					
+					if (sum.has_samples()) {
+						lresult += sum.value(); 
+						++count; 
+					}
+					
+					
+				}
+			}
+			return make_pair(result.first + lresult, result.second + count); 
+		};
+		
+		pair<float,int> init{0, 0}; 
+		auto r = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), init, evaluate_local_cost, 
+					 [](const pair<float,int>& x, const pair<float,int>& y){return make_pair(x.first + y.first, x.second + y.second);});	
+		cvdebug() << "result={" << r.first << " /  " <<  r.second << "\n"; 
+		return r.second > 0 ? r.first / r.second : 0.0; 
+	}
+}; 
+
+
+double CLNCC2DImageCost::do_value(const Data& a, const Data& b, const Mask& m) const
+{
+	FEvalCost ecost(m_hwidth, m); 
+	return mia::filter(ecost, a, b); 
+}
+
+
+class FEvalCostForce : public TFilter<float> {
+	int m_hw;
+	const C2DBitImage& m_mask; 
+	C2DFVectorfield& m_force; 
+public: 
+	FEvalCostForce(int hw, const C2DBitImage& mask, C2DFVectorfield& force):
+		m_hw(hw), 
+		m_mask(mask), 
+		m_force(force)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		auto ag = get_gradient(mov); 
+		auto evaluate_local_cost_force = [this, &mov, &ref, &ag](const tbb::blocked_range<size_t>& range, 
+									 const pair<float, int>& result) -> pair<float, int> {
+			
+			CThreadMsgStream msks; 		
+			float lresult = 0.0; 
+			int count = 0; 
+			const int max_length = 2 * m_hw + 1;
+			vector<float> a_buffer( max_length * max_length * max_length); 
+			vector<float> b_buffer( max_length * max_length * max_length); 
+
+			for (auto y = range.begin(); y != range.end(); ++y) {
+                        
+				auto iforce = m_force.begin_at(0,y);
+				auto imask = m_mask.begin_at(0,y);
+				auto ig = ag.begin_at(0,y);
+				auto imov = mov.begin_at(0,y);
+				auto iref = ref.begin_at(0,y);
+                        
+				for (size_t x = 0; x < mov.get_size().x; ++x, ++iforce, ++imask, ++ig, ++iref, ++imov) {
+					if (!*imask) 
+						continue; 
+                                        
+					auto c_block = prepare_range(mov.get_size(), x, y, m_hw); 
+					
+					
+					NCCSums sum; 
+					for (unsigned iy = c_block.first.y; iy < c_block.second.y; ++iy) {
+						auto ia = mov.begin_at(0,iy); 
+						auto ib = ref.begin_at(0, iy); 
+						auto im = m_mask.begin_at(0, iy); 
+						for (unsigned ix = c_block.first.x; ix < c_block.second.x; ++ix) {
+							
+							// make a local copy 
+							if (im[ix]) {
+								sum.add(ia[ix], ib[ix]);
+							}
+						}
+					}
+					
+					if (sum.has_samples()) {
+						auto res = sum.get_grad_helper(); 
+						lresult += res.first;
+						*iforce = res.second.get_gradient_scale(*imov, *iref) * *ig; 
+						++count; 
+					}
+					
+				}
+			}
+			return make_pair(result.first + lresult, result.second + count); 
+		};
+		pair<float,int> init{0, 0}; 		
+		auto r = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), init, evaluate_local_cost_force, 
+					 [](const pair<float,int>& x, const pair<float,int>& y){
+						 return make_pair(x.first + y.first, x.second + y.second);
+					 });
+		
+		return r.second > 0 ? r.first / r.second : 0.0; 
+	}
+	
+};
+
+double CLNCC2DImageCost::do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const
+{
+	FEvalCostForce ecostforce(m_hwidth, m, force); 
+	return mia::filter(ecostforce, a, b); 
+}
+
+
+CLNCC2DImageCostPlugin::CLNCC2DImageCostPlugin():
+C2DMaskedImageCostPlugin("lncc"), 
+     m_hw(5)
+{
+	this->add_parameter("w", new CUIntParameter(m_hw, 1, 256, false, 
+						    "half width of the window used for evaluating the localized cross correlation")); 
+}
+
+C2DMaskedImageCost *CLNCC2DImageCostPlugin::do_create() const
+{
+	return new CLNCC2DImageCost(m_hw);
+}
+
+const std::string CLNCC2DImageCostPlugin::do_get_descr() const
+{
+	return "local normalized cross correlation with masking support."; 
+}
+
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new CLNCC2DImageCostPlugin();
+}
+
+NS_END
diff --git a/mia/2d/maskedcost/lncc.hh b/mia/2d/maskedcost/lncc.hh
new file mode 100644
index 0000000..6f861f5
--- /dev/null
+++ b/mia/2d/maskedcost/lncc.hh
@@ -0,0 +1,55 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_2d_maskedcost_lncc_hh
+#define mia_2d_maskedcost_lncc_hh
+
+#include <mia/2d/maskedcost.hh>
+
+#define NS mia_2d_maskedlncc
+
+NS_BEGIN(NS)
+
+class CLNCC2DImageCost: public mia::C2DMaskedImageCost {
+public: 	
+	typedef mia::C2DMaskedImageCost::Data Data; 
+	typedef mia::C2DMaskedImageCost::Force Force; 
+	typedef mia::C2DMaskedImageCost::Mask Mask; 
+
+	CLNCC2DImageCost(int hw);
+private: 
+	virtual double do_value(const Data& a, const Data& b, const Mask& m) const; 
+	virtual double do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const; 
+
+        int m_hwidth; 
+};
+
+class CLNCC2DImageCostPlugin: public mia::C2DMaskedImageCostPlugin {
+public: 
+	CLNCC2DImageCostPlugin();
+	mia::C2DMaskedImageCost *do_create() const;
+private: 
+	const std::string do_get_descr() const; 
+        unsigned int m_hw; 
+};
+
+NS_END
+
+#endif 
diff --git a/mia/2d/maskedcost/mi.cc b/mia/2d/maskedcost/mi.cc
new file mode 100644
index 0000000..eff7d4b
--- /dev/null
+++ b/mia/2d/maskedcost/mi.cc
@@ -0,0 +1,38 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/maskedcost/mi.hh>
+#include <mia/template/mi_masked.cxx>
+
+NS_BEGIN(NS)
+
+NS_MIA_USE;
+using namespace std;
+using namespace boost;
+
+template class TMIMaskedImageCost<mia::C2DMaskedImageCost>;
+template class TMIMaskedImageCostPlugin<mia::C2DMaskedImageCostPlugin, mia::C2DMaskedImageCost>; 
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C2DMIMaskedCostPlugin();
+}
+
+NS_END
diff --git a/mia/2d/maskedcost/mi.hh b/mia/2d/maskedcost/mi.hh
new file mode 100644
index 0000000..3c2de4c
--- /dev/null
+++ b/mia/2d/maskedcost/mi.hh
@@ -0,0 +1,37 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_2d_cost_mi_hh
+#define mia_2d_cost_mi_hh
+
+#include <mia/2d/maskedcost.hh>
+
+#define NS mia_2dcost_mi_masked
+#include <mia/template/mi_masked.hh>
+
+NS_BEGIN(NS)
+
+typedef TMIMaskedImageCost<mia::C2DMaskedImageCost> C2DMIMaskedImageCost;
+typedef TMIMaskedImageCostPlugin<mia::C2DMaskedImageCostPlugin, mia::C2DMaskedImageCost> C2DMIMaskedCostPlugin; 
+
+NS_END
+
+
+#endif
diff --git a/mia/2d/maskedcost/ncc.cc b/mia/2d/maskedcost/ncc.cc
new file mode 100644
index 0000000..113b4ed
--- /dev/null
+++ b/mia/2d/maskedcost/ncc.cc
@@ -0,0 +1,185 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/maskedcost/ncc.hh>
+
+#include <mia/core/threadedmsg.hh>
+#include <mia/core/nccsum.hh> 
+#include <tbb/parallel_reduce.h>
+#include <tbb/parallel_for.h>
+#include <tbb/blocked_range.h>
+
+
+NS_BEGIN(NS)
+
+using namespace mia; 
+
+
+CNCC2DImageCost::CNCC2DImageCost()
+{
+}
+
+template <typename T, typename S> 
+struct FEvaluateNCCSum {
+	FEvaluateNCCSum(const C2DBitImage& mask, const T& mov, const S& ref); 
+	NCCSums operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const; 
+private: 
+	C2DBitImage m_mask; 
+	T m_mov; 
+	S m_ref; 
+};
+
+
+template <typename T, typename S> 
+FEvaluateNCCSum<T,S>::FEvaluateNCCSum(const C2DBitImage& mask, const T& mov, const S& ref):
+	m_mask(mask),  m_mov(mov), m_ref(ref) 
+{
+	
+}
+
+template <typename T, typename S> 
+NCCSums FEvaluateNCCSum<T,S>::operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const
+{
+	CThreadMsgStream msks; 
+	
+	NCCSums sum;
+	for (auto z = range.begin(); z != range.end(); ++z) {
+		auto imask  = m_mask.begin_at(0,z);
+		auto ia = m_mov.begin_at(0, z); 
+		auto ib = m_ref.begin_at(0, z); 
+		auto eb = m_ref.begin_at(0, z + 1); 
+		
+		while (ib != eb) {
+			if (*imask) {
+				sum.add(*ia, *ib); 
+			}
+			++ia; ++ib; ++imask; 
+		}
+	}
+	return sum + sumacc; 
+};
+
+
+class FEvalCost : public TFilter<float> {
+	const C2DBitImage& m_mask; 
+public:
+	FEvalCost(const C2DBitImage& mask):
+		m_mask(mask)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+
+		FEvaluateNCCSum<T,R> ev(m_mask, mov, ref); 
+		NCCSums sum; 
+		sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), sum, ev, 
+				      [](const NCCSums& x, const NCCSums& y){
+					      return x + y;
+				      });
+		return sum.value(); 
+	}
+}; 
+
+
+double CNCC2DImageCost::do_value(const Data& a, const Data& b, const Mask& m) const
+{
+	FEvalCost ecost(m); 
+	return mia::filter(ecost, a, b); 
+}
+
+
+class FEvalCostForce : public TFilter<float> {
+	const C2DBitImage& m_mask; 
+	C2DFVectorfield& m_force; 
+public: 
+	FEvalCostForce(const C2DBitImage& mask, C2DFVectorfield& force):
+		m_mask(mask), 
+		m_force(force)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		CThreadMsgStream msks;
+		
+		NCCSums sum; 
+		FEvaluateNCCSum<T,R> ev(m_mask, mov, ref); 
+		sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), sum, ev, 
+					 [](const NCCSums& x, const NCCSums& y){
+					      return x + y;
+				      });
+		
+		auto geval = sum.get_grad_helper(); 
+
+		auto grad = get_gradient(mov); 
+		auto grad_eval = [this, &mov, &ref, &grad, &geval](const tbb::blocked_range<size_t>& range) {
+			for (auto z = range.begin(); z != range.end(); ++z) {
+				auto ig = grad.begin_at(0,z); 
+				auto iforce = m_force.begin_at(0,z); 
+				auto im = m_mask.begin_at(0,z); 
+				auto ia = mov.begin_at(0,z); 
+				auto ib = ref.begin_at(0,z); 
+				auto eb = ref.begin_at(0,z+1); 
+				
+				while (ib != eb) {
+					if (*im) {
+						*iforce = geval.second.get_gradient_scale(*ia, *ib) * *ig; 
+					}
+					++ig; 
+					++iforce; 
+					++ia; ++ib; ++im; 
+				}
+			}; 
+		}; 
+		
+		parallel_for(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), grad_eval); 
+
+		return geval.first; 
+	}
+	
+};
+
+double CNCC2DImageCost::do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const
+{
+	FEvalCostForce ecostforce(m, force); 
+	return mia::filter(ecostforce, a, b); 
+}
+
+
+CNCC2DImageCostPlugin::CNCC2DImageCostPlugin():
+C2DMaskedImageCostPlugin("ncc")
+{
+}
+
+C2DMaskedImageCost *CNCC2DImageCostPlugin::do_create() const
+{
+	return new CNCC2DImageCost();
+}
+
+const std::string CNCC2DImageCostPlugin::do_get_descr() const
+{
+	return "normalized cross correlation with masking support."; 
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new CNCC2DImageCostPlugin();
+}
+
+NS_END
diff --git a/mia/2d/maskedcost/ncc.hh b/mia/2d/maskedcost/ncc.hh
new file mode 100644
index 0000000..a48ab3e
--- /dev/null
+++ b/mia/2d/maskedcost/ncc.hh
@@ -0,0 +1,52 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_2d_maskedcost_ncc_hh
+#define mia_2d_maskedcost_ncc_hh
+
+#include <mia/2d/maskedcost.hh>
+
+#define NS mia_2d_maskedncc
+
+NS_BEGIN(NS)
+
+class CNCC2DImageCost: public mia::C2DMaskedImageCost {
+public: 	
+	typedef mia::C2DMaskedImageCost::Data Data; 
+	typedef mia::C2DMaskedImageCost::Force Force; 
+	typedef mia::C2DMaskedImageCost::Mask Mask; 
+
+	CNCC2DImageCost();
+private: 
+	virtual double do_value(const Data& a, const Data& b, const Mask& m) const; 
+	virtual double do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const; 
+};
+
+class CNCC2DImageCostPlugin: public mia::C2DMaskedImageCostPlugin {
+public: 
+	CNCC2DImageCostPlugin();
+	mia::C2DMaskedImageCost *do_create() const;
+private: 
+	const std::string do_get_descr() const; 
+};
+
+NS_END
+
+#endif 
diff --git a/mia/2d/maskedcost/ssd.cc b/mia/2d/maskedcost/ssd.cc
new file mode 100644
index 0000000..e408815
--- /dev/null
+++ b/mia/2d/maskedcost/ssd.cc
@@ -0,0 +1,38 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/2d/maskedcost/ssd.hh>
+#include <mia/template/ssd_masked.cxx>
+
+NS_BEGIN(NS)
+
+NS_MIA_USE;
+using namespace std;
+using namespace boost;
+
+template class TSSDMaskedImageCost<mia::C2DMaskedImageCost>;
+template class TSSDMaskedImageCostPlugin<mia::C2DMaskedImageCostPlugin, mia::C2DMaskedImageCost>; 
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C2DSSDMaskedCostPlugin();
+}
+
+NS_END
diff --git a/mia/2d/maskedcost/ssd.hh b/mia/2d/maskedcost/ssd.hh
new file mode 100644
index 0000000..b2a67b6
--- /dev/null
+++ b/mia/2d/maskedcost/ssd.hh
@@ -0,0 +1,37 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_2d_maskedcost_ssd_hh
+#define mia_2d_maskedcost_ssd_hh
+
+#include <mia/2d/maskedcost.hh>
+
+#define NS mia_2dcost_ssd_masked
+#include <mia/template/ssd_masked.hh>
+
+NS_BEGIN(NS)
+
+typedef TSSDMaskedImageCost<mia::C2DMaskedImageCost> C2DSSDMaskedImageCost;
+typedef TSSDMaskedImageCostPlugin<mia::C2DMaskedImageCostPlugin, mia::C2DMaskedImageCost> C2DSSDMaskedCostPlugin; 
+
+NS_END
+
+
+#endif
diff --git a/mia/2d/maskedcost/test_lncc.cc b/mia/2d/maskedcost/test_lncc.cc
new file mode 100644
index 0000000..7d612af
--- /dev/null
+++ b/mia/2d/maskedcost/test_lncc.cc
@@ -0,0 +1,112 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <mia/internal/plugintester.hh>
+#include <mia/2d/maskedcost/lncc.hh>
+
+using namespace NS; 
+using namespace mia; 
+
+
+
+
+BOOST_AUTO_TEST_CASE( test_masked_lncc_1 ) 
+{
+        C2DBounds size(4,4); 
+        auto lncc = BOOST_TEST_create_from_plugin<CLNCC2DImageCostPlugin>("lncc:w=1");
+
+	const float src_data[16] = {           
+		1, 1, 2, 2, 
+		2, 3, 4, 4, 
+		4, 4, 3, 3, 
+		2, 2, 2, 1, 
+		
+		};                                     /*      5  9  9  8  2  7  5  3        */
+	
+	const float ref_data[16] = {
+		1, 2, 1, 5, 
+		1, 1, 1, 1, 
+		2, 2, 2, 7,
+		4, 3, 2, 2
+	};
+
+	const bool mask_data[64] = {
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+	};
+
+        
+	C2DFImage src_f(size, src_data); 
+        C2DFImage ref_f(size, ref_data); 
+        C2DBitImage mask(size, mask_data); 
+
+        
+        lncc->set_reference(ref_f); 
+        BOOST_CHECK_SMALL(lncc->value(ref_f, mask),1e-10);
+        
+        auto v = lncc->value(src_f, mask); 
+        BOOST_CHECK_CLOSE(v, 1.0 -0.199159659, 0.1); 
+        
+	C2DFVectorfield zero_force(size); 
+	v = lncc->evaluate_force(ref_f, mask, zero_force); 
+	BOOST_CHECK_SMALL(v, 1e-10);
+
+	for (auto iv = zero_force.begin(); iv != zero_force.end();  ++iv) {
+		BOOST_CHECK_SMALL(iv->x, 1e-8f); 
+		BOOST_CHECK_SMALL(iv->y, 1e-8f); 
+	}
+	
+
+	C2DFVectorfield force(size); 
+
+	v = lncc->evaluate_force(src_f, mask, force); 
+	BOOST_CHECK_CLOSE(v, 1.0 -0.199159659, 0.1); 
+        
+	
+	float gradx[] = {
+		0,0.1423816568,-0.0565096061,0,
+		0,-0.0094921105,-0.0110429448,0,
+		0,-0.0464876033,0.0032142857,0,
+		0,0,-0.0148760331,0
+	};
+
+	float grady[] = {
+		0,0,0,0,
+		0,-0.0142381657,-0.0110429448,-0.0253807107,
+		0,-0.0464876033,0.0064285714,-0.1171571544,
+		0,0,0,0
+	}; 
+	
+
+	auto igx = gradx; 
+	auto igy = grady; 
+	for (auto iv = force.begin(); iv != force.end();  ++iv, ++igx, ++igy) {
+		if (*igx == 0.0) 
+			BOOST_CHECK_SMALL(iv->x, 1e-8f); 
+		else 
+			BOOST_CHECK_CLOSE(iv->x, *igx, 0.1); 
+
+		if (*igy == 0.0) 
+			BOOST_CHECK_SMALL(iv->y, 1e-8f); 
+		else 
+			BOOST_CHECK_CLOSE(iv->y, *igy, 0.1); 
+	}
+}
diff --git a/mia/2d/maskedcost/test_mi.cc b/mia/2d/maskedcost/test_mi.cc
new file mode 100644
index 0000000..0ad9ef5
--- /dev/null
+++ b/mia/2d/maskedcost/test_mi.cc
@@ -0,0 +1,160 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <mia/2d/maskedcost/mi.hh>
+#include <cmath>
+
+
+NS_MIA_USE
+using namespace std;
+using namespace ::boost::unit_test;
+using namespace NS;
+
+
+class MIFixture {
+protected: 
+	MIFixture(); 
+	
+	
+	C2DBounds size; 
+	P2DImage src; 
+	P2DImage ref; 
+	C2DBitImage mask; 
+	C2DFVectorfield grad; 
+	unique_ptr<C2DMIMaskedImageCost> cost; 
+}; 
+
+
+BOOST_FIXTURE_TEST_CASE( test_MI_2D_self, MIFixture )
+{
+	cost->set_reference(*ref);
+	
+	const double test_cost_value =-1.2440862175787268; 
+
+	double cost_value = cost->value(*ref, mask);
+	BOOST_CHECK_CLOSE(cost_value, test_cost_value, 0.1);
+
+	C2DFVectorfield force(C2DBounds(8,8));
+	
+	BOOST_CHECK_CLOSE(cost->evaluate_force(*ref, mask, force), 1.0 * test_cost_value, 0.1);
+
+	// unfortunately the gradient self tests fail because the 
+	// spline based gradent evaluation is not zero at the expected minimum
+}
+
+/*
+   currently all tests fail, because the test values are not yet evaluated
+
+
+BOOST_FIXTURE_TEST_CASE( test_MI_2D, MIFixture )
+{
+	cost->set_reference(*ref);
+	
+	double cost_value = cost->value(*src);
+	BOOST_CHECK_CLOSE(cost_value, -74.402 / 64.0, 0.1);
+
+	C2DFVectorfield force(C2DBounds(8,8));
+
+	BOOST_CHECK_CLOSE(cost->evaluate_force(*src, 1.0, force), -74.402, 0.1);
+
+
+	for (auto iforce = force.begin(), ig = grad.begin(); ig != grad.end(); ++ig, ++iforce) {
+		BOOST_CHECK_CLOSE(iforce->x, ig->x, 0.1f);
+		BOOST_CHECK_CLOSE(iforce->y, ig->y, 0.1f);
+	}; 
+}
+*/
+
+MIFixture::MIFixture():
+	size(8,8),
+	mask(size),
+	grad(size) 
+	
+{
+	const float src_data[64] = {           /*   0  1  2  3  4  5  6  7  8  9     */    
+		1, 1, 2, 2, 2, 3, 4, 4,        /*1                                 0 */
+		4, 4, 3, 3, 2, 2, 2, 1,        /*2     1  2  1  1     1            6 */
+		2, 2, 3, 4, 5, 6, 7, 8,        /*3        1  2     1  1  1  1      7 */
+		8, 7, 2, 8, 3, 4, 2, 2,        /*4     1     1  1     2  1  1      7 */ 
+		3, 1, 3, 4, 5, 6, 7, 8,        /*5     1     2  1        2  1      7 */
+		3, 4, 4, 5, 6, 4, 2, 2,        /*6        3     3     1            7 */
+	        3, 2, 3, 4, 5, 3, 1, 4,        /*7     1  1  2  2  1               7 */
+		5, 6, 7, 3, 2, 1, 2, 6         /*8     1  2  1        2  1         7 */
+	};                                     /*      5  9  9  8  2  7  5  3        */
+	
+	const float ref_data[64] = {
+		1, 1, 1, 5, 1, 1, 1, 1, 
+		2, 2, 2, 7, 2, 2, 2, 2,
+		3, 3, 3, 5, 3, 3, 3, 3, 
+		4, 4, 6, 4, 3, 4, 4, 4,
+		5, 5, 5, 6, 4, 2, 1, 5, 
+		6, 6, 4, 5, 6, 6, 6, 6,
+	        7, 7, 7, 7, 7, 5, 7, 7, 
+		8, 8, 8, 8, 8, 8, 8, 8
+	};
+
+	const float mask_data[64] = {
+		0, 0, 0, 0, 0, 0, 0, 0, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+	        0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1
+	};
+
+
+	const float grady[64] = {
+		+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
+		+0.00000, 0.00000,-1.30000, 0.00000,-0.35294,-0.35294,-0.35294, 0.00000,
+		-0.00000,-0.70588, 0.68182, 0.00000, 0.16667, 3.76471, 0.00000, 0.00000,
+		+0.00000,-1.66667,-0.00000, 0.00000,-0.00000, 0.00000,-0.00000,-0.00000,
+		+0.00000,-0.00000,-1.36364,-0.00000, 0.50000, 0.00000, 0.00000, 0.00000,
+		+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.70588, 0.00000,
+		-0.00000,-0.23529,-2.04545, 0.00000,-0.66667, 2.04545, 0.00000,-0.00000,
+		+0.00000,+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000
+	}; 
+	const float gradx[64] = {
+		+ 0.00000,  0.00000, 0.00000, 0.00000, 0.00000, 0.00000,-0.00000,-0.00000, 
+		+ 0.00000,- 0.00000, 1.30000,-0.00000, 0.11765,-0.00000, 0.11765,-0.00000,
+		- 0.00000,- 0.11765,-1.36364, 0.00000, 0.33333, 3.76471, 1.40000, 0.00000, 
+		+ 0.00000,-11.66667, 0.23529, 1.81818, 3.33333,-0.00000, 0.23529,-0.00000, 
+		+ 0.00000,  0.00000,-2.04545, 0.00000, 0.33333, 0.40000, 0.00000, 0.00000,
+	        - 0.00000,  0.00000, 0.00000, 0.33333,-0.20000, 0.00000, 0.23529,-0.00000,
+		- 0.00000,- 0.35294,-1.36364,-0.00000,-0.16667, 2.72727, 0.00000,-0.00000,
+		+ 0.00000,  0.00000,-0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000
+	}; 
+
+
+	copy(mask_data, mask_data + 64, mask.begin()); 
+	src.reset(new C2DFImage(size, src_data ));
+	ref.reset(new C2DFImage(size, ref_data ));
+	
+
+	auto ig = grad.begin(); 
+	for (int i = 0; i < 64; ++i, ++ig) {
+		ig->x = gradx[i]; 
+		ig->y = grady[i];
+	}
+	cost.reset(new 	C2DMIMaskedImageCost(8, produce_spline_kernel("bspline:d=0"), 
+					     8, produce_spline_kernel("bspline:d=3"), 0)); 
+}
diff --git a/mia/2d/maskedcost/test_ncc.cc b/mia/2d/maskedcost/test_ncc.cc
new file mode 100644
index 0000000..db60752
--- /dev/null
+++ b/mia/2d/maskedcost/test_ncc.cc
@@ -0,0 +1,169 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+#include <mia/2d/maskedcost/ncc.hh>
+#include <mia/core/nccsum.hh>
+
+using namespace NS; 
+using namespace mia; 
+
+
+
+
+BOOST_AUTO_TEST_CASE( test_masked_ncc_zero ) 
+{
+        C2DBounds size(4,4); 
+        auto ncc = BOOST_TEST_create_from_plugin<CNCC2DImageCostPlugin>("ncc");
+        
+        C2DFImage a(size); 
+        C2DFImage b(size); 
+        C2DBitImage mask(size); 
+
+        fill(mask.begin(), mask.end(), true); 
+        
+        auto ia = a.begin_range(C2DBounds::_0, size); 
+        auto ib = b.begin_range(C2DBounds::_0, size); 
+        auto ea = a.end_range(C2DBounds::_0, size); 
+
+        while (ia != ea) {
+                *ia = ia.pos().x + ia.pos().y; 
+                *ib = 2* *ia; 
+                ++ib; ++ia; 
+        }
+
+        ncc->set_reference(b); 
+        BOOST_CHECK_SMALL(ncc->value(b, mask), 1e-7); 
+
+        BOOST_CHECK_SMALL(ncc->value(a, mask), 1e-7); 
+        
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_masked_ncc_nonzero ) 
+{
+        C2DBounds size(4,4); 
+        auto ncc = BOOST_TEST_create_from_plugin<CNCC2DImageCostPlugin>("ncc");
+        
+        C2DFImage a(size); 
+        C2DFImage b(size); 
+        C2DBitImage mask(size); 
+
+        fill(mask.begin(), mask.end(), true); 
+        
+        auto ia = a.begin_range(C2DBounds::_0, size); 
+        auto ib = b.begin_range(C2DBounds::_0, size); 
+        auto ea = a.end_range(C2DBounds::_0, size); 
+
+        NCCSums sum; 
+
+        while (ia != ea) {
+                *ia = ia.pos().x + ia.pos().y; 
+                *ib = ia.pos().x * ia.pos().y; 
+                sum.add(*ia, *ib); 
+                ++ib; ++ia; 
+        }
+
+        ncc->set_reference(b); 
+        BOOST_CHECK_CLOSE(ncc->value(a, mask), sum.value(), 0.1); 
+        
+        C2DFVectorfield grad(size); 
+
+        BOOST_CHECK_CLOSE(ncc->evaluate_force(a, mask, grad), sum.value(), 0.01);
+
+
+	auto ag = get_gradient(a); 
+	
+	auto iag = ag.begin(); 
+	auto ia2 = a.begin(); 
+	auto ib2 = b.begin(); 
+	auto iforce = grad.begin(); 
+	auto eforce = grad.end(); 
+
+	auto gs = sum.get_grad_helper().second; 
+	while (iforce != eforce) {
+		auto expect = *iag * gs.get_gradient_scale(*ia2, *ib2); 
+		BOOST_CHECK_CLOSE(iforce->x, expect.x, 0.01); 
+		BOOST_CHECK_CLOSE(iforce->y, expect.y, 0.01); 
+		++iag; ++ia2; ++ib2; ++iforce;
+	}
+}
+
+
+BOOST_AUTO_TEST_CASE( test_masked_ncc_nonzero_with_mask ) 
+{
+        C2DBounds size(4,4); 
+        auto ncc = BOOST_TEST_create_from_plugin<CNCC2DImageCostPlugin>("ncc");
+        
+        C2DFImage a(size); 
+        C2DFImage b(size); 
+        C2DBitImage mask(size); 
+
+        fill(mask.begin(), mask.end(), true); 
+	mask(2,3) = false; 
+	mask(1,2) = false; 
+        
+        auto ia = a.begin_range(C2DBounds::_0, size); 
+        auto ib = b.begin_range(C2DBounds::_0, size); 
+        auto im = mask.begin_range(C2DBounds::_0, size); 
+        auto ea = a.end_range(C2DBounds::_0, size); 
+
+        NCCSums sum; 
+
+        while (ia != ea) {
+		if (*im) {
+			*ia = ia.pos().x + ia.pos().y; 
+			*ib = ia.pos().x * ia.pos().y; 
+			sum.add(*ia, *ib); 
+		}
+                ++ib; ++ia; ++im; 
+        }
+
+        ncc->set_reference(b); 
+        BOOST_CHECK_CLOSE(ncc->value(a, mask), sum.value(), 0.1); 
+        
+        C2DFVectorfield grad(size); 
+
+        BOOST_CHECK_CLOSE(ncc->evaluate_force(a, mask, grad), sum.value(), 0.01);
+
+
+	auto ag = get_gradient(a); 
+	
+	auto iag = ag.begin(); 
+	auto ia2 = a.begin(); 
+	auto ib2 = b.begin(); 
+	auto im2 = mask.begin(); 
+	auto iforce = grad.begin(); 
+	auto eforce = grad.end(); 
+
+	auto gs = sum.get_grad_helper().second; 
+	while (iforce != eforce) {
+		if (*im2) {
+			auto expect = *iag * gs.get_gradient_scale(*ia2, *ib2); 
+			BOOST_CHECK_CLOSE(iforce->x, expect.x, 0.01); 
+			BOOST_CHECK_CLOSE(iforce->y, expect.y, 0.01); 
+		}else{
+			BOOST_CHECK_SMALL(iforce->x, 1e-8f); 
+			BOOST_CHECK_SMALL(iforce->y, 1e-8f); 
+		}
+		++iag; ++ia2; ++ib2; ++iforce; ++im2; 
+	}
+}
+
diff --git a/mia/2d/maskedcost/test_ssd.cc b/mia/2d/maskedcost/test_ssd.cc
new file mode 100644
index 0000000..a5249c7
--- /dev/null
+++ b/mia/2d/maskedcost/test_ssd.cc
@@ -0,0 +1,153 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <mia/2d/maskedcost/ssd.hh>
+#include <cmath>
+
+
+NS_MIA_USE
+using namespace std;
+using namespace ::boost::unit_test;
+using namespace NS;
+
+
+class SSDFixture {
+protected: 
+	SSDFixture(); 
+	
+	
+	C2DBounds size; 
+	P2DImage src; 
+	P2DImage ref; 
+	C2DBitImage mask; 
+	C2DFVectorfield grad; 
+	unique_ptr<C2DSSDMaskedImageCost> cost; 
+
+	double test_cost_pair; 
+}; 
+
+
+BOOST_FIXTURE_TEST_CASE( test_SSD_2D_self, SSDFixture )
+{
+	cost->set_reference(*ref);
+	
+	const double test_cost_value =-0.0; 
+
+	double cost_value = cost->value(*ref, mask);
+	BOOST_CHECK_CLOSE(cost_value, test_cost_value, 0.1);
+
+	C2DFVectorfield force(C2DBounds(8,8));
+	
+	BOOST_CHECK_CLOSE(cost->evaluate_force(*ref, mask, force), 1.0 * test_cost_value, 0.1);
+	
+	for(auto g : force) {
+		BOOST_CHECK_EQUAL(g, C2DFVector(0,0));
+	}
+}
+
+BOOST_FIXTURE_TEST_CASE( test_SSD_2D_pair, SSDFixture )
+{
+	cost->set_reference(*ref);
+	
+	double cost_value = cost->value(*src, mask);
+	BOOST_CHECK_CLOSE(cost_value, test_cost_pair, 0.1);
+
+	C2DFVectorfield force(C2DBounds(8,8));
+	
+	BOOST_CHECK_CLOSE(cost->evaluate_force(*src, mask, force), test_cost_pair, 0.1);
+
+	for(auto iforce = force.begin(), iexpect = grad.begin(); iforce != force.end(); 
+	    ++iforce, ++iexpect) {
+		BOOST_CHECK_CLOSE(iforce->x, iexpect->x, 0.1);
+		BOOST_CHECK_CLOSE(iforce->y, iexpect->y, 0.1);
+	} 
+}
+
+
+SSDFixture::SSDFixture():
+	size(8,8),
+	mask(size),
+	grad(size) 
+{
+	const float src_data[64] = {           /*   0  1  2  3  4  5  6  7  8  9     */    
+		1, 1, 2, 2, 2, 3, 4, 4,        /*1                                 0 */
+		4, 4, 3, 3, 2, 2, 2, 1,        /*2     1  2  1  1     1            6 */
+		2, 2, 3, 4, 5, 6, 7, 8,        /*3        1  2     1  1  1  1      7 */
+		8, 7, 2, 8, 3, 4, 2, 2,        /*4     1     1  1     2  1  1      7 */ 
+		3, 1, 3, 4, 5, 6, 7, 8,        /*5     1     2  1        2  1      7 */
+		3, 4, 4, 5, 6, 4, 2, 2,        /*6        3     3     1            7 */
+	        3, 2, 3, 4, 5, 3, 1, 4,        /*7     1  1  2  2  1               7 */
+		5, 6, 7, 3, 2, 1, 2, 6         /*8     1  2  1        2  1         7 */
+	};                                     /*      5  9  9  8  2  7  5  3        */
+	
+	const float ref_data[64] = {
+		1, 1, 1, 5, 1, 1, 1, 1, 
+		2, 2, 2, 7, 2, 2, 2, 2,
+		3, 3, 3, 5, 3, 3, 3, 3, 
+		4, 4, 6, 4, 3, 4, 4, 4,
+		5, 5, 5, 6, 4, 2, 1, 5, 
+		6, 6, 4, 5, 6, 6, 6, 6,
+	        7, 7, 7, 7, 7, 5, 7, 7, 
+		8, 8, 8, 8, 8, 8, 8, 8
+	};
+
+	const float mask_data[64] = {
+		0, 0, 0, 0, 0, 0, 0, 0, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+	        0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1
+	};
+
+
+	
+
+	copy(mask_data, mask_data + 64, mask.begin()); 
+	auto src_f = new C2DFImage(size, src_data ); 
+	src.reset(src_f);
+	auto ref_f = new C2DFImage(size, ref_data ); 
+	ref.reset(ref_f);
+	
+
+	grad = get_gradient(*src_f); 
+
+	auto ig = grad.begin(); 
+	auto is = src_f->begin(); 
+	auto ir = ref_f->begin(); 
+	auto im = mask.begin(); 
+	auto em = mask.end(); 
+
+	test_cost_pair = 0.0; 
+	while(im != em) {
+		double delta = (*is - *ir); 
+		*ig *= *im * delta / 64.0; 
+		if (*im) 
+			test_cost_pair += delta * delta; 
+
+		++ig; ++is; ++ir; ++im; 
+	}
+	test_cost_pair /= 128.0; 
+	
+	cost.reset(new 	C2DSSDMaskedImageCost); 
+}
diff --git a/mia/2d/matrix.hh b/mia/2d/matrix.hh
index bfee459..2616139 100644
--- a/mia/2d/matrix.hh
+++ b/mia/2d/matrix.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/model.cc b/mia/2d/model.cc
index f38bb72..e4e4d7e 100644
--- a/mia/2d/model.cc
+++ b/mia/2d/model.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/model.hh b/mia/2d/model.hh
index 71c4fdc..b3e06e0 100644
--- a/mia/2d/model.hh
+++ b/mia/2d/model.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -61,8 +61,18 @@ typedef TFactory<C2DRegModel>  C2DRegModelPlugin;
    @ingroup registration 
    @brief Plugin handler for the 2D registration model. 
 */
+
+template <> const char *  const TPluginHandler<C2DRegModelPlugin>::m_help; 
+
 typedef THandlerSingleton< TFactoryPluginHandler<C2DRegModelPlugin> > C2DRegModelPluginHandler;
 
+extern template class EXPORT_2D TRegModel<2>;
+extern template class EXPORT_2D TPlugin<C2DImage, regmodel_type>;
+extern template class EXPORT_2D TFactory<C2DRegModel>;
+extern template class EXPORT_2D TFactoryPluginHandler<C2DRegModelPlugin>;
+extern template class EXPORT_2D THandlerSingleton< TFactoryPluginHandler<C2DRegModelPlugin> >; 
+
+
 NS_MIA_END
 
 #endif
diff --git a/mia/2d/model/CMakeLists.txt b/mia/2d/model/CMakeLists.txt
index 08d4e0e..542b8b2 100644
--- a/mia/2d/model/CMakeLists.txt
+++ b/mia/2d/model/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/model/identity.cc b/mia/2d/model/identity.cc
index 562d897..6f33412 100644
--- a/mia/2d/model/identity.cc
+++ b/mia/2d/model/identity.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/model/identity.hh b/mia/2d/model/identity.hh
index ea32861..038b181 100644
--- a/mia/2d/model/identity.hh
+++ b/mia/2d/model/identity.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/model/navier.cc b/mia/2d/model/navier.cc
index ddfbf25..53e174e 100644
--- a/mia/2d/model/navier.cc
+++ b/mia/2d/model/navier.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/model/navier.hh b/mia/2d/model/navier.hh
index 1fb5f08..2171351 100644
--- a/mia/2d/model/navier.hh
+++ b/mia/2d/model/navier.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/model/naviera.cc b/mia/2d/model/naviera.cc
index 8fadb3f..98712cd 100644
--- a/mia/2d/model/naviera.cc
+++ b/mia/2d/model/naviera.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -175,7 +175,6 @@ C2DNavierRegModelPlugin::C2DNavierRegModelPlugin():
 	m_epsilon(0.0001),
 	m_maxiter(100)
 {
-	typedef CParamList::PParameter PParameter;
 	add_parameter("mu", new CFloatParameter(m_mu, 0.0, numeric_limits<float>::max(),
 							   false, "isotropic compliance"));
 	add_parameter("lambda", new CFloatParameter(m_lambda, 0.0, numeric_limits<float>::max(),
diff --git a/mia/2d/model/naviera.hh b/mia/2d/model/naviera.hh
index 2c6f5d7..7fd824c 100644
--- a/mia/2d/model/naviera.hh
+++ b/mia/2d/model/naviera.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/model/test_identity.cc b/mia/2d/model/test_identity.cc
index 07fee9f..7eaf688 100644
--- a/mia/2d/model/test_identity.cc
+++ b/mia/2d/model/test_identity.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/model/test_navier.cc b/mia/2d/model/test_navier.cc
index b052b1a..d0244f9 100644
--- a/mia/2d/model/test_navier.cc
+++ b/mia/2d/model/test_navier.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/model/test_naviera.cc b/mia/2d/model/test_naviera.cc
index 0e44c73..498902a 100644
--- a/mia/2d/model/test_naviera.cc
+++ b/mia/2d/model/test_naviera.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/modelsolverreg.cc b/mia/2d/modelsolverreg.cc
index 8526ce9..5b1f867 100644
--- a/mia/2d/modelsolverreg.cc
+++ b/mia/2d/modelsolverreg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/modelsolverreg.hh b/mia/2d/modelsolverreg.hh
index a5fb605..425f3d8 100644
--- a/mia/2d/modelsolverreg.hh
+++ b/mia/2d/modelsolverreg.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/morphshape.cc b/mia/2d/morphshape.cc
index fa4e1a3..45c93c7 100644
--- a/mia/2d/morphshape.cc
+++ b/mia/2d/morphshape.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/morphshape.hh b/mia/2d/morphshape.hh
index de9f7bd..a7ab808 100644
--- a/mia/2d/morphshape.hh
+++ b/mia/2d/morphshape.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/multicost.cc b/mia/2d/multicost.cc
index aef660f..e2c153a 100644
--- a/mia/2d/multicost.cc
+++ b/mia/2d/multicost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/multicost.hh b/mia/2d/multicost.hh
index 16537d0..32d38b5 100644
--- a/mia/2d/multicost.hh
+++ b/mia/2d/multicost.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/nfg.cc b/mia/2d/nfg.cc
index 6846db0..6e2fec8 100644
--- a/mia/2d/nfg.cc
+++ b/mia/2d/nfg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/nfg.hh b/mia/2d/nfg.hh
index 808c723..e2483b1 100644
--- a/mia/2d/nfg.hh
+++ b/mia/2d/nfg.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/nonrigidregister.cc b/mia/2d/nonrigidregister.cc
index efde13f..70ebceb 100644
--- a/mia/2d/nonrigidregister.cc
+++ b/mia/2d/nonrigidregister.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/nonrigidregister.hh b/mia/2d/nonrigidregister.hh
index 0754af5..52047aa 100644
--- a/mia/2d/nonrigidregister.hh
+++ b/mia/2d/nonrigidregister.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/perfusion.cc b/mia/2d/perfusion.cc
index eb3ce0c..1f151b0 100644
--- a/mia/2d/perfusion.cc
+++ b/mia/2d/perfusion.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -67,7 +67,8 @@ struct C2DPerfusionAnalysisImpl {
 	size_t m_length; 
 	int m_ica_approach; 
 	bool m_use_guess_model; 
-	CAttributedData m_image_attributes; 
+	C2DFImage m_image_attributes; 
+	float m_min_movement_frequency;  
 };
 
 
@@ -100,6 +101,14 @@ void C2DPerfusionAnalysis::set_max_ica_iterations(size_t maxiter)
 	impl->m_max_iterations = maxiter; 
 }
 
+void C2DPerfusionAnalysis::set_min_movement_frequency(float min_freq) 
+{
+	assert(impl); 
+	impl->m_min_movement_frequency = min_freq; 
+}
+
+
+
 void C2DPerfusionAnalysis::set_approach(size_t approach)
 {
 	assert(impl); 
@@ -149,7 +158,8 @@ C2DPerfusionAnalysisImpl::C2DPerfusionAnalysisImpl(size_t components,
 	m_max_iterations(0),
 	m_length(0), 
 	m_ica_approach(FICA_APPROACH_DEFL), 
-	m_use_guess_model(false)
+	m_use_guess_model(false), 
+	m_min_movement_frequency(-1)
 {
 }
 
@@ -275,7 +285,7 @@ bool C2DPerfusionAnalysisImpl::run_ica(const vector<C2DFImage>& series)
 		if (!ica->run(m_components, m_meanstrip, m_normalize, guess) && 
 		    (m_ica_approach == FICA_APPROACH_DEFL))
 			return false; 
-		m_cls = CWaveletSlopeClassifier(ica->get_mixing_curves(), false);
+		m_cls = CWaveletSlopeClassifier(ica->get_mixing_curves(), false, m_min_movement_frequency);
 		if (m_cls.result() != CWaveletSlopeClassifier::wsc_fail)
 			has_one = true;
 	} else {
@@ -291,7 +301,7 @@ bool C2DPerfusionAnalysisImpl::run_ica(const vector<C2DFImage>& series)
 				continue; 
 			}
 
-			CWaveletSlopeClassifier cls(l_ica->get_mixing_curves(), false);
+			CWaveletSlopeClassifier cls(l_ica->get_mixing_curves(), false, m_min_movement_frequency);
 			size_t movement_components  = cls.get_number_of_movement_components();
 			if (cls.result() == CWaveletSlopeClassifier::wsc_fail) {
 				// save this since we can still process without bounding box creation 
@@ -495,7 +505,20 @@ retry:
 	cvinfo() << "RV center = " << RV_center << "\n";
 	cvinfo() << "LV center = " << LV_center << "\n";
 
-	float r = LV_mask_amplify * (LV_center - RV_center).norm();
+	C2DFVector delta_center = LV_center - RV_center; 
+	
+	C2DFVector physical_distance2d = m_image_attributes.get_pixel_size() * delta_center; 
+	float physical_distance = physical_distance2d.norm(); 
+
+	cvinfo() << "LV-RV center distance = " << physical_distance << "\n";
+	if ( physical_distance < 30.0) {
+		cvwarn() << "Distance between LV and RV centers < 3cm, assuming bad segmentation\n"; 
+		return P2DFilter();		
+	}
+	
+
+
+	float r = LV_mask_amplify * delta_center.norm();
 	cvinfo() << "r = " << r << "\n";
 	stringstream mask_lv;
 	crop_start = C2DBounds(int(LV_center.x - r), int(LV_center.y - r));
@@ -572,6 +595,18 @@ P2DFilter C2DPerfusionAnalysisImpl::create_LV_cropper_from_features(float LV_mas
 	cvinfo() << "RV center = " << RV_center << "\n";
 	cvinfo() << "LV center = " << LV_center << "\n";
 
+	C2DFVector delta_center = LV_center - RV_center; 
+	
+	C2DFVector physical_distance2d = m_image_attributes.get_pixel_size() * delta_center; 
+	float physical_distance = physical_distance2d.norm(); 
+	cvinfo() << "LV-RV center distance = " << physical_distance << "\n";
+
+	if ( physical_distance < 30.0) {
+		cvwarn() << "Distance between LV and RV centers < 3cm, assuming bad segmentation\n"; 
+		return P2DFilter();		
+	}
+
+
 	float r = LV_mask_amplify * (LV_center - RV_center).norm();
 	cvinfo() << "r = " << r << "\n";
 	stringstream mask_lv;
diff --git a/mia/2d/perfusion.hh b/mia/2d/perfusion.hh
index 20026f3..5744064 100644
--- a/mia/2d/perfusion.hh
+++ b/mia/2d/perfusion.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -130,6 +130,15 @@ public:
 	int get_LV_idx() const; 
 
 
+	/**
+	   Set the minimum mean frequency (in breath per heart beat) that decides whether a slope is 
+	   considered to be periodic. 
+	   \param min_freq The new minimum frequency, a value < 0.0 disables the test (this is the default) 
+	   \remark this values is simply passed through to the wavelet slope classifier 
+	 */
+	void set_min_movement_frequency(float min_freq); 
+
+
         /**
 	   \returns the perfusion enhancement IC index of -1 if it could not be identified
 	*/
diff --git a/mia/2d/polygon.cc b/mia/2d/polygon.cc
index 664b6fa..e07b957 100644
--- a/mia/2d/polygon.cc
+++ b/mia/2d/polygon.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/polygon.hh b/mia/2d/polygon.hh
index 740a634..e9a444b 100644
--- a/mia/2d/polygon.hh
+++ b/mia/2d/polygon.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/ppmatrix.cc b/mia/2d/ppmatrix.cc
index 5ed68e1..068a376 100644
--- a/mia/2d/ppmatrix.cc
+++ b/mia/2d/ppmatrix.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/ppmatrix.hh b/mia/2d/ppmatrix.hh
index d5427dc..4f24a7c 100644
--- a/mia/2d/ppmatrix.hh
+++ b/mia/2d/ppmatrix.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/register.cc b/mia/2d/register.cc
index 372da12..8b2bf2d 100644
--- a/mia/2d/register.cc
+++ b/mia/2d/register.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/register.hh b/mia/2d/register.hh
index b4fed17..3555311 100644
--- a/mia/2d/register.hh
+++ b/mia/2d/register.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/rgbimageio.cc b/mia/2d/rgbimageio.cc
index b7c9bf1..36e93b9 100644
--- a/mia/2d/rgbimageio.cc
+++ b/mia/2d/rgbimageio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/rgbimageio.hh b/mia/2d/rgbimageio.hh
index 05eff92..b094f41 100644
--- a/mia/2d/rgbimageio.hh
+++ b/mia/2d/rgbimageio.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
  */
 
 #ifndef mia_2d_rgbimageio_hh
-#define mia_2drgbimageio_hh
+#define mia_2d_rgbimageio_hh
 
 #include <vector>
 #include <mia/2d/defines2d.hh>
diff --git a/mia/2d/rgbio/CMakeLists.txt b/mia/2d/rgbio/CMakeLists.txt
index 768ae9a..9906a78 100644
--- a/mia/2d/rgbio/CMakeLists.txt
+++ b/mia/2d/rgbio/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/rgbio/bmp.cc b/mia/2d/rgbio/bmp.cc
index bc03c1f..da180bd 100644
--- a/mia/2d/rgbio/bmp.cc
+++ b/mia/2d/rgbio/bmp.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/rigidregister.cc b/mia/2d/rigidregister.cc
index 7bab63a..8440011 100644
--- a/mia/2d/rigidregister.cc
+++ b/mia/2d/rigidregister.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/rigidregister.hh b/mia/2d/rigidregister.hh
index 6a37812..469fee0 100644
--- a/mia/2d/rigidregister.hh
+++ b/mia/2d/rigidregister.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/segframe.cc b/mia/2d/segframe.cc
new file mode 100644
index 0000000..6104227
--- /dev/null
+++ b/mia/2d/segframe.cc
@@ -0,0 +1,377 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdexcept>
+#include <string>
+#include <mia/2d/segframe.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/core/errormacro.hh>
+#include <mia/core/bfsv23dispatch.hh>
+#include <mia/2d/imageio.hh>
+#include <mia/2d/angle.hh>
+
+#include <libxml++/libxml++.h>
+#include <boost/filesystem.hpp> 
+
+
+
+NS_MIA_BEGIN
+using namespace std; 
+using namespace xmlpp; 
+
+namespace bfs=boost::filesystem; 
+
+CSegFrame::CSegFrame():
+	m_has_star(false), 
+	m_version(0)
+{
+}
+
+CSegFrame::CSegFrame(const string& image, const CSegStar& star, const Sections& sections):
+	m_has_star(true),
+	m_star(star), 
+	m_sections(sections),  
+	m_filename(image), 
+	m_quality(0),
+	m_brightness(0), 
+	m_contrast(0), 
+	m_version(0)
+
+{
+}
+
+
+CSegFrame::CSegFrame(const Node& node, int version):
+	m_has_star(false), 
+	m_quality(0),
+	m_brightness(0), 
+	m_contrast(0), 
+	m_version(version)
+{
+	TRACE("CSegFrame::CSegFrame"); 
+	const Element& elm = dynamic_cast<const Element&>(node); 
+		
+	if (elm.get_name() != "frame")
+		throw invalid_argument(string("CSegFrame: unexpected node type: ") + elm.get_name()); 
+	
+	const Attribute *attr = elm.get_attribute("image"); 
+	if (!attr) {
+		throw invalid_argument("CSegFrame: image attribute not found"); 
+	}
+	m_filename = attr->get_value(); 
+	
+	Node::NodeList nodes = elm.get_children(); 
+	
+	for (auto i = nodes.begin(); i != nodes.end(); ++i) {
+
+		if ((*i)->get_name() == "star") {
+			m_star = CSegStar(**i); 
+			m_has_star = true; 
+		}
+		else if ((*i)->get_name() == "section") {
+			m_sections.push_back(CSegSection(**i, version)); 
+		}else {
+			cvinfo() << "ignoring unsuported element '" << (*i)->get_name() << "'\n"; 
+		}
+	}
+	
+	if (version > 1) {
+		if (version == 2 && m_sections.size() > 2)
+			cvwarn() << "CSegFrame: gor a version 2 segmentation, but more then two sections, this may be bogus\n";
+			
+		read_attribute_from_node(elm, "quality", m_quality);  
+		read_attribute_from_node(elm, "brightness", m_brightness);  
+		read_attribute_from_node(elm, "contrast", m_contrast);  
+	}
+}
+
+const std::string& CSegFrame::get_imagename() const
+{
+	return m_filename; 
+}
+
+void CSegFrame::set_imagename(const std::string& name)
+{
+	m_filename = name; 
+}
+
+void CSegFrame::rename_base(const std::string& new_base)
+{
+	bfs::path filename(m_filename); 
+	string suffix = __bfs_get_extension(filename); 
+	string name = __bfs_get_stem(filename);
+	auto i = name.rbegin();
+	int k = 0; 
+	while (i != name.rend() && isdigit(*i) ) {
+		++i; 
+		++k; 
+	}
+	string number(name.end() - k, name.end()); 
+	m_filename = new_base + number + suffix; 
+}
+
+const CSegFrame::Sections& CSegFrame::get_sections()const
+{
+	return m_sections; 
+}
+
+
+const CSegStar& CSegFrame::get_star() const
+{
+	if (!m_has_star) 
+		cvwarn() << "CSegFrame::get_star(): returing fake star"; 
+	return m_star; 
+}
+
+
+void CSegFrame::write(Node& node, int version) const
+{
+	Element* self = node.add_child("frame"); 
+	self->set_attribute("image", m_filename); 	
+
+	if (version > 1) {
+		self->set_attribute("quality", to_string<float>(m_quality)); 	
+		self->set_attribute("brightness", to_string<float>(m_brightness)); 	
+		self->set_attribute("contrast", to_string<float>(m_contrast)); 	
+	}
+	
+	if (m_has_star) 
+		m_star.write(*self);
+	for (auto i = m_sections.begin(); 
+	     i != m_sections.end(); ++i) {
+		i->write(*self, version); 
+	}
+}
+
+const C2DBoundingBox CSegFrame::get_boundingbox() const
+{
+	C2DBoundingBox result; 
+	for (auto i = m_sections.begin(); 
+	     i != m_sections.end(); ++i) {
+		result.unite(i->get_boundingbox()); 
+	}
+	return result; 
+}
+
+void CSegFrame::shift(const C2DFVector& delta, const std::string& cropped_file)
+{
+	if (m_has_star) 
+		m_star.shift(delta); 
+	for (auto i = m_sections.begin(); 
+	     i != m_sections.end(); ++i)
+		i->shift(delta); 
+	m_filename = cropped_file; 
+}
+
+void CSegFrame::transform(const C2DTransformation& t)
+{
+	if (m_has_star) 
+		m_star.transform(t); 
+	for (auto i = m_sections.begin(); 
+	     i != m_sections.end(); ++i)
+		i->transform(t); 
+}
+
+void CSegFrame::set_image(P2DImage image)
+{
+	m_image = image; 
+}
+
+
+void CSegFrame::inv_transform(const C2DTransformation& t)
+{
+	if (m_has_star) 
+		m_star.inv_transform(t); 
+	for (auto i = m_sections.begin(); i != m_sections.end(); ++i)
+		i->inv_transform(t); 
+}
+
+
+float CSegFrame::get_hausdorff_distance(const CSegFrame& other) const
+{
+	C2DPolygon p1; 
+	for(auto s = m_sections.begin(); 
+	    s != m_sections.end(); ++s) 
+		s->append_to(p1); 
+
+
+	C2DPolygon p2; 
+	for(auto s = other.m_sections.begin(); 
+	    s != other.m_sections.end(); ++s) 
+		s->append_to(p2); 
+
+	return p1.get_hausdorff_distance(p2); 
+}
+
+
+C2DUBImage CSegFrame::get_section_masks(const C2DBounds& size) const 
+{
+	C2DUBImage result(size); 
+	if (m_version == 2) {
+		// in version 2 all sections are xor-ed,
+		for (auto i = m_sections.begin(); 
+		     i != m_sections.end(); ++i)
+			i->draw_xor(result); 
+	}else {
+		unsigned char idx = 1; 
+		for (auto i = m_sections.begin(); 
+		     i != m_sections.end(); ++i, ++idx)
+			i->draw(result, idx); 
+	}
+	return result; 
+}
+
+void CSegFrame::load_image() const
+{
+	m_image = load_image2d(m_filename); 
+	if (!m_image) 
+		throw create_exception<runtime_error>( "unable to find image file '", m_filename, "'");
+}
+
+C2DUBImage CSegFrame::get_section_masks() const
+{
+	if (!m_image)
+                load_image(); 
+	return get_section_masks(m_image->get_size()); 
+}
+
+C2DUBImage CSegFrame::get_section_masks(size_t n_sections) const
+{
+	if (!m_image) 		
+		load_image(); 
+	C2DUBImage result = get_section_masks(m_image->get_size()); 
+	if (n_sections != 0 && n_sections != m_sections.size()) {
+		const C2DFVector ray_a = m_star.m_directions[0]; 
+		
+		const double scale = n_sections / (2 * M_PI); 
+		
+		// make a mask and re-run 
+		auto i = result.begin(); 
+		for (size_t y = 0; y < result.get_size().y; ++y)  {
+			for (size_t x = 0; x < result.get_size().x; ++x, ++i)  {
+				if (*i) {
+					const C2DFVector ray_b(static_cast<float>(x) - m_star.m_center.x, 
+							       static_cast<float>(y) - m_star.m_center.y); 
+					double a = scale * angle(ray_a, ray_b);
+					if (a >= n_sections) 
+						a -= n_sections; 
+					*i = (unsigned char) (a + 1.0); 
+				}
+			}
+		}
+	}
+	return result; 
+}
+
+struct EvalMaskStat: public TFilter<CSegFrame::SectionsStats> {
+
+	EvalMaskStat(const C2DUBImage& mask):
+		m_mask(mask) {
+		max_idx = *max_element(mask.begin(), mask.end());
+	}; 
+	
+	template <typename T> 
+	CSegFrame::SectionsStats operator ()(const T2DImage<T>& image) const {
+		CSegFrame::SectionsStats result(max_idx); 
+		vector<size_t> size(max_idx, 0); 
+		auto k = image.begin();
+		for(auto m=m_mask.begin(); m != m_mask.end(); ++k, ++m) {
+			const double v = *k;
+			if (*m) {
+				result[*m-1].first  += v; 
+				result[*m-1].second += v * v; 
+				++size[*m-1]; 
+			}
+		}
+		auto n=size.begin();
+		for (auto i = result.begin(); i != result.end(); ++i, ++n) {
+			if (*n) 
+				i->first /= *n; 
+			if (*n > 1) 
+				i->second = sqrt( (i->second - i->first * i->first * *n)/ (*n - 1)); 
+		}
+		return result; 
+	}
+private: 
+	const C2DUBImage& m_mask; 
+	unsigned char max_idx; 
+}; 
+
+CSegFrame::SectionsStats CSegFrame::get_stats(const C2DUBImage& mask) const
+{
+	if (!m_image)
+		load_image(); 
+	if (mask.get_size() != m_image->get_size()) 
+		throw create_exception<invalid_argument>( "Mask image ",mask.get_size(), " and data image ", 
+						m_image->get_size(), " are of different size");
+	
+	return ::mia::filter(EvalMaskStat(mask), *m_image);  
+
+
+}
+
+CSegFrame::SectionsStats CSegFrame::get_stats(size_t n_sections) const
+{
+	if (!m_image) {
+		m_image = load_image2d(m_filename); 
+		if (!m_image) 
+			throw create_exception<runtime_error>( "unable to find image file '", m_filename, "'");
+	}
+	C2DUBImage mask = get_section_masks(n_sections); 
+	return get_stats(mask); 
+}
+
+size_t CSegFrame::get_nsections() const
+{
+	return m_sections.size(); 
+}
+
+void CSegFrame::set_quality(float q)
+{
+	m_quality = q; 
+}
+
+void CSegFrame::set_brightness(float b)
+{
+	m_brightness = b; 
+}
+
+void CSegFrame::set_contrast(float c) 
+{
+	m_contrast = c; 
+}
+
+float CSegFrame::get_quality() const
+{
+	return m_quality; 
+}
+
+float CSegFrame::get_brightness() const
+{
+	return m_brightness; 
+}
+
+float CSegFrame::get_contrast() const
+{
+	return m_contrast; 
+}
+
+
+NS_MIA_END
diff --git a/mia/2d/segframe.hh b/mia/2d/segframe.hh
new file mode 100644
index 0000000..04e95c0
--- /dev/null
+++ b/mia/2d/segframe.hh
@@ -0,0 +1,240 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef SegFrame_h
+#define SegFrame_h
+
+#include <vector>
+#include <mia/2d/segstar.hh>
+#include <mia/2d/segsection.hh>
+#include <mia/2d/image.hh>
+
+NS_MIA_BEGIN
+
+/**
+   @ingroup perf 
+   \brief A class to represent one segmented frame in a heart perfusion series 
+   
+   This class implements the frame of a myocardial segmentation consisting of 
+   six sections CSegsection, the segmentation helper CSegStar, and the name of the 
+   corresponding image file.  
+*/
+class  EXPORT_2D CSegFrame {
+public:
+	/// convenience typedef for the sections 
+	typedef std::vector<CSegSection> Sections;
+	
+	/** convenience typedef for the statistics values  
+	    @remark maybe a type with more meaningful elements would be better 
+	 */ 
+	typedef std::pair<float, float> Statistics; 
+	
+	/// convenience typedef for the section statistics vector 
+	typedef std::vector<Statistics> SectionsStats; 
+	
+	
+	CSegFrame();
+
+	/**
+	   Construct the segmentation frame from 
+	   \param image image file name 
+	   \param star CSegStar 
+	   \param sections the segmentation sections 
+	 */
+	CSegFrame(const std::string& image, const CSegStar& star, const Sections& sections);
+
+	/**
+	   Construct the segmentation frame from a XML root node
+	   \param node
+	   \param version segmentation set version the node stems from. 
+	 */
+	CSegFrame(const xmlpp::Node& node, int version);
+
+	/// \returns the file name of the corresponding image 
+	const std::string& get_imagename() const;
+
+	/** set the file name of the corresponding image 
+	    \param name 
+	 */
+	void set_imagename(const std::string& name);
+
+	/** rename the file name base of the image according to 
+	    sed -e "s/.*[^0-9]\([0-9]*\..*\)/$new_base\1/"
+	    \param new_base
+	 */
+	void rename_base(const std::string& new_base); 
+
+	/// \returns a read-only reference to the segmentation sections 
+	const Sections& get_sections() const;
+
+	/**
+	   Set the image corresponding to the segmentation frame 
+	   @param image 
+	 */
+	void set_image(P2DImage image); 
+
+	/**
+	   @returns the star of the LV contained in this frame 
+	 */
+	const CSegStar& get_star() const;
+
+	/// @returns the bounding box enclosing all segmentation sections belonging to thie frame 
+	const C2DBoundingBox get_boundingbox() const;
+
+
+	/**
+	   Append the segmentation frame to a XML node 
+	   @param node parent node to append the frame description to 
+	   @param version segmentation set file version that should be used to save the data
+	 */
+	void write(xmlpp::Node& node, int version) const;
+
+	/**
+	   Shift the segmentation frame and change the file name to the new name 
+	   corresponding to the shifted image 
+	   @param delta translation 
+	   @param cropped_file new image file name 
+	*/
+	void shift(const C2DFVector& delta, const std::string& cropped_file);
+
+
+	/**
+	   transform the frame segmentation by a given transformation 
+	   @param t 
+	 */
+	void transform(const C2DTransformation& t);
+
+	/**
+	   transform the frame segmentation by the inverse of the given transformation 
+	   @param t 
+	 */
+	void inv_transform(const C2DTransformation& t);
+
+	/**
+	   Evaluate the Hausdorff distance of this segmentation frame to another 
+	   @param other 
+	   @returns Hausdorff distance
+	 */
+	float get_hausdorff_distance(const CSegFrame& other) const;
+
+
+	/**
+	   Evaluate a mask image based on the segmented sections
+	   @param size size of the output image 
+	   @returns an image containing the masks for each section  numbered in the storage 
+	   order of the sections
+	   @remark If overlap exists between the sections the masks with a higher index overwrite 
+	   the masks with a lower index. 
+	 */
+	C2DUBImage get_section_masks(const C2DBounds& size) const; 
+
+	/**
+	   Create the section masks by using the size of the image corresponding to the frame 
+	   @returns the mask image, for details see get_section_masks(const C2DBounds& size). 
+	 */
+	C2DUBImage get_section_masks() const; 
+
+	/**
+	   Create the section masks by using the size of the image corresponding to the frame. 
+	   If the number of requested sections is equal to the number of sections stored, this 
+	   call is equal to get_section_masks(), 
+           Otherwiese, instead of using the sections as defined, evaluate the union of all the sections 
+	   and then split this union evenly in \a n_sections starting by the first directional ray 
+	   and moving clockwiese with the star center as the angular point. 
+	   @param n_sections number of target sections 
+	   @returns the mask image, for details see get_section_masks(const C2DBounds& size). 
+	 */
+	C2DUBImage get_section_masks(size_t n_sections) const; 
+
+
+	/**
+	   Evaluate inetnsity mean and variation of the image data for the registions  
+	   defined by the given mask image. 
+	   @param mask 
+	   @returns the statustics 
+	 */
+	SectionsStats get_stats(const C2DUBImage& mask) const; 
+	
+	/**
+	   Evaluate inetnsity mean and variation of the image data for the registions  
+	   defined the get_section_masks(size_t n_sections) method. 
+	   @param n_sections 
+	   @returns the statustics 
+	 */
+	SectionsStats get_stats(size_t n_sections) const; 
+
+	/**
+	   \returns number of segmented sections 
+	 */
+	size_t get_nsections() const; 
+
+	/**
+	   \returns slice quality rating 
+	 */
+	float get_quality() const; 
+
+	/**
+	   \returns proposed brightness correction 
+	 */
+	float get_brightness() const; 
+	
+         /**
+	    \returns proposed contrast correction 
+	 */
+	float get_contrast() const; 
+
+
+	/**
+	   set the quality rating for the frame 
+	   \param q 0=not set, 1-5 worst to best 
+	 */
+	void set_quality(float q); 
+
+	/**
+	   set the brightness adjustment for the frame 
+	   \param b 0=no adjustment 
+	 */
+	void set_brightness(float b); 
+	
+         /**
+	    set contrast adjustment 
+	    \param c 0=no adjustment 
+	 */
+	void set_contrast(float c); 
+	
+private:
+	void load_image() const; 
+
+	bool m_has_star;
+	CSegStar m_star;
+	Sections m_sections;
+	std::string m_filename;
+	mutable P2DImage m_image; 
+
+	float m_quality; 
+	float m_brightness; 
+	float m_contrast; 
+	int m_version; 
+};
+
+NS_MIA_END
+
+#endif
+
diff --git a/mia/2d/segpoint.cc b/mia/2d/segpoint.cc
new file mode 100644
index 0000000..8934bf7
--- /dev/null
+++ b/mia/2d/segpoint.cc
@@ -0,0 +1,120 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sstream>
+#include <stdexcept>
+#include <cassert>
+#include <mia/2d/segpoint.hh>
+#include <mia/core/tools.hh>
+#include <libxml++/libxml++.h>
+
+NS_MIA_BEGIN
+
+using namespace xmlpp;
+using namespace std;
+
+void read_attribute_from_node(const Element& elm, const std::string& key, bool& out_value, bool required)
+{
+	auto attr = elm.get_attribute(key);
+	if (!attr) {
+		if (required) 
+			throw create_exception<runtime_error>( elm.get_name(), ":required attribute '", key, "' not found"); 
+		else
+			return; 
+	}
+	
+	if (attr->get_value() == string("false")) 
+		out_value = false; 
+	else if (attr->get_value() == string("true")) 
+		out_value = true; 
+	else 
+		throw create_exception<runtime_error>( elm.get_name(), ":attribute '", key, "' has bogus value '", 
+						       attr->get_value(), "'");
+}
+
+CSegPoint2D::CSegPoint2D()
+{
+}
+
+CSegPoint2D::CSegPoint2D(const C2DFVector& org): C2DFVector(org)
+{
+}
+
+	
+CSegPoint2D& CSegPoint2D::operator = (const C2DFVector& org)
+{
+	C2DFVector::operator =(org); 
+	return *this; 
+}
+
+
+CSegPoint2D::CSegPoint2D(float x, float y):
+	C2DFVector(x,y)
+{
+}
+
+CSegPoint2D::CSegPoint2D(const Node& node)
+{
+	const Element& elm = dynamic_cast<const Element&>(node);
+	Attribute *ax = elm.get_attribute ("x");
+	Attribute *ay = elm.get_attribute ("y");
+	if (!ax || !ay)
+		throw runtime_error("SegSection:Point attribute x or y not found");
+	
+	if (!from_string(ax->get_value(), x)) 
+		throw create_exception<runtime_error>( "CSegPoint2D: x attribute '", 
+					     ax->get_value(), "' is not a floating point value"); 
+
+	if (!from_string(ay->get_value(), y)) 
+		throw create_exception<runtime_error>( "CSegPoint2D: y attribute '", 
+					     ay->get_value(), "' is not a floating point value");
+}
+
+void CSegPoint2D::write(Node& node) const
+{
+	Element* point = node.add_child("point");
+	point->set_attribute("y", to_string<float>(y));
+	point->set_attribute("x", to_string<float>(x));
+}
+
+void CSegPoint2D::transform(const C2DTransformation& t)
+{
+	const C2DFVector r =  t(*this); 
+	x = r.x; 
+	y = r.y;
+}
+
+void CSegPoint2D::inv_transform(const C2DTransformation& t)
+{
+	C2DFVector r(x,y); 
+	cvdebug() << r << "\n"; 
+	int niter = 0; 
+	C2DFVector delta = t(r) - *this; 
+	while (delta.norm2() > 0.000001 && niter++ < 100) {
+		r -= 0.1 * delta; 
+		delta = t(r) - *this; 
+		cvdebug() << r << delta << "\n"; 
+	}
+	x = r.x; 
+	y = r.y; 
+}
+
+
+NS_MIA_END
diff --git a/mia/2d/segpoint.hh b/mia/2d/segpoint.hh
new file mode 100644
index 0000000..e46e160
--- /dev/null
+++ b/mia/2d/segpoint.hh
@@ -0,0 +1,106 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_2d_SegPoint_hh
+#define mia_2d_SegPoint_hh
+
+namespace xmlpp {
+	class Node;
+};
+
+#include <mia/2d/vector.hh>
+#include <mia/2d/defines2d.hh>
+#include <mia/2d/transform.hh>
+
+NS_MIA_BEGIN
+
+/**
+   @ingroup perf 
+   \brief a point in a 2D segmentation shape 
+
+   Point of a segmentation shape. In addition to be a 2D point it can be 
+   read from and written to a XML tree and supports its own tranformation. 
+*/
+
+class  EXPORT_2D CSegPoint2D: public C2DFVector {
+public:
+	CSegPoint2D();
+
+	/// copy constructor 
+	CSegPoint2D(const C2DFVector& org);
+
+	/// assignment operator 
+	CSegPoint2D& operator = (const C2DFVector& org);
+
+	/**
+	   Construct the point with the given coordinates
+	   \param x
+	   \param y
+	 */
+	CSegPoint2D(float x, float y);
+
+	/**
+	   Construct the point from a XML node
+	   \param node
+	 */
+	CSegPoint2D(const xmlpp::Node& node);
+
+	/** Write the point as child-node to a given XML tree
+	    \param node 
+	*/
+	void write(xmlpp::Node& node) const;
+
+	/**
+	   Tranform the point according to the given tranformation 
+	   \param t 
+	 */
+	void transform(const C2DTransformation& t); 
+	
+	/**
+	   Evaluate an approximation of the inverse of the given transform of the point
+	   \param t 
+
+	 */
+	void inv_transform(const C2DTransformation& t); 
+};
+
+
+template <typename T>
+void read_attribute_from_node(const xmlpp::Element& elm, const std::string& key, T& out_value, bool required = false)
+{
+	auto attr = elm.get_attribute(key);
+	if (!attr) {
+		if (required) 
+			throw create_exception<std::runtime_error>( elm.get_name(), ":required attribute '", key, "' not found"); 
+		else 
+			return; 
+	}
+	
+	if (!from_string(attr->get_value(), out_value)) 
+		throw create_exception<std::runtime_error>( elm.get_name(), ":attribute '", key, "' has bogus value '", 
+						       attr->get_value(), "'");
+}
+
+
+void read_attribute_from_node(const xmlpp::Element& elm, const std::string& key, bool& out_value, bool required = false); 
+
+NS_MIA_END
+
+#endif
diff --git a/mia/2d/segsection.cc b/mia/2d/segsection.cc
new file mode 100644
index 0000000..dfecd6a
--- /dev/null
+++ b/mia/2d/segsection.cc
@@ -0,0 +1,208 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define VSTREAM_DOMAIN "SegSection"
+#include <stdexcept>
+#include <mia/core/msgstream.hh>
+#include <mia/2d/segsection.hh>
+#include <libxml++/libxml++.h>
+
+
+NS_MIA_BEGIN
+using namespace std;
+
+CSegSection::CSegSection():
+	m_is_open(false)
+{
+}
+
+CSegSection::CSegSection(const string& id, const Points& points, bool is_open):
+	m_id(id),
+	m_points(points), 
+	m_is_open(is_open)
+{
+}
+
+CSegSection::CSegSection(xmlpp::Node& node, int version):
+	m_is_open(false)
+{
+	TRACE("CSegSection::CSegSection");
+
+	xmlpp::Element& elm = dynamic_cast<xmlpp::Element&>(node);
+	xmlpp::Attribute *id = elm.get_attribute ("color");
+
+	if (!id)
+		throw invalid_argument("CSegSection::CSegSection: node without id");
+	m_id = id->get_value();
+
+	xmlpp::Node::NodeList points = node.get_children("point");
+
+	for (auto i = points.begin(); i != points.end(); ++i)
+		m_points.push_back(CSegPoint2D(**i));
+
+	if (version > 1) {
+		read_attribute_from_node(elm, "open", m_is_open);  
+	}
+}
+
+const string& CSegSection::get_id() const
+{
+	return m_id;
+}
+
+const CSegSection::Points& CSegSection::get_points()const
+{
+	return m_points;
+}
+
+void CSegSection::shift(const C2DFVector& delta)
+{
+	Points::iterator ip = m_points.begin();
+	Points::iterator ep = m_points.end();
+
+	while (ip != ep) {
+		*ip -= delta;
+		++ip;
+	}
+}
+
+void CSegSection::transform(const C2DTransformation& t)
+{
+	for(auto i = m_points.begin(); i != m_points.end(); ++i) 
+		i->transform(t);
+}
+
+
+void CSegSection::inv_transform(const C2DTransformation& t)
+{
+	for(auto i = m_points.begin(); i != m_points.end(); ++i) 
+		i->inv_transform(t);
+}
+
+
+void CSegSection::write(xmlpp::Node& node, int version) const
+{
+	xmlpp::Element* nodeChild = node.add_child("section");
+	nodeChild->set_attribute("color", m_id);
+
+	if (version > 1) {
+		nodeChild->set_attribute("open", m_is_open ? "true" : "false");
+	}
+
+	Points::const_iterator ip = m_points.begin();
+	Points::const_iterator ep = m_points.end();
+
+	while (ip != ep) {
+		ip->write(*nodeChild);
+		++ip;
+	}
+}
+
+const C2DBoundingBox CSegSection::get_boundingbox() const
+{
+
+	C2DBoundingBox result;
+
+	Points::const_iterator ip = m_points.begin();
+	Points::const_iterator ep = m_points.end();
+
+	while (ip != ep) {
+		result.add(*ip++);
+	}
+	return result;
+}
+
+void CSegSection::append_to(C2DPolygon& polygon)const
+{
+	typedef std::vector<CSegPoint2D>::const_iterator point_iterator;
+	for(point_iterator i = m_points.begin(); i != m_points.end(); ++i)
+		polygon.append(*i);
+
+}
+
+float CSegSection::get_hausdorff_distance(const CSegSection& other) const
+{
+
+	C2DPolygon p1;
+	append_to(p1);
+
+	C2DPolygon p2;
+	other.append_to(p2);
+
+	return p1.get_hausdorff_distance(p2);
+}
+
+template <typename FDrawOperator> 
+void draw_private(C2DUBImage& mask, const CSegSection::Points& points,  const FDrawOperator& op)
+{
+	for (size_t y=0; y < mask.get_size().y; y++) {
+		vector<int> nodeX; 
+		int j=points.size()-1;
+		for (size_t i=0; i<points.size(); i++) {
+			if ((points[i].y <= y && points[j].y > y) || 
+			    (points[j].y <= y && points[i].y > y) ) {
+				nodeX.push_back( (int) (points[i].x + 
+						       ( y - points[i].y)/(points[j].y-points[i].y)
+							*(points[j].x - points[i].x)) + 0.5); 
+			}
+			j=i; 
+		}
+		
+		sort(nodeX.begin(), nodeX.end()); 
+		
+		//  Fill the pixels between node pairs.
+		for (size_t i=0; i<nodeX.size(); i+=2) {
+			if   (nodeX[i  ]>=(int)mask.get_size().x) 
+				break;
+			if   (nodeX[i+1]> 0 ) {
+				if (nodeX[i  ] < 0 ) 
+					nodeX[i  ]=0;
+				if (nodeX[i+1] > (int)mask.get_size().x) 
+					nodeX[i+1]=mask.get_size().x;
+				for (int j=nodeX[i]; j<nodeX[i+1]; j++) 
+					op(mask(j,y));
+			}
+		}
+	}
+	
+}
+
+void CSegSection::draw_xor(C2DUBImage& mask)const
+{
+	if (m_is_open) 
+		throw invalid_argument("CSegSection: Section not closed, hence no filled polygon can be drawn"); 
+	auto xor_draw = [](unsigned char& pixel) { pixel ^= 1 ;}; 
+	draw_private(mask, m_points, xor_draw); 
+}
+
+void CSegSection::draw(C2DUBImage& mask, unsigned char color)const
+{
+	if (m_is_open) 
+		throw invalid_argument("CSegSection: Section not closed, hence no filled polygon can be drawn"); 
+	auto color_draw = [color](unsigned char& pixel) { pixel = color;};
+	draw_private(mask, m_points, color_draw); 
+}
+
+bool CSegSection::is_open() const
+{
+	return m_is_open; 
+}
+
+NS_MIA_END
diff --git a/mia/2d/segsection.hh b/mia/2d/segsection.hh
new file mode 100644
index 0000000..20c7eda
--- /dev/null
+++ b/mia/2d/segsection.hh
@@ -0,0 +1,138 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef SegSection_h
+#define SegSection_h
+
+#include <vector>
+#include <string>
+
+#include <mia/2d/segpoint.hh>
+#include <mia/2d/boundingbox.hh>
+#include <mia/2d/polygon.hh>
+
+NS_MIA_BEGIN
+
+/**
+   @ingroup perf 
+   \brief Segmentation class to represent a section of the LV myocardium 
+
+   Structure to save the segmentation of a section of the myocardium. 
+   In theory this can be used for any king of segmentation that uses 
+   a polynom to approximate a segmented 2D shape. 
+*/
+
+
+class  EXPORT_2D CSegSection {
+public:
+	/// convenicence typedef for the points defining the section 
+	typedef std::vector<CSegPoint2D> Points;
+	
+	/// default constructor 
+	CSegSection();
+
+	/**
+	   Constructor to create a segmentation shape and naming it 
+	   @param id ID of the section (and color identifier) 
+	   @param points the points that define a closed polynom representing the shape 
+	   @param is_open describes if points should be interpreted as polygon 
+	   (i.e. the last point connects to the first), or as poly-line only.
+	 */
+	CSegSection(const std::string& id, const Points& points, bool is_open);
+
+	/**
+	   Constructor to create a segmentation shape based on a XML sub tree 
+	   @param node root of the XML sub tree 
+	   \param version segmentation set version the node stems from. 
+	*/
+	CSegSection(xmlpp::Node& node, int version);
+
+	/**
+	   Store the segmented section into a XML sub-tree 
+	   @param node parent node to which the subtree should be added 
+	   \param version segmentation set version the node stems from. 
+	*/
+	void write(xmlpp::Node& node, int version) const;
+
+	/// \returns the ID of the section 
+	const std::string& get_id() const;
+
+	/// \returns the list of the points defining the section shape 
+	const Points& get_points()const;
+
+	/// \returns the orthogonal bounding box enclosing the shape 
+	const C2DBoundingBox get_boundingbox() const;
+
+	/**
+	   translate the segmentation by a given shift 
+	   @param delta 
+	 */
+	void shift(const C2DFVector& delta);
+
+	/**
+	   Evaluate the Hausdorff distance between this shape and another one 
+	   @param other 
+	   @returns the Hausdorff distance
+	 */
+	float get_hausdorff_distance(const CSegSection& other) const;
+
+	/**
+	   Append this shape to another shape, a very crude version of a logical or 
+	   @param polygon to add the shape to 
+	*/
+	void append_to(C2DPolygon& polygon)const;
+
+	/**
+	   transform the shape by transforming its individual points 
+	   @param t the transformation to be applied 
+	 */
+	void transform(const C2DTransformation& t); 
+
+	/**
+	   transform the shape by transforming its individual points 
+	   @param t the inverse of the transformation to be applied 
+	 */
+	void inv_transform(const C2DTransformation& t); 
+
+	/**
+	   Draw the shape to a 2D image with a given color 
+	   @param output image to draw to 
+	   @param color color to use 
+	 */
+	void draw(C2DUBImage& output, unsigned char color)const; 
+
+	/**
+	   Draw the binary shape to a 2D image by xor-ing with what is already in there 
+	   @param output image to draw to 
+	*/
+	void draw_xor(C2DUBImage& output)const; 
+
+	/// \returns whether the curve is open (true) or closed (false). 
+	bool is_open() const; 
+
+private:
+	std::string m_id;
+	Points m_points;
+	bool m_is_open; 
+};
+
+NS_MIA_END
+
+#endif
diff --git a/mia/2d/segset.cc b/mia/2d/segset.cc
new file mode 100644
index 0000000..bdcfc4f
--- /dev/null
+++ b/mia/2d/segset.cc
@@ -0,0 +1,268 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <libxml++/libxml++.h>
+#include <mia/2d/segset.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/core/filetools.hh>
+#include <mia/core/tools.hh>
+
+
+
+NS_MIA_BEGIN
+using namespace std;
+using namespace xmlpp;
+
+
+CSegSet::CSegSet():
+	m_RV_peak(-1),
+	m_LV_peak(-1), 
+	m_preferred_reference(-1), 
+	m_version(2)
+{
+}
+
+CSegSet::CSegSet(int version):
+	m_RV_peak(-1),
+	m_LV_peak(-1), 
+	m_preferred_reference(-1), 
+	m_version(version)
+{
+}
+
+CSegSet::CSegSet(const std::string& src_filename):
+	m_RV_peak(-1),
+	m_LV_peak(-1),
+	m_preferred_reference(-1), 
+	m_version(2)
+{
+	DomParser parser;
+	parser.set_substitute_entities(); //We just want the text to be resolved/unescaped automatically.
+	parser.parse_file(src_filename);
+
+	if (!parser)
+		throw runtime_error(string("CSegSet: Unable to parse input file:") + src_filename);
+
+	read(*parser.get_document());
+
+}
+
+CSegSet::CSegSet(const xmlpp::Document& doc):
+	m_RV_peak(-1),
+	m_LV_peak(-1), 
+	m_preferred_reference(-1), 
+	m_version(1)
+{
+	TRACE("CSegSet::CSegSet");
+	read(doc);
+}
+
+void CSegSet::add_frame(const CSegFrame& frame)
+{
+	m_frames.push_back(frame);
+}
+
+const CSegSet::Frames& CSegSet::get_frames() const
+{
+	return m_frames;
+}
+
+CSegSet::Frames& CSegSet::get_frames()
+{
+	return m_frames;
+}
+
+void CSegSet::rename_base(const std::string& new_base)
+{
+	for (auto i = m_frames.begin(); i != m_frames.end(); ++i) 
+		i->rename_base(new_base);
+}
+
+const C2DBoundingBox CSegSet::get_boundingbox() const
+{
+	C2DBoundingBox result;
+
+	for(Frames::const_iterator i = m_frames.begin(); i != m_frames.end(); ++i)
+		result.unite(i->get_boundingbox());
+
+	return result;
+}
+
+xmlpp::Document *CSegSet::write() const
+{
+	xmlpp::Document *doc = new xmlpp::Document;
+	xmlpp::Element* nodeRoot = doc->create_root_node("workset");
+
+	if (m_version > 1) {
+		nodeRoot->set_attribute("version", to_string<int>(m_version));
+	}
+
+	Element* description = nodeRoot->add_child("description"); 
+	Element* RVPeak = description->add_child("RVpeak"); 
+	RVPeak->set_attribute("value", to_string<int>(m_RV_peak));
+	Element* LVPeak = description->add_child("LVpeak"); 
+	LVPeak->set_attribute("value", to_string<int>(m_LV_peak));
+	Element* PreferedRef = description->add_child("PreferedRef"); 
+	PreferedRef->set_attribute("value", to_string<int>(m_preferred_reference));
+
+
+	for(Frames::const_iterator i = m_frames.begin(); i != m_frames.end(); ++i) {
+		i->write(*nodeRoot, m_version);
+	}
+
+	return doc;
+}
+
+void CSegSet::read(const xmlpp::Document& node)
+{
+	const xmlpp::Element *root = node.get_root_node ();
+	if (root->get_name() != "workset") {
+		throw invalid_argument(string("CSegSet: Document root node: expected 'workset', but got ") +
+				       root->get_name());
+	}
+
+	// without attribute its version 1, otherwise read the version. 
+	const Attribute *attr = root->get_attribute("version"); 
+	if (attr) {
+		if (!from_string(attr->get_value(), m_version)) 
+			throw create_exception<invalid_argument>("bogus version '", 
+								 attr->get_value(), 
+								 "' in segmentation set"); 
+	}
+
+	auto frames = root->get_children("frame");
+	auto i = frames.begin();
+	auto e = frames.end();
+
+	while (i != e) {
+		try {
+			m_frames.push_back(CSegFrame(**i, m_version));
+		}
+		catch (invalid_argument& x) {
+			throw create_exception<invalid_argument>("Segset: Error reading frame ", distance(frames.begin(), i), 
+								 ":", x.what());  
+		}
+		++i;
+	}
+
+	auto descr = root->get_children("description");
+	if (!descr.empty()) 
+		descr = (*descr.begin())->get_children();
+	for(auto i = descr.begin(); i != descr.end(); ++i) {
+		cvdebug() << "description element '" << (*i)->get_name() << "'\n"; 
+		if ((*i)->get_name() == "RVpeak") {
+			const Element& elm = dynamic_cast<const Element&>(**i); 
+			const Attribute *attr = elm.get_attribute("value"); 
+			if (!attr)
+				cvwarn() << "CSegFrame: LVpeak without attribute"; 
+			else 
+				if (!from_string(attr->get_value(), m_RV_peak)) {
+					cvwarn() << "Could't convert RV_peak attribute '" << attr->get_value() 
+						 <<"' to an integer; ignoring\n"; 
+					m_RV_peak = -1; 
+				}
+		} else if ((*i)->get_name() == "LVpeak") {
+			const Element& elm = dynamic_cast<const Element&>(**i); 
+			const Attribute *attr = elm.get_attribute("value"); 
+			if (!attr)
+				cvwarn() << "CSegFrame: LVpeak without attribute"; 
+			else 	
+				if (!from_string(attr->get_value(), m_LV_peak)) {
+					cvwarn() << "Could't convert LV_peak attribute '" << attr->get_value() 
+						 <<"' to an integer; ignoring\n"; 
+					m_LV_peak = -1; 
+				}
+		} else if ((*i)->get_name() == "PreferedRef") {
+			const Element& elm = dynamic_cast<const Element&>(**i); 
+			const Attribute *attr = elm.get_attribute("value"); 
+			if (!attr)
+				cvwarn() << "CSegFrame: PreferedRef without attribute"; 
+			else 	
+				if (!from_string(attr->get_value(), m_preferred_reference)) {
+					cvwarn() << "Could't convert PreferedRef attribute '" << attr->get_value() 
+						 <<"' to an integer; ignoring\n"; 
+					m_preferred_reference = -1; 
+				}
+		}
+		else {
+			cvinfo() << "Ignoring unknown element '" << (*i)->get_name() << "'\n"; 
+		}
+	}
+}
+
+CSegSet  CSegSet::shift_and_rename(size_t skip, const C2DFVector&  shift, const std::string& new_filename_base) const
+{
+	CSegSet result(*this);
+	auto iframe = result.get_frames().begin();
+	auto eframe = result.get_frames().end();
+
+	while (skip-- && iframe != eframe)
+		++iframe;
+
+	while (iframe != eframe ) {
+		string base, suffix, number;
+		split_filename_number_pattern(iframe->get_imagename(), base, suffix, number);
+		stringstream fname;
+		fname << new_filename_base << number << suffix;
+		CSegFrame& rframe = *iframe;
+		rframe.shift(shift, fname.str());
+		++iframe;
+	}
+	return result;
+}
+
+void CSegSet::transform(const C2DTransformation& t)
+{
+	for (auto i = get_frames().begin(); i != get_frames().end(); ++i) 
+		i->transform(t); 
+}
+
+void CSegSet::set_RV_peak(int peak)
+{
+	m_RV_peak = peak; 
+}
+
+int CSegSet::get_RV_peak() const
+{
+	return m_RV_peak; 
+}
+
+
+void CSegSet::set_LV_peak(int peak)
+{
+	m_LV_peak = peak; 
+}
+
+int CSegSet::get_LV_peak() const
+{
+	return m_LV_peak; 
+}
+
+int CSegSet::get_preferred_reference() const
+{
+	return m_preferred_reference; 
+}
+
+void  CSegSet::set_preferred_reference(int value)
+{
+	m_preferred_reference = value; 
+}
+
+NS_MIA_END
diff --git a/mia/2d/segset.hh b/mia/2d/segset.hh
new file mode 100644
index 0000000..56483dd
--- /dev/null
+++ b/mia/2d/segset.hh
@@ -0,0 +1,162 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef SegSet_h
+#define SegSet_h
+
+#include <mia/core/ioplugin.hh>
+#include <mia/2d/segframe.hh>
+#include <mia/2d/boundingbox.hh>
+
+namespace xmlpp {
+	class Document;
+};
+
+NS_MIA_BEGIN
+
+/**
+   @ingroup perf 
+   \brief A set of segmentation of a 2D series of perfusion images 
+   
+   A set of slices containing segmentation information specifically designed for 
+   myocardial perfusion image series. 
+*/
+class EXPORT_2D CSegSet: public CIOData {
+public:
+	/// convenience typedef for the frames comprising a segmentation set 
+	typedef std::vector<CSegFrame> Frames;
+
+	/// Standard constructor 
+	CSegSet();
+	/**
+	   Construct the segmentation set by reading from a file 
+	   \param src_filename file name to read set from 
+	 */
+	CSegSet(const std::string& src_filename);
+
+	/**
+	   Construct a segmentation set by reading from a XML document
+	   \param node the root node of the XML document 
+	 */
+	CSegSet(const xmlpp::Document& node);
+
+
+	CSegSet(int version);
+	/**
+	   Append a segmentation frame 
+	   \param frame 
+	 */
+	void add_frame(const CSegFrame& frame);
+
+	/**
+	   Write the segmentation information to an XML tree 
+	   \returns root node of xml tree. 
+	 */
+	xmlpp::Document *write() const;
+
+
+	/// \returns read-only vector of the segmentation frames 
+	const Frames& get_frames()const;
+
+	/** 
+	    \returns a reference to the read-write vector of the segmentation frames 
+	    Changing this vector changes the segmentation set 
+	*/ 
+	Frames& get_frames();
+
+	/**
+	   \returns the box of minimal size that includes the segmentation 
+	 */
+	const C2DBoundingBox get_boundingbox() const;
+
+	/**
+	   Rename the base of the image file names for all frames on a frame by frame basis. 
+	   \param new_base new base name 
+	*/
+	void rename_base(const std::string& new_base); 
+
+
+	/**
+	   This function renames the images files, shifts the origin of the segmentation and 
+	   removes frames from the beginning of the set 
+	   \param skip number of frames to skipü at the beginning 
+	   \param shift new origin of segmentation 
+	   \param  new_filename_base new file name base
+	   \remark This function does too many things at once. 
+	 */
+	CSegSet  shift_and_rename(size_t skip, const C2DFVector&  shift, const std::string& new_filename_base)const;
+
+	/**
+	   Transform the segmentations slice wise by using the given transformation 
+	   Wroks in-place. 
+	   \param t tranformation 
+	 */
+	void transform(const C2DTransformation& t);
+
+
+	/**
+	   Set the frame number of the RV peak enhancement
+	   \param peak 
+	*/
+	void set_RV_peak(int peak); 
+	
+	/**
+	   \\returns the frame number of the RV peak enhancement (-1 if not set)
+	*/
+	int get_RV_peak() const; 
+
+	/**
+	   Set the frame number of the LV peak enhancement
+	   \param peak 
+	*/
+	void set_LV_peak(int peak); 
+
+	/**
+	   \\returns the frame number of the LV peak enhancement (-1 if not set)
+	*/
+	int get_LV_peak() const; 
+
+	/**
+	   \\returns the frame number of the image that should be used as reference frame 
+	   for time-intensity analysis after motion compensation - if the used motion compensation 
+	   algorithm provides some (like quasiperiodic, one2many, or serial do). Returns -1 if no values is given. 
+	*/
+	int get_preferred_reference() const; 
+
+
+	/**
+	   Set the preferred reference frame for this segmentation set. 
+	   \param value 
+	 */
+	void  set_preferred_reference(int value); 
+
+private:
+	void read(const xmlpp::Document& node);
+	Frames m_frames;
+	int m_RV_peak; 
+	int m_LV_peak; 
+	int m_preferred_reference; 
+	int m_version; 
+};
+
+
+NS_MIA_END
+
+#endif
diff --git a/mia/2d/segsetwithimages.cc b/mia/2d/segsetwithimages.cc
new file mode 100644
index 0000000..af1b7b4
--- /dev/null
+++ b/mia/2d/segsetwithimages.cc
@@ -0,0 +1,226 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdexcept>
+#include <boost/filesystem.hpp>
+#include <mia/core/errormacro.hh>
+#include <mia/2d/segsetwithimages.hh>
+#include <mia/2d/imageio.hh>
+#include <mia/2d/filter.hh>
+
+#include <mia/core/export_handler.hh>
+#include <mia/core/ioplugin.cxx>
+#include <mia/core/iohandler.cxx>
+
+
+namespace bfs=boost::filesystem;
+
+NS_MIA_BEGIN
+using namespace std;
+
+const char *CSegSetWithImages::data_descr = "2dmyocardsegset"; 
+
+CSegSetWithImages::CSegSetWithImages()
+{
+}
+
+CSegSetWithImages::CSegSetWithImages(int version):CSegSet(version)
+{
+}
+
+CSegSetWithImages::CSegSetWithImages(const xmlpp::Document& node, const string& fileroot):
+	CSegSet(node)
+{
+	
+	auto iframe = get_frames().begin();
+	auto eframe = get_frames().end();
+
+	while (iframe != eframe) {
+		string input_image = iframe->get_imagename();
+		string iimage = bfs::path(input_image).string();
+		input_image = (fileroot / bfs::path(iimage) ).string();
+		iframe->set_imagename(iimage);
+		
+		P2DImage image = load_image2d(input_image); 
+		m_images.push_back(image);
+		iframe->set_image(image); 
+		++iframe;
+	}	
+}
+
+CSegSetWithImages::CSegSetWithImages(const string& filename, bool ignore_path):
+	CSegSet(filename)
+{
+	string src_path;
+	if (ignore_path) {
+		bfs::path src_path_(filename);
+		src_path_.remove_filename();
+		src_path = src_path_.string();
+		cvdebug() << "Segmentation path" << src_path << "\n";
+	}
+
+
+	auto iframe = get_frames().begin();
+	auto eframe = get_frames().end();
+
+	while (iframe != eframe) {
+		string input_image = iframe->get_imagename();
+		string iimage = bfs::path(input_image).string();
+		if (ignore_path) {
+			input_image = (src_path / bfs::path(iimage) ).string();
+			iframe->set_imagename(iimage);
+		}
+		P2DImage image = load_image2d(input_image); 
+		m_images.push_back(image);
+		iframe->set_image(image); 
+		++iframe;
+	}
+}
+
+CSegSetWithImages *CSegSetWithImages::clone() const
+{
+	return new CSegSetWithImages(*this);
+}
+
+// sets the image series 
+void CSegSetWithImages::set_images(const C2DImageSeries& series)
+{
+	if (series.size() != get_frames().size()) 
+		throw create_exception<invalid_argument>("image set size (", series.size(), 
+					       ") and number of segmentation frames ",
+					       get_frames().size(), "must have same number of images"); 
+	m_images = series; 
+}
+
+void CSegSetWithImages::save_images(const string& filename) const
+{
+	bfs::path src_path(filename);
+	src_path.remove_filename();
+	
+	auto iframe = get_frames().begin();
+	auto eframe = get_frames().end();
+	auto iimage = m_images.begin();
+
+	while (iframe != eframe) {
+		string image_name = iframe->get_imagename();
+		string filename = (image_name[0] == '/') ? 
+			image_name : (src_path / bfs::path(image_name)).string(); 
+                        
+		if (!save_image(filename, *iimage))
+			throw create_exception<runtime_error>("CSegSetWithImages:unable to save image to '",image_name, "'" ); 
+		++iframe; 
+		++iimage; 
+	}
+}
+
+void CSegSetWithImages::add_frame(const CSegFrame& frame, P2DImage image)
+{
+	assert(	m_images.size() == get_frames().size()); 
+	add_frame(frame); 
+	m_images.push_back(image); 
+}
+
+const C2DImageSeries& CSegSetWithImages::get_images()const
+{
+	return m_images;
+}
+
+struct 	CSegFrameCropper {
+	CSegFrameCropper(const C2DIVector& shift,
+			 P2DFilter filter,
+			 const string& image_name);
+
+	CSegFrame operator()(const CSegFrame& frame, const C2DImage& image) const;
+
+private:
+	C2DIVector m_shift;
+	P2DFilter m_filter;
+	bfs::path m_image_outpath;
+};
+
+
+CSegSetWithImages CSegSetWithImages::crop(const C2DIVector&  start, const C2DIVector&  end,
+	const string& crop_filename_base)
+{
+	CSegSetWithImages result;
+
+	stringstream mask_lv;
+	mask_lv << "crop:start=[" << start
+		<< "],end=[" << end << "]";
+	cvinfo() << "crop region = '" << mask_lv.str() << "'\n";
+	auto image_cropper = C2DFilterPluginHandler::instance().produce(mask_lv.str().c_str());
+
+	CSegFrameCropper frame_cropper(start, image_cropper, crop_filename_base);
+
+	Frames::const_iterator iframe = get_frames().begin();
+	Frames::const_iterator eframe = get_frames().end();
+	C2DImageSeries::const_iterator iimages = get_images().begin();
+
+	size_t i = 0;
+	while (iframe != eframe) {
+		cvinfo() << "Crop Frame " << i++ << "\n";
+
+		result.add_frame(frame_cropper(*iframe, **iimages));
+		++iframe;
+		++iimages;
+	}
+	return result;
+}
+
+
+CSegFrameCropper::CSegFrameCropper(const C2DIVector& shift,
+				   P2DFilter filter,
+				   const string& image_name):
+	m_shift(shift),
+	m_filter(filter),
+	m_image_outpath(image_name)
+{
+	m_image_outpath.remove_filename();
+
+}
+
+
+CSegFrame CSegFrameCropper::operator()(const CSegFrame& frame, const C2DImage& image) const
+{
+	P2DImage cropped = m_filter->filter(image);
+	const string out_filename = (m_image_outpath.string() / bfs::path(frame.get_imagename())).string();
+
+	if (!save_image(out_filename, cropped))
+		cvwarn() << "Could not write cropped file '" << out_filename << "'\n";
+
+	CSegFrame result = frame;
+	result.shift(m_shift, frame.get_imagename());
+	return result;
+
+}
+
+template <> const char *  const
+TPluginHandler<CSegSetWithImagesIOPlugin>::m_help =  
+	"Input/output of 2D image series with segmentations.";
+
+
+template class TIOPlugin<CSegSetWithImages>;
+template class TIOPluginHandler<CSegSetWithImagesIOPlugin>;
+template class TPluginHandler<CSegSetWithImagesIOPlugin>;
+template class THandlerSingleton< TIOPluginHandler<CSegSetWithImagesIOPlugin >>;
+
+
+
+NS_MIA_END
diff --git a/mia/2d/segsetwithimages.hh b/mia/2d/segsetwithimages.hh
new file mode 100644
index 0000000..fd3dcac
--- /dev/null
+++ b/mia/2d/segsetwithimages.hh
@@ -0,0 +1,116 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_2d_SegSetWithImages_hh
+#define mia_2d_SegSetWithImages_hh
+
+
+#include <mia/core/iohandler.hh>
+
+#include <mia/2d/segset.hh>
+#include <mia/2d/image.hh>
+
+namespace xmlpp {
+	class Document;
+};
+
+NS_MIA_BEGIN
+
+/**
+   @ingroup perf 
+   \brief A set of images and its segmentations, related to heart perfusion analysis  
+   
+   A set of slices containing segmentationinformation as well as the images. 
+ */
+class EXPORT_2D CSegSetWithImages: public CSegSet {
+public:
+	static const char *data_descr;	
+	typedef CSegSetWithImages type;	
+	typedef std::shared_ptr<CSegSetWithImages> Pointer; 
+	
+	CSegSetWithImages();
+
+	CSegSetWithImages(int version);
+
+
+	/**
+	   Read the segmentation set and load the images 
+	   \param node the root node of the XML segmentation set description
+	   \param fileroot is the root location of the set file and it is used as 
+	   base path for the images. 
+	*/
+	CSegSetWithImages(const xmlpp::Document& node, const std::string& fileroot); 
+	
+
+	/**
+	   Read the segmentation set and load the images 
+	   \param filename segmentation set 
+	   \param ignore_path if \a true the image reader will ignore the path 
+	   assosiated with the images, and use the base directory of the segmentation set.  
+	 */
+	CSegSetWithImages(const std::string& filename, bool ignore_path);
+
+	/// \returns a vector of the images 
+	const C2DImageSeries& get_images()const;
+
+	/// sets the image series @param series 
+	void set_images(const C2DImageSeries& series); 
+	
+	/// save the images to their give file names with the given directory as root @param root 
+	void save_images(const std::string& root) const; 
+
+
+	using CSegSet::add_frame; 
+	/**
+	   Add a frame ant its correcponding image 
+	   \param frame the new frame 
+	   \param image the image 
+	 */
+	void add_frame(const CSegFrame& frame, P2DImage image); 
+	
+	/** Run acropping on the inout images and correct the segmentation information accordingly 
+	    \param start upper left corner of the cropping reagion 
+	    \param end lower right corner  of the cropping reagion 
+	    \param crop_filename_base new file name base for the cropped images 
+	    \returns a new segmentation set with the cropped images and the corrected segmentation information
+	*/
+	CSegSetWithImages crop(const C2DIVector&  start, const C2DIVector&  end,
+			       const std::string& crop_filename_base);
+
+	CSegSetWithImages *clone() const; 
+private:
+	C2DImageSeries m_images;
+};
+
+typedef CSegSetWithImages::Pointer PSegSetWithImages; 
+
+typedef TIOPlugin<CSegSetWithImages> CSegSetWithImagesIOPlugin;
+typedef THandlerSingleton< TIOPluginHandler<CSegSetWithImagesIOPlugin > > CSegSetWithImagesIOPluginHandler;
+
+template <> 
+struct IOHandler_of<CSegSetWithImages> {
+	typedef CSegSetWithImagesIOPluginHandler type;
+}; 
+
+
+
+NS_MIA_END
+
+#endif
diff --git a/mia/2d/segstar.cc b/mia/2d/segstar.cc
new file mode 100644
index 0000000..9394bcd
--- /dev/null
+++ b/mia/2d/segstar.cc
@@ -0,0 +1,179 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <sstream>
+#include <stdexcept>
+#include <cassert>
+#include <mia/core/msgstream.hh>
+#include <mia/core/tools.hh>
+
+#include <mia/2d/segstar.hh>
+#include <libxml++/libxml++.h>
+
+
+NS_MIA_BEGIN
+using namespace std;
+
+CSegStar::CSegStar():
+	m_radius(0.0)
+{
+}
+
+CSegStar::CSegStar(const CSegPoint2D& center, float r, const CSegPoint2D& d1, 
+		   const CSegPoint2D& d2, const CSegPoint2D& d3):
+	m_center(center),
+	m_radius(r)
+{
+	m_directions[0] = d1;
+	m_directions[1] = d2;
+	m_directions[2] = d3;
+}
+
+
+CSegStar::CSegStar(const xmlpp::Node& n)
+{
+	TRACE("CSegStar::CSegStar");
+
+	if (n.get_name() != "star")
+		throw create_exception<runtime_error>("CSegStar: expect node of type 'star', but got '", n.get_name(), "'");
+
+	const xmlpp::Element& node = dynamic_cast<const xmlpp::Element&>(n);
+
+
+	m_center = CSegPoint2D(node);
+	xmlpp::Attribute *rx = node.get_attribute ("r");
+	if (!rx)
+		throw runtime_error("CSegStar: attribute r not found");
+
+	if (!from_string(rx->get_value(), m_radius)) 
+		throw create_exception<runtime_error>("CSegStar: radius attribute '", rx->get_value(), "' is not a floating point value"); 
+
+	cvdebug() << "Got star center (" << m_center.x << ", " << m_center.y << " @ " << m_radius << ")\n";
+
+	xmlpp::Node::NodeList points = node.get_children("point");
+	size_t npoints  = points.size();
+
+	if (npoints != 3)
+		throw invalid_argument("Bogus: Star should have 3 direction points");
+
+	size_t k = 0;
+	for (xmlpp::Node::NodeList::const_iterator i = points.begin();
+	     i != points.end(); ++i, ++k) {
+		xmlpp::Element& node = dynamic_cast<xmlpp::Element&>(**i);
+		m_directions[k] = CSegPoint2D(node);
+	}
+}
+
+void CSegStar::shift(const C2DFVector& delta)
+{
+	m_center -= delta;
+}
+
+void CSegStar::transform(const C2DTransformation& t)
+{
+	cvdebug() << "CSegStar::transform: " << m_center << "@" << m_radius << "\n"; 
+	for (size_t i = 0; i < 3; ++i) {
+		cvdebug() << "CSegStar::transform:" << i << ":" << m_center + m_radius * m_directions[i] << "\n"; 
+		m_directions[i] = t(m_center + m_radius * m_directions[i]);
+		cvdebug() << "CSegStar::transform:" << i << ":" << m_directions[i] << "\n"; 
+	}
+	recenter_rays(); 
+}
+
+inline double  __calc_bc(double a, double b, double c)
+{
+	return a * a *( b * b + c * c - a *a ); 
+}
+		
+
+// re-evaluate the center after a transformation has been applied 
+// since the transformation may be non-rigid, base this evaluation on the 
+// points located at the circumfence 
+void CSegStar::reeval_center() 
+{
+	double a = (m_directions[1] - m_directions[2]).norm(); 
+	double b = (m_directions[2] - m_directions[0]).norm(); 
+	double c = (m_directions[0] - m_directions[1]).norm(); 
+	
+	vector<double> x(3); 
+	x[0] = __calc_bc(a, b, c); 
+	x[1] = __calc_bc(b, c, a); 
+	x[2] = __calc_bc(c, a, b); 
+	
+        double sum = x[0] + x[1] + x[2]; 
+        for (size_t i = 0; i < 3; ++i) {
+		x[i] /= sum; 
+	}
+	C2DFVector result(0,0); 
+	
+	for (size_t i = 0; i < 3; ++i) 
+		result += x[i] * m_directions[i]; 
+        m_center = result; 
+}
+
+
+
+void CSegStar::recenter_rays()
+{
+	reeval_center(); 
+	m_directions[0] -= m_center; 
+	float n = m_directions[0].norm(); 
+	m_radius = n; 
+	m_directions[0] /= n; 
+
+        float c = -0.5; 
+        float s = sqrt(0.75); 
+
+	m_directions[1] = C2DFVector(  c * m_directions[0].x +  s * m_directions[0].y,  
+				       c * m_directions[0].y -  s * m_directions[0].x); 
+	if (m_directions[1].x < 0) 
+		m_directions[1] *= -1; 
+	
+	m_directions[2] = C2DFVector(  c * m_directions[0].x -  s * m_directions[0].y,  
+				       c * m_directions[0].y +  s * m_directions[0].x); 
+	
+	if (m_directions[2].x > 0) 
+		m_directions[2] *= -1; 
+	
+
+}
+
+void CSegStar::inv_transform(const C2DTransformation& t)
+{
+	for (size_t i = 0; i < 3; ++i) {
+		m_directions[i] = m_center + m_radius * m_directions[i];
+		m_directions[i].inv_transform(t);
+	}
+	recenter_rays();
+}
+
+void CSegStar::write(xmlpp::Node& node) const
+{
+	xmlpp::Element* nodeChild = node.add_child("star");
+
+	nodeChild->set_attribute("y", to_string<float>(m_center.y));
+	nodeChild->set_attribute("x", to_string<float>(m_center.x));
+	nodeChild->set_attribute("r", to_string<float>(m_radius));
+
+	for (size_t i = 0; i < 3; ++i)
+		m_directions[i].write(*nodeChild);
+}
+
+NS_MIA_END
diff --git a/mia/2d/segstar.hh b/mia/2d/segstar.hh
new file mode 100644
index 0000000..e5caddd
--- /dev/null
+++ b/mia/2d/segstar.hh
@@ -0,0 +1,101 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef SegStar_h
+#define SegStar_h
+
+#include <mia/2d/segpoint.hh>
+#include <vector>
+
+NS_MIA_BEGIN
+
+/**
+   @ingroup perf 
+   \brief Helper class for the segmentation of the left heart ventricle myocardium 
+
+   This class implements the segmentation helper that defines the
+   center of a circle, six rays and the circle. 
+   It is used to help the (manual) segmentation of the left heart myocardium.
+ */
+
+class  EXPORT_2D CSegStar {
+public:
+	/** Standard constructor */
+	CSegStar();
+
+	/**
+	   Constructor to create the CSegStar from given data 
+	   @param center center of the circle appoximating the outer wall of the myocardium 
+	   @param r radius of the circle appoximating the outer wall of the myocardium 
+	   @param d1 first ray, its intersection should coinceede with the right ventricle 
+	   insertion point 
+	   @param d2 second ray direction vector  
+	   @param d3 third ray  direction vector 
+	 */
+	CSegStar(const CSegPoint2D& center, float r, 
+		 const CSegPoint2D& d1, const CSegPoint2D& d2, const CSegPoint2D& d3);
+	
+	/**
+	   Constructor to create a CSegStar from a XML sub tree
+	   @param node root of the sub tree 
+	 */
+	CSegStar(const xmlpp::Node& node);
+
+	/**
+	   write the CSegStar info to a XML node 
+	   @param node root node to add the info to 
+	 */
+	void write(xmlpp::Node& node) const;
+
+	/**
+	   Shift the segmentation data 
+	   @param delta
+	 */
+	void shift(const C2DFVector& delta);
+
+	/**
+	   Transform the star by transforming the intersections between the rays and the circle
+	   and then re-evaluating the center and the circle radius 
+	   \param t transformation to be applied 
+	 */
+	void transform(const C2DTransformation& t);
+
+	/**
+	   Transform the star by transforming the intersections between the rays and the circle
+	   and then re-evaluating the center and the circle radius 
+	   \param t inverse of the transformation to be applied 
+	 */
+	void inv_transform(const C2DTransformation& t);
+
+	/// center of the circle approximating the outer wall of the LV myocardium 
+	CSegPoint2D m_center;
+	/// radius of the circle approximating the outer wall of the LV myocardium 
+	float m_radius;
+	/// the ray directions to define the star 
+	CSegPoint2D m_directions[3];
+private: 
+	void recenter_rays(); 
+	void reeval_center(); 
+};
+
+NS_MIA_END
+
+
+#endif
diff --git a/mia/2d/shape.cc b/mia/2d/shape.cc
index 6ad4b20..98e8d87 100644
--- a/mia/2d/shape.cc
+++ b/mia/2d/shape.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -62,14 +62,6 @@ TPluginHandler<TFactory<C2DShape>>::m_help =  "These plug-ins define 2D structur
 				"to describe neighborhoods for morphological and other filters."; 
 
 
-using boost::filesystem::path; 
-C2DShapePluginHandlerTestPath::C2DShapePluginHandlerTestPath()
-{
-	CPathNameArray sksearchpath({path(MIA_BUILD_ROOT"/mia/2d/shapes")});
-	C2DShapePluginHandler::set_search_path(sksearchpath); 
-	
-}
-	
 P2DShape rotate_90_degree(const C2DShape& shape)
 {
 	P2DShape result(new C2DShape); 
diff --git a/mia/2d/shape.hh b/mia/2d/shape.hh
index 558c36c..e8ed038 100644
--- a/mia/2d/shape.hh
+++ b/mia/2d/shape.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -40,28 +40,14 @@ typedef TFactory<C2DShape> C2DShapePlugin;
 /// Plug-in handler for the shape plug-ins 
 typedef THandlerSingleton<TFactoryPluginHandler<C2DShapePlugin> > C2DShapePluginHandler;
 
-/** 
-    @cond INTERNAL  
-    \ingroup test 
-    \brief Class to initialiaze the plug-in search path fot testing without installing the plug-ins 
-*/
-class EXPORT_2D C2DShapePluginHandlerTestPath {
-public: 
-	C2DShapePluginHandlerTestPath(); 
-}; 
-/// @endcond 
+extern template class EXPORT_2D TShape<T2DVector, C2DBitImage>;
 
 /**
    Convenience function to produce a shape from a plugin
-   \param descr the description of the shape 
+   \param shape the description of the shape 
    \returns the newly created shape 
 */
 
-inline P2DShape produce_2d_shape(const std::string& descr) 
-{
-	return C2DShapePluginHandler::instance().produce(descr); 
-}
-
 P2DShape EXPORT_2D rotate_90_degree(const C2DShape& shape); 
 
 /// @cond NEVER 
@@ -69,6 +55,11 @@ P2DShape EXPORT_2D rotate_90_degree(const C2DShape& shape);
 FACTORY_TRAIT(C2DShapePluginHandler); 
 /// @endcond 
 
+inline P2DShape produce_2d_shape(const std::string& descr) 
+{
+	return C2DShapePluginHandler::instance().produce(descr); 
+}
+
 NS_MIA_END
 
 #endif
diff --git a/mia/2d/shapes/CMakeLists.txt b/mia/2d/shapes/CMakeLists.txt
index b06ddf4..7c4118d 100644
--- a/mia/2d/shapes/CMakeLists.txt
+++ b/mia/2d/shapes/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/shapes/basic_shapes.cc b/mia/2d/shapes/basic_shapes.cc
index e5a5c63..dae19ab 100644
--- a/mia/2d/shapes/basic_shapes.cc
+++ b/mia/2d/shapes/basic_shapes.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/shapes/basic_shapes.hh b/mia/2d/shapes/basic_shapes.hh
index 6dc0093..338467d 100644
--- a/mia/2d/shapes/basic_shapes.hh
+++ b/mia/2d/shapes/basic_shapes.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/shapes/rect.cc b/mia/2d/shapes/rect.cc
index bccbf00..54fdbbe 100644
--- a/mia/2d/shapes/rect.cc
+++ b/mia/2d/shapes/rect.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/shapes/rect.hh b/mia/2d/shapes/rect.hh
index e02bb58..e5f3209 100644
--- a/mia/2d/shapes/rect.hh
+++ b/mia/2d/shapes/rect.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/shapes/sphere.cc b/mia/2d/shapes/sphere.cc
index bd9fb69..a74d657 100644
--- a/mia/2d/shapes/sphere.cc
+++ b/mia/2d/shapes/sphere.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/shapes/sphere.hh b/mia/2d/shapes/sphere.hh
index 4833660..831bbf2 100644
--- a/mia/2d/shapes/sphere.hh
+++ b/mia/2d/shapes/sphere.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/shapes/test_basic_shapes.cc b/mia/2d/shapes/test_basic_shapes.cc
index 0449924..ca0de07 100644
--- a/mia/2d/shapes/test_basic_shapes.cc
+++ b/mia/2d/shapes/test_basic_shapes.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/shapes/test_rect.cc b/mia/2d/shapes/test_rect.cc
index ca923b4..6856ab0 100644
--- a/mia/2d/shapes/test_rect.cc
+++ b/mia/2d/shapes/test_rect.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/shapes/test_sphere.cc b/mia/2d/shapes/test_sphere.cc
index 74e4e5e..637ba00 100644
--- a/mia/2d/shapes/test_sphere.cc
+++ b/mia/2d/shapes/test_sphere.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/similarity_profile.cc b/mia/2d/similarity_profile.cc
index c66ddf9..5673044 100644
--- a/mia/2d/similarity_profile.cc
+++ b/mia/2d/similarity_profile.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/similarity_profile.hh b/mia/2d/similarity_profile.hh
index c80b261..bce6cfe 100644
--- a/mia/2d/similarity_profile.hh
+++ b/mia/2d/similarity_profile.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/sparse_image_solver.cc b/mia/2d/sparse_image_solver.cc
index 4f059c4..3bd18e8 100644
--- a/mia/2d/sparse_image_solver.cc
+++ b/mia/2d/sparse_image_solver.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,15 +56,6 @@ EXPORT_2D C2DFImage operator * (const C2DImageSolverAmultx& A, const C2DFImage&
 	return result; 
 }
 
-
-using boost::filesystem::path; 
-using std::list; 
-C2DImageSparseSolverTestPath::C2DImageSparseSolverTestPath() 
-{
-	CPathNameArray sksearchpath({path(MIA_BUILD_ROOT"/mia/2d/sparsimgsolver")});
-	C2DImageSparseSolverPluginHandler::set_search_path(sksearchpath); 
-}
-
 template <> const char *  const 
 TPluginHandler<TFactory<C2DImageSolverAmultx>>::m_help =  "These plug-ins define the multiplication of a sparse matrix "
 				"with a vector that is used in the sparse image solver class.";
diff --git a/mia/2d/sparse_image_solver.hh b/mia/2d/sparse_image_solver.hh
index 96023b2..2e55e3d 100644
--- a/mia/2d/sparse_image_solver.hh
+++ b/mia/2d/sparse_image_solver.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,18 +36,6 @@ typedef std::shared_ptr<C2DImageSparseSolver > P2DImageSparseSolver;
 /// Plugin handler for sparse image solver plug-ins 
 typedef THandlerSingleton<TFactoryPluginHandler<TFactory<C2DImageSparseSolver> > > C2DImageSparseSolverPluginHandler;
 
-/**   
-      @cond INTERNAL 
-      \ingroup tests 
-      Class to set up the plug-in search path for spline kernels when running tests
-      in the build tree 
-*/
-struct EXPORT_2D C2DImageSparseSolverTestPath {
-	C2DImageSparseSolverTestPath(); 
-}; 
-
-/// @endcond 
-
 /// base class for the Matrix-Vector multiplication 
 typedef C2DImageSparseSolver::A_mult_x C2DImageSolverAmultx; 
 
diff --git a/mia/2d/splinepenalty/CMakeLists.txt b/mia/2d/splinepenalty/CMakeLists.txt
index b6f5e42..166dc03 100644
--- a/mia/2d/splinepenalty/CMakeLists.txt
+++ b/mia/2d/splinepenalty/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/splinepenalty/divcurl.cc b/mia/2d/splinepenalty/divcurl.cc
index af6519a..808f797 100644
--- a/mia/2d/splinepenalty/divcurl.cc
+++ b/mia/2d/splinepenalty/divcurl.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,8 +24,8 @@ NS_BEGIN(divcurl_splinepenalty)
 
 NS_MIA_USE
 
-C2DDivcurlSplinePenalty::C2DDivcurlSplinePenalty(double weight, double div_weight, double curl_weight):
-	C2DSplineTransformPenalty(weight), 
+C2DDivcurlSplinePenalty::C2DDivcurlSplinePenalty(double weight, bool normalize, double div_weight, double curl_weight):
+	C2DSplineTransformPenalty(weight, normalize), 
 	m_div_weight(div_weight), 
 	m_curl_weight(curl_weight)
 {
@@ -56,7 +56,7 @@ double C2DDivcurlSplinePenalty::do_value_and_gradient(const C2DFVectorfield&  co
 C2DSplineTransformPenalty *C2DDivcurlSplinePenalty::do_clone() const
 {
 	C2DSplineTransformPenalty *result =  
-		new C2DDivcurlSplinePenalty(get_weight(), m_div_weight, m_curl_weight);
+		new C2DDivcurlSplinePenalty(get_weight(), get_normalize(), m_div_weight, m_curl_weight);
 	if (get_kernel()) 
 		result->initialize(get_size(), get_range(), get_kernel()); 
 	return result; 
@@ -79,9 +79,9 @@ const std::string C2DDivcurlSplinePenaltyPlugin::do_get_descr() const
 	return "divcurl penalty on the transformation"; 
 }
 
-C2DDivcurlSplinePenaltyPlugin::Product *C2DDivcurlSplinePenaltyPlugin::do_create(float weight) const
+C2DDivcurlSplinePenaltyPlugin::Product *C2DDivcurlSplinePenaltyPlugin::do_create(float weight, bool normalize) const
 {
-	return new C2DDivcurlSplinePenalty(weight, m_div_weight, m_curl_weight); 
+	return new C2DDivcurlSplinePenalty(weight, normalize, m_div_weight, m_curl_weight); 
 }
 
 extern "C" EXPORT CPluginBase *get_plugin_interface()
diff --git a/mia/2d/splinepenalty/divcurl.hh b/mia/2d/splinepenalty/divcurl.hh
index 6f87236..0686168 100644
--- a/mia/2d/splinepenalty/divcurl.hh
+++ b/mia/2d/splinepenalty/divcurl.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@ NS_BEGIN(divcurl_splinepenalty)
 class C2DDivcurlSplinePenalty: public mia::C2DSplineTransformPenalty {
 public: 
 	
-	C2DDivcurlSplinePenalty(double weight, double div_weight, double curl_weight);
+	C2DDivcurlSplinePenalty(double weight, bool normalize, double div_weight, double curl_weight);
 	
 private: 
 	void do_initialize(); 
@@ -51,7 +51,7 @@ public:
 	
 private: 
 	virtual const std::string do_get_descr() const;
-	virtual Product *do_create(float weight) const __attribute__((warn_unused_result));
+	virtual Product *do_create(float weight, bool normalize) const __attribute__((warn_unused_result));
 	float m_div_weight; 
 	float m_curl_weight; 
 
diff --git a/mia/2d/splinepenalty/test_divcurl.cc b/mia/2d/splinepenalty/test_divcurl.cc
index 332273d..b9a0828 100644
--- a/mia/2d/splinepenalty/test_divcurl.cc
+++ b/mia/2d/splinepenalty/test_divcurl.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,11 +28,9 @@ using namespace divcurl_splinepenalty;
 NS_MIA_USE
 namespace bfs=::boost::filesystem;
 
-CSplineKernelTestPath kernel_test_path; 
-
 BOOST_AUTO_TEST_CASE( test_divcurl_cost ) 
 {
-	C2DDivcurlSplinePenalty  penalty(1.0, 1.0, 1.0); 
+	C2DDivcurlSplinePenalty  penalty(1.0, false, 1.0, 1.0); 
 
 	C2DBounds size(31,31); 
 	C2DFVector range(8,8); 
@@ -64,7 +62,7 @@ BOOST_AUTO_TEST_CASE( test_divcurl_cost )
 
 BOOST_AUTO_TEST_CASE( test_divcurl_cost_scale_weight ) 
 {
-	C2DDivcurlSplinePenalty  penalty(.5, 1.0, 1.0); 
+	C2DDivcurlSplinePenalty  penalty(.5, false, 1.0, 1.0); 
 
 	C2DBounds size(31,31); 
 	C2DFVector range(8,8); 
@@ -96,7 +94,7 @@ BOOST_AUTO_TEST_CASE( test_divcurl_cost_scale_weight )
 
 BOOST_AUTO_TEST_CASE( test_divcurl_cost_scale_div_weight ) 
 {
-	C2DDivcurlSplinePenalty  penalty(1.0, 0.5, 1.0); 
+	C2DDivcurlSplinePenalty  penalty(1.0, false, 0.5, 1.0); 
 
 	C2DBounds size(31,31); 
 	C2DFVector range(8,8); 
@@ -128,7 +126,7 @@ BOOST_AUTO_TEST_CASE( test_divcurl_cost_scale_div_weight )
 
 BOOST_AUTO_TEST_CASE( test_divcurl_cost_scale_curl_weight ) 
 {
-	C2DDivcurlSplinePenalty  penalty(1.0, 1.0, 0.5); 
+	C2DDivcurlSplinePenalty  penalty(1.0, false, 1.0, 0.5); 
 
 	C2DBounds size(31,31); 
 	C2DFVector range(8,8); 
diff --git a/mia/2d/splinetransformpenalty.cc b/mia/2d/splinetransformpenalty.cc
index d062d04..f33f9c6 100644
--- a/mia/2d/splinetransformpenalty.cc
+++ b/mia/2d/splinetransformpenalty.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,8 +30,9 @@ using namespace std;
 const char *C2DSplineTransformPenalty::data_descr = "2dtransform";
 const char *C2DSplineTransformPenalty::type_descr = "splinepenalty"; 
 
-C2DSplineTransformPenalty::C2DSplineTransformPenalty(double weight):
-m_weight(weight)
+C2DSplineTransformPenalty::C2DSplineTransformPenalty(double weight, bool normalize):
+        m_weight(weight), 
+	m_normalize(normalize)
 {
 }
 
@@ -51,7 +52,8 @@ void C2DSplineTransformPenalty::initialize(const C2DBounds& size, const C2DFVect
 double C2DSplineTransformPenalty::value(const C2DFVectorfield&  coefficients) const
 {
 	assert(coefficients.get_size() == get_size()); 
-	return m_weight * do_value(coefficients); 
+	const double w = m_normalize ? m_weight / m_range.product() : m_weight; 
+	return w * do_value(coefficients); 
 }
 
 
@@ -60,9 +62,10 @@ double C2DSplineTransformPenalty::value_and_gradient(const C2DFVectorfield&  coe
 	assert(coefficients.get_size() == get_size()); 
 	assert(coefficients.size() * 2 == gradient.size()); 
 
-	double value =  m_weight * do_value_and_gradient(coefficients, gradient); 
+	const double w = m_normalize ? m_weight / m_range.product() : m_weight; 
+	double value =  w * do_value_and_gradient(coefficients, gradient); 
 	transform(gradient.begin(), gradient.end(), gradient.begin(), 
-		  [this](double x) { return - m_weight * x;}); 
+		  [w](double x) { return - w * x;}); 
 	return value; 
 }
 
@@ -86,6 +89,12 @@ double C2DSplineTransformPenalty::get_weight() const
 	return m_weight; 
 }
 
+bool C2DSplineTransformPenalty::get_normalize() const
+{
+	return m_normalize; 
+}
+
+
 C2DSplineTransformPenalty *C2DSplineTransformPenalty::clone() const
 {
 	return do_clone(); 
@@ -99,15 +108,18 @@ C2DSplineTransformPenaltyPluginHandler::ProductPtr produce_2d_spline_transform_p
 
 C2DSplineTransformPenaltyPlugin::C2DSplineTransformPenaltyPlugin(char const * const  name):
 	TFactory<C2DSplineTransformPenalty>(name), 
-	m_weight(1.0)
+	m_weight(1.0), 
+	m_normalize(false)
 {
 	add_parameter("weight", new CFloatParameter(m_weight, 0.0f, std::numeric_limits<float>::max(), 
 						    false, "weight of penalty energy"));
+	add_parameter("norm", new CBoolParameter(m_normalize, false, "Set to 1 if the penalty should be normalized " 
+						 "with respect to the image size")); 
 }
 
 C2DSplineTransformPenaltyPlugin::Product *C2DSplineTransformPenaltyPlugin::do_create() const
 {
-	return do_create(m_weight); 
+	return do_create(m_weight, m_normalize); 
 }
 
 
diff --git a/mia/2d/splinetransformpenalty.hh b/mia/2d/splinetransformpenalty.hh
index 2dc9f72..3299ee9 100644
--- a/mia/2d/splinetransformpenalty.hh
+++ b/mia/2d/splinetransformpenalty.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -46,9 +46,10 @@ public:
 	
 	/**
 	   Constructor that sets the weight of the penalty term 
-	   \param weight 
+	   @param weight 
+	   @param normalize 
 	 */
-	C2DSplineTransformPenalty(double weight); 
+	C2DSplineTransformPenalty(double weight, bool normalize); 
 
 	C2DSplineTransformPenalty(const C2DSplineTransformPenalty& org) = delete; 
 	C2DSplineTransformPenalty& operator = (const C2DSplineTransformPenalty& org) = delete; 
@@ -87,8 +88,6 @@ public:
 	double value_and_gradient(const C2DFVectorfield&  coefficients, CDoubleVector& gradient) const;
 
 protected: 
-
-
 	
 	const C2DBounds& get_size() const;
 	
@@ -97,6 +96,8 @@ protected:
 	PSplineKernel get_kernel() const;        
 
 	double get_weight() const; 
+	
+	bool get_normalize() const; 
 
 private:
 
@@ -109,6 +110,7 @@ private:
 	virtual C2DSplineTransformPenalty *do_clone() const  = 0;
 
 	double m_weight; 
+	bool m_normalize; 
 
 	C2DBounds m_size;
 	C2DFVector m_range; 
@@ -123,9 +125,10 @@ public:
 	C2DSplineTransformPenaltyPlugin(char const * const  name); 
 private: 
 	virtual Product *do_create() const __attribute__((warn_unused_result));
-	virtual Product *do_create(float weight) const __attribute__((warn_unused_result)) = 0 ;
+	virtual Product *do_create(float weight, bool normalize) const __attribute__((warn_unused_result)) = 0 ;
 
 	float m_weight; 
+	bool m_normalize; 
 }; 
 
 
diff --git a/mia/2d/test_2d.cc b/mia/2d/test_2d.cc
index ae3a9cd..f20d00d 100644
--- a/mia/2d/test_2d.cc
+++ b/mia/2d/test_2d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_angle.cc b/mia/2d/test_angle.cc
index 69ed447..56e4609 100644
--- a/mia/2d/test_angle.cc
+++ b/mia/2d/test_angle.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_boundingbox.cc b/mia/2d/test_boundingbox.cc
index 30d3656..a7e6aa1 100644
--- a/mia/2d/test_boundingbox.cc
+++ b/mia/2d/test_boundingbox.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
  */
 
 #include <mia/internal/autotest.hh>
-#include <mia/2d/BoundingBox.hh>
+#include <mia/2d/boundingbox.hh>
 
 NS_MIA_USE;
 
diff --git a/mia/2d/test_combiner.cc b/mia/2d/test_combiner.cc
index 22d4c52..ebf7895 100644
--- a/mia/2d/test_combiner.cc
+++ b/mia/2d/test_combiner.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_correlation_weight.cc b/mia/2d/test_correlation_weight.cc
index d8489f4..3f531f5 100644
--- a/mia/2d/test_correlation_weight.cc
+++ b/mia/2d/test_correlation_weight.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_cost.cc b/mia/2d/test_cost.cc
index 36fc592..298976f 100644
--- a/mia/2d/test_cost.cc
+++ b/mia/2d/test_cost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,21 +25,13 @@
 NS_MIA_USE
 namespace bfs=::boost::filesystem; 
 using namespace boost::unit_test;
-
-CSplineKernelTestPath spline_kernel_set_test_path; 
+using std::set; 
+using std::string; 
 
 BOOST_AUTO_TEST_CASE( test_2dimage_cost_avail )
 {
-	CPathNameArray searchpath; 
-	
-	searchpath.push_back(bfs::path("cost")); 
-
-	C2DImageCostPluginHandler::set_search_path(searchpath); 
-	
-	const auto& handler = C2DImageCostPluginHandler::instance(); 
-
-	BOOST_CHECK_EQUAL(handler.size(), 4u); 
-	BOOST_CHECK_EQUAL(handler.get_plugin_names(), "lsd mi ngf ssd "); 
+	set<string> test_data = {"lncc","lsd", "mi", "ngf", "ncc", "ssd", "ssd-automask"}; 
+	test_pluginsets(C2DImageCostPluginHandler::instance().get_set(), test_data); 
 }
 
 
diff --git a/mia/2d/test_datafield.cc b/mia/2d/test_datafield.cc
index 93dfeee..3f87372 100644
--- a/mia/2d/test_datafield.cc
+++ b/mia/2d/test_datafield.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_distance.cc b/mia/2d/test_distance.cc
index 0ddbc54..875ece4 100644
--- a/mia/2d/test_distance.cc
+++ b/mia/2d/test_distance.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_divcurlmatrix.cc b/mia/2d/test_divcurlmatrix.cc
index 283ebfc..3fb55e8 100644
--- a/mia/2d/test_divcurlmatrix.cc
+++ b/mia/2d/test_divcurlmatrix.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_filter.cc b/mia/2d/test_filter.cc
index cc02f65..2c769aa 100644
--- a/mia/2d/test_filter.cc
+++ b/mia/2d/test_filter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,14 +31,13 @@
 
 NS_MIA_USE
 using namespace std; 
-C2DFilterPluginHandlerTestPath filter_test_path; 
 
 BOOST_AUTO_TEST_CASE(test_available_filters)
 {
 	const C2DFilterPluginHandler::Instance& handler = C2DFilterPluginHandler::instance(); 
 
 	set<string> test_data = {
-		"adaptmed", "admean", "aniso", "bandpass", "binarize", "close", "convert", "crop", 
+		"adaptmed", "admean", "aniso", "bandpass", "binarize", "close", "combiner", "convert", "crop", 
 		"dilate", "distance", "downscale", "erode", "gauss", "gradnorm", "invert", "kmeans", 
 		"label", "labelmap", "load", "mask", "mean", "median", "mlv", "ngfnorm", "noise", "open",
 		"pruning", "regiongrow", "sandp", "scale", "selectbig", "sepconv", "shmean", "sort-label", 
@@ -73,3 +72,32 @@ BOOST_AUTO_TEST_CASE(test_run_filters)
 	}
 }
 
+
+BOOST_AUTO_TEST_CASE(test_chain_filters)
+{
+	C2DBounds size(2,2); 
+	const unsigned int   init_data[] = {1, 10, 100, 200}; 
+	const unsigned short test_data[] = {2, 2, 5, 2}; 
+
+	C2DUIImage *int_image = new C2DUIImage(size, init_data); 
+	P2DImage image(int_image); 
+
+	auto allfilters = produce_2dimage_filter("bandpass:min=1,max=150+binarize:min=100,max=200"
+					       "+convert:repn=ushort,map=linear,b=2,a=3"); 
+
+	auto testimg = allfilters->filter(image); 
+
+	BOOST_CHECK_EQUAL(testimg->get_pixel_type(), it_ushort); 
+	auto test_image = dynamic_cast<const C2DUSImage&>(*testimg); 
+	
+	BOOST_CHECK_EQUAL(test_image.get_size(), size); 
+	
+	auto it = test_image.begin(); 
+	auto et = test_image.end(); 
+	auto id = test_data; 
+	while (it != et) {
+		BOOST_CHECK_EQUAL(*it, *id); 
+		++it; ++id; 
+	}
+}
+
diff --git a/mia/2d/test_filter_cast.cc b/mia/2d/test_filter_cast.cc
index 4718c24..6729522 100644
--- a/mia/2d/test_filter_cast.cc
+++ b/mia/2d/test_filter_cast.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_fullcost.cc b/mia/2d/test_fullcost.cc
index 86d2c58..a3e0846 100644
--- a/mia/2d/test_fullcost.cc
+++ b/mia/2d/test_fullcost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,8 +30,6 @@
 NS_MIA_USE
 namespace bfs=::boost::filesystem; 
 
-CSplineKernelTestPath spline_kernel_path_init; 
-
 class C2DFullCostMock: public C2DFullCost {
 public: 
 	C2DFullCostMock(double weight, double cost, double gx, double gy); 
@@ -197,7 +195,7 @@ BOOST_AUTO_TEST_CASE( test_load_plugins )
 {	
 	const C2DFullCostPluginHandler::Instance& handler = PrepareFullcostTests::instance().fullcost_handler(); 
 	BOOST_CHECK_EQUAL(handler.size(), 2u); 
-	BOOST_CHECK_EQUAL(handler.get_plugin_names(), "divcurl image ");
+	BOOST_CHECK_EQUAL(handler.get_plugin_names(), "image maskedimage ");
 }
 
 #if 0 
diff --git a/mia/2d/test_fullcost_mi_spline.cc b/mia/2d/test_fullcost_mi_spline.cc
index 2c2e488..9780d45 100644
--- a/mia/2d/test_fullcost_mi_spline.cc
+++ b/mia/2d/test_fullcost_mi_spline.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,10 +33,6 @@ NS_MIA_USE
 namespace bfs=::boost::filesystem; 
 using namespace std; 
 
-C2DFullCostPluginHandlerTestPath fullcost_path_init; 
-C2DTransformCreatorHandlerTestPath transform_path_init;
-
-
 BOOST_AUTO_TEST_CASE (test_image_spline_gradinet ) 
 {
 	C2DBounds size(mi_test_size.width, mi_test_size.height); 
diff --git a/mia/2d/test_groundtruthproblem.cc b/mia/2d/test_groundtruthproblem.cc
index b7cdd2e..3bf655e 100644
--- a/mia/2d/test_groundtruthproblem.cc
+++ b/mia/2d/test_groundtruthproblem.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,7 +32,6 @@ const size_t N = 5;
 const C2DBounds slice_size(3,3);
 const size_t psize = 5 * 9;
 
-
 struct GroundTruthAccess: public GroundTruthProblem {
 	GroundTruthAccess(const CDoubleVector& left_side,
 			   const  CCorrelationEvaluator::result_type& corr);
diff --git a/mia/2d/test_ica.cc b/mia/2d/test_ica.cc
index ef7d8e0..a648576 100644
--- a/mia/2d/test_ica.cc
+++ b/mia/2d/test_ica.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_image.cc b/mia/2d/test_image.cc
index 3992723..38be58e 100644
--- a/mia/2d/test_image.cc
+++ b/mia/2d/test_image.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_imagecostbase.cc b/mia/2d/test_imagecostbase.cc
index cc21348..716990c 100644
--- a/mia/2d/test_imagecostbase.cc
+++ b/mia/2d/test_imagecostbase.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_imageio.cc b/mia/2d/test_imageio.cc
index 5d9141f..44975c5 100644
--- a/mia/2d/test_imageio.cc
+++ b/mia/2d/test_imageio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,6 +21,7 @@
 #include <mia/internal/autotest.hh>
 #include <boost/filesystem/path.hpp>
 
+#include <mia/core/attribute_names.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/2d/imageio.hh>
 
@@ -30,8 +31,6 @@ using namespace boost;
 using namespace boost::unit_test;
 namespace bfs = ::boost::filesystem; 
 
-C2DImageIOPluginHandlerTestPath test_imageio_path; 
-
 static P2DImage create_test_image(int acquisition, int instance, const string& protocol) 
 {
 	C2DSIImage *image = new C2DSIImage(C2DBounds(1,2)); 
diff --git a/mia/2d/test_interpol.cc b/mia/2d/test_interpol.cc
index 47c5ced..8f6e5d5 100644
--- a/mia/2d/test_interpol.cc
+++ b/mia/2d/test_interpol.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -40,8 +40,6 @@ using namespace boost;
 
 namespace bmpl=boost::mpl;
 
-CSplineKernelTestPath init_splinekernel_path; 
-
 template <class Data2D, class Interpolator>
 void test_interpolator(const Data2D& data, const Interpolator& src)
 {
diff --git a/mia/2d/test_iterator.cc b/mia/2d/test_iterator.cc
index 8ceece9..3238812 100644
--- a/mia/2d/test_iterator.cc
+++ b/mia/2d/test_iterator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
 #include <mia/2d/vectorfield.hh>
 #include <mia/2d/datafield.cxx>
 #include <mia/2d/iterator.cxx>
+#include <mia/2d/image.hh>
 
 NS_MIA_USE;
 
@@ -84,6 +85,34 @@ BOOST_AUTO_TEST_CASE (test_fill_all)
 }
 
 
+BOOST_AUTO_TEST_CASE (test_fill_window) 
+{
+	C2DBounds start(2,3); 
+	C2DBounds size(3,4); 
+	C2DUBImage patch(size);
+	C2DUBImage image(C2DBounds(10,20));
+	
+	unsigned char i = 1; 
+	for (auto k =  patch.begin(); k != patch.end(); ++k, ++i) 
+		*k = i; 
+	
+	
+	copy(patch.begin(), patch.end(), image.begin_range(start, start+size)); 
+	
+
+	i = 1; 
+	auto end = image.end_range(start, start+size); 
+	for (auto k = image.begin_range(start, start+size); k != end; ++k, ++i) 
+		BOOST_CHECK_EQUAL(*k, i); 
+	
+	auto end2 = image.end_range(C2DBounds::_0, image.get_size()); 
+	for (auto k = image.begin_range(C2DBounds::_0, image.get_size()); k != end2; ++k) {
+		if ( k.pos().x < 2 || k.pos().x >= 5 || k.pos().y < 3 || k.pos().y >= 7)
+			     BOOST_CHECK_EQUAL(*k, 0); 
+	}
+}
+
+
 BOOST_AUTO_TEST_CASE (test_access_coordinates) 
 {
 	C2DBounds size(3,4); 
@@ -115,19 +144,19 @@ BOOST_AUTO_TEST_CASE (test_iterator_boundaries)
 	C2DBounds start(0,0);
 	T2DDatafield<int> test(size); 
 	
-	fill(test.begin(), test.end(), C2DFDatafield::range_iterator::eb_none); 
+	fill(test.begin(), test.end(), C2DFDatafield::range_iterator_with_boundary_flag::eb_none); 
 	
 	for (unsigned int  y = 0; y < size.y; ++y) {
-		test(0,y) |= C2DFDatafield::range_iterator::eb_xlow; 
-		test(size.x - 1,y) |= C2DFDatafield::range_iterator::eb_xhigh;
+		test(0,y) |= C2DFDatafield::range_iterator_with_boundary_flag::eb_xlow; 
+		test(size.x - 1,y) |= C2DFDatafield::range_iterator_with_boundary_flag::eb_xhigh;
 	}
 	
 	for (unsigned int  x = 0; x < size.x; ++x) {
-		test(x,0) |= C2DFDatafield::range_iterator::eb_ylow; 
-		test(x, size.y-1) |= C2DFDatafield::range_iterator::eb_yhigh;
+		test(x,0) |= C2DFDatafield::range_iterator_with_boundary_flag::eb_ylow; 
+		test(x, size.y-1) |= C2DFDatafield::range_iterator_with_boundary_flag::eb_yhigh;
 	}
-	auto ifield = field.begin_range(C2DBounds(0,0), size); 
-	auto efield = field.end_range(C2DBounds(0,0), size); 
+	auto ifield = field.begin_range(C2DBounds(0,0), size).with_boundary_flag(); 
+	auto efield = field.end_range(C2DBounds(0,0), size).with_boundary_flag(); 
 	auto itest = test.begin(); 
 	
 	for (;ifield != efield; ++ifield, ++itest) {
@@ -140,16 +169,20 @@ BOOST_AUTO_TEST_CASE (test_iterator_some_boundaries)
 	C2DBounds size(7,5); 
 	C2DFDatafield field(size);
 
-	auto ifield = field.begin_range(C2DBounds(1,1), size - C2DBounds(0,1)); 
-	auto efield = field.end_range(C2DBounds(1,1), size - C2DBounds(0,1)); 
+	auto ifield = field.begin_range(C2DBounds(1,1), size - C2DBounds(0,1)).with_boundary_flag(); 
+	auto efield = field.end_range(C2DBounds(1,1), size - C2DBounds(0,1)).with_boundary_flag(); 
 	
 	for (;ifield != efield; ++ifield) {
 		cvdebug() <<ifield.pos()<< " : " << ifield.get_boundary_flags() << "\n"; 
-		BOOST_CHECK_EQUAL(ifield.pos().x == 0, bool(ifield.get_boundary_flags() & C2DFDatafield::range_iterator::eb_xlow)); 
-		BOOST_CHECK_EQUAL(ifield.pos().y == 0, bool(ifield.get_boundary_flags() & C2DFDatafield::range_iterator::eb_ylow)); 
+		BOOST_CHECK_EQUAL(ifield.pos().x == 0, bool(ifield.get_boundary_flags() & 
+							    C2DFDatafield::range_iterator_with_boundary_flag::eb_xlow)); 
+		BOOST_CHECK_EQUAL(ifield.pos().y == 0, bool(ifield.get_boundary_flags() & 
+							    C2DFDatafield::range_iterator_with_boundary_flag::eb_ylow)); 
 		
-		BOOST_CHECK_EQUAL(ifield.pos().x == 6, bool(ifield.get_boundary_flags() & C2DFDatafield::range_iterator::eb_xhigh)); 
-		BOOST_CHECK_EQUAL(ifield.pos().y == 4, bool(ifield.get_boundary_flags() & C2DFDatafield::range_iterator::eb_yhigh)); 
+		BOOST_CHECK_EQUAL(ifield.pos().x == 6, bool(ifield.get_boundary_flags() & 
+							    C2DFDatafield::range_iterator_with_boundary_flag::eb_xhigh)); 
+		BOOST_CHECK_EQUAL(ifield.pos().y == 4, bool(ifield.get_boundary_flags() & 
+							    C2DFDatafield::range_iterator_with_boundary_flag::eb_yhigh)); 
 	}
 }
 
@@ -160,8 +193,8 @@ BOOST_AUTO_TEST_CASE (test_iterator_no_boundaries)
 
 	C2DBounds start(1,1);
 	
-	auto ifield = field.begin_range(C2DBounds(1,1), size - C2DBounds::_1); 
-	auto efield = field.end_range(C2DBounds(1,1), size - C2DBounds::_1); 
+	auto ifield = field.begin_range(C2DBounds(1,1), size - C2DBounds::_1).with_boundary_flag(); 
+	auto efield = field.end_range(C2DBounds(1,1), size - C2DBounds::_1).with_boundary_flag(); 
 	
 	for (;ifield != efield; ++ifield) {
 		BOOST_CHECK_EQUAL(ifield.get_boundary_flags(), 0); 
@@ -198,6 +231,38 @@ BOOST_AUTO_TEST_CASE (test_fill_part)
 }
 
 
+// this tests whether the traits are properly set
+BOOST_AUTO_TEST_CASE (test_std_copy) 
+{
+	C2DBounds size(7,5); 
+	C2DFVectorfield in_field(size);
+	C2DBounds start(1,2); 
+	C2DBounds end(6,3); 
+	C2DBounds out_size = end - start; 
+	C2DFVectorfield out_field(out_size);
+
+	auto ibegin = in_field.begin_range(start, end);
+	auto iend = in_field.end_range(start, end);
+	
+	while (ibegin != iend) {
+		*ibegin = C2DFVector(ibegin.pos()); 
+		++ibegin; 
+	}
+
+	std::copy(in_field.begin_range(start, end), in_field.end_range(start, end), out_field.begin()); 
+	
+	auto ofb = out_field.begin_range(C2DBounds::_0, out_size); 
+	auto ofe = out_field.end_range(C2DBounds::_0, out_size); 
+	
+	while (ofb != ofe) {
+		BOOST_CHECK_EQUAL(*ofb, C2DFVector(ofb.pos() + start)); 
+		++ofb; 
+	}
+	
+	
+}
+
+
 BOOST_FIXTURE_TEST_CASE (test_const_lala, VFIteratorFixture) 
 {
 	const_range2d_vfiterator begin(C2DBounds(2,2), size, 
diff --git a/mia/2d/test_matrix.cc b/mia/2d/test_matrix.cc
index bebacb9..9f920ae 100644
--- a/mia/2d/test_matrix.cc
+++ b/mia/2d/test_matrix.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_modelsolverreg.cc b/mia/2d/test_modelsolverreg.cc
index dfcfec5..0c6f76b 100644
--- a/mia/2d/test_modelsolverreg.cc
+++ b/mia/2d/test_modelsolverreg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,7 +22,6 @@
 #include <climits>
 
 #include <mia/internal/autotest.hh>
-
 #include <mia/2d/modelsolverreg.hh>
 
 
@@ -30,6 +29,7 @@ NS_MIA_USE
 using namespace boost;
 using namespace std;
 
+
 class TestTimeStep : public C2DRegTimeStep {
 private:
 
diff --git a/mia/2d/test_morphshape.cc b/mia/2d/test_morphshape.cc
index c083bb5..c776386 100644
--- a/mia/2d/test_morphshape.cc
+++ b/mia/2d/test_morphshape.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_nfg.cc b/mia/2d/test_nfg.cc
index 6288bb8..6cd2c5d 100644
--- a/mia/2d/test_nfg.cc
+++ b/mia/2d/test_nfg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_nonrigidregister.cc b/mia/2d/test_nonrigidregister.cc
index 691f5d4..7baca16 100644
--- a/mia/2d/test_nonrigidregister.cc
+++ b/mia/2d/test_nonrigidregister.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_oldnewintegrate.cc b/mia/2d/test_oldnewintegrate.cc
index ef39e99..6a4d366 100644
--- a/mia/2d/test_oldnewintegrate.cc
+++ b/mia/2d/test_oldnewintegrate.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,8 +33,6 @@ using namespace boost;
 
 namespace bmpl=boost::mpl;
 
-CSplineKernelTestPath init_splinekernel_path; 
-
 struct TestIntegral2DFixture {
 
 	void check(double x0, double xF, double s1, double s2, double n, int n1, int n2);
diff --git a/mia/2d/test_param.cc b/mia/2d/test_param.cc
index f5fe86b..016fa7b 100644
--- a/mia/2d/test_param.cc
+++ b/mia/2d/test_param.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_perfusion.cc b/mia/2d/test_perfusion.cc
index dc540da..be84021 100644
--- a/mia/2d/test_perfusion.cc
+++ b/mia/2d/test_perfusion.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_polygon.cc b/mia/2d/test_polygon.cc
index ce82ec7..90bb3e6 100644
--- a/mia/2d/test_polygon.cc
+++ b/mia/2d/test_polygon.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_ppmatrix.cc b/mia/2d/test_ppmatrix.cc
index 27238b5..c7be3d6 100644
--- a/mia/2d/test_ppmatrix.cc
+++ b/mia/2d/test_ppmatrix.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,8 +24,6 @@
 
 NS_MIA_USE;
 
-CSplineKernelTestPath init_splinekernel_path; 
-
 struct TransformSplineFixtureFieldBase {
 	TransformSplineFixtureFieldBase()
 	{
diff --git a/mia/2d/test_register.cc b/mia/2d/test_register.cc
index 6a1e13c..2f931fb 100644
--- a/mia/2d/test_register.cc
+++ b/mia/2d/test_register.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_regplugins.cc b/mia/2d/test_regplugins.cc
index 045487a..e73d290 100644
--- a/mia/2d/test_regplugins.cc
+++ b/mia/2d/test_regplugins.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_rigidregister.cc b/mia/2d/test_rigidregister.cc
index a1e9e03..6512cfe 100644
--- a/mia/2d/test_rigidregister.cc
+++ b/mia/2d/test_rigidregister.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,8 +35,6 @@ using namespace mia;
 using namespace std; 
 namespace bfs=boost::filesystem;
 
-PrepareTestPluginPath g_prepare_pluginpath; 
-
 class RigidRegisterFixture  {
 protected: 
 	RigidRegisterFixture(); 
diff --git a/mia/2d/test_segframe.cc b/mia/2d/test_segframe.cc
index 7a6cdb1..cf449ce 100644
--- a/mia/2d/test_segframe.cc
+++ b/mia/2d/test_segframe.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,10 +21,10 @@
 #include <mia/internal/autotest.hh>
 
 #include <numeric>
-#include <mia/2d/SegSetWithImages.hh>
-#include <mia/2d/BoundingBox.hh>
-#include <mia/2d/inittesthandlers.hh>
+#include <mia/2d/segsetwithimages.hh>
+#include <mia/2d/boundingbox.hh>
 #include <mia/2d/imageio.hh>
+#include <mia/2d/transformfactory.hh>
 #include <libxml++/libxml++.h>
 
 using namespace mia; 
@@ -34,10 +34,6 @@ using namespace ::boost::unit_test;
 using namespace xmlpp;
 namespace bfs=boost::filesystem;
 
-C2DImageIOPluginHandlerTestPath test_imageio2d_path; 
-C2DTransformCreatorHandlerTestPath test_transform2d_creator_path; 
-
-
 extern const char *testframe_init;
 extern const char *testframe_init2;
 const size_t size = 3;
diff --git a/mia/2d/test_segmentation.cc b/mia/2d/test_segmentation.cc
index 6b821f0..d8a6e46 100644
--- a/mia/2d/test_segmentation.cc
+++ b/mia/2d/test_segmentation.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,8 +21,8 @@
 #include <mia/internal/autotest.hh>
 
 #include <numeric>
-#include <mia/2d/SegSetWithImages.hh>
-#include <mia/2d/BoundingBox.hh>
+#include <mia/2d/segsetwithimages.hh>
+#include <mia/2d/boundingbox.hh>
 #include <mia/2d/transformfactory.hh>
 #include <mia/2d/imageio.hh>
 
@@ -30,13 +30,13 @@
 
 namespace bfs=boost::filesystem;
 
+
 NS_MIA_USE
 using namespace std;
 using namespace ::boost;
 using namespace ::boost::unit_test;
 using namespace xmlpp;
 
-
 const char *testpoint_init  =
 	"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test><point y=\"20\" x=\"10\"/></test>\n";
 
@@ -402,9 +402,9 @@ BOOST_AUTO_TEST_CASE(test_segstart_error_attribute)
 input_set.save_images(); 
 */
 
-BOOST_AUTO_TEST_CASE( test_segset_write )
+BOOST_AUTO_TEST_CASE( test_segset_write_version1 )
 {
-	CSegSet segset;
+	CSegSet segset(1);
 	CSegStar star1(CSegPoint2D(109, 118), 21, CSegPoint2D(10, 20),
 		       CSegPoint2D(20, 10), CSegPoint2D(0, 4));
 	CSegStar star2(CSegPoint2D(109, 118), 22, CSegPoint2D(10, 20),
diff --git a/mia/2d/test_segpoint.cc b/mia/2d/test_segpoint.cc
index 9814f39..366e87d 100644
--- a/mia/2d/test_segpoint.cc
+++ b/mia/2d/test_segpoint.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,15 +20,12 @@
 
 #include <mia/internal/autotest.hh>
 #include <mia/2d/transformfactory.hh>
-#include <mia/2d/SegPoint.hh>
+#include <mia/2d/segpoint.hh>
 
 using namespace mia;
 
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath spline_kernel_path_init; 
-
-
 class SegPointSplineTransformFixture {
 protected: 
 	SegPointSplineTransformFixture(); 
@@ -61,10 +58,6 @@ BOOST_FIXTURE_TEST_CASE ( test_inv_transform, SegPointSplineTransformFixture )
 SegPointSplineTransformFixture::SegPointSplineTransformFixture()
 {
 
-	CPathNameArray kernelsearchpath;
-	kernelsearchpath.push_back(bfs::path("transform"));
-	C2DTransformCreatorHandler::set_search_path(kernelsearchpath);
-
 	C2DBounds size(10,10); 
 	auto spline_creator = C2DTransformCreatorHandler::instance().produce("spline:rate=1"); 
 	t = spline_creator->create(size); 
diff --git a/mia/2d/test_shape.cc b/mia/2d/test_shape.cc
index 576a586..33cb374 100644
--- a/mia/2d/test_shape.cc
+++ b/mia/2d/test_shape.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,8 +28,6 @@ NS_MIA_USE
 using namespace std; 
 using namespace boost;
 
-C2DShapePluginHandlerTestPath test_path; 
-
 
 BOOST_AUTO_TEST_CASE( test_2dshape_handler ) 
 {
diff --git a/mia/2d/test_similarity_profile.cc b/mia/2d/test_similarity_profile.cc
index 6a0af60..25fd280 100644
--- a/mia/2d/test_similarity_profile.cc
+++ b/mia/2d/test_similarity_profile.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,8 +28,6 @@
 namespace bfs=::boost::filesystem;
 NS_MIA_USE; 
 
-CSplineKernelTestPath init_splinekernel_path; 
-
 struct SimityProfileFixture {
 	SimityProfileFixture(); 
 
@@ -42,7 +40,7 @@ struct SimityProfileFixture {
 BOOST_FIXTURE_TEST_CASE (test_C2DSimilarityProfile_ref10, SimityProfileFixture) 
 {
 	
-	C2DSimilarityProfile sp(cost, series, 10); 
+	C2DSimilarityProfile sp(cost, series, 10, 0); 
 	// test value obtained by using octave 
 	BOOST_CHECK_CLOSE(sp.get_peak_frequency(), 108.98704, 0.1);
 	
@@ -52,22 +50,6 @@ BOOST_FIXTURE_TEST_CASE (test_C2DSimilarityProfile_ref10, SimityProfileFixture)
 
 SimityProfileFixture::SimityProfileFixture()
 {
-	CPathNameArray cost_plugpath;
-	cost_plugpath.push_back(bfs::path("cost"));
-	C2DImageCostPluginHandler::set_search_path(cost_plugpath);
-
-	CPathNameArray filter_plugpath;
-	filter_plugpath.push_back(bfs::path("filter"));
-	C2DFilterPluginHandler::set_search_path(filter_plugpath);
-
-	CPathNameArray io_plugpath;
-	io_plugpath.push_back(bfs::path("io"));
-	C2DImageIOPluginHandler::set_search_path(io_plugpath);
-
-	CPathNameArray fullcost_plugpath;
-	fullcost_plugpath.push_back(bfs::path("fullcost"));
-	C2DFullCostPluginHandler::set_search_path(fullcost_plugpath);
-
 
 	cost = C2DFullCostPluginHandler::instance().produce("image:cost=ssd");
 
diff --git a/mia/2d/test_sparse_image_solver.cc b/mia/2d/test_sparse_image_solver.cc
index 2e9fd9d..abd180a 100644
--- a/mia/2d/test_sparse_image_solver.cc
+++ b/mia/2d/test_sparse_image_solver.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/test_splinetransformpenalty.cc b/mia/2d/test_splinetransformpenalty.cc
index 6f48f54..fdb3928 100644
--- a/mia/2d/test_splinetransformpenalty.cc
+++ b/mia/2d/test_splinetransformpenalty.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@ NS_MIA_USE;
 class C2DSplinePenaltyMock: public C2DSplineTransformPenalty {
 public: 
 	
-	C2DSplinePenaltyMock(double weight); 
+	C2DSplinePenaltyMock(double weight, bool normalize); 
 	
 private: 
 	void do_initialize(); 
@@ -44,7 +44,7 @@ private:
 
 BOOST_AUTO_TEST_CASE( weight_1_1_1_1p5_2p9_bspline3 )
 {
-	C2DSplinePenaltyMock penalty(1.0); 
+	C2DSplinePenaltyMock penalty(1.0, false); 
 	C2DBounds size(1,1); 
 	penalty.initialize(size, C2DFVector(1.5,2.9), produce_spline_kernel("bspline:d=2"));
 
@@ -69,9 +69,37 @@ BOOST_AUTO_TEST_CASE( weight_1_1_1_1p5_2p9_bspline3 )
 }
 
 
+BOOST_AUTO_TEST_CASE( weight_1_2_2_1p5_2p9_bspline3 )
+{
+	C2DSplinePenaltyMock penalty(1.0, true); 
+	C2DBounds size(2,2); 
+	penalty.initialize(size, C2DFVector(2.0,2.0), produce_spline_kernel("bspline:d=2"));
+
+	C2DFVectorfield coef(size); 
+	coef(0,0) = C2DFVector(2.0,.5); 
+	
+	BOOST_CHECK_CLOSE(penalty.value(coef), .625, 0.1); 
+
+	CDoubleVector grad(8); 
+	BOOST_CHECK_CLOSE(penalty.value_and_gradient(coef, grad), .625, 0.1); 
+
+	BOOST_CHECK_CLOSE(grad[0], .5, 0.1); 
+	BOOST_CHECK_CLOSE(grad[1], .125, 0.1); 
+
+	std::unique_ptr<C2DSplineTransformPenalty> penalty2(penalty.clone()); 
+	
+	BOOST_CHECK_CLOSE(penalty2->value(coef), .625, 0.1); 
+	BOOST_CHECK_CLOSE(penalty2->value_and_gradient(coef, grad), .625, 0.1); 
+	BOOST_CHECK_CLOSE(grad[0], .5, 0.1); 
+	BOOST_CHECK_CLOSE(grad[1], .125, 0.1); 
+	
+}
+
+
+
 BOOST_AUTO_TEST_CASE( weight_0p5_1_1_1p5_2p9_bspline3 )
 {
-	C2DSplinePenaltyMock penalty(0.5); 
+	C2DSplinePenaltyMock penalty(0.5, false); 
 	C2DBounds size(1,1); 
 	penalty.initialize(size, C2DFVector(1.5,2.9), produce_spline_kernel("bspline:d=2"));
 
@@ -97,7 +125,7 @@ BOOST_AUTO_TEST_CASE( weight_0p5_1_1_1p5_2p9_bspline3 )
 
 BOOST_AUTO_TEST_CASE( weight_0p5_2_3_2_3_bspline3 )
 {
-	C2DSplinePenaltyMock penalty(0.5); 
+	C2DSplinePenaltyMock penalty(0.5, false); 
 	C2DBounds size(2,3); 
 	penalty.initialize(size, C2DFVector(2,3), produce_spline_kernel("bspline:d=2"));
 
@@ -157,8 +185,8 @@ BOOST_AUTO_TEST_CASE( weight_0p5_2_3_2_3_bspline3 )
 	BOOST_CHECK_CLOSE(grad[11], 1.0, 0.1); 	
 }
 
-C2DSplinePenaltyMock::C2DSplinePenaltyMock(double weight):
-C2DSplineTransformPenalty(weight)
+C2DSplinePenaltyMock::C2DSplinePenaltyMock(double weight, bool normalize):
+C2DSplineTransformPenalty(weight,normalize)
 {
 }
 
@@ -204,17 +232,11 @@ double C2DSplinePenaltyMock::do_value_and_gradient(const C2DFVectorfield&  coeff
 
 C2DSplineTransformPenalty *C2DSplinePenaltyMock::do_clone() const
 {
-	C2DSplineTransformPenalty *result =  new C2DSplinePenaltyMock(get_weight());
+	C2DSplineTransformPenalty *result =  new C2DSplinePenaltyMock(get_weight(), get_normalize());
 	result->initialize(get_size(), get_range(), get_kernel()); 
 	return result; 
 }
   
-
-CSplineKernelTestPath kernel_test_path; 
-
-
-C2DSplineTransformPenaltyPluginHandlerTest penalty_plug_path; 
-
 BOOST_AUTO_TEST_CASE(test_available_plugins)
 {
 	std::set<std::string> test_data = {"divcurl"}; 
diff --git a/mia/2d/test_trackpoint.cc b/mia/2d/test_trackpoint.cc
index 35b1060..8b4807a 100644
--- a/mia/2d/test_trackpoint.cc
+++ b/mia/2d/test_trackpoint.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,15 +20,12 @@
 
 #include <mia/internal/autotest.hh>
 #include <mia/2d/trackpoint.hh>
-#include <mia/2d/inittesthandlers.hh>
+#include <mia/2d/transformfactory.hh>
 #include <sstream>
 
 using namespace std; 
 using namespace mia; 
 
-C2DTransformCreatorHandlerTestPath test_creator_path; 
-
-
 const char test_input[] = 
 	"1;12;10;5;some text\n"
 	"2;13;7;5;other text\n"
diff --git a/mia/2d/test_transform.cc b/mia/2d/test_transform.cc
index c6b196a..e8efc9d 100644
--- a/mia/2d/test_transform.cc
+++ b/mia/2d/test_transform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,8 +31,6 @@
 NS_MIA_USE; 
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath spline_kernel_path_init; 
-
 class Cost2DMock {
 public: 
 	Cost2DMock(const C2DBounds& size); 
diff --git a/mia/2d/test_transformfactory.cc b/mia/2d/test_transformfactory.cc
index ea47468..63db398 100644
--- a/mia/2d/test_transformfactory.cc
+++ b/mia/2d/test_transformfactory.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,22 +30,9 @@ using namespace ::boost;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath init_splinekernel_path; 
 
-struct HandlerTestFixture {
-	HandlerTestFixture();
 
-};
-
-HandlerTestFixture::HandlerTestFixture()
-{
-
-	CPathNameArray kernelsearchpath;
-	kernelsearchpath.push_back(bfs::path("transform"));
-	C2DTransformCreatorHandler::set_search_path(kernelsearchpath);
-}
-
-BOOST_FIXTURE_TEST_CASE(test_handler, HandlerTestFixture)
+BOOST_AUTO_TEST_CASE(test_handler)
 {
 	const C2DTransformCreatorHandler::Instance& handler =
 		C2DTransformCreatorHandler::instance();
@@ -55,7 +42,7 @@ BOOST_FIXTURE_TEST_CASE(test_handler, HandlerTestFixture)
 }
 
 
-BOOST_FIXTURE_TEST_CASE(test_affine_creator, HandlerTestFixture)
+BOOST_AUTO_TEST_CASE(test_affine_creator)
 {
 	const C2DTransformCreatorHandler::Instance& handler =
 		C2DTransformCreatorHandler::instance();
@@ -64,7 +51,7 @@ BOOST_FIXTURE_TEST_CASE(test_affine_creator, HandlerTestFixture)
 	BOOST_CHECK_EQUAL(transform->get_size(), C2DBounds(10,20));
 }
 
-BOOST_FIXTURE_TEST_CASE(test_spline_creator_isotropic, HandlerTestFixture)
+BOOST_AUTO_TEST_CASE(test_spline_creator_isotropic)
 {
 	const C2DTransformCreatorHandler::Instance& handler =
 		C2DTransformCreatorHandler::instance();
@@ -77,7 +64,7 @@ BOOST_FIXTURE_TEST_CASE(test_spline_creator_isotropic, HandlerTestFixture)
 	BOOST_CHECK_EQUAL(transform->degrees_of_freedom(), static_cast<size_t>((4+4) * (8+4) * 2));
 }
 
-BOOST_FIXTURE_TEST_CASE(test_spline_creator_anisotropic, HandlerTestFixture)
+BOOST_AUTO_TEST_CASE(test_spline_creator_anisotropic)
 {
 	const C2DTransformCreatorHandler::Instance& handler =
 		C2DTransformCreatorHandler::instance();
@@ -91,7 +78,7 @@ BOOST_FIXTURE_TEST_CASE(test_spline_creator_anisotropic, HandlerTestFixture)
 }
 
 
-BOOST_FIXTURE_TEST_CASE(test_vf_creator, HandlerTestFixture)
+BOOST_AUTO_TEST_CASE(test_vf_creator)
 {
 	const C2DTransformCreatorHandler::Instance& handler =
 		C2DTransformCreatorHandler::instance();
@@ -101,7 +88,7 @@ BOOST_FIXTURE_TEST_CASE(test_vf_creator, HandlerTestFixture)
 }
 
 
-BOOST_FIXTURE_TEST_CASE(test_transform_creator, HandlerTestFixture)
+BOOST_AUTO_TEST_CASE(test_transform_creator)
 {
 	const C2DTransformCreatorHandler::Instance& handler =
 		C2DTransformCreatorHandler::instance();
@@ -110,7 +97,7 @@ BOOST_FIXTURE_TEST_CASE(test_transform_creator, HandlerTestFixture)
 	BOOST_CHECK_EQUAL(transform->get_size(), C2DBounds(10,20));
 }
 
-BOOST_FIXTURE_TEST_CASE(test_transform_creator_option, HandlerTestFixture)
+BOOST_AUTO_TEST_CASE(test_transform_creator_option)
 {
 	auto product = C2DTransformCreatorHandler::instance().produce("spline"); 
 	BOOST_CHECK_EQUAL(product->get_init_string(), "spline"); 
@@ -122,7 +109,7 @@ BOOST_FIXTURE_TEST_CASE(test_transform_creator_option, HandlerTestFixture)
 	
 }
 
-BOOST_FIXTURE_TEST_CASE(test_transform_creator_option2, HandlerTestFixture)
+BOOST_AUTO_TEST_CASE(test_transform_creator_option2)
 {
 	C2DTransformCreatorHandler::ProductPtr product; 
 	
diff --git a/mia/2d/test_transio.cc b/mia/2d/test_transio.cc
index 0f49aa1..3632cf8 100644
--- a/mia/2d/test_transio.cc
+++ b/mia/2d/test_transio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,19 +24,17 @@
 
 NS_MIA_USE; 
 using std::stringstream; 
+using std::string; 
 
 namespace bfs=::boost::filesystem; 
 
-CSplineKernelTestPath spline_kernel_path_init; 
-
 class PrepareTransIOTests {
 public: 
 	static const PrepareTransIOTests& instance(); 
+	PrepareTransIOTests(){}; 
 	
 	const C2DTransformationIOPluginHandler::Instance& transformio_handler()const; 
 	const C2DTransformCreatorHandler::Instance& transform_handler()const; 
-private:
-	PrepareTransIOTests(); 
 }; 
 
 BOOST_AUTO_TEST_CASE(test_transform_io) 
@@ -72,6 +70,8 @@ BOOST_AUTO_TEST_CASE(test_transform_io)
 		for (size_t k = 0; k < params.size(); ++k) 
 			params[k] = k + 1; 
 		tr->set_parameters(params);
+
+		tr->set_attribute("string_attr", "string"); 
 		
 		for (size_t i = 0; i < n_io; ++i) {
 			stringstream fname; 
@@ -88,8 +88,11 @@ BOOST_AUTO_TEST_CASE(test_transform_io)
 			BOOST_CHECK_EQUAL(lparams.size(), params.size()); 
 			for (size_t k = 0; k < lparams.size(); ++k) 
 				BOOST_CHECK_EQUAL(lparams[k], k + 1); 
+			
+			BOOST_REQUIRE(t_loaded->has_attribute("string_attr")); 
+			BOOST_CHECK_EQUAL(t_loaded->get_attribute_as<string>("string_attr"), "string"); 
 			unlink( fname.str().c_str()); 
-
+			
 		}
 	}
 }
@@ -112,16 +115,3 @@ const C2DTransformCreatorHandler::Instance& PrepareTransIOTests::transform_handl
 	return C2DTransformCreatorHandler::instance(); 
 }
 
-PrepareTransIOTests::PrepareTransIOTests()
-{
-	CPathNameArray transformio_plugpath; 
-	transformio_plugpath.push_back(bfs::path("transio"));
-	C2DTransformationIOPluginHandler::set_search_path(transformio_plugpath);
-	
-	CPathNameArray transform_searchpath;
-	transform_searchpath.push_back(bfs::path("transform"));
-	C2DTransformCreatorHandler::set_search_path(transform_searchpath);
-
-}
-
-
diff --git a/mia/2d/test_vector.cc b/mia/2d/test_vector.cc
index 1c35dc3..756f988 100644
--- a/mia/2d/test_vector.cc
+++ b/mia/2d/test_vector.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -122,3 +122,14 @@ BOOST_AUTO_TEST_CASE(test_vector_fill)
 
 }
 
+BOOST_AUTO_TEST_CASE( test_minus )
+{
+	T2DVector<int> test(1,-2);
+	T2DVector<int> mtest = -test; 
+
+	BOOST_CHECK_EQUAL(mtest.x, -1);
+	BOOST_CHECK_EQUAL(mtest.y,  2);
+
+
+
+}
diff --git a/mia/2d/test_vectorfield_interpolator.cc b/mia/2d/test_vectorfield_interpolator.cc
index 54ec0c6..ec92320 100644
--- a/mia/2d/test_vectorfield_interpolator.cc
+++ b/mia/2d/test_vectorfield_interpolator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,8 +32,6 @@ using namespace ::boost;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath init_splinekernel_path; 
-
 struct FieldSplineFixture {
 	FieldSplineFixture():
 		size(30, 32),
@@ -50,10 +48,6 @@ struct FieldSplineFixture {
 
 		std::shared_ptr<T2DInterpolator<C2DFVector>  > source(ipf.create(field));
 
-		CPathNameArray kernelsearchpath;
-		kernelsearchpath.push_back(bfs::path("../core/spacialkernel"));
-		C1DSpacialKernelPluginHandler::set_search_path(kernelsearchpath);
-
 	}
 	C2DBounds size;
 	C2DFVectorfield field;
diff --git a/mia/2d/test_vfio.cc b/mia/2d/test_vfio.cc
index 9d9c426..5b72380 100644
--- a/mia/2d/test_vfio.cc
+++ b/mia/2d/test_vfio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/timestep.cc b/mia/2d/timestep.cc
index 6c4067f..4bdd1bc 100644
--- a/mia/2d/timestep.cc
+++ b/mia/2d/timestep.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/timestep.hh b/mia/2d/timestep.hh
index 3b55b68..096e9ca 100644
--- a/mia/2d/timestep.hh
+++ b/mia/2d/timestep.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/timestep/CMakeLists.txt b/mia/2d/timestep/CMakeLists.txt
index d588f50..cb2dae7 100644
--- a/mia/2d/timestep/CMakeLists.txt
+++ b/mia/2d/timestep/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/timestep/direct.cc b/mia/2d/timestep/direct.cc
index ce31050..e91b88f 100644
--- a/mia/2d/timestep/direct.cc
+++ b/mia/2d/timestep/direct.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/timestep/direct.hh b/mia/2d/timestep/direct.hh
index ccb5021..f17905e 100644
--- a/mia/2d/timestep/direct.hh
+++ b/mia/2d/timestep/direct.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/timestep/fluid.cc b/mia/2d/timestep/fluid.cc
index 975d134..0ee0e91 100644
--- a/mia/2d/timestep/fluid.cc
+++ b/mia/2d/timestep/fluid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/timestep/fluid.hh b/mia/2d/timestep/fluid.hh
index 5d28d1c..88622fb 100644
--- a/mia/2d/timestep/fluid.hh
+++ b/mia/2d/timestep/fluid.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/timestep/test_direct.cc b/mia/2d/timestep/test_direct.cc
index 61bbba2..4dccea3 100644
--- a/mia/2d/timestep/test_direct.cc
+++ b/mia/2d/timestep/test_direct.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,8 +25,6 @@
 NS_USE(direct_timestep_2d);
 NS_MIA_USE;
 
-CSplineKernelTestPath kernel_test_path; 
-
 class C2DDummyTransformation: public C2DTransformMock {
 
 
diff --git a/mia/2d/timestep/test_fluid.cc b/mia/2d/timestep/test_fluid.cc
index d1b1f2c..3d97a4f 100644
--- a/mia/2d/timestep/test_fluid.cc
+++ b/mia/2d/timestep/test_fluid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,8 +25,6 @@
 NS_USE(fluid_timestep_2d);
 NS_MIA_USE;
 
-CSplineKernelTestPath kernel_test_path; 
-
 class C2DDummyTransformation: public C2DTransformMock {
 	virtual C2DTransformation *clone() const {
 		return new C2DDummyTransformation();
diff --git a/mia/2d/trackpoint.cc b/mia/2d/trackpoint.cc
index 4a8f71b..501c1f2 100644
--- a/mia/2d/trackpoint.cc
+++ b/mia/2d/trackpoint.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/trackpoint.hh b/mia/2d/trackpoint.hh
index d1f1b69..15bca70 100644
--- a/mia/2d/trackpoint.hh
+++ b/mia/2d/trackpoint.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 David Pastor, Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 David Pastor, Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/trait.hh b/mia/2d/trait.hh
index 3fc0f81..c184ca9 100644
--- a/mia/2d/trait.hh
+++ b/mia/2d/trait.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/transform.cc b/mia/2d/transform.cc
index afb66a5..b35fad3 100644
--- a/mia/2d/transform.cc
+++ b/mia/2d/transform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -214,11 +214,28 @@ const C2DFVector  *C2DTransformation::const_iterator::operator ->() const
 	return &m_holder->get_value(); 
 }
 
+const C2DBounds& C2DTransformation::const_iterator::pos() const
+{
+	assert(m_holder); 
+	return m_holder->get_pos(); 
+}
+
+const C2DBounds& C2DTransformation::const_iterator::get_size() const
+{
+	assert(m_holder); 
+	return m_holder->get_size(); 
+}
+
+
 bool C2DTransformation::refine()
 {
 	return false; 
 }
 
+C2DBounds C2DTransformation::get_minimal_supported_image_size() const
+{
+	return C2DBounds::_1;
+}
 
 /**
    @brief Helper functor for 2D image transformations 
diff --git a/mia/2d/transform.hh b/mia/2d/transform.hh
index 25b76e6..b378f5a 100644
--- a/mia/2d/transform.hh
+++ b/mia/2d/transform.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -204,6 +204,10 @@ public:
 		/// @returns the pointer version of the current value of the transformation 
 		const C2DFVector  *operator ->() const;
 
+		const C2DBounds& pos() const; 
+
+		const C2DBounds& get_size() const; 
+
 		/** Print the current position and value to an output stream 
 		    \param os 
 		*/
@@ -351,30 +355,30 @@ public:
 
 
 	/**
-	   Evaluate the grad div ^2 + grad rot ^2 value and its gradient for the 
-	   transformtion 
-	   \param wd weight of the divergence
-	   \param wr weight of the rotation 
-	   \param[out] gradient vector to hold the resulting gradient 
-	   \returns cost function value 
+	   If applicaple the transformation model is refined (e.g. splines 
+	   are converted to a denser coefficient distribution. 
+	   \returns \a true if refinement was applied, and \a false otherwise
 	 */
-	virtual double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const = 0; 
+	virtual bool refine(); 
 
+	/* Attributes */
 	/**
-	   Evaluate the grad div ^2 + grad rot ^2 value for the transformtion 
-	   \param wd weight of the divergence
-	   \param wr weight of the rotation 
-	   \returns cost function value 
+	   This attribute defines the voxel spacing of the input data of this transform. 
 	 */
+	static constexpr const char *input_spacing_attr = "in-pixel-spacing"; 
+
+	/**
+	   This attribute defines the output voxel spacing of this transform. 
+	 */
+	static constexpr const char *output_spacing_attr = "out-pixel-spacing"; 
 
-	virtual double get_divcurl_cost(double wd, double wr) const = 0; 
 
 	/**
-	   If applicaple the transformation model is refined (e.g. splines 
-	   are converted to a denser coefficient distribution. 
-	   \returns \a true if refinement was applied, and \a false otherwise
+	   \returns the minimal image size that makes sense for the transformation. 
+	   Usually this is (1,1), but for spline based transformation the image must 
+	   be larger. 
 	 */
-	virtual bool refine(); 
+	virtual C2DBounds get_minimal_supported_image_size() const; 
 
 private: 
 
diff --git a/mia/2d/transform/CMakeLists.txt b/mia/2d/transform/CMakeLists.txt
index 3e76d38..c308a45 100644
--- a/mia/2d/transform/CMakeLists.txt
+++ b/mia/2d/transform/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,6 +16,9 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 
-SET(transforms affine rigid rotation spline translate vectorfield) 
+SET(transforms affine rigid rotation translate) 
 PLUGINGROUP_WITH_TEST_AND_PREFIX2("2dimage" "transform" "${transforms}" "${MIA2DLIBS}")
 
+SET(nonlinear_src spline.cc  vectorfield.cc) 
+PLUGIN_WITH_TEST_MULTISOURCE("nonlinear" "2dimage" "transform" "${nonlinear_src}" "${MIA2DLIBS}") 
+
diff --git a/mia/2d/transform/affine.cc b/mia/2d/transform/affine.cc
index f29195d..6ea2515 100644
--- a/mia/2d/transform/affine.cc
+++ b/mia/2d/transform/affine.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -163,39 +163,6 @@ void C2DAffineTransformation::set_parameters(const CDoubleVector& params)
 
 }
 
-double C2DAffineTransformation::get_divcurl_cost(double, double, CDoubleVector&) const
-{
-	return 0.0; 
-}
-
-double C2DAffineTransformation::get_divcurl_cost(double, double) const
-{
-	return 0.0; 
-}
-
-
-float C2DAffineTransformation::divergence() const
-{
-	return m_t[0] + m_t[1] + m_t[3] + m_t[4] - 2.0f;
-}
-
-float C2DAffineTransformation::grad_divergence() const
-{
-	return 0.0;
-}
-
-
-float C2DAffineTransformation::grad_curl() const
-{
-	return 0.0;
-}
-
-
-float C2DAffineTransformation::curl() const
-{
-	return m_t[1] + m_t[4] - m_t[0] - m_t[3];
-}
-
 const C2DBounds& C2DAffineTransformation::get_size() const
 {
 	return m_size;
diff --git a/mia/2d/transform/affine.hh b/mia/2d/transform/affine.hh
index a675269..b4b07da 100644
--- a/mia/2d/transform/affine.hh
+++ b/mia/2d/transform/affine.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -87,12 +87,6 @@ public:
 	virtual C2DFVector operator () (const C2DFVector& x) const;
 	virtual float get_jacobian(const C2DFVectorfield& v, float delta) const;
 	C2DFVector transform(const C2DFVector& x)const;
-	virtual float divergence() const;
-	virtual float curl() const;
-	float grad_divergence() const;
-	float grad_curl() const;
-	double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	double get_divcurl_cost(double wd, double wr) const; 
 private:
 	virtual C2DTransformation *do_clone() const;
 	void evaluate_t() const;
diff --git a/mia/2d/transform/rigid.cc b/mia/2d/transform/rigid.cc
index 75596d5..ca7b1f6 100644
--- a/mia/2d/transform/rigid.cc
+++ b/mia/2d/transform/rigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -161,40 +161,6 @@ void C2DRigidTransformation::set_parameters(const CDoubleVector& params)
 	m_matrix_valid = false;
 }
 
-float C2DRigidTransformation::divergence() const
-{
-	return 0.0;
-}
-
-float C2DRigidTransformation::grad_divergence() const
-{
-	return 0.0;
-}
-
-
-float C2DRigidTransformation::grad_curl() const
-{
-	return 0.0;
-}
-
-
-float C2DRigidTransformation::curl() const
-{
-	// this is not right
-	return m_rotation;
-}
-
-double C2DRigidTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/, CDoubleVector& /*gradient*/) const
-{
-	return 0.0; 
-}
-
-double C2DRigidTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/) const
-{
-	return 0.0; 
-}
-
-
 const C2DBounds& C2DRigidTransformation::get_size() const
 {
 	return m_size;
diff --git a/mia/2d/transform/rigid.hh b/mia/2d/transform/rigid.hh
index 237ded0..7d0afe2 100644
--- a/mia/2d/transform/rigid.hh
+++ b/mia/2d/transform/rigid.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -88,12 +88,6 @@ public:
 	virtual C2DFVector operator () (const C2DFVector& x) const;
 	virtual float get_jacobian(const C2DFVectorfield& v, float delta) const;
 	C2DFVector transform(const C2DFVector& x)const;
-	virtual float divergence() const;
-	virtual float curl() const;
-	float grad_divergence() const;
-	float grad_curl() const;
-	double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	double get_divcurl_cost(double wd, double wr) const; 
 private:
 	void initialize(); 
 	virtual C2DTransformation *do_clone() const;
diff --git a/mia/2d/transform/rotation.cc b/mia/2d/transform/rotation.cc
index c54d94c..b49007d 100644
--- a/mia/2d/transform/rotation.cc
+++ b/mia/2d/transform/rotation.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -131,39 +131,6 @@ void C2DRotationTransformation::set_parameters(const CDoubleVector& params)
 	m_matrix_valid = false;
 }
 
-float C2DRotationTransformation::divergence() const
-{
-	return 0.0;
-}
-
-float C2DRotationTransformation::grad_divergence() const
-{
-	return 0.0;
-}
-
-
-float C2DRotationTransformation::grad_curl() const
-{
-	return 0.0;
-}
-
-
-float C2DRotationTransformation::curl() const
-{
-	// this is not right
-	return m_rotation;
-}
-
-double C2DRotationTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/, CDoubleVector& /*gradient*/) const
-{
-	return 0.0; 
-}
-
-double C2DRotationTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/) const
-{
-	return 0.0; 
-}
-
 
 const C2DBounds& C2DRotationTransformation::get_size() const
 {
diff --git a/mia/2d/transform/rotation.hh b/mia/2d/transform/rotation.hh
index 6e510c8..f6a1683 100644
--- a/mia/2d/transform/rotation.hh
+++ b/mia/2d/transform/rotation.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -79,12 +79,6 @@ public:
 	virtual C2DFVector operator () (const C2DFVector& x) const;
 	virtual float get_jacobian(const C2DFVectorfield& v, float delta) const;
 	C2DFVector transform(const C2DFVector& x)const;
-	virtual float divergence() const;
-	virtual float curl() const;
-	float grad_divergence() const;
-	float grad_curl() const;
-	double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	double get_divcurl_cost(double wd, double wr) const; 
 private:
 	void initialize(); 
 	virtual C2DTransformation *do_clone() const;
diff --git a/mia/2d/transform/spline.cc b/mia/2d/transform/spline.cc
index 75c3d7d..4a54a4e 100644
--- a/mia/2d/transform/spline.cc
+++ b/mia/2d/transform/spline.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
 #include <iomanip>
 #include <numeric>
 #include <mia/2d/transform/spline.hh>
+#include <mia/2d/transform/vectorfield.hh>
 #include <mia/2d/transformfactory.hh>
 
 
@@ -207,6 +208,11 @@ void C2DSplineTransformation::reinit()
 	}
 }
 
+C2DBounds C2DSplineTransformation::get_minimal_supported_image_size() const
+{
+	return C2DBounds(ceil(m_target_c_rate.x), ceil(m_target_c_rate.y)) + C2DBounds::_1; 
+}
+
 C2DFVector C2DSplineTransformation::interpolate(const C2DFVector& x) const 
 {
 	TRACE_FUNCTION;
@@ -242,10 +248,30 @@ C2DTransformation *C2DSplineTransformation::do_clone()const
 	return new C2DSplineTransformation(*this);
 }
 
+C2DFVector C2DSplineTransformation::find_inverse(const C2DBounds& x) const 
+{
+	C2DFVector r(x);
+	int niter = 0; 
+	C2DFVector delta = (*this)(r) - r;
+	while (delta.norm2() > 0.000001 && niter++ < 100) {
+		r -= 0.1 * delta; 
+		delta = (*this)(r) - r; 
+	}
+	return r; 
+}
+
 C2DTransformation *C2DSplineTransformation::invert() const
 {
 	assert(0 && "not implemented"); 
-	return new C2DSplineTransformation(*this);
+	C2DGridTransformation *result = new C2DGridTransformation(get_size(), get_interpolator_factory());
+	
+	auto iv = result->field_begin(); 
+	
+	for (unsigned y = 0; y < get_size().y; ++y) 
+		for (unsigned x = 0; x < get_size().x; ++x, ++iv) 
+			*iv = find_inverse(C2DBounds(x,y)); 
+
+	return result;
 }
 
 
@@ -661,35 +687,6 @@ void C2DSplineTransformation::iterator_impl::do_y_increment()
 	m_value_valid = false; 
 }
 
-
-double C2DSplineTransformation::get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const
-{
-	// create PP matrices or adapt size 
-	if (!m_divcurl_matrix) 
-		m_divcurl_matrix.reset(new C2DPPDivcurlMatrix(m_coefficients.get_size(), m_range, 
-							       *m_kernel, wd, wr)); 
-	else 
-		m_divcurl_matrix->reset(m_coefficients.get_size(), m_range, 
-					 *m_kernel, wd, wr); 
-	
-	
-	return m_divcurl_matrix->evaluate(m_coefficients, gradient); 
-}
-
-double C2DSplineTransformation::get_divcurl_cost(double wd, double wr) const
-{
-	// create PP matrices or adapt size 
-	if (!m_divcurl_matrix) 
-		m_divcurl_matrix.reset(new C2DPPDivcurlMatrix(m_coefficients.get_size(), m_range, 
-							       *m_kernel, wd, wr)); 
-	else 
-		m_divcurl_matrix->reset(m_coefficients.get_size(), m_range, 
-					 *m_kernel, wd, wr); 
-	
-
-	return *m_divcurl_matrix * m_coefficients; 
-}
-
 double C2DSplineTransformation::do_get_energy_penalty_and_gradient(CDoubleVector& gradient) const
 {
 	assert(m_penalty); 
@@ -736,20 +733,6 @@ P2DTransformation C2DSplineTransformCreator::do_create(const C2DBounds& size, co
 }
 
 
-
-
-class C2DSplineTransformCreatorPlugin: public C2DTransformCreatorPlugin {
-public:
-	C2DSplineTransformCreatorPlugin();
-	virtual C2DTransformCreator *do_create(const C2DInterpolatorFactory& ipf) const;
-	const std::string do_get_descr() const;
-private:
-	PSplineKernel m_interpolator;
-	float m_rate; 
-	C2DFVector m_rate2d;
-	P2DSplineTransformPenalty m_penalty; 
-};
-
 C2DSplineTransformCreatorPlugin::C2DSplineTransformCreatorPlugin():
 	C2DTransformCreatorPlugin("spline"),
 	m_rate(10), 
@@ -781,7 +764,10 @@ const std::string C2DSplineTransformCreatorPlugin::do_get_descr() const
 
 extern "C" EXPORT CPluginBase *get_plugin_interface()
 {
-	return new C2DSplineTransformCreatorPlugin();
+	auto p = new C2DGridTransformCreatorPlugin();
+	p->append_interface(new C2DSplineTransformCreatorPlugin()); 
+	return p; 
+
 }
 
 NS_MIA_END
diff --git a/mia/2d/transform/spline.hh b/mia/2d/transform/spline.hh
index 3196203..1d4ae9b 100644
--- a/mia/2d/transform/spline.hh
+++ b/mia/2d/transform/spline.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 #define mia_2d_splinetransform_hh
 
 #include <mia/2d/interpolator.hh>
-#include <mia/2d/transform.hh>
+#include <mia/2d/transformfactory.hh>
 #include <mia/2d/splinetransformpenalty.hh>
 #include <mia/2d/ppmatrix.hh>
 
@@ -87,15 +87,14 @@ public:
 	virtual float pertuberate(C2DFVectorfield& v) const;
 	virtual float get_jacobian(const C2DFVectorfield& v, float delta) const;
 	virtual C2DFVector operator () (const C2DFVector& x) const;
-
-	virtual double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	virtual double get_divcurl_cost(double wd, double wr) const; 
+	virtual C2DBounds get_minimal_supported_image_size() const; 
 
 	C2DFVector on_grid(const mia::C2DBounds& x) const; 
 
 
 private:
 	C2DFMatrix do_derivative_at(const C2DFVector& x) const;
+	C2DFVector find_inverse(const C2DBounds& x) const; 
 	
 	typedef std::vector<std::pair<int, std::vector<float> > > CSplineDerivativeRow; 
 	CSplineDerivativeRow get_derivative_row(size_t nin, size_t nout, double scale) const; 
@@ -121,7 +120,6 @@ private:
 	C2DFVector m_inv_scale;
 	bool m_interpolator_valid;
 	//mutable std::shared_ptr<T2DConvoluteInterpolator<C2DFVector> >  m_interpolator;
-	mutable std::shared_ptr<C2DPPDivcurlMatrix > m_divcurl_matrix; 
 	std::vector<std::vector<double> > m_x_weights; 
 	std::vector<int> m_x_indices; 
 	std::vector<std::vector<double> > m_y_weights; 
@@ -136,6 +134,20 @@ private:
 
 };
 
+
+
+class C2DSplineTransformCreatorPlugin: public C2DTransformCreatorPlugin {
+public:
+	C2DSplineTransformCreatorPlugin();
+	virtual C2DTransformCreator *do_create(const C2DInterpolatorFactory& ipf) const;
+	const std::string do_get_descr() const;
+private:
+	PSplineKernel m_interpolator;
+	float m_rate; 
+	C2DFVector m_rate2d;
+	P2DSplineTransformPenalty m_penalty; 
+};
+
 NS_MIA_END
 
 #endif
diff --git a/mia/2d/transform/test_affine.cc b/mia/2d/transform/test_affine.cc
index dee08af..9d1e47a 100644
--- a/mia/2d/transform/test_affine.cc
+++ b/mia/2d/transform/test_affine.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,8 +30,6 @@ using namespace ::boost;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath kernel_test_path; 
-
 struct ipfFixture {
 	ipfFixture():ipf("bspline:d=3", "mirror") {}
 	C2DInterpolatorFactory ipf; 
@@ -202,17 +200,6 @@ BOOST_FIXTURE_TEST_CASE( test_affine_clone, TranslateTransFixture )
 }
 
 
-BOOST_FIXTURE_TEST_CASE( test_gridtransform_get_curl, RotateTransFixture )
-{
-	BOOST_CHECK_CLOSE(rtrans.grad_curl()+ 1.0, 1.0, 0.1);
-}
-
-BOOST_FIXTURE_TEST_CASE( test_gridtransform_get_divergence, RotateTransFixture )
-{
-	BOOST_CHECK_CLOSE(rtrans.grad_divergence() + 1.0, 1.0, 0.1);
-}
-
-
 BOOST_FIXTURE_TEST_CASE(derivative_RotateTransFixture, RotateTransFixture)
 {
 	C2DFMatrix d = 	rtrans.derivative_at(10,10);
diff --git a/mia/2d/transform/test_nonlinear.cc b/mia/2d/transform/test_nonlinear.cc
new file mode 100644
index 0000000..e4293f2
--- /dev/null
+++ b/mia/2d/transform/test_nonlinear.cc
@@ -0,0 +1,25 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+
+#include "test_spline.cc"
+#include "test_vectorfield.cc"
+
diff --git a/mia/2d/transform/test_rigid.cc b/mia/2d/transform/test_rigid.cc
index c557fe4..5b97005 100644
--- a/mia/2d/transform/test_rigid.cc
+++ b/mia/2d/transform/test_rigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,8 +31,6 @@ using namespace ::boost;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath kernel_test_path; 
-
 struct TranslateTransFixture {
 	TranslateTransFixture():size(60, 80),
 				rtrans(size, C2DFVector::_0, C2DInterpolatorFactory("bspline:d=3", "mirror"))
@@ -213,16 +211,6 @@ BOOST_FIXTURE_TEST_CASE( test_rigid_clone, TranslateTransFixture )
 	}
 }
 
-BOOST_FIXTURE_TEST_CASE( test_gridtransform_get_curl, RotateTransFixture )
-{
-	BOOST_CHECK_CLOSE(rtrans.grad_curl()+ 1.0, 1.0, 0.1);
-}
-
-BOOST_FIXTURE_TEST_CASE( test_gridtransform_get_divergence, RotateTransFixture )
-{
-	BOOST_CHECK_CLOSE(rtrans.grad_divergence() + 1.0, 1.0, 0.1);
-}
-
 BOOST_FIXTURE_TEST_CASE(derivative_RotateTransFixture, RotateTransFixture)
 {
 	C2DFMatrix d = 	rtrans.derivative_at(10,10);
diff --git a/mia/2d/transform/test_rotation.cc b/mia/2d/transform/test_rotation.cc
index 47d58ad..add8ccf 100644
--- a/mia/2d/transform/test_rotation.cc
+++ b/mia/2d/transform/test_rotation.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,10 +30,6 @@ using namespace ::boost;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath kernel_test_path; 
-
-
-
 struct ipfFixture {
 	ipfFixture():
 		ipf("bspline:d=3", "mirror")
diff --git a/mia/2d/transform/test_spline.cc b/mia/2d/transform/test_spline.cc
index 9434a30..e298a8c 100644
--- a/mia/2d/transform/test_spline.cc
+++ b/mia/2d/transform/test_spline.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,7 +20,6 @@
 
 #include <cmath>
 #include <fstream>
-#include <mia/internal/autotest.hh>
 
 #include <mia/core/spacial_kernel.hh>
 #include <mia/2d/interpolator.hh>
@@ -34,8 +33,6 @@ using namespace ::boost;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath init_path; 
-
 struct TransformSplineFixture {
 	TransformSplineFixture():
 		size(33,65),
diff --git a/mia/2d/transform/test_translate.cc b/mia/2d/transform/test_translate.cc
index 2009cb5..1335dd9 100644
--- a/mia/2d/transform/test_translate.cc
+++ b/mia/2d/transform/test_translate.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,8 +26,6 @@
 NS_MIA_USE
 using namespace std; 
 
-CSplineKernelTestPath init_path; 
-
 struct TranslateTransformFixture {
 
 	TranslateTransformFixture();
diff --git a/mia/2d/transform/test_vectorfield.cc b/mia/2d/transform/test_vectorfield.cc
index baa7b6f..84f7149 100644
--- a/mia/2d/transform/test_vectorfield.cc
+++ b/mia/2d/transform/test_vectorfield.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,8 +19,6 @@
  */
 
 #include <cmath>
-#include <mia/internal/autotest.hh>
-
 #include <mia/core/spacial_kernel.hh>
 #include <mia/2d/transform/vectorfield.hh>
 
@@ -30,8 +28,6 @@ using namespace std;
 using namespace ::boost;
 using namespace boost::unit_test;
 
-CSplineKernelTestPath kernel_path_init; 
-
 struct GridTransformFixture {
 	GridTransformFixture():
 		size(256, 128),
@@ -650,185 +646,6 @@ BOOST_FIXTURE_TEST_CASE( DivGradFixture_selftest, DivGradFixture )
 	
 }
 
-BOOST_FIXTURE_TEST_CASE( test_grid_derivatives, DivGradFixture ) 
-{
-	const int x = 120; 
-	const int y = 131; 
-	
-	BOOST_CHECK_CLOSE(field.dddgx_xxx(x,y), dddgx_xxx(x,y), 0.5); 
-	BOOST_CHECK_CLOSE(field.dddgy_yyy(x,y), dddgy_yyy(x,y), 0.5); 
-	
-	C2DFVector ddd_xx = field.ddg_xx(x, y); 
-	BOOST_CHECK_CLOSE(ddd_xx.x, ddgx_xx(x,y), 0.5); 
-	BOOST_CHECK_CLOSE(ddd_xx.y, ddgy_xx(x,y), 0.5); 
-
-	C2DFVector ddd_xxy = field.dddg_xxy(x, y); 
-	
-	BOOST_CHECK_CLOSE(ddd_xxy.x, dddgx_xxy(x,y), 0.5); 
-	BOOST_CHECK_CLOSE(ddd_xxy.y, dddgy_xxy(x,y), 0.5); 
-
-	C2DFVector ddd_yy = field.ddg_yy(x, y); 
-	BOOST_CHECK_CLOSE(ddd_yy.x, ddgx_yy(x,y), 0.5); 
-	BOOST_CHECK_CLOSE(ddd_yy.y, ddgy_yy(x,y), 0.5); 
-
-	C2DFVector ddd_yyx = field.dddg_yyx(x, y); 
-	
-	BOOST_CHECK_CLOSE(ddd_yyx.x, dddgx_yyx(x,y), 0.5); 
-	BOOST_CHECK_CLOSE(ddd_yyx.y, dddgy_yyx(x,y), 0.5); 
-
-	C2DFVector dd_xy = field.ddg_xy(x, y); 
-	BOOST_CHECK_CLOSE(dd_xy.x, ddgx_xy(x,y), 0.5); 
-	BOOST_CHECK_CLOSE(dd_xy.y, ddgy_xy(x,y), 0.5); 
-	
-
-}
-
-///\todo gradient of grid-divcurl needs testing too
-BOOST_FIXTURE_TEST_CASE( test_grid_div_value, DivGradFixture )
-{
-
-	CDoubleVector gradient(field.degrees_of_freedom(), true); 
-	double divcurlcost =  field.get_divcurl_cost(1.0, 0.0, gradient); 
-	BOOST_CHECK_CLOSE(corr*corr*divcurlcost, 6 * M_PI, 0.2); 
-
-	double curlcost =  field.get_divcurl_cost(0.0, 1.0, gradient); 
-	BOOST_CHECK_CLOSE(1.0 + curlcost, 1.0, 1); 
-
-
-	// strange that it would multiply by the range ... 
-	double divcost =  field.get_divcurl_cost(1.0, 1.0, gradient); 
-	BOOST_CHECK_CLOSE(corr*corr*divcost, 6 * M_PI, 0.2); 
-
-}
-
-BOOST_FIXTURE_TEST_CASE( test_grid_div_gradient_at, DivGradFixture )
-{
-	float s2 = scale * scale; 
-	float fx = scale * (140-dsize); 
-	float fy = scale * (132-dsize); 
-	float x2y2 = fx * fx + fy * fy; 
-	float e2x2y2 = exp(-2 * x2y2);
-	
-	float help = -32 * s2 * s2 * scale * ( x2y2 - 2) * ( 2 * x2y2 * x2y2  - 7 * x2y2 + 2) * e2x2y2;
-	float dx = fx * help; 
-	float dy = fy * help; 
-	C2DFVector g = field.get_graddiv_at(140, 132); 
-	BOOST_CHECK_CLOSE(g.x, dx, 0.4); 
-	BOOST_CHECK_CLOSE(g.y, dy, 0.4); 
-}
-
-BOOST_FIXTURE_TEST_CASE( test_grid_div_gradient_full, DivGradFixture )
-{
-	CDoubleVector gradient(field.degrees_of_freedom(), true); 
-	field.get_divcurl_cost(1.0, 0.0, gradient); 
-
-
-	auto ig = gradient.begin() + 4*(size.x + 1); 
-	for (int y = 2; y < (int)size.y-2; ++y, ig += 8) 
-		for (int x = 2; x < (int)size.x-2; ++x, ig+=2) {
-			float fx = scale * (x-dsize); 
-			float fy = scale * (y-dsize); 
-			float x2y2 = fx * fx + fy * fy; 
-			float e2x2y2 = exp(-2 * x2y2);
-
-			float help = -32 * scale2 * scale2 * scale * ( x2y2 - 2) * 
-				( 2 * x2y2 * x2y2  - 7 * x2y2 + 2) * e2x2y2;
-			float dx = fx * help; 
-			float dy = fy * help; 
-			cvdebug() << x << ", " << y << ":" << ig[0] << ", " << ig[1] << "\n"; 
-			if (abs(dx) > 1e-5 || abs(ig[0]) > 1e-5)
-				BOOST_CHECK_CLOSE(ig[0], dx, 0.3); 
-			if (abs(dy) > 1e-5 || abs(ig[1]) > 1e-5) 
-				BOOST_CHECK_CLOSE(ig[1], dy, 0.3); 
-		}
-	
-}
-
-///\todo gradient of grid-divcurl needs testing too
-BOOST_AUTO_TEST_CASE( test_grid_curl )
-{
-	const int dsize = 128; 
-	const float  range = 4.0; 
-	C2DBounds size(2*dsize + 1, 2*dsize + 1); 
-	float scale = range / dsize; 
-	float corr = dsize /range; 
-
-	cvinfo() << size << "\n"; 
-
-	C2DGridTransformation field(size, C2DInterpolatorFactory("bspline:d=1", "mirror")); 
-	
-	auto i = field.field_begin(); 
-	for (int y = 0; y < (int)size.y; ++y) 
-		for (int x = 0; x < (int)size.x; ++x, ++i) {
-			float fx = scale * (x-dsize); 
-			float fy = scale * (y-dsize); 
-			float help = exp(-fx * fx - fy * fy); ; 
-			i->x = fy * help; 
-			i->y = -fx * help; 
-
-		}
-	
-	CDoubleVector gradient(field.degrees_of_freedom()); 
-	double curlcost =  field.get_divcurl_cost(0.0, 1.0, gradient); 
-	BOOST_CHECK_CLOSE(corr * corr * curlcost, 6 * M_PI, 0.2); 
-
-
-	double divcurlcost =  field.get_divcurl_cost(1.0, 1.0, gradient); 
-	BOOST_CHECK_CLOSE(corr * corr * divcurlcost, 6 * M_PI, 0.2); 
-
-	double divcost =  field.get_divcurl_cost(1.0, 0.0, gradient); 
-	BOOST_CHECK_CLOSE(1.0 + corr * corr * divcost, 1.0, 1); 
-
-	// gradient needs testing too!!!
-}
-
-BOOST_FIXTURE_TEST_CASE( test_grid_curl_derivative_at, CurlGradFixture )
-{
-	float s2 = scale * scale; 
-	float fx = scale * (140-dsize); 
-	float fy = scale * (132-dsize); 
-	float x2y2 = fx * fx + fy * fy; 
-	float e2x2y2 = exp(-2 * x2y2);
-	
-	float help = -32 * s2 * s2 * scale * ( x2y2 - 2) * ( x2y2 * (2 * x2y2  - 7 ) + 2) * e2x2y2;
-	float dx = fx * help; 
-	float dy = fy * help; 
-	C2DFVector g = field.get_gradcurl_at(140, 132); 
-	BOOST_CHECK_CLOSE(g.x, dx, 0.4); 
-	BOOST_CHECK_CLOSE(g.y, dy, 0.4); 
-	
-}
-
-BOOST_FIXTURE_TEST_CASE( test_grid_curl_gradient_full, CurlGradFixture )
-{
-	CDoubleVector gradient(field.degrees_of_freedom(), true); 
-	field.get_divcurl_cost(1.0, 0.0, gradient); 
-
-	
-
-	auto ig = gradient.begin() + 4*(size.x + 1); 
-	for (int y = 2; y < (int)size.y-2; ++y, ig += 8) 
-		for (int x = 2; x < (int)size.x-2; ++x, ig+=2) {
-			float fx = scale * (x-dsize); 
-			float fy = scale * (y-dsize); 
-			float x2y2 = fx * fx + fy * fy; 
-			float e2x2y2 = exp(-2 * x2y2);
-
-
-			float help = -32 * scale2 * scale2 * scale * 
-				( x2y2 - 2) * ( x2y2 * (2 * x2y2  - 7 ) + 2) * e2x2y2;
-			float dx = fx * help; 
-			float dy = fy * help; 
-			cvdebug() << x << ", " << y << ":" << ig[0] << ", " << ig[1] << "\n"; 
-			if (abs(dx) > 1e-5 || abs(ig[0]) > 1e-5)
-				BOOST_CHECK_CLOSE(ig[0], dx, 0.3); 
-			if (abs(dy) > 1e-5 || abs(ig[1]) > 1e-5) 
-				BOOST_CHECK_CLOSE(ig[1], dy, 0.3); 
-		}
-	
-}
-
-
 
 float GridTransformFixture::fx(float x, float y)
 {
diff --git a/mia/2d/transform/translate.cc b/mia/2d/transform/translate.cc
index 9f105b2..dad7fdf 100644
--- a/mia/2d/transform/translate.cc
+++ b/mia/2d/transform/translate.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -196,37 +196,6 @@ C2DFVector C2DTranslateTransformation::transform(const C2DFVector& x)const
 	return x + m_transform;
 }
 
-float C2DTranslateTransformation::divergence() const
-{
-	return 0.0;
-}
-
-float C2DTranslateTransformation::curl() const
-{
-	return 0.0;
-}
-
-float C2DTranslateTransformation::grad_divergence() const
-{
-	return 0.0;
-}
-
-float C2DTranslateTransformation::grad_curl() const
-{
-	return 0.0;
-}
-
-double C2DTranslateTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/, 
-						    CDoubleVector& /*gradient*/) const
-{
-	return 0.0;
-}
-
-double C2DTranslateTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/) const
-{
-	return 0.0;
-}
-
 
 class C2DTranslateTransformCreator: public C2DTransformCreator {
 public: 
diff --git a/mia/2d/transform/translate.hh b/mia/2d/transform/translate.hh
index 1d1e8e7..907de21 100644
--- a/mia/2d/transform/translate.hh
+++ b/mia/2d/transform/translate.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -71,12 +71,6 @@ public:
 	virtual C2DFVector operator () (const C2DFVector& x) const;
 	virtual float get_jacobian(const C2DFVectorfield& v, float delta) const;
 	C2DFVector transform(const C2DFVector& x)const;
-	virtual float divergence() const;
-	virtual float curl() const;
-	float grad_divergence() const;
-	float grad_curl() const;
-	virtual double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	virtual double get_divcurl_cost(double wd, double wr) const; 
 private:
 	virtual C2DTransformation *do_clone() const;
 	C2DFVector m_transform;
diff --git a/mia/2d/transform/vectorfield.cc b/mia/2d/transform/vectorfield.cc
index a1ba58f..1e3bcc7 100644
--- a/mia/2d/transform/vectorfield.cc
+++ b/mia/2d/transform/vectorfield.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,7 +21,6 @@
 #include <limits>
 #include <mia/core/msgstream.hh>
 #include <mia/2d/transform/vectorfield.hh>
-#include <mia/2d/transformfactory.hh>
 #include <mia/2d/vfio.hh>
 
 NS_MIA_BEGIN
@@ -306,210 +305,6 @@ float C2DGridTransformation::pertuberate(C2DFVectorfield& v) const
 	return sqrt(max_gamma);
 }
 
-double C2DGridTransformation::dddgx_xxx(int x, int y) const 
-{
-	return 0.5 * ((m_field(x+2,y).x - 2 * m_field(x+1,y).x) - 
-		      ( m_field(x-2,y).x - 2 * m_field(x-1,y).x)); 
-}
-
-double C2DGridTransformation::dddgy_yyy(int x, int y) const 
-{
-	return 0.5 * ((m_field(x,y+2).y - 2 * m_field(x,y+1).y) - 
-		      ( m_field(x,y-2).y - 2 * m_field(x,y-1).y)); 
-}
-
-double C2DGridTransformation::dddgy_xxx(int x, int y) const 
-{
-	return 0.5 * ((m_field(x+2,y).y - 2 * m_field(x+1,y).y) - 
-		      ( m_field(x-2,y).y - 2 * m_field(x-1,y).y)); 
-}
-
-double C2DGridTransformation::dddgx_yyy(int x, int y) const 
-{
-	return 0.5 * ((m_field(x,y+2).x - 2 * m_field(x,y+1).x) - 
-		      ( m_field(x,y-2).x - 2 * m_field(x,y-1).x)); 
-}
-
-
-C2DFVector C2DGridTransformation::ddg_xx(int x, int y) const
-{
-	return m_field(x+1,y) + m_field(x-1,y) - 2 * m_field(x,y); 
-}
-
-C2DFVector C2DGridTransformation::ddg_xy(int x, int y) const
-{
-	return 0.25 * ((m_field(x+1,y+1) + m_field(x-1,y-1)) - 
-		       (m_field(x+1,y-1) + m_field(x-1,y+1))); 
-}
-
-
-C2DFVector C2DGridTransformation::ddg_yy(int x, int y) const
-{
-	return m_field(x,y+1) + m_field(x,y-1) - 2 * m_field(x,y); 
-}
-
-
-C2DFVector C2DGridTransformation::dddg_xxy(int x, int y) const
-{
-	return 0.5 * (ddg_xx(x, y+1) - ddg_xx(x, y-1)); 	
-}
-
-C2DFVector C2DGridTransformation::dddg_yyx(int x, int y) const
-{
-	return 0.5 * (ddg_yy(x+1, y) - ddg_yy(x-1, y)); 	
-}
-
-
-C2DFVector C2DGridTransformation::get_graddiv_at(int x, int y) const
-{
-
-	const double dfx_xx =  (m_field(x+1,y).x + m_field(x-1,y).x - 2 * m_field(x,y).x);
-	const double dfy_yy =  (m_field(x,y+1).y + m_field(x,y-1).y - 2 * m_field(x,y).y);
-	
-	const C2DFVector df_xxy = dddg_xxy(x, y); 
-	const C2DFVector df_yyx = dddg_yyx(x,y); 
-	const double dfx_xxx =  dddgx_xxx(x, y); 
-	const double dfy_yyy =  dddgy_yyy(x, y); 
-
-	const C2DFVector df_xy = ddg_xy(x,y); 
-
-	const double dhx = (df_yyx.y + df_xxy.x) * (dfy_yy + df_xy.x) + 
-		(df_xy.y + dfx_xx) * (df_xxy.y + dfx_xxx ); 
-	
-	const double dhy = (dfy_yyy + df_yyx.x) * (dfy_yy + df_xy.x) + 
-		(df_xy.y + dfx_xx) * (df_yyx.y + df_xxy.x); 
-	
-	C2DFVector vv(2*dhx, 2*dhy); 
-	cvdebug() << x << ", " << y <<  vv << "\n"; 
-	return vv; 
-}
-
-C2DFVector C2DGridTransformation::get_gradcurl_at(int x, int y) const
-{
-	const double dfy_xx =  (m_field(x+1,y).y + m_field(x-1,y).y - 2 * m_field(x,y).y);
-	const double dfx_yy =  (m_field(x,y+1).x + m_field(x,y-1).x - 2 * m_field(x,y).x);
-	const double dfy_xxx =  dddgy_xxx(x, y); 
-	const double dfx_yyy =  dddgx_yyy(x, y); 
-	
-	const C2DFVector df_xy = ddg_xy(x,y); 
-	const C2DFVector df_xxy = dddg_xxy(x, y); 	
-	const C2DFVector df_yyx = dddg_yyx(x,y); 
-
-
-	const double p1 = dfy_xx - df_xy.x; 
-	const double p2 = df_xy.y - dfx_yy;
-
-	const double dhx = p1 * (dfy_xxx - df_xxy.x) + p2 * (df_xxy.y - df_yyx.x);
-	
-	const double dhy = p1 * (df_xxy.y - df_yyx.x) + p2 * (df_yyx.y - dfx_yyy);
-
-	C2DFVector vv(2*dhx, 2*dhy); 
-	cvdebug() << x << ", " << y <<  vv << "\n"; 
-	return vv; 
-
-}
-
-float C2DGridTransformation::grad_divergence(double weight, CDoubleVector& gradient) const
-{
-	const int dx =  m_field.get_size().x;
-	auto iv = m_field.begin() + dx + 1; 
-	
-	double result = 0.0;
-	auto ig = gradient.begin() + 2*(2*dx + 2); 
-	for(size_t y = 2; y < m_field.get_size().y - 2; ++y, iv += 4, ig += 8 )
-		for(size_t x = 2; x < m_field.get_size().x - 2; ++x, ++iv, ig += 2){
-
-			const double dfx_xx =  (iv[ 1].x + iv[- 1].x - 2 * iv[0].x);
-			const double dfy_yy =  (iv[dx].y + iv[-dx].y - 2 * iv[0].y);
-			const double dfy_xy = 0.25 * (iv[dx + 1].y + iv[-dx-1].y - iv[1-dx].y - iv[dx-1].y);
-			const double dfx_xy = 0.25 * (iv[dx + 1].x + iv[-dx-1].x - iv[1-dx].x - iv[dx-1].x); 
-
-			const double p1 = dfy_yy + dfx_xy; 
-			const double p2 = dfx_xx + dfy_xy; 
-
-			C2DFVector grd = get_graddiv_at(x, y); 
-			// this needs to be tested 
-			ig[0] +=  weight * grd.x; 
-			ig[1] +=  weight * grd.y; 
-
-
-			const double v = p1 * p1 + p2 * p2; 
-			result += v; 
-		}
-	return weight * result;
-}
-
-double C2DGridTransformation::grad_curl(double weight, CDoubleVector& gradient) const
-{
-	const int dx =  m_field.get_size().x;
-	auto iv = m_field.begin() + dx + 1; 
-	
-	double result = 0.0;
-	auto ig = gradient.begin() + dx + 1; 	
-	for(size_t y = 1; y < m_field.get_size().y - 1; ++y, iv += 2, ig += 4 )
-		for(size_t x = 1; x < m_field.get_size().x - 1; ++x, ++iv,  ig += 2) {
-			const double dfy_xx = iv[ 1].y + iv[- 1].y - 2 * iv[0].y;
-			const double dfx_yy = iv[dx].x + iv[-dx].x - 2 * iv[0].x;
-			const double dfy_xy = iv[dx].y + iv[-1].y -  iv[0].y - iv[dx-1].y;
-			const double dfx_xy = iv[1].x - iv[0].x - iv[1-dx].x + iv[-dx].x; 
-			
-			const double dhx = dfy_xx - dfx_xy;
-			const double dhy = dfx_yy - dfy_xy;
-			
-
-			C2DFVector grd = get_gradcurl_at(x, y); 
-			ig[0] +=  weight * grd.x; 
-			ig[1] +=  weight * grd.y; 
-
-			result += (dhx * dhx + dhy * dhy); 
-		}
-	return weight * result;
-}
-
-double C2DGridTransformation::get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const
-{
-	double result = 0.0; 
-	// todo: if wd == wr run special case 
-
-	if (wd > 0) 
-		result += grad_divergence(wd, gradient); 
-	if (wr > 0) 
-		result += grad_curl(wr, gradient); 
-	
-	return result; 
-}
-
-double C2DGridTransformation::get_divcurl_cost(double wd, double wr) const
-{
-	double result = 0.0; 
-	// todo: if wd == wr run special case 
-	const int dx =  m_field.get_size().x;
-	auto iv = m_field.begin() + dx + 1; 
-	
-	for(size_t y = 1; y < m_field.get_size().y - 1; ++y, iv += 2 )
-		for(size_t x = 1; x < m_field.get_size().x - 1; ++x, ++iv) {
-			const double dfx_xx = iv[ 1].x + iv[- 1].x - 2 * iv[0].x;
-			const double dfy_yy = iv[dx].y + iv[-dx].y - 2 * iv[0].y;
-			const double dfy_xy = iv[dx].y + iv[-1].y -  iv[0].y - iv[dx-1].y;
-			const double dfx_xy = iv[1].x - iv[0].x - iv[1-dx].x + iv[-dx].x; 
-			const double dfy_xx = iv[ 1].y + iv[- 1].y - 2 * iv[0].y;
-			const double dfx_yy = iv[dx].x + iv[-dx].x - 2 * iv[0].x;
-			
-			const double dhx = dfy_xx - dfx_xy;
-			const double dhy = dfx_yy - dfy_xy;
-
-
-			const double dgx = dfx_xx + dfy_xy;
-			const double dgy = dfy_yy + dfx_xy;
-			
-
-			result += wr * (dhx * dhx + dhy * dhy) + 
-				wd * (dgx * dgx + dgy * dgy); 
-		}
-	return result; 
-}
-
-
 float C2DGridTransformation::get_jacobian(const C2DFVectorfield& v, float delta) const
 {
 	assert(v.get_size() == get_size());
@@ -551,16 +346,6 @@ EXPORT_2D C2DGridTransformation operator + (const C2DGridTransformation& a, cons
 	return result;
 }
 
-/**
-   Transformation creator 
- */
-class C2DGridTransformCreator: public C2DTransformCreator {
-public: 
-	C2DGridTransformCreator(const C2DInterpolatorFactory& ipf); 
-private: 
-	virtual P2DTransformation do_create(const C2DBounds& size, const C2DInterpolatorFactory& ipf) const;
-};
-
 C2DGridTransformCreator::C2DGridTransformCreator(const C2DInterpolatorFactory& ipf):
 	C2DTransformCreator(ipf)
 {
@@ -576,13 +361,6 @@ P2DTransformation C2DGridTransformCreator::do_create(const C2DBounds& size, cons
 /**
    Plugin class to create the creater.  
  */
-class C2DGridTransformCreatorPlugin: public C2DTransformCreatorPlugin {
-public:
-	C2DGridTransformCreatorPlugin();
-	virtual C2DTransformCreator *do_create(const C2DInterpolatorFactory& ipf) const;
-	const std::string do_get_descr() const;
-};
-
 C2DGridTransformCreatorPlugin::C2DGridTransformCreatorPlugin():
 	C2DTransformCreatorPlugin("vf")
 {
@@ -599,11 +377,5 @@ const std::string C2DGridTransformCreatorPlugin::do_get_descr() const
 		"each point of the grid defining the domain of the transformation.";
 }
 
-extern "C" EXPORT CPluginBase *get_plugin_interface()
-{
-	return new C2DGridTransformCreatorPlugin();
-}
-
-
 
 NS_MIA_END
diff --git a/mia/2d/transform/vectorfield.hh b/mia/2d/transform/vectorfield.hh
index 1374150..9408287 100644
--- a/mia/2d/transform/vectorfield.hh
+++ b/mia/2d/transform/vectorfield.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
 
 
 #include <iterator>
-#include <mia/2d/transform.hh>
+#include <mia/2d/transformfactory.hh>
 
 
 NS_MIA_BEGIN
@@ -90,29 +90,7 @@ public:
 	virtual float pertuberate(C2DFVectorfield& v) const;
 	virtual float get_jacobian(const C2DFVectorfield& v, float delta) const;
 	C2DFVector operator ()(const  C2DFVector& x) const;
-	double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	double get_divcurl_cost(double wd, double wr) const; 
 
-	// these functions are here for testing 
-
-
-	double dddgx_xxx(int x, int y) const; 
-	double dddgy_yyy(int x, int y) const; 
-	
-	double dddgy_xxx(int x, int y) const; 
-	double dddgx_yyy(int x, int y) const; 
-
-
-	C2DFVector ddg_xx(int x, int y) const; 
-	C2DFVector dddg_xxy(int x, int y) const; 
-
-	C2DFVector ddg_yy(int x, int y) const; 
-	C2DFVector dddg_yyx(int x, int y) const; 
-
-	C2DFVector ddg_xy(int x, int y) const; 
-
-	C2DFVector get_graddiv_at(int x, int y) const; 
-	C2DFVector get_gradcurl_at(int x, int y) const; 
 private:
 	virtual C2DTransformation *do_clone() const;
 	float grad_divergence(double weight, CDoubleVector& gradient) const; 
@@ -133,6 +111,23 @@ inline C2DFVector C2DGridTransformation::apply(const  C2DFVector& x) const
 
 EXPORT_2D C2DGridTransformation operator + (const C2DGridTransformation& a, const C2DGridTransformation& b);
 
+/**
+   Transformation creator 
+ */
+class C2DGridTransformCreator: public C2DTransformCreator {
+public: 
+	C2DGridTransformCreator(const C2DInterpolatorFactory& ipf); 
+private: 
+	virtual P2DTransformation do_create(const C2DBounds& size, const C2DInterpolatorFactory& ipf) const;
+};
+
+class C2DGridTransformCreatorPlugin: public C2DTransformCreatorPlugin {
+public:
+	C2DGridTransformCreatorPlugin();
+	virtual C2DTransformCreator *do_create(const C2DInterpolatorFactory& ipf) const;
+	const std::string do_get_descr() const;
+};
+
 NS_MIA_END
 
 namespace std {
diff --git a/mia/2d/transformfactory.cc b/mia/2d/transformfactory.cc
index 24fbe4b..eef3929 100644
--- a/mia/2d/transformfactory.cc
+++ b/mia/2d/transformfactory.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/transformfactory.hh b/mia/2d/transformfactory.hh
index dc85e97..6fc4c40 100644
--- a/mia/2d/transformfactory.hh
+++ b/mia/2d/transformfactory.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/transformio.cc b/mia/2d/transformio.cc
index a3148f4..19d6907 100644
--- a/mia/2d/transformio.cc
+++ b/mia/2d/transformio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,17 +22,25 @@
 
 #include <mia/core/errormacro.hh>
 #include <mia/2d/transformio.hh>
+#include <mia/2d/defines2d.hh>
 #include <mia/core/ioplugin.cxx>
 #include <mia/core/iohandler.cxx>
 
 NS_MIA_BEGIN
 
+C2DTransformIOPluginHandlerImpl::C2DTransformIOPluginHandlerImpl()
+{
+	TTranslator<C2DFVector>::register_for(C2DTransformation::input_spacing_attr);
+	TTranslator<C2DFVector>::register_for(C2DTransformation::output_spacing_attr);
+}
+
+
 template <> const char *  const 
 	TPluginHandler<C2DTransformationIO>::m_help =  
        "These plug-ins implement the support for loading and storing 2D transformations to various file types.";
 
 template class TIOPlugin<C2DTransformation>;
-template class THandlerSingleton<TIOPluginHandler<C2DTransformationIO> >;
+template class THandlerSingleton<C2DTransformIOPluginHandlerImpl>;
 template class TIOPluginHandler<C2DTransformationIO>;
 template class TPluginHandler<C2DTransformationIO>;
 
diff --git a/mia/2d/transformio.hh b/mia/2d/transformio.hh
index d5048bf..f1dadd1 100644
--- a/mia/2d/transformio.hh
+++ b/mia/2d/transformio.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -37,11 +37,23 @@ NS_MIA_BEGIN
 */ 
 typedef TIOPlugin<C2DTransformation> C2DTransformationIO; 
 
+
+/**
+   \ingroup io
+   \brief The non-singleton plug-in handler for 3D transformations 
+*/
+
+
+class EXPORT_2D C2DTransformIOPluginHandlerImpl: public TIOPluginHandler<C2DTransformationIO> {
+protected:  
+	C2DTransformIOPluginHandlerImpl(); 
+};
+
 /**
    @ingroup io 
    \brief The 2D transformationb plugin handler 
 */
-typedef THandlerSingleton< TIOPluginHandler<C2DTransformationIO> > C2DTransformationIOPluginHandler;
+typedef THandlerSingleton< C2DTransformIOPluginHandlerImpl > C2DTransformationIOPluginHandler;
 
 /**
    @ingroup io 
diff --git a/mia/2d/transformmock.cc b/mia/2d/transformmock.cc
index 7dd680f..fe13640 100644
--- a/mia/2d/transformmock.cc
+++ b/mia/2d/transformmock.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/transformmock.hh b/mia/2d/transformmock.hh
index 9ccb2e1..ea9fa91 100644
--- a/mia/2d/transformmock.hh
+++ b/mia/2d/transformmock.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/transio/CMakeLists.txt b/mia/2d/transio/CMakeLists.txt
index 20bdf02..57dc798 100644
--- a/mia/2d/transio/CMakeLists.txt
+++ b/mia/2d/transio/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/transio/bbs.cc b/mia/2d/transio/bbs.cc
index 6586d70..5aaea30 100644
--- a/mia/2d/transio/bbs.cc
+++ b/mia/2d/transio/bbs.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/transio/pbs.cc b/mia/2d/transio/pbs.cc
index bb5bb4e..6ad4a8a 100644
--- a/mia/2d/transio/pbs.cc
+++ b/mia/2d/transio/pbs.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/transio/serialization.hh b/mia/2d/transio/serialization.hh
index b146a40..915eb42 100644
--- a/mia/2d/transio/serialization.hh
+++ b/mia/2d/transio/serialization.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
 #include <cassert>
 #include <boost/serialization/vector.hpp>
 #include <boost/serialization/string.hpp>
+#include <boost/serialization/map.hpp>
 #include <boost/serialization/version.hpp>
 #include <boost/serialization/split_free.hpp>
 #include <mia/2d/transformfactory.hh>
@@ -35,10 +36,19 @@ void save(Archive & ar, const mia::C2DTransformation& t, unsigned int )
 	ar << make_nvp("creator", t.get_creator_string()); 
 	ar << make_nvp("size_x", t.get_size().x); 
 	ar << make_nvp("size_y", t.get_size().y); 
+	
+	std::map<std::string, std::string> attr; 
+	for (auto i = t.begin_attributes(); i != t.end_attributes(); ++i) {
+		attr.insert(std::make_pair(i->first, i->second->as_string())); 
+	}
+	ar << make_nvp("attributes", attr);
+
 	auto params = t.get_parameters(); 
 	std::vector<double> help(params.size()); 
 	std::copy(params.begin(), params.end(), help.begin()); 
 	ar << make_nvp("params", help);
+
+
 }
 
 template<class Archive>
@@ -51,6 +61,8 @@ void load(Archive & ar, mia::P2DTransformation & t, unsigned int )
 	ar >> make_nvp("creator",init); 
 	ar >> make_nvp("size_x",size.x); 
 	ar >> make_nvp("size_y",size.y); 
+	std::map<std::string, std::string> attr; 
+	ar >> make_nvp("attributes", attr); 
 	ar >> make_nvp("params", help); 
 
 	auto creator = mia::C2DTransformCreatorHandler::instance().produce(init);  
@@ -61,6 +73,10 @@ void load(Archive & ar, mia::P2DTransformation & t, unsigned int )
 				   help.size(), " parameters, but transformation needs ", params.size()); 
 	std::copy(help.begin(), help.end(), params.begin()); 
 	t->set_parameters(params); 
+
+	for(auto i = attr.begin(); i != attr.end(); ++i) {
+		t->set_attribute(i->first, mia::CStringAttrTranslatorMap::instance().to_attr(i->first, i->second)); 
+	}
 }
 
 /*
diff --git a/mia/2d/transio/xml.cc b/mia/2d/transio/xml.cc
index d0adf0e..c84d182 100644
--- a/mia/2d/transio/xml.cc
+++ b/mia/2d/transio/xml.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/2d/vector.hh b/mia/2d/vector.hh
index df267b3..a8acb50 100644
--- a/mia/2d/vector.hh
+++ b/mia/2d/vector.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,6 +32,7 @@
 // MIA specific
 #include <mia/core/type_traits.hh>
 #include <mia/core/errormacro.hh>
+#include <mia/core/attributetype.hh>
 
 NS_MIA_BEGIN
 
@@ -147,6 +148,10 @@ public:
 		return *this;
 	}
 
+	T2DVector operator -() const {
+		return 	T2DVector<T>(-x, -y); 
+	}
+
 	/// returns the size of this vector, always 2
 	size_t size() const {
 		return 2;
@@ -239,6 +244,22 @@ public:
 
 };
 
+
+struct EAttributeType_2d : public EAttributeType {
+	
+	static const int vector_2d_bit = 0x20000; 
+	
+	static bool is_vector2d(int type) {
+		return type & vector_2d_bit; 
+        }
+}; 
+
+template <typename T> 
+struct attribute_type<T2DVector<T>> : public EAttributeType_2d {
+        static const int value = attribute_type<T>::value | vector_2d_bit;
+}; 
+
+
 /// @cond NEVER  
 
 template <typename T> 
diff --git a/mia/2d/vectorfield.cc b/mia/2d/vectorfield.cc
index fb3f4d7..952a428 100644
--- a/mia/2d/vectorfield.cc
+++ b/mia/2d/vectorfield.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,12 +28,74 @@
 #  endif 
 #endif
 
+#include <mia/2d/defines2d.hh>
 #include <mia/2d/vectorfield.hh>
 #include <mia/2d/datafield.cxx>
 #include <mia/2d/iterator.cxx>
 
 NS_MIA_BEGIN
 
+
+template class EXPORT_2D T2DDatafield<C2DFVector>;
+template class EXPORT_2D T2DDatafield<C2DDVector>;
+
+template <typename T> 
+T2DVectorfield<T>::T2DVectorfield()
+{
+};
+
+template <typename T> 
+T2DVectorfield<T>::T2DVectorfield(const C2DBounds& size):
+	T2DDatafield<T>(size) 
+{
+};
+
+
+template <typename T> 
+T2DVectorfield<T>::T2DVectorfield(const CAttributedData& data, const C2DBounds& size):
+	T2DDatafield<T>(size),
+	CAttributedData(data)
+{
+}
+	
+template <typename T> 
+C2DFVector T2DVectorfield<T>::get_pixel_size() const 
+{
+	const PAttribute attr = get_attribute("pixel");
+	if (!attr) {
+		cvinfo() << "C2DImage::get_pixel_size(): pixel size not defined\n";
+		return C2DFVector(1,1);
+	}
+	
+	const TAttribute<C2DFVector> * vs = dynamic_cast<TAttribute<C2DFVector> *>(attr.get());
+	if (!vs){
+		cvinfo() << "C2DImage::get_pixel_size(): pixel size wrong type\n";
+		return C2DFVector(1,1);
+	}
+	return *vs;
+}
+
+
+template <typename T> 
+void T2DVectorfield<T>::set_pixel_size(const C2DFVector& pixel)
+{
+	set_attribute("pixel", PAttribute(new TAttribute<C2DFVector>(pixel)));
+}
+
+template <typename T>
+const char *T2DVectorfield<T>::data_descr = "2dvf"; 
+
+#define INSTANCIATE(TYPE) \
+	template class EXPORT_2D T2DVectorfield<TYPE>;			\
+	template class EXPORT_2D range2d_iterator<T2DDatafield<TYPE>::iterator>; \
+	template class EXPORT_2D range2d_iterator<T2DDatafield<TYPE>::const_iterator>; \
+	template class EXPORT_2D range2d_iterator_with_boundary_flag<T2DDatafield<TYPE>::iterator>; \
+	template class EXPORT_2D range2d_iterator_with_boundary_flag<T2DDatafield<TYPE>::const_iterator>;
+
+
+INSTANCIATE(C2DFVector);
+INSTANCIATE(C2DDVector);
+
 /**
    
  */
@@ -55,18 +117,11 @@ EXPORT_2D C2DFVectorfield& operator += (C2DFVectorfield& a, const C2DFVectorfiel
 	}
 	return a;
 }
-template <typename T>
-const char *T2DVectorfield<T>::data_descr = "2dvf"; 
 
-#define INSTANCIATE(TYPE) \
-	template class EXPORT_2D T2DDatafield<TYPE>;			\
-	template class EXPORT_2D T2DVectorfield<TYPE>;			\
-	template class EXPORT_2D range2d_iterator<T2DDatafield<TYPE>::iterator>; \
-	template class EXPORT_2D range2d_iterator<T2DDatafield<TYPE>::const_iterator>;
 
 
-INSTANCIATE(C2DFVector);
-INSTANCIATE(C2DDVector);
+
+
 
 
 NS_MIA_END
diff --git a/mia/2d/vectorfield.hh b/mia/2d/vectorfield.hh
index c41ec9f..a48180f 100644
--- a/mia/2d/vectorfield.hh
+++ b/mia/2d/vectorfield.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,30 +33,30 @@ NS_MIA_BEGIN
    This class provides an  interface to make the IO opf vector fields possible 
  */
 template <typename T>
-class EXPORT_2D T2DVectorfield: public T2DDatafield<T>, public CAttributedData {
+class EXPORT_2D  T2DVectorfield: public T2DDatafield<T>, public CAttributedData {
 public:
 	/// plug.in related type description string 
 	static const char *data_descr;
 
-	T2DVectorfield(){};
+	T2DVectorfield();
 
 	/**
 	   Contruct a vector field of the given size 
 	   @param size of vector field 
 	 */
-	T2DVectorfield(const C2DBounds& size):
-		T2DDatafield<T>(size) {};
+	T2DVectorfield(const C2DBounds& size);
 
 
 	/**
 	   @param data meta data  
 	   @param size of vector field 
 	 */
-	T2DVectorfield(const CAttributedData& data, const C2DBounds& size):
-		T2DDatafield<T>(size),
-		CAttributedData(data)
-	{
-	}
+	T2DVectorfield(const CAttributedData& data, const C2DBounds& size); 
+
+	C2DFVector get_pixel_size() const; 
+
+	void set_pixel_size(const C2DFVector& pixel); 
+
 };
 
 /// 2D vector field to store single precicion 2D vectors 
@@ -74,6 +74,11 @@ typedef T2DVectorfield<C2DDVector>  C2DDVectorfield;
 */
 EXPORT_2D C2DFVectorfield& operator += (C2DFVectorfield& a, const C2DFVectorfield& b);
 
+/// @cond never 
+extern template class EXPORT_2D T2DDatafield<C2DFVector>;
+extern template class EXPORT_2D range2d_iterator<T2DDatafield<C2DFVector>::iterator>;
+/// @endcond never 
+
 NS_MIA_END
 
 #endif
diff --git a/mia/2d/vfio.cc b/mia/2d/vfio.cc
index 852780d..5558554 100644
--- a/mia/2d/vfio.cc
+++ b/mia/2d/vfio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
 
 #include <mia/core/export_handler.hh>
 
+#include <mia/2d/defines2d.hh>
 #include <mia/2d/vfio.hh>
 #include <mia/core/ioplugin.cxx>
 #include <mia/core/iohandler.cxx>
@@ -61,6 +62,8 @@ template <> const char *  const
 TPluginHandler<C2DVFIOPlugin>::m_help =  
    "These plug-ins handle loading and storing of the supported 2D vector field file types.";
 
+
+template class TPlugin<io_2dvf_type, io_plugin_type>; 
 template class TIOPlugin<io_2dvf_type>;
 template class THandlerSingleton<TIOPluginHandler<C2DVFIOPlugin> >;
 template class TIOPluginHandler<C2DVFIOPlugin>;
diff --git a/mia/2d/vfio.hh b/mia/2d/vfio.hh
index 02fb922..35fd306 100644
--- a/mia/2d/vfio.hh
+++ b/mia/2d/vfio.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -57,16 +57,26 @@ public:
 	C2DIOVectorfield *clone() const __attribute__((warn_unused_result));
 };
 
-struct io_2dvf_type {
+struct EXPORT_2D io_2dvf_type {
 	typedef  C2DIOVectorfield type;
 	static const char *data_descr;
 };
 
+
+
 /// Base class for 2D vector field IO plugins 
 typedef TIOPlugin<io_2dvf_type> C2DVFIOPlugin;
 
+template <> const char *  const TPluginHandler<C2DVFIOPlugin>::m_help; 
+
+extern template class EXPORT_2D TPlugin<io_2dvf_type, io_plugin_type>; 
+extern template class EXPORT_2D TIOPlugin<io_2dvf_type>; 
+extern template class EXPORT_2D TIOPluginHandler<C2DVFIOPlugin>;
+extern template class EXPORT_2D THandlerSingleton<TIOPluginHandler<C2DVFIOPlugin> >;
+
 /// Handler for 2D vector field IO 
-typedef THandlerSingleton<TIOPluginHandler<C2DVFIOPlugin> > C2DVFIOPluginHandler;
+typedef  THandlerSingleton<TIOPluginHandler<C2DVFIOPlugin> > C2DVFIOPluginHandler;
+
 
 NS_MIA_END
 
diff --git a/mia/2d/vfiotest.cc b/mia/2d/vfiotest.cc
index 83abe56..9e25437 100644
--- a/mia/2d/vfiotest.cc
+++ b/mia/2d/vfiotest.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d.hh b/mia/3d.hh
index 7092ff8..9b7afd9 100644
--- a/mia/3d.hh
+++ b/mia/3d.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
 #include <mia/3d/creator.hh>
 #include <mia/3d/fullcost.hh>
 #include <mia/3d/interpolator.hh>
+#include <mia/3d/maskedcost.hh>
 #include <mia/3d/model.hh>
 #include <mia/3d/transformfactory.hh>
 #include <mia/3d/transformio.hh>
@@ -37,6 +38,7 @@
 #include <mia/3d/stackdisttrans.hh>
 #include <mia/3d/nonrigidregister.hh>
 #include <mia/3d/shape.hh>
+#include <mia/3d/splinetransformpenalty.hh>
 
 
 #endif
diff --git a/mia/3d/2dimagefifofilter.cc b/mia/3d/2dimagefifofilter.cc
index 018282f..646e14c 100644
--- a/mia/3d/2dimagefifofilter.cc
+++ b/mia/3d/2dimagefifofilter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/2dimagefifofilter.hh b/mia/3d/2dimagefifofilter.hh
index fe7126c..3c2d043 100644
--- a/mia/3d/2dimagefifofilter.hh
+++ b/mia/3d/2dimagefifofilter.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/CMakeLists.txt b/mia/3d/CMakeLists.txt
index 43cc3d2..57861a2 100644
--- a/mia/3d/CMakeLists.txt
+++ b/mia/3d/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -28,54 +28,59 @@ ENDIF(ITPP_FOUND)
 
 
 SET(MIA3D_SRC 
+  affine_matrix.cc
   camera.cc
   cost.cc
   creator.cc
   critical_point.cc
   2dimagefifofilter.cc
   datafield.cc
-  image.cc
-  vectorfield.cc
-  filter.cc
-  imageio.cc
-  vfio.cc
   distance.cc
+  filter.cc
   fullcost.cc
   fuzzyseg.cc
-  fuzzyClusterSolverCG.cc
+  fuzzyclustersolver_cg.cc
+  image.cc
+  imageio.cc
   imagecollect.cc
   interpolator.cc
   landmark.cc
   landmarklist.cc
   landmarklistio.cc
+  maskedcost.cc
+  matrix.cc 
   model.cc
   multicost.cc
   nfg.cc 
   nonrigidregister.cc
   orientation.cc
-  quaternion.cc
   ppmatrix.cc 
+  quaternion.cc
   register.cc
   rigidregister.cc
-  timestep.cc
+  rot.cc
+  shape.cc
   similarity_profile.cc
   splinetransformpenalty.cc
+  stackdisttrans.cc
+  timestep.cc
   trackpoint.cc
   transform.cc
   transformfactory.cc
   transformio.cc
-  shape.cc
-  stackdisttrans.cc
+  vectorfield.cc
+  vfio.cc
   ${ITPP_SRC}
   )
 
 SET(MIA3D_HEADERS
+  affine_matrix.hh
   2dimagefifofilter.hh
   datafield.hh datafield.cxx
-  vectorfield.hh
   image.hh
   filter.hh
   imageio.hh
+  imagetest.hh
   imageiotest.hh
   vector.hh
   vfio.hh
@@ -90,7 +95,7 @@ SET(MIA3D_HEADERS
   fifotestfixture.hh
   fullcost.hh
   fuzzyseg.hh
-  fuzzyClusterSolverCG.hh
+  fuzzyclustersolver_cg.hh
   interpolator.hh interpolator.cxx
   iterator.hh iterator.cxx
   ica.hh
@@ -98,6 +103,7 @@ SET(MIA3D_HEADERS
   landmark.hh
   landmarklist.hh
   landmarklistio.hh
+  maskedcost.hh
   matrix.hh
   model.hh
   multicost.hh
@@ -109,6 +115,7 @@ SET(MIA3D_HEADERS
   quaternion.hh
   register.hh
   rigidregister.hh
+  rot.hh
   shape.hh 
   similarity_profile.hh
   stackdisttrans.hh
@@ -121,6 +128,8 @@ SET(MIA3D_HEADERS
   transformio.hh
   transformmock.hh
   ${ITPP_HEADER}
+  valueattributetranslator.hh
+  vectorfield.hh
   )
 
 SET(MIA3DTEST_SRC
@@ -155,6 +164,7 @@ SET(MIA3DLIBS mia3d  ${LIBS})
 
 SET(mia3dtestsrc 
   imageiotest.cc 
+  imagetest.cc 
   vfiotest.cc 
   fifotestfixture.cc
   transformmock.cc
@@ -181,10 +191,9 @@ IF (WIN32)
   ADD_TEST(3d "${CMAKE_CURRENT_SOURCE_DIR}/test-3d.bat")
 ELSE (WIN32)
   ADD_TEST(3d test-3d)
-  ADD_TEST(3d-imageio test-3dimageio)
 ENDIF(WIN32)
 
-TEST_3D(imageio imageio)
+TEST_3D(affine_matrix affine_matrix)
 TEST_3D(2dimagefifofilter imagefifofilter)
 TEST_3D(nfg nfg)
 TEST_3D(vectorfield vectorfield)
@@ -210,6 +219,7 @@ TEST_3D(similarity_profile similarity_profile)
 TEST_3D(trackpoint similarity_profile)
 TEST_3D(distance distance)
 TEST_3D(imagecollect imagecollect)
+TEST_3D(rot rot)
 TEST_3D(splinetransformpenalty splinetransformpenalty)
 #
 # installation 
@@ -228,6 +238,7 @@ ADD_SUBDIRECTORY(filter   )
 ADD_SUBDIRECTORY(fifof    )
 ADD_SUBDIRECTORY(fullcost )
 ADD_SUBDIRECTORY(io       )
+ADD_SUBDIRECTORY(maskedcost )
 ADD_SUBDIRECTORY(reg3d    )
 ADD_SUBDIRECTORY(shapes   )
 ADD_SUBDIRECTORY(splinepenalty  )
diff --git a/mia/3d/affine_matrix.cc b/mia/3d/affine_matrix.cc
new file mode 100644
index 0000000..0fca110
--- /dev/null
+++ b/mia/3d/affine_matrix.cc
@@ -0,0 +1,394 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <cmath>
+#include <mia/3d/affine_matrix.hh>
+
+NS_MIA_BEGIN
+
+using std::vector; 
+using std::runtime_error; 
+
+CAffinTransformMatrix::CAffinTransformMatrix():m_matrix(16, 0.0f)
+{
+        identity();
+}
+
+CAffinTransformMatrix::CAffinTransformMatrix(float a11, float a12, float a13, float a14, 
+					     float a21, float a22, float a23, float a24, 
+					     float a31, float a32, float a33, float a34):m_matrix(16, 0.0f)
+{
+	m_matrix[0] = a11; 
+	m_matrix[4] = a12; 
+	m_matrix[8] = a13; 
+	m_matrix[12]= a14; 
+
+	m_matrix[1] = a21; 
+	m_matrix[5] = a22; 
+	m_matrix[9] = a23; 
+	m_matrix[13]= a24; 
+
+	m_matrix[2] = a31; 
+	m_matrix[6] = a32; 
+	m_matrix[10]= a33; 
+	m_matrix[14]= a34; 
+
+	m_matrix[15]=1.0f;
+
+}
+
+void CAffinTransformMatrix::rotate_x(float angle, const C3DFVector& center)
+{
+        float c, s; 
+        sincosf(angle, &s, &c); 
+
+	float ac[8]; 
+	float as[8]; 
+
+	const int a1 = 0; 
+	const int a2 = 1;
+	const int a5 = 2; 
+	const int a6 = 3;
+	const int a9 = 4; 
+	const int aA = 5;
+	const int aD = 6; 
+	const int aE = 7;
+
+	ac[a1] = m_matrix[1] * c; as[a1] = m_matrix[1] * s; 
+	ac[a2] = m_matrix[2] * c; as[a2] = m_matrix[2] * s; 
+	ac[a5] = m_matrix[5] * c; as[a5] = m_matrix[5] * s; 
+	ac[a6] = m_matrix[6] * c; as[a6] = m_matrix[6] * s; 
+	ac[a9] = m_matrix[9] * c; as[a9] = m_matrix[9] * s; 
+	ac[aA] = m_matrix[10]* c; as[aA] = m_matrix[10] * s; 
+	ac[aD] = m_matrix[13]* c; as[aD] = m_matrix[13] * s; 
+	ac[aE] = m_matrix[14]* c; as[aE] = m_matrix[14] * s; 
+
+	m_matrix[1] = ac[a1] - as[a2]; 
+	m_matrix[5] = ac[a5] - as[a6]; 
+	m_matrix[9] = ac[a9] - as[aA]; 
+	m_matrix[13] = ac[aD] - as[aE] + center.z * s - center.y * c + center.y; 
+
+	m_matrix[2] = as[a1] + ac[a2]; 
+	m_matrix[6] = as[a5] + ac[a6]; 
+	m_matrix[10]= as[a9] + ac[aA]; 
+	m_matrix[14]= as[aD] + ac[aE] - center.y * s - center.z * c + center.z;
+	
+
+}
+
+void CAffinTransformMatrix::rotate_y(float angle, const C3DFVector& center)
+{
+        float c, s; 
+        sincosf(angle, &s, &c); 
+
+	float ac[8]; 
+	float as[8]; 
+
+	const int a0 = 0; 
+	const int a2 = 1;
+	const int a4 = 2; 
+	const int a6 = 3;
+	const int a8 = 4; 
+	const int aA = 5;
+	const int aC = 6; 
+	const int aE = 7;
+
+	ac[a0] = m_matrix[0] * c; as[a0] = m_matrix[0] * s; 
+	ac[a2] = m_matrix[2] * c; as[a2] = m_matrix[2] * s; 
+	ac[a4] = m_matrix[4] * c; as[a4] = m_matrix[4] * s; 
+	ac[a6] = m_matrix[6] * c; as[a6] = m_matrix[6] * s; 
+	ac[a8] = m_matrix[8] * c; as[a8] = m_matrix[8] * s; 
+	ac[aA] = m_matrix[10]* c; as[aA] = m_matrix[10] * s; 
+	ac[aC] = m_matrix[12]* c; as[aC] = m_matrix[12] * s; 
+	ac[aE] = m_matrix[14]* c; as[aE] = m_matrix[14] * s; 
+
+	m_matrix[0] = ac[a0] - as[a2]; 
+	m_matrix[4] = ac[a4] - as[a6]; 
+	m_matrix[8] = ac[a8] - as[aA]; 
+	m_matrix[12] = ac[aC] - as[aE] + center.z * s - center.x * c + center.x; 
+
+	m_matrix[2] = as[a0] + ac[a2]; 
+	m_matrix[6] = as[a4] + ac[a6]; 
+	m_matrix[10]= as[a8] + ac[aA]; 
+	m_matrix[14]= as[aC] + ac[aE] - center.x * s - center.z * c + center.z;
+
+}
+
+void CAffinTransformMatrix::rotate_z(float angle, const C3DFVector& center)
+{
+        float c, s; 
+        sincosf(angle, &s, &c); 
+
+	float ac[8]; 
+	float as[8]; 
+
+	const int a0 = 0; 
+	const int a1 = 1;
+	const int a4 = 2; 
+	const int a5 = 3;
+	const int a8 = 4; 
+	const int a9 = 5;
+	const int aC = 6; 
+	const int aD = 7;
+
+	ac[a0] = m_matrix[0] * c; as[a0] = m_matrix[0] * s; 
+	ac[a1] = m_matrix[1] * c; as[a1] = m_matrix[1] * s; 
+	ac[a4] = m_matrix[4] * c; as[a4] = m_matrix[4] * s; 
+	ac[a5] = m_matrix[5] * c; as[a5] = m_matrix[5] * s; 
+	ac[a8] = m_matrix[8] * c; as[a8] = m_matrix[8] * s; 
+	ac[a9] = m_matrix[9] * c; as[a9] = m_matrix[9] * s; 
+	ac[aC] = m_matrix[12]* c; as[aC] = m_matrix[12] * s; 
+	ac[aD] = m_matrix[13]* c; as[aD] = m_matrix[13] * s; 
+
+	m_matrix[0] = ac[a0] - as[a1]; 
+	m_matrix[4] = ac[a4] - as[a5]; 
+	m_matrix[8] = ac[a8] - as[a9]; 
+	m_matrix[12] = ac[aC] - as[aD] + center.y * s - center.x * c + center.x; 
+
+	m_matrix[1] = as[a0] + ac[a1]; 
+	m_matrix[5] = as[a4] + ac[a5]; 
+	m_matrix[9]= as[a8] + ac[a9]; 
+	m_matrix[13]= as[aC] + ac[aD] - center.x * s - center.y * c + center.y;
+}
+
+
+void CAffinTransformMatrix::transform_centered(const C3DFMatrix& m, const C3DFVector& center)
+{
+	const auto shift = center - m * center; 
+	vector<float> help(16,0.0f); 
+	
+	// multiplying from right side with m transposed 
+	help[0] = m_matrix[0] * m.x.x + m_matrix[1] * m.x.y + m_matrix[2] * m.x.z;  
+	help[1] = m_matrix[0] * m.y.x + m_matrix[1] * m.y.y + m_matrix[2] * m.y.z;  
+	help[2] = m_matrix[0] * m.z.x + m_matrix[1] * m.z.y + m_matrix[2] * m.z.z;  
+
+	help[4] = m_matrix[4] * m.x.x + m_matrix[5] * m.x.y + m_matrix[6] * m.x.z;  
+	help[5] = m_matrix[4] * m.y.x + m_matrix[5] * m.y.y + m_matrix[6] * m.y.z;  
+	help[6] = m_matrix[4] * m.z.x + m_matrix[5] * m.z.y + m_matrix[6] * m.z.z;  
+
+	help[8] = m_matrix[8] * m.x.x + m_matrix[9] * m.x.y + m_matrix[10] * m.x.z;
+	help[9] = m_matrix[8] * m.y.x + m_matrix[9] * m.y.y + m_matrix[10] * m.y.z;
+	help[10]= m_matrix[8] * m.z.x + m_matrix[9] * m.z.y + m_matrix[10] * m.z.z;
+
+	help[12] = m_matrix[12] * m.x.x + m_matrix[13] * m.x.y + m_matrix[14] * m.x.z + shift.x; 
+	help[13] = m_matrix[12] * m.y.x + m_matrix[13] * m.y.y + m_matrix[14] * m.y.z + shift.y;
+	help[14] = m_matrix[12] * m.z.x + m_matrix[13] * m.z.y + m_matrix[14] * m.z.z + shift.z;
+
+
+	help[15] = 1.0f; 
+
+	swap(help, m_matrix); 
+
+}
+
+void CAffinTransformMatrix::rotate(const Quaternion& q, const C3DFVector& center)
+{
+	const auto rot = C3DFMatrix(q.get_rotation_matrix()); 
+	const auto shift = center - rot * center; 
+	vector<float> help(16,0.0f); 
+	
+	// multiplying from right side with rot transposed 
+	help[0] = m_matrix[0] * rot.x.x + m_matrix[1] * rot.x.y + m_matrix[2] * rot.x.z;  
+	help[1] = m_matrix[0] * rot.y.x + m_matrix[1] * rot.y.y + m_matrix[2] * rot.y.z;  
+	help[2] = m_matrix[0] * rot.z.x + m_matrix[1] * rot.z.y + m_matrix[2] * rot.z.z;  
+
+	help[4] = m_matrix[4] * rot.x.x + m_matrix[5] * rot.x.y + m_matrix[6] * rot.x.z;  
+	help[5] = m_matrix[4] * rot.y.x + m_matrix[5] * rot.y.y + m_matrix[6] * rot.y.z;  
+	help[6] = m_matrix[4] * rot.z.x + m_matrix[5] * rot.z.y + m_matrix[6] * rot.z.z;  
+
+	help[8] = m_matrix[8] * rot.x.x + m_matrix[9] * rot.x.y + m_matrix[10] * rot.x.z;
+	help[9] = m_matrix[8] * rot.y.x + m_matrix[9] * rot.y.y + m_matrix[10] * rot.y.z;
+	help[10]= m_matrix[8] * rot.z.x + m_matrix[9] * rot.z.y + m_matrix[10] * rot.z.z;
+
+	help[12] = m_matrix[12] * rot.x.x + m_matrix[13] * rot.x.y + m_matrix[14] * rot.x.z + shift.x; 
+	help[13] = m_matrix[12] * rot.y.x + m_matrix[13] * rot.y.y + m_matrix[14] * rot.y.z + shift.y;
+	help[14] = m_matrix[12] * rot.z.x + m_matrix[13] * rot.z.y + m_matrix[14] * rot.z.z + shift.z;
+
+
+	help[15] = 1.0f; 
+
+	swap(help, m_matrix); 
+
+}
+
+void CAffinTransformMatrix::scale(const C3DFVector& scale, const C3DFVector& center)
+{
+	const C3DFVector sh = (C3DFVector::_1 - scale) * center; 
+
+	for (int i = 0; i < 4; ++i) {
+		m_matrix[4*i] *= scale.x; 
+		m_matrix[4*i + 1] *= scale.y; 
+		m_matrix[4*i + 2] *= scale.z; 
+	}
+	m_matrix[12]  += sh.x; 
+	m_matrix[13]  += sh.y; 
+	m_matrix[14] += sh.z; 
+	
+}
+
+const std::vector<float>& CAffinTransformMatrix::data() const
+{
+	return m_matrix; 
+}
+
+void CAffinTransformMatrix::translate(const C3DFVector& shift)
+{
+	m_matrix[12] += shift.x; 
+	m_matrix[13] += shift.y; 
+	m_matrix[14] += shift.z; 
+}
+
+void CAffinTransformMatrix::identity()
+{
+	fill(m_matrix.begin(), m_matrix.end(), 0.0f); 
+        m_matrix[0] = m_matrix[5] = m_matrix[10] = m_matrix[15] = 1.0f; 
+}
+
+CAffinTransformMatrix& CAffinTransformMatrix::operator *= (const CAffinTransformMatrix& other)
+{
+	vector<float> help(16,0.0f); 
+
+	help[0] = m_matrix[0] * other.m_matrix[0] + m_matrix[4] * other.m_matrix[1] + m_matrix[8] * other.m_matrix[2];  
+	help[1] = m_matrix[1] * other.m_matrix[0] + m_matrix[5] * other.m_matrix[1] + m_matrix[9] * other.m_matrix[2];  
+	help[2] = m_matrix[2] * other.m_matrix[0] + m_matrix[6] * other.m_matrix[1] + m_matrix[10]* other.m_matrix[2];
+
+	help[4] = m_matrix[0] * other.m_matrix[4] + m_matrix[4] * other.m_matrix[5] + m_matrix[8] * other.m_matrix[6];  
+	help[5] = m_matrix[1] * other.m_matrix[4] + m_matrix[5] * other.m_matrix[5] + m_matrix[9] * other.m_matrix[6];  
+	help[6] = m_matrix[2] * other.m_matrix[4] + m_matrix[6] * other.m_matrix[5] + m_matrix[10] * other.m_matrix[6];
+
+	help[8] = m_matrix[0] * other.m_matrix[8] + m_matrix[4] * other.m_matrix[9] + m_matrix[8] * other.m_matrix[10];  
+	help[9] = m_matrix[1] * other.m_matrix[8] + m_matrix[5] * other.m_matrix[9] + m_matrix[9] * other.m_matrix[10];  
+	help[10]= m_matrix[2] * other.m_matrix[8] + m_matrix[6] * other.m_matrix[9] + m_matrix[10]* other.m_matrix[10];
+
+	help[12]= other.m_matrix[12] * m_matrix[0] + other.m_matrix[13] * m_matrix[4] + other.m_matrix[14] * m_matrix[8] + m_matrix[12]; 
+	help[13]= other.m_matrix[12] * m_matrix[1] + other.m_matrix[13] * m_matrix[5] + other.m_matrix[14] * m_matrix[9] + m_matrix[13];
+	help[14]= other.m_matrix[12] * m_matrix[2] + other.m_matrix[13] * m_matrix[6] + other.m_matrix[14] * m_matrix[10]+ m_matrix[14];
+
+	help[15] = 1.0f; 
+
+	swap(m_matrix, help); 
+	return *this; 
+}
+
+C3DFVector CAffinTransformMatrix::rotate(const C3DFVector& x) const
+{
+	return C3DFVector(m_matrix[0] * x.x + m_matrix[4] * x.y + m_matrix[8] * x.z, 
+			  m_matrix[1] * x.x + m_matrix[5] * x.y + m_matrix[9] * x.z, 
+			  m_matrix[2] * x.x + m_matrix[6] * x.y + m_matrix[10] * x.z); 
+}
+
+const CAffinTransformMatrix CAffinTransformMatrix::inverse() const
+{
+	const float det = (m_matrix[0]*m_matrix[5]-m_matrix[4]*m_matrix[1])*m_matrix[10]+
+		(m_matrix[8]*m_matrix[1]-m_matrix[0]*m_matrix[9])*m_matrix[6]+
+		(m_matrix[4]*m_matrix[9]-m_matrix[8]*m_matrix[5])*m_matrix[2]; 
+
+	if (::fabs(det) < 1e-8)
+		throw runtime_error("CAffinTransformMatrix:inverse(): Matrix is (numerically) singular"); 
+	
+	const float inv_det = 1.0f/det; 
+	
+	CAffinTransformMatrix result; 
+
+	result.m_matrix[0] = inv_det * (m_matrix[5]*m_matrix[10]- m_matrix[9]*m_matrix[6]); 
+	result.m_matrix[4] = inv_det * (m_matrix[8]*m_matrix[6] - m_matrix[4]*m_matrix[10]); 
+	result.m_matrix[8] = inv_det * (m_matrix[4]*m_matrix[9] - m_matrix[8]*m_matrix[5]); 
+	result.m_matrix[12] = inv_det * ((m_matrix[8]*m_matrix[5] - m_matrix[4]*m_matrix[9])*m_matrix[14]+
+					(m_matrix[4]*m_matrix[13] - m_matrix[12]*m_matrix[5])*m_matrix[10]+
+					(m_matrix[12]*m_matrix[9] - m_matrix[8]*m_matrix[13])*m_matrix[6]); 
+		
+	result.m_matrix[1] = inv_det *  (m_matrix[9]*m_matrix[2] - m_matrix[1]*m_matrix[10]); 
+	result.m_matrix[5] = inv_det *  (m_matrix[0]*m_matrix[10]- m_matrix[8]*m_matrix[2]); 
+	result.m_matrix[9] = inv_det *  (m_matrix[8]*m_matrix[1] - m_matrix[0]*m_matrix[9]);
+	result.m_matrix[13] = inv_det *  ((m_matrix[0]*m_matrix[9]-m_matrix[8]*m_matrix[1])*m_matrix[14]+
+					 (m_matrix[12]*m_matrix[1]-m_matrix[0]*m_matrix[13])*m_matrix[10]+
+					 (m_matrix[8]*m_matrix[13]-m_matrix[12]*m_matrix[9])*m_matrix[2]); 
+
+	result.m_matrix[2] = inv_det *  (m_matrix[1]*m_matrix[6] - m_matrix[5]*m_matrix[2]); 
+	result.m_matrix[6] = inv_det *  (m_matrix[4]*m_matrix[2] - m_matrix[0]*m_matrix[6]); 
+	result.m_matrix[10]= inv_det *  (m_matrix[0]*m_matrix[5] - m_matrix[4]*m_matrix[1]); 
+	result.m_matrix[14]= inv_det *  ((m_matrix[4]*m_matrix[1] - m_matrix[0]*m_matrix[5])*m_matrix[14]+
+					 (m_matrix[0]*m_matrix[13] - m_matrix[12]*m_matrix[1])*m_matrix[6]+
+					 (m_matrix[12]*m_matrix[5] - m_matrix[4]*m_matrix[13])*m_matrix[2]); 
+	
+	result.m_matrix[15] = 1.0f; 
+	
+	return result; 
+}
+
+void CAffinTransformMatrix::shear(const C3DFVector& shear, const C3DFVector& origin)
+{
+	vector<float> help(m_matrix); 
+	
+	help[ 0] += m_matrix[ 1] * shear.x; 
+	help[ 4] += m_matrix[ 5] * shear.x; 
+	help[ 8] += m_matrix[ 9] * shear.x; 
+
+	help[ 1] += m_matrix[ 2] * shear.y; 
+	help[ 5] += m_matrix[ 6] * shear.y; 
+	help[ 9] += m_matrix[10] * shear.y; 
+
+	help[ 2] += m_matrix[ 0] * shear.z; 
+	help[ 6] += m_matrix[ 4] * shear.z; 
+	help[10] += m_matrix[ 8] * shear.z; 
+
+	help[12] += m_matrix[13] * shear.x; 
+	help[13] += m_matrix[14] * shear.y; 
+	help[14] += m_matrix[12] * shear.z;
+
+	if (origin != C3DFVector::_0) {
+                help[12] += origin.x
+			-(m_matrix[9]*shear.x + m_matrix[8])*origin.z
+                        -(m_matrix[5]*shear.x + m_matrix[4])*origin.y
+                        -(m_matrix[1]*shear.x + m_matrix[0])*origin.x; 
+
+		help[13] += origin.y 
+			-(m_matrix[10]*shear.y + m_matrix[9]) * origin.z
+			-(m_matrix[ 6]*shear.y + m_matrix[5]) * origin.y
+			-(m_matrix[ 2]*shear.y + m_matrix[1]) * origin.x; 
+			
+		
+		help[14] += origin.z 
+			-(m_matrix[8]*shear.z + m_matrix[10])*origin.z
+			-(m_matrix[4]*shear.z + m_matrix[ 6])*origin.y
+			-(m_matrix[0]*shear.z + m_matrix[ 2])*origin.x;
+	}
+	swap(m_matrix, help); 
+}
+
+
+
+C3DFVector CAffinTransformMatrix::operator * (const C3DFVector& x) const
+{
+	return C3DFVector(
+		m_matrix[0] * x.x + m_matrix[4] * x.y + m_matrix[8] * x.z + m_matrix[12], 
+		m_matrix[1] * x.x + m_matrix[5] * x.y + m_matrix[9] * x.z + m_matrix[13], 
+		m_matrix[2] * x.x + m_matrix[6] * x.y + m_matrix[10] * x.z + m_matrix[14]); 
+}
+
+
+CAffinTransformMatrix operator * (const CAffinTransformMatrix& lhs, const CAffinTransformMatrix& rhs)
+{
+	CAffinTransformMatrix h(lhs); 
+	h*=rhs; 
+	return h; 
+}
+
+NS_MIA_END
diff --git a/mia/3d/affine_matrix.hh b/mia/3d/affine_matrix.hh
new file mode 100644
index 0000000..64d5a25
--- /dev/null
+++ b/mia/3d/affine_matrix.hh
@@ -0,0 +1,163 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_affine_matrix_hh
+#define mia_3d_affine_matrix_hh
+
+#include <mia/3d/quaternion.hh>
+
+NS_MIA_BEGIN
+
+
+/**
+   This class implements an affine 3D transformation as is is used with OpenGL. 
+   
+   This class implements affine 3D transformations. The storage layout is compatible 
+   with OpenGL. 
+*/
+class EXPORT_3D CAffinTransformMatrix {
+
+public: 
+	/// standard constructor, initializes the transformation with the identity. 
+        CAffinTransformMatrix(); 
+
+	/** A constructor to set all matrix values. Note, that in the numbering of the parameters 
+	    corresponds to (column, row) and that the last column is always [0,0,0,1]. 
+	 */
+        CAffinTransformMatrix(float a11, float a12, float a13, float a14, 
+			      float a21, float a22, float a23, float a24, 
+			      float a31, float a32, float a33, float a34); 
+
+	/**
+	   multiply the current matrix by a rotation around the x axis centered at the given location and with the given angle. 
+	   \param angle rotation angle in radians 
+	   \param center rotation center 
+	*/
+        void rotate_x(float angle, const C3DFVector& center = C3DFVector::_0); 
+
+	/**
+	   multiply the current matrix by a rotation around the y axis centered at the given location and with the given angle. 
+	   \param angle rotation angle in radians 
+	   \param center rotation center 
+	*/
+        void rotate_y(float angle, const C3DFVector& center = C3DFVector::_0); 
+
+	/**
+	   multiply the current matrix by a rotation around the z axis centered at the given location and with the given angle. 
+	   \param angle rotation angle in radians 
+	   \param center rotation center 
+	*/
+        void rotate_z(float angle, const C3DFVector& center = C3DFVector::_0); 
+
+	/**
+	   multiply the current matrix by a rotation as defined by the given quaternion  centered at the given location
+	   \param q quaternion describing rotation axis and angle
+	   \param center rotation center 
+
+	*/
+        void rotate(const Quaternion& q, const C3DFVector& center = C3DFVector::_0);
+
+	/**
+	   multiply the current matrix by a 3x3 transformation matrix centered at the given location 
+	   \param m 3x3 transformation matrix 
+	   \param center rotation center 
+
+	*/
+        void transform_centered(const C3DFMatrix& m, const C3DFVector& center = C3DFVector::_0);
+
+	/**
+	   multiply the current matrix by a scaling matrix centered at the given location
+	   \param scale saling factors along the three axis
+	   \param center of the scaling 
+
+	*/
+        void scale(const C3DFVector& scale, const C3DFVector& center = C3DFVector::_0); 
+
+
+	/**
+	   multiply the current matrix by a shearing matrix centered at the given location
+	   \param shear sharing factors along the three axis
+	   \param center of the scaling 
+
+	*/
+        void shear(const C3DFVector& shear, const C3DFVector& center = C3DFVector::_0); 
+
+	/**
+	   multiply the current matrix by a translation matrix
+	   \param shift the translation 
+	*/
+        void translate(const C3DFVector& shift); 
+
+	/**
+	   Reset the matrix to represent the identity matrix 
+	 */
+        void identity();
+
+	/**
+	   Multiply  the matrix with another matric from the right side. 
+	   \param rhs right hand side matrix 
+	   \returns a reference to the changed matrix 
+	 */
+        CAffinTransformMatrix& operator *= (const CAffinTransformMatrix& rhs); 
+        
+	/**
+	   \returns the inverse of the matrix
+	 */
+        const CAffinTransformMatrix inverse() const; 
+	
+	/**
+	   Apply the transformation to row vector \a x by multiplying it with the matrix 
+	   \remark the resulting notation is mentally wrong 
+	   \param x the vector to be transformed 
+	   \returns the transformed vector 
+	 */
+
+        C3DFVector operator * (const C3DFVector& x) const;
+
+	/**
+	   Apply only the rotation and scaling part of the transform. This is useful 
+	   to transform the rotation axis to the coordinate system the matrix is currently 
+	   aligned to. 
+	   \remark wrong frasing 
+	   \param x the input vector 
+	   \returns the rotated and scaled vector. 
+	 */
+        C3DFVector rotate(const C3DFVector& x) const;
+
+	/**
+	   \returns the raw matrix element in the apropriate order usable by OpenGL 
+	*/
+	const std::vector<float>& data() const; 
+private: 
+	std::vector<float> m_matrix;
+	
+}; 
+	
+
+/**
+   Multiply two affine matrices
+ */
+EXPORT_3D CAffinTransformMatrix operator * (const CAffinTransformMatrix& lhs, const CAffinTransformMatrix& rhs); 
+
+
+
+
+NS_MIA_END
+#endif 
diff --git a/mia/3d/camera.cc b/mia/3d/camera.cc
index af5ee80..0d4a6d0 100644
--- a/mia/3d/camera.cc
+++ b/mia/3d/camera.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/camera.hh b/mia/3d/camera.hh
index a5f4a7b..280ec8a 100644
--- a/mia/3d/camera.hh
+++ b/mia/3d/camera.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/combiner/CMakeLists.txt b/mia/3d/combiner/CMakeLists.txt
index e45d8fb..00cc67f 100644
--- a/mia/3d/combiner/CMakeLists.txt
+++ b/mia/3d/combiner/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 #
 
 SET(combiner3d
-	labelxmap
+#	labelxmap
 	ops
 )
 
diff --git a/mia/3d/combiner/labelxmap.cc b/mia/3d/combiner/labelxmap.cc
index 7138287..34cfa78 100644
--- a/mia/3d/combiner/labelxmap.cc
+++ b/mia/3d/combiner/labelxmap.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/combiner/labelxmap.hh b/mia/3d/combiner/labelxmap.hh
index 8a3a2e4..9f9c60b 100644
--- a/mia/3d/combiner/labelxmap.hh
+++ b/mia/3d/combiner/labelxmap.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/combiner/ops.cc b/mia/3d/combiner/ops.cc
index 5cb2c1c..d6ec4d0 100644
--- a/mia/3d/combiner/ops.cc
+++ b/mia/3d/combiner/ops.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,25 +26,10 @@ NS_BEGIN(Combiner3d)
 using namespace mia; 
 using namespace std; 
 
-C3DImageOpCombinerResult::C3DImageOpCombinerResult(P3DImage result):
-	m_result(result)
-{
-	
-}
-
-void C3DImageOpCombinerResult::do_save(const std::string& fname) const
-{
-	save_image(fname, m_result); 
-}
-
-boost::any C3DImageOpCombinerResult::do_get() const
-{
-	return boost::any(m_result);
-}
 
 template <typename BO>
 template <typename T, typename S>
-mia::PCombinerResult T3DImageCombiner<BO>::operator () ( const T3DImage<T>& a, const T3DImage<S>& b) const
+mia::P3DImage T3DImageCombiner<BO>::operator () ( const T3DImage<T>& a, const T3DImage<S>& b) const
 {
 	// there's got to be a better way ...
 	BO bo; 
@@ -55,11 +40,11 @@ mia::PCombinerResult T3DImageCombiner<BO>::operator () ( const T3DImage<T>& a, c
 	P3DImage result(r);
 
 	transform(a.begin(), a.end(), b.begin(), r->begin(), bo); 
-        return mia::PCombinerResult(new C3DImageOpCombinerResult(result)); 
+        return result; 
 }
 
 template <typename BO>
-mia::PCombinerResult  T3DImageCombiner<BO>::do_combine( const C3DImage& a, const C3DImage& b) const
+mia::P3DImage  T3DImageCombiner<BO>::do_combine( const C3DImage& a, const C3DImage& b) const
 {
 	if (a.get_size() != b.get_size()) {
 		throw create_exception<invalid_argument>("C3DAddImageCombiner: input images have different size: ", 
diff --git a/mia/3d/combiner/ops.hh b/mia/3d/combiner/ops.hh
index 4332066..3835fed 100644
--- a/mia/3d/combiner/ops.hh
+++ b/mia/3d/combiner/ops.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,15 +27,6 @@
 
 NS_BEGIN(Combiner3d)
 
-class C3DImageOpCombinerResult: public mia::CCombinerResult {
-public:
-	C3DImageOpCombinerResult(mia::P3DImage result);
-private:
-	virtual void do_save(const std::string& fname) const;
-	virtual boost::any do_get() const; 
-	mia::P3DImage m_result;
-};
-
 
 template <typename CombineOP>
 class T3DImageCombiner: public mia::C3DImageCombiner {
@@ -44,15 +35,15 @@ class T3DImageCombiner: public mia::C3DImageCombiner {
 	friend typename F::result_type mia::_filter(const F& f, const A& a, const B& b); 
 	
 	template <typename T, typename S>
-	mia::PCombinerResult operator () ( const mia::T3DImage<T>& a, const mia::T3DImage<S>& b) const;
+	mia::P3DImage operator () ( const mia::T3DImage<T>& a, const mia::T3DImage<S>& b) const;
 
-	mia::PCombinerResult do_combine( const mia::C3DImage& a, const mia::C3DImage& b) const;
+	mia::P3DImage do_combine( const mia::C3DImage& a, const mia::C3DImage& b) const;
 }; 
 
 
 #define COMBINE_OP(NAME, op) \
 	template <typename A, typename B>	\
-	struct __Combine##NAME {					\
+	struct __Combine##NAME {				\
 		typedef decltype(*(A*)0 op *(B*)0) return_type; \
 		static return_type apply(A a, B b) {		\
 			return a op b;				\
@@ -71,7 +62,29 @@ class T3DImageCombiner: public mia::C3DImageCombiner {
 COMBINE_OP(Add,   +)
 COMBINE_OP(Sub,   -)
 COMBINE_OP(Times, *)
-COMBINE_OP(Div,   /)
+
+
+template <typename A, typename B>				
+struct __CombineDiv {				
+	typedef decltype(*(A*)0 / *(B*)0) return_type; 
+	static return_type apply(A a, B b) {
+		if (b == 0) {
+			if (a == 0) 
+				return return_type(); 
+			mia::cvwarn() << "Error: division by zero, retain numerator value\n"; 
+			return a; 
+		}
+		return a / b;				
+	}
+};						
+
+class CombineDiv {
+public:									
+	template <typename A, typename B>
+	typename __CombineDiv<A,B>::return_type operator ()(A a, B b)const {
+		return __CombineDiv<A,B>::apply(a,b);
+	}
+};									\
 
 
 template <typename A, typename B>
@@ -82,6 +95,8 @@ struct __CombineAbsDiff {
 		}
 };						
 
+typedef T3DImageCombiner<CombineDiv> C3DDivImageCombiner;
+
 class CombineAbsDiff {							
 public:									
 	template <typename A, typename B>
diff --git a/mia/3d/combiner/plugin.hh b/mia/3d/combiner/plugin.hh
index 7fc7fa8..11c4f9c 100644
--- a/mia/3d/combiner/plugin.hh
+++ b/mia/3d/combiner/plugin.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/combiner/test_labelxmap.cc b/mia/3d/combiner/test_labelxmap.cc
index be64e3e..27dc065 100644
--- a/mia/3d/combiner/test_labelxmap.cc
+++ b/mia/3d/combiner/test_labelxmap.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/combiner/test_ops.cc b/mia/3d/combiner/test_ops.cc
index 6626c27..a4140ee 100644
--- a/mia/3d/combiner/test_ops.cc
+++ b/mia/3d/combiner/test_ops.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -81,36 +81,36 @@ CombinerOpsFixture::CombinerOpsFixture():
 
 BOOST_FIXTURE_TEST_CASE( test_add_combiner, CombinerOpsFixture )
 {
-	auto result = any_cast<P3DImage>(C3DAddImageCombiner().combine(*src1, *src2)->get()); 
+	auto result = C3DAddImageCombiner().combine(*src1, *src2); 
 	test_result<float>(*result, test_add); 
 }
 
 BOOST_FIXTURE_TEST_CASE( test_sub_combiner, CombinerOpsFixture )
 {
-	auto result = any_cast<P3DImage>(C3DSubImageCombiner().combine(*src1, *src2)->get()); 
+	auto result = C3DSubImageCombiner().combine(*src1, *src2); 
 	test_result<float>(*result, test_sub12); 
 	
-	result = any_cast<P3DImage>(C3DSubImageCombiner().combine(*src2, *src1)->get()); 
+	result = C3DSubImageCombiner().combine(*src2, *src1); 
 	test_result<float>(*result, test_sub21); 
 }
 
 BOOST_FIXTURE_TEST_CASE( test_times_combiner, CombinerOpsFixture )
 {
-	auto result = any_cast<P3DImage>(C3DTimesImageCombiner().combine(*src1, *src2)->get()); 
+	auto result = C3DTimesImageCombiner().combine(*src1, *src2); 
 	test_result<float>(*result, test_mult); 
 }
 
 BOOST_FIXTURE_TEST_CASE( test_div_combiner, CombinerOpsFixture )
 {
-	auto result = any_cast<P3DImage>(C3DDivImageCombiner().combine(*src2, *src1)->get()); 
+	auto result = C3DDivImageCombiner().combine(*src2, *src1); 
 	test_result<float>(*result, test_div21); 
 }
 
 BOOST_FIXTURE_TEST_CASE( test_absdiff_combiner, CombinerOpsFixture )
 {
-	auto result = any_cast<P3DImage>(C3DAbsDiffImageCombiner().combine(*src2, *src1)->get()); 
+	auto result = C3DAbsDiffImageCombiner().combine(*src2, *src1); 
 	test_result<float>(*result, test_absdiff); 
-	result = any_cast<P3DImage>(C3DAbsDiffImageCombiner().combine(*src1, *src2)->get()); 
+	result = C3DAbsDiffImageCombiner().combine(*src1, *src2); 
 	test_result<float>(*result, test_absdiff); 
 }
 
diff --git a/mia/3d/cost.cc b/mia/3d/cost.cc
index fb924a4..7ab7ff8 100644
--- a/mia/3d/cost.cc
+++ b/mia/3d/cost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,19 +34,10 @@ TPluginHandler<TFactory<C3DImageCost>>::m_help =
   "or will be called from generalized image similarity cost plug-ins that also take "
   "care of transforming and scaling the images during the image registration process.";
 
-using boost::filesystem::path; 
-C3DImageCostPluginHandlerTestPath::C3DImageCostPluginHandlerTestPath()
-{
-	CPathNameArray costsearchpath;
-	costsearchpath.push_back( path(MIA_BUILD_ROOT"/mia/3d/cost") );
-	C3DImageCostPluginHandler::set_search_path(costsearchpath);
-	
-}
-
-template class EXPORT_HANDLER TCost<C3DImage, C3DFVectorfield>;
-template class EXPORT_HANDLER TPlugin<C3DImage, cost_type>;
-template class EXPORT_HANDLER TFactory<C3DImageCost>;
-template class EXPORT_HANDLER THandlerSingleton<TFactoryPluginHandler<C3DImageCostPlugin> >;
+template class TCost<C3DImage, C3DFVectorfield>;
+template class TPlugin<C3DImage, cost_type>;
+template class TFactory<C3DImageCost>;
+template class THandlerSingleton<TFactoryPluginHandler<C3DImageCostPlugin> >;
 template class TFactoryPluginHandler<C3DImageCostPlugin>;
 template class TPluginHandler<C3DImageCostPlugin>;
 
diff --git a/mia/3d/cost.hh b/mia/3d/cost.hh
index 30371ba..dfa24a6 100644
--- a/mia/3d/cost.hh
+++ b/mia/3d/cost.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,8 @@
 
 NS_MIA_BEGIN
 
+
+extern template class EXPORT_3D TCost<C3DImage, C3DFVectorfield>;
 /**
    @ingroup registration 
    @brief the image-to-image cost function base class 
@@ -50,16 +52,6 @@ typedef TFactory<C3DImageCost> C3DImageCostPlugin;
 */
 typedef THandlerSingleton<TFactoryPluginHandler<C3DImageCostPlugin> > C3DImageCostPluginHandler;
 
-/** 
-    @cond INTERNAL
-    @ingroup test 
-    @brief Initializer for testing un-installed plug-ins 
- */
-struct EXPORT_3D C3DImageCostPluginHandlerTestPath {
-	C3DImageCostPluginHandlerTestPath(); 
-}; 
-/// @endcond 
-
 /// @cond NEVER 
 FACTORY_TRAIT(C3DImageCostPluginHandler);
 /// @endcond 
diff --git a/mia/3d/cost/CMakeLists.txt b/mia/3d/cost/CMakeLists.txt
index 756a32b..052f745 100644
--- a/mia/3d/cost/CMakeLists.txt
+++ b/mia/3d/cost/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,7 +18,10 @@
 
 SET(cost3d
 	   ssd
+           ssd-automask
+           lncc
 	   ngf
+           ncc 
 	   mi 
 )
 
diff --git a/mia/3d/cost/lncc.cc b/mia/3d/cost/lncc.cc
new file mode 100644
index 0000000..c8e28aa
--- /dev/null
+++ b/mia/3d/cost/lncc.cc
@@ -0,0 +1,219 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/cost/lncc.hh>
+
+#include <mia/core/threadedmsg.hh>
+#include <mia/core/nccsum.hh>
+#include <tbb/parallel_reduce.h>
+#include <tbb/blocked_range.h>
+
+
+NS_BEGIN(NS)
+
+using namespace mia; 
+using std::vector; 
+using std::pair; 
+using std::make_pair; 
+
+CLNCC3DImageCost::CLNCC3DImageCost(int hw):
+m_hwidth(hw)
+{
+}
+
+inline pair<C3DBounds, C3DBounds> prepare_range(const C3DBounds& size, int cx, int cy, int cz, int hw) 
+{
+	int zb = cz - hw;
+	if (zb < 0) zb = 0; 
+	unsigned ze = cz + hw + 1; 
+	if (ze > size.z) ze = size.z; 
+	
+	int yb = cy - hw;
+	if (yb < 0) yb = 0; 
+	unsigned ye = cy + hw + 1; 
+	if (ye > size.y) ye = size.y; 
+	
+	int xb = cx - hw;
+	if (xb < 0) xb = 0; 
+	unsigned xe = cx + hw + 1; 
+	if (xe > size.x) xe = size.x; 
+	
+	return make_pair(C3DBounds(xb,yb,zb), C3DBounds(xe,ye,ze)); 
+}
+
+
+
+class FEvalCost : public TFilter<float> {
+	int m_hw;
+public:
+	FEvalCost(int hw):
+		m_hw(hw)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		auto evaluate_local_cost = [this, &mov, &ref](const tbb::blocked_range<size_t>& range, const pair<float, int>& result) -> pair<float, int> {
+			CThreadMsgStream msks; 
+			float lresult = 0.0; 
+			int count = 0; 
+		
+			for (auto z = range.begin(); z != range.end(); ++z) {
+				for (size_t y = 0; y < mov.get_size().y; ++y)
+					for (size_t x = 0; x < mov.get_size().x; ++x) {
+						
+						auto c_block = prepare_range(mov.get_size(), x, y, z, m_hw); 
+						auto ia = mov.begin_range(c_block.first,c_block.second); 
+						auto ea = mov.end_range(c_block.first,c_block.second); 
+						auto ib = ref.begin_range(c_block.first,c_block.second); 
+						
+						auto delta_size = c_block.second - c_block.first; 
+						auto n = delta_size.product(); 
+						
+						if (n > 1) {
+							
+							NCCSums sum; 
+							
+							while (ia != ea) {
+								sum.add(*ia, *ib); 
+								++ia; ++ib; 
+							}
+							
+							lresult += sum.value(); 
+							++count; 
+						}
+					}
+			}
+			return make_pair(result.first + lresult, result.second + count); 
+		};
+		
+		pair<float,int> init{0, 0}; 
+		auto r = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), init, evaluate_local_cost, 
+					 [](const pair<float,int>& x, const pair<float,int>& y){
+						 return make_pair(x.first + y.first, x.second + y.second);
+					 });	
+		return r.second > 0 ? r.first / r.second : 0.0; 
+	}
+}; 
+
+
+double CLNCC3DImageCost::do_value(const Data& a, const Data& b) const
+{
+	FEvalCost ecost(m_hwidth); 
+	return mia::filter(ecost, a, b); 
+}
+
+
+class FEvalCostForce : public TFilter<float> {
+	int m_hw;
+	C3DFVectorfield& m_force; 
+public: 
+	FEvalCostForce(int hw, C3DFVectorfield& force):
+		m_hw(hw), 
+		m_force(force)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		auto ag = get_gradient(mov); 
+		auto evaluate_local_cost_force = [this, &mov, &ref, &ag](const tbb::blocked_range<size_t>& range, 
+									 const pair<float, int>& result) -> pair<float, int> {
+			
+			CThreadMsgStream msks; 		
+			float lresult = 0.0; 
+			int count = 0; 
+			for (auto z = range.begin(); z != range.end(); ++z) {
+                        
+				auto iforce = m_force.begin_at(0,0,z);
+				auto ig = ag.begin_at(0,0,z);
+				auto imov = mov.begin_at(0,0,z);
+				auto iref = ref.begin_at(0,0,z);
+                        
+				for (size_t y = 0; y < mov.get_size().y; ++y)
+					for (size_t x = 0; x < mov.get_size().x; ++x, ++iforce, ++ig, ++iref, ++imov) {
+						auto c_block = prepare_range(mov.get_size(), x, y, z, m_hw); 
+						auto ia = mov.begin_range(c_block.first,c_block.second); 
+						auto ea = mov.end_range(c_block.first,c_block.second); 
+						auto ib = ref.begin_range(c_block.first,c_block.second); 
+						
+						auto delta_size = c_block.second - c_block.first; 
+						auto n = delta_size.product(); 
+						
+						if (n > 1) {
+
+							NCCSums sum; 
+
+							while (ia != ea) {
+								sum.add(*ia, *ib); 
+								++ia; ++ib; 
+							}
+							
+							auto res = sum.get_grad_helper(); 
+							lresult += res.first;
+							*iforce = res.second.get_gradient_scale(*imov, *iref) * *ig; 
+							++count; 
+							
+						}
+					}
+			}
+			return make_pair(result.first + lresult, result.second + count); 
+		};
+		pair<float,int> init{0, 0}; 		
+		auto r = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), init, evaluate_local_cost_force, 
+					 [](const pair<float,int>& x, const pair<float,int>& y){
+						 return make_pair(x.first + y.first, x.second + y.second);
+					 });
+		
+		return r.second > 0 ? r.first / r.second : 0.0; 
+	}
+	
+};
+
+double CLNCC3DImageCost::do_evaluate_force(const Data& a, const Data& b, Force& force) const
+{
+	FEvalCostForce ecostforce(m_hwidth, force); 
+	return mia::filter(ecostforce, a, b); 
+}
+
+
+CLNCC3DImageCostPlugin::CLNCC3DImageCostPlugin():
+        C3DImageCostPlugin("lncc"), 
+	m_hw(5)
+{
+	this->add_parameter("w", new CUIntParameter(m_hw, 1, 256, false, 
+						    "half width of the window used for evaluating the localized cross correlation")); 
+}
+
+C3DImageCost *CLNCC3DImageCostPlugin::do_create() const
+{
+	return new CLNCC3DImageCost(m_hw);
+}
+
+const std::string CLNCC3DImageCostPlugin::do_get_descr() const
+{
+	return "local normalized cross correlation with masking support."; 
+}
+
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new CLNCC3DImageCostPlugin();
+}
+
+NS_END
diff --git a/mia/3d/cost/lncc.hh b/mia/3d/cost/lncc.hh
new file mode 100644
index 0000000..42ee1dd
--- /dev/null
+++ b/mia/3d/cost/lncc.hh
@@ -0,0 +1,53 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_maskedcost_lncc_hh
+#define mia_3d_maskedcost_lncc_hh
+
+#include <mia/3d/cost.hh>
+
+#define NS mia_3d_lncc
+
+NS_BEGIN(NS)
+
+class CLNCC3DImageCost: public mia::C3DImageCost {
+public: 	
+	typedef mia::C3DImageCost::Data Data; 
+
+	CLNCC3DImageCost(int hw);
+private: 
+	virtual double do_value(const Data& a, const Data& b) const; 
+	virtual double do_evaluate_force(const Data& a, const Data& b, Force& force) const; 
+
+        int m_hwidth; 
+};
+
+class CLNCC3DImageCostPlugin: public mia::C3DImageCostPlugin {
+public: 
+	CLNCC3DImageCostPlugin();
+	mia::C3DImageCost *do_create() const;
+private: 
+	const std::string do_get_descr() const; 
+        unsigned int m_hw; 
+};
+
+NS_END
+
+#endif 
diff --git a/mia/3d/cost/mi.cc b/mia/3d/cost/mi.cc
index f80ecef..35a2639 100644
--- a/mia/3d/cost/mi.cc
+++ b/mia/3d/cost/mi.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/cost/mi.hh b/mia/3d/cost/mi.hh
index 166fb92..85ecf4b 100644
--- a/mia/3d/cost/mi.hh
+++ b/mia/3d/cost/mi.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/cost/ncc.cc b/mia/3d/cost/ncc.cc
new file mode 100644
index 0000000..fe9ed2d
--- /dev/null
+++ b/mia/3d/cost/ncc.cc
@@ -0,0 +1,171 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/cost/ncc.hh>
+
+#include <mia/core/threadedmsg.hh>
+#include <mia/core/nccsum.hh> 
+#include <tbb/parallel_reduce.h>
+#include <tbb/parallel_for.h>
+#include <tbb/blocked_range.h>
+
+
+NS_BEGIN(NS)
+
+using namespace mia; 
+
+
+CNCC3DImageCost::CNCC3DImageCost()
+{
+}
+
+template <typename T, typename S> 
+struct FEvaluateNCCSum {
+	FEvaluateNCCSum(const T& mov, const S& ref); 
+	NCCSums operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const; 
+private: 
+	T m_mov; 
+	S m_ref; 
+};
+
+
+template <typename T, typename S> 
+FEvaluateNCCSum<T,S>::FEvaluateNCCSum(const T& mov, const S& ref):
+	m_mov(mov), m_ref(ref) 
+{
+	
+}
+
+template <typename T, typename S> 
+NCCSums FEvaluateNCCSum<T,S>::operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const
+{
+	CThreadMsgStream msks; 
+	
+	NCCSums sum;
+	for (auto z = range.begin(); z != range.end(); ++z) {
+		auto ia = m_mov.begin_at(0, 0, z); 
+		auto ib = m_ref.begin_at(0, 0, z); 
+		auto eb = m_ref.begin_at(0, 0, z + 1); 
+		
+		while (ib != eb) {
+			sum.add(*ia, *ib); 
+			++ia; ++ib; 
+		}
+	}
+	return sum + sumacc; 
+};
+
+
+class FEvalCost : public TFilter<float> {
+public:
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+
+		FEvaluateNCCSum<T,R> ev(mov, ref); 
+		NCCSums sum; 
+		sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), sum, ev, 
+				      [](const NCCSums& x, const NCCSums& y){
+					      return x + y;
+				      });
+		return sum.value(); 
+	}
+}; 
+
+
+double CNCC3DImageCost::do_value(const Data& a, const Data& b) const
+{
+	FEvalCost ecost; 
+	return mia::filter(ecost, a, b); 
+}
+
+
+class FEvalCostForce : public TFilter<float> {
+	C3DFVectorfield& m_force; 
+public: 
+	FEvalCostForce(C3DFVectorfield& force):
+		m_force(force)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		CThreadMsgStream msks;
+		
+		NCCSums sum; 
+		FEvaluateNCCSum<T,R> ev(mov, ref); 
+		sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), sum, ev, 
+					 [](const NCCSums& x, const NCCSums& y){
+					      return x + y;
+				      });
+		
+		auto geval = sum.get_grad_helper(); 
+
+		auto grad = get_gradient(mov); 
+		auto grad_eval = [this, &mov, &ref, &grad, &geval](const tbb::blocked_range<size_t>& range) {
+			for (auto z = range.begin(); z != range.end(); ++z) {
+				auto ig = grad.begin_at(0,0,z); 
+				auto iforce = m_force.begin_at(0,0,z); 
+				auto ia = mov.begin_at(0,0,z); 
+				auto ib = ref.begin_at(0,0,z); 
+				auto eb = ref.begin_at(0,0,z+1); 
+				
+				while (ib != eb) {
+					*iforce = geval.second.get_gradient_scale(*ia, *ib) * *ig; 
+					++ig; 
+					++iforce; 
+					++ia; ++ib;
+				}
+			}; 
+		}; 
+		
+		parallel_for(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), grad_eval); 
+
+		return geval.first; 
+	}
+	
+};
+
+double CNCC3DImageCost::do_evaluate_force(const Data& a, const Data& b, Force& force) const
+{
+	FEvalCostForce ecostforce(force); 
+	return mia::filter(ecostforce, a, b); 
+}
+
+
+CNCC3DImageCostPlugin::CNCC3DImageCostPlugin():
+C3DImageCostPlugin("ncc")
+{
+}
+
+C3DImageCost *CNCC3DImageCostPlugin::do_create() const
+{
+	return new CNCC3DImageCost();
+}
+
+const std::string CNCC3DImageCostPlugin::do_get_descr() const
+{
+	return "normalized cross correlation."; 
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new CNCC3DImageCostPlugin();
+}
+
+NS_END
diff --git a/mia/3d/cost/ncc.hh b/mia/3d/cost/ncc.hh
new file mode 100644
index 0000000..8ed3b32
--- /dev/null
+++ b/mia/3d/cost/ncc.hh
@@ -0,0 +1,51 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_cost_ncc_hh
+#define mia_3d_cost_ncc_hh
+
+#include <mia/3d/cost.hh>
+
+#define NS mia_3d_ncc
+
+NS_BEGIN(NS)
+
+class CNCC3DImageCost: public mia::C3DImageCost {
+public: 	
+	typedef mia::C3DImageCost::Data Data; 
+	typedef mia::C3DImageCost::Force Force; 
+
+	CNCC3DImageCost();
+private: 
+	virtual double do_value(const Data& a, const Data& b) const; 
+	virtual double do_evaluate_force(const Data& a, const Data& b, Force& force) const; 
+};
+
+class CNCC3DImageCostPlugin: public mia::C3DImageCostPlugin {
+public: 
+	CNCC3DImageCostPlugin();
+	mia::C3DImageCost *do_create() const;
+private: 
+	const std::string do_get_descr() const; 
+};
+
+NS_END
+
+#endif 
diff --git a/mia/3d/cost/ngf.cc b/mia/3d/cost/ngf.cc
index ded5e15..378b8da 100644
--- a/mia/3d/cost/ngf.cc
+++ b/mia/3d/cost/ngf.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,19 +34,19 @@ double FEvaluator::operator()(const mia::C3DFVector& src, const mia::C3DFVector&
 	return cost(src, ref); 
 }
 
-C3DFMatrix FEvaluator::get_gradient(C3DFVectorfield::const_range_iterator& irsrc, int nx, int nxy) const
+C3DFMatrix FEvaluator::get_gradient(field_range_iterator& irsrc, int nx, int nxy) const
 {
 	cvdebug() << irsrc.get_boundary_flags() << "\n"; 
 	C3DFMatrix result; 
 	C3DFVectorfield::const_iterator isrc = irsrc.get_point(); 
 	
-	if (! (irsrc.get_boundary_flags() & C3DFVectorfield::const_range_iterator::eb_x))
+	if (! (irsrc.get_boundary_flags() & field_range_iterator::eb_x))
 		result.x = 0.5 * (isrc[1] - isrc[-1]); 
 	
-	if (! (irsrc.get_boundary_flags() & C3DFVectorfield::const_range_iterator::eb_y))
+	if (! (irsrc.get_boundary_flags() & field_range_iterator::eb_y))
 		result.y = 0.5 * (isrc[nx] - isrc[-nx]); 
 	
-	if (! (irsrc.get_boundary_flags() & C3DFVectorfield::const_range_iterator::eb_z))
+	if (! (irsrc.get_boundary_flags() & field_range_iterator::eb_z))
 		result.z = 0.5 * (isrc[nxy] - isrc[-nxy]); 
 
 	cvdebug() << irsrc.get_boundary_flags() << "\n"; 
@@ -63,12 +63,12 @@ double FScalar::cost(const C3DFVector& src, const C3DFVector& ref) const
 
 
 
-C3DFVector  FScalar::grad (int nx, int nxy, C3DFVectorfield::const_range_iterator irsrc,
+C3DFVector  FScalar::grad (int nx, int nxy, field_range_iterator& irsrc,
 			   const C3DFVector& ref, double& cost) const	
 {
 	double d = dot(*irsrc,ref);
 	cost -= d * d;
-	return - d * (ref * get_gradient(irsrc, nx, nxy)); 
+	return - d * (get_gradient(irsrc, nx, nxy) * ref); 
 }
 
 double FCross::cost(const C3DFVector& src, const C3DFVector& ref) const
@@ -77,7 +77,7 @@ double FCross::cost(const C3DFVector& src, const C3DFVector& ref) const
 	return d.norm2(); 
 }
 
-C3DFVector  FCross::grad (int nx, int nxy, C3DFVectorfield::const_range_iterator irsrc,
+C3DFVector  FCross::grad (int nx, int nxy, field_range_iterator& irsrc,
 	      const C3DFVector& ref, double& cost) const 
 {
 	C3DFVector d = cross(*irsrc, ref);
@@ -114,7 +114,7 @@ double FDeltaScalar::cost (const C3DFVector& src, const C3DFVector& ref) const
 	return dot(dh.delta, dh.delta); 
 }
 
-C3DFVector FDeltaScalar::grad (int nx, int nxy, C3DFVectorfield::const_range_iterator irsrc,
+C3DFVector FDeltaScalar::grad (int nx, int nxy, field_range_iterator& irsrc,
 			     const C3DFVector& ref, double& cost) const
 {
 	DotHelper dh(*irsrc, ref); 
@@ -167,8 +167,9 @@ double C3DNFGImageCost::do_evaluate_force(const mia::C3DImage& a,
 	const int nx = ng_a.get_size().x; 
 	const int nxy = nx * ng_a.get_size().y; 
 	
-	auto ia = ng_a.begin_range(C3DBounds::_0, ng_a.get_size()); 
-	auto ie = ng_a.end_range(C3DBounds::_0, ng_a.get_size()); 
+	auto  ia = ng_a.begin_range(C3DBounds::_0, ng_a.get_size()).with_boundary_flag(); 
+	auto  ie = ng_a.end_range(C3DBounds::_0, ng_a.get_size()).with_boundary_flag(); 
+	
 	auto ib = m_ng_ref.begin_range(C3DBounds::_0, m_ng_ref.get_size()); 
 	auto iforce = force.begin_range(C3DBounds::_0, force.get_size()); 
 
@@ -183,38 +184,41 @@ double C3DNFGImageCost::do_evaluate_force(const mia::C3DImage& a,
 	return 0.5 * sum;
 }
 
+const TDictMap<C3DNFGImageCostPlugin::ESubTypes>::Table lut[] = {
+	{"ds", C3DNFGImageCostPlugin::st_delta_scalar, "square of scaled difference"},
+	{"dot", C3DNFGImageCostPlugin::st_scalar, "scalar product kernel"},
+	{"cross", C3DNFGImageCostPlugin::st_cross, "cross product kernel"},
+	{0, C3DNFGImageCostPlugin::st_unknown, ""}
+};
+const TDictMap<C3DNFGImageCostPlugin::ESubTypes> subtypemap(lut);
+
 C3DNFGImageCostPlugin::C3DNFGImageCostPlugin():
 	C3DImageCostPlugin("ngf"),
-	m_kernel("ds")
+	m_kernel(st_delta_scalar)
 {
 	TRACE("C3DNFGImageCostPlugin::C3DNFGImageCostPlugin()");
+
+
+
 	add_parameter("eval",
-		      new CStringParameter(m_kernel, false, "plugin subtype (sq, ds,dot,cross)"));
+		      new CDictParameter<ESubTypes>(m_kernel, subtypemap, "plugin subtype (sq, ds,dot,cross)"));
 
 }
 
-enum ESubTypes {st_unknown, st_delta_scalar, st_scalar, st_cross};
 
 C3DImageCost *C3DNFGImageCostPlugin::do_create()const
 {
 	TRACE("C3DNFGImageCostPlugin::do_create");
 
-	const TDictMap<ESubTypes>::Table lut[] = {
-		{"ds", st_delta_scalar, "square of scaled difference"},
-		{"dot", st_scalar, "scalar product kernel"},
-		{"cross", st_cross, "cross product kernel"},
-		{0, st_unknown, ""}
-	};
-	const TDictMap<ESubTypes> subtypemap(lut);
 
 	PEvaluator eval;
-	switch (subtypemap.get_value(m_kernel.c_str())) {
+	switch (m_kernel) {
 	case st_delta_scalar: eval.reset(new FDeltaScalar()); break;
 	case st_scalar: eval.reset(new FScalar()); break;
 	case st_cross: eval.reset(new FCross()); break;
 	default:
 		throw invalid_argument(string("C3DNFGImageCostPlugin: unknown cost sub-type '")
-				       +m_kernel+"'");
+				       +subtypemap.get_name(m_kernel)+"'");
 	}
 	return new C3DNFGImageCost(eval);
 }
diff --git a/mia/3d/cost/ngf.hh b/mia/3d/cost/ngf.hh
index e1b9328..505a8d4 100644
--- a/mia/3d/cost/ngf.hh
+++ b/mia/3d/cost/ngf.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,21 +29,22 @@ NS_BEGIN(ngf_3dimage_cost)
 
 class FEvaluator {
 public:
+	typedef mia::C3DFVectorfield::const_range_iterator_with_boundary_flag field_range_iterator; 
 	typedef double result_type; 
         virtual ~FEvaluator(){};
 	virtual double cost (const mia::C3DFVector& src, const mia::C3DFVector& ref) const = 0;
-	virtual mia::C3DFVector grad(int nx, int nxy, mia::C3DFVectorfield::const_range_iterator isrc,
+	virtual mia::C3DFVector grad(int nx, int nxy, field_range_iterator& isrc,
 				     const mia::C3DFVector& ref, double& cost) const = 0;
 
 	double operator()(const mia::C3DFVector& src, const mia::C3DFVector& ref) const; 
 protected:
-	mia::C3DFMatrix get_gradient(mia::C3DFVectorfield::const_range_iterator& isrc, int nx, int nxy) const; 
+	mia::C3DFMatrix get_gradient(field_range_iterator& isrc, int nx, int nxy) const; 
 };
 
 class FScalar: public FEvaluator {
 public:
 	virtual double cost (const mia::C3DFVector& src, const mia::C3DFVector& ref) const;
-	virtual mia::C3DFVector grad(int nx, int nxy, mia::C3DFVectorfield::const_range_iterator isrc,
+	virtual mia::C3DFVector grad(int nx, int nxy, field_range_iterator& isrc,
 				     const mia::C3DFVector& ref, double& cost) const;
 };
 
@@ -51,14 +52,14 @@ class FCross: public FEvaluator {
 public:
 	virtual double cost (const mia::C3DFVector& src, const mia::C3DFVector& ref) const; 
 	
-	virtual mia::C3DFVector grad(int nx, int nxy, mia::C3DFVectorfield::const_range_iterator isrc,
+	virtual mia::C3DFVector grad(int nx, int nxy, field_range_iterator& isrc,
 				     const mia::C3DFVector& ref, double& cost) const;
 };
 
 class FDeltaScalar: public FEvaluator {
 public:
 	virtual double cost (const mia::C3DFVector& src, const mia::C3DFVector& ref) const; 
-	virtual mia::C3DFVector grad(int nx, int nxy, mia::C3DFVectorfield::const_range_iterator isrc,
+	virtual mia::C3DFVector grad(int nx, int nxy, field_range_iterator& isrc,
 				     const mia::C3DFVector& ref, double& cost) const; 
 };
 
@@ -80,12 +81,13 @@ private:
 
 class C3DNFGImageCostPlugin: public mia::C3DImageCostPlugin {
 public:
+	enum ESubTypes {st_unknown, st_delta_scalar, st_scalar, st_cross};
 	C3DNFGImageCostPlugin();
 private:
 	virtual mia::C3DImageCost *do_create()const;
 
 	const std::string do_get_descr()const;
-	std::string m_kernel;
+	ESubTypes m_kernel;
 };
 
 
diff --git a/mia/3d/cost/ssd-automask.cc b/mia/3d/cost/ssd-automask.cc
new file mode 100644
index 0000000..c2c1703
--- /dev/null
+++ b/mia/3d/cost/ssd-automask.cc
@@ -0,0 +1,51 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/cost.hh>
+
+#define NS ssdautomask_3dimage_cost
+#include <mia/3d/cost/ssd-automask.hh>
+#include <mia/template/ssd-automask.cxx>
+
+NS_BEGIN(NS)
+
+
+NS_MIA_USE;
+using namespace std;
+using namespace boost;
+
+
+template class TSSDAutomaskCost<C3DImageCost>;
+
+
+const string C3DSSDAutomaskCostPlugin::do_get_descr()const
+{
+	return "3D image cost: sum of squared differences, with automasking based on given thresholds";
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C3DSSDAutomaskCostPlugin();
+}
+
+
+NS_END
+
+
diff --git a/mia/3d/cost/ssd-automask.hh b/mia/3d/cost/ssd-automask.hh
new file mode 100644
index 0000000..288d18a
--- /dev/null
+++ b/mia/3d/cost/ssd-automask.hh
@@ -0,0 +1,36 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/cost.hh>
+
+#define NS ssdautomask_3dimage_cost
+#include <mia/template/ssd-automask.hh>
+
+NS_BEGIN(NS);
+
+
+typedef TSSDAutomaskCost<mia::C3DImageCost> C3DSSDAutomaskCost;
+
+class C3DSSDAutomaskCostPlugin: public TSSDAutomaskCostPlugin<mia::C3DImageCostPlugin, C3DSSDAutomaskCost> {
+private:
+	virtual const std::string do_get_descr()const;
+};
+
+NS_END
diff --git a/mia/3d/cost/ssd.cc b/mia/3d/cost/ssd.cc
index b440959..6189546 100644
--- a/mia/3d/cost/ssd.cc
+++ b/mia/3d/cost/ssd.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/cost/ssd.hh b/mia/3d/cost/ssd.hh
index 732f44b..70335e7 100644
--- a/mia/3d/cost/ssd.hh
+++ b/mia/3d/cost/ssd.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/cost/test_lncc.cc b/mia/3d/cost/test_lncc.cc
new file mode 100644
index 0000000..ed184ba
--- /dev/null
+++ b/mia/3d/cost/test_lncc.cc
@@ -0,0 +1,188 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <mia/internal/plugintester.hh>
+#include <mia/3d/cost/lncc.hh>
+
+using namespace NS; 
+using namespace mia; 
+
+
+
+
+BOOST_AUTO_TEST_CASE( test_lncc_1 ) 
+{
+        C3DBounds size(4,4,4); 
+        auto lncc = BOOST_TEST_create_from_plugin<CLNCC3DImageCostPlugin>("lncc:w=1");
+
+        	const float src_data[64] = {           /*   0  1  2  3  4  5  6  7  8  9     */    
+		1, 1, 2, 2, 
+		2, 3, 4, 4,        /*1                                 0 */
+		4, 4, 3, 3, 
+		2, 2, 2, 1,        /*2     1  2  1  1     1            6 */
+		
+		2, 2, 3, 4, 
+		5, 6, 7, 8,        /*3        1  2     1  1  1  1      7 */
+		8, 7, 2, 8, 
+		3, 4, 2, 2,        /*4     1     1  1     2  1  1      7 */ 
+		
+		3, 1, 3, 4, 
+		5, 6, 7, 8,        /*5     1     2  1        2  1      7 */
+		3, 4, 4, 5, 
+		6, 4, 2, 2,        /*6        3     3     1            7 */
+		
+	        3, 2, 3, 4, 
+		5, 3, 1, 4,        /*7     1  1  2  2  1               7 */
+		5, 6, 7, 3, 
+		2, 1, 2, 6         /*8     1  2  1        2  1         7 */
+		};                                     /*      5  9  9  8  2  7  5  3        */
+	
+	const float ref_data[64] = {
+		1, 1, 1, 5, 
+		1, 1, 1, 1, 
+		2, 2, 2, 7,
+		2, 2, 2, 2,
+		
+		3, 3, 3, 5, 
+		3, 3, 3, 3, 
+		4, 4, 6, 4, 
+		3, 4, 4, 4,
+
+		5, 5, 5, 6, 
+		4, 2, 1, 5, 
+		6, 6, 4, 5, 
+		6, 6, 6, 6,
+		
+	        7, 7, 7, 7, 
+		7, 5, 7, 7, 
+		8, 8, 8, 8, 
+		8, 8, 8, 8
+	};
+
+        
+	C3DFImage src_f(size, src_data); 
+        C3DFImage ref_f(size, ref_data); 
+
+        
+        lncc->set_reference(ref_f); 
+        BOOST_CHECK_SMALL(lncc->value(ref_f), 1e-10);
+        
+        auto v = lncc->value(src_f); 
+        BOOST_CHECK_CLOSE(v, 1 - 0.1240591275, 0.1); 
+        
+	C3DFVectorfield zero_force(size); 
+	v = lncc->evaluate_force(ref_f, zero_force); 
+	BOOST_CHECK_SMALL(v, 1e-10);
+
+	for (auto iv = zero_force.begin(); iv != zero_force.end();  ++iv) {
+		BOOST_CHECK_SMALL(iv->x, 1e-8f); 
+		BOOST_CHECK_SMALL(iv->y, 1e-8f); 
+		BOOST_CHECK_SMALL(iv->z, 1e-8f); 
+	}
+	
+	C3DFVectorfield force(size); 
+
+	v = lncc->evaluate_force(src_f, force); 
+	BOOST_CHECK_CLOSE(v, 1 - 0.1240591275, 0.1); 
+        
+	
+	float gradx[] = {
+		0,0.009024,0.0067829344,0,
+		0,0.0207070571,0.0025820212,0,
+		0,-0.0043571612,-0.0007584461,0,
+		0,0,-0.0051883059,0,
+		
+		0,-0.0001718316,0,0,
+		0,0.0001363411,-0.0002484197,0,
+		0,0.0005363503,0.0021445316,0,
+		0,6.74712351959028E-006,-0.0003612011,0,
+		
+		0,0,-0.0051916234,0,
+		0,-0.0113564346,-0.0215016708,0,
+		0,0.0022341183,-0.0051260847,0,
+		0,-0.000510479,0.0001938512,0,
+		
+		0,0,0.0296423058,0,
+		0,0.0122280155,0.001550289,0,
+		0,0.0322028493,-0.0435344672,0,
+		0,0,-0.0193401882,0
+	};
+
+	float grady[] = {
+		0,0,0,0,
+		0.0519478283,0.0310605856,0.0025820212,-0.0056788204,
+		0,-0.0043571612,-0.0015168922,-0.0150381199,
+		0,0,0,0,
+		0,0,0,0,
+		0.0076591376,0.0003408528,0.0001242098,-0.0022727478,
+		-0.0071921279,0.0001787834,-0.0107226582,-0.0106848188,
+		0,0,0,0,
+		0,0,0,0,
+		0,-0.0170346519,-0.0107508354,0.0073412295,
+		5.36748306398076E-005,-0.0044682366,0.0256304233,0.0056020016,
+		0,0,0,0,
+		0,0,0,0,
+		0.0035010614,-0.0122280155,0.0062011562,-0.0092450912,
+		-0.0721751187,-0.0322028493,0.0145114891,0.019820525,
+		0,0,0,0
+	}; 
+	
+	float gradz[] = {
+		0,0,0,0,
+		0,0,0,0,
+		0,0,0,0,
+		0,0,0,0,
+		-0.0050152483,0,0,0.003136997,
+		0.0038295688,0.0002045117,-0.0003726295,-0.0022727478,
+		-0.0035960639,0,0.0021445316,0.0035616063,
+		0.0196224432,-1.34942470391806E-005,0,0.0004336735,
+		0.002956669,0,0,0,
+		0,0.0170346519,0.0645050124,-0.0293649178,
+		-0.0001610245,-0.0022341183,-0.0256304233,0.0046683347,
+		-0.0048455579,-0.0003828592,0,-0.0010597761,
+		0,0,0,0,
+		0,0,0,0,
+		0,0,0,0,
+		0,0,0,0
+	}; 
+
+
+	auto igx = gradx; 
+	auto igy = grady; 
+	auto igz = gradz; 
+
+	for (auto iv = force.begin(); iv != force.end();  ++iv, ++igx, ++igy, ++igz) {
+		if (*igx == 0.0) 
+			BOOST_CHECK_SMALL(iv->x, 1e-8f); 
+		else 
+			BOOST_CHECK_CLOSE(iv->x, *igx, 0.1); 
+
+		if (*igy == 0.0) 
+			BOOST_CHECK_SMALL(iv->y, 1e-8f); 
+		else 
+			BOOST_CHECK_CLOSE(iv->y, *igy, 0.1); 
+		
+		if (*igz == 0.0)
+			BOOST_CHECK_SMALL(iv->z, 1e-8f); 
+		else 	
+			BOOST_CHECK_CLOSE(iv->z, *igz, 0.1); 
+	}
+}
diff --git a/mia/3d/cost/test_mi.cc b/mia/3d/cost/test_mi.cc
index c7dc0ac..6d12f9d 100644
--- a/mia/3d/cost/test_mi.cc
+++ b/mia/3d/cost/test_mi.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,8 +28,6 @@ using namespace std;
 using namespace ::boost::unit_test;
 using namespace mia_3dcost_mi;
 
-CSplineKernelTestPath spline_kernel_init_path; 
-
 class MIFixture {
 protected: 
 	MIFixture(); 
diff --git a/mia/3d/cost/test_ncc.cc b/mia/3d/cost/test_ncc.cc
new file mode 100644
index 0000000..975db10
--- /dev/null
+++ b/mia/3d/cost/test_ncc.cc
@@ -0,0 +1,105 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+#include <mia/3d/cost/ncc.hh>
+#include <mia/core/nccsum.hh>
+
+using namespace NS; 
+using namespace mia; 
+
+
+
+
+BOOST_AUTO_TEST_CASE( test_ncc_zero ) 
+{
+        C3DBounds size(4,4,4); 
+        auto ncc = BOOST_TEST_create_from_plugin<CNCC3DImageCostPlugin>("ncc");
+        
+        C3DFImage a(size); 
+        C3DFImage b(size); 
+        
+        auto ia = a.begin_range(C3DBounds::_0, size); 
+        auto ib = b.begin_range(C3DBounds::_0, size); 
+        auto ea = a.end_range(C3DBounds::_0, size); 
+
+        while (ia != ea) {
+                *ia = ia.pos().x + ia.pos().y + ia.pos().z; 
+                *ib = 2* *ia; 
+                ++ib; ++ia; 
+        }
+
+        ncc->set_reference(b); 
+        BOOST_CHECK_SMALL(ncc->value(b), 1e-7); 
+
+        BOOST_CHECK_SMALL(ncc->value(a), 1e-7); 
+        
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_ncc_nonzero ) 
+{
+        C3DBounds size(4,4,4); 
+        auto ncc = BOOST_TEST_create_from_plugin<CNCC3DImageCostPlugin>("ncc");
+        
+        C3DFImage a(size); 
+        C3DFImage b(size); 
+
+       
+        auto ia = a.begin_range(C3DBounds::_0, size); 
+        auto ib = b.begin_range(C3DBounds::_0, size); 
+        auto ea = a.end_range(C3DBounds::_0, size); 
+
+        NCCSums sum; 
+
+        while (ia != ea) {
+                *ia = ia.pos().x + ia.pos().y + ia.pos().z; 
+                *ib = ia.pos().x + ia.pos().y * ia.pos().z; 
+                sum.add(*ia, *ib); 
+                ++ib; ++ia; 
+        }
+
+        ncc->set_reference(b); 
+        BOOST_CHECK_CLOSE(ncc->value(a), sum.value(), 0.1); 
+        
+        C3DFVectorfield grad(size); 
+
+        BOOST_CHECK_CLOSE(ncc->evaluate_force(a, grad), sum.value(), 0.01);
+
+
+	auto ag = get_gradient(a); 
+	
+	auto iag = ag.begin(); 
+	auto ia2 = a.begin(); 
+	auto ib2 = b.begin(); 
+	auto iforce = grad.begin(); 
+	auto eforce = grad.end(); 
+
+	auto gs = sum.get_grad_helper().second; 
+	while (iforce != eforce) {
+		auto expect = *iag * gs.get_gradient_scale(*ia2, *ib2); 
+		BOOST_CHECK_CLOSE(iforce->x, expect.x, 0.01); 
+		BOOST_CHECK_CLOSE(iforce->y, expect.y, 0.01); 
+		BOOST_CHECK_CLOSE(iforce->z, expect.z, 0.01); 
+		++iag; ++ia2; ++ib2; ++iforce;
+	}
+}
+
+
diff --git a/mia/3d/cost/test_ngf.cc b/mia/3d/cost/test_ngf.cc
index a6543f7..d8cd3a7 100644
--- a/mia/3d/cost/test_ngf.cc
+++ b/mia/3d/cost/test_ngf.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -45,12 +45,13 @@ BOOST_FIXTURE_TEST_CASE( test_ngf_evaluator_dot, C3DFVectorfieldFixture )
 	BOOST_CHECK_CLOSE( scalar.cost(field(0,0,0), field(1,1,1)), - 26.0f*26.0f, 0.01f); 
 	
 	double cost = 0.0; 
-	auto grad = scalar.grad(3, 9, field.begin_range(C3DBounds(1,1,1), C3DBounds(3,3,3)), field(0,0,0), cost); 
+	FEvaluator::field_range_iterator ifield = field.begin_range(C3DBounds(1,1,1), C3DBounds(3,3,3)).with_boundary_flag(); 
+	auto grad = scalar.grad(3, 9, ifield,  field(0,0,0), cost); 
 
 	BOOST_CHECK_CLOSE( cost, - 26.0f* 26.0f, 0.01f); 
 	BOOST_CHECK_CLOSE( grad.x, 13.0f * 19.0f, 0.01f); 
 	BOOST_CHECK_CLOSE( grad.y, -13.0f * 15.0f, 0.01f); 
-	BOOST_CHECK_CLOSE( grad.z, -13.0f * 31.0f, 0.01f); 
+	BOOST_CHECK_CLOSE( grad.z, -13.0f * 31.0f, 0.01f);
 	
 }
 
@@ -64,7 +65,8 @@ BOOST_FIXTURE_TEST_CASE( test_ngf_evaluator_cross, C3DFVectorfieldFixture )
 	BOOST_CHECK_CLOSE( costfunct.cost(field(0,0,0), field(1,1,1)),10.0f, 0.01f); 
 	
 	double cost = 0.0; 
-	auto grad = costfunct.grad(3, 9, field.begin_range(C3DBounds(1,1,1), C3DBounds(3,3,3)), field(0,0,0), cost); 
+	FEvaluator::field_range_iterator ifield = field.begin_range(C3DBounds(1,1,1), C3DBounds(3,3,3)).with_boundary_flag(); 
+	auto grad = costfunct.grad(3, 9, ifield, field(0,0,0), cost); 
 
 	BOOST_CHECK_CLOSE( cost, 10.0f, 0.01f); 
 	BOOST_CHECK_CLOSE( grad.x, 9.0f, 0.01f); 
@@ -83,7 +85,7 @@ BOOST_FIXTURE_TEST_CASE( test_ngf_evaluator_delta_scalar, C3DFVectorfieldFixture
 	BOOST_CHECK_CLOSE( costfunct.cost(field(1,1,1),field(0,0,0)), 2*5.3330572096f, 0.01f); 
 	
 	double cost = 0.0; 
-	auto ifield = field.begin_range(C3DBounds(1,1,1), C3DBounds(3,3,3)); 
+	FEvaluator::field_range_iterator ifield = field.begin_range(C3DBounds(1,1,1), C3DBounds(3,3,3)).with_boundary_flag(); 
 	cvdebug() << "ifield:boundary=" << ifield.get_boundary_flags() << "\n"; 
 	auto grad = costfunct.grad(3, 9, ifield, field(0,0,0), cost); 
 
@@ -147,17 +149,17 @@ public:
 		return 1.0; 
 	}
 	
-	C3DFVector grad(int /*nx*/, int /*nxy*/, C3DFVectorfield::const_range_iterator irsrc,
+	C3DFVector grad(int /*nx*/, int /*nxy*/, field_range_iterator& irsrc,
 			const C3DFVector& /*ref*/, double& cost) const {
 		cost += 1; 
 		C3DFVector result; 
-		if (! (irsrc.get_boundary_flags() & C3DFVectorfield::const_range_iterator::eb_x))
+		if (! (irsrc.get_boundary_flags() & field_range_iterator::eb_x))
 			result.x = 1;
 		
-		if (! (irsrc.get_boundary_flags() & C3DFVectorfield::const_range_iterator::eb_y))
+		if (! (irsrc.get_boundary_flags() & field_range_iterator::eb_y))
 			result.y = 2;
 		
-		if (! (irsrc.get_boundary_flags() & C3DFVectorfield::const_range_iterator::eb_z))
+		if (! (irsrc.get_boundary_flags() & field_range_iterator::eb_z))
 			result.z = 3; 
 		
 		return result; 
diff --git a/mia/3d/cost/test_ssd-automask.cc b/mia/3d/cost/test_ssd-automask.cc
new file mode 100644
index 0000000..656b603
--- /dev/null
+++ b/mia/3d/cost/test_ssd-automask.cc
@@ -0,0 +1,70 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <mia/3d/cost/ssd-automask.hh>
+
+
+using namespace std;
+using namespace boost;
+namespace bfs=::boost::filesystem;
+using namespace mia;
+using namespace NS;
+
+BOOST_AUTO_TEST_CASE( test_SSD_3D_norm )
+{
+	float src_data[27] = { 1, 2, 3,  2, 3, 4,  1, 4, 2,
+			       3, 4, 6,  8, 7, 4,  2, 3, 1,
+			       4, 5, 7,  3, 1, 3,  6, 7, 8 };
+
+	float ref_data[27] = { 5, 6, 7,  2, 1, 2,  2, 3, 2,
+			       6, 7, 8,  0, 9, 9,  7, 6, 5,
+			       1, 2, 3,  4, 6, 8,  3, 2, 3 };
+
+	// delta             { -, 4, 4, 0, 2, 2,  -, 1, 0,
+	//		       3, 3, 2, -, 2, 5,  5, 3, -,
+	//		       3, 3, 4, 1, -, 5,  3, 5, 5 };
+
+	// unmasked           { 0 1  1   1  1  1   0  1  1
+        //                      1 1  1   0  1  1   1  1  0
+//                              1 1  1   1  0  1   1  1  1         
+	
+	// 16  * 4 + 4 * 4 + 6 * 9 + 6 * 25 + 2 * 1
+
+ 
+  	C3DFImage *fsrc = new C3DFImage(C3DBounds(3,3,3), src_data );
+	C3DFImage *fref = new C3DFImage(C3DBounds(3,3,3), ref_data );
+	std::shared_ptr<C3DImage > src(fsrc);
+	std::shared_ptr<C3DImage > ref(fref);
+
+	C3DSSDAutomaskCost cost(2, 1);
+	cost.set_reference(*ref); 
+	BOOST_CHECK_CLOSE(cost.value(*src),  0.5 * 245.0 / 22.0, 0.1);
+
+	C3DFVectorfield force(C3DBounds(3,3,3));
+
+	BOOST_CHECK_CLOSE(cost.evaluate_force(*src, force),  0.5 * 245.0 / 22.0, 0.1);
+
+	auto f = force(1,1,1); 
+	BOOST_CHECK_CLOSE(f.x,  4/ 22.0, 0.01); 
+	BOOST_CHECK_CLOSE(f.y,  1/ 22.0, 0.01); 
+	BOOST_CHECK_CLOSE(f.z,  2/ 22.0, 0.01); 
+}
+
diff --git a/mia/3d/cost/test_ssd.cc b/mia/3d/cost/test_ssd.cc
index 0c81d65..c44943a 100644
--- a/mia/3d/cost/test_ssd.cc
+++ b/mia/3d/cost/test_ssd.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -43,7 +43,7 @@ BOOST_AUTO_TEST_CASE( test_SSD_3D_norm )
 	std::shared_ptr<C3DImage > src(fsrc);
 	std::shared_ptr<C3DImage > ref(fref);
 
-	C3DSSDCost cost(true);
+	C3DSSDCost cost(true, 0.0f);
 	cost.set_reference(*ref); 
 	BOOST_CHECK_CLOSE(cost.value(*src),  0.5 * 367.0 / 27.0, 0.1);
 
@@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE( test_SSD_3D )
 	std::shared_ptr<C3DImage > src(fsrc);
 	std::shared_ptr<C3DImage > ref(fref);
 
-	C3DSSDCost cost(false);
+	C3DSSDCost cost(false, 0.0f);
 	cost.set_reference(*ref); 
 	BOOST_CHECK_CLOSE(cost.value(*src),  0.5 * 367.0, 0.1);
 
diff --git a/mia/3d/cost/test_ssdautomask.cc b/mia/3d/cost/test_ssdautomask.cc
new file mode 100644
index 0000000..5b324be
--- /dev/null
+++ b/mia/3d/cost/test_ssdautomask.cc
@@ -0,0 +1,63 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <mia/3d/cost/ssd.hh>
+
+
+using namespace std;
+using namespace boost;
+namespace bfs=::boost::filesystem;
+using namespace mia;
+using namespace NS;
+
+BOOST_AUTO_TEST_CASE( test_SSD_3D_norm )
+{
+	float src_data[27] = { 1, 2, 3,  2, 3, 4,  1, 4, 2,
+			       3, 4, 6,  8, 7, 4,  2, 3, 1,
+			       4, 5, 7,  3, 1, 3,  6, 7, 8 };
+
+	float ref_data[27] = { 5, 6, 7,  2, 1, 2,  2, 3, 2,
+			       6, 7, 8,  0, 9, 9,  7, 6, 5,
+			       1, 2, 3,  4, 6, 8,  3, 2, 3 };
+
+	// delta             { 0, 4, 4, 0., 2, 2,  0, 1, 0.,
+	//		       3, 3, 2,  2, 0, 5,  5, 3, 4,
+	//		       3, 3, 4,  1, 5, 5,  3, 5, 5 };
+	
+	// 16  * 4 + 4 * 4 + 6 * 9 + 6 * 25 + 2 * 1
+
+ 
+	C3DFImage *fsrc = new C3DFImage(C3DBounds(3,3,3), src_data );
+	C3DFImage *fref = new C3DFImage(C3DBounds(3,3,3), ref_data );
+	std::shared_ptr<C3DImage > src(fsrc);
+	std::shared_ptr<C3DImage > ref(fref);
+
+	C3DSSDCost cost(2, 1);
+	cost.set_reference(*ref); 
+	BOOST_CHECK_CLOSE(cost.value(*src),  0.5 * 286.0 / 23.0, 0.1);
+
+	C3DFVectorfield force(C3DBounds(3,3,3));
+
+	cost.evaluate_force(*src, force);
+
+	BOOST_CHECK_EQUAL(force(1,1,1), C3DFVector(-12/ 23.0, -4/ 23.0, -8/ 23.0) );
+}
+
diff --git a/mia/3d/creator.cc b/mia/3d/creator.cc
index 77b013f..4c11d18 100644
--- a/mia/3d/creator.cc
+++ b/mia/3d/creator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/creator.hh b/mia/3d/creator.hh
index 6dcfafc..654f111 100644
--- a/mia/3d/creator.hh
+++ b/mia/3d/creator.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/creator/CMakeLists.txt b/mia/3d/creator/CMakeLists.txt
index 650d522..3bb4c6f 100644
--- a/mia/3d/creator/CMakeLists.txt
+++ b/mia/3d/creator/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/creator/lattic.cc b/mia/3d/creator/lattic.cc
index d38e3f5..19a6301 100644
--- a/mia/3d/creator/lattic.cc
+++ b/mia/3d/creator/lattic.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/creator/lattic.hh b/mia/3d/creator/lattic.hh
index a4622ba..adf7104 100644
--- a/mia/3d/creator/lattic.hh
+++ b/mia/3d/creator/lattic.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/creator/sphere.cc b/mia/3d/creator/sphere.cc
index 9a3fe74..3d4f486 100644
--- a/mia/3d/creator/sphere.cc
+++ b/mia/3d/creator/sphere.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/creator/sphere.hh b/mia/3d/creator/sphere.hh
index 81641cb..85fb6e9 100644
--- a/mia/3d/creator/sphere.hh
+++ b/mia/3d/creator/sphere.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/creator/test_lattic.cc b/mia/3d/creator/test_lattic.cc
index d4f55f9..2240bf1 100644
--- a/mia/3d/creator/test_lattic.cc
+++ b/mia/3d/creator/test_lattic.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,8 +25,6 @@
 using namespace creator_lattic_3d;
 using namespace mia;
 
-C3DFilterPluginHandlerTestPath filter_test_path; 
-
 BOOST_AUTO_TEST_CASE ( test_sphere ) 
 {
 	C3DBounds size(10,20,30); 
diff --git a/mia/3d/creator/test_sphere.cc b/mia/3d/creator/test_sphere.cc
index 9f917a1..6f9dac2 100644
--- a/mia/3d/creator/test_sphere.cc
+++ b/mia/3d/creator/test_sphere.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/critical_point.cc b/mia/3d/critical_point.cc
index 73c295f..f63877d 100644
--- a/mia/3d/critical_point.cc
+++ b/mia/3d/critical_point.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -138,9 +138,9 @@ bool C3DCriticalPointEigen::estimate()
 			cerr << "ERROR: 3 distinct eigenvalues but rank not 3!" << endl; 
 			return false; 
 		}
-		if (portrait.get_eigenvector(eval1,evec1)) cerr << "shouldn't happen 3.3.1" << endl;
-		if (portrait.get_eigenvector(eval2,evec2)) cerr << "shouldn't happen 3.3.2" << endl;
-		if (portrait.get_eigenvector(eval3,evec3)) cerr << "shouldn't happen 3.3.3" << endl;
+		evec1 = portrait.get_eigenvector(0); 
+		evec2 = portrait.get_eigenvector(1); 
+		evec3 = portrait.get_eigenvector(2); 
 		type = ev_real; 
 		return true; 
 		
@@ -150,30 +150,21 @@ bool C3DCriticalPointEigen::estimate()
 				cerr << "ERROR: 3 distinct eigenvalues but rank not 3!" << endl; 
 				return false; 
 			}
-			if (portrait.get_eigenvector(eval1,evec1)) cerr << "shouldn't happen 1.3.1" << endl;
-			// now for the complex eigenvectors
-			C3DFMatrix B =  (portrait * portrait) - (portrait * (2 * eval2)) ; 
-			B.get_eigenvector(- eval3 * eval3 - eval2 * eval2, evec3); 
-			C3DFMatrix C = portrait - C3DFMatrix::diagonal(eval2);
-			evec2 = (C * evec3) / eval3;
+			evec1 = portrait.get_eigenvector(0); 
+			evec2 = portrait.get_eigenvector(1); 
+			evec2 = portrait.get_eigenvector(2); 
+			
 			type = ev_complex; 
 			return true; 
 		}
 	case 2:// three ev's but at least two are equal
-		if (eval1 != eval2) {
-			if ( portrait.get_eigenvector(eval1,evec1)) cerr << "shouldn't happen 2.1" << endl;
-			if ( portrait.get_eigenvector(eval2,evec2)) cerr << "shouldn't happen 2.2" << endl;
-			evec3 = evec1 ^ evec2;
-			type = ev_real_two_equal;
-			return true;
-		}else{
-			evec1 = C3DFVector(1,0,0);
-			evec2 = C3DFVector(0,1,0);
-			evec3 = C3DFVector(0,0,1);			
-		}
-		break; 
+		evec1 = portrait.get_eigenvector(0); 
+		evec2 = portrait.get_eigenvector(1); 
+		evec3 = portrait.get_eigenvector(2); 
+		type = ev_real_two_equal;
+		return true;
 	default: 
-		if ( portrait.get_eigenvector(eval1,evec1)) cerr << "hit default in C3DCriticalPointEigen::estimate()"<< endl;
+		evec1 = portrait.get_eigenvector(0); 
 		return false;
 		
 	}
diff --git a/mia/3d/critical_point.hh b/mia/3d/critical_point.hh
index 53d3d0a..6c92651 100644
--- a/mia/3d/critical_point.hh
+++ b/mia/3d/critical_point.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/datafield.cc b/mia/3d/datafield.cc
index 0c75d1d..03f74f5 100644
--- a/mia/3d/datafield.cc
+++ b/mia/3d/datafield.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -71,9 +71,11 @@ T3DDatafield<bool>::get_trilin_interpol_val_at(const T3DVector<float >& p) const
 }
 
 #define INSTANCIATE(TYPE) \
-	template class  EXPORT_3D T3DDatafield<TYPE>;			\
+	template class  T3DDatafield<TYPE>;			\
 	template class  EXPORT_3D range3d_iterator<T3DDatafield<TYPE>::iterator>; \
 	template class  EXPORT_3D range3d_iterator<T3DDatafield<TYPE>::const_iterator>; \
+	template class  EXPORT_3D range3d_iterator_with_boundary_flag<T3DDatafield<TYPE>::iterator>; \
+	template class  EXPORT_3D range3d_iterator_with_boundary_flag<T3DDatafield<TYPE>::const_iterator>; \
 	template class  EXPORT_3D range2d_iterator<T3DDatafield<TYPE>::iterator>; \
 	template class  EXPORT_3D range2d_iterator<T3DDatafield<TYPE>::const_iterator>;
 
diff --git a/mia/3d/datafield.cxx b/mia/3d/datafield.cxx
index d01273d..7b6469d 100644
--- a/mia/3d/datafield.cxx
+++ b/mia/3d/datafield.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -66,6 +66,14 @@ T3DDatafield<T>::T3DDatafield(const C3DBounds& size, const T *data):
 {
 	std::copy(data, data + m_data->size(), m_data->begin()); 
 }
+
+template <typename T>
+T3DDatafield<T>::T3DDatafield(const C3DBounds& size, const data_array& data):
+	m_size(size), 
+	m_xy(size.x * size.y), 
+	m_data(new data_array(data))
+{
+}
 	
 template <typename T>
 T3DDatafield<T>::~T3DDatafield()
diff --git a/mia/3d/datafield.hh b/mia/3d/datafield.hh
index 234c092..d8aff60 100644
--- a/mia/3d/datafield.hh
+++ b/mia/3d/datafield.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,7 +44,9 @@ NS_MIA_BEGIN
 template <class T>
 class  EXPORT_3D T3DDatafield {
 
-        typedef std::shared_ptr<std::vector<T>  >  ref_data_type;
+	typedef  ::std::vector<T> data_array;
+
+        typedef std::shared_ptr<data_array>  ref_data_type;
 
         /** Size of the field */
         C3DBounds  m_size;
@@ -90,6 +92,10 @@ public:
 	typedef typename atomic_data<T>::type atomic_type; 
 	typedef range3d_iterator<iterator> range_iterator; 
 	typedef range3d_iterator<const_iterator> const_range_iterator; 
+
+	typedef range3d_iterator_with_boundary_flag<iterator> range_iterator_with_boundary_flag; 
+	typedef range3d_iterator_with_boundary_flag<const_iterator> const_range_iterator_with_boundary_flag; 
+
 	typedef C3DBounds dimsize_type;
 	/// \endcond 
 
@@ -105,6 +111,13 @@ public:
         T3DDatafield(const C3DBounds& size, const T *data);
 
 
+        /** Constructor to create Datafield if given size and with initialization data
+            \param size the size of the 3D-field
+            \param data to use for initialization
+         */
+        T3DDatafield(const C3DBounds& size, const data_array& data);
+
+
         /** copy - Constructor */
         T3DDatafield(const T3DDatafield<T>& org);
 
diff --git a/mia/3d/defines3d.hh b/mia/3d/defines3d.hh
index 8b651b4..3b7bfa2 100644
--- a/mia/3d/defines3d.hh
+++ b/mia/3d/defines3d.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -63,4 +63,5 @@
 #  define VSTREAM "MIA3DTEST"
 #endif
 
+
 #endif
diff --git a/mia/3d/deformer.hh b/mia/3d/deformer.hh
index ec98853..2202576 100644
--- a/mia/3d/deformer.hh
+++ b/mia/3d/deformer.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/distance.cc b/mia/3d/distance.cc
index 1358833..26e04d9 100644
--- a/mia/3d/distance.cc
+++ b/mia/3d/distance.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/distance.hh b/mia/3d/distance.hh
index 534a3d7..816ac26 100644
--- a/mia/3d/distance.hh
+++ b/mia/3d/distance.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/CMakeLists.txt b/mia/3d/fifof/CMakeLists.txt
index 31292fa..cfbc601 100644
--- a/mia/3d/fifof/CMakeLists.txt
+++ b/mia/3d/fifof/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/byslice.cc b/mia/3d/fifof/byslice.cc
index 5c8121e..cf824f3 100644
--- a/mia/3d/fifof/byslice.cc
+++ b/mia/3d/fifof/byslice.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/byslice.hh b/mia/3d/fifof/byslice.hh
index 4a0d00a..f4050d4 100644
--- a/mia/3d/fifof/byslice.hh
+++ b/mia/3d/fifof/byslice.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/gauss.cc b/mia/3d/fifof/gauss.cc
index fb46d7a..3de86ed 100644
--- a/mia/3d/fifof/gauss.cc
+++ b/mia/3d/fifof/gauss.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/gauss.hh b/mia/3d/fifof/gauss.hh
index 8687916..4acc6d9 100644
--- a/mia/3d/fifof/gauss.hh
+++ b/mia/3d/fifof/gauss.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/label.cc b/mia/3d/fifof/label.cc
index 01bb233..99ab4d2 100644
--- a/mia/3d/fifof/label.cc
+++ b/mia/3d/fifof/label.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -269,7 +269,7 @@ C2DLabelFifoFilterPlugin::C2DLabelFifoFilterPlugin():
 {
 	add_parameter("n", make_param(m_neighbourhood, "4n", false, 
 				      "2D neighbourhood shape to define connectedness"));
-	add_parameter("map", new CStringParameter(m_mapfile, true, 
+	add_parameter("map", new CStringParameter(m_mapfile, CCmdOptionFlags::required_input, 
 						  "Mapfile to save label numbers that are joined"));
 }
 
diff --git a/mia/3d/fifof/label.hh b/mia/3d/fifof/label.hh
index f2fceef..1b7c6ce 100644
--- a/mia/3d/fifof/label.hh
+++ b/mia/3d/fifof/label.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/median.cc b/mia/3d/fifof/median.cc
index 343aca4..1c368a5 100644
--- a/mia/3d/fifof/median.cc
+++ b/mia/3d/fifof/median.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/median.hh b/mia/3d/fifof/median.hh
index dd183f6..3dbe799 100644
--- a/mia/3d/fifof/median.hh
+++ b/mia/3d/fifof/median.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/mlv.cc b/mia/3d/fifof/mlv.cc
index 65e5b4e..f197faf 100644
--- a/mia/3d/fifof/mlv.cc
+++ b/mia/3d/fifof/mlv.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/mlv.hh b/mia/3d/fifof/mlv.hh
index 8873605..363046e 100644
--- a/mia/3d/fifof/mlv.hh
+++ b/mia/3d/fifof/mlv.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/morphological.cc b/mia/3d/fifof/morphological.cc
index 95257c2..beb129c 100644
--- a/mia/3d/fifof/morphological.cc
+++ b/mia/3d/fifof/morphological.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/morphological.hh b/mia/3d/fifof/morphological.hh
index 5adf23b..13183f1 100644
--- a/mia/3d/fifof/morphological.hh
+++ b/mia/3d/fifof/morphological.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/regiongrow.cc b/mia/3d/fifof/regiongrow.cc
index c51c7a5..6eaef61 100644
--- a/mia/3d/fifof/regiongrow.cc
+++ b/mia/3d/fifof/regiongrow.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -188,7 +188,7 @@ C2DRegiongrowFifoFilterPlugin::C2DRegiongrowFifoFilterPlugin():
 	m_class(2),
 	m_depth(10)
 {
-	add_parameter("map", new CStringParameter(m_map, true, "seed class map"));
+	add_parameter("map", new CStringParameter(m_map, CCmdOptionFlags::required_input, "seed class map"));
 	add_parameter("low", new CFloatParameter(m_low, .0f, 1.0f, false,
 						 "low threshold for acceptance probability"));
 	add_parameter("seed", new CFloatParameter(m_seed, .0f, 1.0f, false,
diff --git a/mia/3d/fifof/regiongrow.hh b/mia/3d/fifof/regiongrow.hh
index 958ea3c..cab1d82 100644
--- a/mia/3d/fifof/regiongrow.hh
+++ b/mia/3d/fifof/regiongrow.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/rgg.cc b/mia/3d/fifof/rgg.cc
index a19218a..e258ecf 100644
--- a/mia/3d/fifof/rgg.cc
+++ b/mia/3d/fifof/rgg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -160,7 +160,7 @@ C2DRGGStackFilterFactory::C2DRGGStackFilterFactory():
 	m_depth(5), 
 	m_gradient_thresh(4.0)
 {
-	add_parameter("map", new CStringParameter(m_seed_map, true, "class probability map"));
+	add_parameter("map", new CStringParameter(m_seed_map, CCmdOptionFlags::required_input, "class probability map"));
 	add_parameter("st", new CFloatParameter(m_seed_thresh, 0.0, 1.0, 
 					      false, "seed probability threshhold"));
 	add_parameter("depth", new CIntParameter(m_depth, 1, 30, 
diff --git a/mia/3d/fifof/rgg2pass.cc b/mia/3d/fifof/rgg2pass.cc
index 0168cfa..bd492f7 100644
--- a/mia/3d/fifof/rgg2pass.cc
+++ b/mia/3d/fifof/rgg2pass.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/test_byslice.cc b/mia/3d/fifof/test_byslice.cc
index 67b41a5..b5e41b6 100644
--- a/mia/3d/fifof/test_byslice.cc
+++ b/mia/3d/fifof/test_byslice.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,27 +28,8 @@ NS_MIA_USE;
 namespace bfs=::boost::filesystem;
 
 
-void init_path() 
-{
-	static bool run = false; 
-	if (run) 
-		return; 
-	
-	CPathNameArray kernelsearchpath;
-	kernelsearchpath.push_back(bfs::path("..")/bfs::path("..")/
-				   bfs::path("core")/bfs::path("spacialkernel"));
-	C1DSpacialKernelPluginHandler::set_search_path(kernelsearchpath);
-	
-	CPathNameArray filter2dpath;
-	filter2dpath.push_back(bfs::path("../../2d/filter"));
-	C2DFilterPluginHandler::set_search_path(filter2dpath);
-	run = true; 
-}
-
 BOOST_FIXTURE_TEST_CASE( test_fifof_byslice_median , fifof_Fixture )
 {
-	init_path(); 
-
 	const size_t n_slices = 3;
 	const C2DBounds size(3,3);
 
diff --git a/mia/3d/fifof/test_gauss.cc b/mia/3d/fifof/test_gauss.cc
index 4370637..17062c1 100644
--- a/mia/3d/fifof/test_gauss.cc
+++ b/mia/3d/fifof/test_gauss.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,23 +27,8 @@ NS_MIA_USE;
 
 namespace bfs=::boost::filesystem;
 
-struct GaussFixture: public fifof_Fixture {
-	GaussFixture() {
-		CPathNameArray kernelsearchpath;
-		kernelsearchpath.push_back(bfs::path("..")/bfs::path("..")/
-					   bfs::path("core")/bfs::path("spacialkernel"));
-		C1DSpacialKernelPluginHandler::set_search_path(kernelsearchpath);
 
-		CPathNameArray selfpath;
-		selfpath.push_back(bfs::path("..")/bfs::path("..")/
-				   bfs::path("2d")/bfs::path("filter"));
-		C2DFilterPluginHandler::set_search_path(selfpath);
-
-	}
-};
-
-
-BOOST_FIXTURE_TEST_CASE( test_fifof_gauss , GaussFixture )
+BOOST_FIXTURE_TEST_CASE( test_fifof_gauss, fifof_Fixture )
 {
 	const size_t slices = 4;
 	const C2DBounds size(3,3);
diff --git a/mia/3d/fifof/test_label.cc b/mia/3d/fifof/test_label.cc
index e5a6356..19301d9 100644
--- a/mia/3d/fifof/test_label.cc
+++ b/mia/3d/fifof/test_label.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,11 +32,6 @@ namespace bfs=::boost::filesystem;
 
 BOOST_FIXTURE_TEST_CASE( test_fifof_label , fifof_Fixture )
 {
-	CPathNameArray shape2dsearchpath;
-	shape2dsearchpath.push_back(bfs::path("..")/bfs::path("..")/
-				   bfs::path("2d")/bfs::path("shapes"));
-	C2DShapePluginHandler::set_search_path(shape2dsearchpath);
-
 
 	const size_t n_slices = 6; 
 	const C2DBounds size(4,4); 
diff --git a/mia/3d/fifof/test_median.cc b/mia/3d/fifof/test_median.cc
index e5c1c05..d931519 100644
--- a/mia/3d/fifof/test_median.cc
+++ b/mia/3d/fifof/test_median.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/test_mlv.cc b/mia/3d/fifof/test_mlv.cc
index 00d6ef7..f58e13d 100644
--- a/mia/3d/fifof/test_mlv.cc
+++ b/mia/3d/fifof/test_mlv.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,7 +28,6 @@ NS_MIA_USE;
 using namespace std; 
 
 
-C3DFilterPluginHandlerTestPath filter3d_plugin_path; 
 
 BOOST_FIXTURE_TEST_CASE( test_fifof_mlv_const, fifof_Fixture )
 {
diff --git a/mia/3d/fifof/test_morphological.cc b/mia/3d/fifof/test_morphological.cc
index 2c36e2c..a220afb 100644
--- a/mia/3d/fifof/test_morphological.cc
+++ b/mia/3d/fifof/test_morphological.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifof/test_regiongrow.cc b/mia/3d/fifof/test_regiongrow.cc
index e661d32..3890e23 100644
--- a/mia/3d/fifof/test_regiongrow.cc
+++ b/mia/3d/fifof/test_regiongrow.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifotestfixture.cc b/mia/3d/fifotestfixture.cc
index e5cbd7e..280a36c 100644
--- a/mia/3d/fifotestfixture.cc
+++ b/mia/3d/fifotestfixture.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fifotestfixture.hh b/mia/3d/fifotestfixture.hh
index 11d290c..ae6ef65 100644
--- a/mia/3d/fifotestfixture.hh
+++ b/mia/3d/fifotestfixture.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter.cc b/mia/3d/filter.cc
index a3b353e..1d34f0e 100644
--- a/mia/3d/filter.cc
+++ b/mia/3d/filter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,40 +21,25 @@
 #include <mia/core/export_handler.hh>
 
 #include <mia/3d/filter.hh>
-#include <mia/core/combiner.hh>
 #include <mia/core/plugin_base.cxx>
 #include <mia/core/handler.cxx>
+#include <mia/template/combiner.cxx>
+
 
 NS_MIA_BEGIN
 
 using namespace boost;
 
-
-using boost::filesystem::path; 
-C3DFilterPluginHandlerTestPath::C3DFilterPluginHandlerTestPath()
-{
-	CPathNameArray searchpath; 
-	searchpath.push_back( path(MIA_BUILD_ROOT"/mia/3d/filter"));
-	C3DFilterPluginHandler::set_search_path(searchpath); 
-}
-
-
-C3DImageCombiner::~C3DImageCombiner()
-{
-}
-
-C3DImageCombiner::result_type C3DImageCombiner::combine( const C3DImage& a,
-							 const C3DImage& b) const
-{
-	return do_combine(a,b);
-}
-
-
 template<> const  char * const 
 TPluginHandler<C3DFilterPlugin>::m_help = 
-   "These plug-ins provide 3D image filters. Unless otherwise noted, "
-   "they take a gray scale image of abitrary pixel type as input, "
-   "process it and hand it to the next filter in the pipeline." 
+	"These plug-ins provide 3D image filters. Unless otherwise noted, "
+	"they take a gray scale image of abitrary pixel type as input, "
+	"process it and return the filtered result as a new image. "
+	"Filters can be chained by specifying more then one filter description "
+	"concated with the '+' sign. for example \n"
+	"   bandpass:min=10,max=20+median:w=3+convert:repn=ushort:map=copy'\n"
+	"will create a filter chain that first runs a bandpass, then a median "
+	"filter and a conversion to unsigned short values by a plain copy."
 ; 
 
 template<> const  char * const 
@@ -87,11 +72,9 @@ template class TPlugin<C3DImage, filter_type>;
 template class THandlerSingleton<TFactoryPluginHandler<C3DFilterPlugin> >;
 template class TFactoryPluginHandler<C3DFilterPlugin>;
 template class TPluginHandler<C3DFilterPlugin>;
-template class TPlugin<C3DImage, combiner_type>;
-template class TFactory<C3DImageCombiner>;
-template class THandlerSingleton<TFactoryPluginHandler<C3DImageCombinerPlugin> >;
-template class TFactoryPluginHandler<C3DImageCombinerPlugin>;
-template class TPluginHandler<C3DImageCombinerPlugin>;
 
 
+template class TImageCombiner<C3DImage>; 
+EXPLICIT_INSTANCE_HANDLER(C3DImageCombiner);
+
 NS_MIA_END
diff --git a/mia/3d/filter.hh b/mia/3d/filter.hh
index 0c9bcef..c20a434 100644
--- a/mia/3d/filter.hh
+++ b/mia/3d/filter.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
 #include <mia/core/filter.hh>
 #include <mia/core/spacial_kernel.hh>
 #include <mia/template/filter_chain.hh>
+#include <mia/template/combiner.hh>
 
 NS_MIA_BEGIN
 
@@ -66,41 +67,13 @@ typedef std::shared_ptr<C3DFilter> P3DFilter;
    This class is the base class for all combiners that are used to combine two 3D images.  
    The result of the combination can be anything derived from CCombinerResult. 
 */
-class EXPORT_3D C3DImageCombiner : public TFilter< PCombinerResult >, public CProductBase {
-public:
-	typedef C3DImage plugin_data; 
-	typedef combiner_type plugin_type; 
-	
-	virtual ~C3DImageCombiner();
-	/**
-	   Combine two images and and store it in a CCombinerResult return a shared pointer pointer to the result.
-	 */
-	result_type combine( const C3DImage& a, const C3DImage& b) const;
-private:
-	virtual result_type do_combine( const C3DImage& a, const C3DImage& b) const = 0;
-};
-
+typedef TImageCombiner< C3DImage > C3DImageCombiner; 
+typedef std::shared_ptr<C3DImageCombiner> P3DImageCombiner; 
 typedef TFactory<C3DImageCombiner> C3DImageCombinerPlugin;
-typedef std::shared_ptr<C3DImageCombiner > P3DImageCombiner;
-typedef THandlerSingleton<TFactoryPluginHandler<C3DImageCombinerPlugin> > C3DImageCombinerPluginHandler;
-
-
-/** 
-    @cond INTERNAL 
-    @ingroup test 
-    @brief class to initialize the plug-in path for tests on the uninstalled library 
-*/
-class EXPORT_3D C3DFilterPluginHandlerTestPath {
-public: 
-	C3DFilterPluginHandlerTestPath(); 
-private: 
-	C1DSpacialKernelPluginHandlerTestPath spk_path; 
-}; 
-/// @endcond 
-
-
-
 
+/// Plugin handler for image combiner plugins 
+typedef THandlerSingleton<TFactoryPluginHandler<C3DImageCombinerPlugin> > 
+        C3DImageCombinerPluginHandler;
 
 
 /// @cond NEVER 
diff --git a/mia/3d/filter/CMakeLists.txt b/mia/3d/filter/CMakeLists.txt
index c183b8f..277da32 100644
--- a/mia/3d/filter/CMakeLists.txt
+++ b/mia/3d/filter/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,9 +18,11 @@
 
 SET(filters3dNew 	    
   binarize 
-  bandpass 
+  bandpass
+  combiner
   convert 
   crop 
+  distance
   downscale 
   gradnorm
   growmask
@@ -28,11 +30,14 @@ SET(filters3dNew
   kmeans 
   label
   load
+  lvdownscale
   mask
+  mean 
   median 
   mlv 
   morphological 
-  reorient 
+  msnormalizer
+#  reorient 
   resize
   scale
   seededwatershed
@@ -45,7 +50,7 @@ SET(filters3dNew
   )
 
 PLUGINGROUP_WITH_TEST_AND_PREFIX2("3dimage" "filter" "${filters3dNew}" 
-  "${MIA3DLIBS}"
+  "${MIA3DLIBS}" TESTLIBS  mia3dtest
   )
 
 
diff --git a/mia/3d/filter/aniso.cc b/mia/3d/filter/aniso.cc
index 644be05..faf6715 100644
--- a/mia/3d/filter/aniso.cc
+++ b/mia/3d/filter/aniso.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/bandpass.cc b/mia/3d/filter/bandpass.cc
index 186d59d..38ca2e7 100644
--- a/mia/3d/filter/bandpass.cc
+++ b/mia/3d/filter/bandpass.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/bandpass.hh b/mia/3d/filter/bandpass.hh
index d849a47..20eb8e2 100644
--- a/mia/3d/filter/bandpass.hh
+++ b/mia/3d/filter/bandpass.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/binarize.cc b/mia/3d/filter/binarize.cc
index 8806fc8..63bb2b2 100644
--- a/mia/3d/filter/binarize.cc
+++ b/mia/3d/filter/binarize.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/binarize.hh b/mia/3d/filter/binarize.hh
index 5f7d8db..41239f8 100644
--- a/mia/3d/filter/binarize.hh
+++ b/mia/3d/filter/binarize.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/combiner.cc b/mia/3d/filter/combiner.cc
new file mode 100644
index 0000000..271315e
--- /dev/null
+++ b/mia/3d/filter/combiner.cc
@@ -0,0 +1,36 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/filter/combiner.hh>
+#include <mia/3d/imageio.hh>
+
+NS_MIA_BEGIN
+
+template class  TImageCombinerFilter<C3DImage>; 
+template class  TImageCombinerFilterPlugin<C3DImage>; 
+
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+        return new C3DImageCombinerFilterPlugin; 
+}
+
+NS_MIA_END
+
diff --git a/mia/3d/filter/combiner.hh b/mia/3d/filter/combiner.hh
new file mode 100644
index 0000000..771c2b7
--- /dev/null
+++ b/mia/3d/filter/combiner.hh
@@ -0,0 +1,38 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/filter.hh>
+#include <mia/3d/image.hh>
+#include <mia/template/combiner_filter.hh>
+
+
+#ifndef mia_3d_filter_combiner_hh
+#define mia_3d_filter_combiner_hh
+
+NS_MIA_BEGIN
+
+typedef TImageCombinerFilter<C3DImage> C3DImageCombinerFilter; 
+typedef TImageCombinerFilterPlugin<C3DImage> C3DImageCombinerFilterPlugin; 
+
+NS_MIA_END
+
+#endif 
+
+
diff --git a/mia/3d/filter/convert.cc b/mia/3d/filter/convert.cc
index 5f8aa64..079e364 100644
--- a/mia/3d/filter/convert.cc
+++ b/mia/3d/filter/convert.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/convert.hh b/mia/3d/filter/convert.hh
index cf4a59f..6a811a9 100644
--- a/mia/3d/filter/convert.hh
+++ b/mia/3d/filter/convert.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/crop.cc b/mia/3d/filter/crop.cc
index eca9ea0..9967188 100644
--- a/mia/3d/filter/crop.cc
+++ b/mia/3d/filter/crop.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/crop.hh b/mia/3d/filter/crop.hh
index 75c1e3c..69066e4 100644
--- a/mia/3d/filter/crop.hh
+++ b/mia/3d/filter/crop.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/distance.cc b/mia/3d/filter/distance.cc
new file mode 100644
index 0000000..baab730
--- /dev/null
+++ b/mia/3d/filter/distance.cc
@@ -0,0 +1,96 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <mia/3d/filter/distance.hh>
+#include <mia/core/distance.hh>
+
+namespace distance_3d_filter {
+
+using namespace mia; 
+
+using std::vector; 
+using std::string; 
+
+template <typename T> 
+P3DImage C3DDistanceFilter::operator () ( const T3DImage<T>& image) const
+{
+	C3DFImage *result = new C3DFImage(image.get_size(), image);
+	vector<float> buffer(image.get_size().x); 
+	vector<T> in_buffer(image.get_size().x); 
+	for (size_t z = 0; z < image.get_size().z; ++z) {
+		for (size_t y = 0; y < image.get_size().y; ++y) {
+			image.get_data_line_x(y, z, in_buffer);
+                        distance_transform_prepare(in_buffer.begin(), in_buffer.end(), buffer.begin()); 
+			distance_transform_inplace(buffer); 
+			result->put_data_line_x(y, z, buffer);
+		}
+	}
+	
+	buffer.resize(image.get_size().y); 
+	for (size_t z = 0; z < image.get_size().z; ++z) {
+		for (size_t x = 0; x < image.get_size().x; ++x) {
+			result->get_data_line_y(x, z, buffer);
+ 			distance_transform_inplace(buffer); 
+			result->put_data_line_y(x, z, buffer);
+		}
+	}
+
+	buffer.resize(image.get_size().z); 
+	for (size_t y = 0; y < image.get_size().y; ++y) {
+		for (size_t x = 0; x < image.get_size().x; ++x) {
+			result->get_data_line_z(x, y, buffer);
+			distance_transform_inplace(buffer); 
+			result->put_data_line_z(x, y, buffer);
+		}
+	}
+	return P3DImage(result); 
+}
+
+P3DImage C3DDistanceFilter::do_filter(const mia::C3DImage& image) const
+{
+        return mia::filter(*this, image); 
+}
+
+C3DDistanceImageFilterFactory::C3DDistanceImageFilterFactory():
+C3DFilterPlugin("distance")
+{
+}
+
+C3DFilter *C3DDistanceImageFilterFactory::do_create()const
+{
+        return new C3DDistanceFilter(); 
+}
+const string C3DDistanceImageFilterFactory::do_get_descr()const
+{
+        return "Evaluate the 3D distance transform of an image. "
+                "If the image is a binary mask, then result of the distance "
+                "transform in each point corresponds to the Euclidian distance to the "
+                "mask. If the input image is of a scalar pixel value, then the this "
+                "scalar is interpreted as heighfield and the per pixel value adds "
+                "to the distance."; 
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C3DDistanceImageFilterFactory();
+}
+
+}
diff --git a/mia/3d/filter/distance.hh b/mia/3d/filter/distance.hh
new file mode 100644
index 0000000..2a37ca2
--- /dev/null
+++ b/mia/3d/filter/distance.hh
@@ -0,0 +1,44 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/filter.hh>
+
+namespace distance_3d_filter {
+
+class C3DDistanceFilter: public mia::C3DFilter {
+public:
+	template <typename T>
+	C3DDistanceFilter::result_type operator () (const mia::T3DImage<T>& data) const;
+private:
+	virtual mia::P3DImage do_filter(const mia::C3DImage& image) const;
+};
+
+/* The factory class - this is what the application gets first. This factory class is used to
+   create the actual filter object. It also provides some filter testing routines.
+*/
+class C3DDistanceImageFilterFactory: public mia::C3DFilterPlugin {
+public:
+	C3DDistanceImageFilterFactory();
+	virtual mia::C3DFilter *do_create()const;
+	virtual const std::string do_get_descr()const;
+private:
+};
+
+}
diff --git a/mia/3d/filter/downscale.cc b/mia/3d/filter/downscale.cc
index 2a2b278..b9e9e20 100644
--- a/mia/3d/filter/downscale.cc
+++ b/mia/3d/filter/downscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -102,7 +102,7 @@ CDownscale::result_type CDownscale::do_filter(const C3DImage& image) const
 
 C3DDownscaleFilterPlugin::C3DDownscaleFilterPlugin():
 	C3DFilterPlugin("downscale"),
-	m_b(1,1,1),
+	m_b(1,1,1), 
 	m_filter("gauss")
 {
 	add_parameter("bx", new CUIntParameter(m_b.x, 1,
@@ -119,10 +119,11 @@ C3DDownscaleFilterPlugin::C3DDownscaleFilterPlugin():
 
 	add_parameter("b", new C3DBoundsParameter(m_b, false, "blocksize"));
 
-	add_parameter("kernel", new CStringParameter(m_filter, false,
-						     "smoothing filter kernel to be applied "
-						     "(filter width is determined based on the scaling factor)", 
-						     &C1DSpacialKernelPluginHandler::instance()));
+
+	add_parameter("kernel", new CStringParameter(m_filter, CCmdOptionFlags::none, 
+						     "smoothing filter kernel to be applied, the "
+						     "size of the filter is estimated based on the blocksize.", 
+						     &C1DSpacialKernelPluginHandler::instance())); 
 }
 
 C3DFilter *C3DDownscaleFilterPlugin::do_create()const
diff --git a/mia/3d/filter/downscale.hh b/mia/3d/filter/downscale.hh
index ff619ef..74eddd6 100644
--- a/mia/3d/filter/downscale.hh
+++ b/mia/3d/filter/downscale.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/gradnorm.cc b/mia/3d/filter/gradnorm.cc
index ade4785..b0acfe2 100644
--- a/mia/3d/filter/gradnorm.cc
+++ b/mia/3d/filter/gradnorm.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -40,14 +40,16 @@ CGradnorm::result_type CGradnorm::operator () (const T3DImage<T>& data) const
 	TRACE("CGradnorm::operator ()");
 
 	C3DFVectorfield vf(data.get_size()); 
-	typedef typename T3DImage<T>::range_iterator::EBoundary  EBoundary; 
+	typedef typename T3DImage<T>::const_range_iterator_with_boundary_flag range_iterator_with_boundary; 
+	typedef typename range_iterator_with_boundary::EBoundary  EBoundary; 
 	int dx = data.get_size().x; 
 	int dxy = dx * data.get_size().y; 
 
 	auto iv = vf.begin(); 
-	auto e = data.end_range(C3DBounds::_0, data.get_size()); 
+	auto e = data.end_range(C3DBounds::_0, data.get_size()).with_boundary_flag(); 
 	float maxnorm = 0.0; 
-	for (auto d = data.begin_range(C3DBounds::_0, data.get_size()); d != e; ++iv, ++d) {
+	for (auto d = data.begin_range(C3DBounds::_0, data.get_size()).with_boundary_flag(); 
+	     d != e; ++iv, ++d) {
 		auto i = d.get_point(); 
 		iv->x = d.get_boundary_flags() & EBoundary::eb_x ? 0.0 : i[1] - i[-1]; 
 		iv->y = d.get_boundary_flags() & EBoundary::eb_y ? 0.0 : i[dx] - i[-dx]; 
diff --git a/mia/3d/filter/gradnorm.hh b/mia/3d/filter/gradnorm.hh
index 3444b4b..0b439e8 100644
--- a/mia/3d/filter/gradnorm.hh
+++ b/mia/3d/filter/gradnorm.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/growmask.cc b/mia/3d/filter/growmask.cc
index 42b1eed..a1491a2 100644
--- a/mia/3d/filter/growmask.cc
+++ b/mia/3d/filter/growmask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -109,7 +109,8 @@ C3DGrowmaskImageFilterFactory::C3DGrowmaskImageFilterFactory():
 	C3DFilterPlugin("growmask"),
 	m_min(1.0)
 {
-	add_parameter("ref", new CStringParameter(m_ref_filename, true, "reference image for mask region growing", 
+	add_parameter("ref", new CStringParameter(m_ref_filename, CCmdOptionFlags::required_input, 
+						  "reference image for mask region growing", 
 			      &C3DImageIOPluginHandler::instance()));
 	add_parameter("shape", make_param(m_shape, "6n", false, "neighborhood mask"));
 	add_parameter("min", new CFloatParameter(m_min, -numeric_limits<float>::max(),
diff --git a/mia/3d/filter/growmask.hh b/mia/3d/filter/growmask.hh
index fc53837..69a446e 100644
--- a/mia/3d/filter/growmask.hh
+++ b/mia/3d/filter/growmask.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/invert.cc b/mia/3d/filter/invert.cc
index 86f4bb7..3201442 100644
--- a/mia/3d/filter/invert.cc
+++ b/mia/3d/filter/invert.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/invert.hh b/mia/3d/filter/invert.hh
index bbeff60..b09983b 100644
--- a/mia/3d/filter/invert.hh
+++ b/mia/3d/filter/invert.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/kmeans.cc b/mia/3d/filter/kmeans.cc
index a66d178..1268c8c 100644
--- a/mia/3d/filter/kmeans.cc
+++ b/mia/3d/filter/kmeans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/kmeans.hh b/mia/3d/filter/kmeans.hh
index 21c69d4..33a5b40 100644
--- a/mia/3d/filter/kmeans.hh
+++ b/mia/3d/filter/kmeans.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/label.cc b/mia/3d/filter/label.cc
index 470bb6a..b693cfc 100644
--- a/mia/3d/filter/label.cc
+++ b/mia/3d/filter/label.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/label.hh b/mia/3d/filter/label.hh
index 1f26b8f..cfe74d7 100644
--- a/mia/3d/filter/label.hh
+++ b/mia/3d/filter/label.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/load.cc b/mia/3d/filter/load.cc
index 00a7dd4..8966544 100644
--- a/mia/3d/filter/load.cc
+++ b/mia/3d/filter/load.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -39,7 +39,7 @@ mia::P3DImage C3DLoad::do_filter(const mia::C3DImage& MIA_PARAM_UNUSED(image)) c
 C3DLoadFilterPluginFactory::C3DLoadFilterPluginFactory(): 
 	C3DFilterPlugin("load")
 {
-	add_parameter("file", new CStringParameter(m_filename, true,
+	add_parameter("file", new CStringParameter(m_filename, CCmdOptionFlags::required_input,
 						   "name of the input file to load from.", 
 						   &C3DImageIOPluginHandler::instance()));
 }
diff --git a/mia/3d/filter/load.hh b/mia/3d/filter/load.hh
index fb45745..dedbabd 100644
--- a/mia/3d/filter/load.hh
+++ b/mia/3d/filter/load.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/lvdownscale.cc b/mia/3d/filter/lvdownscale.cc
new file mode 100644
index 0000000..b0b8ff0
--- /dev/null
+++ b/mia/3d/filter/lvdownscale.cc
@@ -0,0 +1,158 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/filter/lvdownscale.hh>
+
+NS_BEGIN(lvdownscale_3dimage_filter)
+
+using namespace std; 
+using namespace mia; 
+
+C3DLVDownscale::C3DLVDownscale(const C3DBounds& block_size):m_block_size(block_size) 
+{
+}
+
+
+
+inline pair<unsigned, unsigned> clamp_coord(unsigned i, unsigned di, unsigned ni) 
+{
+	unsigned first = i * di; 
+	unsigned second = first +  di; 
+	return make_pair(first, second > ni? ni: second); 
+}; 
+
+
+template <typename  T>
+C3DFilter::result_type C3DLVDownscale::operator () (const T3DImage<T>& data) const
+{
+	
+	auto get_max_represented = [] (const vector<T>& buffer) -> T {
+		T max_elm = T(); 
+		if (buffer.empty()) 
+			return max_elm; 
+		unsigned int max_num = 1; 
+		unsigned int cur_num = 1; 
+
+		max_elm = buffer[0]; 
+		
+		T cur_elm = max_elm; 
+
+		for (auto ib = buffer.begin() + 1; ib != buffer.end() ; ++ib) {
+			if (cur_elm == *ib) {
+				++cur_num; 
+			}else{
+				if (cur_num > max_num) {
+					max_num = cur_num; 
+					max_elm = cur_elm; 
+				}
+				cur_num = 1; 
+				cur_elm = *ib; 
+			}
+		}
+		if (cur_num > max_num) {
+			max_elm = cur_elm; 
+		}
+		return max_elm; 
+	}; 
+
+	C3DBounds rsize ( data.get_size() / m_block_size); 
+	if (rsize.x < 1) rsize.x = 1; 
+	if (rsize.y < 1) rsize.y = 1; 
+	if (rsize.z < 1) rsize.z = 1; 
+
+	T3DImage<T> *result = new T3DImage<T>(rsize, data); 
+
+
+	vector<T> buffer; 
+	const size_t buffer_size = m_block_size.product(); 
+
+	auto ir = result->begin(); 
+	for (unsigned z = 0; z < rsize.z; ++z) {
+		auto rangez = clamp_coord(z, m_block_size.z, data.get_size().z); 
+		for (unsigned y = 0; y < rsize.y; ++y) {
+			auto rangey = clamp_coord(y, m_block_size.y, data.get_size().y); 
+			for (unsigned x = 0; x < rsize.x; ++x, ++ir) {
+				auto rangex = clamp_coord(x, m_block_size.x, data.get_size().x);
+				C3DBounds ibegin(rangex.first, rangey.first, rangez.first); 
+				C3DBounds iend(rangex.second, rangey.second, rangez.second);
+								
+				buffer.clear(); 
+				buffer.reserve(buffer_size); 
+				for_each(data.begin_range(ibegin, iend), data.end_range(ibegin, iend), 
+					 [&buffer](T pixel) {
+						 if (pixel)
+							 buffer.push_back(pixel); 
+					 }); 
+				sort(buffer.begin(), buffer.end()); 
+				*ir = get_max_represented(buffer); 
+				
+			}
+		}
+	}
+	
+	C3DFVector pixel_size = data.get_voxel_size();
+	pixel_size.x *= m_block_size.x;
+	pixel_size.y *= m_block_size.y;
+	pixel_size.z *= m_block_size.z;
+	result->set_voxel_size(pixel_size);
+	
+	return P3DImage(result); 
+}
+
+
+C3DFilter::result_type C3DLVDownscale::do_filter(const C3DImage& image) const
+{
+	return mia::filter(*this, image); 
+}
+
+
+
+C3DLVDownscaleFilterPlugin::C3DLVDownscaleFilterPlugin():
+	C3DFilterPlugin("lvdownscale"),
+	m_b(1,1,1)
+{
+	add_parameter("b", new C3DBoundsParameter(m_b, false, "blocksize for the downscaling. Each block will be represented "
+						  "by one pixel in the target image."));
+
+}
+
+
+C3DFilter *C3DLVDownscaleFilterPlugin::do_create()const
+{
+	return new C3DLVDownscale(m_b); 
+}
+
+const string C3DLVDownscaleFilterPlugin::do_get_descr()const
+{
+	return "This is a label voting downscale filter. It adownscales a 3D image by blocks. "
+		"For each block the (non-zero) label that appears most times in the block is "
+		"issued as output pixel in the target image. If two labels appear the same number "
+		"of times, the one with the lower absolute value wins."; 
+}
+
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C3DLVDownscaleFilterPlugin();
+}
+
+
+NS_END
+
diff --git a/mia/3d/filter/lvdownscale.hh b/mia/3d/filter/lvdownscale.hh
new file mode 100644
index 0000000..c8cc2c6
--- /dev/null
+++ b/mia/3d/filter/lvdownscale.hh
@@ -0,0 +1,54 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_filter_lvdownscale_hh
+#define mia_3d_filter_lvdownscale_hh
+
+#include <mia/3d/filter.hh>
+
+NS_BEGIN(lvdownscale_3dimage_filter)
+
+class C3DLVDownscale: public mia::C3DFilter {
+public:
+	C3DLVDownscale(const mia::C3DBounds& block_size);
+
+	template <typename  T>
+	mia::C3DFilter::result_type operator () (const mia::T3DImage<T>& data) const;
+
+private:
+	mia::C3DFilter::result_type do_filter(const mia::C3DImage& image) const;
+
+	const mia::C3DBounds m_block_size;
+
+
+};
+
+class C3DLVDownscaleFilterPlugin: public mia::C3DFilterPlugin {
+public:
+	C3DLVDownscaleFilterPlugin();
+	virtual mia::C3DFilter *do_create()const;
+	virtual const std::string do_get_descr()const;
+private:
+	mia::C3DBounds m_b;
+};
+
+NS_END
+
+#endif
diff --git a/mia/3d/filter/mask.cc b/mia/3d/filter/mask.cc
index 3cca00c..7008235 100644
--- a/mia/3d/filter/mask.cc
+++ b/mia/3d/filter/mask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -112,7 +112,7 @@ mia::P3DImage C3DMask::do_filter(const mia::C3DImage& image) const
 C3DMaskImageFilterFactory::C3DMaskImageFilterFactory():
 	C3DFilterPlugin("mask")
 {
-	add_parameter("input", new CStringParameter(m_mask_filename, true, "second input image file name", 
+	add_parameter("input", new CStringParameter(m_mask_filename, CCmdOptionFlags::required_input, "second input image file name", 
 			      &C3DImageIOPluginHandler::instance()));
 }
 
diff --git a/mia/3d/filter/mask.hh b/mia/3d/filter/mask.hh
index 43c5621..1bb8855 100644
--- a/mia/3d/filter/mask.hh
+++ b/mia/3d/filter/mask.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/mean.cc b/mia/3d/filter/mean.cc
new file mode 100644
index 0000000..9689f2a
--- /dev/null
+++ b/mia/3d/filter/mean.cc
@@ -0,0 +1,256 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <limits>
+#include <mia/3d/filter/mean.hh>
+#include <mia/core/utils.hh>
+#include <mia/core/threadedmsg.hh>
+
+
+#include <tbb/parallel_for.h>
+#include <tbb/blocked_range.h>
+
+
+NS_BEGIN(mean_3dimage_filter)
+using namespace mia; 
+using std::unique_ptr; 
+using std::pair;
+using std::make_pair; 
+
+C3DMeanFilter::C3DMeanFilter(int hwidth):
+      m_hwidth(hwidth)
+{
+}
+
+inline pair<C3DBounds, C3DBounds> prepare_range(const C3DBounds& size, int cx, int cy, int cz, int hw) 
+{
+	int zb = cz - hw;
+	if (zb < 0) zb = 0; 
+	unsigned ze = cz + hw + 1; 
+	if (ze > size.z) ze = size.z; 
+	
+	int yb = cy - hw;
+	if (yb < 0) yb = 0; 
+	unsigned ye = cy + hw + 1; 
+	if (ye > size.y) ye = size.y; 
+	
+	int xb = cx - hw;
+	if (xb < 0) xb = 0; 
+	unsigned xe = cx + hw + 1; 
+	if (xe > size.x) xe = size.x; 
+	
+	return make_pair(C3DBounds(xb,yb,zb), C3DBounds(xe,ye,ze)); 
+}
+
+
+template <typename T, bool value> 
+struct __dispatch_filter {
+	static T apply(const T3DImage<T>& data, int cx, int cy, int cz, int hw, int freedom) {
+		double result = 0.0; 
+		int n = freedom;
+		// 
+		// Coverty complains about this: 1128688, 1128687 
+		// 
+		// hw >= 1, cy >= 0 && cy < data.get_size().y
+		// therefore n>=8
+		// 
+		auto range = prepare_range(data.get_size(), cx, cy, cz, hw); 
+		auto rb = data.begin_range(range.first,range.second); 
+		auto re = data.end_range(range.first,range.second); 
+		
+		while (rb != re) {
+			result += *rb; 
+			++rb;
+			++n; 
+		}
+		return mia_round_clamped<T>(rint(result/n)); 
+	}
+}; 
+
+template <typename T> 
+struct __dispatch_filter<T, true> {
+	static T apply(const T3DImage<T>& data, int cx, int cy, int cz, int  hw, int freedom) {
+		double result = 0.0; 
+		int n = freedom; 
+		// 
+		// see above. Coverty  1128688, 1128687
+		// 
+		auto range = prepare_range(data.get_size(), cx, cy, cz, hw); 
+		auto rb = data.begin_range(range.first,range.second); 
+		auto re = data.end_range(range.first,range.second); 
+		
+		while (rb != re) {
+			result += *rb; 
+			++rb; 
+			++n; 
+		}
+		return static_cast<T>(result/n); 
+	}
+}; 
+
+// special case bool - if the number of pixels counted is even and the 
+// the number of trues and falses equal return the original value
+template <> 
+struct __dispatch_filter<bool, false> {
+	static bool apply(const T3DImage<bool>& data, int cx, int cy, int cz, int hw, int MIA_PARAM_UNUSED(freedom)) {
+		int balance = 0; 
+		
+		auto range = prepare_range(data.get_size(), cx, cy, cz, hw); 
+		auto rb = data.begin_range(range.first,range.second); 
+		auto re = data.end_range(range.first,range.second); 
+		
+		while (rb != re) {
+			balance += *rb  ? 1 : -1; 
+			++rb; 
+		}
+
+		return (balance > 0) ? true : 
+			((balance < 0) ? false : data(cx,cy,cz)); 
+	}
+};
+
+template <class T>
+mia::T3DImage<T> *C3DMeanFilter::apply(const mia::T3DImage<T>& data) const
+{
+        const bool is_floating_point = std::is_floating_point<T>::value; 
+        T3DImage<T> * result = new T3DImage<T>(data.get_size(), data);
+        const int hw = m_hwidth; 
+
+        auto run_slice  = [hw, data, result](const tbb::blocked_range<size_t>& range) {
+                for (auto z = range.begin(); z != range.end(); ++z) {
+                        auto ir = result->begin_at(0,0,z);  
+                        for (size_t y = 0; y < data.get_size().y; ++y)
+                                for (size_t x = 0; x < data.get_size().x; ++x, ++ir) {
+                                        *ir = __dispatch_filter<T, is_floating_point>::apply(data, x,y,z, hw, 0); 
+                                }
+                }
+        }; 
+        parallel_for(tbb::blocked_range<size_t>(0, data.get_size().z, 1), run_slice);
+        return result;
+}
+
+
+template <class T>
+mia::P3DImage C3DMeanFilter::operator () (const T3DImage<T>& data) const 
+{
+        return P3DImage(apply(data)); 
+}
+
+mia::P3DImage C3DMeanFilter::do_filter(const mia::C3DImage& image) const
+{
+        return mia::filter(*this, image); 
+}
+
+
+
+C3DMeanFilterPlugin::C3DMeanFilterPlugin():
+        C3DFilterPlugin("mean"), 
+        m_hw(1)
+{
+        add_parameter("w", new CIntParameter(m_hw, 1, std::numeric_limits<int>::max(), false, "half filter width"));
+}
+                       
+C3DFilter *C3DMeanFilterPlugin::do_create()const
+{
+        return new C3DMeanFilter(m_hw);
+}
+
+const std::string  C3DMeanFilterPlugin::do_get_descr() const
+{
+        return "3D image mean filter";
+}
+
+
+
+C3DVarianceFilter::C3DVarianceFilter(int hwidth):
+m_hwidth(hwidth), 
+        m_mean(hwidth)
+{
+        
+}
+
+template <class T>
+P3DImage C3DVarianceFilter::operator () (const mia::T3DImage<T>& data) const
+{
+        unique_ptr<mia::T3DImage<T>> mean(m_mean.apply(data)); 
+        
+        transform(data.begin(), data.end(), mean->begin(), mean->begin(), 
+                  [](T x, T y) -> T { T xy = x - y; return xy*xy; }); 
+
+        const bool is_floating_point = std::is_floating_point<T>::value; 
+        T3DImage<T> * result = new T3DImage<T>(data.get_size(), data);
+        const int hw = m_hwidth; 
+
+        auto run_slice  = [hw, &mean, result](const tbb::blocked_range<size_t>& range) {
+                for (auto z = range.begin(); z != range.end(); ++z) {
+                        auto ir = result->begin_at(0,0,z);  
+                        for (size_t y = 0; y < mean->get_size().y; ++y)
+                                for (size_t x = 0; x < mean->get_size().x; ++x, ++ir) {
+                                        *ir = sqrt(__dispatch_filter<T, is_floating_point>::apply(*mean, x,y,z, hw, -1)); 
+                                        
+                                }
+                }
+        }; 
+        parallel_for(tbb::blocked_range<size_t>(0, data.get_size().z, 1), run_slice);
+        return P3DImage(result);
+ }
+
+mia::P3DImage C3DVarianceFilter::operator () (const mia::C3DBitImage& data) const
+{
+	cvwarn() << "This filter does not really evaluate the pixel wise variance\n";  
+        C3DFImage fimage(data.get_size(), data); 
+        copy(data.begin(), data.end(), fimage.begin()); 
+        return this->operator()(fimage);
+}
+
+P3DImage C3DVarianceFilter::do_filter(const mia::C3DImage& image) const
+{
+        return mia::filter(*this, image); 
+}
+
+
+C3DVarianceFilterPlugin::C3DVarianceFilterPlugin():
+C3DFilterPlugin("variance"), 
+        m_hw(1)
+{
+        add_parameter("w", new CIntParameter(m_hw, 1, std::numeric_limits<int>::max(), false, "half filter width"));        
+}
+        
+mia::C3DFilter *C3DVarianceFilterPlugin::do_create()const
+{
+        return new C3DVarianceFilter(m_hw); 
+}
+
+const std::string  C3DVarianceFilterPlugin::do_get_descr() const
+{
+        return "3D image variance filter"; 
+}
+
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+        auto chain = new C3DMeanFilterPlugin();
+        chain->append_interface(new C3DVarianceFilterPlugin()); 
+	return chain; 
+}
+
+
+NS_END
+
diff --git a/mia/3d/filter/mean.hh b/mia/3d/filter/mean.hh
new file mode 100644
index 0000000..5da34cd
--- /dev/null
+++ b/mia/3d/filter/mean.hh
@@ -0,0 +1,86 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_filter_mean_hh
+#define mia_3d_filter_mean_hh
+
+#include <mia/3d/filter.hh>
+
+NS_BEGIN(mean_3dimage_filter)
+
+class C3DMeanFilter: public mia::C3DFilter {
+public:
+	C3DMeanFilter(int hwidth);
+
+	template <class T>
+	mia::T3DImage<T> *apply(const mia::T3DImage<T>& data) const ;
+
+
+	template <class T>
+	mia::P3DImage operator () (const mia::T3DImage<T>& data) const ;
+private:
+	virtual mia::P3DImage do_filter(const mia::C3DImage& image) const;
+	int m_hwidth;
+};
+
+
+
+class C3DMeanFilterPlugin: public mia::C3DFilterPlugin {
+public:
+	C3DMeanFilterPlugin();
+private:
+	virtual mia::C3DFilter *do_create()const;
+	virtual const std::string  do_get_descr() const;
+	int m_hw;
+};
+
+
+class C3DVarianceFilter: public mia::C3DFilter {
+public:
+	C3DVarianceFilter(int hwidth);
+
+	template <class T>
+	mia::P3DImage operator () (const mia::T3DImage<T>& data) const;
+
+	mia::P3DImage operator () (const mia::C3DBitImage& data) const;
+
+private:
+	virtual mia::P3DImage do_filter(const mia::C3DImage& image) const;
+	int m_hwidth;
+        C3DMeanFilter m_mean; 
+};
+
+
+
+class C3DVarianceFilterPlugin: public mia::C3DFilterPlugin {
+public:
+	C3DVarianceFilterPlugin();
+private:
+	virtual mia::C3DFilter *do_create()const;
+	virtual const std::string  do_get_descr() const;
+	int m_hw;
+};
+
+
+
+
+NS_END
+
+#endif
diff --git a/mia/3d/filter/median.cc b/mia/3d/filter/median.cc
index 6b940ee..1b10264 100644
--- a/mia/3d/filter/median.cc
+++ b/mia/3d/filter/median.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/median.hh b/mia/3d/filter/median.hh
index 2af7412..a878ac6 100644
--- a/mia/3d/filter/median.hh
+++ b/mia/3d/filter/median.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/mlv.cc b/mia/3d/filter/mlv.cc
index fa03241..111c8d7 100644
--- a/mia/3d/filter/mlv.cc
+++ b/mia/3d/filter/mlv.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/mlv.hh b/mia/3d/filter/mlv.hh
index 36ff648..dc27a2a 100644
--- a/mia/3d/filter/mlv.hh
+++ b/mia/3d/filter/mlv.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/morphological.cc b/mia/3d/filter/morphological.cc
index ce6f9b8..d7c6b30 100644
--- a/mia/3d/filter/morphological.cc
+++ b/mia/3d/filter/morphological.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,6 +23,11 @@
 #include <boost/static_assert.hpp>
 #include <mia/3d/filter/morphological.hh>
 
+#include <mia/core/threadedmsg.hh>
+#include <tbb/parallel_for.h>
+#include <tbb/blocked_range.h>
+
+
 NS_BEGIN(morph_3dimage_filter)
 
 NS_MIA_USE
@@ -43,28 +48,32 @@ struct __dispatch_dilate {
 	static T3DImage<T> *apply(const T3DImage<T>& image, const C3DShape& shape, bool /*black*/) {
 		const C3DBounds& size = image.get_size();
 
-		T3DImage<T> *result = new T3DImage<T>(image);
-
-		typename T3DImage<T>::const_iterator src_i = image.begin();
-		typename T3DImage<T>::iterator res_i = result->begin();
-
-		for (size_t z = 0; z < size.z; ++z)
-			for (size_t y = 0; y < size.y; ++y)
-				for (size_t x = 0; x < size.x; ++x,  ++src_i, ++res_i) {
-
-					C3DShape::const_iterator sb = shape.begin();
-					C3DShape::const_iterator se = shape.end();
-
-					while (sb != se) {
-						C3DBounds nl(x + sb->x, y + sb->y, z + sb->z);
-						if (nl < size) {
-							T val = image(nl);
-							if (*res_i < val )
-								*res_i = val;
+		T3DImage<T> *result = new T3DImage<T>(size, image);
+		copy(image.begin(), image.end(), result->begin()); 
+		
+		auto run_slice = [&size, &image, &shape, &result](const tbb::blocked_range<size_t>& range) {
+			for (auto z = range.begin(); z != range.end(); ++z){
+				auto src_i = image.begin_at(0,0,z);
+				auto res_i = result->begin_at(0,0,z);
+				for (size_t y = 0; y < size.y; ++y)
+					for (size_t x = 0; x < size.x; ++x,  ++src_i, ++res_i) {
+						auto sb = shape.begin();
+						auto  se = shape.end();
+						
+						while (sb != se) {
+							C3DBounds nl(x + sb->x, y + sb->y, z + sb->z);
+							if (nl < size) {
+								T val = image(nl);
+								if (*res_i < val )
+									*res_i = val;
+							}
+							++sb;
+							
 						}
-						++sb;
 					}
-				}
+			}
+		};
+		tbb::parallel_for(tbb::blocked_range<size_t>(0, image.get_size().z, 1), run_slice); 
 		return result;
 	}
 };
@@ -147,7 +156,7 @@ C3DMorphFilterFactory::C3DMorphFilterFactory(const char *name):
 	m_hint("black")
 {
 	add_parameter("shape", make_param(m_shape, "sphere:r=2", false, "structuring element"));
-	add_parameter("hint", new CStringParameter(m_hint, false, "a hint at the main image content (black|white)"));
+	add_parameter("hint", new CStringParameter(m_hint, CCmdOptionFlags::none, "a hint at the main image content (black|white)"));
 }
 
 
@@ -187,28 +196,31 @@ struct __dispatch_erode {
 	static T3DImage<T> *apply(const T3DImage<T>& image, const C3DShape& shape, bool /*black*/) {
 		const C3DBounds size = image.get_size();
 
-		T3DImage<T> *result = new T3DImage<T>(image);
-
-		typename T3DImage<T>::const_iterator src_i = image.begin();
-		typename T3DImage<T>::iterator res_i = result->begin();
-
-		for (size_t z = 0; z < size.z; ++z)
-			for (size_t y = 0; y < size.y; ++y)
-				for (size_t x = 0; x < size.x; ++x,  ++src_i, ++res_i) {
-
-					C3DShape::const_iterator sb = shape.begin();
-					C3DShape::const_iterator se = shape.end();
-
-					while (sb != se) {
-						C3DBounds nl(x + sb->x, y + sb->y, z + sb->z);
-						if (nl < size) {
-							T val = image(nl);
-							if (*res_i > val )
-								*res_i = val;
+		T3DImage<T> *result = new T3DImage<T>(size, image);
+		copy(image.begin(), image.end(), result->begin()); 
+		
+		auto run_slice = [&size, &image, &shape, &result](const tbb::blocked_range<size_t>& range) {
+			for (auto z = range.begin(); z != range.end(); ++z){
+				auto src_i = image.begin_at(0,0,z);
+				auto res_i = result->begin_at(0,0,z);
+				for (size_t y = 0; y < size.y; ++y)
+					for (size_t x = 0; x < size.x; ++x,  ++src_i, ++res_i) {
+						auto  sb = shape.begin();
+						auto  se = shape.end();
+						
+						while (sb != se) {
+							C3DBounds nl(x + sb->x, y + sb->y, z + sb->z);
+							if (nl < size) {
+								T val = image(nl);
+								if (*res_i > val )
+									*res_i = val;
+							}
+							++sb;
 						}
-						++sb;
 					}
-				}
+			}
+		}; 
+		tbb::parallel_for(tbb::blocked_range<size_t>(0, image.get_size().z, 1), run_slice); 
 		return result;
 	}
 };
diff --git a/mia/3d/filter/morphological.hh b/mia/3d/filter/morphological.hh
index 7bd7809..38bd7bc 100644
--- a/mia/3d/filter/morphological.hh
+++ b/mia/3d/filter/morphological.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/msnormalizer.cc b/mia/3d/filter/msnormalizer.cc
new file mode 100644
index 0000000..77f4d9e
--- /dev/null
+++ b/mia/3d/filter/msnormalizer.cc
@@ -0,0 +1,173 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <tbb/parallel_for.h>
+#include <tbb/blocked_range.h>
+
+#include <mia/3d/filter/msnormalizer.hh>
+#include <mia/core/threadedmsg.hh>
+
+extern "C" {
+#include <cblas.h>
+}
+
+
+NS_BEGIN(msnormalizer_3dimage_filter)
+
+using namespace mia; 
+using std::pair; 
+using std::make_pair; 
+using std::string; 
+using std::vector; 
+
+C3DMSNormalizerFilter::C3DMSNormalizerFilter(int hwidth):
+m_hwidth(hwidth)
+{
+}
+
+pair<int, int> get_range(int i, int n)
+{
+        if (i <= 0) 
+                return make_pair(0, n+i);
+        else 
+                return make_pair(i, n-i+1);
+}
+
+int n_elements( int i, int n, int w) 
+{
+	int wl = i >= w ? w : i; 
+	int wr = i + w  < n ? w : n - i - 1; 
+	return wl + wr + 1; 
+}
+
+template <class T>
+void  C3DMSNormalizerFilter::add(C3DFImage& mean, C3DFImage& variance, const mia::T3DImage<T>& data, 
+          const C3DBounds& bi, const C3DBounds& bo, const C3DBounds& ei) const
+{
+
+        int x_length = ei.x - bi.x; 
+	
+	auto sum_slice = [&data, &mean, &variance, bi, bo, ei, x_length](const tbb::blocked_range<int>& range) {
+		vector <float> in_buffer(x_length);
+		for(auto z = range.begin(); z != range.end(); ++z) {
+			for(unsigned y = bi.y, oy = 0; y != ei.y; ++y, ++oy) {
+				
+				auto in_start = data.begin_at(bi.x,y,bi.z + z); 
+				copy(in_start, in_start + x_length, in_buffer.begin());
+				
+				cblas_saxpy(x_length, 1.0f, &in_buffer[0],  1, &mean(bo.x, bo.y + oy, bo.z + z), 1);
+				
+				transform(in_buffer.begin(), in_buffer.end(), 
+					  in_buffer.begin(), [](float x){ return x*x;});
+				cblas_saxpy(x_length, 1.0f, &in_buffer[0],  1, &variance(bo.x,bo.y + oy, bo.z + z), 1); 
+			}
+		}
+	}; 
+
+	parallel_for(tbb::blocked_range<int>(0, ei.z - bi.z, 1), sum_slice);
+
+
+}
+
+template <class T>
+mia::P3DImage C3DMSNormalizerFilter::operator () (const mia::T3DImage<T>& data) const
+{
+        // prepare buffers
+        C3DFImage *mean = new C3DFImage(data.get_size(), data);
+        C3DFImage variance(data.get_size());
+
+        C3DBounds bo; 
+
+        // evaluate sum 
+        for (int z = -m_hwidth; z <= m_hwidth; ++z) {
+		cvmsg() << "Run filter block  " << z + m_hwidth << " of " << 2*m_hwidth+1 << "\n"; 
+                auto z_range = get_range(z, data.get_size().z);
+                bo.z = z >= 0 ? 0 : -z;  
+                for (int y = -m_hwidth; y <= m_hwidth; ++y) {
+                        auto y_range = get_range(y, data.get_size().y);
+                        bo.y = y >= 0 ? 0 : -y; 
+                        for (int x = -m_hwidth; x <= m_hwidth; ++x) {
+                                auto x_range = get_range(x, data.get_size().x);
+                                bo.x = x >= 0 ? 0 : -x; 
+                                C3DBounds bi(x_range.first, y_range.first, z_range.first);
+                                C3DBounds ei(x_range.second, y_range.second, z_range.second);
+				cvdebug() << "bi(" << bi << ")->bo(" << bo << ")\n"; 
+                                add(*mean, variance, data, bi, bo, ei);
+                        }
+                }
+        }
+
+	
+	auto evaluate_result = [data, this, &mean, &variance](const tbb::blocked_range<unsigned>& range) {
+		CThreadMsgStream thread_stream;
+		for (auto z = range.begin(); z != range.end(); ++z) {
+			cvmsg() << "Evaluate slice " << z << "\n"; 
+			auto im = mean->begin_at(0,0,z); 
+			auto iv = variance.begin_at(0,0,z);
+			auto ii = data.begin_at(0,0,z); 
+			
+			const int nz = n_elements(z, data.get_size().z, m_hwidth); 
+			for (unsigned y = 0; y != data.get_size().y; ++y) {
+				const int ny = n_elements(y, data.get_size().y, m_hwidth); 
+				for (unsigned x = 0; x != data.get_size().x; ++x, ++im, ++iv, ++ii) {
+					const int nx = n_elements(x, data.get_size().x, m_hwidth); 
+					int n = nx * ny * nz; 
+					float mean = *im / n;
+					float var = (n > 1.0) ? (*iv - *im * mean) / (n - 1.0f) : 0.0f;
+					*im = var > 0 ? (*ii - mean) / sqrt(var) : 0.0f; 
+				}
+			}
+		}
+	}; 
+	
+	parallel_for(tbb::blocked_range<unsigned>(0, data.get_size().z, 1), evaluate_result);
+	
+        return P3DImage(mean); 
+}
+
+
+mia::P3DImage C3DMSNormalizerFilter::do_filter(const mia::C3DImage& image) const
+{
+        return mia::filter(*this, image); 
+}
+
+C3DMSNormalizerFilterPlugin::C3DMSNormalizerFilterPlugin():
+C3DFilterPlugin("msnormalizer"), 
+        m_hw(1)
+{
+        add_parameter("w", new CIntParameter(m_hw, 1, std::numeric_limits<int>::max(), false, "half filter width"));        
+}
+
+mia::C3DFilter *C3DMSNormalizerFilterPlugin::do_create()const
+{
+        return new C3DMSNormalizerFilter(m_hw); 
+}
+
+const std::string  C3DMSNormalizerFilterPlugin::do_get_descr() const
+{
+        return "3D image mean-sigma normalizing filter"; 
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+        return new C3DMSNormalizerFilterPlugin();
+}
+
+NS_END
diff --git a/mia/3d/filter/msnormalizer.hh b/mia/3d/filter/msnormalizer.hh
new file mode 100644
index 0000000..d8cbd48
--- /dev/null
+++ b/mia/3d/filter/msnormalizer.hh
@@ -0,0 +1,57 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_filter_msnormaliter_hh
+#define mia_3d_filter_msnormaliter_hh
+
+#include <mia/3d/filter.hh>
+
+NS_BEGIN(msnormalizer_3dimage_filter)
+ 
+int n_elements( int i, int n, int w); 
+
+class C3DMSNormalizerFilter: public mia::C3DFilter {
+public:
+	C3DMSNormalizerFilter(int hwidth);
+        
+	template <class T>
+	mia::P3DImage operator () (const mia::T3DImage<T>& data) const;
+        
+private:
+
+        template <class T>
+        void  add(mia::C3DFImage& mean, mia::C3DFImage& variance, const mia::T3DImage<T>& data, 
+                  const mia::C3DBounds& bi, const mia::C3DBounds& bo, const mia::C3DBounds& ei) const; 
+	virtual mia::P3DImage do_filter(const mia::C3DImage& image) const;
+	int m_hwidth;
+};
+
+class C3DMSNormalizerFilterPlugin: public mia::C3DFilterPlugin {
+public:
+	C3DMSNormalizerFilterPlugin();
+private:
+	virtual mia::C3DFilter *do_create()const;
+	virtual const std::string  do_get_descr() const;
+	int m_hw;
+};
+
+NS_END
+
+#endif 
diff --git a/mia/3d/filter/reorient.cc b/mia/3d/filter/reorient.cc
index 35594bd..517ae00 100644
--- a/mia/3d/filter/reorient.cc
+++ b/mia/3d/filter/reorient.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/reorient.hh b/mia/3d/filter/reorient.hh
index 23af4c0..2b327ce 100644
--- a/mia/3d/filter/reorient.hh
+++ b/mia/3d/filter/reorient.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/resize.cc b/mia/3d/filter/resize.cc
index 552129e..2b356b8 100644
--- a/mia/3d/filter/resize.cc
+++ b/mia/3d/filter/resize.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/resize.hh b/mia/3d/filter/resize.hh
index cd11fd7..04a2a04 100644
--- a/mia/3d/filter/resize.hh
+++ b/mia/3d/filter/resize.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/scale.cc b/mia/3d/filter/scale.cc
index 84aa9b5..03d9748 100644
--- a/mia/3d/filter/scale.cc
+++ b/mia/3d/filter/scale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/scale.hh b/mia/3d/filter/scale.hh
index 72820a9..e8113e7 100644
--- a/mia/3d/filter/scale.hh
+++ b/mia/3d/filter/scale.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/seededwatershed.cc b/mia/3d/filter/seededwatershed.cc
index 3c6a4a7..3d318ab 100644
--- a/mia/3d/filter/seededwatershed.cc
+++ b/mia/3d/filter/seededwatershed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/seededwatershed.hh b/mia/3d/filter/seededwatershed.hh
index 562b58a..0bdae3b 100644
--- a/mia/3d/filter/seededwatershed.hh
+++ b/mia/3d/filter/seededwatershed.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/selectbig.cc b/mia/3d/filter/selectbig.cc
index 407bf81..2d226e9 100644
--- a/mia/3d/filter/selectbig.cc
+++ b/mia/3d/filter/selectbig.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/selectbig.hh b/mia/3d/filter/selectbig.hh
index cb2d122..9edcf0b 100644
--- a/mia/3d/filter/selectbig.hh
+++ b/mia/3d/filter/selectbig.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/sepconv.cc b/mia/3d/filter/sepconv.cc
index 7242e77..4a1af9a 100644
--- a/mia/3d/filter/sepconv.cc
+++ b/mia/3d/filter/sepconv.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/sepconv.hh b/mia/3d/filter/sepconv.hh
index b2e8c94..93adca5 100644
--- a/mia/3d/filter/sepconv.hh
+++ b/mia/3d/filter/sepconv.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/tee.cc b/mia/3d/filter/tee.cc
index 9f0b7ea..5002269 100644
--- a/mia/3d/filter/tee.cc
+++ b/mia/3d/filter/tee.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@ mia::P3DImage C3DTee::do_filter(mia::P3DImage image) const
 C3DTeeFilterPluginFactory::C3DTeeFilterPluginFactory(): 
 	C3DFilterPlugin("tee")
 {
-	add_parameter("file", new CStringParameter(m_filename, true,
+	add_parameter("file", new CStringParameter(m_filename, CCmdOptionFlags::required_output,
 						   "name of the output file to save the image too.", 
 						   &C3DImageIOPluginHandler::instance()));
 }
diff --git a/mia/3d/filter/tee.hh b/mia/3d/filter/tee.hh
index e348f6c..db8d980 100644
--- a/mia/3d/filter/tee.hh
+++ b/mia/3d/filter/tee.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_bandpass.cc b/mia/3d/filter/test_bandpass.cc
index e726c42..ce1a4ba 100644
--- a/mia/3d/filter/test_bandpass.cc
+++ b/mia/3d/filter/test_bandpass.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_binarize.cc b/mia/3d/filter/test_binarize.cc
index d45dfa4..3f094e7 100644
--- a/mia/3d/filter/test_binarize.cc
+++ b/mia/3d/filter/test_binarize.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_combiner.cc b/mia/3d/filter/test_combiner.cc
new file mode 100644
index 0000000..2b5ebcf
--- /dev/null
+++ b/mia/3d/filter/test_combiner.cc
@@ -0,0 +1,110 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+#include <mia/3d/filter/combiner.hh>
+
+#include <mia/core/datapool.hh>
+#include <mia/3d/imageio.hh>
+#include <mia/3d/imagetest.hh>
+
+NS_MIA_USE
+
+struct Combiner3DFilterFixture {
+
+        Combiner3DFilterFixture(); 
+        ~Combiner3DFilterFixture();        
+        C3DFImage *image1; 
+        C3DFImage *image2; 
+        
+        P3DImage pimage1;
+        P3DImage pimage2; 
+        C3DBounds size; 
+};
+
+
+BOOST_FIXTURE_TEST_CASE(test_sub_default, Combiner3DFilterFixture) 
+{
+        auto c = BOOST_TEST_create_from_plugin<C3DImageCombinerFilterPlugin>("combiner:image=other.@,op=sub");
+
+
+        auto result = c->filter(pimage1); 
+        BOOST_REQUIRE(result); 
+
+        C3DFImage expect(size); 
+        transform(image1->begin(), image1->end(), image2->begin(), expect.begin(), 
+                  [](float a, float b){return a-b;}); 
+
+
+        test_image_equal(*result, expect);
+
+}
+
+BOOST_FIXTURE_TEST_CASE(test_sub_reverse, Combiner3DFilterFixture) 
+{
+        auto c = BOOST_TEST_create_from_plugin<C3DImageCombinerFilterPlugin>("combiner:image=other.@,op=sub,reverse=1");
+
+        auto result = c->filter(pimage1); 
+        BOOST_REQUIRE(result); 
+
+        C3DFImage expect(size); 
+        transform(image2->begin(), image2->end(), image1->begin(), expect.begin(), 
+                  [](float a, float b){return a-b;}); 
+
+        test_image_equal(*result, expect);
+}
+
+Combiner3DFilterFixture::Combiner3DFilterFixture():
+        size(3,4,2)
+{
+        image2 = new  C3DFImage(size); 
+        pimage2.reset(image2); 
+
+        float x = 0.1; 
+        for (auto i = image2->begin(); i != image2->end(); ++i, x += 0.2)
+                *i = x; 
+
+        image1 = new  C3DFImage(size); 
+        pimage1.reset(image1); 
+
+        x = 0.2; 
+        for (auto i = image1->begin(); i != image1->end(); ++i, x += 0.3)
+                *i = x; 
+
+
+        save_image("other.@", pimage2); 
+
+}
+
+Combiner3DFilterFixture::~Combiner3DFilterFixture()
+{
+        boost::any dummy = CDatapool::instance().get_and_remove("other.@");
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mia/3d/filter/test_convert.cc b/mia/3d/filter/test_convert.cc
index 7fb74ab..c724579 100644
--- a/mia/3d/filter/test_convert.cc
+++ b/mia/3d/filter/test_convert.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_crop.cc b/mia/3d/filter/test_crop.cc
index b1d3f1e..bd2c226 100644
--- a/mia/3d/filter/test_crop.cc
+++ b/mia/3d/filter/test_crop.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -47,6 +47,7 @@ CropFixture::CropFixture():
 			for (size_t x = 0; x < size.x; ++x, ++i) {
 				*i = (x+1 ) * (y +1) * (z+1);
 			}
+	src.set_voxel_size(C3DFVector(2,3,4)); 
 }
 
 void CropFixture::check_result(C3DCrop& f, const C3DBounds& start, C3DBounds rsize)
@@ -63,6 +64,7 @@ void CropFixture::check_result(C3DCrop& f, const C3DBounds& start, C3DBounds rsi
 				BOOST_CHECK_EQUAL(static_cast<size_t>(*i), 
 						  (x+1+start.x ) * (y +1+start.y) * (z+1+start.z));
 			}
+	BOOST_CHECK_EQUAL(result->get_voxel_size(), src.get_voxel_size()); 
 }
 
 BOOST_FIXTURE_TEST_CASE( test_crop_inside, CropFixture )
diff --git a/mia/3d/filter/test_distance.cc b/mia/3d/filter/test_distance.cc
new file mode 100644
index 0000000..8f52392
--- /dev/null
+++ b/mia/3d/filter/test_distance.cc
@@ -0,0 +1,104 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+#include <mia/3d/filter/distance.hh>
+
+using namespace mia; 
+using namespace mia; 
+
+using namespace distance_3d_filter; 
+
+struct Distance3DInfFixture {
+	static const bool src_init[64]; 
+	static const float test_val[64]; 
+}; 
+
+struct Distance3DFuncFixture {
+	static const float src_init[64]; 
+	static const float test_val[64]; 
+}; 
+
+
+BOOST_AUTO_TEST_CASE( test_plugin ) 
+{
+        BOOST_TEST_create_from_plugin<C3DDistanceImageFilterFactory>("distance"); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_distance_full3d_inf, Distance3DInfFixture ) 
+{
+
+        C3DDistanceFilter distance; 
+	C3DBitImage src_img(C3DBounds(4,4,4), src_init); 
+	
+	
+	P3DImage presult =  distance.filter(src_img); 
+        const C3DFImage& result = dynamic_cast<const C3DFImage&>(*presult); 
+
+	int k = 0; 
+	for(auto i = result.begin(); i != result.end(); ++i, ++k ) {
+		BOOST_CHECK_CLOSE(*i, test_val[k], 0.1); 
+	}
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_distance_full3d_func,  Distance3DFuncFixture ) 
+{
+        C3DDistanceFilter distance; 
+	C3DFImage src_img(C3DBounds(4,4,4), src_init); 
+	
+	P3DImage presult =  distance.filter(src_img); 
+        const C3DFImage& result = dynamic_cast<const C3DFImage&>(*presult); 
+
+	int k = 0; 
+	for(auto i = result.begin(); i != result.end(); ++i, ++k ) {
+		cvdebug() << "k=" << k << ":" << *i << ", vs " << test_val[k] << "\n"; 
+		BOOST_CHECK_CLOSE(*i, test_val[k], 0.1); 
+	}
+}
+
+const bool Distance3DInfFixture::src_init[] = {
+		1, 0, 0, 0,   0, 0, 0, 0,   0, 0, 0, 0,  0, 0, 0, 0,    
+		0, 0, 0, 0,   0, 0, 0, 0,   0, 0, 1, 0,  0, 0, 0, 0, 
+		0, 0, 0, 0,   0, 1, 0, 0,   0, 0, 0, 0,  0, 0, 0, 0,
+		0, 0, 0, 0,   0, 0, 0, 0,   0, 1, 0, 0,  0, 0, 0, 0
+	}; 
+
+
+const float Distance3DInfFixture::test_val[] = {
+		0, 1, 4, 6,   1, 2, 2, 3,   4, 2, 1, 2,   6, 3, 2, 3,   
+		1, 2, 3, 5,   2, 1, 1, 2,   3, 1, 0, 1,   5, 2, 1, 2,  
+		2, 1, 2, 5,   1, 0, 1, 3,   2, 1, 1, 2,   3, 2, 2, 3,   
+		3, 2, 3, 6,   2, 1, 2, 5,   1, 0, 1, 4,   2, 1, 2, 5
+}; 
+
+const float Distance3DFuncFixture::src_init[] = {
+	1, 2, 4, 5,   5, 4, 3, 2,   3, 2, 2, 3,  4, 5, 3, 1, 
+	1, 4, 5, 2,   1, 2, 3, 3,   2, 3, 1, 4,  4, 4, 3, 4, 
+	3, 2, 1, 1,   2, 1, 4, 3,   0, 3, 2, 1,  5, 4, 4, 2,
+	7, 8, 1, 2,   6, 5, 4, 3,   4, 1, 4, 2,  5, 5, 4, 3
+}; 
+	
+const float Distance3DFuncFixture::test_val[] = {
+	1, 2, 5, 5,   2, 3, 3, 4,   3, 3, 2, 2,  5, 4, 2, 1, 
+	1, 2, 2, 2,   1, 2, 2, 3,   1, 2, 1, 2,  2, 3, 2, 2, 
+	2, 2, 1, 1,   1, 1, 2, 2,   0, 1, 2, 1,  1, 2, 3, 2,
+	4, 2, 1, 2,   2, 2, 2, 3,   1, 1, 2, 2,  2, 2, 3, 3
+}; 
diff --git a/mia/3d/filter/test_downscale.cc b/mia/3d/filter/test_downscale.cc
index eda002d..06ea0fe 100644
--- a/mia/3d/filter/test_downscale.cc
+++ b/mia/3d/filter/test_downscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,9 +30,6 @@ namespace bfs=boost::filesystem;
 using namespace downscale_3dimage_filter;
 
 
-C1DSpacialKernelPluginHandlerTestPath spacial_kernel_test_path; 
-C3DFilterPluginHandlerTestPath filter_test_path; 
-
 BOOST_AUTO_TEST_CASE( test_downscale )
 {
 	const short init[64] = {
diff --git a/mia/3d/filter/test_gradnorm.cc b/mia/3d/filter/test_gradnorm.cc
index 6194d3b..a57c101 100644
--- a/mia/3d/filter/test_gradnorm.cc
+++ b/mia/3d/filter/test_gradnorm.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_growmask.cc b/mia/3d/filter/test_growmask.cc
index 277f413..d80daec 100644
--- a/mia/3d/filter/test_growmask.cc
+++ b/mia/3d/filter/test_growmask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,8 +29,6 @@ using namespace ::boost;
 using namespace ::boost::unit_test;
 using namespace growmask_3dimage_filter;
 
-C3DShapePluginHandlerTestPath shape_path; 
-
 const size_t nx = 5;
 const size_t ny = 4;
 const size_t nz = 3;
diff --git a/mia/3d/filter/test_invert.cc b/mia/3d/filter/test_invert.cc
index 458b09e..0274550 100644
--- a/mia/3d/filter/test_invert.cc
+++ b/mia/3d/filter/test_invert.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_kmeans.cc b/mia/3d/filter/test_kmeans.cc
index effc85a..0d30fe2 100644
--- a/mia/3d/filter/test_kmeans.cc
+++ b/mia/3d/filter/test_kmeans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_label.cc b/mia/3d/filter/test_label.cc
index 4347bcc..fbc92af 100644
--- a/mia/3d/filter/test_label.cc
+++ b/mia/3d/filter/test_label.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,9 +44,6 @@ static void check(const C3DImage& inp, const char* mask_descr, unsigned char *an
 
 BOOST_AUTO_TEST_CASE( test_label )
 {
-	CPathNameArray kernelsearchpath;
-	kernelsearchpath.push_back(bfs::path("..")/bfs::path("shapes"));
-	C3DShapePluginHandler::set_search_path(kernelsearchpath);
 
 	bool input[27] = { 1, 0, 0,
 			   0, 0, 0,
diff --git a/mia/3d/filter/test_load.cc b/mia/3d/filter/test_load.cc
index ffc5756..4c353a0 100644
--- a/mia/3d/filter/test_load.cc
+++ b/mia/3d/filter/test_load.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_lvdownscale.cc b/mia/3d/filter/test_lvdownscale.cc
new file mode 100644
index 0000000..a464bb6
--- /dev/null
+++ b/mia/3d/filter/test_lvdownscale.cc
@@ -0,0 +1,132 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+#include <mia/3d/filter/lvdownscale.hh>
+
+NS_MIA_USE
+using namespace std;
+using namespace lvdownscale_3dimage_filter;
+
+class LVDownscaleFixture {
+protected: 
+	void check(const short *init, const short *expect, 
+		   const C3DBounds& init_siize, const C3DBounds& block_size,  const C3DBounds& expect_size, 
+		   const C3DFVector& init_voxel, const C3DFVector& expect_voxel); 
+
+}; 
+
+
+
+BOOST_FIXTURE_TEST_CASE( test_lvdownscale_all_zero,  LVDownscaleFixture )
+{
+	const short init[64] = {
+		0, 0, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 0, 0,
+		0, 0, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 0, 0,
+		0, 0, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 0, 0,
+		0, 0, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 0, 0
+	};
+
+	// todo should test with a do-nothing filter
+	const short test[8] = {
+		0, 0, 0, 0, 0, 0, 0, 0
+	};
+
+	check(init, test, C3DBounds(4, 4, 4), C3DBounds(2, 2, 2), C3DBounds(2, 2, 2), 
+	      C3DFVector(2.0, 3.0, 1.0), C3DFVector(4.0f, 6.0f, 2.0f)); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_lvdownscale_result_all_one,  LVDownscaleFixture )
+{
+	const short init[64] = {
+		1, 0, 0, 0, /**/ 0, 0, 0, 1, /**/ 0, 0, 0, 0, /**/ 0, 0, 1, 0,
+		0, 0, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 1, 0, 0, /**/ 0, 0, 0, 0,
+		0, 1, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 1, 0, /**/ 1, 0, 0, 0,
+		0, 0, 0, 0, /**/ 0, 0, 1, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 0, 0
+	};
+
+	// todo should test with a do-nothing filter
+	const short test[8] = {
+		1, 1, 1, 1, 1, 1, 1, 1
+	};
+
+	check(init, test, C3DBounds(4, 4, 4), C3DBounds(2, 2, 2), C3DBounds(2, 2, 2), 
+	      C3DFVector(2.0, 3.0, 1.0), C3DFVector(4.0f, 6.0f, 2.0f)); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_lvdownscale_result_some_real_voting,  LVDownscaleFixture )
+{
+	const short init[64] = {
+		1, 2, 0, 0, /**/ 2, 2, 0, 1, /**/ 0, 0, 0, 0, /**/ 0, 0, 1, 0,
+		1, 1, 0, 0, /**/ 2, 2, 0, 0, /**/ 0, 1, 0, 0, /**/ 0, 0, 0, 0,
+		0, 1, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 2, 2, /**/ 1, 0, 1, 1,
+		0, 0, 0, 0, /**/ 0, 0, 1, 0, /**/ 0, 0, 2, 2, /**/ 0, 0, 1, 1
+	};
+
+	// todo should test with a do-nothing filter
+	const short test[8] = {
+		2, 1, 1, 1, 1, 1, 1, 1
+	};
+
+	check(init, test, C3DBounds(4, 4, 4), C3DBounds(2, 2, 2), C3DBounds(2, 2, 2), 
+	      C3DFVector(2.0, 3.0, 1.0), C3DFVector(4.0f, 6.0f, 2.0f)); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_lvdownscale_result_some_real_voting2,  LVDownscaleFixture )
+{
+	const short init[64] = {
+		1, 2, 0, 0, /**/ 2, 2, 0, 0, /**/ 0, 0, 0, 0, /**/ 0, 0, 1, 0,
+		1, 1, 0, 0, /**/ 2, 2, 0, 0, /**/ 0, 1, 0, 0, /**/ 0, 0, 0, 0,
+		0, 1, 0, 0, /**/ 0, 0, 3, 3, /**/ 0, 0, 2, 2, /**/ 1, 0, 1, 1,
+		0, 0, 0, 0, /**/ 0, 0, 1, 0, /**/ 0, 0, 2, 2, /**/ 0, 0, 1, 1
+	};
+
+	// todo should test with a do-nothing filter
+	const short test[8] = {
+		2, 0, 1, 1, 1, 3, 1, 1
+	};
+
+	check(init, test, C3DBounds(4, 4, 4), C3DBounds(2, 2, 2), C3DBounds(2, 2, 2), 
+	      C3DFVector(2.0, 3.0, 1.0), C3DFVector(4.0f, 6.0f, 2.0f)); 
+}
+
+
+void LVDownscaleFixture::check(const short *init, const short *expect, 
+			       const C3DBounds& init_size, const C3DBounds& block_size,  const C3DBounds& expect_size, 
+			       const C3DFVector& init_voxel, const C3DFVector& expect_voxel)
+{
+
+	C3DSSImage fimage(init_size, init );
+
+	fimage.set_voxel_size(init_voxel);
+
+	C3DLVDownscale scaler(block_size);
+
+	P3DImage scaled = scaler.filter(fimage);
+
+	BOOST_CHECK_EQUAL(scaled->get_size(), expect_size);
+
+	const C3DSSImage& fscaled = dynamic_cast<const C3DSSImage&>(*scaled);
+	BOOST_CHECK_EQUAL(fscaled.get_voxel_size(), expect_voxel);
+	const short *t = expect;
+	for( C3DSSImage::const_iterator k = fscaled.begin(); k != fscaled.end(); ++k, ++t ) {
+		BOOST_CHECK_EQUAL(*k, *t);
+	}
+}
diff --git a/mia/3d/filter/test_mask.cc b/mia/3d/filter/test_mask.cc
index 9ba7d10..8f88413 100644
--- a/mia/3d/filter/test_mask.cc
+++ b/mia/3d/filter/test_mask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_mean.cc b/mia/3d/filter/test_mean.cc
new file mode 100644
index 0000000..67918f5
--- /dev/null
+++ b/mia/3d/filter/test_mean.cc
@@ -0,0 +1,129 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+/*
+  The test result numbes were created with libreoffice' calc program 4.1.5.3 
+  testhelpers/3d-mean-variance-test.ods
+*/
+
+
+#include <mia/internal/plugintester.hh>
+#include <mia/3d/filter/mean.hh>
+#include <mia/3d/imagetest.hh>
+
+
+using namespace mia;
+using namespace std;
+using namespace mean_3dimage_filter;
+
+BOOST_AUTO_TEST_CASE( test_mean_from_plugin_simple)
+{
+        C3DFImage image(C3DBounds(3,4,5)); 
+	
+
+        fill(image.begin(), image.end(), 1.0f); 
+
+        auto c = BOOST_TEST_create_from_plugin<C3DMeanFilterPlugin>("mean:w=1");
+
+        auto result = c->filter(image); 
+        BOOST_REQUIRE(result); 
+
+        test_image_equal(*result, image);
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_mean_from_plugin_real)
+{
+        C3DFImage image(C3DBounds(3,4,6)); 
+        C3DFImage expect(C3DBounds(3,4,6)); 
+	
+	float init[72] = {
+		1, 2, 3,  2, 3, 1,  2, 2, 5,  3, 3, 1,  
+		3, 2, 3,  3, 3, 2,  2, 5, 5,  3, 5, 3,  
+		4, 3, 4,  2, 3, 2,  2, 5, 2,  6, 5, 4,  
+		5, 4, 3,  2, 3, 1,  2, 2, 5,  5, 6, 2,  
+		4, 2, 4,  2, 4, 1,  5, 2, 2,  3, 3, 1,  
+		1, 2, 3,  2, 3, 1,  2, 3, 2,  4, 3, 1
+	}; 
+
+	float test_data[72] = {
+		19.0f/ 8, 28.0f/12, 19.0f/ 8,   30.0f/12, 49.0f/18, 36.0f/12,   36.0f/12, 53.0f/18, 38.0f/12,   25.0f/ 8, 39.0f/12, 29.0f/8, 
+		31.0f/12, 46.0f/18, 31.0f/12,   49.0f/18, 76.0f/27, 55.0f/18,   59.0f/18, 84.0f/27, 59.0f/18,   43.0f/12, 63.0f/18, 45.0f/12,
+		37.0f/12, 52.0f/18, 33.0f/12,   55.0f/18, 82.0f/27, 57.0f/18,   64.0f/18, 90.0f/27, 63.0f/18,   48.0f/12, 69.0f/18, 49.0f/12,
+		38.0f/12, 53.0f/18, 34.0f/12,   56.0f/18, 80.0f/27, 52.0f/18,   62.0f/18, 82.0f/27, 53.0f/18,   46.0f/12, 62.0f/18, 39.0f/12,
+		34.0f/12, 47.0f/18, 31.0f/12,   50.0f/18, 72.0f/27, 47.0f/18,   56.0f/18, 72.0f/27, 45.0f/18,   40.0f/12, 53.0f/18, 32.0f/12,
+		20.0f/ 8, 29.0f/12, 20.0f/ 8,   32.0f/12, 45.0f/18, 29.0f/12,   36.0f/12, 44.0f/18, 26.0f/12,   25.0f/ 8, 31.0f/12, 17.0f/8
+	}; 
+
+	copy(init, init + 72, image.begin()); 
+	copy(test_data, test_data + 72, expect.begin()); 
+
+        auto c = BOOST_TEST_create_from_plugin<C3DMeanFilterPlugin>("mean:w=1");
+
+        auto result = c->filter(image); 
+        BOOST_REQUIRE(result); 
+
+        test_image_equal(*result, expect);
+        
+}
+
+
+BOOST_AUTO_TEST_CASE( test_variance_from_plugin_real)
+{
+        C3DFImage image(C3DBounds(3,4,6)); 
+        C3DFImage expect(C3DBounds(3,4,6)); 
+	
+	float init[72] = {
+		1, 2, 3,  2, 3, 1,  2, 2, 5,  3, 3, 1,  
+		3, 2, 3,  3, 3, 2,  2, 5, 5,  3, 5, 3,  
+		4, 3, 4,  2, 3, 2,  2, 5, 2,  6, 5, 4,  
+		5, 4, 3,  2, 3, 1,  2, 2, 5,  5, 6, 2,  
+		4, 2, 4,  2, 4, 1,  5, 2, 2,  3, 3, 1,  
+		1, 2, 3,  2, 3, 1,  2, 3, 2,  4, 3, 1
+	}; 
+
+
+	float test_data[72] = {
+		0.6461538669, 0.8842581575, 0.9418553707, 0.9541867709, 1.1381303158, 1.2430416439, 
+		0.9629315991, 1.3082114628, 1.5308439032, 1.1808589713, 1.4629136824, 1.7135035969,
+		0.6667967162, 0.8908964824, 0.9118896119, 1.0053070916, 1.1495839577, 1.2117508995, 
+		1.1343259506, 1.3065862705, 1.404543673, 1.3591319872, 1.4624087158, 1.5652038894, 
+		0.8672395154, 0.9725722993, 0.9184631921, 1.1332712116, 1.2260257661, 1.2400617594, 
+		1.3691203891, 1.3795603149, 1.4392941391, 1.634941698, 1.5525440296, 1.627502342, 
+		1.035581741, 1.1611008606, 1.1442518335, 1.1923399406, 1.2712151864, 1.2229523468, 
+		1.3388592824, 1.3737998014, 1.3841640767, 1.5296769137, 1.4715249579, 1.4543121033, 
+		1.0848790377, 1.1732768267, 1.1340058468, 1.122744563, 1.1830172368, 1.0975180696, 
+		1.1308862301, 1.2406709754, 1.3025937332, 1.2587245411, 1.2727286891, 1.3019245601, 
+		1.0166710035, 1.1319696192, 1.1609364188, 1.0684026803, 1.0763137756, 0.9753916592, 
+		0.92694914, 1.0396658344, 1.0392902185, 0.9542701996, 0.9860666514, 0.8661049513
+	}; 
+
+	copy(init, init + 72, image.begin()); 
+	copy(test_data, test_data + 72, expect.begin()); 
+
+        auto c = BOOST_TEST_create_from_plugin<C3DVarianceFilterPlugin>("variance:w=1");
+
+        auto result = c->filter(image); 
+        BOOST_REQUIRE(result); 
+
+        test_image_equal(*result, expect);
+        
+}
diff --git a/mia/3d/filter/test_median.cc b/mia/3d/filter/test_median.cc
index 8bee8ff..60d551d 100644
--- a/mia/3d/filter/test_median.cc
+++ b/mia/3d/filter/test_median.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_mlv.cc b/mia/3d/filter/test_mlv.cc
index fcba327..9ac5ec6 100644
--- a/mia/3d/filter/test_mlv.cc
+++ b/mia/3d/filter/test_mlv.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_morphological.cc b/mia/3d/filter/test_morphological.cc
index e306231..c3699f3 100644
--- a/mia/3d/filter/test_morphological.cc
+++ b/mia/3d/filter/test_morphological.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_msnormalizer.cc b/mia/3d/filter/test_msnormalizer.cc
new file mode 100644
index 0000000..b44d300
--- /dev/null
+++ b/mia/3d/filter/test_msnormalizer.cc
@@ -0,0 +1,87 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+#include <mia/3d/filter/msnormalizer.hh>
+#include <mia/3d/imagetest.hh>
+
+using namespace msnormalizer_3dimage_filter; 
+using namespace mia; 
+
+
+BOOST_AUTO_TEST_CASE( test_n_elements )
+{
+
+	int n = 7; 
+	int w = 3; 
+
+	BOOST_CHECK_EQUAL(n_elements(0, n, w), 4); 
+	BOOST_CHECK_EQUAL(n_elements(1, n, w), 5); 
+	BOOST_CHECK_EQUAL(n_elements(2, n, w), 6); 
+	BOOST_CHECK_EQUAL(n_elements(3, n, w), 7); 
+	BOOST_CHECK_EQUAL(n_elements(4, n, w), 6); 
+	BOOST_CHECK_EQUAL(n_elements(5, n, w), 5); 
+	BOOST_CHECK_EQUAL(n_elements(6, n, w), 4); 
+
+
+
+}
+
+BOOST_AUTO_TEST_CASE( test_msnormalizer_from_plugin_real)
+{
+        C3DFImage image(C3DBounds(3,4,6)); 
+        C3DFImage expect(C3DBounds(3,4,6)); 
+	
+	float init[72] = {
+		1, 2, 3,  2, 3, 1,  2, 2, 5,  3, 3, 1,  
+		3, 2, 3,  3, 3, 2,  2, 5, 5,  3, 5, 3,  
+		4, 3, 4,  2, 3, 2,  2, 5, 2,  6, 5, 4,  
+		5, 4, 3,  2, 3, 1,  2, 2, 5,  5, 6, 2,  
+		4, 2, 4,  2, 4, 1,  5, 2, 2,  3, 3, 1,  
+		1, 2, 3,  2, 3, 1,  2, 3, 2,  4, 3, 1
+	}; 
+
+	float test_data[72] = {
+		
+		-1.8480591388, -0.4281744193, 0.8400268813, -0.5, 0.2263120871, -1.4832396974, 
+		-0.9574271078, -0.7237994818, 1.2001983963, -0.1002869446, -0.1757807623, -1.6426888243, 
+		0.5254563899, -0.6493281021, 0.5254563899, 0.2586252121, 0.1572154843, -0.8384379738, 
+		-0.9681718242, 1.35310631, 1.1899285569, -0.3875860749, 0.9967479589, -0.5051283393, 
+		1.0181376927, 0.115334446, 1.443375673, -0.9509794538, -0.0310627228, -0.9344333141, 
+		-1.0344111478, 1.1158901057, -0.9967479589, 1.2110601416, 0.7558641345, -0.0577350269, 
+		1.7801819062, 0.9085875536, 0.1495249932, -0.9394989938, 0.0295071476, -1.5339391607, 
+		-0.9605246372, -0.6664051775, 1.3245128873, 0.7104094931, 1.5461189428, -0.7537783614, 
+		0.9775856785, -0.4915303319, 1.2165448525, -0.6670671874, 1.0749676998, -1.4073885704, 
+		1.5339391607, -0.4807401701, -0.3509820591, -0.2431867286, 0.0376857693, -1.1129864055, 
+		-1.40312152, -0.3578073095, 0.4183300133, -0.5773502692, 0.4346134937, -1.4220635116, 
+		-1.0488088482, 0.4835011658, -0.1618347187, 0.8829187134, 0.3578073095, -1.3480755514
+	}; 
+
+	copy(init, init + 72, image.begin()); 
+	copy(test_data, test_data + 72, expect.begin()); 
+
+        auto c = BOOST_TEST_create_from_plugin<C3DMSNormalizerFilterPlugin>("msnormalizer:w=1");
+
+        auto result = c->filter(image); 
+        BOOST_REQUIRE(result); 
+
+        test_image_equal(*result, expect);
+        
+}
diff --git a/mia/3d/filter/test_reorient.cc b/mia/3d/filter/test_reorient.cc
index d6f9380..2e8de09 100644
--- a/mia/3d/filter/test_reorient.cc
+++ b/mia/3d/filter/test_reorient.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_resize.cc b/mia/3d/filter/test_resize.cc
index 6f1c684..ad5b878 100644
--- a/mia/3d/filter/test_resize.cc
+++ b/mia/3d/filter/test_resize.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_scale.cc b/mia/3d/filter/test_scale.cc
index 6e9bcae..fe7399a 100644
--- a/mia/3d/filter/test_scale.cc
+++ b/mia/3d/filter/test_scale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,8 +27,6 @@ using namespace ::boost;
 using namespace ::boost::unit_test;
 using namespace scale_3dimage_filter;
 
-CSplineKernelTestPath splinekernel_init_path; 
-
 BOOST_AUTO_TEST_CASE( test_downscale )
 {
 
diff --git a/mia/3d/filter/test_seededwatershed.cc b/mia/3d/filter/test_seededwatershed.cc
index 111a7df..f0c9750 100644
--- a/mia/3d/filter/test_seededwatershed.cc
+++ b/mia/3d/filter/test_seededwatershed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,9 +26,6 @@
 using namespace mia; 
 using namespace std; 
 
-C3DFilterPluginHandlerTestPath filter_test_path; 
-C3DShapePluginHandlerTestPath shape_test_path; 
-
 const unsigned char  seed[3*72] = {
 	1, 0, 0, 0, 0, 0, 0, 0, 4,
 	0, 0, 0, 0, 0, 0, 0, 0, 0,
diff --git a/mia/3d/filter/test_selectbig.cc b/mia/3d/filter/test_selectbig.cc
index a430212..4ee03d1 100644
--- a/mia/3d/filter/test_selectbig.cc
+++ b/mia/3d/filter/test_selectbig.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_sepconv.cc b/mia/3d/filter/test_sepconv.cc
index 3367c48..be15403 100644
--- a/mia/3d/filter/test_sepconv.cc
+++ b/mia/3d/filter/test_sepconv.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,11 +30,6 @@ using namespace sepconv_3dimage_filter;
 
 BOOST_AUTO_TEST_CASE( test_sepconv )
 {
-
-	CPathNameArray kernelsearchpath;
-	kernelsearchpath.push_back(bfs::path("..")/bfs::path("..")/bfs::path("core")/bfs::path("spacialkernel"));
-	C1DSpacialKernelPluginHandler::set_search_path(kernelsearchpath);
-
 	C3DFImage src(C3DBounds(3,3,3));
 	fill(src.begin(), src.end(), 0);
 	src(1,1,1) = 64.0f;
diff --git a/mia/3d/filter/test_tee.cc b/mia/3d/filter/test_tee.cc
index ca65b40..67a57a2 100644
--- a/mia/3d/filter/test_tee.cc
+++ b/mia/3d/filter/test_tee.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_thinning.cc b/mia/3d/filter/test_thinning.cc
index 615943a..63eb5c5 100644
--- a/mia/3d/filter/test_thinning.cc
+++ b/mia/3d/filter/test_thinning.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/test_transform.cc b/mia/3d/filter/test_transform.cc
index 2ff5cf6..09d7f44 100644
--- a/mia/3d/filter/test_transform.cc
+++ b/mia/3d/filter/test_transform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,8 +28,6 @@
 using namespace transform_3dimage_filter; 
 using namespace mia; 
 
-C3DTransformCreatorHandlerTestPath transformhandler_init_path; 
-
 struct TransformFixture {
 
 	TransformFixture();
diff --git a/mia/3d/filter/test_watershed.cc b/mia/3d/filter/test_watershed.cc
index 927ab73..67e055d 100644
--- a/mia/3d/filter/test_watershed.cc
+++ b/mia/3d/filter/test_watershed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,9 +26,6 @@
 using namespace mia; 
 using namespace std; 
 
-C3DFilterPluginHandlerTestPath filter_test_path; 
-C3DShapePluginHandlerTestPath shape_test_path; 
-
 BOOST_AUTO_TEST_CASE ( test_seeded_watershead ) 
 {
 	const C3DBounds size(11, 10, 3); 
diff --git a/mia/3d/filter/thinning.cc b/mia/3d/filter/thinning.cc
index 761cae1..54505fc 100644
--- a/mia/3d/filter/thinning.cc
+++ b/mia/3d/filter/thinning.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/thinning.hh b/mia/3d/filter/thinning.hh
index c2b0ff9..5d62f94 100644
--- a/mia/3d/filter/thinning.hh
+++ b/mia/3d/filter/thinning.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/transform.cc b/mia/3d/filter/transform.cc
index de97fb3..2734f68 100644
--- a/mia/3d/filter/transform.cc
+++ b/mia/3d/filter/transform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,14 +25,30 @@ NS_BEGIN( transform_3dimage_filter)
 
 NS_MIA_USE; 
 
-C3DTransform::C3DTransform(const std::string& name):
-	m_name(name)
+C3DTransform::C3DTransform(const std::string& name, const std::string& kernel, const std::string& bc):
+m_name(name), 
+	m_kernel(kernel), 
+	m_bc(bc)
 {
 }
 
 mia::P3DImage C3DTransform::do_filter(const mia::C3DImage& image) const
 {
         auto transform = load_transform<P3DTransformation>(m_name); 
+	if (!m_kernel.empty()) {
+		if (m_bc.empty()) {
+			cvdebug() << "Override interpolator with kernel="
+				  << m_kernel << " and mirror boundary conditions\n"; 
+			C3DInterpolatorFactory ipf(m_kernel, "mirror");
+			transform->set_interpolator_factory(ipf); 
+		}else{
+			cvdebug() << "Override interpolator with kernel="
+				  << m_kernel << " and "<< m_bc << " boundary conditions\n"; 
+			C3DInterpolatorFactory ipf(m_kernel, m_bc);
+			transform->set_interpolator_factory(ipf); 
+		}
+	}
+	
         return (*transform)(image); 
 	
 }
@@ -40,14 +56,26 @@ mia::P3DImage C3DTransform::do_filter(const mia::C3DImage& image) const
 C3DTransformFilterPluginFactory::C3DTransformFilterPluginFactory(): 
 	C3DFilterPlugin("transform")
 {
-	add_parameter("file", new CStringParameter(m_filename, true,
+	add_parameter("file", new CStringParameter(m_filename, CCmdOptionFlags::required_input,
 						   "Name of the file containing the transformation.", 
 						   &C3DTransformationIOPluginHandler::instance()));
+
+	
+	add_parameter("imgkernel", new CStringParameter(m_interpolator_kernel, CCmdOptionFlags::none, 
+							"override image interpolator kernel", 
+							&CSplineKernelPluginHandler::instance()));
+	add_parameter("imgboundary", new CStringParameter(m_interpolator_bc, CCmdOptionFlags::none, 
+							  "override image interpolation boundary conditions", 
+							  &CSplineBoundaryConditionPluginHandler::instance())); 
+ 
+
 }
 
 mia::C3DFilter *C3DTransformFilterPluginFactory::do_create()const
 {
-	return new C3DTransform(m_filename); 
+	
+
+	return new C3DTransform(m_filename, m_interpolator_kernel, m_interpolator_bc); 
 }
 
 const std::string C3DTransformFilterPluginFactory::do_get_descr()const
diff --git a/mia/3d/filter/transform.hh b/mia/3d/filter/transform.hh
index 98f65b2..8c724b3 100644
--- a/mia/3d/filter/transform.hh
+++ b/mia/3d/filter/transform.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,11 +25,14 @@ NS_BEGIN( transform_3dimage_filter)
 
 class C3DTransform : public mia::C3DFilter {
 public:
-	C3DTransform(const std::string& name);
+	C3DTransform(const std::string& name, const std::string& kernel, const std::string& bc);
 
 private:
 	virtual mia::P3DImage do_filter(const mia::C3DImage& image) const;
 	std::string m_name; 
+	std::string m_kernel;
+	std::string m_bc; 
+
 };
 
 class C3DTransformFilterPluginFactory: public mia::C3DFilterPlugin {
@@ -39,6 +42,8 @@ private:
 	virtual mia::C3DFilter *do_create()const;
 	virtual const std::string do_get_descr()const;
 	std::string m_filename; 
+	std::string m_interpolator_kernel;
+	std::string m_interpolator_bc; 
 };
 
 NS_END
diff --git a/mia/3d/filter/watershed.cc b/mia/3d/filter/watershed.cc
index 6542565..70ba3ae 100644
--- a/mia/3d/filter/watershed.cc
+++ b/mia/3d/filter/watershed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/filter/watershed.hh b/mia/3d/filter/watershed.hh
index cdbd9d4..6174676 100644
--- a/mia/3d/filter/watershed.hh
+++ b/mia/3d/filter/watershed.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fullcost.cc b/mia/3d/fullcost.cc
index 70abac0..3bdaffd 100644
--- a/mia/3d/fullcost.cc
+++ b/mia/3d/fullcost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fullcost.hh b/mia/3d/fullcost.hh
index 67b9ddd..a53e5ba 100644
--- a/mia/3d/fullcost.hh
+++ b/mia/3d/fullcost.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fullcost/CMakeLists.txt b/mia/3d/fullcost/CMakeLists.txt
index f3529e6..f7f2d59 100644
--- a/mia/3d/fullcost/CMakeLists.txt
+++ b/mia/3d/fullcost/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 
-SET(fullcost image divcurl taggedssd)
+SET(fullcost image maskedimage taggedssd)
 PLUGINGROUP_WITH_TEST_AND_PREFIX2("3dimage" "fullcost" "${fullcost}" mia3d TESTLIBS
   mia3dtest
   )
diff --git a/mia/3d/fullcost/divcurl.cc b/mia/3d/fullcost/divcurl.cc
deleted file mode 100644
index f399611..0000000
--- a/mia/3d/fullcost/divcurl.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <mia/3d/fullcost/divcurl.hh>
-#include <mia/template/divcurl.cxx>
-
-NS_MIA_BEGIN
-
-template class TDivcurlFullCostPlugin<C3DTransformation>; 
-template class  TDivCurlFullCost<C3DTransformation>; 
-
-extern "C" EXPORT CPluginBase *get_plugin_interface()
-{
-	return new C3DDivCurlFullCostPlugin();
-}
-
-NS_MIA_END
-
-
-
diff --git a/mia/3d/fullcost/divcurl.hh b/mia/3d/fullcost/divcurl.hh
deleted file mode 100644
index d119935..0000000
--- a/mia/3d/fullcost/divcurl.hh
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef mia_3d_divcurl_hh
-#define mia_3d_divcurl_hh
-
-
-#include <mia/3d/fullcost.hh>
-#include <mia/template/divcurl.hh>
-
-
-NS_MIA_BEGIN
-typedef TDivcurlFullCostPlugin<C3DTransformation> C3DDivCurlFullCostPlugin; 
-typedef TDivCurlFullCost<C3DTransformation> C3DDivCurlFullCost; 
-NS_MIA_END
-
-#endif
diff --git a/mia/3d/fullcost/image.cc b/mia/3d/fullcost/image.cc
index 97b607d..c2473f6 100644
--- a/mia/3d/fullcost/image.cc
+++ b/mia/3d/fullcost/image.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,13 +27,13 @@ using namespace std;
 
 C3DImageFullCost::C3DImageFullCost(const std::string& src, 
 				   const std::string& ref, 
-				   const std::string& cost, 
+				   P3DImageCost cost, 
 				   double weight, 
 				   bool debug):
 	C3DFullCost(weight), 
 	m_src_key(C3DImageIOPluginHandler::instance().load_to_pool(src)), 
 	m_ref_key(C3DImageIOPluginHandler::instance().load_to_pool(ref)), 
-	m_cost_kernel(C3DImageCostPluginHandler::instance().produce(cost)), 
+	m_cost_kernel(cost), 
 	m_debug(debug)
 {
 	assert(m_cost_kernel); 
@@ -148,7 +148,7 @@ private:
 	const std::string do_get_descr() const;
 	std::string m_src_name;
 	std::string m_ref_name;
-	std::string m_cost_kernel;
+	P3DImageCost m_cost_kernel;
 	bool m_debug; 
 }; 
 
@@ -156,12 +156,11 @@ C3DImageFullCostPlugin::C3DImageFullCostPlugin():
 	C3DFullCostPlugin("image"), 
 	m_src_name("src.@"), 
 	m_ref_name("ref.@"), 
-	m_cost_kernel("ssd"), 
 	m_debug(false)
 {
-	add_parameter("src", new CStringParameter(m_src_name, false, "Study image", &C3DImageIOPluginHandler::instance()));
-	add_parameter("ref", new CStringParameter(m_ref_name, false, "Reference image", &C3DImageIOPluginHandler::instance()));
-	add_parameter("cost", new CStringParameter(m_cost_kernel, false, "Cost function kernel"));
+	add_parameter("src", new CStringParameter(m_src_name, CCmdOptionFlags::input, "Study image", &C3DImageIOPluginHandler::instance()));
+	add_parameter("ref", new CStringParameter(m_ref_name, CCmdOptionFlags::input, "Reference image", &C3DImageIOPluginHandler::instance()));
+	add_parameter("cost", make_param(m_cost_kernel, "ssd", false, "Cost function kernel"));
 	add_parameter("debug", new CBoolParameter(m_debug, false, "Save intermediate resuts for debugging")); 
 }
 
diff --git a/mia/3d/fullcost/image.hh b/mia/3d/fullcost/image.hh
index 501533d..20fe631 100644
--- a/mia/3d/fullcost/image.hh
+++ b/mia/3d/fullcost/image.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@ class EXPORT C3DImageFullCost : public C3DFullCost {
 public: 
 	C3DImageFullCost(const std::string& src, 
 			 const std::string& ref, 
-			 const std::string& cost, 
+			 P3DImageCost cost, 
 			 double weight, 
 			 bool debug); 
 private: 
diff --git a/mia/3d/fullcost/maskedimage.cc b/mia/3d/fullcost/maskedimage.cc
new file mode 100644
index 0000000..ac042be
--- /dev/null
+++ b/mia/3d/fullcost/maskedimage.cc
@@ -0,0 +1,343 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/fullcost/maskedimage.hh>
+#include <mia/3d/filter.hh>
+
+NS_MIA_BEGIN
+
+using namespace std; 
+
+C3DMaskedImageFullCost::C3DMaskedImageFullCost(const std::string& src, 
+					       const std::string& ref, 
+					       const std::string& src_mask, 
+					       const std::string& ref_mask, 
+					       P3DFilter src_mask_prefilter, 
+					       P3DFilter ref_mask_prefilter, 
+					       P3DMaskedImageCost cost, 
+					       double weight):
+	C3DFullCost(weight), 
+	m_src_key(C3DImageIOPluginHandler::instance().load_to_pool(src)), 
+	m_ref_key(C3DImageIOPluginHandler::instance().load_to_pool(ref)),
+	m_src_mask_prefilter(src_mask_prefilter), 
+	m_ref_mask_prefilter(ref_mask_prefilter), 
+        m_ref_mask_bit(nullptr), 
+	m_ref_mask_scaled_bit(nullptr), 
+	m_cost_kernel(cost)
+{
+	assert(m_cost_kernel); 
+
+        if (!src_mask.empty()) 
+                m_src_mask_key = C3DImageIOPluginHandler::instance().load_to_pool(src_mask); 
+        
+        if (!ref_mask.empty()) 
+                m_ref_mask_key = C3DImageIOPluginHandler::instance().load_to_pool(ref_mask); 
+
+        if (src_mask.empty() && ref_mask.empty()) {
+                throw invalid_argument("C3DMaskedImageFullCost: No masks give, you should used "
+                                       "the plain image cost instead"); 
+        }
+}
+
+bool C3DMaskedImageFullCost::do_has(const char *property) const
+{
+	return m_cost_kernel->has(property); 
+}
+
+/* 
+   This functions combines the moving and the fixed masks to a singular mask for cost function evaluation. 
+   - if no transformation is given then the original masks will be or-combined. In this case 
+     the masks must be of the same size. 
+   - if a transformation is given then the moving mask is transformed and then combined with 
+     the reference image mask 
+*/
+P3DImage C3DMaskedImageFullCost::get_combined_mask(const C3DTransformation *t, C3DBitImage **combined_mask) const 
+{
+        P3DImage temp_mask; 
+        *combined_mask = m_ref_mask_scaled_bit; 
+        if (m_src_mask_scaled) {
+		cvdebug() << "Maskedimage: Start with moving mask\n"; 
+                temp_mask = t ? (*t)(*m_src_mask_scaled): 
+                        temp_mask = m_src_mask_scaled->clone(); 
+
+                *combined_mask = static_cast<C3DBitImage *>(temp_mask.get());
+                assert(*combined_mask); 
+                
+                if (m_ref_mask_scaled_bit) {
+			cvdebug() << "Maskedimage: Combine with reference mask\n"; 
+                        if ( (*combined_mask)->get_size() != m_ref_mask_scaled_bit->get_size()){
+                                assert(!t && "Bug: The transformation should have created a mask of "
+                                       "the same size like the reference image mask"); 
+                                
+                                throw create_exception<invalid_argument>
+                                        ("C3DMaskedImageFullCost: the masks to be combined are "
+                                         "of different size: moving=[", (*combined_mask)->get_size(), 
+                                         "], reference=[", m_ref_mask_scaled_bit->get_size(), "]");
+                        }
+
+                        // A parameter should define how the masks are combined 
+                        transform((*combined_mask)->begin(), (*combined_mask)->end(),
+                                  m_ref_mask_scaled_bit->begin(), (*combined_mask)->begin(),
+                                  [](bool a, bool b){ return a && b;});
+                        
+                        // here a penalty could be added e.g. to ensure that the moving mask is 
+                        // always inside the fixed mask. However, it is difficult to evaluate a 
+                        // force for this.
+                }
+        }else
+		cvdebug() << "Maskedimage: Only have reference mask\n"; 
+        return temp_mask; 
+}
+
+double C3DMaskedImageFullCost::do_value(const C3DTransformation& t) const
+{
+	TRACE_FUNCTION; 
+	assert(m_src_scaled  && "Bug: you must call 'reinit()' before calling value(transform)"); 
+	P3DImage temp  = t(*m_src_scaled);
+        
+        C3DBitImage *temp_mask_bit = nullptr;
+        P3DImage temp_mask  = get_combined_mask(&t, &temp_mask_bit);
+        assert(temp_mask_bit); 
+        
+	const double result = m_cost_kernel->value(*temp, *temp_mask_bit); 
+	cvdebug() << "C3DMaskedImageFullCost::value = " << result << "\n"; 
+	return result; 
+}
+
+double C3DMaskedImageFullCost::do_value() const
+{
+	TRACE_FUNCTION; 
+	assert(m_src_scaled  && "Bug: you must call 'reinit()' before calling value()"); 
+
+        C3DBitImage *temp_mask_bit = nullptr;
+        P3DImage temp_mask  = get_combined_mask(nullptr, &temp_mask_bit);
+        assert(temp_mask_bit); 
+
+	const double result = m_cost_kernel->value(*m_src_scaled, *temp_mask_bit); 
+	cvdebug() << "C3DMaskedImageFullCost::value = " << result << "\n"; 
+	return result; 
+}
+
+
+double C3DMaskedImageFullCost::do_evaluate(const C3DTransformation& t, CDoubleVector& gradient) const
+{
+	TRACE_FUNCTION; 
+	assert(m_src_scaled  && "Bug: you must call 'reinit()' before calling evauate(...)"); 
+	
+	P3DImage temp  = t(*m_src_scaled);
+
+        C3DBitImage *temp_mask_bit = nullptr;
+        P3DImage temp_mask  = get_combined_mask(&t, &temp_mask_bit);
+        assert(temp_mask_bit); 
+        
+	C3DFVectorfield force(get_current_size()); 
+ 	double result = m_cost_kernel->evaluate_force(*temp, *temp_mask_bit, force); 
+	t.translate(force, gradient); 
+	return result; 
+	
+}
+
+void C3DMaskedImageFullCost::do_set_size()
+{
+	TRACE_FUNCTION; 
+	assert(m_src); 
+	assert(m_ref); 
+
+	if (m_src_scaled->get_size() != get_current_size() ||
+	    m_ref_scaled->get_size() != get_current_size())
+	{
+		stringstream filter_descr; 
+		filter_descr << "scale:s=[" << get_current_size()<<"]"; 
+		auto scaler = C3DFilterPluginHandler::instance().produce(filter_descr.str()); 
+		assert(scaler); 
+		cvdebug() << "C3DMaskedImageFullCost:scale images to " << get_current_size() << 
+			" using '" << filter_descr.str() << "'\n"; 
+		m_src_scaled = scaler->filter(*m_src); 
+		m_ref_scaled = scaler->filter(*m_ref);
+		m_cost_kernel->set_reference(*m_ref_scaled); 
+
+                if (m_src_mask)  {
+                    m_src_mask_scaled  = scaler->filter(*m_src_mask);
+                }
+
+                if (m_ref_mask)  {
+                    m_ref_mask_scaled  = scaler->filter(*m_ref_mask);
+                    m_ref_mask_scaled_bit = static_cast<C3DBitImage*>(m_ref_mask_scaled.get());  
+                }
+                assert ((m_src_mask_scaled || m_ref_mask_scaled) && 
+                        "Bug: At this point at least one mask should be available"); 
+	}
+}
+
+bool C3DMaskedImageFullCost::do_get_full_size(C3DBounds& size) const
+{
+	TRACE_FUNCTION; 
+	assert(m_src && "Hint: call 'reinit()' before calling get_full_size()"); 
+	if (size == C3DBounds::_0) {
+		size = m_src->get_size(); 
+		return true; 
+	}else
+		return 	size == m_src->get_size(); 
+}
+
+void C3DMaskedImageFullCost::do_reinit()
+{
+	TRACE_FUNCTION; 
+	//cvmsg() << "C3DMaskedImageFullCost: read " << m_src_key << " and " << m_ref_key << "\n"; 
+	m_src_scaled = m_src = get_from_pool(m_src_key);
+	m_ref_scaled = m_ref = get_from_pool(m_ref_key);
+
+        if (m_src_mask_key.key_is_valid()) {
+                m_src_mask = get_from_pool(m_src_mask_key);
+		// prefilter?
+		if (m_src_mask_prefilter) 
+			m_src_mask = m_src_mask_prefilter->filter(*m_src_mask); 
+
+                if (m_src->get_size() != m_src_mask->get_size()) {
+                        throw create_exception<runtime_error>("C3DMaskedImageFullCost: moving image has size [", 
+                                                              m_src->get_size(), "], but corresponding mask is of size [", 
+                                                              m_src_mask->get_size(), "]"); 
+                }
+		
+
+
+                if (m_src_mask->get_pixel_type() != it_bit) {
+                        // one could also add a binarize filter here, but  it's better to force 
+                        // the user to set the pixel type correctly 
+                        throw create_exception<invalid_argument>("C3DMaskedImageFullCost: moving mask image ", 
+								 m_src_mask_key.get_key(), 
+                                                                 " must be binary. You could add a src-mask-filter"
+								 " to convert the mask image."); 
+                }
+		m_src_mask_scaled = m_src_mask; 
+        }
+
+        if (m_ref_mask_key.key_is_valid()) {
+                m_ref_mask = get_from_pool(m_ref_mask_key);
+		if (m_ref_mask_prefilter) 
+			m_ref_mask = m_src_mask_prefilter->filter(*m_ref_mask); 
+				
+                if (m_ref->get_size() != m_ref_mask->get_size()) {
+                        throw create_exception<runtime_error>("C3DMaskedImageFullCost: reference image has size [", 
+                                                              m_src->get_size(), "], but corresponding mask is of size [",
+                                                              m_src_mask->get_size(), "]"); 
+                }
+
+
+                m_ref_mask_scaled_bit = m_ref_mask_bit = dynamic_cast<C3DBitImage *>(m_ref_mask.get());
+                if (!m_ref_mask_scaled_bit)  {
+                        throw create_exception<invalid_argument>("C3DMaskedImageFullCost: reference mask image "
+                                                                 "must be binary");
+                }
+        }
+
+	if (m_src->get_size() != m_ref->get_size()) {
+                cvinfo() << "C3DMaskedImageFullCost: registering moving image of size [" << m_src->get_size() << "] " 
+                         << "to reference image of size [" << m_ref->get_size() << "]\n"; 
+        }
+
+        
+
+	if (m_src->get_voxel_size() != m_ref->get_voxel_size()) {
+		cvwarn() << "C3DMaskedImageFullCost: moving and reference image are of differnet pixel dimensions."
+                         << "unless you optimize a transformation that supports global scaling this might "
+                         << "not be what you want to do\n"; 
+	}
+	m_cost_kernel->set_reference(*m_ref_scaled); 
+}
+
+P3DImage C3DMaskedImageFullCost::get_from_pool(const C3DImageDataKey& key)
+{
+	C3DImageIOPlugin::PData in_image_list = key.get();
+		
+	if (!in_image_list || in_image_list->empty())
+		throw invalid_argument("C3DMaskedImageFullCost: no image available in data pool");
+
+	return (*in_image_list)[0];
+}
+
+
+// plugin implementation 
+class C3DMaskedImageFullCostPlugin: public C3DFullCostPlugin {
+public: 
+	C3DMaskedImageFullCostPlugin(); 
+private: 
+	C3DFullCost *do_create(float weight) const;
+	const std::string do_get_descr() const;
+	std::string m_src_name;
+	std::string m_ref_name;
+	std::string m_src_mask_name;
+	std::string m_ref_mask_name;
+	P3DFilter m_src_mask_prefilter; 
+	P3DFilter m_ref_mask_prefilter; 
+
+	P3DMaskedImageCost m_cost_kernel;
+}; 
+
+C3DMaskedImageFullCostPlugin::C3DMaskedImageFullCostPlugin():
+	C3DFullCostPlugin("maskedimage"), 
+	m_src_name("src.@"), 
+	m_ref_name("ref.@")
+{
+	add_parameter("src", new CStringParameter(m_src_name, CCmdOptionFlags::input, "Study image", &C3DImageIOPluginHandler::instance()));
+	add_parameter("ref", new CStringParameter(m_ref_name, CCmdOptionFlags::input, "Reference image", &C3DImageIOPluginHandler::instance()));
+
+	add_parameter("src-mask", new CStringParameter(m_src_mask_name, CCmdOptionFlags::input, 
+                                                       "Study image mask (binary)", &C3DImageIOPluginHandler::instance()));
+	add_parameter("ref-mask", new CStringParameter(m_ref_mask_name, CCmdOptionFlags::input, 
+                                                       "Reference image mask  (binary)", &C3DImageIOPluginHandler::instance()));
+
+	add_parameter("src-mask-filter", make_param(m_src_mask_prefilter, "", false, 
+						    "Filter to prepare the study mask image, the output must be a binary image."));
+	add_parameter("ref-mask-filter", make_param(m_ref_mask_prefilter, "", false, 
+						    "Filter to prepare the reference mask image, the output must be a binary image."));
+
+	add_parameter("cost", make_param(m_cost_kernel, "ssd", false, "Cost function kernel"));
+}
+
+C3DFullCost *C3DMaskedImageFullCostPlugin::do_create(float weight) const
+{
+	cvdebug() << "create C3DMaskedImageFullCostPlugin with weight= " << weight 
+		  << " src=" << m_src_name << " ref=" << m_ref_name 
+                  << " src-mask='" << m_src_mask_name << "' ref='" << m_ref_name 
+		  << "' cost=" << m_cost_kernel << "\n";
+
+	return new C3DMaskedImageFullCost(m_src_name, m_ref_name, 
+                                          m_src_mask_name, m_ref_mask_name,
+					  m_src_mask_prefilter, m_ref_mask_prefilter, 
+                                          m_cost_kernel, weight); 
+}
+
+const std::string C3DMaskedImageFullCostPlugin::do_get_descr() const
+{
+	return "Generalized masked image similarity cost function that also handles multi-resolution processing. "
+                "The provided masks should be densly filled regions in multi-resolution procesing because "
+                "otherwise the mask information may get lost when downscaling the image. " 
+		"The mask may be pre-filtered - after pre-filtering the masks must be of bit-type."
+                "The reference mask and the transformed mask of the study image are combined by binary AND. "
+		"The actual similarity measure is given es extra parameter.";
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C3DMaskedImageFullCostPlugin();
+}
+
+NS_MIA_END
diff --git a/mia/3d/fullcost/maskedimage.hh b/mia/3d/fullcost/maskedimage.hh
new file mode 100644
index 0000000..7e03af9
--- /dev/null
+++ b/mia/3d/fullcost/maskedimage.hh
@@ -0,0 +1,87 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_imagefullcost_hh
+#define mia_3d_imagefullcost_hh
+
+
+#include <mia/3d/fullcost.hh>
+#include <mia/3d/imageio.hh>
+#include <mia/3d/maskedcost.hh>
+#include <mia/3d/filter.hh>
+
+NS_MIA_BEGIN
+
+class EXPORT C3DMaskedImageFullCost : public C3DFullCost {
+public: 
+	C3DMaskedImageFullCost(const std::string& src, 
+                               const std::string& ref, 
+                               const std::string& src_mask, 
+                               const std::string& ref_mask,
+			       P3DFilter src_mask_prefilter, 
+			       P3DFilter ref_mask_prefilter, 
+			       P3DMaskedImageCost cost, 
+                               double weight); 
+private: 
+	double do_evaluate(const C3DTransformation& t, CDoubleVector& gradient) const;
+	void do_set_size(); 
+
+	static P3DImage get_from_pool(const C3DImageDataKey& key); 
+        
+        P3DImage get_combined_mask(const C3DTransformation *t, C3DBitImage **combined_mask) const __attribute__((warn_unused_result)); 
+
+	bool do_has(const char *property) const; 
+	double do_value(const C3DTransformation& t) const; 
+
+	double do_value() const; 
+	void do_reinit(); 
+	bool do_get_full_size(C3DBounds& size) const; 
+
+	C3DImageDataKey m_src_key;
+	C3DImageDataKey m_ref_key;
+
+	C3DImageDataKey m_src_mask_key;
+	C3DImageDataKey m_ref_mask_key;
+	
+	P3DImage m_src; 
+	P3DImage m_ref; 
+	P3DImage m_src_mask; 
+	P3DImage m_ref_mask; 
+
+        P3DImage m_src_scaled; 
+	P3DImage m_ref_scaled;
+
+        P3DFilter m_src_mask_prefilter; 
+	P3DFilter m_ref_mask_prefilter;
+
+	C3DBitImage *m_ref_mask_bit; 
+
+	P3DImage m_src_mask_scaled; 
+	P3DImage m_ref_mask_scaled; 
+
+	C3DBitImage *m_ref_mask_scaled_bit;
+
+	P3DMaskedImageCost m_cost_kernel; 
+	bool m_debug;
+}; 
+
+NS_MIA_END
+
+#endif
diff --git a/mia/3d/fullcost/taggedssd.cc b/mia/3d/fullcost/taggedssd.cc
index 7d40743..d23144d 100644
--- a/mia/3d/fullcost/taggedssd.cc
+++ b/mia/3d/fullcost/taggedssd.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -408,15 +408,22 @@ private:
 }; 
 
 C3DTaggedSSDCostPlugin::C3DTaggedSSDCostPlugin():
-	C3DFullCostPlugin("taggedssd")
+C3DFullCostPlugin("taggedssd"), 
+      m_srcx_name("srcx.@"), 
+      m_refx_name("refx.@"), 
+      m_srcy_name("srcy.@"), 
+      m_refy_name("refy.@"),
+      m_srcz_name("srcz.@"),
+      m_refz_name("refz.@")
+										      
 {
 	const auto& io = C3DImageIOPluginHandler::instance(); 
-	add_parameter("srcx", new CStringParameter(m_srcx_name, true, "Study image X-tag", &io));
-	add_parameter("refx", new CStringParameter(m_refx_name, true, "Reference image  X-tag", &io));
-	add_parameter("srcy", new CStringParameter(m_srcy_name, true, "Study image Y-tag", &io));
-	add_parameter("refy", new CStringParameter(m_refy_name, true, "Reference image  Y-tag", &io));
-	add_parameter("srcz", new CStringParameter(m_srcz_name, true, "Study image Z-tag", &io));
-	add_parameter("refz", new CStringParameter(m_refz_name, true, "Reference image  Z-tag", &io));
+	add_parameter("srcx", new CStringParameter(m_srcx_name, CCmdOptionFlags::input, "Study image X-tag", &io));
+	add_parameter("refx", new CStringParameter(m_refx_name, CCmdOptionFlags::input, "Reference image  X-tag", &io));
+	add_parameter("srcy", new CStringParameter(m_srcy_name, CCmdOptionFlags::input, "Study image Y-tag", &io));
+	add_parameter("refy", new CStringParameter(m_refy_name, CCmdOptionFlags::input, "Reference image  Y-tag", &io));
+	add_parameter("srcz", new CStringParameter(m_srcz_name, CCmdOptionFlags::input, "Study image Z-tag", &io));
+	add_parameter("refz", new CStringParameter(m_refz_name, CCmdOptionFlags::input, "Reference image  Z-tag", &io));
 }
 
 C3DFullCost *C3DTaggedSSDCostPlugin::do_create(float weight) const
diff --git a/mia/3d/fullcost/taggedssd.hh b/mia/3d/fullcost/taggedssd.hh
index f45ec62..bc8e1a2 100644
--- a/mia/3d/fullcost/taggedssd.hh
+++ b/mia/3d/fullcost/taggedssd.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/fullcost/test_divcurl.cc b/mia/3d/fullcost/test_divcurl.cc
deleted file mode 100644
index 93ded57..0000000
--- a/mia/3d/fullcost/test_divcurl.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <mia/3d/transformmock.hh>
-
-#include <mia/internal/autotest.hh>
-#include <mia/3d/fullcost/divcurl.hh>
-#include <mia/3d/transformmock.hh>
-
-NS_MIA_USE
-namespace bfs=::boost::filesystem;
-CSplineKernelTestPath splinekernel_init_path; 
-
-BOOST_AUTO_TEST_CASE( test_divcurl_cost ) 
-{
-	C3DDivCurlFullCost  div(4.0, 6.0, 1.0); 
-
-	C3DBounds size(1, 2, 1); 
-	C3DTransformMock t(size, C3DInterpolatorFactory("bspline:d=3", "mirror")); 
-	div.set_size(size); 
-
-	CDoubleVector gradient(t.degrees_of_freedom()); 
-	BOOST_CHECK_EQUAL(div.evaluate(t, gradient), 5.0); 
-	BOOST_CHECK_EQUAL(gradient[0], -2.0); 
-	BOOST_CHECK_EQUAL(gradient[1], -3.0); 
-	BOOST_CHECK_EQUAL(gradient[2], -1.0);
-}
-
-BOOST_AUTO_TEST_CASE( test_div_cost ) 
-{
-	C3DDivCurlFullCost  div(4.0, 0.0, 0.5); 
-
-	C3DBounds size(1, 2, 1); 
-	C3DTransformMock t(size, C3DInterpolatorFactory("bspline:d=3", "mirror")); 
-	div.set_size(size); 
-
-	CDoubleVector gradient(t.degrees_of_freedom()); 
-	BOOST_CHECK_EQUAL(div.evaluate(t, gradient), 1.0); 
-	BOOST_CHECK_EQUAL(gradient[0], -1.0); 
-	BOOST_CHECK_EQUAL(gradient[1],  0.0); 
-	BOOST_CHECK_EQUAL(gradient[2],  1.0);
-}
-
-BOOST_AUTO_TEST_CASE( test_curl_cost ) 
-{
-	C3DDivCurlFullCost  div(0.0, 3.0, 2.0); 
-
-	C3DBounds size(1,2,1); 
-	C3DTransformMock t(size, C3DInterpolatorFactory("bspline:d=3", "mirror")); 
-	div.set_size(size); 
-
-	CDoubleVector gradient(t.degrees_of_freedom()); 
-	BOOST_CHECK_EQUAL(div.evaluate(t, gradient), 3.0);
-	BOOST_CHECK_EQUAL(gradient[0], 0.0);
-	BOOST_CHECK_EQUAL(gradient[1], -3.0);
-	BOOST_CHECK_EQUAL(gradient[2], -3.0);
-}
-
-BOOST_AUTO_TEST_CASE( test_curl_cost_notrans ) 
-{
-	C3DDivCurlFullCost  div(0.0, 4.0, 2.0); 
-
-	C3DBounds size(1,2,1); 
-	div.set_size(size); 
-
-	BOOST_CHECK_EQUAL(div.cost_value(), 0.0); 
-}
diff --git a/mia/3d/fullcost/test_image.cc b/mia/3d/fullcost/test_image.cc
index 0f3930d..923265a 100644
--- a/mia/3d/fullcost/test_image.cc
+++ b/mia/3d/fullcost/test_image.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,7 +33,6 @@ struct ImagefullcostFixture {
 	
 }; 
 
-CSplineKernelTestPath splinekernel_init_path; 
 
 BOOST_FIXTURE_TEST_CASE( test_imagefullcost_2,  ImagefullcostFixture)
 {
@@ -75,7 +74,7 @@ BOOST_FIXTURE_TEST_CASE( test_imagefullcost_2,  ImagefullcostFixture)
 	BOOST_REQUIRE(save_image("src.@", src)); 
 	BOOST_REQUIRE(save_image("ref.@", ref)); 
 
-	C3DImageFullCost cost("src.@", "ref.@", "ssd", 1.0, false); 
+	C3DImageFullCost cost("src.@", "ref.@", C3DImageCostPluginHandler::instance().produce("ssd"), 1.0, false); 
 	cost.reinit(); 
 	cost.set_size(size);
 	
diff --git a/mia/3d/fullcost/test_maskedimage.cc b/mia/3d/fullcost/test_maskedimage.cc
new file mode 100644
index 0000000..6286cc3
--- /dev/null
+++ b/mia/3d/fullcost/test_maskedimage.cc
@@ -0,0 +1,221 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define VSTREAM_DOMAIN "test-maskedimage" 
+#include <mia/3d/fullcost/maskedimage.hh>
+#include <mia/3d/transformmock.hh>
+#include <mia/3d/imageio.hh>
+#include <mia/3d/filter.hh>
+
+#include <mia/internal/autotest.hh>
+
+NS_MIA_USE
+namespace bfs=::boost::filesystem;
+
+BOOST_AUTO_TEST_CASE( test_imagefullcost_src_mask)
+{
+
+	// create two images 
+	const unsigned char src_data[64] = {
+		0, 0, 0, 0,   0,  0,  0, 0,  0,  0,  0, 0,   0, 0, 0, 0,
+ 		0, 0, 0, 0,   0,  0,  0, 0,  0,  0,  0, 0,   0, 0, 0, 0,
+ 		0, 0, 0, 0,   0,255,255, 0,  0,255,255, 0,   0, 0, 0, 0,
+		0, 0, 0, 0,   0,255,  0, 0,  0,  0,  0, 0,   0, 0, 0, 0
+
+	};
+	const unsigned char ref_data[64] = {
+		0, 0, 0, 0, 
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0
+
+	};
+
+	const bool src_mask_data[64] = {
+		0, 0, 0, 0, 
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 1, 1, 0,
+		0, 1, 1, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0
+
+	};
+
+	C3DBounds size(4,4,4); 
+
+	P3DImage src(new C3DUBImage(size, src_data ));
+	P3DImage ref(new C3DUBImage(size, ref_data ));
+
+	P3DImage src_mask(new C3DBitImage(size, src_mask_data ));
+	
+	BOOST_REQUIRE(save_image("src.@", src)); 
+	BOOST_REQUIRE(save_image("ref.@", ref)); 
+	BOOST_REQUIRE(save_image("src-mask.@", src_mask)); 
+
+        assert("at least one mask must be provided"); 
+	C3DMaskedImageFullCost cost("src.@", "ref.@","src-mask.@", "" , nullptr, nullptr, 
+                                    C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0); 
+
+	cvdebug() << "prepare cost\n"; 
+	cost.reinit(); 
+	cvdebug() << "set size cost\n"; 
+	cost.set_size(size);
+
+	
+	C3DTransformMock t(size, C3DInterpolatorFactory("bspline:d=3", "mirror")); 
+	
+	CDoubleVector gradient(t.degrees_of_freedom()); 
+	double cost_value = cost.evaluate(t, gradient);
+	BOOST_CHECK_EQUAL(gradient.size(), 3u * 64u); 
+
+	BOOST_CHECK_CLOSE(cost_value, 0.5 * 255 * 255.0/16.0 , 0.1);
+
+	double value = cost.cost_value(t);
+
+	BOOST_CHECK_CLOSE(value, 0.5 * 255 * 255.0/16.0  , 0.1);
+	
+	BOOST_CHECK_CLOSE(gradient[111], 255 *255/128.0 , 0.1);
+	BOOST_CHECK_CLOSE(gradient[112], 255 *255/128.0 , 0.1);
+	BOOST_CHECK_CLOSE(gradient[113], 255 *255/128.0 , 0.1);
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_imagefullcost_ref_mask)
+{
+
+	// create two images 
+	const unsigned char src_data[64] = {
+		0, 0, 0, 0,   0,  0,  0, 0,  0,  0,  0, 0,   0, 0, 0, 0,
+ 		0, 0, 0, 0,   0,  0,  0, 0,  0,  0,  0, 0,   0, 0, 0, 0,
+ 		0, 0, 0, 0,   0,255,255, 0,  0,255,255, 0,   0, 0, 0, 0,
+		0, 0, 0, 0,   0,255,  0, 0,  0,  0,  0, 0,   0, 0, 0, 0
+
+	};
+	const unsigned char ref_data[64] = {
+		0, 0, 0, 0, 
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0
+
+	};
+
+	const bool src_mask_data[64] = {
+		0, 0, 0, 0, 
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 1, 1, 0,
+		0, 1, 1, 0,
+		0, 0, 0, 0,
+
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0,
+		0, 0, 0, 0
+
+	};
+
+	C3DBounds size(4,4,4); 
+
+	P3DImage src(new C3DUBImage(size, src_data ));
+	P3DImage ref(new C3DUBImage(size, ref_data ));
+
+	P3DImage src_mask(new C3DBitImage(size, src_mask_data ));
+	
+	BOOST_REQUIRE(save_image("src.@", src)); 
+	BOOST_REQUIRE(save_image("ref.@", ref)); 
+	BOOST_REQUIRE(save_image("ref-mask.@", src_mask)); 
+
+        assert("at least one mask must be provided"); 
+	C3DMaskedImageFullCost cost("src.@", "ref.@","", "ref-mask.@", nullptr, nullptr, 
+                                    C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0); 
+
+	cvdebug() << "prepare cost\n"; 
+	cost.reinit(); 
+	cvdebug() << "set size cost\n"; 
+	cost.set_size(size);
+	
+	C3DTransformMock t(size, C3DInterpolatorFactory("bspline:d=3", "mirror")); 
+	
+	CDoubleVector gradient(t.degrees_of_freedom()); 
+	double cost_value = cost.evaluate(t, gradient);
+	BOOST_CHECK_EQUAL(gradient.size(), 3u * 64u); 
+
+	BOOST_CHECK_CLOSE(cost_value, 0.5 * 255 * 255.0/16.0 , 0.1);
+
+	double value = cost.cost_value(t);
+
+	BOOST_CHECK_CLOSE(value, 0.5 * 255 * 255.0/16.0  , 0.1);
+	
+	BOOST_CHECK_CLOSE(gradient[111], 255 *255/128.0 , 0.1);
+	BOOST_CHECK_CLOSE(gradient[112], 255 *255/128.0 , 0.1);
+	BOOST_CHECK_CLOSE(gradient[113], 255 *255/128.0 , 0.1);
+	
+}
diff --git a/mia/3d/fullcost/test_taggedssd.cc b/mia/3d/fullcost/test_taggedssd.cc
index d677621..8e34478 100644
--- a/mia/3d/fullcost/test_taggedssd.cc
+++ b/mia/3d/fullcost/test_taggedssd.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,13 +28,6 @@
 NS_MIA_USE; 
 NS_USE(taggedssd_3d); 
 
-namespace bfs=::boost::filesystem;
-
-
-CSplineKernelTestPath splinekernel_init_path; 
-C3DFilterPluginHandlerTestPath filter_init_path; 
-C3DImageIOPluginHandlerTestPath init_3dimage_path; 
-
 BOOST_AUTO_TEST_CASE( test_taggedssd)
 {
 
diff --git a/mia/3d/fuzzyClusterSolverCG.cc b/mia/3d/fuzzyClusterSolverCG.cc
deleted file mode 100644
index 942a251..0000000
--- a/mia/3d/fuzzyClusterSolverCG.cc
+++ /dev/null
@@ -1,366 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <cstring>
-
-#include "fuzzyClusterSolverCG.hh"
-
-NS_MIA_BEGIN
-#warning this needs to be tested
-bool fborder (long index, long nx, long ny, long nz)
-{
-	const long x = index % nx;
-
-	if ( x < 2 || x > nx-3 )
-	     return true;
-
-	index /= nx;
-
-	const long y = index % ny;
-	if ( y < 2 || y > ny-3 )
-	     return true;
-
-	index /= nx;
-
-	const long z = index / ny;
-	if ( z < 2 || z > nz-3 )
-	     return true;
-
-	return false;
-
-}
-
-
-
-solve_sCG::solve_sCG (C3DFImage& w1, C3DFImage& f1, C3DFImage& gain_image, double l1, double l2, double r_res, double m_res):
-	__lambda1(l1),
-	__lambda2(l2),
-	__iter(0),
-	__nx(w1.get_size().x),
-	__ny(w1.get_size().y),
-	__nz(w1.get_size().z),
-	__count(__nz*__ny*__nx),
-	__weight_imagePtr(&w1(0, 0, 0)),
-	__fptr(&f1(0, 0, 0)),
-	__gain_image_ptr(&gain_image(0, 0, 0)),
-
-	__b(new double[__count]),
-	__v(new double[__count]),
-	__r(new double[__count]),
-
-	__rho(new double[__count]),   // p^(k)
-	__g(new double[__count]),
-	__Ag(new double[__count]),   // speichert A * p
-
-	__scale(new double[__count]),
-	__scale2(new double[__count]),
-	__border(new bool[__count]),
-
-	__r1rho1(0.0), 
-	__r2rho2(0.0),
-	 __normr0(0.0),
-	__q(0.0), 
-	__e(0.0),
-	__sprod(0.0),
-
-	__min_res(m_res),
-	__relres(r_res)
-
-{
-	init ();
-
-}
-
-
-solve_sCG::~solve_sCG()
-{
-  delete[] __b;
-  delete[] __v;
-  delete[] __scale;
-  delete[] __scale2;
-  delete[] __border;
-
-  // free pointers
-  delete[] __r;
-  delete[] __rho;
-  delete[] __g;
-  delete[] __Ag;
-}
-
-
-
-// Umweg, da keine Methoden parallel aufgerufen werden koennen
-void solver(solve_sCG *s, long *maxit, double *normr, double *firstnormr0)
-{
-    s->solvepar(maxit, normr, firstnormr0);
-}
-
-
-int solve_sCG::solve(long max_iterations, double *firstnormr0) {
-
-        double normr;
-
-#ifdef PARALLEL
-    	m_set_procs(NPROCS);
-    	m_fork((void (*)())solver, this, &max_iterations, &normr,firstnormr0);
-    	m_kill_procs();
-#else
-    	solver(this, &max_iterations, &normr,firstnormr0);
-#endif
-
-	return normr > 1;
-}
-
-
-// loest das Gleichungssystem mittels CG-Algorithmus
-void solve_sCG::solvepar(long *maxit, double *normr, double *firstnormr0) {
-
-    // Prozessornummer
-    int me;
-
-    // Start und Ende fuer Vektoroperationen
-    long start;
-    long ende;
-
-    // Setze me, start und ende
-    me = 0;
-    start = 0;
-    ende = __count;
-
-    // Initialisierung
-    multA(__v, __r, start, ende);
-
-    // Berechnung normr0;
-    double tmp_normr0 = 0;
-    for(long i = start; i < ende; i++) {
-      __r[i] += __b[i];
-      double square = __r[i]/__scale[i];
-      tmp_normr0 += square*square;
-    }
-
-    __normr0 = tmp_normr0;
-
-    if (me == 0)
-	    *normr = __normr0 = sqrt(__normr0);
-
-
-    if (*firstnormr0 == 1.0 && __normr0 > 1.0)
-	    *firstnormr0 = __normr0;
-
-
-    // Iterationen
-    while (*normr >= __min_res && __iter < *maxit && *normr / *firstnormr0 > __relres){
-
-    	if (me == 0) {
-	  		__iter++;
-	  		memcpy(__rho, __r, __count * sizeof(double));
-	  		__r2rho2 = __r1rho1;
-        }
-
-
-	// r1rho1 = r * rho
-	if (me == 0) __r1rho1 = 0;
-
-	double tmp_r1rho1 = 0;
-	for(long i = start; i < ende; i++) {
-	  tmp_r1rho1 += __r[i] * __rho[i];
-	}
-
-	__r1rho1 = tmp_r1rho1;
-
-	if (__iter >= 2 && me == 0) __e = __r1rho1 / __r2rho2; else __e = 0;
-
-	for(long i = start; i < ende; i++) __g[i] = -__rho[i] + __e * __g[i];
-
-	multA(__g, __Ag, start, ende);
-
-	// q = r1rho1 / (g * Ag)
-	if (me == 0) __sprod = 0;
-	double tmp_sprod = 0;
-
-	for(long i = start; i < ende; i++) tmp_sprod += __g[i] * __Ag[i];
-
-	__sprod = tmp_sprod;
-
-	if (me == 0) __q = __r1rho1 / __sprod;
-
-	// v = v1 + q * g, r = r1 + q * Ag
-	if (me == 0) *normr = 0;
-	double tmp_normr = 0;
-
-	for(long i = start; i < ende; i++) {
-
-	  __v[i] += __q * __g[i];
-	  __r[i] += __q * __Ag[i];
-	  tmp_normr += pow(__r[i]/__scale[i], 2);
-
-	}
-
-	*normr = tmp_normr;
-
-	if (me == 0)
-		*normr = sqrt(*normr);
-
-	//*\todo implement some progression alert here */
-
-    }
-
-    return;
- }
-
-
-// Vektor-Matrix-Multiplikation
-#define VALUE(o) (sc2[o] * x2[o])
-
-void solve_sCG::multA(double *x, double *result, long start, long ende) {
-
-    long i;
-    bool *bord2;
-    double *x2, *sc2, *res2;
-
-    for(i = start; i < ende; i++) {
-
-		double s1, s2, s3;
-
-		bord2 = &__border[i];
-		res2  = &result[i];
-
-		x2    = &x[i];
-
-		if (*bord2) {
-			*res2 = *x2;
-			continue;
-		}
-
-		sc2 = &__scale2[i];
-
-		s1= VALUE(-__nx)    + VALUE(-1) + VALUE(+1) + VALUE(+__nx) +
-			VALUE(-__nx*__ny) + VALUE(+__nx*__ny);
-
-		s2= VALUE(-__nx-1)     + VALUE(-__nx+1)	+ VALUE(+__nx-1)     + VALUE(+__nx+1)    +
-			VALUE(-__nx*__ny-1)  + VALUE(-__nx*__ny+1)  + VALUE(-__nx*__ny-__nx) + VALUE(-__nx*__ny+__nx) +
-			VALUE(+__nx*__ny-1)  + VALUE(+__nx*__ny+1)  + VALUE(+__nx*__ny-__nx) + VALUE(+__nx*__ny+__nx);
-
-		s3= VALUE( - 2*__nx) + VALUE( - 2)       + VALUE( + 2) +
-			VALUE( + 2*__nx) + VALUE( - 2*__nx*__ny) + VALUE( + 2*__nx*__ny);
-
-		*res2 = (*x2 + ((s3 + 2*s2 - 12*s1) * __lambda2 - __lambda1 * s1) * *sc2);
-    }
-
-}
-
-
-#define VALUE2(o) ((bord2[o])?0:x2[o])
-
-void solve_sCG::multA_float(float *x, float *result) {
-
-    bool *bord2;
-    float *x2, *res2;
-
-    for(unsigned long i = 0; i < __count; i++) {
-
-       double s1, s2, s3;
-
-       bord2 = __border + i;
-       res2  = result + i;
-       x2    = x + i;
-
-       if (*bord2) {
-	       *res2 = (__weight_imagePtr[i] + 6*__lambda1 + 42*__lambda2) * *x2;
-	       continue;
-       }
-
-       s1 = VALUE2(-__nx)    + VALUE2(-1) + VALUE2(+1) + VALUE2(+__nx) +
-    	    VALUE2(-__nx*__ny) + VALUE2(+__nx*__ny);
-
-       s2= VALUE2(-__nx-1)     + VALUE2(-__nx+1)	 + VALUE2(+__nx-1)     + VALUE2(+__nx+1)	+
-    	   VALUE2(-__nx*__ny-1)  + VALUE2(-__nx*__ny+1)  + VALUE2(-__nx*__ny-__nx) + VALUE2(-__nx*__ny+__nx) +
-    	   VALUE2(+__nx*__ny-1)  + VALUE2(+__nx*__ny+1)  + VALUE2(+__nx*__ny-__nx) + VALUE2(+__nx*__ny+__nx);
-
-       s3= VALUE2( - 2*__nx) + VALUE2( - 2)	+ VALUE2( + 2) +
-    	   VALUE2( + 2*__nx) + VALUE2( - 2*__nx*__ny) + VALUE2( + 2*__nx*__ny);
-
-       *res2 = (__weight_imagePtr[i] + 6*__lambda1+42*__lambda2) * *x2
-    	       + ((s3 + 2*s2 - 12*s1) * __lambda2 - __lambda1 * s1);
-
-    }
-}
-
-
-// loest die PDE  (w + __lambda1 * H1 + __lambda2 * H2)*m = f
-void solve_sCG::init()
-{
-
-
-    if (!__b || !__v || !__scale || !__scale2 || !__border)
-	    throw runtime_error("not enough memory");
-
-
-    // set b and scaling
-    for(unsigned long i = 0; i < __count; i++) {
-		__border[i] = (fborder(i, __nx, __ny, __nz)? 1 : 0);
-	}
-
-	for(unsigned long i = 0; i < __count; i++) {
-        // Wenn Element Randelement ist, setze b entsprechend
-       	if (__border[i]) {
-    	    __b[i] = -__gain_image_ptr[i];
-    	    __scale[i] = 1.0;
-    	    __scale2[i] = 0;
-    	    __v[i] = __gain_image_ptr[i] / __scale[i];
-    	    continue;
-		}
-
-       // set b[i]
-       __b[i] = -__fptr[i];
-
-       // ziehe Anteile aus Randelementen ab
-
-       // scaling
-       __scale[i] = __scale2[i] = 1.0 / sqrt(__weight_imagePtr[i] + 6*__lambda1 + 42*__lambda2);
-       __b[i] *= __scale[i];
-       __v[i] = __gain_image_ptr[i] / __scale[i];
-	}
-
-    return;
-}
-
-
-void solve_sCG::get_solution(C3DFImage& m) {
-
-  C3DFImage::iterator __gain_image_ptr = m.begin();
-  for(unsigned long i = 0; i < __count; i++, ++__gain_image_ptr)
-    *__gain_image_ptr = (float)__v[i] * __scale[i];
-
-  return;
-}
-
-
-void solve_sCG::add_to_solution(C3DFImage *e) {
-
-  C3DFImage::iterator eptr = e->begin();
-
-  for(unsigned long i = 0; i < __count; i++)
-    __v[i] += eptr[i] / __scale[i];
-
-  return;
-}
-
-NS_MIA_END
diff --git a/mia/3d/fuzzyClusterSolverCG.hh b/mia/3d/fuzzyClusterSolverCG.hh
deleted file mode 100644
index aead47f..0000000
--- a/mia/3d/fuzzyClusterSolverCG.hh
+++ /dev/null
@@ -1,183 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef __SOLVERCG_HH
-#define __SOLVERCG_HH
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <mia/3d.hh>
-#include <cstdio>
-#include <stdexcept>
-#include <string>
-
-
-
-NS_MIA_BEGIN
-
-using namespace std;
-
-
-
-/*! 
-  @ingroup filtering 
-  \brief function defining field borders
-
-    \param index  index running from 0 to NoOfPixels
-    \param nx     no of pixels in x
-    \param ny     no of pixels in y
-    \param nz     no of pixels in z
-
-*/
-extern bool fborder (long index, long nx, long ny, long nz);
-
-/*! 
-  @ingroup filtering 
-  \brief a class providing a CG solver
-  
-  This contains basic solver functions based on CG schemes
-  
-  \author Stefan Burckhardt and Carsten Wolters, wolters at mis.mpg.de, 2004
-  \remark adapted for libmona by Heike Jaenicke and Marc Tittgemeyer, tittge at cbs.mpg.de, 2004
-  \remark adapted for mia2 by Gert Wollny, gw.fossdev at gmail.com 2011 
-*/
-
-
-class solve_sCG {
-
-  private:
-
-	double __lambda1;
-	double __lambda2;
-
-	// Dimension of images
-	long __iter;
-	unsigned int  __nx, __ny, __nz;
-	unsigned long __count;
-
-	// Pointer to Elements of w
-	float *__weight_imagePtr;
-	float *__fptr;
-	float *__gain_image_ptr;
-
-
-
-	// b and x for solution of system
-	double *__b;
-	double *__v;
-
-	// counts iterations
-
-
-	// help pointers for one iteration cycle
-	double *__r;	   // r^(k)
-	double *__rho;     // p^(k)
-	double *__g;
-	double *__Ag;	   // speichert A * p
-	// Field of scaling factors
-	double *__scale;
-	double *__scale2;
-
-	// field for border voxels
-	bool *__border;
-
-
-	double __r1rho1;   // speichert r1 * rho1
-	double __r2rho2;   // speichert r2 * rho2
-	double __normr0;
-	double __q, __e, __sprod;
-
-	// minimal residuum
-	double __min_res, __relres;
-
-	/** function for initialising
-         */
-        void init();
-
-  public:
-	/** constructor
-	    \param w1
-	    \param f1
-	    \param g1
-	    \param l1
-	    \param l2
-	    \param r_res
-	    \param m_res
-	 */
-	solve_sCG (C3DFImage& w1, C3DFImage&  f1, C3DFImage& g1, double l1, double l2, double r_res, double m_res);
-
-	~solve_sCG();
-
-	/** Function to solve ...
-	    \param max_iterations Maximum number of iterations
-	    \param firstnormr0
-	    \returns
-	 */
-	int solve(long max_iterations, double *firstnormr0);
-
-	/** Function to get preset number of iterations
-	    \returns Number of iterations
-	 */
-	inline long get_iterations() {return __iter;}
-
-	/** Multiplication of vector and matrix
-
-	TODO mit standard classe Austauschen
-
-	    \param x
-	    \param result
-	    \param start
-	    \param ende
-	 */
-	void multA(double *x, double *result, long start, long ende);
-
-	/** Multiplication
-
-	TODO mit standard classe Austauschen
-
-	    \param x Pointer at
-	    \param result Pointer at
-	 */
-	void multA_float(float *x, float *result);
-
-	/**
-	    \param gain Image with gain-field
-	 */
-	void get_solution(C3DFImage& gain);
-
-	/**
-	    \param e
-	 */
-	void add_to_solution(C3DFImage *e);
-
-	/** function for parallel solver
-	    @param max_iteration
-	    @param normr
-	    @param firstnormr0
-	 */
-	void solvepar(long *max_iteration, double *normr, double *firstnormr0);
-
-};
-
-NS_MIA_END
-
-#endif
diff --git a/mia/3d/fuzzyclustersolver_cg.cc b/mia/3d/fuzzyclustersolver_cg.cc
new file mode 100644
index 0000000..e04ab33
--- /dev/null
+++ b/mia/3d/fuzzyclustersolver_cg.cc
@@ -0,0 +1,366 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <cstring>
+
+#include <mia/3d/fuzzyclustersolver_cg.hh>
+
+NS_MIA_BEGIN
+// this needs to be tested
+bool fborder (long index, long nx, long ny, long nz)
+{
+	const long x = index % nx;
+
+	if ( x < 2 || x > nx-3 )
+	     return true;
+
+	index /= nx;
+
+	const long y = index % ny;
+	if ( y < 2 || y > ny-3 )
+	     return true;
+
+	index /= nx;
+
+	const long z = index / ny;
+	if ( z < 2 || z > nz-3 )
+	     return true;
+
+	return false;
+
+}
+
+
+
+solve_sCG::solve_sCG (C3DFImage& w1, C3DFImage& f1, C3DFImage& gain_image, double l1, double l2, double r_res, double m_res):
+	__lambda1(l1),
+	__lambda2(l2),
+	__iter(0),
+	__nx(w1.get_size().x),
+	__ny(w1.get_size().y),
+	__nz(w1.get_size().z),
+	__count(__nz*__ny*__nx),
+	__weight_imagePtr(&w1(0, 0, 0)),
+	__fptr(&f1(0, 0, 0)),
+	__gain_image_ptr(&gain_image(0, 0, 0)),
+
+	__b(new double[__count]),
+	__v(new double[__count]),
+	__r(new double[__count]),
+
+	__rho(new double[__count]),   // p^(k)
+	__g(new double[__count]),
+	__Ag(new double[__count]),   // speichert A * p
+
+	__scale(new double[__count]),
+	__scale2(new double[__count]),
+	__border(new bool[__count]),
+
+	__r1rho1(0.0), 
+	__r2rho2(0.0),
+	 __normr0(0.0),
+	__q(0.0), 
+	__e(0.0),
+	__sprod(0.0),
+
+	__min_res(m_res),
+	__relres(r_res)
+
+{
+	init ();
+
+}
+
+
+solve_sCG::~solve_sCG()
+{
+  delete[] __b;
+  delete[] __v;
+  delete[] __scale;
+  delete[] __scale2;
+  delete[] __border;
+
+  // free pointers
+  delete[] __r;
+  delete[] __rho;
+  delete[] __g;
+  delete[] __Ag;
+}
+
+
+
+// Umweg, da keine Methoden parallel aufgerufen werden koennen
+void solver(solve_sCG *s, long *maxit, double *normr, double *firstnormr0)
+{
+    s->solvepar(maxit, normr, firstnormr0);
+}
+
+
+int solve_sCG::solve(long max_iterations, double *firstnormr0) {
+
+        double normr;
+
+#ifdef PARALLEL
+    	m_set_procs(NPROCS);
+    	m_fork((void (*)())solver, this, &max_iterations, &normr,firstnormr0);
+    	m_kill_procs();
+#else
+    	solver(this, &max_iterations, &normr,firstnormr0);
+#endif
+
+	return normr > 1;
+}
+
+
+// loest das Gleichungssystem mittels CG-Algorithmus
+void solve_sCG::solvepar(long *maxit, double *normr, double *firstnormr0) {
+
+    // Prozessornummer
+    int me;
+
+    // Start und Ende fuer Vektoroperationen
+    long start;
+    long ende;
+
+    // Setze me, start und ende
+    me = 0;
+    start = 0;
+    ende = __count;
+
+    // Initialisierung
+    multA(__v, __r, start, ende);
+
+    // Berechnung normr0;
+    double tmp_normr0 = 0;
+    for(long i = start; i < ende; i++) {
+      __r[i] += __b[i];
+      double square = __r[i]/__scale[i];
+      tmp_normr0 += square*square;
+    }
+
+    __normr0 = tmp_normr0;
+
+    if (me == 0)
+	    *normr = __normr0 = sqrt(__normr0);
+
+
+    if (*firstnormr0 == 1.0 && __normr0 > 1.0)
+	    *firstnormr0 = __normr0;
+
+
+    // Iterationen
+    while (*normr >= __min_res && __iter < *maxit && *normr / *firstnormr0 > __relres){
+
+    	if (me == 0) {
+	  		__iter++;
+	  		memcpy(__rho, __r, __count * sizeof(double));
+	  		__r2rho2 = __r1rho1;
+        }
+
+
+	// r1rho1 = r * rho
+	if (me == 0) __r1rho1 = 0;
+
+	double tmp_r1rho1 = 0;
+	for(long i = start; i < ende; i++) {
+	  tmp_r1rho1 += __r[i] * __rho[i];
+	}
+
+	__r1rho1 = tmp_r1rho1;
+
+	if (__iter >= 2 && me == 0) __e = __r1rho1 / __r2rho2; else __e = 0;
+
+	for(long i = start; i < ende; i++) __g[i] = -__rho[i] + __e * __g[i];
+
+	multA(__g, __Ag, start, ende);
+
+	// q = r1rho1 / (g * Ag)
+	if (me == 0) __sprod = 0;
+	double tmp_sprod = 0;
+
+	for(long i = start; i < ende; i++) tmp_sprod += __g[i] * __Ag[i];
+
+	__sprod = tmp_sprod;
+
+	if (me == 0) __q = __r1rho1 / __sprod;
+
+	// v = v1 + q * g, r = r1 + q * Ag
+	if (me == 0) *normr = 0;
+	double tmp_normr = 0;
+
+	for(long i = start; i < ende; i++) {
+
+	  __v[i] += __q * __g[i];
+	  __r[i] += __q * __Ag[i];
+	  tmp_normr += pow(__r[i]/__scale[i], 2);
+
+	}
+
+	*normr = tmp_normr;
+
+	if (me == 0)
+		*normr = sqrt(*normr);
+
+	//*\todo implement some progression alert here */
+
+    }
+
+    return;
+ }
+
+
+// Vektor-Matrix-Multiplikation
+#define VALUE(o) (sc2[o] * x2[o])
+
+void solve_sCG::multA(double *x, double *result, long start, long ende) {
+
+    long i;
+    bool *bord2;
+    double *x2, *sc2, *res2;
+
+    for(i = start; i < ende; i++) {
+
+		double s1, s2, s3;
+
+		bord2 = &__border[i];
+		res2  = &result[i];
+
+		x2    = &x[i];
+
+		if (*bord2) {
+			*res2 = *x2;
+			continue;
+		}
+
+		sc2 = &__scale2[i];
+
+		s1= VALUE(-__nx)    + VALUE(-1) + VALUE(+1) + VALUE(+__nx) +
+			VALUE(-__nx*__ny) + VALUE(+__nx*__ny);
+
+		s2= VALUE(-__nx-1)     + VALUE(-__nx+1)	+ VALUE(+__nx-1)     + VALUE(+__nx+1)    +
+			VALUE(-__nx*__ny-1)  + VALUE(-__nx*__ny+1)  + VALUE(-__nx*__ny-__nx) + VALUE(-__nx*__ny+__nx) +
+			VALUE(+__nx*__ny-1)  + VALUE(+__nx*__ny+1)  + VALUE(+__nx*__ny-__nx) + VALUE(+__nx*__ny+__nx);
+
+		s3= VALUE( - 2*__nx) + VALUE( - 2)       + VALUE( + 2) +
+			VALUE( + 2*__nx) + VALUE( - 2*__nx*__ny) + VALUE( + 2*__nx*__ny);
+
+		*res2 = (*x2 + ((s3 + 2*s2 - 12*s1) * __lambda2 - __lambda1 * s1) * *sc2);
+    }
+
+}
+
+
+#define VALUE2(o) ((bord2[o])?0:x2[o])
+
+void solve_sCG::multA_float(float *x, float *result) {
+
+    bool *bord2;
+    float *x2, *res2;
+
+    for(unsigned long i = 0; i < __count; i++) {
+
+       double s1, s2, s3;
+
+       bord2 = __border + i;
+       res2  = result + i;
+       x2    = x + i;
+
+       if (*bord2) {
+	       *res2 = (__weight_imagePtr[i] + 6*__lambda1 + 42*__lambda2) * *x2;
+	       continue;
+       }
+
+       s1 = VALUE2(-__nx)    + VALUE2(-1) + VALUE2(+1) + VALUE2(+__nx) +
+    	    VALUE2(-__nx*__ny) + VALUE2(+__nx*__ny);
+
+       s2= VALUE2(-__nx-1)     + VALUE2(-__nx+1)	 + VALUE2(+__nx-1)     + VALUE2(+__nx+1)	+
+    	   VALUE2(-__nx*__ny-1)  + VALUE2(-__nx*__ny+1)  + VALUE2(-__nx*__ny-__nx) + VALUE2(-__nx*__ny+__nx) +
+    	   VALUE2(+__nx*__ny-1)  + VALUE2(+__nx*__ny+1)  + VALUE2(+__nx*__ny-__nx) + VALUE2(+__nx*__ny+__nx);
+
+       s3= VALUE2( - 2*__nx) + VALUE2( - 2)	+ VALUE2( + 2) +
+    	   VALUE2( + 2*__nx) + VALUE2( - 2*__nx*__ny) + VALUE2( + 2*__nx*__ny);
+
+       *res2 = (__weight_imagePtr[i] + 6*__lambda1+42*__lambda2) * *x2
+    	       + ((s3 + 2*s2 - 12*s1) * __lambda2 - __lambda1 * s1);
+
+    }
+}
+
+
+// loest die PDE  (w + __lambda1 * H1 + __lambda2 * H2)*m = f
+void solve_sCG::init()
+{
+
+
+    if (!__b || !__v || !__scale || !__scale2 || !__border)
+	    throw runtime_error("not enough memory");
+
+
+    // set b and scaling
+    for(unsigned long i = 0; i < __count; i++) {
+		__border[i] = (fborder(i, __nx, __ny, __nz)? 1 : 0);
+	}
+
+	for(unsigned long i = 0; i < __count; i++) {
+        // Wenn Element Randelement ist, setze b entsprechend
+       	if (__border[i]) {
+    	    __b[i] = -__gain_image_ptr[i];
+    	    __scale[i] = 1.0;
+    	    __scale2[i] = 0;
+    	    __v[i] = __gain_image_ptr[i] / __scale[i];
+    	    continue;
+		}
+
+       // set b[i]
+       __b[i] = -__fptr[i];
+
+       // ziehe Anteile aus Randelementen ab
+
+       // scaling
+       __scale[i] = __scale2[i] = 1.0 / sqrt(__weight_imagePtr[i] + 6*__lambda1 + 42*__lambda2);
+       __b[i] *= __scale[i];
+       __v[i] = __gain_image_ptr[i] / __scale[i];
+	}
+
+    return;
+}
+
+
+void solve_sCG::get_solution(C3DFImage& m) {
+
+  C3DFImage::iterator __gain_image_ptr = m.begin();
+  for(unsigned long i = 0; i < __count; i++, ++__gain_image_ptr)
+    *__gain_image_ptr = (float)__v[i] * __scale[i];
+
+  return;
+}
+
+
+void solve_sCG::add_to_solution(C3DFImage *e) {
+
+  C3DFImage::iterator eptr = e->begin();
+
+  for(unsigned long i = 0; i < __count; i++)
+    __v[i] += eptr[i] / __scale[i];
+
+  return;
+}
+
+NS_MIA_END
diff --git a/mia/3d/fuzzyclustersolver_cg.hh b/mia/3d/fuzzyclustersolver_cg.hh
new file mode 100644
index 0000000..d8153b3
--- /dev/null
+++ b/mia/3d/fuzzyclustersolver_cg.hh
@@ -0,0 +1,183 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef __SOLVERCG_HH
+#define __SOLVERCG_HH
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <mia/3d.hh>
+#include <cstdio>
+#include <stdexcept>
+#include <string>
+
+
+
+NS_MIA_BEGIN
+
+using namespace std;
+
+
+
+/*! 
+  @ingroup filtering 
+  \brief function defining field borders
+
+    \param index  index running from 0 to NoOfPixels
+    \param nx     no of pixels in x
+    \param ny     no of pixels in y
+    \param nz     no of pixels in z
+
+*/
+extern bool fborder (long index, long nx, long ny, long nz);
+
+/*! 
+  @ingroup filtering 
+  \brief a class providing a CG solver
+  
+  This contains basic solver functions based on CG schemes
+  
+  \author Stefan Burckhardt and Carsten Wolters, wolters at mis.mpg.de, 2004
+  \remark adapted for libmona by Heike Jaenicke and Marc Tittgemeyer, tittge at cbs.mpg.de, 2004
+  \remark adapted for mia2 by Gert Wollny, gw.fossdev at gmail.com 2011 
+*/
+
+
+class solve_sCG {
+
+  private:
+
+	double __lambda1;
+	double __lambda2;
+
+	// Dimension of images
+	long __iter;
+	unsigned int  __nx, __ny, __nz;
+	unsigned long __count;
+
+	// Pointer to Elements of w
+	float *__weight_imagePtr;
+	float *__fptr;
+	float *__gain_image_ptr;
+
+
+
+	// b and x for solution of system
+	double *__b;
+	double *__v;
+
+	// counts iterations
+
+
+	// help pointers for one iteration cycle
+	double *__r;	   // r^(k)
+	double *__rho;     // p^(k)
+	double *__g;
+	double *__Ag;	   // speichert A * p
+	// Field of scaling factors
+	double *__scale;
+	double *__scale2;
+
+	// field for border voxels
+	bool *__border;
+
+
+	double __r1rho1;   // speichert r1 * rho1
+	double __r2rho2;   // speichert r2 * rho2
+	double __normr0;
+	double __q, __e, __sprod;
+
+	// minimal residuum
+	double __min_res, __relres;
+
+	/** function for initialising
+         */
+        void init();
+
+  public:
+	/** constructor
+	    \param w1
+	    \param f1
+	    \param g1
+	    \param l1
+	    \param l2
+	    \param r_res
+	    \param m_res
+	 */
+	solve_sCG (C3DFImage& w1, C3DFImage&  f1, C3DFImage& g1, double l1, double l2, double r_res, double m_res);
+
+	~solve_sCG();
+
+	/** Function to solve ...
+	    \param max_iterations Maximum number of iterations
+	    \param firstnormr0
+	    \returns
+	 */
+	int solve(long max_iterations, double *firstnormr0);
+
+	/** Function to get preset number of iterations
+	    \returns Number of iterations
+	 */
+	inline long get_iterations() {return __iter;}
+
+	/** Multiplication of vector and matrix
+
+	TODO mit standard classe Austauschen
+
+	    \param x
+	    \param result
+	    \param start
+	    \param ende
+	 */
+	void multA(double *x, double *result, long start, long ende);
+
+	/** Multiplication
+
+	TODO mit standard classe Austauschen
+
+	    \param x Pointer at
+	    \param result Pointer at
+	 */
+	void multA_float(float *x, float *result);
+
+	/**
+	    \param gain Image with gain-field
+	 */
+	void get_solution(C3DFImage& gain);
+
+	/**
+	    \param e
+	 */
+	void add_to_solution(C3DFImage *e);
+
+	/** function for parallel solver
+	    @param max_iteration
+	    @param normr
+	    @param firstnormr0
+	 */
+	void solvepar(long *max_iteration, double *normr, double *firstnormr0);
+
+};
+
+NS_MIA_END
+
+#endif
diff --git a/mia/3d/fuzzyseg.cc b/mia/3d/fuzzyseg.cc
index c7cf081..c7155ee 100644
--- a/mia/3d/fuzzyseg.cc
+++ b/mia/3d/fuzzyseg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@
 
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/histogram.hh>
-#include <mia/3d/fuzzyClusterSolverCG.hh>
+#include <mia/3d/fuzzyclustersolver_cg.hh>
 #include <mia/3d/fuzzyseg.hh>
 
 NS_MIA_BEGIN
diff --git a/mia/3d/fuzzyseg.hh b/mia/3d/fuzzyseg.hh
index 2c38934..ab6ddac 100644
--- a/mia/3d/fuzzyseg.hh
+++ b/mia/3d/fuzzyseg.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/ica.cc b/mia/3d/ica.cc
index 39c4fb2..609ddb9 100644
--- a/mia/3d/ica.cc
+++ b/mia/3d/ica.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/ica.hh b/mia/3d/ica.hh
index b5494ab..b36ee06 100644
--- a/mia/3d/ica.hh
+++ b/mia/3d/ica.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/image.cc b/mia/3d/image.cc
index bc8af88..75ccc25 100644
--- a/mia/3d/image.cc
+++ b/mia/3d/image.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -47,22 +47,95 @@ EPixelType C3DImage::get_pixel_type() const
 	return m_pixel_type;
 }
 
-
 E3DImageOrientation C3DImage::get_orientation() const
 {
-	const PAttribute orattr = get_attribute("orientation");
-	const C3DImageOrientation *orient = dynamic_cast<const C3DImageOrientation *>(orattr.get());
-	if (!orient)
-		return ior_unknown;
-	else
-		return *orient;
+	E3DImageOrientation axis_orientation = ior_default; 
+	const PAttribute attr = get_attribute("orientation");
+	if (attr) {
+		auto op = dynamic_cast<const TAttribute<E3DImageOrientation> *>(attr.get());
+		if (!op) {
+			cvwarn() << "C3DImage::get_orientation: Bogus orientation attribute, return default\n"; 
+		}else {
+			axis_orientation = *op; 
+		}
+	}
+	return axis_orientation; 
 }
 
 void C3DImage::set_orientation(E3DImageOrientation orient)
 {
-	set_attribute("orientation", PAttribute(new C3DImageOrientation(orient)));
+	set_attribute("orientation", PAttribute(new TAttribute<E3DImageOrientation>(orient)));
+}
+
+void C3DImage::set_voxel_size(const C3DFVector& voxel)
+{
+	set_attribute("voxel", PAttribute(new CVoxelAttribute(voxel)));
 }
 
+C3DFVector C3DImage::get_voxel_size() const
+{
+	const PAttribute attr = get_attribute("voxel");
+	if (!attr) {
+		cvinfo() << "T3DImage<T>::get_voxel_size(): voxel size not defined, default to <1,1,1>\n";
+		return C3DFVector::_1;
+	}
+
+	const CVoxelAttribute * vs = dynamic_cast<const CVoxelAttribute *>(attr.get());
+	if (!vs){
+		cvinfo() << "T3DImage<T>::get_voxel_size(): voxel size wrong type, default to <1,1,1>\n";
+		return C3DFVector::_1;
+	}
+
+	return *vs;
+}
+
+
+C3DFVector C3DImage::get_origin() const 
+{
+	const PAttribute attr = get_attribute("origin3d");
+	if (!attr) {
+		cvinfo() << "T3DImage<T>::get_origin(): Origin size not defined, default to <0,0,0>\n";
+		return C3DFVector::_0;
+	}
+
+	const CVoxelAttribute * vs = dynamic_cast<const CVoxelAttribute *>(attr.get());
+	if (!vs){
+		cvinfo() << "T3DImage<T>::get_origin(): origin attribute of wrong type, default to <0,0,0>\n";
+		return C3DFVector::_0;
+	}
+
+	return *vs;
+}
+
+void C3DImage::set_origin(const C3DFVector& voxel) 
+{
+	set_attribute("origin3d", PAttribute(new CVoxelAttribute(voxel)));
+}
+
+
+C3DRotation C3DImage::get_rotation() const
+{
+	const PAttribute attr = get_attribute("rotation3d");
+	if (!attr) {
+		cvinfo() << "T3DImage<T>::get_rotation(): Rotation size not defined, default to no rotation\n";
+		return C3DRotation::_1;
+	}
+	
+	const C3DRotationAttribute * vs = dynamic_cast<const C3DRotationAttribute *>(attr.get());
+	if (!vs){
+		cvinfo() << "T3DImage<T>::get_rotation(): Rotation attribute is of wrong type, default to no rotation\n";
+		return C3DRotation::_1;
+	}
+	return *vs;
+}
+
+void C3DImage::set_rotation(const C3DRotation& rot)
+{
+	set_attribute("rotation3d", PAttribute(new C3DRotationAttribute(rot)));
+}
+
+
+
 template <typename T>
 T3DImage<T>::T3DImage(const C3DBounds& size, const T* init_data):
 	C3DImage((EPixelType)pixel_type<T>::value),
@@ -71,6 +144,14 @@ T3DImage<T>::T3DImage(const C3DBounds& size, const T* init_data):
 }
 
 template <typename T>
+T3DImage<T>::T3DImage(const C3DBounds& size, const data_array& init_data):
+	C3DImage((EPixelType)pixel_type<T>::value),
+	m_image(size, init_data)
+{
+}
+
+
+template <typename T>
 T3DImage<T>::T3DImage(const C3DBounds& size, const CAttributedData& attr):
 	C3DImage(attr, (EPixelType)pixel_type<T>::value),
 	m_image(size)
@@ -205,30 +286,6 @@ const C3DBounds& T3DImage<T>::get_size() const
 	return m_image.get_size();
 }
 
-template <class T>
-void T3DImage<T>::set_voxel_size(const C3DFVector& voxel)
-{
-	set_attribute("voxel", PAttribute(new CVoxelAttribute(voxel)));
-}
-
-template <class T>
-C3DFVector T3DImage<T>::get_voxel_size() const
-{
-	const PAttribute attr = get_attribute("voxel");
-	if (!attr) {
-		cvinfo() << "T3DImage<T>::get_voxel_size(): voxel size not defined, default to <1,1,1>\n";
-		return C3DFVector(1,1,1);
-	}
-
-	const CVoxelAttribute * vs = dynamic_cast<const CVoxelAttribute *>(attr.get());
-	if (!vs){
-		cvinfo() << "T3DImage<T>::get_voxel_size(): voxel size wrong type, default to <1,1,1>\n";
-		return C3DFVector(1,1,1);
-	}
-
-	return *vs;
-
-}
 
 struct FGetGradient3D: public TFilter< C3DFVectorfield> {
 	template <typename T>
@@ -418,10 +475,14 @@ PAttribute C3DValueAttributeTranslator<T>::do_from_string(const std::string& val
 }
 
 template <typename T>
-void C3DValueAttributeTranslator<T>::register_for(const std::string& key)
+bool C3DValueAttributeTranslator<T>::register_for(const std::string& key)
 {
-	static C3DValueAttributeTranslator me;
-	me.do_register(key);
+	C3DValueAttributeTranslator *me = new C3DValueAttributeTranslator();
+	if (!me->do_register(key)) {
+		return false; 
+		delete me; 
+	}
+	return true; 
 }
 
 template class C3DValueAttribute<float>;
@@ -429,5 +490,4 @@ template class  EXPORT_3D C3DValueAttributeTranslator<float>;
 template class  EXPORT_3D C3DValueAttribute<int>;
 template class  EXPORT_3D C3DValueAttributeTranslator<int>;
 
-
 NS_MIA_END
diff --git a/mia/3d/image.hh b/mia/3d/image.hh
index e0aee9e..fb308ac 100644
--- a/mia/3d/image.hh
+++ b/mia/3d/image.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,14 +18,16 @@
  *
  */
 
-#ifndef mia_3d_3dimage_hh
-#define mia_3d_3dimage_hh
+#ifndef mia_3d_image_hh
+#define mia_3d_image_hh
 
 #include <mia/3d/vectorfield.hh>
 #include <mia/3d/orientation.hh>
+#include <mia/3d/rot.hh>
+
 #include <mia/2d/image.hh>
 
-#include <mia/core/attributes.hh>
+#include <mia/3d/valueattributetranslator.hh>
 #include <mia/core/pixeltype.hh>
 #include <mia/core/filter.hh>
 
@@ -92,11 +94,24 @@ public:
 	virtual Pointer clone() const = 0;
 
 	///  \returns the voxel size in world units
-
-	virtual C3DFVector get_voxel_size() const = 0;
+	C3DFVector get_voxel_size() const;
 
 	/// set the voxel size on world units
-	virtual void set_voxel_size(const C3DFVector& voxel) = 0;
+	void set_voxel_size(const C3DFVector& voxel);
+
+
+	///  \returns the origin i.e. world units of the pixel at (0,0,0)
+	C3DFVector get_origin() const;
+
+	/// set the origin i.e. world units  of the pixel at (0,0,0)
+	void set_origin(const C3DFVector& voxel);
+	
+
+	///  \returns the rotation about the origin of the image 
+	C3DRotation get_rotation() const;
+
+	/// set the rotation about the origin of the image 
+	void set_rotation(const C3DRotation& voxel);
 
 	///@returns the orientation of the image 
 	E3DImageOrientation get_orientation() const;
@@ -142,6 +157,10 @@ public:
 	typedef typename T3DDatafield<T>::size_type size_type;
 	typedef typename T3DDatafield<T>::range_iterator range_iterator; 
 	typedef typename T3DDatafield<T>::const_range_iterator const_range_iterator; 
+	typedef typename T3DDatafield<T>::range_iterator_with_boundary_flag range_iterator_with_boundary_flag; 
+	typedef typename T3DDatafield<T>::const_range_iterator_with_boundary_flag const_range_iterator_with_boundary_flag; 
+
+	typedef	typename T2DDatafield<T>::data_array data_array;
 	/// \endcond
 	
 	/**
@@ -157,6 +176,9 @@ public:
 	   \param attr
 	 */
 	T3DImage(const C3DBounds& size, const CAttributedData& attr);
+
+
+	T3DImage(const C3DBounds& size, const data_array& init_data); 
 	/**
 	   Construct a new image of a given size
 	   \param size
@@ -323,12 +345,6 @@ public:
 	/// \returns the 3D size of the image
 	virtual const C3DBounds& get_size() const;
 
-	/// \returns the physical voxel size 
-	virtual C3DFVector get_voxel_size() const;
-
-	/// set the voxel size on world units
-	virtual void set_voxel_size(const C3DFVector& voxel);
-
 private:
 	T3DDatafield<T> m_image;
 };
@@ -450,74 +466,6 @@ struct Binder<C3DImage> {
 
 /// @endcond
 
-/**
-   @ingroup basic 
-   @brief a translater for 3D vectors to and from a std::string
-*/
-template <typename T>
-class EXPORT_3D C3DValueAttributeTranslator: public CAttrTranslator {
-public:
-	static  void register_for(const std::string& key);
-private:
-	PAttribute do_from_string(const std::string& value) const;
-};
-
-/**
-   @ingroup basic 
-   @brief a 3D vector value used in attributes 
-   @tparam T the data type of the vector elements 
-*/
-template <typename T>
-class EXPORT_3D C3DValueAttribute : public CAttribute {
-public:
-
-	/**
-	   Constructor to initialize the attribute by using a 3D Vector value 
-	   @param value 
-	 */
-	C3DValueAttribute(const T3DVector<T>& value);
-	
-	/// \returns the value of the attribute as 3D vector 
-	operator T3DVector<T>()const;
-
-	/**
-	   Obtain a run-time unique type description of the value type 
-	   @returns the typeid of the T3DVector<T>
-	 */
-	const char *typedescr() const	{
-		return typeid(T3DVector<T>).name();
-	}
-private:
-	std::string do_as_string() const;
-	bool do_is_equal(const CAttribute& other) const;
-	bool do_is_less(const CAttribute& other) const;
-	T3DVector<T> m_value;
-};
-
-/**
-   @ingroup basic 
-   @brief a 3D floating point vector used for the voxel size attribute 
-*/
-typedef C3DValueAttribute<float> CVoxelAttribute;
-
-/**
-   @ingroup basic 
-   @brief attribute translator for a 3D floating point vector used for the voxel size
-*/
-typedef C3DValueAttributeTranslator<float> CVoxelAttributeTranslator;
-
-/**
-   @ingroup basic 
-   @brief a 3D integer vector
-*/
-typedef C3DValueAttribute<int> C3DIntAttribute;
-
-/**
-   @ingroup basic 
-   @brief attribute translator for a 3D integer vector
-*/
-typedef C3DValueAttributeTranslator<int> C3DIntAttributeTranslator;
-
 NS_MIA_END
 
 #endif
diff --git a/mia/3d/imagecollect.cc b/mia/3d/imagecollect.cc
index f199633..c06008e 100644
--- a/mia/3d/imagecollect.cc
+++ b/mia/3d/imagecollect.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/imagecollect.hh b/mia/3d/imagecollect.hh
index 2af31c6..2f7f978 100644
--- a/mia/3d/imagecollect.hh
+++ b/mia/3d/imagecollect.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/imageio.cc b/mia/3d/imageio.cc
index 8765977..1dac3ce 100644
--- a/mia/3d/imageio.cc
+++ b/mia/3d/imageio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -74,15 +74,6 @@ bool  EXPORT_3D save_image(const std::string& filename, C3DImage& image)
       return save_image(filename, P3DImage(&image, void_destructor<C3DImage>())); 
 }
 
-C3DImageIOPluginHandlerTestPath::C3DImageIOPluginHandlerTestPath()
-{
-	CPathNameArray searchpath;
-	searchpath.push_back(bfs::path(MIA_BUILD_ROOT"/mia/3d/io"));
-	C3DImageIOPluginHandler::set_search_path(searchpath);
-	
-}
-
-
 template class TIOPlugin<io_3dimage_data>;
 template class THandlerSingleton<TIOPluginHandler<C3DImageIOPlugin> >;
 template class TIOPluginHandler<C3DImageIOPlugin>;
diff --git a/mia/3d/imageio.hh b/mia/3d/imageio.hh
index 84ca5eb..02af158 100644
--- a/mia/3d/imageio.hh
+++ b/mia/3d/imageio.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -58,6 +58,12 @@ typedef TIOPlugin<io_3dimage_data> C3DImageIOPlugin;
 */
 typedef THandlerSingleton<TIOPluginHandler<C3DImageIOPlugin> > C3DImageIOPluginHandler;
 
+template <> 
+struct IOHandler_of<C3DImage> {
+	typedef C3DImageIOPluginHandler type;
+}; 
+
+
 /**
    @ingroup io
    @brief Data key type used to load and store to the CDatapool 
@@ -71,16 +77,6 @@ typedef C3DImageIOPluginHandler::Instance::DataKey C3DImageDataKey;
 typedef C3DImageIOPluginHandler::Instance::PData P3DImageVector;
 
 /** 
-    @cond INTERNAL 
-    @ingroup test 
-    @brief class to initialize the plug-in path for tests on the uninstalled library 
-*/
-struct EXPORT_3D C3DImageIOPluginHandlerTestPath {
-	C3DImageIOPluginHandlerTestPath(); 
-}; 
-/// @endcond
-
-/** 
     @ingroup convenience 
     convenience function to create an image vector from a single image 
     \param image 
diff --git a/mia/3d/imageiotest.cc b/mia/3d/imageiotest.cc
index bc54cce..74bf83c 100644
--- a/mia/3d/imageiotest.cc
+++ b/mia/3d/imageiotest.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/imageiotest.hh b/mia/3d/imageiotest.hh
index d50fb62..59c9171 100644
--- a/mia/3d/imageiotest.hh
+++ b/mia/3d/imageiotest.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/imagetest.cc b/mia/3d/imagetest.cc
new file mode 100644
index 0000000..b0a8731
--- /dev/null
+++ b/mia/3d/imagetest.cc
@@ -0,0 +1,95 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/type_traits.hh>
+#include <boost/test/unit_test.hpp>
+#include <mia/3d/imagetest.hh>
+
+NS_MIA_BEGIN
+using namespace boost;
+
+template <typename T, typename R>
+struct __compare {
+	static void apply(const T3DImage<T>& /*a*/, const T3DImage<R>& /*b*/) {
+		BOOST_FAIL("Image pixels have different type");
+	}
+};
+
+template <typename T, bool is_fp>
+struct __check_equal{
+	static void apply(T test, T expect) {
+		BOOST_CHECK_EQUAL(test, expect);
+	}
+};
+
+template <typename T>
+struct __check_equal<T, true>{
+	static void apply(T test, T expect) {
+		if (expect == 0.0) 
+			BOOST_CHECK_SMALL(test, static_cast<T>(1e-6));
+		else 
+			BOOST_CHECK_CLOSE(test, expect, 0.1);
+	}
+};
+
+template <typename T>
+struct __compare<T,T> {
+	static void apply(const T3DImage<T>& a, const T3DImage<T>& b) {
+		const bool is_fp = std::is_floating_point<T>::value;
+		typename T3DImage<T>::const_iterator ia = a.begin();
+		typename T3DImage<T>::const_iterator ie = a.end();
+		typename T3DImage<T>::const_iterator ib = b.begin();
+
+
+		while (ia != ie) {
+			__check_equal<T, is_fp>::apply(*ia, *ib);
+			++ia;
+			++ib;
+		}
+	}
+};
+
+class C3DImageCompare: public TFilter<bool>  {
+public:
+	template <typename  T, typename  S>
+	C3DImageCompare::result_type operator()(const T3DImage<T>& a, const T3DImage<S>& b) const
+	{
+		__compare<T, S>::apply(a,b);
+		return C3DImageCompare::result_type();
+	}
+};
+
+void  EXPORT_3D test_image_equal(const C3DImage& test, const C3DImage& expect)
+{
+	BOOST_CHECK_EQUAL(test.get_size(), expect.get_size());
+	BOOST_REQUIRE(test.get_size() == expect.get_size());
+
+	BOOST_CHECK_EQUAL(test.get_pixel_type(), expect.get_pixel_type());
+
+	C3DImageCompare c;
+	mia::filter(c, test, expect);
+
+	const CAttributedData& attr_test = test;
+	const CAttributedData& attr_expect = expect;
+
+	BOOST_CHECK(attr_test == attr_expect);
+}
+
+NS_MIA_END
diff --git a/mia/3d/imagetest.hh b/mia/3d/imagetest.hh
new file mode 100644
index 0000000..d789d95
--- /dev/null
+++ b/mia/3d/imagetest.hh
@@ -0,0 +1,45 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_imagetest_hh
+#define mia_3d_imagetest_hh
+
+#include <mia/3d/image.hh>
+
+NS_MIA_BEGIN
+
+/**
+   @ingroup test 
+   \brief test if two images are equal and report the results by using BOOST_TEST methods. 
+
+   Test if two images are ove equal size, equal pixel type and if their 
+   pixel values are equal if the pixel type is integral, or close 
+   if the pixel type is floating point. 
+   The backend uses the BOOST unit test library to report sucess or failture. 
+
+   @param A test image 
+   @param expect the expected image 
+   
+ */
+void EXPORT_3D test_image_equal(const C3DImage& A, const C3DImage& expect);
+
+NS_MIA_END
+
+#endif
diff --git a/mia/3d/interpolator.cc b/mia/3d/interpolator.cc
index a234568..4ccc080 100644
--- a/mia/3d/interpolator.cc
+++ b/mia/3d/interpolator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -496,8 +496,8 @@ float add_3d<T3DDatafield< float >, 4>::value(const T3DDatafield< float >&  coef
 #endif
 
 #define INSTANCIATE_INTERPOLATORS(TYPE)			\
-	template class T3DInterpolator<TYPE>;		\
-	template class T3DConvoluteInterpolator<TYPE>
+	template class EXPORT_3D T3DInterpolator<TYPE>;		\
+	template class EXPORT_3D T3DConvoluteInterpolator<TYPE>
 
 INSTANCIATE_INTERPOLATORS(bool);
 INSTANCIATE_INTERPOLATORS(unsigned char);
@@ -516,11 +516,11 @@ INSTANCIATE_INTERPOLATORS(unsigned long);
 INSTANCIATE_INTERPOLATORS(C3DFVector);
 INSTANCIATE_INTERPOLATORS(C3DDVector);
 
-template class T1DInterpolator<C3DFVector>;
-template class T1DConvoluteInterpolator<C3DFVector>;
+template class EXPORT_3D T1DInterpolator<C3DFVector>;
+template class EXPORT_3D T1DConvoluteInterpolator<C3DFVector>;
 
-template class T1DInterpolator<C3DDVector>;
-template class T1DConvoluteInterpolator<C3DDVector>;
+template class EXPORT_3D T1DInterpolator<C3DDVector>;
+template class EXPORT_3D T1DConvoluteInterpolator<C3DDVector>;
 
 
 NS_MIA_END
diff --git a/mia/3d/interpolator.cxx b/mia/3d/interpolator.cxx
index ac7ec39..4c82b5a 100644
--- a/mia/3d/interpolator.cxx
+++ b/mia/3d/interpolator.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -110,6 +110,10 @@ void T3DConvoluteInterpolator<T>::prefilter(const T3DDatafield<T>& image)
 	m_z_cache.reset(); 
 
 	min_max_3d<T>::get(image, &m_min, &m_max);
+	// we always allow that a pixel is set to zero
+	if (T() < m_min) 
+		m_min = T(); 
+
 	std::copy(image.begin(), image.end(), m_coeff.begin());
 
 
diff --git a/mia/3d/interpolator.hh b/mia/3d/interpolator.hh
index 4b2f838..c42e222 100644
--- a/mia/3d/interpolator.hh
+++ b/mia/3d/interpolator.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/io/CMakeLists.txt b/mia/3d/io/CMakeLists.txt
index ee105e3..8217af6 100644
--- a/mia/3d/io/CMakeLists.txt
+++ b/mia/3d/io/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/io/analyze.cc b/mia/3d/io/analyze.cc
index e06a0d7..b67ec66 100644
--- a/mia/3d/io/analyze.cc
+++ b/mia/3d/io/analyze.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -110,17 +110,17 @@ struct analyze_dsr
 #pragma pack()
 
 /* Acceptable values for datatype */
-#define DT_NONE                      0
-#define DT_UNKNOWN                   0
-#define DT_BINARY                    1
-#define DT_UNSIGNED_CHAR             2
-#define DT_SIGNED_SHORT              4
-#define DT_SIGNED_INT                8
-#define DT_FLOAT                     16
-#define DT_COMPLEX                   32
-#define DT_DOUBLE                    64
-#define DT_RGB                       128
-#define DT_ALL                       255
+#define DTA_NONE                      0
+#define DTA_UNKNOWN                   0
+#define DTA_BINARY                    1
+#define DTA_UNSIGNED_CHAR             2
+#define DTA_SIGNED_SHORT              4
+#define DTA_SIGNED_INT                8
+#define DTA_FLOAT                     16
+#define DTA_COMPLEX                   32
+#define DTA_DOUBLE                    64
+#define DTA_RGB                       128
+#define DTA_ALL                       255
 
 enum EAnaOrientation {
 	ao_transverse_unflipped = 0,
@@ -293,7 +293,7 @@ void swap_endian(T3DImage<T>& image)
 }
 
 
-template <typename T, bool flipped>
+template <typename T>
 struct do_read_image {
 	static C3DImage * apply(const C3DBounds& size, CInputFile& data_file, bool do_swap_endian) {
 		T3DImage<T> *result = new T3DImage<T>(size);
@@ -305,50 +305,19 @@ struct do_read_image {
 	}
 };
 
-template <typename T>
-struct do_read_image<T, true> {
-	static C3DImage * apply(const C3DBounds& size, CInputFile& data_file, bool do_swap_endian) {
-		T3DImage<T> *result = new T3DImage<T>(size);
-		for (size_t z = size.z; z > 0; --z)
-			if (fread(&(*result)(0,0,z - 1), sizeof(T), result->size(), data_file) != result->size())
-				throw runtime_error("Analyze: unable to read data");
-		if (do_swap_endian)
-			swap_endian(*result);
-		return result;
-	}
-};
-
-
-#if 0
-template <>
-struct do_read_image<bool> {
-	static C3DImage * apply(const C3DBounds& size, CInputFile& data_file, bool swap_endian) const {
-
-
-		T3DImage<bool> *result = new T3DImage<bool>(size);
-		if (fread(&(*result)(0,0,0), sizeof(T), result->size(), data_file) != result->size())
-			throw runtime_error("Analyze: unable to read data");
-		if (swap_endian)
-			swap_endian(*result);
-		return result;
-	}
-};
-
-#endif
 
-template <bool flipped>
 C3DImage *CAnalyze3DImageIOPlugin::read_image(const C3DBounds& size, short datatype, CInputFile& data_file) const
 {
 	if (datatype & 128)
 		cvwarn() << "Got an RGB indicator but I will ignore it\n";
 
 	switch (datatype & 0xFF) {
-//	case DT_BINARY       :return do_read_image<bool>::apply(size, data_file, m_swap_endian);
-	case DT_UNSIGNED_CHAR:return do_read_image<unsigned char, flipped>::apply(size, data_file, m_swap_endian);
-	case DT_SIGNED_SHORT :return do_read_image<signed short, flipped>::apply(size, data_file, m_swap_endian);
-	case DT_SIGNED_INT   :return do_read_image<signed int, flipped>::apply(size, data_file, m_swap_endian);
-	case DT_FLOAT        :return do_read_image<float, flipped>::apply(size, data_file, m_swap_endian);
-	case DT_DOUBLE       :return do_read_image<double, flipped>::apply(size, data_file, m_swap_endian);
+//	case DTA_BINARY       :return do_read_image<bool>::apply(size, data_file, m_swap_endian);
+	case DTA_UNSIGNED_CHAR:return do_read_image<unsigned char>::apply(size, data_file, m_swap_endian);
+	case DTA_SIGNED_SHORT :return do_read_image<signed short>::apply(size, data_file, m_swap_endian);
+	case DTA_SIGNED_INT   :return do_read_image<signed int>::apply(size, data_file, m_swap_endian);
+	case DTA_FLOAT        :return do_read_image<float>::apply(size, data_file, m_swap_endian);
+	case DTA_DOUBLE       :return do_read_image<double>::apply(size, data_file, m_swap_endian);
 	default:
 		stringstream msg;
 		msg << "Analyze: unsupported image type:" << datatype;
@@ -361,27 +330,27 @@ void set_typeinfo(analyze_image_dimension& dime, EPixelType pixel_type)
 {
 	switch (pixel_type) {
 	case it_ubyte:
-		dime.datatype = DT_UNSIGNED_CHAR;
+		dime.datatype = DTA_UNSIGNED_CHAR;
 		dime.bitpix   = 8;
 		break;
 
 	case it_sshort:
-		dime.datatype = DT_SIGNED_SHORT;
+		dime.datatype = DTA_SIGNED_SHORT;
 		dime.bitpix   = 16;
 		break;
 
 	case it_sint:
-		dime.datatype = DT_SIGNED_INT;
+		dime.datatype = DTA_SIGNED_INT;
 		dime.bitpix   = 32;
 		break;
 
 	case it_float:
-		dime.datatype = DT_FLOAT;
+		dime.datatype = DTA_FLOAT;
 		dime.bitpix   = 32;
 		break;
 
 	case it_double:
-		dime.datatype = DT_DOUBLE;
+		dime.datatype = DTA_DOUBLE;
 		dime.bitpix   = 64;
 		break;
 
@@ -459,19 +428,20 @@ CAnalyze3DImageIOPlugin::PData CAnalyze3DImageIOPlugin::do_load(const string&  f
 	while (num_img > 0) {
 		--num_img;
 		E3DImageOrientation orientation = ior_unknown;
-		bool unflipped = false;
 		switch ( hdr.hist.orient ) {
-		case ao_transverse_unflipped: unflipped = true;
-		case ao_transverse_flipped: orientation = ior_axial;
+		case ao_transverse_unflipped: orientation = ior_axial;
+			break; 
+		case ao_transverse_flipped: orientation = ior_axial_flipped;
 			break;
-		case ao_coronal_unflipped: unflipped = true;
-		case ao_coronal_flipped:    orientation = ior_coronal;
+		case ao_coronal_unflipped: orientation = ior_coronal;
+			break; 
+		case ao_coronal_flipped:   orientation = ior_coronal_flipped ;
 			break;
-		case ao_saggital_unflipped: unflipped = true;
-		case ao_saggital_flipped:    orientation = ior_saggital;
+		case ao_saggital_unflipped: orientation = ior_saggital;
+			break; 
+		case ao_saggital_flipped:   orientation = ior_saggital_flipped;
 			break;
 		default:
-			unflipped = true;
 			orientation = ior_unknown;
 		}
 		if (voffset < 0) {
@@ -479,12 +449,7 @@ CAnalyze3DImageIOPlugin::PData CAnalyze3DImageIOPlugin::do_load(const string&  f
 				throw create_exception<runtime_error>("Analyze: unable seek in data file '", 
 							      data_file_name, "':", strerror(errno) );
 		}
-		C3DImage *img = unflipped ?
-			read_image<false>(size, hdr.dime.datatype , data_file)
-			:
-			read_image<true>(size, hdr.dime.datatype , data_file);
-
-		P3DImage image(img);
+		P3DImage image(read_image(size, hdr.dime.datatype , data_file));
 		image->set_voxel_size(voxel);
 		image->set_orientation(orientation);
 		result->push_back(image);
@@ -571,18 +536,27 @@ bool CAnalyze3DImageIOPlugin::do_save(const string& fname, const Data& data) con
 	C3DFVector voxel = (*k)->get_voxel_size();
 	EPixelType pixel_type = (*k)->get_pixel_type();
 
-	E3DImageOrientation orient = (*k)->get_orientation();
+	auto orient = (*k)->get_orientation();
 
 	switch (orient) {
 	case ior_axial:
 			hdr.hist.orient = ao_transverse_unflipped;
 			break;
+	case ior_axial_flipped:
+			hdr.hist.orient = ao_transverse_flipped;
+			break;
 	case ior_coronal:
 			hdr.hist.orient = ao_coronal_unflipped;
 			break;
+	case ior_coronal_flipped:
+			hdr.hist.orient = ao_coronal_flipped;
+			break;
 	case ior_saggital:
 			hdr.hist.orient = ao_saggital_unflipped;
 			break;
+	case ior_saggital_flipped:
+			hdr.hist.orient = ao_saggital_flipped;
+			break;
 	default:
 		hdr.hist.orient = ao_unknown;
 	}
@@ -625,7 +599,7 @@ bool CAnalyze3DImageIOPlugin::do_save(const string& fname, const Data& data) con
 	return true;
 }
 
-std::string CAnalyze3DImageIOPlugin::do_get_preferred_suffix() const
+const std::string CAnalyze3DImageIOPlugin::do_get_preferred_suffix() const
 {
 	return "hdr"; 
 }
diff --git a/mia/3d/io/analyze.hh b/mia/3d/io/analyze.hh
index 5322be1..e3cffdc 100644
--- a/mia/3d/io/analyze.hh
+++ b/mia/3d/io/analyze.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,11 +38,10 @@ private:
 	virtual PData do_load(const std::string&  filename) const;
 	virtual bool do_save(const std::string& fname, const Data& data) const;
 	virtual const std::string do_get_descr() const;
-	std::string do_get_preferred_suffix() const; 
+	const std::string do_get_preferred_suffix() const; 
 
 	void swap_hdr(analyze_dsr& hdr) const;
 
-	template <bool flipped>
 	mia::C3DImage *read_image(const mia::C3DBounds& size, short datatype, mia::CInputFile& data_file)const;
 
 	bool save_data(const std::string& fname, const Data& data, analyze_image_dimension& dime) const;
diff --git a/mia/3d/io/inria.cc b/mia/3d/io/inria.cc
index ea6af7e..2ce6ae9 100644
--- a/mia/3d/io/inria.cc
+++ b/mia/3d/io/inria.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -72,7 +72,7 @@ private:
 	virtual PData do_load(const string&  filename) const;
 	virtual bool do_save(const string& fname, const Data& data) const;
 	virtual const string do_get_descr() const;
-	std::string do_get_preferred_suffix() const; 
+	const std::string do_get_preferred_suffix() const; 
 };
 
 extern "C" EXPORT CPluginBase *get_plugin_interface()
@@ -569,7 +569,7 @@ bool CInria3DImageIOPlugin::do_save(string const&  filename, const C3DImageVecto
 }
 
 
-std::string CInria3DImageIOPlugin::do_get_preferred_suffix() const
+const std::string CInria3DImageIOPlugin::do_get_preferred_suffix() const
 {
 	return "inr"; 
 }
diff --git a/mia/3d/io/vff.cc b/mia/3d/io/vff.cc
index 432dfba..1650add 100644
--- a/mia/3d/io/vff.cc
+++ b/mia/3d/io/vff.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/iterator.cxx b/mia/3d/iterator.cxx
index f46b824..0b4c706 100644
--- a/mia/3d/iterator.cxx
+++ b/mia/3d/iterator.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,8 +31,7 @@ range3d_iterator<I>::range3d_iterator():
 	m_begin(0,0,0), 
 	m_end(0,0,0), 
 	m_xstride(0),
-	m_ystride(0), 
-	m_boundary(eb_none)
+	m_ystride(0)
 {
 }
 
@@ -43,8 +42,7 @@ range3d_iterator<I>::range3d_iterator(const C3DBounds& pos):
 	m_begin(0,0,0), 
 	m_end(0,0,0), 
 	m_xstride(0),
-	m_ystride(0), 
-	m_boundary(eb_none)
+	m_ystride(0)
 {
 }
 
@@ -56,27 +54,9 @@ range3d_iterator<I>::range3d_iterator(const C3DBounds& pos, const C3DBounds& siz
 	m_begin(begin), 
 	m_end(end),
 	m_xstride(m_size.x - (m_end.x - m_begin.x)),
-	m_iterator(iterator), 
-	m_boundary(eb_none)
+	m_iterator(iterator)
 {
-	cvdebug() << "m_boundary=" << m_boundary << "\n"; 
 	m_ystride = (m_size.y - (m_end.y - m_begin.y))*m_size.x; 
-	if (m_pos.x == 0)
-		m_boundary |= eb_xlow; 
-	if (m_pos.x == size.x - 1)
-		m_boundary |= eb_xhigh; 
-	
-	if (m_pos.y == 0)
-		m_boundary |= eb_ylow; 
-	if (m_pos.y == size.y - 1)
-		m_boundary |= eb_yhigh; 
-
-	if (m_pos.z == 0)
-		m_boundary |= eb_zlow; 
-	if (m_pos.z == size.z - 1)
-		m_boundary |= eb_zhigh; 
-	cvdebug() << "m_boundary=" << m_boundary << "\n"; 
-	
 }
 
 
@@ -90,7 +70,6 @@ range3d_iterator<I>& range3d_iterator<I>::operator = (const range3d_iterator<I>&
 	m_iterator = other.m_iterator; 
 	m_xstride = other.m_xstride; 
 	m_ystride = other.m_ystride;
-	m_boundary = other.m_boundary; 
 	return *this; 
 }
 
@@ -104,8 +83,7 @@ range3d_iterator<I>::range3d_iterator(const range3d_iterator<I>& other):
 	m_end(other.m_end), 
 	m_xstride(other.m_xstride),
 	m_ystride(other.m_ystride),
-	m_iterator(other.m_iterator), 
-	m_boundary(other.m_boundary)
+	m_iterator(other.m_iterator)
 {
 }	
 
@@ -116,13 +94,9 @@ range3d_iterator<I>& range3d_iterator<I>::operator ++()
 	
 	++m_pos.x;
 	++m_iterator; 
-	m_boundary &= ~eb_x;
 	if (m_pos.x == m_end.x) {
 		increment_y(); 
-		if (m_pos.x == 0) 
-			m_boundary |= eb_xlow;
-	}else if (m_pos.x == m_size.x - 1)
-		m_boundary |= eb_xhigh; 
+	}
 	
 	return *this; 
 }
@@ -133,14 +107,10 @@ void range3d_iterator<I>::increment_y()
 	if (m_pos.y < m_end.y) {
 		m_pos.x = m_begin.x; 
 		++m_pos.y; 
-		m_boundary &= ~eb_y;
 		std::advance(m_iterator, m_xstride);
 		if (m_pos.y == m_end.y) {
 			increment_z();
-			if (m_pos.y == 0) 
-				m_boundary |= eb_ylow; 
-		} else if (m_pos.y == m_size.y - 1)
-			m_boundary |= eb_yhigh; 
+		}
 	} 
 }
 
@@ -150,13 +120,9 @@ void range3d_iterator<I>::increment_z()
 	if (m_pos.z < m_end.z - 1) {
 		m_pos.y = m_begin.y; 
 		++m_pos.z; 
-		m_boundary &= ~eb_zlow; 
 		std::advance(m_iterator, m_ystride);
-		if (m_pos.z == m_size.z - 1)
-			m_boundary |= eb_zhigh; 
 	}else if (m_pos.z == m_end.z - 1) {
 		m_pos = m_end; 
-
 	}
 }
 
@@ -217,7 +183,181 @@ const C3DBounds& range3d_iterator<I>::pos() const
 }
 
 template <typename I> 
-int range3d_iterator<I>::get_boundary_flags() const
+range3d_iterator_with_boundary_flag<I> range3d_iterator<I>::with_boundary_flag() const
+{
+	return 	range3d_iterator_with_boundary_flag<I>(m_pos, m_size, m_begin, m_end, m_iterator);
+}
+
+template <typename I> 
+range3d_iterator_with_boundary_flag<I>::range3d_iterator_with_boundary_flag():
+	m_pos(0,0,0), 
+	m_size(0,0,0), 
+	m_begin(0,0,0), 
+	m_end(0,0,0), 
+	m_xstride(0),
+	m_ystride(0), 
+	m_boundary(eb_none)
+{
+}
+
+template <typename I> 
+range3d_iterator_with_boundary_flag<I>::range3d_iterator_with_boundary_flag(const C3DBounds& pos):
+	m_pos(pos), 
+	m_size(0,0,0), 
+	m_begin(0,0,0), 
+	m_end(0,0,0), 
+	m_xstride(0),
+	m_ystride(0), 
+	m_boundary(eb_none)
+{
+}
+
+template <typename I> 
+range3d_iterator_with_boundary_flag<I>::range3d_iterator_with_boundary_flag(const C3DBounds& pos, const C3DBounds& size, 
+				      const C3DBounds& begin, const C3DBounds& end, I iterator):
+	m_pos(pos), 
+	m_size(size), 
+	m_begin(begin), 
+	m_end(end),
+	m_xstride(m_size.x - (m_end.x - m_begin.x)),
+	m_iterator(iterator), 
+	m_boundary(eb_none)
+{
+	m_ystride = (m_size.y - (m_end.y - m_begin.y))*m_size.x; 
+	if (m_pos.x == 0)
+		m_boundary |= eb_xlow; 
+	if (m_pos.x == size.x - 1)
+		m_boundary |= eb_xhigh; 
+	
+	if (m_pos.y == 0)
+		m_boundary |= eb_ylow; 
+	if (m_pos.y == size.y - 1)
+		m_boundary |= eb_yhigh; 
+
+	if (m_pos.z == 0)
+		m_boundary |= eb_zlow; 
+	if (m_pos.z == size.z - 1)
+		m_boundary |= eb_zhigh; 
+}
+
+
+template <typename I> 
+range3d_iterator_with_boundary_flag<I>& range3d_iterator_with_boundary_flag<I>::operator = (const range3d_iterator_with_boundary_flag<I>& other)
+{
+	m_pos = other.m_pos; 
+	m_size = other.m_size;  
+	m_begin = other.m_begin; 
+	m_end = other.m_end; 
+	m_iterator = other.m_iterator; 
+	m_xstride = other.m_xstride; 
+	m_ystride = other.m_ystride;
+	m_boundary = other.m_boundary; 
+	return *this; 
+}
+
+
+
+template <typename I> 
+range3d_iterator_with_boundary_flag<I>::range3d_iterator_with_boundary_flag(const range3d_iterator_with_boundary_flag<I>& other):
+	m_pos(other.m_pos), 
+	m_size(other.m_size), 
+	m_begin(other.m_begin), 
+	m_end(other.m_end), 
+	m_xstride(other.m_xstride),
+	m_ystride(other.m_ystride),
+	m_iterator(other.m_iterator), 
+	m_boundary(other.m_boundary)
+{
+}	
+
+template <typename I> 
+range3d_iterator_with_boundary_flag<I>& range3d_iterator_with_boundary_flag<I>::operator ++()
+{
+	DEBUG_ASSERT_RELEASE_THROW(m_pos.x < m_end.x, "range3d_iterator_with_boundary_flag: trying to increment past end");
+	
+	++m_pos.x;
+	++m_iterator; 
+	m_boundary &= ~eb_x;
+	
+	if (m_pos.x == m_end.x) {
+		increment_y(); 
+		if (m_pos.x == 0) 
+			m_boundary |= eb_xlow;
+	}
+	if (m_pos.x == m_size.x - 1)
+		m_boundary |= eb_xhigh; 
+	
+	return *this; 
+}
+
+template <typename I> 
+void range3d_iterator_with_boundary_flag<I>::increment_y()
+{
+	if (m_pos.y < m_end.y) {
+		m_pos.x = m_begin.x; 
+		++m_pos.y; 
+		m_boundary &= ~eb_y;
+		std::advance(m_iterator, m_xstride);
+		if (m_pos.y == m_end.y) {
+			increment_z();
+			if (m_pos.y == 0) 
+				m_boundary |= eb_ylow; 
+		} 
+		if (m_pos.y == m_size.y - 1)
+			m_boundary |= eb_yhigh; 
+	} 
+}
+
+template <typename I> 
+void range3d_iterator_with_boundary_flag<I>::increment_z()
+{
+	if (m_pos.z < m_end.z - 1) {
+		m_pos.y = m_begin.y; 
+		++m_pos.z; 
+		m_boundary &= ~eb_zlow; 
+		std::advance(m_iterator, m_ystride);
+		if (m_pos.z == m_size.z - 1)
+			m_boundary |= eb_zhigh; 
+	}else if (m_pos.z == m_end.z - 1) {
+		m_pos = m_end; 
+	}
+}
+
+template <typename I> 
+typename range3d_iterator_with_boundary_flag<I>::internal_iterator 
+range3d_iterator_with_boundary_flag<I>::get_point()
+{
+	return m_iterator; 
+}
+
+template <typename I> 
+range3d_iterator_with_boundary_flag<I> range3d_iterator_with_boundary_flag<I>::operator ++(int)
+{
+	range3d_iterator_with_boundary_flag result(*this); 
+	++(*this); 
+	return result; 
+}
+
+template <typename I> 
+typename range3d_iterator_with_boundary_flag<I>::reference range3d_iterator_with_boundary_flag<I>::operator *() const
+{
+	return *m_iterator; 
+}
+
+template <typename I> 
+typename range3d_iterator_with_boundary_flag<I>::pointer range3d_iterator_with_boundary_flag<I>::operator ->() const
+{
+	return __iterator3d_dispatch_operator_for_bool<internal_iterator>::apply(m_iterator);
+}
+
+template <typename I> 
+const C3DBounds& range3d_iterator_with_boundary_flag<I>::pos() const
+{
+	return m_pos; 
+}
+
+template <typename I> 
+int range3d_iterator_with_boundary_flag<I>::get_boundary_flags() const
 {
 	return m_boundary; 
 }
diff --git a/mia/3d/iterator.hh b/mia/3d/iterator.hh
index fe2dff1..499ce0e 100644
--- a/mia/3d/iterator.hh
+++ b/mia/3d/iterator.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,12 +25,13 @@
 
 NS_MIA_BEGIN
 
+
+
 /**
    @ingroup basic 
-   \brief a 3D iterator that knows its position in the 3D grid ans supports iterating over 
-   sub-ranges 
+   \brief a 3D iterator that knows its position in the 3D grid, has a flag indicating 
+     whether it is on a boundary, and supports iterating over  sub-ranges 
    
-
    Iterator to iterate over a sub-range of 3D data that is given on a grid. 
    Two iterators are considered to be equal, if their positions are equal.  
    \tparam the internal iterator that is used to iterate of the original 
@@ -39,12 +40,17 @@ NS_MIA_BEGIN
  */
 
 template <typename I> 
-class range3d_iterator: public std::forward_iterator_tag {
+class range3d_iterator_with_boundary_flag: public std::forward_iterator_tag {
 public: 
 	/// data type reference 
 	typedef typename I::reference reference; 
+
 	/// data type pointer  
 	typedef typename I::pointer pointer; 
+
+	/// data value type 
+	typedef typename I::value_type value_type; 
+
 	/// data type for the real iterator in the background 
 	typedef I internal_iterator; 
 	
@@ -71,6 +77,130 @@ public:
 
 	
 	/** standard constructor */
+	range3d_iterator_with_boundary_flag(); 
+
+	/**
+	   Full constructor of the range iterator 
+	   @param pos iterator position to initialize the iterator with 
+	   @param size size of the original data field 
+	   @param start start of the iterator range 
+	   @param end end of the iterator range 
+	   @param iterator the iterator of the underlying 3D data structure 
+	*/
+	range3d_iterator_with_boundary_flag(const C3DBounds& pos, const C3DBounds& size, 
+			 const C3DBounds& start, const C3DBounds& end, I iterator);
+	
+	/**
+	   End iterator, can't be dereferenced  
+	   This iterator is only there to define the end position of the range_iterator. 
+	   \param pos end position to set this iterator to. 
+	 */
+	range3d_iterator_with_boundary_flag(const C3DBounds& pos);
+
+	/// assignment operator 
+	range3d_iterator_with_boundary_flag<I>& operator = (const range3d_iterator_with_boundary_flag<I>& other); 
+	
+	/// copy constructore 
+	range3d_iterator_with_boundary_flag(const range3d_iterator_with_boundary_flag<I>& other); 
+
+	/// friend iterator type because we may want to copy a iterator to a const_iterator. 
+	template <typename AI> 
+	friend class range3d_iterator_with_boundary_flag; 
+
+
+	/**
+	   Constructor to construct the iterator  from one that is based on another 
+	   iterator type. The usual idea is that a iterator may be converted  into it's const variant. 
+	   \tparam AI the other iterator type. Iterator type I must be copy-constructable from 
+	   type AI 
+	   \param other 
+	 */
+	template <typename AI>
+	range3d_iterator_with_boundary_flag(const range3d_iterator_with_boundary_flag<AI>& other); 
+
+	/**
+	   Assignment operator from another type of iterator 
+	   \tparam AI other iterator type. The assignment I b = a; with a of type AI must be defined.
+	   \param other 
+	 */
+	template <typename AI>
+	range3d_iterator_with_boundary_flag<I>& operator = (const range3d_iterator_with_boundary_flag<AI>& other); 
+
+	
+	/// prefix increment 
+	range3d_iterator_with_boundary_flag<I>& operator ++(); 
+	/// postfix increment 
+	range3d_iterator_with_boundary_flag<I> operator ++(int); 
+	
+	/// @returns current value the iterator points to 
+	reference  operator *() const;
+	
+	/// @returns pointer to the current value the iterator points to 
+	pointer    operator ->() const;
+
+	/** \returns the current position within the 3D grid with respect to the 
+	    full size of the grid. 
+	 */
+	const C3DBounds& pos() const; 
+
+	/// @cond NOFRIENDDOC
+	template <typename T> friend
+	bool operator == (const range3d_iterator_with_boundary_flag<T>& left, const range3d_iterator_with_boundary_flag<T>& right); 
+	/// @endcond 
+
+	/**
+	   Return the internal iterator
+	 */
+	internal_iterator get_point(); 
+
+	/// \returns the flags describing whether the iterator is on a domain boundary. 
+	int get_boundary_flags() const; 
+
+private: 
+
+	void increment_y(); 
+	void increment_z(); 
+
+	C3DBounds m_pos; 
+	C3DBounds m_size; 
+	C3DBounds m_begin; 
+	C3DBounds m_end; 
+	int m_xstride; 
+	int m_ystride; 
+	I m_iterator; 
+	int m_boundary; 
+}; 
+
+
+
+/**
+   @ingroup basic 
+   \brief a 3D iterator that knows its position in the 3D grid ans supports iterating over 
+   sub-ranges 
+   
+   Iterator to iterate over a sub-range of 3D data that is given on a grid. 
+   Two iterators are considered to be equal, if their positions are equal.  
+   \tparam the internal iterator that is used to iterate of the original 
+   grid without skipping. 
+   
+ */
+
+template <typename I> 
+class range3d_iterator: public std::forward_iterator_tag {
+public: 
+	/// data type reference 
+	typedef typename I::reference reference; 
+	/// data type pointer  
+	typedef typename I::pointer pointer; 
+
+	/// data value type 
+	typedef typename I::value_type value_type; 
+
+	/// data type for the real iterator in the background 
+	typedef I internal_iterator; 
+	
+	
+	/** standard constructor */
 	range3d_iterator(); 
 
 	/**
@@ -100,6 +230,11 @@ public:
 	/// friend iterator type because we may want to copy a iterator to a const_iterator. 
 	template <typename AI> 
 	friend class range3d_iterator; 
+
+	/// friend iterator type because we may want to copy a iterator to a const_iterator. 
+	template <typename AI> 
+	friend class range3d_iterator_with_boundary_flag; 
+
 	
 	/**
 	   Constructor to construct the iterator  from one that is based on another 
@@ -143,12 +278,15 @@ public:
 	/// @endcond 
 
 	/**
-	   Return the internal iterator
+	   \return the internal iterator
 	 */
 	internal_iterator get_point(); 
 
-	/// \returns the flags describing whether the iterator is on a domain boundary. 
-	int get_boundary_flags() const; 
+	/**
+	   \returns the same iterator but with boundary checks and flags. 
+	*/
+	range3d_iterator_with_boundary_flag<I> with_boundary_flag() const;
+
 
 private: 
 
@@ -162,7 +300,6 @@ private:
 	int m_xstride; 
 	int m_ystride; 
 	I m_iterator; 
-	int m_boundary; 
 }; 
 
 
@@ -178,7 +315,6 @@ range3d_iterator<I>& range3d_iterator<I>::operator = (const range3d_iterator<AI>
 	m_iterator = other.m_iterator; 
 	m_xstride = other.m_xstride; 
 	m_ystride = other.m_ystride; 
-	m_boundary = other.m_boundary; 
 	return *this; 
 }
 
@@ -191,8 +327,7 @@ range3d_iterator<I>::range3d_iterator(const range3d_iterator<AI>& other):
 	m_end(other.m_end), 
 	m_xstride(other.m_xstride),
 	m_ystride(other.m_ystride),
-	m_iterator(other.m_iterator), 
-	m_boundary(other.m_boundary)
+	m_iterator(other.m_iterator)
 {
 }	
 
@@ -222,6 +357,88 @@ bool operator != (const range3d_iterator<I>& a, const range3d_iterator<I>& b)
 	return !(a == b); 
 }
 
+
+
+
+
+template <typename I> 
+template <typename AI>
+range3d_iterator_with_boundary_flag<I>& range3d_iterator_with_boundary_flag<I>::operator = (const range3d_iterator_with_boundary_flag<AI>& other)
+{
+	m_pos = other.m_pos; 
+	m_size = other.m_size;  
+	m_begin = other.m_begin; 
+	m_end = other.m_end; 
+	m_iterator = other.m_iterator; 
+	m_xstride = other.m_xstride; 
+	m_ystride = other.m_ystride; 
+	m_boundary = other.m_boundary; 
+	return *this; 
+}
+
+template <typename I> 
+template <typename AI>
+range3d_iterator_with_boundary_flag<I>::range3d_iterator_with_boundary_flag(const range3d_iterator_with_boundary_flag<AI>& other):
+	m_pos(other.m_pos), 
+	m_size(other.m_size), 
+	m_begin(other.m_begin), 
+	m_end(other.m_end), 
+	m_xstride(other.m_xstride),
+	m_ystride(other.m_ystride),
+	m_iterator(other.m_iterator), 
+	m_boundary(other.m_boundary)
+{
+}	
+
+/**
+   Compare two range iterators. There equivalence is only decided based on the grid position. 
+ */
+
+template <typename I> 
+bool operator == (const range3d_iterator_with_boundary_flag<I>& left, const range3d_iterator_with_boundary_flag<I>& right)
+{
+	// we really want these two to the same range 
+//	assert(left.m_size == right.m_size);
+//	assert(left.m_begin == right.m_begin);
+//	assert(left.m_end == right.m_end);
+
+	return left.m_pos == right.m_pos; 
+
+}
+
+/**
+   Compare two range iterators. There equivalence is only decided based on the grid position. 
+ */
+template <typename I> 
+bool operator != (const range3d_iterator_with_boundary_flag<I>& a, const range3d_iterator_with_boundary_flag<I>& b)
+{
+	return !(a == b); 
+}
+
 NS_MIA_END
 
+namespace std {
+
+template <typename I>
+class iterator_traits< mia::range3d_iterator<I> > {
+public: 
+	typedef typename I::difference_type  difference_type; 
+	typedef typename I::value_type	value_type; 
+	typedef typename I::pointer	pointer; 
+	typedef typename I::reference	reference; 
+	typedef forward_iterator_tag	iterator_category; 
+}; 
+
+template <typename I>
+class iterator_traits< mia::range3d_iterator_with_boundary_flag<I> > {
+public: 
+	typedef typename I::difference_type  difference_type; 
+	typedef typename I::value_type	value_type; 
+	typedef typename I::pointer	pointer; 
+	typedef typename I::reference	reference; 
+	typedef forward_iterator_tag	iterator_category; 
+}; 
+
+}
+
 #endif
diff --git a/mia/3d/landmark.cc b/mia/3d/landmark.cc
index 11d5cc0..922c8cf 100644
--- a/mia/3d/landmark.cc
+++ b/mia/3d/landmark.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/landmark.hh b/mia/3d/landmark.hh
index c74efd7..e0f368a 100644
--- a/mia/3d/landmark.hh
+++ b/mia/3d/landmark.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/landmarklist.cc b/mia/3d/landmarklist.cc
index 73379a1..52d9448 100644
--- a/mia/3d/landmarklist.cc
+++ b/mia/3d/landmarklist.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/landmarklist.hh b/mia/3d/landmarklist.hh
index eb2f079..874ebc6 100644
--- a/mia/3d/landmarklist.hh
+++ b/mia/3d/landmarklist.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/landmarklistio.cc b/mia/3d/landmarklistio.cc
index f06a9e6..82b7077 100644
--- a/mia/3d/landmarklistio.cc
+++ b/mia/3d/landmarklistio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,14 +31,6 @@ template <> const char *  const
 TPluginHandler<C3DLandmarklistIOPlugin>::m_help =  
 	"Loading and storing of 3D landmark list.";
 
-C3DLandmarklistIOTestPath::C3DLandmarklistIOTestPath() 
-{
-	CPathNameArray sksearchpath; 
-	sksearchpath.push_back( boost::filesystem::path(MIA_BUILD_ROOT"/mia/3d/lmio"));
-	C3DLandmarklistIOPluginHandler::set_search_path(sksearchpath); 
-
-}
-
 EXPLICITE_INSTANCEIATE_IO_HANDLER(C3DLandmarklist); 
 
 NS_MIA_END
diff --git a/mia/3d/landmarklistio.hh b/mia/3d/landmarklistio.hh
index e07a228..a6679a4 100644
--- a/mia/3d/landmarklistio.hh
+++ b/mia/3d/landmarklistio.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -39,16 +39,6 @@ typedef TIOPlugin<C3DLandmarklist> C3DLandmarklistIOPlugin;
 */
 typedef THandlerSingleton<TIOPluginHandler<C3DLandmarklistIOPlugin> > C3DLandmarklistIOPluginHandler;
 
-/**   
-      \ingroup tests 
-      Class to set up the plug-in search path for landmark list io plug-ins when running tests
-      in the build tree 
-*/
-struct EXPORT_3D C3DLandmarklistIOTestPath {
-	C3DLandmarklistIOTestPath(); 
-}; 
-
-
 /**
    @ingroup io 
    @brief 3D Landmark list data key to load and store to the CDatapool
diff --git a/mia/3d/linear_transform.cc b/mia/3d/linear_transform.cc
index 17d8d99..8bdecf2 100644
--- a/mia/3d/linear_transform.cc
+++ b/mia/3d/linear_transform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/linear_transform.hh b/mia/3d/linear_transform.hh
index 728a03d..97051fd 100644
--- a/mia/3d/linear_transform.hh
+++ b/mia/3d/linear_transform.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/lmio/CMakeLists.txt b/mia/3d/lmio/CMakeLists.txt
index 0246fd4..3029342 100644
--- a/mia/3d/lmio/CMakeLists.txt
+++ b/mia/3d/lmio/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/lmio/lmx.cc b/mia/3d/lmio/lmx.cc
index a8fb493..d7cf542 100644
--- a/mia/3d/lmio/lmx.cc
+++ b/mia/3d/lmio/lmx.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/maskedcost.cc b/mia/3d/maskedcost.cc
new file mode 100644
index 0000000..9deccbf
--- /dev/null
+++ b/mia/3d/maskedcost.cc
@@ -0,0 +1,45 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/export_handler.hh>
+
+#include <mia/3d/maskedcost.hh>
+#include <mia/template/masked_cost.cxx>
+#include <mia/core/handler.cxx>
+#include <mia/core/plugin_base.cxx>
+
+NS_MIA_BEGIN
+
+template <> const char *  const 
+TPluginHandler<TFactory<C3DMaskedImageCost>>::m_help =  
+	"3D image similarity kernels evaluate the according similarity measure between "
+	"two images by using a mask. These kernels may be used standalone, like e.g. in "
+	"linear registration, or will be called from generalized image similarity cost "
+	"plug-ins that also take care of transforming and scaling the images during the "
+	"image registration process.";
+
+template class TMaskedCost<C3DImage, C3DBitImage, C3DFVectorfield>;
+template class TPlugin<C3DImage, masked_cost_type>;
+template class TFactory<C3DMaskedImageCost>;
+template class THandlerSingleton<TFactoryPluginHandler<C3DMaskedImageCostPlugin> >;
+template class TFactoryPluginHandler<C3DMaskedImageCostPlugin>;
+template class TPluginHandler<C3DMaskedImageCostPlugin>;
+
+NS_MIA_END
diff --git a/mia/3d/maskedcost.hh b/mia/3d/maskedcost.hh
new file mode 100644
index 0000000..4e33a23
--- /dev/null
+++ b/mia/3d/maskedcost.hh
@@ -0,0 +1,60 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_masked_cost_hh
+#define mia_3d_masked_cost_hh
+
+#include <mia/template/masked_cost.hh>
+#include <mia/3d/image.hh>
+
+NS_MIA_BEGIN
+
+/**
+   @ingroup registration 
+   @brief the image-to-image cost function base class 
+*/
+typedef TMaskedCost<C3DImage, C3DBitImage, C3DFVectorfield> C3DMaskedImageCost;
+
+/**
+   @ingroup registration 
+   @brief pointer type of the image-to-image cost function base class 
+*/
+typedef std::shared_ptr<C3DMaskedImageCost > P3DMaskedImageCost;
+
+/**
+   @ingroup registration 
+   @brief plug-in for the image-to-image cost function base class 
+*/
+typedef TFactory<C3DMaskedImageCost> C3DMaskedImageCostPlugin;
+
+/**
+   @ingroup registration 
+   @brief plug-in handler for the image-to-image cost function base class 
+*/
+typedef THandlerSingleton<TFactoryPluginHandler<C3DMaskedImageCostPlugin> > C3DMaskedImageCostPluginHandler;
+
+/// @cond NEVER 
+FACTORY_TRAIT(C3DMaskedImageCostPluginHandler);
+/// @endcond 
+
+NS_MIA_END
+
+
+#endif 
diff --git a/mia/3d/maskedcost/CMakeLists.txt b/mia/3d/maskedcost/CMakeLists.txt
new file mode 100644
index 0000000..0676ceb
--- /dev/null
+++ b/mia/3d/maskedcost/CMakeLists.txt
@@ -0,0 +1,35 @@
+#
+# This file is part of MIA - a toolbox for medical image analysis 
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+#
+# MIA is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+
+SET(maskedcost3d
+  lncc
+  mi 
+  ncc 
+  ssd
+)
+
+PLUGINGROUP_WITH_TEST_AND_PREFIX2("3dimage" "maskedcost" "${maskedcost3d}" 
+  "${MIA3DLIBS}" )
+
+
+#SET(fatcost3d fatngf fatssd) 
+
+#PLUGINGROUP_WITH_TEST_AND_PREFIX(3d-fatcost "${fatcost3d}" 
+#  "${MIA3DLIBS}" "${PLUGIN_INSTALL_PATH}/3dimage/fatcost"
+#  )
+
diff --git a/mia/3d/maskedcost/lncc.cc b/mia/3d/maskedcost/lncc.cc
new file mode 100644
index 0000000..0d235ed
--- /dev/null
+++ b/mia/3d/maskedcost/lncc.cc
@@ -0,0 +1,246 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/maskedcost/lncc.hh>
+
+#include <mia/core/threadedmsg.hh>
+#include <mia/core/nccsum.hh> 
+#include <tbb/parallel_reduce.h>
+#include <tbb/blocked_range.h>
+
+
+NS_BEGIN(NS)
+
+using namespace mia; 
+using std::vector; 
+using std::pair; 
+using std::make_pair; 
+
+CLNCC3DImageCost::CLNCC3DImageCost(int hw):
+m_hwidth(hw)
+{
+}
+
+inline pair<C3DBounds, C3DBounds> prepare_range(const C3DBounds& size, int cx, int cy, int cz, int hw) 
+{
+	int zb = cz - hw;
+	if (zb < 0) zb = 0; 
+	unsigned ze = cz + hw + 1; 
+	if (ze > size.z) ze = size.z; 
+	
+	int yb = cy - hw;
+	if (yb < 0) yb = 0; 
+	unsigned ye = cy + hw + 1; 
+	if (ye > size.y) ye = size.y; 
+	
+	int xb = cx - hw;
+	if (xb < 0) xb = 0; 
+	unsigned xe = cx + hw + 1; 
+	if (xe > size.x) xe = size.x; 
+	
+	return make_pair(C3DBounds(xb,yb,zb), C3DBounds(xe,ye,ze)); 
+}
+
+#ifdef __SSE2__
+typedef double v2df __attribute__ ((vector_size (16)));
+#endif
+
+
+class FEvalCost : public TFilter<float> {
+	int m_hw;
+	const C3DBitImage& m_mask; 
+public:
+	FEvalCost(int hw, const C3DBitImage& mask):
+		m_hw(hw), 
+		m_mask(mask)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		auto evaluate_local_cost = [this, &mov, &ref](const tbb::blocked_range<size_t>& range, const pair<float, int>& result) -> pair<float, int> {
+			CThreadMsgStream msks; 
+			float lresult = 0.0; 
+			int count = 0; 
+			const int max_length = 2 * m_hw +1; 
+			vector<float> a_buffer( max_length * max_length * max_length); 
+			vector<float> b_buffer( max_length * max_length * max_length); 
+			
+			for (auto z = range.begin(); z != range.end(); ++z) {
+				auto imask  = m_mask.begin_at(0,0,z);
+			
+				for (size_t y = 0; y < mov.get_size().y; ++y)
+					for (size_t x = 0; x < mov.get_size().x; ++x, ++imask) {
+						
+						if (!*imask) 
+							continue; 
+						
+						auto c_block = prepare_range(mov.get_size(), x, y, z, m_hw); 
+						
+						NCCSums sum; 
+						for (unsigned iz = c_block.first.z; iz < c_block.second.z; ++iz) {
+							for (unsigned iy = c_block.first.y; iy < c_block.second.y; ++iy) {
+								auto ia = mov.begin_at(0,iy,iz); 
+								auto ib = ref.begin_at(0, iy, iz); 
+								auto im = m_mask.begin_at(0, iy, iz); 
+								for (unsigned ix = c_block.first.x; ix < c_block.second.x; ++ix) {
+									
+									// make a local copy 
+									if (im[ix]) {
+										sum.add(ia[ix], ib[ix]);
+									}
+								}
+							}
+						}
+						
+						if (sum.has_samples()) {
+							lresult += sum.value(); 
+							++count; 
+						}
+					}
+			}
+
+			return make_pair(result.first + lresult, result.second + count); 
+		};
+		
+		pair<float,int> init{0, 0}; 
+		auto r = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), init, evaluate_local_cost, 
+					 [](const pair<float,int>& x, const pair<float,int>& y){return make_pair(x.first + y.first, x.second + y.second);});	
+		cvdebug() << "result={" << r.first << " /  " <<  r.second << "\n"; 
+		return r.second > 0 ? r.first / r.second : 0.0; 
+	}
+}; 
+
+
+double CLNCC3DImageCost::do_value(const Data& a, const Data& b, const Mask& m) const
+{
+	FEvalCost ecost(m_hwidth, m); 
+	return mia::filter(ecost, a, b); 
+}
+
+
+class FEvalCostForce : public TFilter<float> {
+	int m_hw;
+	const C3DBitImage& m_mask; 
+	C3DFVectorfield& m_force; 
+public: 
+	FEvalCostForce(int hw, const C3DBitImage& mask, C3DFVectorfield& force):
+		m_hw(hw), 
+		m_mask(mask), 
+		m_force(force)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		auto ag = get_gradient(mov); 
+		auto evaluate_local_cost_force = [this, &mov, &ref, &ag](const tbb::blocked_range<size_t>& range, 
+									 const pair<float, int>& result) -> pair<float, int> {
+			
+			CThreadMsgStream msks; 		
+			float lresult = 0.0; 
+			int count = 0; 
+			const int max_length = 2 * m_hw + 1;
+			vector<float> a_buffer( max_length * max_length * max_length); 
+			vector<float> b_buffer( max_length * max_length * max_length); 
+
+			for (auto z = range.begin(); z != range.end(); ++z) {
+                        
+				auto iforce = m_force.begin_at(0,0,z);
+				auto imask = m_mask.begin_at(0,0,z);
+				auto ig = ag.begin_at(0,0,z);
+				auto imov = mov.begin_at(0,0,z);
+				auto iref = ref.begin_at(0,0,z);
+                        
+				for (size_t y = 0; y < mov.get_size().y; ++y)
+					for (size_t x = 0; x < mov.get_size().x; ++x, ++iforce, ++imask, ++ig, ++iref, ++imov) {
+						if (!*imask) 
+							continue; 
+                                        
+						auto c_block = prepare_range(mov.get_size(), x, y, z, m_hw); 
+						
+						NCCSums sum; 
+						for (unsigned iz = c_block.first.z; iz < c_block.second.z; ++iz) {
+							for (unsigned iy = c_block.first.y; iy < c_block.second.y; ++iy) {
+								auto ia = mov.begin_at(0,iy,iz); 
+								auto ib = ref.begin_at(0, iy, iz); 
+								auto im = m_mask.begin_at(0, iy, iz); 
+								for (unsigned ix = c_block.first.x; ix < c_block.second.x; ++ix) {
+									
+									// make a local copy 
+									if (im[ix]) {
+										sum.add(ia[ix], ib[ix]);
+									}
+								}
+							}
+						}
+						
+						if (sum.has_samples()) {
+							auto res = sum.get_grad_helper(); 
+							lresult += res.first;
+							*iforce = res.second.get_gradient_scale(*imov, *iref) * *ig; 
+							++count; 
+						}
+
+					}
+			}
+			return make_pair(result.first + lresult, result.second + count); 
+		};
+		pair<float,int> init{0, 0}; 		
+		auto r = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), init, evaluate_local_cost_force, 
+					 [](const pair<float,int>& x, const pair<float,int>& y){
+						 return make_pair(x.first + y.first, x.second + y.second);
+					 });
+
+		return r.second > 0 ? r.first / r.second : 0.0; 
+	}
+	
+};
+
+double CLNCC3DImageCost::do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const
+{
+	FEvalCostForce ecostforce(m_hwidth, m, force); 
+	return mia::filter(ecostforce, a, b); 
+}
+
+
+CLNCC3DImageCostPlugin::CLNCC3DImageCostPlugin():
+C3DMaskedImageCostPlugin("lncc"), 
+	m_hw(5)
+{
+	this->add_parameter("w", new CUIntParameter(m_hw, 1, 256, false, 
+						    "half width of the window used for evaluating the localized cross correlation")); 
+}
+
+C3DMaskedImageCost *CLNCC3DImageCostPlugin::do_create() const
+{
+	return new CLNCC3DImageCost(m_hw);
+}
+
+const std::string CLNCC3DImageCostPlugin::do_get_descr() const
+{
+	return "local normalized cross correlation with masking support."; 
+}
+
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new CLNCC3DImageCostPlugin();
+}
+
+NS_END
diff --git a/mia/3d/maskedcost/lncc.hh b/mia/3d/maskedcost/lncc.hh
new file mode 100644
index 0000000..85afc37
--- /dev/null
+++ b/mia/3d/maskedcost/lncc.hh
@@ -0,0 +1,54 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_maskedcost_lncc_hh
+#define mia_3d_maskedcost_lncc_hh
+
+#include <mia/3d/maskedcost.hh>
+
+#define NS mia_3d_maskedlncc
+
+NS_BEGIN(NS)
+
+class CLNCC3DImageCost: public mia::C3DMaskedImageCost {
+public: 	
+	typedef mia::C3DMaskedImageCost::Data Data; 
+	typedef mia::C3DMaskedImageCost::Force Force; 
+	typedef mia::C3DMaskedImageCost::Mask Mask; 
+
+	CLNCC3DImageCost(int hw);
+private: 
+	virtual double do_value(const Data& a, const Data& b, const Mask& m) const; 
+	virtual double do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const; 
+        int m_hwidth; 
+};
+
+class CLNCC3DImageCostPlugin: public mia::C3DMaskedImageCostPlugin {
+public: 
+	CLNCC3DImageCostPlugin();
+	mia::C3DMaskedImageCost *do_create() const;
+private: 
+	const std::string do_get_descr() const; 
+        unsigned int m_hw; 
+};
+
+NS_END
+
+#endif 
diff --git a/mia/3d/maskedcost/mi.cc b/mia/3d/maskedcost/mi.cc
new file mode 100644
index 0000000..cee031b
--- /dev/null
+++ b/mia/3d/maskedcost/mi.cc
@@ -0,0 +1,38 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/maskedcost/mi.hh>
+#include <mia/template/mi_masked.cxx>
+
+NS_BEGIN(NS)
+
+NS_MIA_USE;
+using namespace std;
+using namespace boost;
+
+template class TMIMaskedImageCost<mia::C3DMaskedImageCost>;
+template class TMIMaskedImageCostPlugin<mia::C3DMaskedImageCostPlugin, mia::C3DMaskedImageCost>; 
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C3DMIMaskedCostPlugin();
+}
+
+NS_END
diff --git a/mia/3d/maskedcost/mi.hh b/mia/3d/maskedcost/mi.hh
new file mode 100644
index 0000000..8ec33c1
--- /dev/null
+++ b/mia/3d/maskedcost/mi.hh
@@ -0,0 +1,37 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_cost_mi_hh
+#define mia_3d_cost_mi_hh
+
+#include <mia/3d/maskedcost.hh>
+
+#define NS mia_3dcost_mi_masked
+#include <mia/template/mi_masked.hh>
+
+NS_BEGIN(NS)
+
+typedef TMIMaskedImageCost<mia::C3DMaskedImageCost> C3DMIMaskedImageCost;
+typedef TMIMaskedImageCostPlugin<mia::C3DMaskedImageCostPlugin, mia::C3DMaskedImageCost> C3DMIMaskedCostPlugin; 
+
+NS_END
+
+
+#endif
diff --git a/mia/3d/maskedcost/ncc.cc b/mia/3d/maskedcost/ncc.cc
new file mode 100644
index 0000000..f6d854b
--- /dev/null
+++ b/mia/3d/maskedcost/ncc.cc
@@ -0,0 +1,185 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/maskedcost/ncc.hh>
+
+#include <mia/core/threadedmsg.hh>
+#include <mia/core/nccsum.hh> 
+#include <tbb/parallel_reduce.h>
+#include <tbb/parallel_for.h>
+#include <tbb/blocked_range.h>
+
+
+NS_BEGIN(NS)
+
+using namespace mia; 
+
+
+CNCC3DImageCost::CNCC3DImageCost()
+{
+}
+
+template <typename T, typename S> 
+struct FEvaluateNCCSum {
+	FEvaluateNCCSum(const C3DBitImage& mask, const T& mov, const S& ref); 
+	NCCSums operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const; 
+private: 
+	C3DBitImage m_mask; 
+	T m_mov; 
+	S m_ref; 
+};
+
+
+template <typename T, typename S> 
+FEvaluateNCCSum<T,S>::FEvaluateNCCSum(const C3DBitImage& mask, const T& mov, const S& ref):
+	m_mask(mask),  m_mov(mov), m_ref(ref) 
+{
+	
+}
+
+template <typename T, typename S> 
+NCCSums FEvaluateNCCSum<T,S>::operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const
+{
+	CThreadMsgStream msks; 
+	
+	NCCSums sum;
+	for (auto z = range.begin(); z != range.end(); ++z) {
+		auto imask  = m_mask.begin_at(0,0,z);
+		auto ia = m_mov.begin_at(0, 0, z); 
+		auto ib = m_ref.begin_at(0, 0, z); 
+		auto eb = m_ref.begin_at(0, 0, z + 1); 
+		
+		while (ib != eb) {
+			if (*imask) {
+				sum.add(*ia, *ib); 
+			}
+			++ia; ++ib; ++imask; 
+		}
+	}
+	return sum + sumacc; 
+};
+
+
+class FEvalCost : public TFilter<float> {
+	const C3DBitImage& m_mask; 
+public:
+	FEvalCost(const C3DBitImage& mask):
+		m_mask(mask)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+
+		FEvaluateNCCSum<T,R> ev(m_mask, mov, ref); 
+		NCCSums sum; 
+		sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), sum, ev, 
+				      [](const NCCSums& x, const NCCSums& y){
+					      return x + y;
+				      });
+		return sum.value(); 
+	}
+}; 
+
+
+double CNCC3DImageCost::do_value(const Data& a, const Data& b, const Mask& m) const
+{
+	FEvalCost ecost(m); 
+	return mia::filter(ecost, a, b); 
+}
+
+
+class FEvalCostForce : public TFilter<float> {
+	const C3DBitImage& m_mask; 
+	C3DFVectorfield& m_force; 
+public: 
+	FEvalCostForce(const C3DBitImage& mask, C3DFVectorfield& force):
+		m_mask(mask), 
+		m_force(force)
+		{}
+	
+	template <typename T, typename R> 
+	float operator () ( const T& mov, const R& ref) const {
+		CThreadMsgStream msks;
+		
+		NCCSums sum; 
+		FEvaluateNCCSum<T,R> ev(m_mask, mov, ref); 
+		sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), sum, ev, 
+					 [](const NCCSums& x, const NCCSums& y){
+					      return x + y;
+				      });
+		
+		auto geval = sum.get_grad_helper(); 
+
+		auto grad = get_gradient(mov); 
+		auto grad_eval = [this, &mov, &ref, &grad, &geval](const tbb::blocked_range<size_t>& range) {
+			for (auto z = range.begin(); z != range.end(); ++z) {
+				auto ig = grad.begin_at(0,0,z); 
+				auto iforce = m_force.begin_at(0,0,z); 
+				auto im = m_mask.begin_at(0,0,z); 
+				auto ia = mov.begin_at(0,0,z); 
+				auto ib = ref.begin_at(0,0,z); 
+				auto eb = ref.begin_at(0,0,z+1); 
+				
+				while (ib != eb) {
+					if (*im) {
+						*iforce = geval.second.get_gradient_scale(*ia, *ib) * *ig; 
+					}
+					++ig; 
+					++iforce; 
+					++ia; ++ib; ++im; 
+				}
+			}; 
+		}; 
+		
+		parallel_for(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), grad_eval); 
+
+		return geval.first; 
+	}
+	
+};
+
+double CNCC3DImageCost::do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const
+{
+	FEvalCostForce ecostforce(m, force); 
+	return mia::filter(ecostforce, a, b); 
+}
+
+
+CNCC3DImageCostPlugin::CNCC3DImageCostPlugin():
+C3DMaskedImageCostPlugin("ncc")
+{
+}
+
+C3DMaskedImageCost *CNCC3DImageCostPlugin::do_create() const
+{
+	return new CNCC3DImageCost();
+}
+
+const std::string CNCC3DImageCostPlugin::do_get_descr() const
+{
+	return "normalized cross correlation with masking support."; 
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new CNCC3DImageCostPlugin();
+}
+
+NS_END
diff --git a/mia/3d/maskedcost/ncc.hh b/mia/3d/maskedcost/ncc.hh
new file mode 100644
index 0000000..dc7b80e
--- /dev/null
+++ b/mia/3d/maskedcost/ncc.hh
@@ -0,0 +1,52 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_maskedcost_ncc_hh
+#define mia_3d_maskedcost_ncc_hh
+
+#include <mia/3d/maskedcost.hh>
+
+#define NS mia_3d_maskedncc
+
+NS_BEGIN(NS)
+
+class CNCC3DImageCost: public mia::C3DMaskedImageCost {
+public: 	
+	typedef mia::C3DMaskedImageCost::Data Data; 
+	typedef mia::C3DMaskedImageCost::Force Force; 
+	typedef mia::C3DMaskedImageCost::Mask Mask; 
+
+	CNCC3DImageCost();
+private: 
+	virtual double do_value(const Data& a, const Data& b, const Mask& m) const; 
+	virtual double do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const; 
+};
+
+class CNCC3DImageCostPlugin: public mia::C3DMaskedImageCostPlugin {
+public: 
+	CNCC3DImageCostPlugin();
+	mia::C3DMaskedImageCost *do_create() const;
+private: 
+	const std::string do_get_descr() const; 
+};
+
+NS_END
+
+#endif 
diff --git a/mia/3d/maskedcost/ssd.cc b/mia/3d/maskedcost/ssd.cc
new file mode 100644
index 0000000..7056db4
--- /dev/null
+++ b/mia/3d/maskedcost/ssd.cc
@@ -0,0 +1,38 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/maskedcost/ssd.hh>
+#include <mia/template/ssd_masked.cxx>
+
+NS_BEGIN(NS)
+
+NS_MIA_USE;
+using namespace std;
+using namespace boost;
+
+template class TSSDMaskedImageCost<mia::C3DMaskedImageCost>;
+template class TSSDMaskedImageCostPlugin<mia::C3DMaskedImageCostPlugin, mia::C3DMaskedImageCost>; 
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C3DSSDMaskedCostPlugin();
+}
+
+NS_END
diff --git a/mia/3d/maskedcost/ssd.hh b/mia/3d/maskedcost/ssd.hh
new file mode 100644
index 0000000..310a42a
--- /dev/null
+++ b/mia/3d/maskedcost/ssd.hh
@@ -0,0 +1,37 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_maskedcost_ssd_hh
+#define mia_3d_maskedcost_ssd_hh
+
+#include <mia/3d/maskedcost.hh>
+
+#define NS mia_3dcost_ssd_masked
+#include <mia/template/ssd_masked.hh>
+
+NS_BEGIN(NS)
+
+typedef TSSDMaskedImageCost<mia::C3DMaskedImageCost> C3DSSDMaskedImageCost;
+typedef TSSDMaskedImageCostPlugin<mia::C3DMaskedImageCostPlugin, mia::C3DMaskedImageCost> C3DSSDMaskedCostPlugin; 
+
+NS_END
+
+
+#endif
diff --git a/mia/3d/maskedcost/test_lncc.cc b/mia/3d/maskedcost/test_lncc.cc
new file mode 100644
index 0000000..9fbee5d
--- /dev/null
+++ b/mia/3d/maskedcost/test_lncc.cc
@@ -0,0 +1,194 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <mia/internal/plugintester.hh>
+#include <mia/3d/maskedcost/lncc.hh>
+
+using namespace NS; 
+using namespace mia; 
+
+
+
+
+BOOST_AUTO_TEST_CASE( test_masked_lncc_1 ) 
+{
+        C3DBounds size(4,4,4); 
+        auto lncc = BOOST_TEST_create_from_plugin<CLNCC3DImageCostPlugin>("lncc:w=1");
+
+        	const float src_data[64] = {           /*   0  1  2  3  4  5  6  7  8  9     */    
+		1, 1, 2, 2, 
+		2, 3, 4, 4,        /*1                                 0 */
+		4, 4, 3, 3, 
+		2, 2, 2, 1,        /*2     1  2  1  1     1            6 */
+		
+		2, 2, 3, 4, 
+		5, 6, 7, 8,        /*3        1  2     1  1  1  1      7 */
+		8, 7, 2, 8, 
+		3, 4, 2, 2,        /*4     1     1  1     2  1  1      7 */ 
+		
+		3, 1, 3, 4, 
+		5, 6, 7, 8,        /*5     1     2  1        2  1      7 */
+		3, 4, 4, 5, 
+		6, 4, 2, 2,        /*6        3     3     1            7 */
+		
+	        3, 2, 3, 4, 
+		5, 3, 1, 4,        /*7     1  1  2  2  1               7 */
+		5, 6, 7, 3, 
+		2, 1, 2, 6         /*8     1  2  1        2  1         7 */
+		};                                     /*      5  9  9  8  2  7  5  3        */
+	
+	const float ref_data[64] = {
+		1, 1, 1, 5, 
+		1, 1, 1, 1, 
+		2, 2, 2, 7,
+		2, 2, 2, 2,
+		
+		3, 3, 3, 5, 
+		3, 3, 3, 3, 
+		4, 4, 6, 4, 
+		3, 4, 4, 4,
+
+		5, 5, 5, 6, 
+		4, 2, 1, 5, 
+		6, 6, 4, 5, 
+		6, 6, 6, 6,
+		
+	        7, 7, 7, 7, 
+		7, 5, 7, 7, 
+		8, 8, 8, 8, 
+		8, 8, 8, 8
+	};
+
+	const bool mask_data[64] = {
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+	        0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1
+	};
+
+        
+	C3DFImage src_f(size, src_data); 
+        C3DFImage ref_f(size, ref_data); 
+        C3DBitImage mask(size, mask_data); 
+
+        
+        lncc->set_reference(ref_f); 
+        BOOST_CHECK_SMALL(lncc->value(ref_f, mask), 1e-10);
+        
+        auto v = lncc->value(src_f, mask); 
+        BOOST_CHECK_CLOSE(v, 1.0 - 0.1206397729, 0.1); 
+        
+	C3DFVectorfield zero_force(size); 
+	v = lncc->evaluate_force(ref_f, mask, zero_force); 
+	BOOST_CHECK_SMALL(v,  1e-10);
+
+	for (auto iv = zero_force.begin(); iv != zero_force.end();  ++iv) {
+		BOOST_CHECK_SMALL(iv->x, 1e-8f); 
+		BOOST_CHECK_SMALL(iv->y, 1e-8f); 
+		BOOST_CHECK_SMALL(iv->z, 1e-8f); 
+	}
+	
+	
+
+
+	C3DFVectorfield force(size); 
+
+	v = lncc->evaluate_force(src_f, mask, force); 
+	BOOST_CHECK_CLOSE(v, 1.0 - 0.1206397729, 0.1); 
+        
+	
+	float gradx[] = {
+		0,0.0064692292,0.0067829344,0, 
+		0,0.0211819153,0.0025820212,0, 
+		0,-0.0034389918,-0.0007584461,0, 
+		0,0,-0.0051883059,0, 
+		
+		0,0.0001722104,0,0, 
+		0.,8.16718273792367E-005,-0.0002484197,0, 
+		0,0.0008372734,0.0021445316, 0, 
+		0,-0.0009001972,-0.0003612011,0, 
+		
+		0,0,-0.0051916234,0, 
+		0,-0.0158841787,-0.0215016708,0, 
+		0,0.0032574205,-0.0051260847,0, 
+		0,-0.0004368596,0.0001938512,0, 
+		
+		0,0,0.0296423058,0, 
+		0,0.0132227233,0.001550289,0, 
+		0,0.0402855406,-0.0435344672,0, 
+		0,0,-0.0193401882,0
+	};
+
+	float grady[] = {
+		0,0,0,0,
+		0.0676691729,0.0317728729,0.0025820212,-0.0056788204,
+		0,-0.0034389918,-0.0015168922,-0.0150381199,
+		0,0,0,0,
+		0,0,0,0,
+		0.0041567101,0.0002041796,0.0001242098,-0.0022727478,
+		0,0.0002790911,-0.0107226582,-0.0106848188,
+		0,0,0,0,
+		0,0,0,0,
+		0,-0.023826268,-0.0107508354,0.0073412295,
+		0,-0.0065148409,0.0256304233,0.0056020016,
+		0,0,0,0,
+		0,0,0,0,
+		0.015625,-0.0132227233,0.0062011562,-0.0092450912,
+		0,-0.0402855406,0.0145114891,0.019820525,
+		0,0,0,0
+	}; 
+	
+	float gradz[] = {
+		0,0,0,0,
+		0,0,0,0,
+		0,0,0,0,
+		0,0,0,0,
+		
+		0,0,0,0.003136997,
+		0.002078355,0.0001225077,-0.0003726295,-0.0022727478,
+		0,0,0.0021445316,0.0035616063,
+		0.0282984061,0.0018003944,0,0.0004336735,
+		
+		0,0,0,0,
+		0,0.023826268,0.0645050124,-0.0293649178,
+		0,-0.0032574205,-0.0256304233,0.0046683347,
+		-0.0065214016,-0.0003276447,0,-0.0010597761,
+		
+		0,0,0,0,
+		0,0,0,0,
+		0,0,0,0,
+		0,0,0,0
+		
+	}; 
+
+	auto igx = gradx; 
+	auto igy = grady; 
+	auto igz = gradz; 
+	for (auto iv = force.begin(); iv != force.end();  ++iv, ++igx, ++igy, ++igz) {
+		BOOST_CHECK_CLOSE(iv->x, *igx, 0.1); 
+		BOOST_CHECK_CLOSE(iv->y, *igy, 0.1); 
+		BOOST_CHECK_CLOSE(iv->z, *igz, 0.1); 
+	}
+}
diff --git a/mia/3d/maskedcost/test_mi.cc b/mia/3d/maskedcost/test_mi.cc
new file mode 100644
index 0000000..195af86
--- /dev/null
+++ b/mia/3d/maskedcost/test_mi.cc
@@ -0,0 +1,170 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <mia/3d/maskedcost/mi.hh>
+#include <cmath>
+
+
+NS_MIA_USE
+using namespace std;
+using namespace ::boost::unit_test;
+using namespace NS;
+
+class MIFixture {
+protected: 
+	MIFixture(); 
+	
+	
+	C3DBounds size; 
+	P3DImage src; 
+	P3DImage ref; 
+	C3DBitImage mask; 
+	C3DFVectorfield grad; 
+	unique_ptr<C3DMIMaskedImageCost> cost; 
+}; 
+
+
+BOOST_FIXTURE_TEST_CASE( test_MI_3D_self, MIFixture )
+{
+	cost->set_reference(*ref);
+	
+	const double test_cost_value =-1.2440862175787268; 
+
+	double cost_value = cost->value(*ref, mask);
+	BOOST_CHECK_CLOSE(cost_value, test_cost_value, 0.1);
+
+	C3DFVectorfield force(C3DBounds(4,4,4));
+	
+	BOOST_CHECK_CLOSE(cost->evaluate_force(*ref, mask, force), 1.0 * test_cost_value, 0.1);
+
+	// unfortunately the gradient self tests fail because the 
+	// spline based gradent evaluation is not zero at the expected minimum
+}
+
+/*
+   currently all tests fail, because the test values are not yet evaluated
+
+
+BOOST_FIXTURE_TEST_CASE( test_MI_3D, MIFixture )
+{
+	cost->set_reference(*ref);
+	
+	double cost_value = cost->value(*src);
+	BOOST_CHECK_CLOSE(cost_value, -74.402 / 64.0, 0.1);
+
+	C3DFVectorfield force(C3DBounds(8,8));
+
+	BOOST_CHECK_CLOSE(cost->evaluate_force(*src, 1.0, force), -74.402, 0.1);
+
+
+	for (auto iforce = force.begin(), ig = grad.begin(); ig != grad.end(); ++ig, ++iforce) {
+		BOOST_CHECK_CLOSE(iforce->x, ig->x, 0.1f);
+		BOOST_CHECK_CLOSE(iforce->y, ig->y, 0.1f);
+	}; 
+}
+*/
+
+MIFixture::MIFixture():
+	size(4,4,4),
+	mask(size),
+	grad(size) 
+	
+{
+	const float src_data[64] = {           /*   0  1  2  3  4  5  6  7  8  9     */    
+		1, 1, 2, 2, 2, 3, 4, 4,        /*1                                 0 */
+		4, 4, 3, 3, 2, 2, 2, 1,        /*2     1  2  1  1     1            6 */
+		2, 2, 3, 4, 5, 6, 7, 8,        /*3        1  2     1  1  1  1      7 */
+		8, 7, 2, 8, 3, 4, 2, 2,        /*4     1     1  1     2  1  1      7 */ 
+		3, 1, 3, 4, 5, 6, 7, 8,        /*5     1     2  1        2  1      7 */
+		3, 4, 4, 5, 6, 4, 2, 2,        /*6        3     3     1            7 */
+	        3, 2, 3, 4, 5, 3, 1, 4,        /*7     1  1  2  2  1               7 */
+		5, 6, 7, 3, 2, 1, 2, 6         /*8     1  2  1        2  1         7 */
+	};                                     /*      5  9  9  8  2  7  5  3        */
+	
+	const float ref_data[64] = {
+		1, 1, 1, 5, 1, 1, 1, 1, 
+		2, 2, 2, 7, 2, 2, 2, 2,
+		3, 3, 3, 5, 3, 3, 3, 3, 
+		4, 4, 6, 4, 3, 4, 4, 4,
+		5, 5, 5, 6, 4, 2, 1, 5, 
+		6, 6, 4, 5, 6, 6, 6, 6,
+	        7, 7, 7, 7, 7, 5, 7, 7, 
+		8, 8, 8, 8, 8, 8, 8, 8
+	};
+
+	const float mask_data[64] = {
+		0, 0, 0, 0, 0, 0, 0, 0, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+	        0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1
+	};
+
+
+	const float grady[64] = {
+		+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
+		+0.00000, 0.00000,-1.30000, 0.00000,-0.35294,-0.35294,-0.35294, 0.00000,
+		-0.00000,-0.70588, 0.68182, 0.00000, 0.16667, 3.76471, 0.00000, 0.00000,
+		+0.00000,-1.66667,-0.00000, 0.00000,-0.00000, 0.00000,-0.00000,-0.00000,
+		+0.00000,-0.00000,-1.36364,-0.00000, 0.50000, 0.00000, 0.00000, 0.00000,
+		+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.70588, 0.00000,
+		-0.00000,-0.23529,-2.04545, 0.00000,-0.66667, 2.04545, 0.00000,-0.00000,
+		+0.00000,+0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000
+	}; 
+	const float gradx[64] = {
+		+ 0.00000,  0.00000, 0.00000, 0.00000, 0.00000, 0.00000,-0.00000,-0.00000, 
+		+ 0.00000,- 0.00000, 1.30000,-0.00000, 0.11765,-0.00000, 0.11765,-0.00000,
+		- 0.00000,- 0.11765,-1.36364, 0.00000, 0.33333, 3.76471, 1.40000, 0.00000, 
+		+ 0.00000,-11.66667, 0.23529, 1.81818, 3.33333,-0.00000, 0.23529,-0.00000, 
+		+ 0.00000,  0.00000,-2.04545, 0.00000, 0.33333, 0.40000, 0.00000, 0.00000,
+	        - 0.00000,  0.00000, 0.00000, 0.33333,-0.20000, 0.00000, 0.23529,-0.00000,
+		- 0.00000,- 0.35294,-1.36364,-0.00000,-0.16667, 2.72727, 0.00000,-0.00000,
+		+ 0.00000,  0.00000,-0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000
+	}; 
+
+	const float gradz[64] = {
+		+ 0.00000,  0.00000, 0.00000, 0.00000, 0.00000, 0.00000,-0.00000,-0.00000, 
+		+ 0.00000,- 0.00000, 1.30000,-0.00000, 0.11765,-0.00000, 0.11765,-0.00000,
+		- 0.00000,- 0.11765,-1.36364, 0.00000, 0.33333, 3.76471, 1.40000, 0.00000, 
+		+ 0.00000,-11.66667, 0.23529, 1.81818, 3.33333,-0.00000, 0.23529,-0.00000, 
+		+ 0.00000,  0.00000,-2.04545, 0.00000, 0.33333, 0.40000, 0.00000, 0.00000,
+	        - 0.00000,  0.00000, 0.00000, 0.33333,-0.20000, 0.00000, 0.23529,-0.00000,
+		- 0.00000,- 0.35294,-1.36364,-0.00000,-0.16667, 2.72727, 0.00000,-0.00000,
+		+ 0.00000,  0.00000,-0.00000, 0.00000, 0.00000, 0.00000, 0.00000, 0.00000
+	}; 
+
+	copy(mask_data, mask_data + 64, mask.begin()); 
+	src.reset(new C3DFImage(size, src_data ));
+	ref.reset(new C3DFImage(size, ref_data ));
+	
+
+	auto ig = grad.begin(); 
+	for (int i = 0; i < 64; ++i, ++ig) {
+		ig->x = gradx[i]; 
+		ig->y = grady[i];
+		ig->z = gradz[i];
+	}
+	cost.reset(new 	C3DMIMaskedImageCost(8, produce_spline_kernel("bspline:d=0"), 
+					     8, produce_spline_kernel("bspline:d=3"), 0)); 
+}
diff --git a/mia/3d/maskedcost/test_ncc.cc b/mia/3d/maskedcost/test_ncc.cc
new file mode 100644
index 0000000..b4c17cb
--- /dev/null
+++ b/mia/3d/maskedcost/test_ncc.cc
@@ -0,0 +1,172 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+#include <mia/3d/maskedcost/ncc.hh>
+#include <mia/core/nccsum.hh>
+
+using namespace NS; 
+using namespace mia; 
+
+
+
+
+BOOST_AUTO_TEST_CASE( test_masked_ncc_zero ) 
+{
+        C3DBounds size(4,4,4); 
+        auto ncc = BOOST_TEST_create_from_plugin<CNCC3DImageCostPlugin>("ncc");
+        
+        C3DFImage a(size); 
+        C3DFImage b(size); 
+        C3DBitImage mask(size); 
+
+        fill(mask.begin(), mask.end(), true); 
+        
+        auto ia = a.begin_range(C3DBounds::_0, size); 
+        auto ib = b.begin_range(C3DBounds::_0, size); 
+        auto ea = a.end_range(C3DBounds::_0, size); 
+
+        while (ia != ea) {
+                *ia = ia.pos().x + ia.pos().y + ia.pos().z; 
+                *ib = 2* *ia; 
+                ++ib; ++ia; 
+        }
+
+        ncc->set_reference(b); 
+        BOOST_CHECK_SMALL(ncc->value(b, mask), 1e-7); 
+
+        BOOST_CHECK_SMALL(ncc->value(a, mask), 1e-7); 
+        
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_masked_ncc_nonzero ) 
+{
+        C3DBounds size(4,4,4); 
+        auto ncc = BOOST_TEST_create_from_plugin<CNCC3DImageCostPlugin>("ncc");
+        
+        C3DFImage a(size); 
+        C3DFImage b(size); 
+        C3DBitImage mask(size); 
+
+        fill(mask.begin(), mask.end(), true); 
+        
+        auto ia = a.begin_range(C3DBounds::_0, size); 
+        auto ib = b.begin_range(C3DBounds::_0, size); 
+        auto ea = a.end_range(C3DBounds::_0, size); 
+
+        NCCSums sum; 
+
+        while (ia != ea) {
+                *ia = ia.pos().x + ia.pos().y + ia.pos().z; 
+                *ib = ia.pos().x + ia.pos().y * ia.pos().z; 
+                sum.add(*ia, *ib); 
+                ++ib; ++ia; 
+        }
+
+        ncc->set_reference(b); 
+        BOOST_CHECK_CLOSE(ncc->value(a, mask), sum.value(), 0.1); 
+        
+        C3DFVectorfield grad(size); 
+
+        BOOST_CHECK_CLOSE(ncc->evaluate_force(a, mask, grad), sum.value(), 0.01);
+
+
+	auto ag = get_gradient(a); 
+	
+	auto iag = ag.begin(); 
+	auto ia2 = a.begin(); 
+	auto ib2 = b.begin(); 
+	auto iforce = grad.begin(); 
+	auto eforce = grad.end(); 
+
+	auto gs = sum.get_grad_helper().second; 
+	while (iforce != eforce) {
+		auto expect = *iag * gs.get_gradient_scale(*ia2, *ib2); 
+		BOOST_CHECK_CLOSE(iforce->x, expect.x, 0.01); 
+		BOOST_CHECK_CLOSE(iforce->y, expect.y, 0.01); 
+		BOOST_CHECK_CLOSE(iforce->z, expect.z, 0.01); 
+		++iag; ++ia2; ++ib2; ++iforce;
+	}
+}
+
+
+BOOST_AUTO_TEST_CASE( test_masked_ncc_nonzero_with_mask ) 
+{
+        C3DBounds size(4,4,4); 
+        auto ncc = BOOST_TEST_create_from_plugin<CNCC3DImageCostPlugin>("ncc");
+        
+        C3DFImage a(size); 
+        C3DFImage b(size); 
+        C3DBitImage mask(size); 
+
+        fill(mask.begin(), mask.end(), true); 
+	mask(2,3,1) = false; 
+	mask(1,2,1) = false; 
+        
+        auto ia = a.begin_range(C3DBounds::_0, size); 
+        auto ib = b.begin_range(C3DBounds::_0, size); 
+        auto im = mask.begin_range(C3DBounds::_0, size); 
+        auto ea = a.end_range(C3DBounds::_0, size); 
+
+        NCCSums sum; 
+
+        while (ia != ea) {
+		if (*im) {
+			*ia = ia.pos().x + ia.pos().y + ia.pos().z; 
+			*ib = ia.pos().x + ia.pos().y * ia.pos().z; 
+			sum.add(*ia, *ib); 
+		}
+                ++ib; ++ia; ++im; 
+        }
+
+        ncc->set_reference(b); 
+        BOOST_CHECK_CLOSE(ncc->value(a, mask), sum.value(), 0.1); 
+        
+        C3DFVectorfield grad(size); 
+
+        BOOST_CHECK_CLOSE(ncc->evaluate_force(a, mask, grad), sum.value(), 0.01);
+
+
+	auto ag = get_gradient(a); 
+	
+	auto iag = ag.begin(); 
+	auto ia2 = a.begin(); 
+	auto ib2 = b.begin(); 
+	auto im2 = mask.begin(); 
+	auto iforce = grad.begin(); 
+	auto eforce = grad.end(); 
+
+	auto gs = sum.get_grad_helper().second; 
+	while (iforce != eforce) {
+		if (*im2) {
+			auto expect = *iag * gs.get_gradient_scale(*ia2, *ib2); 
+			BOOST_CHECK_CLOSE(iforce->x, expect.x, 0.01); 
+			BOOST_CHECK_CLOSE(iforce->y, expect.y, 0.01); 
+			BOOST_CHECK_CLOSE(iforce->z, expect.z, 0.01); 
+		}else{
+			BOOST_CHECK_SMALL(iforce->x, 1e-8f); 
+			BOOST_CHECK_SMALL(iforce->y, 1e-8f); 
+			BOOST_CHECK_SMALL(iforce->z, 1e-8f); 
+		}
+		++iag; ++ia2; ++ib2; ++iforce; ++im2; 
+	}
+}
+
diff --git a/mia/3d/maskedcost/test_ssd.cc b/mia/3d/maskedcost/test_ssd.cc
new file mode 100644
index 0000000..d28ba17
--- /dev/null
+++ b/mia/3d/maskedcost/test_ssd.cc
@@ -0,0 +1,154 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <mia/3d/maskedcost/ssd.hh>
+#include <cmath>
+
+
+NS_MIA_USE
+using namespace std;
+using namespace ::boost::unit_test;
+using namespace NS;
+
+
+class SSDFixture {
+protected: 
+	SSDFixture(); 
+	
+	
+	C3DBounds size; 
+	P3DImage src; 
+	P3DImage ref; 
+	C3DBitImage mask; 
+	C3DFVectorfield grad; 
+	unique_ptr<C3DSSDMaskedImageCost> cost; 
+
+	double test_cost_pair; 
+}; 
+
+
+BOOST_FIXTURE_TEST_CASE( test_SSD_3D_self, SSDFixture )
+{
+	cost->set_reference(*ref);
+	
+	const double test_cost_value =-0.0; 
+
+	double cost_value = cost->value(*ref, mask);
+	BOOST_CHECK_CLOSE(cost_value, test_cost_value, 0.1);
+
+	C3DFVectorfield force(C3DBounds(4,4,4));
+	
+	BOOST_CHECK_CLOSE(cost->evaluate_force(*ref, mask, force), 1.0 * test_cost_value, 0.1);
+	
+	for(auto g : force) {
+		BOOST_CHECK_EQUAL(g, C3DFVector(0,0,0));
+	}
+}
+
+BOOST_FIXTURE_TEST_CASE( test_SSD_3D_pair, SSDFixture )
+{
+	cost->set_reference(*ref);
+	
+	double cost_value = cost->value(*src, mask);
+	BOOST_CHECK_CLOSE(cost_value, test_cost_pair, 0.1);
+
+	C3DFVectorfield force(C3DBounds(4,4,4));
+	
+	BOOST_CHECK_CLOSE(cost->evaluate_force(*src, mask, force), test_cost_pair, 0.1);
+
+	for(auto iforce = force.begin(), iexpect = grad.begin(); iforce != force.end(); 
+	    ++iforce, ++iexpect) {
+		BOOST_CHECK_CLOSE(iforce->x, iexpect->x, 0.1);
+		BOOST_CHECK_CLOSE(iforce->y, iexpect->y, 0.1);
+		BOOST_CHECK_CLOSE(iforce->z, iexpect->z, 0.1);
+	} 
+}
+
+
+SSDFixture::SSDFixture():
+	size(4,4,4),
+	mask(size),
+	grad(size) 
+{
+	const float src_data[64] = {           /*   0  1  2  3  4  5  6  7  8  9     */    
+		1, 1, 2, 2, 2, 3, 4, 4,        /*1                                 0 */
+		4, 4, 3, 3, 2, 2, 2, 1,        /*2     1  2  1  1     1            6 */
+		2, 2, 3, 4, 5, 6, 7, 8,        /*3        1  2     1  1  1  1      7 */
+		8, 7, 2, 8, 3, 4, 2, 2,        /*4     1     1  1     2  1  1      7 */ 
+		3, 1, 3, 4, 5, 6, 7, 8,        /*5     1     2  1        2  1      7 */
+		3, 4, 4, 5, 6, 4, 2, 2,        /*6        3     3     1            7 */
+	        3, 2, 3, 4, 5, 3, 1, 4,        /*7     1  1  2  2  1               7 */
+		5, 6, 7, 3, 2, 1, 2, 6         /*8     1  2  1        2  1         7 */
+	};                                     /*      5  9  9  8  2  7  5  3        */
+	
+	const float ref_data[64] = {
+		1, 1, 1, 5, 1, 1, 1, 1, 
+		2, 2, 2, 7, 2, 2, 2, 2,
+		3, 3, 3, 5, 3, 3, 3, 3, 
+		4, 4, 6, 4, 3, 4, 4, 4,
+		5, 5, 5, 6, 4, 2, 1, 5, 
+		6, 6, 4, 5, 6, 6, 6, 6,
+	        7, 7, 7, 7, 7, 5, 7, 7, 
+		8, 8, 8, 8, 8, 8, 8, 8
+	};
+
+	const float mask_data[64] = {
+		0, 0, 0, 0, 0, 0, 0, 0, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+		0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1,
+	        0, 1, 1, 1, 1, 1, 1, 1, 
+		0, 1, 1, 1, 1, 1, 1, 1
+	};
+
+
+	
+
+	copy(mask_data, mask_data + 64, mask.begin()); 
+	auto src_f = new C3DFImage(size, src_data ); 
+	src.reset(src_f);
+	auto ref_f = new C3DFImage(size, ref_data ); 
+	ref.reset(ref_f);
+	
+
+	grad = get_gradient(*src_f); 
+
+	auto ig = grad.begin(); 
+	auto is = src_f->begin(); 
+	auto ir = ref_f->begin(); 
+	auto im = mask.begin(); 
+	auto em = mask.end(); 
+
+	test_cost_pair = 0.0; 
+	while(im != em) {
+		double delta = (*is - *ir); 
+		*ig *= *im * delta / 64.0; 
+		if (*im) 
+			test_cost_pair += delta * delta; 
+
+		++ig; ++is; ++ir; ++im; 
+	}
+	test_cost_pair /= 128.0; 
+	
+	cost.reset(new 	C3DSSDMaskedImageCost); 
+}
diff --git a/mia/3d/matrix.cc b/mia/3d/matrix.cc
new file mode 100644
index 0000000..d2d1b2f
--- /dev/null
+++ b/mia/3d/matrix.cc
@@ -0,0 +1,236 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/matrix.hh>
+
+
+
+NS_MIA_BEGIN
+
+template <typename T> 
+T3DMatrix<T>::T3DMatrix(const T3DMatrix<T>& o):
+	T3DVector< T3DVector<T> >
+        (o.x, o.y, o.z)
+{
+}
+
+
+template <typename T> 
+T3DMatrix<T>& T3DMatrix<T>::operator = (const T3DMatrix<T>& o)
+{
+	this->x = o.x; 
+	this->y = o.y; 
+	this->z = o.z; 
+
+	this->m_esolver.reset(nullptr); 
+	return *this; 
+
+}
+
+template <typename T> 
+T3DMatrix<T> T3DMatrix<T>::diagonal(T v)
+{
+	return T3DMatrix<T>(T3DVector< T >(v,0,0), 
+			    T3DVector< T >(0,v,0),
+			    T3DVector< T >(0,0,v));
+}
+
+template <typename T> 
+T3DMatrix<T> T3DMatrix<T>::diagonal(const T3DVector<T>& v)
+{
+	return T3DMatrix<T>(T3DVector< T >(v.x,0,0), 
+			    T3DVector< T >(0,v.y,0),
+			    T3DVector< T >(0,0,v.z));
+}
+
+template <typename T> 
+T3DMatrix<T>::T3DMatrix(const T3DVector< T3DVector<T> >& other):
+	T3DVector<T3DVector<T> >(other.x, other.y, other.z)
+{
+}
+
+template <typename T> 
+T3DMatrix<T>::T3DMatrix(const T3DVector< T >& x, const T3DVector< T >& y, const T3DVector< T >& z ):
+	T3DVector<T3DVector<T> >(x, y, z)
+{
+}
+template <typename T> 
+void T3DMatrix<T>::print( std::ostream& os) const
+{
+	os  << this->x << "; " << this->y << "; " << this->z; 
+}
+
+template <typename T> 
+T3DMatrix<T>  T3DMatrix<T>::transposed()const
+{
+	return T3DMatrix<T>(T3DVector<T>(this->x.x, this->y.x, this->z.x), 
+			    T3DVector<T>(this->x.y, this->y.y, this->z.y), 
+			    T3DVector<T>(this->x.z, this->y.z, this->z.z)); 
+}
+
+template <typename T> 
+void T3DMatrix<T>::evaluate_ev() const
+{
+	EMatrix3  matrix; 
+	matrix << this->x.x, this->x.y, this->x.z, /**/ this->y.x, this->y.y, this->y.z, /**/  this->z.x, this->z.y, this->
+z.z; 
+	m_esolver.reset( new ESolver3(matrix, true)); 
+
+	auto eval = m_esolver->eigenvalues(); 
+
+	// check if there are complex eigenvalues
+	bool complex = false; 
+	for (int i = 0; i < 3 && !complex; ++i) {
+		if (eval[i].imag() != 0.0) {
+			complex = true; 
+		}
+	}
+	
+	if (complex) {
+		for (int i = 0; i < 3; ++i) {
+			if (eval[i].imag() == 0.0) {
+				m_ev_order[0] = i; 
+				// in the complex case, the two complex evalues are 
+				// conjugated complex 
+				m_ev_order[1] = i+1 % 3; 
+				m_ev_order[2] = i+1 % 3; 
+				return; 
+			}
+		}
+	}
+
+	// not complex, just sort the eval indices
+	double evnorms[3]; 
+	for (int i = 0; i < 3; ++i)
+		evnorms[i] = std::norm(eval(i)); 
+
+
+		
+	if (evnorms[0] < evnorms[1]) {
+                if (evnorms[0] < evnorms[2]) {
+			m_ev_order[2] = 0; 
+                        if (evnorms[1] < evnorms[2]) {
+				m_ev_order[0] = 2; 
+				m_ev_order[1] = 1; 
+		
+                        }else{
+				m_ev_order[0] = 1; 
+				m_ev_order[1] = 2; 
+			}
+                }else {
+			m_ev_order[0] = 1; 
+			m_ev_order[1] = 0; 
+			m_ev_order[2] = 2; 
+		}
+                        
+        } else { 
+                
+                if (evnorms[0] > evnorms[2]) {
+			m_ev_order[0] = 0; 
+			
+                        if (evnorms[1] < evnorms[2]) {
+				m_ev_order[1] = 2; 
+				m_ev_order[2] = 1; 
+			}else{
+				m_ev_order[1] = 1; 
+				m_ev_order[2] = 2; 
+			}
+
+                }else{ 
+			m_ev_order[0] = 2; 
+			m_ev_order[1] = 0; 
+			m_ev_order[2] = 1; 
+		}
+	}
+}
+
+template <typename T> 
+int T3DMatrix<T>::get_rank()const
+{
+	C3DFVector ev; 
+	auto type = this->get_eigenvalues(ev); 
+	cvdebug()<< "Matrix = "<< *this <<", Rank: eigenvalues: " << ev << "\n"; 
+	
+	switch (type) {
+	case 1: return (ev.x != 0.0) ? 3 : 2; 
+	case 3: return (ev.z != 0.0) ? 3 : 2; 
+	default: {
+		int rank = 0; 
+		if (ev.x != 0.0)  
+			rank++; 
+		if (ev.y != 0.0)  
+			rank++; 
+		if (ev.z != 0.0)  
+			rank++; 
+		return rank; 
+	}
+
+	}
+}
+
+template <class T>
+T T3DMatrix<T>::get_det()  const 
+{
+	return  dot(this->x,T3DVector<T>(this->y.y * this->z.z - this->z.y * this->y.z, 
+					 this->y.z * this->z.x - this->y.x * this->z.z, 
+					 this->y.x * this->z.y - this->y.y * this->z.x)); 
+}
+
+
+template <typename T> 
+int T3DMatrix<T>::get_eigenvalues(C3DFVector& result)const
+{
+	if (!m_esolver) 
+		evaluate_ev(); 
+
+	auto eval = m_esolver->eigenvalues(); 
+
+	result.x = eval[m_ev_order[0]].real(); 
+	
+	if (m_ev_order[1] == m_ev_order[2]) {
+		// complex case
+		result.y = eval[m_ev_order[1]].real(); 
+		result.y = eval[m_ev_order[2]].imag(); 
+		return 1;
+	}
+
+	result.y = eval[m_ev_order[1]].real(); 
+	result.z = eval[m_ev_order[2]].real();
+
+	if (result.x == result.y || result.y == result.z) 
+		return 2; 
+	return 3; 
+}
+
+template <typename T> 
+C3DFVector T3DMatrix<T>::get_eigenvector(int i)const
+{
+	if (!m_esolver) 
+		evaluate_ev(); 
+	
+
+	const auto evec = m_esolver->eigenvectors().col(m_ev_order[i]); 
+	return C3DFVector(evec(0).real(), evec(1).real(), evec(2).real()); 
+}
+
+template class T3DMatrix<float>; 
+template class T3DMatrix<double>; 
+
+NS_MIA_END
diff --git a/mia/3d/matrix.hh b/mia/3d/matrix.hh
index edd6b08..56c477a 100644
--- a/mia/3d/matrix.hh
+++ b/mia/3d/matrix.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,6 +20,22 @@
 #ifndef __mia_3d_matrix_hh
 #define __mia_3d_matrix_hh
 
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#ifndef __clang__ 
+#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#endif 
+#endif 
+
+#include <Eigen/Core>
+#include <Eigen/Eigenvalues> 
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif 
+
+#include <memory>
+
 #include <mia/3d/vector.hh>
 #include <mia/core/msgstream.hh>
 
@@ -36,10 +52,15 @@ NS_MIA_BEGIN
  */
 
 template <typename T> 
-struct T3DMatrix: public T3DVector< T3DVector<T> > {
+class T3DMatrix: public T3DVector< T3DVector<T> > {
+
+
+public:  
 	
 	T3DMatrix() = default; 
-	T3DMatrix(const T3DMatrix<T>& o) = default; 
+	T3DMatrix(const T3DMatrix<T>& o); 
+
+	T3DMatrix<T>& operator = (const T3DMatrix<T>& o); 
 
 
 	/**
@@ -127,12 +148,10 @@ struct T3DMatrix: public T3DVector< T3DVector<T> > {
 
 	/** Calculate the eigenvector to a given eigenvalues. If the eigenvalue is complex, the 
 	    matrix has to be propagated to a complex one using the type converting copy constructor
-	    \param[in] ev the eigenvalue
-	    \param[out] v the estimated eigenvector 
-	    \returns 0 eigenvector is valid
-	             2 no eigenvector found
+	    \param i number of eigenvector 
+	    \returns the requested eigenvector
 	 */
-	int get_eigenvector(float ev, C3DFVector& v)const; 
+	C3DFVector get_eigenvector(int i)const; 
 
 
 	/// The unity matrix 
@@ -141,61 +160,39 @@ struct T3DMatrix: public T3DVector< T3DVector<T> > {
 	/// The zero matrix 
 	static const T3DMatrix _0; 
 
-}; 
-
-
-/// a simple 3x3 matrix 
-typedef T3DMatrix<float> C3DFMatrix; 
-
-
-template <typename T> 
-const T3DMatrix<T> T3DMatrix<T>::_1(T3DVector< T >(1,0,0), 
-				 T3DVector< T >(0,1,0),
-				 T3DVector< T >(0,0,1));
-
-template <typename T> 
-const T3DMatrix<T> T3DMatrix<T>::_0 = T3DMatrix<T>();
-
-
-template <typename T> 
-T3DMatrix<T> T3DMatrix<T>::diagonal(T v)
-{
-	return T3DMatrix<T>(T3DVector< T >(v,0,0), 
-			    T3DVector< T >(0,v,0),
-			    T3DVector< T >(0,0,v));
-}
+private:
+	void evaluate_ev() const; 
 
-template <typename T> 
-T3DMatrix<T> T3DMatrix<T>::diagonal(const T3DVector<T>& v)
-{
-	return T3DMatrix<T>(T3DVector< T >(v.x,0,0), 
-			    T3DVector< T >(0,v.y,0),
-			    T3DVector< T >(0,0,v.z));
-}
+	typedef Eigen::Matrix<T, 3, 3> EMatrix3; 
+	typedef Eigen::EigenSolver<EMatrix3>  ESolver3; 
+		
+	mutable std::unique_ptr<ESolver3> m_esolver; 
+	mutable int m_ev_order[3]; 
+}; 
 
 template <typename T> 
 template <typename I>
 T3DMatrix<T>::T3DMatrix(const T3DMatrix<I>& o):
-	T3DVector<T3DVector<T> >(o.x, o.y, o.z)
+	T3DVector<T3DVector<T> >(T3DVector<T>(o.x), 
+				 T3DVector<T>(o.y), 
+				 T3DVector<T>(o.z))
 {
 }
 
 template <typename T> 
-T3DMatrix<T>::T3DMatrix(const T3DVector< T3DVector<T> >& other):
-	T3DVector<T3DVector<T> >(other.x, other.y, other.z)
+T3DVector<T> operator * (const T3DMatrix<T>& m, const T3DVector<T>& x)
 {
+	return T3DVector<T>(dot(m.x, x), dot(m.y, x), dot(m.z, x)); 
 }
 
 template <typename T> 
-T3DMatrix<T>::T3DMatrix(const T3DVector< T >& x, const T3DVector< T >& y, const T3DVector< T >& z ):
-	T3DVector<T3DVector<T> >(x, y, z)
+T3DVector<T> operator * (const T3DVector<T>& x, const T3DMatrix<T>& m )
 {
+	return T3DVector<T>(m.x.x * x.x + m.y.x * x.y + m.z.x * x.z, 
+			    m.x.y * x.x + m.y.y * x.y + m.z.y * x.z,
+			    m.x.z * x.x + m.y.z * x.y + m.z.z * x.z);
 }
-template <typename T> 
-void T3DMatrix<T>::print( std::ostream& os) const
-{
-	os << "<" << this->x << ", " << this->y << ", " << this->z << " >"; 
-}
+
 
 template <typename T> 
 std::ostream& operator << (std::ostream& os, const T3DMatrix<T>& m) 
@@ -214,28 +211,6 @@ T3DMatrix<T>& T3DMatrix<T>::operator -= (const T3DMatrix<T>& o)
 }
 
 template <typename T> 
-T3DMatrix<T>  T3DMatrix<T>::transposed()const
-{
-	return T3DMatrix<T>(T3DVector<T>(this->x.x, this->y.x, this->z.x), 
-			    T3DVector<T>(this->x.y, this->y.y, this->z.y), 
-			    T3DVector<T>(this->x.z, this->y.z, this->z.z)); 
-}
-
-template <typename T> 
-T3DVector<T> operator * (const T3DVector<T>& x, const T3DMatrix<T>& m)
-{
-	return T3DVector<T>(dot(m.x, x), dot(m.y, x), dot(m.z, x)); 
-}
-
-template <typename T> 
-T3DVector<T> operator * (const T3DMatrix<T>& m, const T3DVector<T>& x  )
-{
-	return T3DVector<T>(m.x.x * x.x + m.y.x * x.y + m.z.x * x.z, 
-			    m.x.y * x.x + m.y.y * x.y + m.z.y * x.z,
-			    m.x.z * x.x + m.y.z * x.y + m.z.z * x.z);
-}
-
-template <typename T> 
 T3DMatrix<T> operator * (const T3DMatrix<T>& m, const T3DMatrix<T>& x  )
 {
 	return T3DMatrix<T>(T3DVector<T>(m.x.x * x.x.x + m.x.y * x.y.x + m.x.z * x.z.x, 
@@ -249,213 +224,23 @@ T3DMatrix<T> operator * (const T3DMatrix<T>& m, const T3DMatrix<T>& x  )
 					 m.z.x * x.x.z + m.z.y * x.y.z + m.z.z * x.z.z));
 }
 
+/// a simple 3x3 matrix with single precision floating point values 
+typedef T3DMatrix<float> C3DFMatrix; 
 
-template <typename T> 
-int T3DMatrix<T>::get_rank()const
-{
-	C3DFVector ev; 
-	this->get_eigenvalues(ev); 
-	cvdebug()<< "Matrix = "<< *this <<", Rank: eigenvalues: " << ev << "\n"; 
-	int rank = 0; 
-	if (ev.x != 0.0)  
-		rank++; 
-	if (ev.y != 0.0)  
-		rank++; 
-	if (ev.z != 0.0)  
-		rank++; 
-	return rank; 
-}
-
-inline double cubrt(double a) 
-{
-	if ( a == 0.0 )
-		return 0.0;
-	return  a > 0.0 ? pow(a,1.0/3.0) : - pow(-a, 1.0/ 3.0); 
-}
-
-
-template <class T>
-T T3DMatrix<T>::get_det()  const 
-{
-	return  dot(this->x,T3DVector<T>(this->y.y * this->z.z - this->z.y * this->y.z, 
-					 this->y.z * this->z.x - this->y.x * this->z.z, 
-					 this->y.x * this->z.y - this->y.y * this->z.x)); 
-}
+/// a simple 3x3 matrix with double precision floating point values 
+typedef T3DMatrix<double> C3DDMatrix; 
 
 
 template <typename T> 
-int T3DMatrix<T>::get_eigenvalues(C3DFVector& result)const
-{
-	int retval = 0; 
-	
-	double t = - get_det();
-	double s =   this->x.x * this->y.y + this->z.z * this->y.y + this->x.x * this->z.z -
-		this->x.y * this->y.x - this->x.z * this->z.x - this->y.z * this->z.y;
-	
-	double r =  - this->x.x - this->y.y - this->z.z;
-	
-	//	 a = 1; 
-	
-	double p = s - r * r / 3.0; 
-	double q = ( 27.0 * t - 9.0 * r * s + 2.0 * r * r * r ) / 27.0;
-	
-	double diskr = q *q / 4.0 + p * p * p / 27.0;
-	
-	cvdebug() << "discr =" << diskr << "\n"; 
-	if ( diskr > 1e-6 ) {
-		// complex solution
-		double sqrt_discr = sqrt(diskr);
-		double u = cubrt( - q/2.0 + sqrt_discr );
-		double v = cubrt( - q/2.0 - sqrt_discr );
-		result.x = u + v - r / 3.0;
-		result.y = -(u + v) / 2.0 - r / 3.0; // real part 
-		result.z = (u - v)/2.0 * sqrt(3.0f);    // imag part
-		return 1;
-		
-	}
-
-	std::vector<double> res(3); 
-	if ( diskr < -1e-6) {
-		double rho = sqrt(-p*p*p/ 27.0); 
-		double cphi = - q / ( 2.0 * rho); 
-		double phi = acos(cphi)/3.0;
-		double sqrt_p = 2 * cubrt(rho);
-		res[0] = sqrt_p * cos(phi)- r/3.;
-		res[1] = sqrt_p * cos(phi + M_PI * 2.0 / 3.0) - r/3.; 
-		res[2] = sqrt_p * cos(phi + M_PI * 4.0 / 3.0) - r/3.; 
-		retval = 3;		
-	} else  { // at least two values are equal, all real  
-		double u = cubrt( - q/2.0 );
-		res[0] = 2.0 * u - r / 3.0;
-		res[1] =  - u - r / 3.0; 
-		res[2] = res[1]; 
-		retval = 2; 
-	}
-	
-	std::sort(res.begin(), res.end(),  [](double x, double y){ return std::fabs(x) > std::fabs(y);}); 
-	
-	for_each(res.begin(), res.end(), [](double& x){ if (std::fabs(x) < 1e-12) x = 0.0;}); 
-
-	result.x = res[0]; 
-	result.y = res[1]; 
-	result.z = res[2];
-	return retval;
-
-}
-
-/** solve a 2x2 system of equations 
-      a11 * x1 + a12 * x2 = b1
-      a21 * x1 + a22 * x2 = b2
-    \param a11
-    \param a12
-    \param b1
-    \param a21
-    \param a22
-    \param b2    
-    \param x1
-    \param x2
-    \returns true if system was solved, false otherwise
-*/
-template<class T> 
-bool solve_2x2(T a11, T a12,T b1,T a21, T a22,T b2,T *x1,T *x2)
-{
-	T h1 = a11 * a22 - a12 * a21; 
-	if (h1 == T())
-		return false;
-	
-	*x1 = (b1 * a22 - b2 * a12) / h1; 
-	*x2 = (b2 * a11 - b1 * a21) / h1; 
-	return true;
-}
-
-/** some struct to help solving the 3x3 Matrix eigenvalue problem */
-struct solve_lines_t {
-	int a,b; 
-};
-
+const T3DMatrix<T> T3DMatrix<T>::_1(T3DVector< T >(1,0,0), 
+				 T3DVector< T >(0,1,0),
+				 T3DVector< T >(0,0,1));
 
 template <typename T> 
-int T3DMatrix<T>::get_eigenvector(float ev, C3DFVector& v)const
-{
-	const solve_lines_t l[3] = { {0,1}, {1,2}, {2,0}};
-	//	T b1,b2,a11,a12,a21,a22; 
-	if (ev == 0.0) {
-		return 1;
-	}
-	
-	T3DMatrix<T> M = *this - T3DMatrix<T>::diagonal(ev);
-
-	float x = std::abs(M.x.x)+std::abs(M.y.x)+std::abs(M.z.x);
-	float y = std::abs(M.x.y)+std::abs(M.y.y)+std::abs(M.z.y);
-	float z = std::abs(M.x.z)+std::abs(M.y.z)+std::abs(M.z.z);
-	
-	if (x+y+z == 0.0) {
-		v = T3DVector<T>(1,0,0);
-		return 0;
-	}
-
-	T3DVector<int> col;
-	T *rx;
-	T *ry;
-
-	// thats tricky: 
-	// 1st col index is 1st column in solver 
-	// 2nd col index is 2nd column in solver
-	// 3th col index is right side 
-	// the respective result value is 0=x,1=y,2=z
-	// the right side presenting value of result is preset with 1.0
-	// the others get a pointer
-	
-	if (x < y) {
-		if (x < z){
-			col = T3DVector<int>(1,2,0);
-			rx = &v.y;
-			ry = &v.z;
-			v.x = 1.0;
-		}else{
-			col = T3DVector<int>(0,1,2);
-			rx = &v.x;
-			ry = &v.y;
-			v.z = 1.0; 
-		}
-	}else{
-		if (y < z){
-			col = T3DVector<int>(0,2,1);
-			rx = &v.x;
-			ry = &v.z;
-			v.y = 1.0; 
-
-		}else{
-			col = T3DVector<int>(0,1,2);			
-			rx = &v.x;
-			ry = &v.y;
-			v.z= 1.0;
-		}
-	}
-	
-	bool good = false; 
-	for (int i = 0; i < 3 && !good; i++) {
-		good = solve_2x2(M[l[i].a][col.x],M[l[i].a][col.y],-M[l[i].a][col.z],
-				 M[l[i].b][col.x],M[l[i].b][col.y],-M[l[i].b][col.z],
-				 rx,ry); 
-	}
-	// seems there is no solution
-	if (!good) 
-		return 2; 
-	
-	
-	if ((M * v).norm2() > 1e-5) {
-		
-		// a solution for only two rows is not a solution
-		// but there is no better
-		fprintf(stderr,"WARNING: rank of A-ev*I\n numerical > 2");
-		return 0;
-	}
-	v /= v.norm();	
-	return 0;
-}
-
+const T3DMatrix<T> T3DMatrix<T>::_0 = T3DMatrix<T>();
 
+extern template class EXPORT_3D T3DMatrix<float>; 
+extern template class EXPORT_3D T3DMatrix<double>; 
 
 
 NS_MIA_END
diff --git a/mia/3d/model.cc b/mia/3d/model.cc
index 4e78d86..f1968ac 100644
--- a/mia/3d/model.cc
+++ b/mia/3d/model.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/model.hh b/mia/3d/model.hh
index 30bbde8..b7e35fc 100644
--- a/mia/3d/model.hh
+++ b/mia/3d/model.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -48,6 +48,11 @@ typedef std::shared_ptr<C3DRegModel > P3DRegModel;
 /// the 3D registration model plug-in base class 
 typedef TFactory<C3DRegModel>  C3DRegModelPlugin;
 
+template <> const char *  const TPluginHandler<C3DRegModelPlugin>::m_help; 
+
+extern template class EXPORT_3D TRegModel<3>; 
+extern template class EXPORT_3D TFactory<C3DRegModel>; 
+extern template class EXPORT_3D THandlerSingleton< TFactoryPluginHandler<C3DRegModelPlugin> >;
 /// the 3D registration model plug-in handler 
 typedef THandlerSingleton< TFactoryPluginHandler<C3DRegModelPlugin> > C3DRegModelPluginHandler;
 
diff --git a/mia/3d/multicost.cc b/mia/3d/multicost.cc
index 1cd4ab8..c38466a 100644
--- a/mia/3d/multicost.cc
+++ b/mia/3d/multicost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/multicost.hh b/mia/3d/multicost.hh
index b9e21ad..df39ed0 100644
--- a/mia/3d/multicost.hh
+++ b/mia/3d/multicost.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/multireg.cc b/mia/3d/multireg.cc
index 79f7b5a..c5c6f67 100644
--- a/mia/3d/multireg.cc
+++ b/mia/3d/multireg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/multireg.hh b/mia/3d/multireg.hh
index aac7b97..c44a36e 100644
--- a/mia/3d/multireg.hh
+++ b/mia/3d/multireg.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/nfg.cc b/mia/3d/nfg.cc
index b9127ad..5e91347 100644
--- a/mia/3d/nfg.cc
+++ b/mia/3d/nfg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/nfg.hh b/mia/3d/nfg.hh
index 1c3e6a7..98adc61 100644
--- a/mia/3d/nfg.hh
+++ b/mia/3d/nfg.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/nonrigidregister.cc b/mia/3d/nonrigidregister.cc
index 0c1713e..7993014 100644
--- a/mia/3d/nonrigidregister.cc
+++ b/mia/3d/nonrigidregister.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/nonrigidregister.hh b/mia/3d/nonrigidregister.hh
index c33dbc1..a578f45 100644
--- a/mia/3d/nonrigidregister.hh
+++ b/mia/3d/nonrigidregister.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/orientation.cc b/mia/3d/orientation.cc
index 8fe2e3b..c8b5d53 100644
--- a/mia/3d/orientation.cc
+++ b/mia/3d/orientation.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,48 +19,225 @@
  */
 
 #include <mia/3d/orientation.hh>
+#include <mia/core/utils.hh>
 
 NS_MIA_BEGIN
 using namespace std; 
 
 
-EXPORT_3D  ostream& operator << (ostream& os, E3DImageOrientation orient)
-{
-	switch (orient) {
-	case ior_axial:
-		os << "axial";
-		break;
-	case ior_coronal:
-		os << "coronal";
-		break;
-	case ior_saggital:
-		os << "saggital";
-		break;
-	case ior_unknown:
-		os << "unknown";
-		break;
-	default:
-		os << "undefined";
+C3DOrientationAndPosition::C3DOrientationAndPosition():
+	m_axisorder(ior_default), 
+	m_origin(0,0,0), 
+	m_scale(1,1,1), 
+	m_rotation(1,0,0,0)
+{
+}
+
+C3DOrientationAndPosition::C3DOrientationAndPosition(E3DImageOrientation axis):
+	m_axisorder(axis), 
+	m_origin(0,0,0), 
+	m_scale(1,1,1), 
+	m_rotation(1,0,0,0)
+{
+}
+
+C3DOrientationAndPosition::C3DOrientationAndPosition(E3DImageOrientation axis, 
+						     const C3DFVector& origin, 
+						     const C3DFVector& scale, 
+						     const Quaternion& rot):
+	m_axisorder(axis), 
+	m_origin(origin), 
+	m_scale(scale), 
+	m_rotation(rot)
+{
+}
+
+void C3DOrientationAndPosition::get_transform_parameters(CDoubleVector& params) const
+{
+	assert(params.size() == 16); 
+
+	const C3DFMatrix& axis_switch = get_axis_switch_matrix(); 
+	const C3DFMatrix rot = m_rotation.get_rotation_matrix(); 
+	const C3DFMatrix scale(C3DFVector(m_scale.x, 0, 0), C3DFVector(0, m_scale.y, 0), C3DFVector(0,0, m_scale.z)); 
+
+	C3DFMatrix rs = axis_switch * (rot * scale);
+	
+	params[0] = rs.x.x; 
+	params[1] = rs.x.y; 
+	params[2] = rs.x.z; 
+	params[3] = m_origin.x; 
+
+	params[4] = rs.y.x; 
+	params[5] = rs.y.y; 
+	params[6] = rs.y.z; 
+	params[7] = m_origin.y; 
+
+	params[8]  = rs.z.x; 
+	params[9]  = rs.z.y; 
+	params[10] = rs.z.z; 
+	params[11] = m_origin.z; 
+
+	params[12] = 0; 
+	params[13] = 0; 
+	params[14] = 0; 
+	params[15] = 1; 
+
+
+}
+
+void C3DOrientationAndPosition::get_inverse_transform_parameters(CDoubleVector& params) const
+{
+	assert(params.size() == 16);
+	const C3DFMatrix& axis_switch = get_axis_switch_matrix(); 
+	const C3DFMatrix rot = m_rotation.get_rotation_matrix().transposed(); 
+	const C3DFMatrix scale(C3DFVector(1.0/m_scale.x, 0, 0), 
+			       C3DFVector(0, 1.0/m_scale.y, 0), 
+			       C3DFVector(0,0, 1.0/m_scale.z)); 
+
+	const C3DFMatrix sr = scale * rot;
+	const C3DFVector mt = C3DFVector::_0 - m_origin; 
+	const C3DFVector it = sr * mt; 
+
+	const C3DFMatrix stf = sr * axis_switch;
+	const C3DFVector ft = it * axis_switch;
+	
+	
+	params[0] = stf.x.x; 
+	params[1] = stf.x.y; 
+	params[2] = stf.x.z; 
+	params[3] = ft.x; 
+
+	params[4] = stf.y.x; 
+	params[5] = stf.y.y; 
+	params[6] = stf.y.z; 
+	params[7] = ft.y; 
+
+	params[8]  = stf.z.x; 
+	params[9]  = stf.z.y; 
+	params[10] = stf.z.z; 
+	params[11] = ft.z;
+
+	params[12] = 0; 
+	params[13] = 0; 
+	params[14] = 0; 
+	params[15] = 1; 
+
+}
+
+const C3DFMatrix& C3DOrientationAndPosition::get_axis_switch_matrix() const
+{
+	switch (m_axisorder) {
+	case ior_xyz:         return ms_order_XYZ; 
+	case ior_xyz_flipped: return ms_order_XYZ_F; 
+	case ior_xzy:         return ms_order_XZY; 
+	case ior_xzy_flipped: return ms_order_XZY_F; 
+	case ior_yxz:         return ms_order_YXZ; 
+	case ior_yxz_flipped: return ms_order_YXZ_F; 
+	case ior_yzx:         return ms_order_YZX; 
+	case ior_yzx_flipped: return ms_order_YZX_F; 
+	case ior_zxy:         return ms_order_ZXY; 
+	case ior_zxy_flipped: return ms_order_ZXY_F; 
+	case ior_zyx:         return ms_order_ZYX; 
+	case ior_zyx_flipped: return ms_order_ZYX_F; 
+	default: 
+		cvwarn() << "C3DOrientationAndPosition: axis ordering not specified, assuming default XYZ\n"; 
+		return ms_order_XYZ; 
 	}
+}
+
+C3DOrientationAndPosition& C3DOrientationAndPosition::operator +=(const C3DOrientationAndPosition& MIA_PARAM_UNUSED(other))
+{
+	assert(0 && "to be implemented"); 
+}
+
+bool C3DOrientationAndPosition::operator == (const C3DOrientationAndPosition& other) const
+{
+	return 	m_axisorder == other.m_axisorder && 
+		m_origin == other.m_origin && 
+		m_scale == other.m_scale && 
+		m_rotation == other.m_rotation; 
+
+}
+
+bool C3DOrientationAndPosition::operator < (const C3DOrientationAndPosition& MIA_PARAM_UNUSED(other)) const
+{
+	assert(0 && "to be implemented"); 
+}
+
+E3DImageOrientation C3DOrientationAndPosition::get_axis_orientation() const
+{
+	return m_axisorder; 
+}
+
+
+
+const mia::C3DFVector& C3DOrientationAndPosition::get_scale() const
+{
+	return m_scale; 
+}
+
+
+const mia::C3DFVector& C3DOrientationAndPosition::get_origin() const
+{
+	return m_origin; 
+}
+
+const mia::Quaternion& C3DOrientationAndPosition::get_rotation() const
+{
+	return m_rotation; 
+}
+
+
+EXPORT_3D  std::ostream& operator << (std::ostream& os, E3DImageOrientation orient)
+{
+	os << g_image_orientation_map.get_name(orient); 
 	return os;
 }
 
-EXPORT_3D istream& operator >> (istream& is, E3DImageOrientation& orient)
+EXPORT_3D std::istream& operator >> (std::istream& is, E3DImageOrientation& orient)
 {
 	string temp;
 	is >> temp;
-
-	if (temp == "axial")
-		orient = ior_axial;
-	else if (temp == "coronal")
-		orient = ior_coronal;
-	else if (temp == "saggital")
-		orient = ior_saggital;
-	else
-		orient = ior_unknown;
+	orient = g_image_orientation_map.get_value(temp.c_str()); 
 	return is;
 }
 
+const C3DFMatrix C3DOrientationAndPosition::ms_order_XYZ(C3DFVector(1,0,0), C3DFVector(0,1,0), C3DFVector(0,0,1)); 
+const C3DFMatrix C3DOrientationAndPosition::ms_order_YXZ(C3DFVector(0,1,0), C3DFVector(1,0,0), C3DFVector(0,0,1));
+const C3DFMatrix C3DOrientationAndPosition::ms_order_XZY(C3DFVector(1,0,0), C3DFVector(0,0,1), C3DFVector(0,1,0));
+const C3DFMatrix C3DOrientationAndPosition::ms_order_ZXY(C3DFVector(0,0,1), C3DFVector(1,0,0), C3DFVector(0,1,0));
+const C3DFMatrix C3DOrientationAndPosition::ms_order_ZYX(C3DFVector(0,0,1), C3DFVector(0,1,0), C3DFVector(1,0,0));
+const C3DFMatrix C3DOrientationAndPosition::ms_order_YZX(C3DFVector(0,1,0), C3DFVector(0,0,1), C3DFVector(1,0,0));
+
+const C3DFMatrix C3DOrientationAndPosition::ms_order_XYZ_F(C3DFVector(1,0,0), C3DFVector(0,1,0), C3DFVector(0,0,-1)); 
+const C3DFMatrix C3DOrientationAndPosition::ms_order_YXZ_F(C3DFVector(0,1,0), C3DFVector(1,0,0), C3DFVector(0,0,-1));
+const C3DFMatrix C3DOrientationAndPosition::ms_order_XZY_F(C3DFVector(1,0,0), C3DFVector(0,0,1), C3DFVector(0,-1,0));
+const C3DFMatrix C3DOrientationAndPosition::ms_order_ZXY_F(C3DFVector(0,0,1), C3DFVector(1,0,0), C3DFVector(0,-1,0));
+const C3DFMatrix C3DOrientationAndPosition::ms_order_ZYX_F(C3DFVector(0,0,1), C3DFVector(0,1,0), C3DFVector(-1,0,0));
+const C3DFMatrix C3DOrientationAndPosition::ms_order_YZX_F(C3DFVector(0,1,0), C3DFVector(0,0,1), C3DFVector(-1,0,0));
+
+
+static const TDictMap<E3DImageOrientation>::Table image_orientation_map[] = {
+	{ "(undefined)", ior_undefined, "image orientation not defined"}, 
+	{ "axial", ior_xyz, "transversal/axial"}, 
+	{ "axial-flipped", ior_xyz_flipped, "transversal/axial z-order reverse"}, 
+	{ "axial-transposed",  ior_yxz, "transversal/axial, transposed"}, 
+	{ "axial-transposed-flipped", ior_yxz_flipped, "transversal/axial, z-order reverse, transposed"}, 
+
+	{ "coronal", ior_xzy, "coronal,  face facing front"}, 
+	{ "coronal-flipped", ior_xzy_flipped, "coronal, back facing front"}, 
+	{ "coronal-transposed", ior_zxy, "coronal, face facing front, transposed"}, 
+	{ "coronal-transposed-flipped", ior_zxy_flipped, "coronal, back facing front,  transposed"},
+
+	{ "saggital", ior_yzx, "saggital,  left facing front"}, 
+	{ "saggital-flipped", ior_yzx_flipped, "saggital, right facing front"}, 
+	{ "saggital-transposed", ior_zyx, "saggital, left facing front, transposed"}, 
+	{ "saggital-transposed-flipped", ior_zyx_flipped, "saggital, right facing front,  transposed"},
+	
+	{ nullptr, ior_undefined,  nullptr}
+}; 
+
+const TDictMap<E3DImageOrientation> g_image_orientation_map(image_orientation_map, true); 
 
 static const TDictMap<E3DPatientPositioning>::Table patient_position_map_table[] = {
 	{"(undefined)", ipp_undefined, "undefined patient position"}, 
@@ -72,11 +249,11 @@ static const TDictMap<E3DPatientPositioning>::Table patient_position_map_table[]
 	{"FFS", ipp_ffs, " feet first supine "},  
 	{"FFDR", ipp_ffdr, " feet first Decubitus Right "},
 	{"FFDL", ipp_ffdl, " feet first Decubitus Left "}, 
-	{0, ipp_lastindex, 0}
+	{0, ipp_undefined, 0}
 }; 
 
 
-const TDictMap<E3DPatientPositioning> g_patient_position_map(patient_position_map_table); 
+const TDictMap<E3DPatientPositioning> g_patient_position_map(patient_position_map_table, true); 
 
 EXPORT_3D  ostream& operator << (ostream& os, E3DPatientPositioning pp)
 {
@@ -88,16 +265,54 @@ EXPORT_3D  istream& operator >> (istream& is, E3DPatientPositioning& pp)
 {
 	string s; 
 	is >> s; 
-	try {
-		pp = g_patient_position_map.get_value(s.c_str()); 
-	}catch (const invalid_argument& e) {
-		cvwarn() << "Reading unknown patient position '" << s 
-			 << "', defaulting to '(undefined)'\n"; 
-		pp = ipp_undefined; 
-	}
+	pp = g_patient_position_map.get_value(s.c_str()); 
 	return is; 
 }
 
 EXPORT_3D const char * IDPatientPosition = "PatientPosition"; 
 
+
+void C3DOrientationAndPosition::print(std::ostream& os)const
+{
+	os << "[" << m_axisorder << " [" << m_origin << "] [" 
+	   << m_scale << "] [" << m_rotation << "]]"; 
+}
+
+EXPORT_3D  std::istream& operator >> (std::istream& is, C3DOrientationAndPosition& orient)
+{
+	const char *msg = "unable to read C3DOrientationAndPosition from stream"; 
+	E3DImageOrientation axisorder; 
+	C3DFVector origin; 
+	C3DFVector scale; 
+	Quaternion rotation; 
+
+	eat_char(is, '[', msg); 
+	
+	is >> axisorder; 
+
+	eat_char(is, '[', msg); 
+
+	is >> origin; 
+
+	eat_char(is, ']', msg); 
+	eat_char(is, '[', msg); 
+	
+	is >> scale; 
+	
+	eat_char(is, ']', msg); 
+	eat_char(is, '[', msg); 
+	
+	
+	is >> rotation; 
+	
+	eat_char(is, ']', msg); 
+	eat_char(is, ']', msg); 
+
+	orient = C3DOrientationAndPosition(axisorder, origin, scale, rotation);
+	
+	return is; 
+}
+
+
+
 NS_MIA_END
diff --git a/mia/3d/orientation.hh b/mia/3d/orientation.hh
index e28c6ad..334276c 100644
--- a/mia/3d/orientation.hh
+++ b/mia/3d/orientation.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,22 +25,126 @@
 #include <istream>
 
 #include <mia/core/attributes.hh>
-#include <mia/3d/defines3d.hh>
-
-
+#include <mia/3d/quaternion.hh>
+#include <mia/3d/matrix.hh>
+#include <mia/core/vector.hh>
 
 NS_MIA_BEGIN
 
+
 /**
    \ingroup basic 
    Basic image orientations based on viewing direction 
  */
-enum E3DImageOrientation {ior_axial, /**< look from above or below at the head */  
-			  ior_coronal, /**< look from behind or the front on the head */
-			  ior_saggital, /**<look from left or right on the head */
-			  ior_unknown /**< stopper index */
+
+enum E3DImageOrientation {
+
+	ior_undefined = 0,  /** undefined image orientation */
+	ior_default = 1,   /**< look from above or below at the head */  
+
+	ior_xyz         = 1,       /**< transversal head first */  
+	ior_xyz_flipped = 2,       /**< transversal feet first */  
+	ior_yxz         = 3,       /**< transversal head first xy transposed  */
+	ior_yxz_flipped = 4,       /**< transversal feet first xy transposed  */
+
+	ior_xzy         = 5,       /**< coronal face first */
+	ior_xzy_flipped = 6,       /**< coronal back first */
+	ior_zxy         = 7,       /**< coronal face first xz transposed */
+	ior_zxy_flipped = 8,       /**< coronal back first xz transposed */
+
+	ior_yzx         = 9,        /**< saggital left first */
+	ior_yzx_flipped =10,        /**< saggital right first */
+	ior_zyx         =11,        /**< saggital left first zy transposed */
+	ior_zyx_flipped =12,        /**< saggital right first zy transposed */
+
+
+	ior_axial = 1,     /**< standard axial/transversal orientation  */  
+	ior_axial_flipped = 2,     /**< standard axial/transversal orientation  */  
+	ior_coronal = 5,   /**< standard coronal orientation */
+	ior_coronal_flipped = 6,   /**< standard coronal orientation */
+	ior_saggital = 9,  /**< standard saggital orientation */
+	ior_saggital_flipped =10,  /**< standard saggital orientation */
+
+
+	ior_unknown = 13,   /**< stopper index */	
 };
 
+
+extern const TDictMap<E3DImageOrientation> g_image_orientation_map; 
+
+/**
+   \brief This class represents the oriantation and position of a 3D data set. 
+   
+   This class represents the oriantation and position of a 3D data set, by using 
+   the following parameters: 
+   - the location of the first data pixel (corresponds to DICOM tag (00020,00032)
+   - the rotation about this point (corresponds to DICOM tag (00020,00037)
+   - the axis ordering (axial, saggital, coronal) 
+   - the flipping of the data 
+   
+*/
+
+class EXPORT_3D C3DOrientationAndPosition {
+public: 
+	C3DOrientationAndPosition(); 
+	
+	explicit C3DOrientationAndPosition(E3DImageOrientation axis); 
+
+	C3DOrientationAndPosition(E3DImageOrientation axis, 
+				  const C3DFVector& origin, 
+				  const C3DFVector& scale, 
+				  const Quaternion& rot); 
+	
+	void get_transform_parameters(CDoubleVector& params) const; 
+	
+	void get_inverse_transform_parameters(CDoubleVector& params) const; 
+
+	C3DOrientationAndPosition& operator +=(const C3DOrientationAndPosition& other); 
+	
+	bool operator == (const C3DOrientationAndPosition& other) const; 
+
+	bool operator < (const C3DOrientationAndPosition& other) const; 
+	
+
+	void print(std::ostream& os) const; 
+
+	E3DImageOrientation get_axis_orientation() const; 
+
+        /// \returns the voxel scale 
+        const mia::C3DFVector& get_scale() const; 
+
+        /// \returns the origin in physical coordinates 
+        const mia::C3DFVector& get_origin()const; 
+
+        /// \returns the rotation of the object 
+        const mia::Quaternion& get_rotation()const;
+
+private:
+	
+	const C3DFMatrix& get_axis_switch_matrix() const; 
+	
+	E3DImageOrientation m_axisorder; 
+	C3DFVector m_origin; 
+	C3DFVector m_scale; 
+	Quaternion m_rotation; 
+
+	static const C3DFMatrix ms_order_XYZ; 
+	static const C3DFMatrix ms_order_YXZ;
+	static const C3DFMatrix ms_order_XZY;
+	static const C3DFMatrix ms_order_ZYX;
+	static const C3DFMatrix ms_order_ZXY;
+	static const C3DFMatrix ms_order_YZX;
+
+	static const C3DFMatrix ms_order_XYZ_F; 
+	static const C3DFMatrix ms_order_YXZ_F;
+	static const C3DFMatrix ms_order_XZY_F;
+	static const C3DFMatrix ms_order_ZXY_F;
+	static const C3DFMatrix ms_order_ZYX_F;
+	static const C3DFMatrix ms_order_YZX_F;
+
+}; 
+
+
 /**
    \ingroup basic 
    The Patient Position (DICOM 7.3.1.1 specifies the position of the patient relative to 
@@ -92,6 +196,29 @@ EXPORT_3D  std::istream& operator >> (std::istream& is, E3DImageOrientation& ori
 
 /**
    \ingroup basic 
+   @brief Stream operator to write orientation+position to stream \a os 
+   \param os
+   \param orient
+   \returns os 
+ */
+inline std::ostream& operator << (std::ostream& os, const C3DOrientationAndPosition& orient) 
+{
+	orient.print(os); 
+	return os; 
+}
+
+/**
+   \ingroup basic 
+   @brief Stream operator to read orientation+position from  stream \a is 
+   \param is
+   \param[out] orient
+   \returns is 
+ */
+EXPORT_3D  std::istream& operator >> (std::istream& is, C3DOrientationAndPosition& orient);
+
+
+/**
+   \ingroup basic 
    @brief Stream operator to write patient position orient to stream \a  os 
    \param os
    \param pp
@@ -126,12 +253,32 @@ typedef TTranslator<E3DImageOrientation> COrientationTranslator;
 */
 typedef TAttribute<E3DPatientPositioning> CPatientPositionAttribute;
 
+
+typedef TAttribute<C3DOrientationAndPosition> C3DImageOrientationPositionAttribute;
+typedef TTranslator<C3DOrientationAndPosition> COrientationPositionTranslator;
 /**
    @ingroup basic 
    @brief translator for the patient position 
 */
 typedef TTranslator<E3DPatientPositioning> CPatientPositionTranslator;
 
+template <> 
+struct attribute_type<E3DImageOrientation> : public EAttributeType {
+        static const int value = 3000;
+}; 
+
+template <> 
+struct attribute_type<E3DPatientPositioning> : public EAttributeType {
+        static const int value = 3001;
+}; 
+
+template <> 
+struct attribute_type<C3DOrientationAndPosition>: public EAttributeType {
+        static const int value = 3002;
+}; 
+
+
+
 extern EXPORT_3D const char * IDPatientPosition; 
 
 NS_MIA_END
diff --git a/mia/3d/ppmatrix.cc b/mia/3d/ppmatrix.cc
index e4d4f5d..b220108 100644
--- a/mia/3d/ppmatrix.cc
+++ b/mia/3d/ppmatrix.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/ppmatrix.hh b/mia/3d/ppmatrix.hh
index f404eff..33d13e1 100644
--- a/mia/3d/ppmatrix.hh
+++ b/mia/3d/ppmatrix.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/quaternion.cc b/mia/3d/quaternion.cc
index 034bba5..d1ed302 100644
--- a/mia/3d/quaternion.cc
+++ b/mia/3d/quaternion.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,20 +17,95 @@
  * along with MIA; if not, see <http://www.gnu.org/licenses/>.
  *
  */
+
+#include <gsl/gsl_math.h>
+#include <gsl/gsl_eigen.h>
+
 #include <mia/3d/quaternion.hh>
 #include <mia/core/utils.hh>
 #include <mia/core/msgstream.hh>
 #include <vector>
+#include <memory>
 
 
 NS_MIA_BEGIN 
 using std::swap; 
+using std::unique_ptr; 
+using std::invalid_argument; 
 
 Quaternion::Quaternion():
 	m_w(0.0)
 {
 }
 
+Quaternion::Quaternion(const C3DFMatrix& m):Quaternion(C3DDMatrix(m))
+{
+}
+
+Quaternion::Quaternion(const C3DDMatrix& m)
+{
+	const double m00 = (m.x.x - m.y.y - m.z.z) / 3.0; 
+	const double m01 = (m.y.x + m.x.y) / 3.0; 
+	const double m02 = (m.z.x + m.x.z) / 3.0; 
+	const double m03 = (m.z.y - m.y.z) / 3.0; 
+	
+
+	const double m11 = (m.y.y - m.x.x - m.z.z) / 3.0; 
+	const double m12 = (m.z.y + m.y.z) / 3.0; 
+	const double m13 = (m.x.z - m.z.x) / 3.0; 
+
+	const double m22 = (m.z.z - m.x.x - m.y.y) / 3.0; 
+	const double m23 = (m.y.x - m.x.y) / 3.0; 
+	
+	const double m33 = (m.z.z + m.x.x + m.y.y) / 3.0; 
+	
+	double data[16] = {
+		m00, m01, m02, m03, 
+		m01, m11, m12, m13, 
+		m02, m12, m22, m23, 
+		m03, m13, m23, m33
+	}; 
+
+	gsl_matrix_view gslm  = gsl_matrix_view_array (data, 4, 4);
+	
+	
+	auto gsl_vector_delete = [](gsl_vector * p) { gsl_vector_free(p); };
+	unique_ptr<gsl_vector, decltype(gsl_vector_delete)> eval(gsl_vector_alloc (4), gsl_vector_delete ); 
+
+	auto gsl_matrix_delete = [](gsl_matrix * p) { gsl_matrix_free(p); };
+	unique_ptr<gsl_matrix, decltype(gsl_matrix_delete)> evec(gsl_matrix_alloc (4, 4), gsl_matrix_delete );
+
+	auto gsl_eigen_symmv_delete = [](gsl_eigen_symmv_workspace * p) { gsl_eigen_symmv_free(p); };
+	unique_ptr<gsl_eigen_symmv_workspace, decltype(gsl_eigen_symmv_delete)> ws(gsl_eigen_symmv_alloc (4), gsl_eigen_symmv_delete);
+
+	gsl_eigen_symmv (&gslm.matrix, eval.get(), evec.get(), ws.get());
+
+	gsl_eigen_symmv_sort (eval.get(), evec.get(), GSL_EIGEN_SORT_ABS_ASC);
+
+	if (cverb.get_level() <= vstream::ml_debug ) {
+		for(int i = 0; i < 4; ++i) {
+			cvdebug() << "eval [" << i << "] = " << gsl_vector_get(eval.get(), i) << "\n"; 
+			cvdebug() << "evec [" << i << "] = "; 
+			for (int j = 0; j < 4; ++j) {
+				cverb << gsl_matrix_get(evec.get(), j, i) << ", "; 
+			}
+			cverb << "\n\n"; 
+		}
+	}
+
+	m_v.x = gsl_matrix_get(evec.get(), 0, 3); 
+	m_v.y = gsl_matrix_get(evec.get(), 1, 3); 
+	m_v.z = gsl_matrix_get(evec.get(), 2, 3);
+	m_w   = gsl_matrix_get(evec.get(), 3, 3); 
+
+	// technically, this is not necessary, but for testing it is better 
+	if (m_w < 0.0) {
+		m_v *= -1.0f; 
+		m_w = -m_w; 
+	}
+
+}
+
 Quaternion::Quaternion(const C3DDVector& rot):
 	m_v(0.0, 0.0, 0.0), 
 	m_w(1.0)
@@ -38,16 +113,52 @@ Quaternion::Quaternion(const C3DDVector& rot):
 {
 	double cos_phi, sin_phi, cos_psi, sin_psi, cos_theta, sin_theta; 
 	sincos(0.5 * rot.x, &sin_phi,   &cos_phi); 
-	sincos(0.5 * rot.y, &sin_psi,   &cos_psi); 
-	sincos(0.5 * rot.z, &sin_theta, &cos_theta); 
+	sincos(0.5 * rot.y, &sin_theta, &cos_theta); 
+	sincos(0.5 * rot.z, &sin_psi,   &cos_psi); 
+
+	m_w   = cos_phi * cos_theta * cos_psi + sin_phi * sin_theta * sin_psi;  
+	m_v.x = sin_phi * cos_theta * cos_psi - cos_phi * sin_theta * sin_psi;  
+	m_v.y = cos_phi * sin_theta * cos_psi + sin_phi * cos_theta * sin_psi; 
+	m_v.z = cos_phi * cos_theta * sin_psi - sin_phi * sin_theta * cos_psi;  
+
+}
+
+const Quaternion Quaternion::_1(1, 0, 0, 0); 
 
+#if 0 
+Quaternion::Quaternion(const C3DFMatrix& rot)
+{
+	double q4  = 1 + rot.x.x + rot.y.y + rot.z.z; 
+	if (q4 <= 0) {
+		throw create_exception<invalid_argument>("Quaternion: Matrix ", rot, 
+							 " is not evem close to be a rotation matrix.");
+	}
+	
+	m_w = 0.5 * sqrt(q4);
+	double s = 0.25 / m_w; 
+	
+	m_v.x = s * (rot.z.y - rot.y.z);  
+	m_v.y = s * (rot.x.z - rot.z.x); 
+	m_v.z = s * (rot.y.x - rot.x.y);  
+}
+#endif 
 
-	m_w   = cos_phi * cos_psi* cos_theta + sin_phi * sin_psi * sin_theta;  
-	m_v.x = sin_phi * cos_psi* cos_theta - cos_phi * sin_psi * sin_theta;  
-	m_v.y = cos_phi * sin_psi* cos_theta + sin_phi * cos_psi * sin_theta;  
-	m_v.z = cos_phi * cos_psi* sin_theta - sin_phi * sin_psi * cos_theta; 
+#if 0 
+const C3DFMatrix Quaternion::get_rotation_matrix() const
+{
+	const C3DDMatrix qq(m_v.x * m_v, m_v.y * m_v, m_v.z * m_v);  
+	cvdebug() << qq << "\n"; 
+	const C3DDMatrix Q(C3DDVector(0, -m_v.z, m_v.y), 
+			   C3DDVector(m_v.z, 0, -m_v.x), 
+			   C3DDVector(-m_v.y, m_v.x, 0)); 
+	cvdebug() << Q << "\n"; 
 
+	cvdebug() << (m_w * m_w - m_v.norm2()) * C3DDMatrix::_1 << "\n"; 
+	const C3DDMatrix r = (m_w * m_w - m_v.norm2()) * C3DDMatrix::_1 + 2.0 * qq + 2.0 * m_w * Q; 
+	cvdebug() << r << "\n"; 
+	return C3DFMatrix(r); 
 }
+#endif 
 
 Quaternion::Quaternion(double w, double  x, double y, double z):
 	m_v(x,y,z), 
@@ -96,9 +207,43 @@ Quaternion Quaternion::inverse() const
 }
 
 
+const C3DDMatrix Quaternion::get_rotation_matrix() const
+{
+	const double a2 = m_w   * m_w;
+	const double b2 = m_v.x * m_v.x;
+	const double c2 = m_v.y * m_v.y;
+	const double d2 = m_v.z * m_v.z;
+
+	const double bc = 2.0 * m_v.x * m_v.y; 
+	const double ad = 2.0 * m_w * m_v.z; 
+	const double bd = 2.0 * m_v.x * m_v.z; 
+	const double ac = 2.0 * m_w * m_v.y; 
+	const double cd = 2.0 * m_v.y * m_v.z; 
+	const double ab = 2.0 * m_w * m_v.x; 
+	
+	return C3DDMatrix(C3DDVector(a2 + b2 - c2 - d2, bc - ad, bd + ac), 
+			  C3DDVector(bc + ad, a2 - b2 + c2 - d2, cd - ab), 
+			  C3DDVector(bd - ac, cd + ab, a2 - b2 - c2 + d2));
+	
+}
+
+
+
 void Quaternion::print(std::ostream& os) const
 {
-	os << "(" << m_w << "," << m_v << ")"; 
+	os << m_w << "," << m_v; 
+}
+
+EXPORT_3D std::istream& operator >> (std::istream& is, Quaternion& a)
+{
+	const char *msg = "Unable to read quaternion from stream"; 
+	float w; 
+	C3DFVector v; 
+	is >> w; 
+	eat_char(is, ',', msg); 
+	is >> v; 
+	a = Quaternion(w, v.x, v.y, v.z); 
+	return is; 
 }
 
 bool operator == (const Quaternion& a, const Quaternion& b)
diff --git a/mia/3d/quaternion.hh b/mia/3d/quaternion.hh
index d835df2..1d31c3a 100644
--- a/mia/3d/quaternion.hh
+++ b/mia/3d/quaternion.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,24 +23,26 @@
 
 #include <ostream>
 #include <mia/3d/defines3d.hh>
+#include <mia/3d/matrix.hh>
 #include <mia/3d/vector.hh>
 
-
 NS_MIA_BEGIN 
 
 /**
    \ingroup misc 
    \brief a class to implement a quaternion
-
+   
    This class implements some operations of a quaternion. 
+   The rotation is implemented as clockwise/left-handed rotation. 
+
 */
 
 class EXPORT_3D Quaternion {
 
 public: 
-	/**
+        /**
 	   The standard constructor that sets all values of the quaternion to zero. 
-	 */
+	*/
 	Quaternion(); 
 
 	/**
@@ -56,6 +58,23 @@ public:
 	*/
 	Quaternion(const C3DDVector& rot); 
 
+
+	/**
+	   This constructor creates a quaternion from a 3x3 rotation matrix. 
+	   If mat3x3 is not a true rotation matrix, then this constructor evaluates the 
+	   rotation quaternion that best resembles the matrix transformation.
+	   \param rot
+	*/
+	Quaternion(const C3DFMatrix& rot); 
+
+	/**
+	   This constructor creates a quaternion from a 3x3 rotation matrix. 
+	   If mat3x3 is not a true rotation matrix, then this constructor evaluates the 
+	   rotation quaternion that best resembles the matrix transformation.
+	   \param rot
+	*/
+	Quaternion(const C3DDMatrix& rot); 
+
 	/**
 	   Constructor to create a quaternion by directly setting its elements. 
 	 */
@@ -121,12 +140,15 @@ public:
 	/// \returns the z- or $x_3$ component of the quaternion 
 	double z() const; 
 
+	const C3DDMatrix get_rotation_matrix() const; 
+
+	static const Quaternion _1; 
+
 private:
 	C3DDVector m_v; 
 	double m_w; 
 }; 
 
-
 bool EXPORT_3D operator == (const Quaternion& a, const Quaternion& b); 
 bool EXPORT_3D operator != (const Quaternion& a, const Quaternion& b); 
 
@@ -161,6 +183,8 @@ inline std::ostream& operator << (std::ostream& os, const Quaternion& a)
 	return os; 
 }
 
+EXPORT_3D std::istream& operator >> (std::istream& os, Quaternion& a); 
+
 NS_MIA_END
 
 #endif
diff --git a/mia/3d/reg3d/CMakeLists.txt b/mia/3d/reg3d/CMakeLists.txt
index dfc4504..225d8c7 100644
--- a/mia/3d/reg3d/CMakeLists.txt
+++ b/mia/3d/reg3d/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/reg3d/direct.cc b/mia/3d/reg3d/direct.cc
index c355333..26c442b 100644
--- a/mia/3d/reg3d/direct.cc
+++ b/mia/3d/reg3d/direct.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/reg3d/fluid.cc b/mia/3d/reg3d/fluid.cc
index 956d233..cf9a0c3 100644
--- a/mia/3d/reg3d/fluid.cc
+++ b/mia/3d/reg3d/fluid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/reg3d/navier.cc b/mia/3d/reg3d/navier.cc
index b0755bf..d6d5d9c 100644
--- a/mia/3d/reg3d/navier.cc
+++ b/mia/3d/reg3d/navier.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -176,7 +176,6 @@ C3DNavierRegModelPlugin::C3DNavierRegModelPlugin():
 	m_epsilon(0.0001),
 	m_maxiter(100)
 {
-	typedef CParamList::PParameter PParameter;
 	add_parameter("mu", new CFloatParameter(m_mu, 0.0, numeric_limits<float>::max(),
 							   false, "isotropic compliance"));
 	add_parameter("lambda", new CFloatParameter(m_lambda, 0.0, numeric_limits<float>::max(),
diff --git a/mia/3d/reg3d/naviera.cc b/mia/3d/reg3d/naviera.cc
index e85f6ef..21a412a 100644
--- a/mia/3d/reg3d/naviera.cc
+++ b/mia/3d/reg3d/naviera.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -402,7 +402,6 @@ C3DNavierRegModelPlugin::C3DNavierRegModelPlugin():
 	m_epsilon(0.0001),
 	m_maxiter(40)
 {
-	typedef CParamList::PParameter PParameter;
 	add_parameter("mu", new CFloatParameter(m_mu, 0.0, numeric_limits<float>::max(),
 							   false, "isotropic compliance"));
 	add_parameter("lambda", new CFloatParameter(m_lambda, 0.0, numeric_limits<float>::max(),
diff --git a/mia/3d/reg3d/navierasse.cc b/mia/3d/reg3d/navierasse.cc
index f460ccb..d93aeb4 100644
--- a/mia/3d/reg3d/navierasse.cc
+++ b/mia/3d/reg3d/navierasse.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -513,7 +513,6 @@ C3DNavierRegModelPlugin::C3DNavierRegModelPlugin():
 	m_epsilon(0.0001),
 	m_maxiter(40)
 {
-	typedef CParamList::PParameter PParameter;
 	add_parameter("mu", new CFloatParameter(m_mu, 0.0, numeric_limits<float>::max(),
 							   false, "isotropic compliance"));
 	add_parameter("lambda", new CFloatParameter(m_lambda, 0.0, numeric_limits<float>::max(),
diff --git a/mia/3d/reg3d/navierpsse.cc b/mia/3d/reg3d/navierpsse.cc
index 7e5efd6..acf3231 100644
--- a/mia/3d/reg3d/navierpsse.cc
+++ b/mia/3d/reg3d/navierpsse.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -514,7 +514,6 @@ C3DNavierRegModelPlugin::C3DNavierRegModelPlugin():
 	m_epsilon(0.0001),
 	m_maxiter(40)
 {
-	typedef CParamList::PParameter PParameter;
 	add_parameter("mu", new CFloatParameter(m_mu, 0.0, numeric_limits<float>::max(),
 							   false, "isotropic compliance"));
 	add_parameter("lambda", new CFloatParameter(m_lambda, 0.0, numeric_limits<float>::max(),
diff --git a/mia/3d/register.cc b/mia/3d/register.cc
index 911be20..f3fd964 100644
--- a/mia/3d/register.cc
+++ b/mia/3d/register.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/register.hh b/mia/3d/register.hh
index b623039..b1b8439 100644
--- a/mia/3d/register.hh
+++ b/mia/3d/register.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/rigidregister.cc b/mia/3d/rigidregister.cc
index 5efccb5..4abb155 100644
--- a/mia/3d/rigidregister.cc
+++ b/mia/3d/rigidregister.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/rigidregister.hh b/mia/3d/rigidregister.hh
index df50acb..e492183 100644
--- a/mia/3d/rigidregister.hh
+++ b/mia/3d/rigidregister.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/rot.cc b/mia/3d/rot.cc
new file mode 100644
index 0000000..778922d
--- /dev/null
+++ b/mia/3d/rot.cc
@@ -0,0 +1,305 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <iostream>
+#include <sstream> 
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
+#include <mia/3d/rot.hh>
+
+NS_MIA_BEGIN
+
+using std::string; 
+using std::istringstream; 
+using std::ostringstream; 
+using std::vector; 
+using std::invalid_argument; 
+
+static const char * c_rot_identity = "rot-identity"; 
+static const char * c_rot_mat = "rot-matrix"; 
+static const char * c_rot_quat = "rot-quaternion"; 
+
+
+
+class C3DRotationImpl {
+        
+public: 
+	virtual ~C3DRotationImpl(); 
+	virtual C3DRotationImpl *clone() const  __attribute__((warn_unused_result))= 0 ; 
+        virtual C3DDMatrix as_matrix_3x3() const = 0;
+        virtual Quaternion as_quaternion() const = 0; 
+        virtual std::string as_string() const = 0; 
+        
+        static C3DRotationImpl* from_string(const std::string& s) __attribute__((warn_unused_result));
+}; 
+
+class C3DQuaternionRotation: public C3DRotationImpl {
+
+public: 
+        C3DQuaternionRotation(const std::string& s); 
+        C3DQuaternionRotation(const Quaternion& q); 
+
+	
+	virtual C3DRotationImpl *clone() const  __attribute__((warn_unused_result)); 
+        virtual C3DDMatrix as_matrix_3x3() const;
+        virtual Quaternion as_quaternion() const; 
+        virtual std::string as_string() const; 
+
+private: 
+        Quaternion m_q;
+        
+}; 
+
+class C3DMatrix3x3Rotation: public C3DRotationImpl {
+public: 
+        C3DMatrix3x3Rotation(const std::string& s);
+        C3DMatrix3x3Rotation(const C3DDMatrix& q); 
+        
+	virtual C3DRotationImpl *clone() const  __attribute__((warn_unused_result)); 
+        virtual C3DDMatrix as_matrix_3x3() const;
+        virtual Quaternion as_quaternion() const; 
+        virtual std::string as_string() const; 
+
+private: 
+
+        C3DDMatrix m_matrix;
+}; 
+
+C3DRotation::C3DRotation():impl(nullptr)
+{
+}
+
+C3DRotation::~C3DRotation()
+{
+	delete impl; 
+}
+
+C3DRotation::C3DRotation(const C3DRotation& other)
+{
+	if (other.impl) 
+		impl = other.impl->clone(); 
+	else 
+		impl = nullptr; 
+}
+
+C3DRotation& C3DRotation::operator = (const C3DRotation& other)
+{
+	if (this != &other) {
+		auto old = impl; 
+		if (other.impl) 
+			impl = other.impl->clone(); 
+		else 
+			impl = nullptr;
+		delete old; 
+	}
+	return *this; 
+}
+
+C3DRotation::C3DRotation(const C3DDMatrix& m)
+{
+	impl = new C3DMatrix3x3Rotation(m); 
+}
+
+C3DRotation::C3DRotation(const Quaternion& q)
+{
+	impl = new C3DQuaternionRotation(q); 
+}
+	
+C3DRotation::C3DRotation(const std::string& s)
+{
+	impl = C3DRotationImpl::from_string(s); 
+}
+
+C3DDMatrix C3DRotation::as_matrix_3x3() const
+{
+	return impl ? impl->as_matrix_3x3() : C3DDMatrix::_1; 
+}
+
+Quaternion C3DRotation::as_quaternion() const
+{
+	return impl ? impl->as_quaternion() : Quaternion::_1; 
+}
+
+string C3DRotation::as_string() const
+{
+	return impl ? impl->as_string() : string(c_rot_identity); 
+}
+
+const C3DRotation C3DRotation::_1; 
+
+C3DRotationImpl::~C3DRotationImpl()
+{
+}
+
+C3DRotationImpl* C3DRotationImpl::from_string(const std::string& s) 
+{
+        vector<string> tockens; 
+        boost::split(tockens, s ,boost::is_any_of("="));
+
+	if ((tockens.size() == 1) && !strcmp(c_rot_identity, tockens[0].c_str()))
+		return nullptr;
+	
+        if (tockens.size() != 2) {
+                throw create_exception<invalid_argument>("Unable to read C3DRotation from '", 
+                                                         s, "'"); 
+        }
+        
+        const char *test_tocken =  tockens[0].c_str(); 
+        if (!strcmp(c_rot_mat, test_tocken))
+                return new C3DMatrix3x3Rotation(tockens[1]); 
+        else if (!strcmp(c_rot_quat, test_tocken))
+                return new C3DQuaternionRotation(tockens[1]);
+	else
+                throw create_exception<invalid_argument>("Unknown C3DRotation type '", tockens[0], "'"); 
+}
+
+C3DRotationImpl *C3DQuaternionRotation::clone() const 
+{
+	return new C3DQuaternionRotation(*this); 
+}
+
+C3DQuaternionRotation::C3DQuaternionRotation(const std::string& s)
+{
+        vector<string> tockens; 
+        boost::split(tockens, s ,boost::is_any_of(","));
+        
+        if (tockens.size() != 4) {
+                throw create_exception<invalid_argument>("Expect four values to create quaternions but got ", tockens.size()); 
+        }
+        
+        double v[4]; 
+        for (int i = 0; i < 4; ++i) {
+                istringstream iss(tockens[i]); 
+                iss >> v[i]; 
+                if (iss.bad()) 
+                        throw create_exception<invalid_argument>("Unable to read quaternions from '", s, "'"); 
+        }
+        m_q = Quaternion(v[0], v[1], v[2], v[3]); 
+}
+
+C3DQuaternionRotation::C3DQuaternionRotation(const Quaternion& q):
+      m_q(q)
+{
+        
+}
+
+C3DDMatrix C3DQuaternionRotation::as_matrix_3x3() const
+{
+        return m_q.get_rotation_matrix(); 
+}
+
+Quaternion C3DQuaternionRotation::as_quaternion() const
+{
+        return m_q; 
+}
+
+std::string C3DQuaternionRotation::as_string() const
+{
+        ostringstream s; 
+        s << c_rot_quat << "=" <<m_q; 
+        return s.str(); 
+}
+
+C3DRotationImpl *C3DMatrix3x3Rotation::clone()const 
+{
+	return new C3DMatrix3x3Rotation(*this); 
+}
+
+C3DMatrix3x3Rotation::C3DMatrix3x3Rotation(const std::string& s)
+{
+        vector<string> tockens; 
+        boost::split(tockens, s ,boost::is_any_of(";"));
+	
+        if (tockens.size() != 3) {
+                throw create_exception<invalid_argument>("Unable to read C3DMatrix3x3Rotation from '", 
+                                                         s, "'"); 
+        }
+
+        istringstream iss_x(tockens[0]); 
+        iss_x >> m_matrix.x; 
+        if (iss_x.bad()) {
+                throw create_exception<invalid_argument>("Unable to rotation matrix x row from '", tockens[0], "'");
+        }
+
+        istringstream iss_y(tockens[1]); 
+        iss_y >> m_matrix.y; 
+        if (iss_y.bad()) {
+                throw create_exception<invalid_argument>("Unable to rotation matrix y row from '", tockens[1], "'");
+        }
+
+        istringstream iss_z(tockens[2]); 
+        iss_z >> m_matrix.z; 
+        if (iss_z.bad()) {
+                throw create_exception<invalid_argument>("Unable to rotation matrix z row from '", tockens[2], "'");
+        }
+
+}
+
+C3DMatrix3x3Rotation::C3DMatrix3x3Rotation(const C3DDMatrix& m):
+m_matrix(m)
+{
+        
+}
+
+
+C3DDMatrix C3DMatrix3x3Rotation::as_matrix_3x3() const
+{
+        return m_matrix; 
+}
+
+Quaternion C3DMatrix3x3Rotation::as_quaternion() const
+{
+        return Quaternion(m_matrix); 
+}
+
+std::string C3DMatrix3x3Rotation::as_string() const
+{
+        ostringstream s; 
+        s << c_rot_mat << "="<< m_matrix; 
+        return s.str(); 
+}
+
+EXPORT_3D bool operator == (const C3DRotation& lhs, const C3DRotation& rhs)
+{
+	// this needs to be done floating point value friendly
+	auto q = lhs.as_quaternion(); 
+	q -= rhs.as_quaternion(); 
+	
+	return (q.norm() < 1e-10); 
+}
+
+EXPORT_3D bool operator < (const C3DRotation& lhs, const C3DRotation& rhs) 
+{
+	auto qlhs = lhs.as_quaternion(); 
+	auto qrhs = rhs.as_quaternion(); 
+
+	return qlhs.w() < qrhs.w() || 
+		(qlhs.w() == qrhs.w() && 
+		 (qlhs.z() < qrhs.z() || 
+		  (qlhs.z() == qrhs.z() && 
+		   ( qlhs.y() < qrhs.y() || 
+		     ( qlhs.y() == qrhs.y() && qlhs.x() < qrhs.x()))))); 
+		  
+}
+
+template class EXPORT_3D TAttribute<C3DRotation>; 
+
+NS_MIA_END
diff --git a/mia/3d/rot.hh b/mia/3d/rot.hh
new file mode 100644
index 0000000..622211d
--- /dev/null
+++ b/mia/3d/rot.hh
@@ -0,0 +1,78 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_rot_hh
+#define mia_3d_rot_hh
+
+#include <mia/core/attributes.hh>
+#include <mia/3d/quaternion.hh>
+#include <mia/3d/matrix.hh>
+
+NS_MIA_BEGIN
+
+class EXPORT_3D C3DRotation {
+public: 
+	C3DRotation(); 
+	~C3DRotation();
+	
+	C3DRotation(const C3DRotation& other); 
+	C3DRotation& operator = (const C3DRotation& other); 
+
+	C3DRotation(const C3DDMatrix& m); 
+	C3DRotation(const Quaternion& q); 
+	C3DRotation(const std::string& s); 
+
+	C3DDMatrix as_matrix_3x3() const;
+	Quaternion as_quaternion() const; 
+	std::string as_string() const; 
+
+	static const C3DRotation _1; 
+
+private: 
+	class C3DRotationImpl *impl;
+}; 
+
+
+
+
+template <>
+struct attribute_type<C3DRotation>  {
+        static const int value = 0x4000;
+}; 
+
+template <>
+struct dispatch_attr_string<C3DRotation> {
+	static std::string val2string(const C3DRotation& value) {
+		return value.as_string();
+	}
+	static C3DRotation string2val(const std::string& str) {
+		return C3DRotation(str); 
+	}
+}; 
+
+
+EXPORT_3D bool operator == (const C3DRotation& lhs, const C3DRotation& rhs); 
+EXPORT_3D bool operator < (const C3DRotation& lhs, const C3DRotation& rhs); 
+
+typedef TAttribute<C3DRotation> C3DRotationAttribute; 
+typedef TTranslator<C3DRotation> C3DRotationAttributeTranslate;
+
+NS_MIA_END
+#endif
diff --git a/mia/3d/shape.cc b/mia/3d/shape.cc
index 57bb5cf..110129f 100644
--- a/mia/3d/shape.cc
+++ b/mia/3d/shape.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -58,24 +58,15 @@ struct __adjust<T3DVector<int> > {
 	}
 };
 
-using boost::filesystem::path; 
-C3DShapePluginHandlerTestPath::C3DShapePluginHandlerTestPath()
-{
-	CPathNameArray sksearchpath; 
-	sksearchpath.push_back( path(MIA_BUILD_ROOT"/mia/3d/shapes"));
-	C3DShapePluginHandler::set_search_path(sksearchpath); 
-}
-
 template <> const char *  const 
 TPluginHandler<TFactory<C3DShape>>::m_help =  "These plug-ins define 3D structuring elements "
 				"to describe neighborhoods for morphological and other filters."; 
 
-
+template class TShape<T3DVector, C3DBitImage>;
 template class TPlugin<C3DImage, shape_type>;
 template class TFactory<C3DShape>;
 template class THandlerSingleton<TFactoryPluginHandler<C3DShapePlugin> >;
 template class TFactoryPluginHandler<C3DShapePlugin>;
-template class TPluginHandler<C3DShapePlugin>;
-template class TShape<T3DVector, C3DBitImage>;
+template class EXPORT_3D TPluginHandler<C3DShapePlugin>;
 
 NS_MIA_END
diff --git a/mia/3d/shape.hh b/mia/3d/shape.hh
index 2a8a1f1..c3127f3 100644
--- a/mia/3d/shape.hh
+++ b/mia/3d/shape.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,19 +50,7 @@ typedef TFactory<C3DShape> C3DShapePlugin;
 */
 typedef THandlerSingleton<TFactoryPluginHandler<C3DShapePlugin> > C3DShapePluginHandler;
 
-
-/** 
-    @cond INTERNAL  
-    \ingroup test 
-    \brief Class to initialiaze the plug-in search path fot testing without installing the plug-ins 
-*/
-class EXPORT_3D C3DShapePluginHandlerTestPath {
-public: 
-	C3DShapePluginHandlerTestPath(); 
-}; 
-/// @endcond 
-
-
+extern template class EXPORT_3D TShape<T3DVector, C3DBitImage>;
 /// @cond never
 FACTORY_TRAIT(C3DShapePluginHandler); 
 /// @endcond 
diff --git a/mia/3d/shapes/CMakeLists.txt b/mia/3d/shapes/CMakeLists.txt
index 5f91b2e..337e937 100644
--- a/mia/3d/shapes/CMakeLists.txt
+++ b/mia/3d/shapes/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/shapes/basic_shapes.cc b/mia/3d/shapes/basic_shapes.cc
index f7bb4f6..1dc5d1c 100644
--- a/mia/3d/shapes/basic_shapes.cc
+++ b/mia/3d/shapes/basic_shapes.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/shapes/sphere.cc b/mia/3d/shapes/sphere.cc
index 18a86c5..5ea4bde 100644
--- a/mia/3d/shapes/sphere.cc
+++ b/mia/3d/shapes/sphere.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/shapes/sphere.hh b/mia/3d/shapes/sphere.hh
index 287e54f..9f5658b 100644
--- a/mia/3d/shapes/sphere.hh
+++ b/mia/3d/shapes/sphere.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/similarity_profile.cc b/mia/3d/similarity_profile.cc
index 2c1be8d..0eb3ffd 100644
--- a/mia/3d/similarity_profile.cc
+++ b/mia/3d/similarity_profile.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/similarity_profile.hh b/mia/3d/similarity_profile.hh
index e3c9243..d6d663c 100644
--- a/mia/3d/similarity_profile.hh
+++ b/mia/3d/similarity_profile.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/splinepenalty/CMakeLists.txt b/mia/3d/splinepenalty/CMakeLists.txt
index 9978122..b638035 100644
--- a/mia/3d/splinepenalty/CMakeLists.txt
+++ b/mia/3d/splinepenalty/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/splinepenalty/divcurl.cc b/mia/3d/splinepenalty/divcurl.cc
index 2db64b8..782147b 100644
--- a/mia/3d/splinepenalty/divcurl.cc
+++ b/mia/3d/splinepenalty/divcurl.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,8 +24,8 @@ NS_BEGIN(divcurl_splinepenalty)
 
 NS_MIA_USE
 
-C3DDivcurlSplinePenalty::C3DDivcurlSplinePenalty(double weight, double div_weight, double curl_weight):
-	C3DSplineTransformPenalty(weight), 
+C3DDivcurlSplinePenalty::C3DDivcurlSplinePenalty(double weight, bool normalize, double div_weight, double curl_weight):
+	C3DSplineTransformPenalty(weight, normalize), 
 	m_div_weight(div_weight), 
 	m_curl_weight(curl_weight)
 {
@@ -56,7 +56,7 @@ double C3DDivcurlSplinePenalty::do_value_and_gradient(const C3DFVectorfield&  co
 C3DSplineTransformPenalty *C3DDivcurlSplinePenalty::do_clone() const
 {
 	C3DSplineTransformPenalty *result =  
-		new C3DDivcurlSplinePenalty(get_weight(), m_div_weight, m_curl_weight);
+		new C3DDivcurlSplinePenalty(get_weight(), get_normalize(), m_div_weight, m_curl_weight);
 	if (get_kernel()) 
 		result->initialize(get_size(), get_range(), get_kernel()); 
 	return result; 
@@ -79,9 +79,9 @@ const std::string C3DDivcurlSplinePenaltyPlugin::do_get_descr() const
 	return "divcurl penalty on the transformation"; 
 }
 
-C3DDivcurlSplinePenaltyPlugin::Product *C3DDivcurlSplinePenaltyPlugin::do_create(float weight) const
+C3DDivcurlSplinePenaltyPlugin::Product *C3DDivcurlSplinePenaltyPlugin::do_create(float weight, bool normalize) const
 {
-	return new C3DDivcurlSplinePenalty(weight, m_div_weight, m_curl_weight); 
+	return new C3DDivcurlSplinePenalty(weight, normalize, m_div_weight, m_curl_weight); 
 }
 
 extern "C" EXPORT CPluginBase *get_plugin_interface()
diff --git a/mia/3d/splinepenalty/divcurl.hh b/mia/3d/splinepenalty/divcurl.hh
index 990b5bf..b91c393 100644
--- a/mia/3d/splinepenalty/divcurl.hh
+++ b/mia/3d/splinepenalty/divcurl.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@ NS_BEGIN(divcurl_splinepenalty)
 class C3DDivcurlSplinePenalty: public mia::C3DSplineTransformPenalty {
 public: 
 	
-	C3DDivcurlSplinePenalty(double weight, double div_weight, double curl_weight);
+	C3DDivcurlSplinePenalty(double weight, bool normalize, double div_weight, double curl_weight);
 	
 private: 
 	void do_initialize(); 
@@ -51,7 +51,7 @@ public:
 	
 private: 
 	virtual const std::string do_get_descr() const;
-	virtual Product *do_create(float weight) const __attribute__((warn_unused_result));
+	virtual Product *do_create(float weight, bool normalize) const __attribute__((warn_unused_result));
 	float m_div_weight; 
 	float m_curl_weight; 
 
diff --git a/mia/3d/splinepenalty/test_divcurl.cc b/mia/3d/splinepenalty/test_divcurl.cc
index 0368181..3d8b4f7 100644
--- a/mia/3d/splinepenalty/test_divcurl.cc
+++ b/mia/3d/splinepenalty/test_divcurl.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,8 +28,6 @@ using namespace divcurl_splinepenalty;
 NS_MIA_USE
 namespace bfs=::boost::filesystem;
 
-CSplineKernelTestPath kernel_test_path; 
-
 /*
   The proper evaluation of the penalty and its gradient 
   is done in test_ppmatrix.cc. Here we only test the proper 
diff --git a/mia/3d/splinetransformpenalty.cc b/mia/3d/splinetransformpenalty.cc
index e620aff..277b545 100644
--- a/mia/3d/splinetransformpenalty.cc
+++ b/mia/3d/splinetransformpenalty.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,8 +30,9 @@ using namespace std;
 const char *C3DSplineTransformPenalty::data_descr = "3dtransform";
 const char *C3DSplineTransformPenalty::type_descr = "splinepenalty"; 
 
-C3DSplineTransformPenalty::C3DSplineTransformPenalty(double weight):
-m_weight(weight)
+C3DSplineTransformPenalty::C3DSplineTransformPenalty(double weight, bool normalize):
+        m_weight(weight), 
+	m_normalize(normalize)
 {
 }
 
@@ -51,7 +52,8 @@ void C3DSplineTransformPenalty::initialize(const C3DBounds& size, const C3DFVect
 double C3DSplineTransformPenalty::value(const C3DFVectorfield&  coefficients) const
 {
 	assert(coefficients.get_size() == get_size()); 
-	return m_weight * do_value(coefficients); 
+	const double w = m_normalize ? get_weight() / m_range.product() : m_weight; 
+	return w * do_value(coefficients); 
 }
 
 
@@ -59,10 +61,11 @@ double C3DSplineTransformPenalty::value_and_gradient(const C3DFVectorfield&  coe
 {
 	assert(coefficients.get_size() == get_size()); 
 	assert(coefficients.size() * 3 == gradient.size()); 
+	const double w = m_normalize ? get_weight() / m_range.product() : m_weight; 
 
-	double value =  m_weight * do_value_and_gradient(coefficients, gradient); 
+	double value =  w * do_value_and_gradient(coefficients, gradient); 
 	transform(gradient.begin(), gradient.end(), gradient.begin(), 
-		  [this](double x) { return - m_weight * x;}); 
+		  [w](double x) { return - w * x;}); 
 	return value; 
 }
 
@@ -86,6 +89,11 @@ double C3DSplineTransformPenalty::get_weight() const
 	return m_weight; 
 }
 
+bool C3DSplineTransformPenalty::get_normalize() const
+{
+	return m_normalize; 
+}
+
 C3DSplineTransformPenalty *C3DSplineTransformPenalty::clone() const
 {
 	return do_clone(); 
@@ -99,15 +107,19 @@ C3DSplineTransformPenaltyPluginHandler::ProductPtr produce_3d_spline_transform_p
 
 C3DSplineTransformPenaltyPlugin::C3DSplineTransformPenaltyPlugin(char const * const  name):
 	TFactory<C3DSplineTransformPenalty>(name), 
-	m_weight(1.0)
+	m_weight(1.0), 
+	m_normalize(false)
 {
 	add_parameter("weight", new CFloatParameter(m_weight, 0.0f, std::numeric_limits<float>::max(), 
 						    false, "weight of penalty energy"));
+	add_parameter("norm", new CBoolParameter(m_normalize, false, "Set to 1 if the penalty should be normalized " 
+						 "with respect to the image size")); 
+	
 }
 
 C3DSplineTransformPenaltyPlugin::Product *C3DSplineTransformPenaltyPlugin::do_create() const
 {
-	return do_create(m_weight); 
+	return do_create(m_weight, m_normalize);
 }
 
 
diff --git a/mia/3d/splinetransformpenalty.hh b/mia/3d/splinetransformpenalty.hh
index 66cf7c8..d8acdb3 100644
--- a/mia/3d/splinetransformpenalty.hh
+++ b/mia/3d/splinetransformpenalty.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -46,9 +46,10 @@ public:
 	
 	/**
 	   Constructor that sets the weight of the penalty term 
-	   \param weight 
+	   @param weight 
+    	   @param normalize 
 	 */
-	C3DSplineTransformPenalty(double weight); 
+	C3DSplineTransformPenalty(double weight, bool normalize); 
 
 	C3DSplineTransformPenalty(const C3DSplineTransformPenalty& org) = delete; 
 	C3DSplineTransformPenalty& operator = (const C3DSplineTransformPenalty& org) = delete; 
@@ -98,6 +99,8 @@ protected:
 
 	double get_weight() const; 
 
+	bool get_normalize() const; 
+
 private:
 
  	virtual void do_initialize() = 0; 
@@ -109,6 +112,7 @@ private:
 	virtual C3DSplineTransformPenalty *do_clone() const  = 0;
 
 	double m_weight; 
+	bool m_normalize; 
 
 	C3DBounds m_size;
 	C3DFVector m_range; 
@@ -123,9 +127,10 @@ public:
 	C3DSplineTransformPenaltyPlugin(char const * const  name); 
 private: 
 	virtual Product *do_create() const __attribute__((warn_unused_result));
-	virtual Product *do_create(float weight) const __attribute__((warn_unused_result)) = 0 ;
+	virtual Product *do_create(float weight, bool normalize) const __attribute__((warn_unused_result)) = 0 ;
 
 	float m_weight; 
+	bool m_normalize; 
 }; 
 
 
diff --git a/mia/3d/stackdisttrans.cc b/mia/3d/stackdisttrans.cc
index eb0d9e5..7276360 100644
--- a/mia/3d/stackdisttrans.cc
+++ b/mia/3d/stackdisttrans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/stackdisttrans.hh b/mia/3d/stackdisttrans.hh
index 9a633c6..761e1fb 100644
--- a/mia/3d/stackdisttrans.hh
+++ b/mia/3d/stackdisttrans.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_2dimagefifofilter.cc b/mia/3d/test_2dimagefifofilter.cc
index 7a6ff16..a841b78 100644
--- a/mia/3d/test_2dimagefifofilter.cc
+++ b/mia/3d/test_2dimagefifofilter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_3d.cc b/mia/3d/test_3d.cc
index 0115a7a..9a591eb 100644
--- a/mia/3d/test_3d.cc
+++ b/mia/3d/test_3d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,45 +19,9 @@
  */
 
 #include <climits>
-#include <boost/test/unit_test_suite.hpp>
-#include <boost/test/unit_test.hpp>
 
-#include <mia/core/cmdlineparser.hh>
+#include <mia/internal/autotest.hh>
 
 using namespace mia;
 using namespace boost::unit_test;
 
-
-extern void add_3dvector_tests(test_suite* suite);
-extern void add_3ddatafield_tests(test_suite* suite);
-extern void add_3dimage_tests(test_suite* suite);
-extern void add_3dinterpol_tests(test_suite* suite);
-
-const SProgramDescription g_general_help = {
-        {pdi_group, "Tests"}, 
-	{pdi_short, "3D tests"}, 
-	{pdi_description, "Run various test for 3D data."}
-}; 
-
-bool init_unit_test_suite( )
-{
-
-	test_suite *suite = &framework::master_test_suite();
-
-	add_3dvector_tests(suite);
-	add_3ddatafield_tests(suite);
-	add_3dimage_tests(suite);
-	add_3dinterpol_tests(suite);
-	return true;
-}
-
-int BOOST_TEST_CALL_DECL
-do_main( int argc, char* argv[] )
-{
-	if (CCmdOptionList(g_general_help).parse(argc, (const char**)argv, "boost-test-option") != CCmdOptionList::hr_no) 
-		return 0; 
-	return ::boost::unit_test::unit_test_main( &init_unit_test_suite, argc, argv );
-}
-
-#include <mia/internal/main.hh>
-MIA_MAIN(do_main);
diff --git a/mia/3d/test_affine_matrix.cc b/mia/3d/test_affine_matrix.cc
new file mode 100644
index 0000000..9c51b31
--- /dev/null
+++ b/mia/3d/test_affine_matrix.cc
@@ -0,0 +1,719 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <mia/3d/affine_matrix.hh>
+
+using namespace mia; 
+
+BOOST_AUTO_TEST_CASE( test_identity ) 
+{
+        CAffinTransformMatrix identity; 
+        
+        C3DFVector x(1.0f, 2.0f, 3.0f); 
+        const C3DFVector y = identity * x; 
+
+        BOOST_CHECK_EQUAL(y, x);
+        
+}
+
+
+BOOST_AUTO_TEST_CASE( test_identity_reset ) 
+{
+        CAffinTransformMatrix identity; 
+
+	// fill matrix with some values
+	identity.rotate_z(2, C3DFVector(1,2,3)); 
+	identity.rotate_y(1, C3DFVector(1,23,3)); 
+	identity.translate(C3DFVector(1,2,3)); 
+	
+	identity.identity(); 
+	
+	const auto& data = identity.data(); 
+	BOOST_CHECK_EQUAL(data[0], 1.0f); 
+	BOOST_CHECK_EQUAL(data[1], 0.0f); 
+	BOOST_CHECK_EQUAL(data[2], 0.0f); 
+	BOOST_CHECK_EQUAL(data[3], 0.0f); 
+
+	BOOST_CHECK_EQUAL(data[4], 0.0f); 
+	BOOST_CHECK_EQUAL(data[5], 1.0f); 
+	BOOST_CHECK_EQUAL(data[6], 0.0f); 
+	BOOST_CHECK_EQUAL(data[7], 0.0f); 
+
+	BOOST_CHECK_EQUAL(data[ 8], 0.0f); 
+	BOOST_CHECK_EQUAL(data[ 9], 0.0f); 
+	BOOST_CHECK_EQUAL(data[10], 1.0f); 
+	BOOST_CHECK_EQUAL(data[11], 0.0f); 
+
+	BOOST_CHECK_EQUAL(data[12], 0.0f); 
+	BOOST_CHECK_EQUAL(data[13], 0.0f); 
+	BOOST_CHECK_EQUAL(data[14], 0.0f); 
+	BOOST_CHECK_EQUAL(data[15], 1.0f); 
+
+
+}
+
+
+BOOST_AUTO_TEST_CASE( test_simple_inverse ) 
+{
+	
+	CAffinTransformMatrix simple(2.0f, 0.0f, 0.0f, 0.0f, 
+				     0.0f, 0.5f, 0.0f, 0.0f, 
+				     0.0f, 0.0f, 0.2f, 0.0f); 
+        
+	
+	auto inv = simple.inverse(); 
+	
+	const auto& inv_data = inv.data(); 
+
+	BOOST_CHECK_CLOSE(inv_data[0], 0.5f, 0.01);
+	BOOST_CHECK_SMALL(inv_data[4], 1e-5f); 
+	BOOST_CHECK_SMALL(inv_data[8], 1e-5f); 
+	BOOST_CHECK_SMALL(inv_data[12], 1e-5f); 
+
+	BOOST_CHECK_SMALL(inv_data[1], 1e-5f); 
+	BOOST_CHECK_CLOSE(inv_data[5], 2.0f, 0.01);
+	BOOST_CHECK_SMALL(inv_data[9], 1e-5f); 
+	BOOST_CHECK_SMALL(inv_data[13], 1e-5f); 
+
+	BOOST_CHECK_SMALL(inv_data[2], 1e-5f); 
+	BOOST_CHECK_SMALL(inv_data[6], 1e-5f); 
+	BOOST_CHECK_CLOSE(inv_data[10], 5.0f, 0.01);
+	BOOST_CHECK_SMALL(inv_data[14], 1e-5f); 
+
+	BOOST_CHECK_SMALL(inv_data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(inv_data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(inv_data[11], 1e-5f); 
+	BOOST_CHECK_CLOSE(inv_data[15], 1.0f, 0.01);
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_inverse ) 
+{
+	
+	CAffinTransformMatrix simple(2.0f, 3.0f, 2.0f, 1.0f, 
+				     3.0f, 1.5f, 3.0f, 5.0f, 
+				     4.0f, 2.0f, 1.2f, 1.8f); 
+
+	
+	auto inv = simple.inverse(); 
+	
+	const auto& inv_data = inv.data(); 
+
+	BOOST_CHECK_CLOSE(inv_data[0], -0.25f, 0.01);
+	BOOST_CHECK_CLOSE(inv_data[4], 1.0f/42.0f, 0.01);
+	BOOST_CHECK_CLOSE(inv_data[8], 5.0f/14.0f, 0.01);
+	BOOST_CHECK_CLOSE(inv_data[12], -43.0f/84.0f, 0.01);
+
+	BOOST_CHECK_CLOSE(inv_data[1], 1.0f/2.0f, 0.01);
+	BOOST_CHECK_CLOSE(inv_data[5], -1.0f/3.0f, 0.01);
+	BOOST_CHECK_SMALL(inv_data[9], 1e-5f);
+	BOOST_CHECK_CLOSE(inv_data[13], 7.0f/6.0f, 0.01);
+
+
+	BOOST_CHECK_SMALL(inv_data[2], 1e-5f);
+	BOOST_CHECK_CLOSE(inv_data[6], 10.0f/21.0f, 0.01);
+	BOOST_CHECK_CLOSE(inv_data[10], -5.0f/14.0f, 0.01);
+	BOOST_CHECK_CLOSE(inv_data[14], -73.0f/42.0f, 0.01);
+
+	BOOST_CHECK_SMALL(inv_data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(inv_data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(inv_data[11], 1e-5f); 
+	BOOST_CHECK_CLOSE(inv_data[15], 1.0f, 0.01);
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_rot_x_from_identity ) 
+{
+	
+	CAffinTransformMatrix m; 
+	
+	m.rotate_x(M_PI/3.0f, C3DFVector(20.0f, 12.0f, 3.0f)); 
+	
+	const float sin_pi_3 = sqrt(3.0f)/ 2.0f; 
+	const float cos_pi_3 = 1.0f/ 2.0f; 
+	
+	const auto& data = m.data();
+
+
+	BOOST_CHECK_CLOSE(data[0], 1.0, 0.01);
+	BOOST_CHECK_SMALL(data[4], 1e-5f);
+	BOOST_CHECK_SMALL(data[8], 1e-5f);
+	BOOST_CHECK_SMALL(data[12], 1e-5f);
+
+	BOOST_CHECK_SMALL(data[1], 1e-5f);
+	BOOST_CHECK_CLOSE(data[5], cos_pi_3, 0.01f);
+	BOOST_CHECK_CLOSE(data[9], -sin_pi_3, 0.01f);
+	BOOST_CHECK_CLOSE(data[13], +12.0f * 0.5f + sin_pi_3 * 3.0f, 0.01f);
+
+	BOOST_CHECK_SMALL(data[2], 1e-5f);
+	BOOST_CHECK_CLOSE(data[6], sin_pi_3, 0.01);
+	BOOST_CHECK_CLOSE(data[10],cos_pi_3, 0.01);
+	BOOST_CHECK_CLOSE(data[14], -12.0f * sin_pi_3 + 1.5f  , 0.01);
+
+	BOOST_CHECK_SMALL(data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+	BOOST_CHECK_CLOSE(data[15], 1.0f, 0.01);
+	
+
+}
+
+BOOST_AUTO_TEST_CASE( test_rot_y_from_identity ) 
+{
+	
+	CAffinTransformMatrix m; 
+	
+	m.rotate_y(M_PI/3.0f, C3DFVector(20.0f, 12.0f, 3.0f)); 
+	
+	const float sin_pi_3 = sqrt(3.0f)/ 2.0f; 
+	const float cos_pi_3 = 1.0f/ 2.0f; 
+	
+	const auto& data = m.data();
+
+	BOOST_CHECK_CLOSE(data[0], cos_pi_3, 0.01f);
+	BOOST_CHECK_SMALL(data[4], 1e-5f);
+	BOOST_CHECK_CLOSE(data[8], -sin_pi_3, 0.01f);
+	BOOST_CHECK_CLOSE(data[12], 20.0f * 0.5f + sin_pi_3 * 3.0f, 0.01f);
+
+	BOOST_CHECK_SMALL(data[1], 1e-5f);
+	BOOST_CHECK_CLOSE(data[5], 1.0f, 0.01);
+	BOOST_CHECK_SMALL(data[9], 1e-5f);
+	BOOST_CHECK_SMALL(data[13], 1e-5f);
+
+
+	BOOST_CHECK_CLOSE(data[2], sin_pi_3, 0.01);
+	BOOST_CHECK_SMALL(data[6], 1e-5f);
+	BOOST_CHECK_CLOSE(data[10],cos_pi_3, 0.01);
+	BOOST_CHECK_CLOSE(data[14],-20.0f * sin_pi_3 + 1.5f  , 0.01);
+
+	BOOST_CHECK_SMALL(data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+	BOOST_CHECK_CLOSE(data[15], 1.0f, 0.01);
+}
+
+BOOST_AUTO_TEST_CASE( test_rot_z_from_identity ) 
+{
+	
+	CAffinTransformMatrix m; 
+	
+	m.rotate_z(M_PI/3.0f, C3DFVector(20.0f, 12.0f, 3.0f)); 
+	
+	const float sin_pi_3 = sqrt(3.0f)/ 2.0f; 
+	const float cos_pi_3 = 1.0f/ 2.0f; 
+	
+	const auto& data = m.data();
+
+	BOOST_CHECK_CLOSE(data[0], cos_pi_3, 0.01f);
+	BOOST_CHECK_CLOSE(data[4], -sin_pi_3, 0.01f);
+	BOOST_CHECK_SMALL(data[8], 1e-5f);
+	BOOST_CHECK_CLOSE(data[12], 20.0f * 0.5f + sin_pi_3 * 12.0f, 0.01f);
+
+
+	BOOST_CHECK_CLOSE(data[1], sin_pi_3, 0.01);
+	BOOST_CHECK_CLOSE(data[5],cos_pi_3, 0.01);
+	BOOST_CHECK_SMALL(data[9], 1e-5f);
+	BOOST_CHECK_CLOSE(data[13], -20.0f * sin_pi_3 + 6.0f  , 0.01);
+
+
+	BOOST_CHECK_SMALL(data[2], 1e-5f);
+	BOOST_CHECK_SMALL(data[6], 1e-5f);
+	BOOST_CHECK_CLOSE(data[10], 1.0f, 0.01);
+	BOOST_CHECK_SMALL(data[14], 1e-5f);
+
+
+	BOOST_CHECK_SMALL(data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+	BOOST_CHECK_CLOSE(data[15], 1.0f, 0.01);
+}
+
+BOOST_AUTO_TEST_CASE( test_translate_from_identity ) 
+{
+	CAffinTransformMatrix m; 
+	m.translate(C3DFVector(2.0f, 3.0f, 4.0f)); 
+	
+	const auto& data = m.data();
+
+	BOOST_CHECK_CLOSE(data[0], 1.0f, 0.01f);
+	BOOST_CHECK_SMALL(data[4], 1e-5f);
+	BOOST_CHECK_SMALL(data[8], 1e-5f);
+	BOOST_CHECK_CLOSE(data[12], 2.0f, 0.01f);
+
+
+	BOOST_CHECK_SMALL(data[1], 1e-5f);
+	BOOST_CHECK_CLOSE(data[5], 1.0f, 0.01f);
+	BOOST_CHECK_SMALL(data[9], 1e-5f);
+	BOOST_CHECK_CLOSE(data[13], 3.0f, 0.01f);
+
+
+	BOOST_CHECK_SMALL(data[2], 1e-5f);
+	BOOST_CHECK_SMALL(data[6], 1e-5f);
+	BOOST_CHECK_CLOSE(data[10], 1.0f, 0.01f);
+	BOOST_CHECK_CLOSE(data[14], 4.0f, 0.01);
+
+
+	BOOST_CHECK_SMALL(data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+	BOOST_CHECK_CLOSE(data[15], 1.0f, 0.01);
+	
+
+	const auto inv = m.inverse(); 
+	const auto& inv_data = inv.data();
+
+
+	BOOST_CHECK_CLOSE(inv_data[0], 1.0f, 0.01f);
+	BOOST_CHECK_SMALL(inv_data[4], 1e-5f);
+	BOOST_CHECK_SMALL(inv_data[8], 1e-5f);
+	BOOST_CHECK_CLOSE(inv_data[12], -2.0f, 0.01f);
+
+
+	BOOST_CHECK_SMALL(inv_data[1], 1e-5f);
+	BOOST_CHECK_CLOSE(inv_data[5], 1.0f, 0.01f);
+	BOOST_CHECK_SMALL(inv_data[9], 1e-5f);
+	BOOST_CHECK_CLOSE(inv_data[13], -3.0f, 0.01f);
+
+
+	BOOST_CHECK_SMALL(inv_data[2], 1e-5f);
+	BOOST_CHECK_SMALL(inv_data[6], 1e-5f);
+	BOOST_CHECK_CLOSE(inv_data[10], 1.0f, 0.01f);
+	BOOST_CHECK_CLOSE(inv_data[14], -4.0f, 0.01);
+
+
+	BOOST_CHECK_SMALL(inv_data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(inv_data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(inv_data[11], 1e-5f); 
+	BOOST_CHECK_CLOSE(inv_data[15], 1.0f, 0.01);
+}
+
+
+struct ConcatationFixture {
+	
+	ConcatationFixture(); 
+	void run_check(const CAffinTransformMatrix& m); 
+
+	CAffinTransformMatrix start; 
+	C3DFVector x; 
+	C3DFVector y1;
+}; 
+
+ConcatationFixture::ConcatationFixture():
+	start(2.0f, 1.0f, 3.0f, 1.0f, 
+	      2.0f, 0.5f, 4.0f, 2.0f, 
+	      3.0f, 4.0f, 0.2f, 1.0f), 
+	x(2.0, 4.0, 9.0), 
+	y1(start * x)
+	
+{
+}
+
+void ConcatationFixture::run_check(const CAffinTransformMatrix& m)
+{
+	C3DFVector y2_direct = start * x;
+	C3DFVector y2_step = m * y1; 
+
+	BOOST_CHECK_CLOSE(y2_direct.x, y2_step.x, 0.01); 
+	BOOST_CHECK_CLOSE(y2_direct.y, y2_step.y, 0.01); 
+	BOOST_CHECK_CLOSE(y2_direct.z, y2_step.z, 0.01); 
+	
+}
+
+BOOST_FIXTURE_TEST_CASE( test_translate , ConcatationFixture) 
+{
+	C3DFVector t(1.0, 2.0, 3.0); 
+	start.translate(t); 
+
+	CAffinTransformMatrix m; 
+	m.translate(t); 
+	
+	run_check(m); 
+}
+
+BOOST_AUTO_TEST_CASE( test_scale_from_identity ) 
+{
+	CAffinTransformMatrix m;
+	
+	C3DFVector center(1,2,3); 
+	m.scale(C3DFVector(2.0f, 3.0f, 4.0f), center); 
+
+	
+	const auto& data = m.data(); 
+
+	BOOST_CHECK_CLOSE(data[0], 2.0f, 0.01f);
+	BOOST_CHECK_SMALL(data[4], 1e-5f);
+	BOOST_CHECK_SMALL(data[8], 1e-5f);
+	BOOST_CHECK_CLOSE(data[12], -1.0f, 0.01f);
+
+	BOOST_CHECK_SMALL(data[1], 1e-5f);
+	BOOST_CHECK_CLOSE(data[5], 3.0f, 0.01f);
+	BOOST_CHECK_SMALL(data[9], 1e-5f);
+	BOOST_CHECK_CLOSE(data[13], -4.0f, 0.01f);
+
+	BOOST_CHECK_SMALL(data[2], 1e-5f);
+	BOOST_CHECK_SMALL(data[6], 1e-5f);
+	BOOST_CHECK_CLOSE(data[10], 4.0f, 0.01f);
+	BOOST_CHECK_CLOSE(data[14],-9.0f, 0.01);
+
+	BOOST_CHECK_SMALL(data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+	BOOST_CHECK_CLOSE(data[15], 1.0f, 0.01);
+	
+}
+
+
+BOOST_AUTO_TEST_CASE( test_rot_from_quaternion_and_identity ) 
+{
+	CAffinTransformMatrix m; 
+
+	C3DFVector center(20.0f, 12.0f, 3.0f); 
+	Quaternion q(sqrt(10.0f)/4.0f, 0.25f, -0.25f, 0.5f); 
+	
+	m.rotate(q, center);
+	
+	const auto& data = m.data();
+
+	BOOST_CHECK_CLOSE(data[0], 0.375f, 0.01f);
+	BOOST_CHECK_CLOSE(data[4], 2 * ( -1/16.0- sqrt(10.0)/8.0)  , 0.01f);
+	BOOST_CHECK_CLOSE(data[8], 2 * (0.125 - sqrt(10.0)/16.0 ), 0.01f );
+	BOOST_CHECK_CLOSE(data[12], 20.0f - (data[0] * 20.0f + data[4] *12.0f + data[8] * 3.0f  ), 0.01f);
+
+
+	BOOST_CHECK_CLOSE(data[1], 2 * ( sqrt(10.0)/8.0 -1/16.0) , 0.01);
+	BOOST_CHECK_CLOSE(data[5], 0.375f, 0.01);
+	BOOST_CHECK_CLOSE(data[9], 2 * (-.125 - sqrt(10.0)/16.0), 0.01f);
+	BOOST_CHECK_CLOSE(data[13], 12.0f - (data[1] * 20 + data[5] *12.0f + data[9] * 3.0f  ) , 0.01);
+
+
+	BOOST_CHECK_CLOSE(data[2], 2 * (1/8.0 + sqrt(10.0)/16.0), 0.01f);
+	BOOST_CHECK_CLOSE(data[6], 2 * (-1/8.0 + sqrt(10.0)/16.0), 0.01f);
+	BOOST_CHECK_CLOSE(data[10], 3.0f/4.0f, 0.01);
+	BOOST_CHECK_CLOSE(data[14], 3.0f - (data[2] * 20 + data[6] *12.0f + data[10]* 3.0f  ), 0.01f);
+
+
+	BOOST_CHECK_SMALL(data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+	BOOST_CHECK_CLOSE(data[15], 1.0f, 0.01);
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_rot_from_quaternion_and_pseudorando_matrix , ConcatationFixture) 
+{
+	
+	C3DFVector center(20.0f, 12.0f, 3.0f); 
+	Quaternion q(sqrt(10.0f)/4.0f, 0.25f, -0.25f, 0.5f); 
+
+	CAffinTransformMatrix m; 	
+	m.rotate(q, center);
+	start.rotate(q, center);
+	
+	run_check(m); 
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_rot_x_pseudorando_matrix , ConcatationFixture) 
+{
+	
+	C3DFVector center(20.0f, 12.0f, 3.0f); 
+
+	CAffinTransformMatrix m; 	
+	m.rotate_x(1.0, center);
+	start.rotate_x(1.0, center);
+	
+	run_check(m); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_rot_y_pseudorando_matrix , ConcatationFixture) 
+{
+	
+	C3DFVector center(20.0f, 12.0f, 3.0f); 
+
+	CAffinTransformMatrix m; 	
+	m.rotate_y(1.0, center);
+	start.rotate_y(1.0, center);
+	
+	run_check(m); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_rot_z_pseudorando_matrix , ConcatationFixture) 
+{
+	
+	C3DFVector center(20.0f, 12.0f, 3.0f); 
+
+	CAffinTransformMatrix m; 	
+	m.rotate_z(1.0, center);
+	start.rotate_z(1.0, center);
+	
+	run_check(m); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_scale_pseudorando_matrix , ConcatationFixture) 
+{
+	
+	C3DFVector center(20.0f, 12.0f, 3.0f); 
+	C3DFVector scales(2.0f, 12.0f, 0.5f); 
+
+	CAffinTransformMatrix m; 	
+	m.scale(scales, center);
+	start.scale(scales, center);
+	
+	run_check(m); 
+}
+
+
+BOOST_AUTO_TEST_CASE( test_multiply ) 
+{
+	CAffinTransformMatrix lhs(2.0f, 1.0f, 3.0f, 1.0f, 
+				  2.0f, 0.5f, 4.0f, 2.0f, 
+				  3.0f, 4.0f, 0.2f, 1.0f); 
+
+	CAffinTransformMatrix rhs(3.0f, 4.0f, 1.0f, 7.0f, 
+				  2.0f, 1.5f, 2.0f, 3.0f, 
+				  3.5f, 2.0f, 2.2f, 2.0f);
+
+	lhs *= rhs; 
+	
+	const auto& data = lhs.data();
+
+	BOOST_CHECK_CLOSE(data[0], 18.5, 0.01);
+	BOOST_CHECK_CLOSE(data[4], 15.5, 0.01);
+	BOOST_CHECK_CLOSE(data[8], 10.6, 0.01);
+	BOOST_CHECK_CLOSE(data[12], 24.0, 0.01);
+
+	BOOST_CHECK_CLOSE(data[1], 21.0, 0.01);
+	BOOST_CHECK_CLOSE(data[5], 16.75, 0.01);
+	BOOST_CHECK_CLOSE(data[9], 11.8, 0.01);
+	BOOST_CHECK_CLOSE(data[13], 25.5, 0.01);
+
+	BOOST_CHECK_CLOSE(data[2], 17.7, 0.01);
+	BOOST_CHECK_CLOSE(data[6], 18.4, 0.01);
+	BOOST_CHECK_CLOSE(data[10], 11.44, 0.01);
+	BOOST_CHECK_CLOSE(data[14], 34.4, 0.01);
+
+	BOOST_CHECK_SMALL(data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+	BOOST_CHECK_EQUAL(data[15], 1.0f);
+	
+}
+
+#if 0 
+// not yet supported, will be added if needed 
+BOOST_AUTO_TEST_CASE( test_shear ) 
+{
+	CAffinTransformMatrix m; 
+	m.shear(1.1, 1.5, 0.5); 
+
+	C3DFVector x(1,2,3); 
+
+	auto y = m * x; 
+	
+	BOOST_CHECK_CLOSE(y.x, 5.6f, 0.01f);
+	BOOST_CHECK_CLOSE(y.y, 4.5f, 0.01f);
+	BOOST_CHECK_CLOSE(y.z, 3.0f, 0.01f);
+
+
+}
+#endif 
+
+BOOST_AUTO_TEST_CASE( test_multiply_const_input ) 
+{
+	const CAffinTransformMatrix lhs(2.0f, 1.0f, 3.0f, 1.0f, 
+				  2.0f, 0.5f, 4.0f, 2.0f, 
+				  3.0f, 4.0f, 0.2f, 1.0f); 
+
+	const CAffinTransformMatrix rhs(3.0f, 4.0f, 1.0f, 7.0f, 
+				  2.0f, 1.5f, 2.0f, 3.0f, 
+				  3.5f, 2.0f, 2.2f, 2.0f);
+
+	auto r = lhs * rhs; 
+	
+	const auto& data = r.data();
+
+	BOOST_CHECK_CLOSE(data[0], 18.5, 0.01);
+	BOOST_CHECK_CLOSE(data[4], 15.5, 0.01);
+	BOOST_CHECK_CLOSE(data[8], 10.6, 0.01);
+	BOOST_CHECK_CLOSE(data[12], 24.0, 0.01);
+
+	BOOST_CHECK_CLOSE(data[1], 21.0, 0.01);
+	BOOST_CHECK_CLOSE(data[5], 16.75, 0.01);
+	BOOST_CHECK_CLOSE(data[9], 11.8, 0.01);
+	BOOST_CHECK_CLOSE(data[13], 25.5, 0.01);
+
+	BOOST_CHECK_CLOSE(data[2], 17.7, 0.01);
+	BOOST_CHECK_CLOSE(data[6], 18.4, 0.01);
+	BOOST_CHECK_CLOSE(data[10], 11.44, 0.01);
+	BOOST_CHECK_CLOSE(data[14], 34.4, 0.01);
+
+	BOOST_CHECK_SMALL(data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+	BOOST_CHECK_EQUAL(data[15], 1.0f);
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_shear_at_zero ) 
+{
+	CAffinTransformMatrix m; 
+	m.shear(C3DFVector(2,3,4)); 
+
+	const auto& data = m.data();
+
+	BOOST_CHECK_CLOSE(data[0], 1.0f, 0.01);
+	BOOST_CHECK_CLOSE(data[4], 2.0f, 0.01);
+	BOOST_CHECK_SMALL(data[8], 1e-5f); 
+	BOOST_CHECK_SMALL(data[12], 1e-5f); 
+
+
+	BOOST_CHECK_SMALL(data[1], 1e-5f);
+	BOOST_CHECK_CLOSE(data[5], 1.0f, 0.01);
+	BOOST_CHECK_CLOSE(data[9], 3.0f, 0.01);
+	BOOST_CHECK_SMALL(data[13], 1e-5f);
+
+	BOOST_CHECK_CLOSE(data[2], 4.0f, 0.01);
+	BOOST_CHECK_SMALL(data[6], 1e-5f);
+	BOOST_CHECK_CLOSE(data[10], 1.0f, 0.01);
+	BOOST_CHECK_SMALL(data[14], 1e-5f);
+
+	BOOST_CHECK_SMALL(data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+	BOOST_CHECK_EQUAL(data[15], 1.0f);
+
+
+}
+
+BOOST_AUTO_TEST_CASE( test_zero_shear_centered ) 
+{
+	CAffinTransformMatrix m;
+	C3DFVector center(2,3,4); 
+	m.shear(C3DFVector::_0, center);
+
+	const auto& data = m.data();
+
+	BOOST_CHECK_CLOSE(data[0], 1.0f, 0.01);
+	BOOST_CHECK_SMALL(data[4], 1e-5f);
+	BOOST_CHECK_SMALL(data[8], 1e-5f); 
+	BOOST_CHECK_SMALL(data[12], 1e-5f); 
+
+
+	BOOST_CHECK_SMALL(data[1], 1e-5f);
+	BOOST_CHECK_CLOSE(data[5], 1.0f, 0.01);
+	BOOST_CHECK_SMALL(data[9], 1e-5f);
+	BOOST_CHECK_SMALL(data[13], 1e-5f);
+
+	BOOST_CHECK_SMALL(data[2], 1e-5f);
+	BOOST_CHECK_SMALL(data[6], 1e-5f);
+	BOOST_CHECK_CLOSE(data[10], 1.0f, 0.01);
+	BOOST_CHECK_SMALL(data[14], 1e-5f);
+
+	BOOST_CHECK_SMALL(data[3], 1e-5f); 
+	BOOST_CHECK_SMALL(data[7], 1e-5f); 
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+	BOOST_CHECK_EQUAL(data[15], 1.0f);
+
+	auto vt = m * center; 
+
+	BOOST_CHECK_CLOSE(vt.x, center.x, 0.01);
+	BOOST_CHECK_CLOSE(vt.y, center.y, 0.01);
+	BOOST_CHECK_CLOSE(vt.z, center.z, 0.01);
+	
+}
+
+
+BOOST_AUTO_TEST_CASE( test_shear_centered ) 
+{
+	CAffinTransformMatrix m; 
+	C3DFVector center(2,3,4);
+
+	m.shear(C3DFVector(0.2,0.3,0.4), center);
+
+	const auto& data = m.data();
+
+	BOOST_CHECK_CLOSE(data[0], 1.0f, 0.01);
+	BOOST_CHECK_SMALL(data[1], 1e-5f);
+	BOOST_CHECK_CLOSE(data[2], 0.4f, 1e-5f);
+	BOOST_CHECK_SMALL(data[3], 1e-5f);
+
+	BOOST_CHECK_CLOSE(data[4], 0.2f, 1e-5f);
+	BOOST_CHECK_CLOSE(data[5], 1.0f, 0.01);
+	BOOST_CHECK_SMALL(data[6], 1e-5f);
+	BOOST_CHECK_SMALL(data[7], 1e-5f);
+
+	BOOST_CHECK_SMALL(data[8], 1e-5f); 
+	BOOST_CHECK_CLOSE(data[9], 0.3f, 1e-5f);
+	BOOST_CHECK_CLOSE(data[10], 1.0f, 0.01);
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+
+	BOOST_CHECK_CLOSE(data[12], -0.6, 1e-4f); 
+	BOOST_CHECK_CLOSE(data[13], -1.2, 1e-4f); 
+	BOOST_CHECK_CLOSE(data[14],-0.8, 1e-4f); 
+	BOOST_CHECK_EQUAL(data[15], 1.0f);
+
+	auto cc = m * center; 
+
+	BOOST_CHECK_CLOSE(cc.x, center.x, 1e-4f); 
+	BOOST_CHECK_CLOSE(cc.y, center.y, 1e-4f); 
+	BOOST_CHECK_CLOSE(cc.z, center.z, 1e-4f); 
+
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_transform_centered ) 
+{
+	CAffinTransformMatrix lhs(2.0f, 1.0f, 3.0f, 1.0f, 
+				  2.0f, 8.0f, 4.0f, 2.0f, 
+				  3.0f, 4.0f, 6.0f, 1.0f); 
+	
+	C3DFMatrix m(C3DFVector(2.0, 3.0, 5.0), 
+		     C3DFVector(4.0, 1.0, 8.0), 
+		     C3DFVector(6.0, 7.0, 9.0)); 
+	
+
+	C3DFVector c(10,11,12);
+	
+	lhs.transform_centered(m, c);
+
+	const auto& data = lhs.data();
+
+	BOOST_CHECK_CLOSE(data[0], 25, 0.01);
+	BOOST_CHECK_CLOSE(data[1], 34, 0.01);
+	BOOST_CHECK_CLOSE(data[2], 53, 0.01);
+	BOOST_CHECK_SMALL(data[3], 1e-5f); 
+
+	BOOST_CHECK_CLOSE(data[4], 46, 0.01);
+	BOOST_CHECK_CLOSE(data[5], 44, 0.01);
+	BOOST_CHECK_CLOSE(data[6], 98, 0.01);
+	BOOST_CHECK_SMALL(data[7], 1e-5f); 
+
+	BOOST_CHECK_CLOSE(data[8], 48, 0.01);
+	BOOST_CHECK_CLOSE(data[9], 64, 0.01);
+	BOOST_CHECK_CLOSE(data[10], 100, 0.01);
+	BOOST_CHECK_SMALL(data[11], 1e-5f); 
+
+	BOOST_CHECK_CLOSE(data[12], -90, 0.01);
+	BOOST_CHECK_CLOSE(data[13], -122, 0.01);
+	BOOST_CHECK_CLOSE(data[14], -204, 0.01);
+	BOOST_CHECK_EQUAL(data[15], 1.0f);
+	
+}
diff --git a/mia/3d/test_combiner.cc b/mia/3d/test_combiner.cc
index 401395b..f08f305 100644
--- a/mia/3d/test_combiner.cc
+++ b/mia/3d/test_combiner.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_cost.cc b/mia/3d/test_cost.cc
index 6ac8f75..c328655 100644
--- a/mia/3d/test_cost.cc
+++ b/mia/3d/test_cost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -49,8 +49,8 @@ static void prepare_plugin_path()
 static void test_3dimage_cost_avail() 
 {
 	const C3DImageCostPluginHandler::Instance& fh = C3DImageCostPluginHandler::instance();
-	BOOST_CHECK(fh.size() == 3); 
-	BOOST_CHECK(fh.get_plugin_names() == "mi ngf ssd ");
+	BOOST_CHECK(fh.size() == 4); 
+	BOOST_CHECK(fh.get_plugin_names() == "mi ncc ngf ssd ");
 }
 
 static void test_3dimage_cost(const C3DImageCostPluginHandler::value_type& i)
diff --git a/mia/3d/test_datafield.cc b/mia/3d/test_datafield.cc
index 71c144f..271e80c 100644
--- a/mia/3d/test_datafield.cc
+++ b/mia/3d/test_datafield.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
  */
 
 #include <climits>
-#include <boost/test/unit_test_suite.hpp>
+
 #include <boost/test/unit_test.hpp>
 
 
@@ -29,7 +29,7 @@
 NS_MIA_USE
 using namespace std; 
 
-static void test_3ddatafield()
+BOOST_AUTO_TEST_CASE(test_3ddatafield)
 {
 
 	const float values[80]=
@@ -123,7 +123,7 @@ static C3DFDatafield create_field(const C3DBounds& size)
 }
 
 
-static void test_3ddatafield_get_put_xy()
+BOOST_AUTO_TEST_CASE(test_3ddatafield_get_put_xy)
 {
 	C3DBounds size(2,3,4);
 	C3DFDatafield data = create_field(size);
@@ -138,7 +138,7 @@ static void test_3ddatafield_get_put_xy()
 	BOOST_CHECK(equal(plane_xy.begin(), plane_xy.end(), data.begin_at(0,0,1)));
 }
 
-static void test_3ddatafield_zslice_flat()
+BOOST_AUTO_TEST_CASE(test_3ddatafield_zslice_flat)
 {
 	C3DBounds size(2,3,4);
 	C3DFDatafield data = create_field(size);
@@ -153,7 +153,7 @@ static void test_3ddatafield_zslice_flat()
 }
 
 
-static void test_3ddatafield_get_put_xz()
+BOOST_AUTO_TEST_CASE(test_3ddatafield_get_put_xz)
 {
 	C3DBounds size(2,3,4);
 	C3DFDatafield data = create_field(size);
@@ -174,7 +174,7 @@ static void test_3ddatafield_get_put_xz()
 
 }
 
-static void test_3ddatafield_yslice_flat()
+BOOST_AUTO_TEST_CASE( test_3ddatafield_yslice_flat )
 {
 	C3DBounds size(2,3,4);
 	C3DFDatafield data = create_field(size);
@@ -194,7 +194,7 @@ static void test_3ddatafield_yslice_flat()
 			BOOST_CHECK_EQUAL(*i, data(x,2,z));
 }
 
-static void test_3ddatafield_xslice_flat()
+BOOST_AUTO_TEST_CASE( test_3ddatafield_xslice_flat )
 {
 	C3DBounds size(2,3,4);
 	C3DFDatafield data = create_field(size);
@@ -216,7 +216,7 @@ static void test_3ddatafield_xslice_flat()
 
 
 
-static void test_3ddatafield_get_put_yz()
+BOOST_AUTO_TEST_CASE( test_3ddatafield_get_put_yz )
 {
 	C3DBounds size(2,3,4);
 	C3DFDatafield data = create_field(size);
@@ -236,13 +236,3 @@ static void test_3ddatafield_get_put_yz()
 			BOOST_CHECK(plane_yz(y, z) == data(1, y, z));
 }
 
-void add_3ddatafield_tests( boost::unit_test::test_suite* suite)
-{
-	suite->add( BOOST_TEST_CASE( &test_3ddatafield));
-	suite->add( BOOST_TEST_CASE( &test_3ddatafield_get_put_xy));
-	suite->add( BOOST_TEST_CASE( &test_3ddatafield_get_put_xz));
-	suite->add( BOOST_TEST_CASE( &test_3ddatafield_get_put_yz));
-	suite->add( BOOST_TEST_CASE( &test_3ddatafield_zslice_flat)); 
-	suite->add( BOOST_TEST_CASE( &test_3ddatafield_yslice_flat)); 
-	suite->add( BOOST_TEST_CASE( &test_3ddatafield_xslice_flat)); 
-}
diff --git a/mia/3d/test_deform.cc b/mia/3d/test_deform.cc
index a39c8f5..8cb1979 100644
--- a/mia/3d/test_deform.cc
+++ b/mia/3d/test_deform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,8 +30,6 @@ using namespace std;
 using namespace ::boost;
 using namespace boost::unit_test;
 
-CSplineKernelTestPath splinekernel_init_path; 
-
 struct DeformFixture {
 	DeformFixture();
 	void check(EInterpolation ip);
diff --git a/mia/3d/test_distance.cc b/mia/3d/test_distance.cc
index 24a5c80..5e5d553 100644
--- a/mia/3d/test_distance.cc
+++ b/mia/3d/test_distance.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_filter.cc b/mia/3d/test_filter.cc
deleted file mode 100644
index 8dfd980..0000000
--- a/mia/3d/test_filter.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include <boost/test/parameterized_test.hpp>
-#include <boost/test/unit_test.hpp>
-
-#include <mia/3d/filter.hh>
-#include <mia/core/history.hh>
-#include <mia/core/spacial_kernel.hh>
-#include <mia/3d/shape.hh>
-
-NS_MIA_USE
-using namespace std; 
-using namespace boost;
-namespace bfs=::boost::filesystem; 
-
-static void setup_filter_search_path()
-{
-	list< bfs::path> searchpath; 
-	if (bfs::path::default_name_check_writable())
-		bfs::path::default_name_check(bfs::portable_posix_name); 
-
-	searchpath.push_back(bfs::path("3d") / bfs::path("filter")); 
-	searchpath.push_back( bfs::path("filter")); 
-
-	C3DFilterPluginHandler::set_search_path(searchpath);
-}
-
-static void 	setup_kernel_search_path()
-{
-	list< bfs::path> searchpath; 
-	
-	if (bfs::path::default_name_check_writable())
-		bfs::path::default_name_check(::boost::filesystem::portable_posix_name); 
-
-	searchpath.push_back(bfs::path("core") / bfs::path("spacialkernel"));
-	searchpath.push_back(bfs::path("..") / bfs::path("core") / bfs::path("spacialkernel"));
-
-	C1DSpacialKernelPluginHandler::set_search_path(searchpath); 
-}
-
-static void setup_shape_search_path()
-{
-	list< bfs::path> searchpath; 
-	
-	if (bfs::path::default_name_check_writable())
-		bfs::path::default_name_check(::boost::filesystem::portable_posix_name); 
-
-	searchpath.push_back(bfs::path("3d") / bfs::path("shapes"));
-	searchpath.push_back(bfs::path("shapes"));
-
-	C3DShapePluginHandler::set_search_path(searchpath); 
-}
-
-static void test_3dfilter(const C3DFilterPluginHandler::value_type& i) 
-{
-	BOOST_CHECK_MESSAGE(i.second->test(true), i.second->get_long_name()); 
-}
-
-
-void add_3dfilter_plugin_tests( boost::unit_test::test_suite* suite)
-{
-	setup_filter_search_path(); 
-	setup_kernel_search_path(); 
-	setup_shape_search_path(); 
-
-	suite->add( BOOST_PARAM_TEST_CASE(&test_3dfilter, 
-					  C3DFilterPluginHandler::instance().begin(), 
-					  C3DFilterPluginHandler::instance().end()
-			    )); 
-}
diff --git a/mia/3d/test_fullcost.cc b/mia/3d/test_fullcost.cc
index 2119971..ad28eee 100644
--- a/mia/3d/test_fullcost.cc
+++ b/mia/3d/test_fullcost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,7 +29,6 @@
 
 NS_MIA_USE
 namespace bfs=::boost::filesystem; 
-CSplineKernelTestPath splinekernel_init_path; 
 
 class C3DFullCostMock: public C3DFullCost {
 public: 
diff --git a/mia/3d/test_ica.cc b/mia/3d/test_ica.cc
index 71eaa0a..2665b56 100644
--- a/mia/3d/test_ica.cc
+++ b/mia/3d/test_ica.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_image.cc b/mia/3d/test_image.cc
index c0e5eed..08c6300 100644
--- a/mia/3d/test_image.cc
+++ b/mia/3d/test_image.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,8 +34,6 @@ NS_MIA_USE
 using namespace boost;
 using namespace std;
 
-CSplineBoundaryConditionTestPath sbc_test_path; 
-
 class CCopyFilter: public TFilter<std::shared_ptr<C3DImage>  > {
 public:
 
@@ -84,7 +82,7 @@ static void creat_and_check(EPixelType type)
 	BOOST_CHECK(voxel2 == timg->get_voxel_size());
 }
 
-static void check_data_types()
+BOOST_AUTO_TEST_CASE( check_data_types )
 {
 	creat_and_check<bool>(it_bit);
 	creat_and_check<unsigned char>(it_ubyte);
@@ -103,7 +101,7 @@ static void check_data_types()
 
 
 
-static void check_gradient()
+BOOST_AUTO_TEST_CASE(check_gradient )
 {
 	const float init_data[64] = {
 		0, 1, 2, 3, /**/ 4, 6, 7, 9, /**/ 4, 3, 2, 1, /**/ 0, 7, 8, 9,
@@ -173,13 +171,22 @@ static void check_gradient()
 
 }
 
-void add_3dimage_tests( boost::unit_test::test_suite* suite)
+BOOST_AUTO_TEST_CASE( test_rotation_attribute )
 {
-	suite->add( BOOST_TEST_CASE(&check_data_types));
-	suite->add( BOOST_TEST_CASE(&check_gradient));
-}
-
+	C3DRotationAttributeTranslate::register_for("rotation3d");
+	string value("rot-quaternion=0.5,0.1,0.5,0.7");
 
+	PAttribute attr = CStringAttrTranslatorMap::instance().to_attr("rotation3d", value);
+	
+	const C3DRotationAttribute& ra = dynamic_cast<C3DRotationAttribute&>(*attr);
+	C3DRotation r = ra; 
+	auto q = r.as_quaternion(); 
+
+	BOOST_CHECK_EQUAL(q.w(), 0.5);
+	BOOST_CHECK_EQUAL(q.x(), 0.1);
+	BOOST_CHECK_EQUAL(q.y(), 0.5);
+	BOOST_CHECK_EQUAL(q.z(), 0.7);
+}
 
 BOOST_AUTO_TEST_CASE( test_voxel_attribute )
 {
diff --git a/mia/3d/test_imagecollect.cc b/mia/3d/test_imagecollect.cc
index 014fe53..6251e8d 100644
--- a/mia/3d/test_imagecollect.cc
+++ b/mia/3d/test_imagecollect.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_imageio.cc b/mia/3d/test_imageio.cc
deleted file mode 100644
index 529f490..0000000
--- a/mia/3d/test_imageio.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
- *
- * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with MIA; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#define BOOST_TEST_MODULE 3DIMAGEIO
-
-
-
-#ifndef BOOST_TEST_DYN_LINK
-#define BOOST_TEST_DYN_LINK
-#endif
-#define BOOST_TEST_ALTERNATIVE_INIT_API
-#define BOOST_TEST_MAIN
-#define BOOST_TEST_NO_MAIN
-#include <boost/test/unit_test.hpp>
-#include <boost/test/floating_point_comparison.hpp>
-
-#include <algorithm>
-
-#include <mia/core/msgstream.hh>
-#include <mia/core/cmdlineparser.hh>
-
-#include <boost/filesystem/convenience.hpp>
-#include <boost/filesystem/path.hpp>
-
-#include <mia/3d/imageio.hh>
-#include <mia/3d/imageiotest.hh>
-
-NS_MIA_USE
-using namespace boost;
-using namespace std;
-using namespace boost::unit_test;
-namespace bfs=::boost::filesystem;
-
-
-const SProgramDescription g_general_help = {
-        {pdi_group, "Tests"}, 
-	{pdi_short, "test 3D image IO"}, 
-	{pdi_description, "Run various test for 3D image IO."}
-}; 
-
-
-BOOST_AUTO_TEST_CASE(test_3dimageio_plugin_avail)
-{
-	const C3DImageIOPluginHandler::Instance&  handler = C3DImageIOPluginHandler::instance();
-
-	BOOST_CHECK(handler.size() == 4);
-	BOOST_CHECK(handler.get_plugin_names() == "analyze datapool inria vff ");
-
-}
-
-
-C3DImageIOPluginHandlerTestPath init_3dimage_path; 
-
-bool init_unit_test_suite( )
-{
-
-	cvdebug() << "init\n";
-	init_unit_test();
-	add_3dimageio_plugin_tests( &framework::master_test_suite());
-	return true;
-}
-
-
-
-NS_MIA_USE; 
-int BOOST_TEST_CALL_DECL
-do_main( int argc, char* argv[] )
-{
-
-#ifdef WIN32
-	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
-	_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
-#endif
-	if (CCmdOptionList(g_general_help).parse(argc, (const char **)argv) != CCmdOptionList::hr_no) 
-		return 0; 
-	cvdebug() << "Initialize test ...\n"; 
-	return ::boost::unit_test::unit_test_main( &init_unit_test_suite, argc, argv );
-}
-
-
-#include <mia/internal/main.hh>
-MIA_MAIN(do_main);
diff --git a/mia/3d/test_interpol.cc b/mia/3d/test_interpol.cc
index 501781e..860031d 100644
--- a/mia/3d/test_interpol.cc
+++ b/mia/3d/test_interpol.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,22 +20,19 @@
 
 #include <climits>
 
-#include <boost/test/unit_test_suite.hpp>
-#include <boost/test/unit_test.hpp>
-
 #include <tbb/parallel_for.h>
 #include <tbb/blocked_range.h>
 
+#include <boost/test/unit_test.hpp>
 #include <mia/3d/interpolator.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/core/threadedmsg.hh>
+#include <boost/mpl/vector.hpp>
 
 NS_MIA_USE
 using namespace std;
 using namespace boost;
-
-CSplineKernelTestPath spline_kernel_init_path; 
-
+namespace bmpl=boost::mpl;
 
 template <typename T, typename  I, bool is_int>
 struct __dispatch_check {
@@ -147,7 +144,7 @@ extern const char bspline5[] = "bspline:d=5";
 extern const char omomsspl3[] = "omoms:d=3"; 
 
 
-static void test_external_cache_interpolator() 
+BOOST_AUTO_TEST_CASE(test_external_cache_interpolator) 
 {
 	T3DDatafield<float> data(C3DBounds(10, 12, 11));
 	auto kernel = produce_spline_kernel(bspline3); 
@@ -237,7 +234,7 @@ struct FParallelInterpolator2 {
 	}
 }; 
 
-static void test_parallel_interpolator() 
+BOOST_AUTO_TEST_CASE(test_parallel_interpolator) 
 {
 	T3DDatafield<float> data(C3DBounds(10, 12, 11));
 	auto kernel = produce_spline_kernel(bspline3); 
@@ -262,7 +259,7 @@ static void test_parallel_interpolator()
 }
 
 
-static void test_parallel_interpolator_zerofill_shifted() 
+BOOST_AUTO_TEST_CASE(test_parallel_interpolator_zerofill_shifted) 
 {
 	C3DFVector shift(1,2,3); 
 
@@ -275,7 +272,7 @@ static void test_parallel_interpolator_zerofill_shifted()
 	for (size_t z = 0; z < data.get_size().z; ++z)
 		for (size_t y = 0; y < data.get_size().y; ++y)
 			for (size_t x = 0; x < data.get_size().x; ++x, ++i) {
-				*i = x + 10 * y + 100 * z;
+				*i = x + 10 * y + 100 * z + 2;
 				if (x >= 1 && y >= 2 && z >= 3) 
 					test_data(x - 1, y - 2, z - 3) = *i; 
 			}
@@ -313,7 +310,7 @@ static double omoms3(double x)
 	return ((0.5 * x - 1) * x + 1/14.0) * x + 13.0 / 21.0;
 }
 
-static void test_omoms3()
+BOOST_AUTO_TEST_CASE(test_omoms3)
 {
 	const double x = 0.2;
 	auto kernel = produce_spline_kernel("omoms:d=3"); 
@@ -326,94 +323,27 @@ static void test_omoms3()
 	}
 }
 
-void add_3dinterpol_tests( boost::unit_test::test_suite* suite)
-{
-	suite->add( BOOST_TEST_CASE( &test_omoms3));
-
-
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned char, bspline1>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed char, bspline1>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned short, bspline1>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed short, bspline1>)));
-#ifdef LONG_64BIT
-	suite->add( BOOST_TEST_CASE(( &test_type<signed long, bspline1>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned long, bspline1>)));
-#endif
-	suite->add( BOOST_TEST_CASE( (&test_type<float, bspline1>)));
-	suite->add( BOOST_TEST_CASE( (&test_type<double, bspline1>)));
-
-
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned char, bspline2>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed char, bspline2>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned short, bspline2>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed short, bspline2>)));
-#ifdef LONG_64BIT
-	suite->add( BOOST_TEST_CASE(( &test_type<signed long, bspline2>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned long, bspline2>)));
-#endif
-	suite->add( BOOST_TEST_CASE( (&test_type<float, bspline2>)));
-	suite->add( BOOST_TEST_CASE( (&test_type<double, bspline2>)));
-
-
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned char, bspline3>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed char, bspline3>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned short, bspline3>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed short, bspline3>)));
-#ifdef LONG_64BIT
-	suite->add( BOOST_TEST_CASE(( &test_type<signed long, bspline3>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned long, bspline3>)));
-#endif
-	suite->add( BOOST_TEST_CASE( (&test_type<float, bspline3>)));
-	suite->add( BOOST_TEST_CASE( (&test_type<double, bspline3>)));
-
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned char, bspline4>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed char, bspline4>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned short, bspline4>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed short, bspline4>)));
+typedef bmpl::vector<unsigned char,
+		     signed char, 
+		     unsigned short, 
+		     signed short, 
 #ifdef LONG_64BIT
-	suite->add( BOOST_TEST_CASE(( &test_type<signed long, bspline4>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned long, bspline4>)));
+		     signed long, 
+		     unsigned long, 
 #endif
-	suite->add( BOOST_TEST_CASE( (&test_type<float, bspline4>)));
-	suite->add( BOOST_TEST_CASE( (&test_type<double, bspline4>)));
+		     float, 
+		     double> types; 
 
 
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned char, bspline5>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed char, bspline5>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned short, bspline5>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed short, bspline5>)));
-#ifdef LONG_64BIT
-	suite->add( BOOST_TEST_CASE(( &test_type<signed long, bspline5>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned long, bspline5>)));
-#endif
-	suite->add( BOOST_TEST_CASE( (&test_type<float, bspline5>)));
-	suite->add( BOOST_TEST_CASE( (&test_type<double, bspline5>)));
-
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned char, bspline0>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed char, bspline0>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned short, bspline0>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed short, bspline0>)));
-#ifdef LONG_64BIT
-	suite->add( BOOST_TEST_CASE(( &test_type<signed long, bspline0>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned long, bspline0>)));
-#endif
-	suite->add( BOOST_TEST_CASE( (&test_type<float, bspline0>)));
-	suite->add( BOOST_TEST_CASE( (&test_type<double, bspline0>)));
-
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned char, omomsspl3>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed char, omomsspl3>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned short, omomsspl3>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<signed short, omomsspl3>)));
-#ifdef LONG_64BIT
-	suite->add( BOOST_TEST_CASE(( &test_type<signed long, omomsspl3>)));
-	suite->add( BOOST_TEST_CASE(( &test_type<unsigned long, omomsspl3>)));
-#endif
-	suite->add( BOOST_TEST_CASE( (&test_type<float, omomsspl3>)));
-	suite->add( BOOST_TEST_CASE( (&test_type<double, omomsspl3>)));
-
-	suite->add( BOOST_TEST_CASE( (&test_external_cache_interpolator))); 
-	suite->add( BOOST_TEST_CASE( (&test_parallel_interpolator))); 
-
-	suite->add( BOOST_TEST_CASE( (&test_parallel_interpolator_zerofill_shifted))); 
 
+BOOST_AUTO_TEST_CASE_TEMPLATE( test_types, T , types )
+{	
+	test_type<T, bspline1>(); 
+	test_type<T, bspline2>();
+	test_type<T, bspline3>();
+	test_type<T, bspline4>();
+	test_type<T, bspline5>();
+	test_type<T, bspline0>();
+	test_type<T, omomsspl3>();
 }
+
diff --git a/mia/3d/test_iterator.cc b/mia/3d/test_iterator.cc
index 1878abe..0496e9e 100644
--- a/mia/3d/test_iterator.cc
+++ b/mia/3d/test_iterator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -114,24 +114,24 @@ BOOST_AUTO_TEST_CASE (test_iterator_boundaries)
 	C3DBounds start(0,0,0);
 	T3DDatafield<int> test(size); 
 	
-	fill(test.begin(), test.end(), C3DFDatafield::range_iterator::eb_none); 
+	fill(test.begin(), test.end(), C3DFDatafield::range_iterator_with_boundary_flag::eb_none); 
 
-	fill(test.begin_at(0,0,0), test.begin_at(0,0,1), C3DFDatafield::range_iterator::eb_zlow); 
-	fill(test.begin_at(0,0,size.z - 1), test.begin_at(0,0,size.z), C3DFDatafield::range_iterator::eb_zhigh); 
+	fill(test.begin_at(0,0,0), test.begin_at(0,0,1), C3DFDatafield::range_iterator_with_boundary_flag::eb_zlow); 
+	fill(test.begin_at(0,0,size.z - 1), test.begin_at(0,0,size.z), C3DFDatafield::range_iterator_with_boundary_flag::eb_zhigh); 
 
 	for (unsigned int  z = 0; z < size.z; ++z) 
 		for (unsigned int  y = 0; y < size.y; ++y) {
-			test(0,y,z) |= C3DFDatafield::range_iterator::eb_xlow; 
-			test(size.x - 1,y,z) |= C3DFDatafield::range_iterator::eb_xhigh;
+			test(0,y,z) |= C3DFDatafield::range_iterator_with_boundary_flag::eb_xlow; 
+			test(size.x - 1,y,z) |= C3DFDatafield::range_iterator_with_boundary_flag::eb_xhigh;
 		}
 
 	for (unsigned int  z = 0; z < size.z; ++z) 
 		for (unsigned int  x = 0; x < size.x; ++x) {
-			test(x,0,z) |= C3DFDatafield::range_iterator::eb_ylow; 
-			test(x, size.y-1,z) |= C3DFDatafield::range_iterator::eb_yhigh;
+			test(x,0,z) |= C3DFDatafield::range_iterator_with_boundary_flag::eb_ylow; 
+			test(x, size.y-1,z) |= C3DFDatafield::range_iterator_with_boundary_flag::eb_yhigh;
 		}
-	auto ifield = field.begin_range(C3DBounds(0,0,0), size); 
-	auto efield = field.end_range(C3DBounds(0,0,0), size); 
+	auto ifield = field.begin_range(C3DBounds(0,0,0), size).with_boundary_flag(); 
+	auto efield = field.end_range(C3DBounds(0,0,0), size).with_boundary_flag(); 
 	auto itest = test.begin(); 
 	
 	for (;ifield != efield; ++ifield, ++itest) {
@@ -144,18 +144,24 @@ BOOST_AUTO_TEST_CASE (test_iterator_some_boundaries)
 	C3DBounds size(7,5,6); 
 	C3DFDatafield field(size);
 
-	auto ifield = field.begin_range(C3DBounds(1,1,0), size - C3DBounds(0,1,1)); 
-	auto efield = field.end_range(C3DBounds(1,1,0), size - C3DBounds(0,1,1)); 
+	auto ifield = field.begin_range(C3DBounds(1,1,0), size - C3DBounds(0,1,1)).with_boundary_flag(); 
+	auto efield = field.end_range(C3DBounds(1,1,0), size - C3DBounds(0,1,1)).with_boundary_flag(); 
 	
 	for (;ifield != efield; ++ifield) {
 		cvdebug() <<ifield.pos()<< " : " << ifield.get_boundary_flags() << "\n"; 
-		BOOST_CHECK_EQUAL(ifield.pos().x == 0, bool(ifield.get_boundary_flags() & C3DFDatafield::range_iterator::eb_xlow)); 
-		BOOST_CHECK_EQUAL(ifield.pos().y == 0, bool(ifield.get_boundary_flags() & C3DFDatafield::range_iterator::eb_ylow)); 
-		BOOST_CHECK_EQUAL(ifield.pos().z == 0, bool(ifield.get_boundary_flags() & C3DFDatafield::range_iterator::eb_zlow)); 
+		BOOST_CHECK_EQUAL(ifield.pos().x == 0, bool(ifield.get_boundary_flags() & 
+							    C3DFDatafield::range_iterator_with_boundary_flag::eb_xlow)); 
+		BOOST_CHECK_EQUAL(ifield.pos().y == 0, bool(ifield.get_boundary_flags() & 
+							    C3DFDatafield::range_iterator_with_boundary_flag::eb_ylow)); 
+		BOOST_CHECK_EQUAL(ifield.pos().z == 0, bool(ifield.get_boundary_flags() & 
+							    C3DFDatafield::range_iterator_with_boundary_flag::eb_zlow)); 
 		
-		BOOST_CHECK_EQUAL(ifield.pos().x == 6, bool(ifield.get_boundary_flags() & C3DFDatafield::range_iterator::eb_xhigh)); 
-		BOOST_CHECK_EQUAL(ifield.pos().y == 4, bool(ifield.get_boundary_flags() & C3DFDatafield::range_iterator::eb_yhigh)); 
-		BOOST_CHECK_EQUAL(ifield.pos().z == 5, bool(ifield.get_boundary_flags() & C3DFDatafield::range_iterator::eb_zhigh)); 
+		BOOST_CHECK_EQUAL(ifield.pos().x == 6, bool(ifield.get_boundary_flags() & 
+							    C3DFDatafield::range_iterator_with_boundary_flag::eb_xhigh)); 
+		BOOST_CHECK_EQUAL(ifield.pos().y == 4, bool(ifield.get_boundary_flags() & 
+							    C3DFDatafield::range_iterator_with_boundary_flag::eb_yhigh)); 
+		BOOST_CHECK_EQUAL(ifield.pos().z == 5, bool(ifield.get_boundary_flags() & 
+							    C3DFDatafield::range_iterator_with_boundary_flag::eb_zhigh)); 
 	}
 }
 
@@ -166,14 +172,45 @@ BOOST_AUTO_TEST_CASE (test_iterator_no_boundaries)
 
 	C3DBounds start(1,1,1);
 	
-	auto ifield = field.begin_range(C3DBounds(1,1,1), size - C3DBounds::_1); 
-	auto efield = field.end_range(C3DBounds(1,1,1), size - C3DBounds::_1); 
+	auto ifield = field.begin_range(C3DBounds(1,1,1), size - C3DBounds::_1).with_boundary_flag(); 
+	auto efield = field.end_range(C3DBounds(1,1,1), size - C3DBounds::_1).with_boundary_flag(); 
 	
 	for (;ifield != efield; ++ifield) {
 		BOOST_CHECK_EQUAL(ifield.get_boundary_flags(), 0); 
 	}
 }
 
+// this tests whether the traits are properly set
+BOOST_AUTO_TEST_CASE (test_std_copy) 
+{
+	C3DBounds size(7,5,6); 
+	C3DFVectorfield in_field(size);
+	C3DBounds start(1,2,2); 
+	C3DBounds end(6,3,5); 
+	C3DBounds out_size = end - start; 
+	C3DFVectorfield out_field(out_size);
+
+	auto ibegin = in_field.begin_range(start, end);
+	auto iend = in_field.end_range(start, end);
+	
+	while (ibegin != iend) {
+		*ibegin = C3DFVector(ibegin.pos()); 
+		++ibegin; 
+	}
+
+	std::copy(in_field.begin_range(start, end), in_field.end_range(start, end), out_field.begin()); 
+	
+	auto ofb = out_field.begin_range(C3DBounds::_0, out_size); 
+	auto ofe = out_field.end_range(C3DBounds::_0, out_size); 
+	
+	while (ofb != ofe) {
+		BOOST_CHECK_EQUAL(*ofb, C3DFVector(ofb.pos() + start)); 
+		++ofb; 
+	}
+	
+	
+}
+
 	
 BOOST_AUTO_TEST_CASE (test_fill_part) 
 {
diff --git a/mia/3d/test_landmark.cc b/mia/3d/test_landmark.cc
index 5a44474..906150d 100644
--- a/mia/3d/test_landmark.cc
+++ b/mia/3d/test_landmark.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_landmarklistio.cc b/mia/3d/test_landmarklistio.cc
index bc02020..c23a714 100644
--- a/mia/3d/test_landmarklistio.cc
+++ b/mia/3d/test_landmarklistio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,8 +26,6 @@
 NS_MIA_USE
 using namespace std;
 
-C3DLandmarklistIOTestPath test_path; 
-
 BOOST_AUTO_TEST_CASE( test_available_plugins ) 
 {
 	set<string> expected_plugins = {"lmx", "datapool"};
diff --git a/mia/3d/test_matrix.cc b/mia/3d/test_matrix.cc
index 4e949d7..950de97 100644
--- a/mia/3d/test_matrix.cc
+++ b/mia/3d/test_matrix.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -106,21 +106,19 @@ void FixtureMatrixTest::run(const C3DFMatrix& m, const C3DFVector& test_values,
 	BOOST_CHECK_CLOSE(eval.y, test_values.y, 0.1); 
 	BOOST_CHECK_CLOSE(eval.z, test_values.z, 0.1); 
 	
-	C3DFVector vec; 
-	BOOST_CHECK_EQUAL(m.get_eigenvector(eval.x,vec), 0); 
+	C3DFVector vec =  m.get_eigenvector(0); 
 	
 	BOOST_CHECK_CLOSE(vec.x, ev1.x, 0.1); 
 	BOOST_CHECK_CLOSE(vec.y, ev1.y, 0.1); 
 	BOOST_CHECK_CLOSE(vec.z, ev1.z, 0.1); 
 
-
-	BOOST_CHECK_EQUAL(m.get_eigenvector(eval.y,vec), 0); 
+	vec =  m.get_eigenvector(1); 
 	
 	BOOST_CHECK_CLOSE(vec.x, ev2.x, 0.1); 
 	BOOST_CHECK_CLOSE(vec.y, ev2.y, 0.1); 
 	BOOST_CHECK_CLOSE(vec.z, ev2.z, 0.1); 
 
-	BOOST_CHECK_EQUAL(m.get_eigenvector(eval.z,vec), 0); 
+	vec =  m.get_eigenvector(2); 
 	
 	BOOST_CHECK_CLOSE(vec.x, ev3.x, 0.1); 
 	BOOST_CHECK_CLOSE(vec.y, ev3.y, 0.1); 
diff --git a/mia/3d/test_nfg.cc b/mia/3d/test_nfg.cc
index 6e0ca5b..4f14942 100644
--- a/mia/3d/test_nfg.cc
+++ b/mia/3d/test_nfg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_nonrigidregister.cc b/mia/3d/test_nonrigidregister.cc
index c331174..75834b5 100644
--- a/mia/3d/test_nonrigidregister.cc
+++ b/mia/3d/test_nonrigidregister.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_orientation.cc b/mia/3d/test_orientation.cc
index 6ac93c1..4cfa842 100644
--- a/mia/3d/test_orientation.cc
+++ b/mia/3d/test_orientation.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,7 +31,8 @@ using namespace boost;
 
 using namespace boost::unit_test;
 
-static void run_test_read(const string& id, E3DImageOrientation test_orient)
+static void run_test_read(const string& id, E3DImageOrientation test_orient, 
+			  const string& expect)
 {
 	E3DImageOrientation orient;
 	istringstream is(id);
@@ -40,16 +41,16 @@ static void run_test_read(const string& id, E3DImageOrientation test_orient)
 
 	stringstream os;
 	os << test_orient;
-	BOOST_CHECK_EQUAL(os.str(), id);
+	BOOST_CHECK_EQUAL(os.str(), expect);
 
 }
 
 BOOST_AUTO_TEST_CASE( test_orientation_streamio )
 {
-	run_test_read("axial", ior_axial);
-	run_test_read("coronal", ior_coronal);
-	run_test_read("saggital", ior_saggital);
-	run_test_read("unknown", ior_unknown);
+	run_test_read("axial", ior_axial, "axial");
+	run_test_read("coronal", ior_coronal, "coronal");
+	run_test_read("saggital", ior_saggital, "saggital");
+	run_test_read("unknown", ior_undefined, "(undefined)");
 }
 
 BOOST_AUTO_TEST_CASE( test_orientation_attribute )
@@ -63,3 +64,309 @@ BOOST_AUTO_TEST_CASE( test_orientation_attribute )
 	BOOST_CHECK_EQUAL(orient, ior_axial);
 }
 
+struct OrientationTestFixture {
+	void check_transform(const C3DOrientationAndPosition& op, const vector<double>& expect); 
+	void check_inv_transform(const C3DOrientationAndPosition& op, const vector<double>& expect); 
+private: 
+	void check(const CDoubleVector& params, const vector<double>& expect); 
+	
+}; 
+
+BOOST_FIXTURE_TEST_CASE(test_scale_x, OrientationTestFixture) 
+{
+	C3DOrientationAndPosition op(ior_default, C3DFVector::_0, C3DFVector(2.0, 1, 1), 
+				     Quaternion::_1);
+
+	vector<double> expect = {
+		2.0, 0.0, 0.0, 0.0, 
+		0.0, 1.0, 0.0, 0.0, 
+		0.0, 0.0, 1.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+
+	check_transform(op, expect); 
+
+	vector<double> inv_expect = {
+		0.5, 0.0, 0.0, 0.0, 
+		0.0, 1.0, 0.0, 0.0, 
+		0.0, 0.0, 1.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	
+	check_inv_transform(op, inv_expect); 
+	
+}
+
+
+BOOST_FIXTURE_TEST_CASE(test_shift_x, OrientationTestFixture) 
+{
+	C3DOrientationAndPosition op(ior_default, C3DFVector(3.0,0,0), C3DFVector::_1, 
+				     Quaternion::_1);
+
+	vector<double> expect = {
+		1.0, 0.0, 0.0, 3.0, 
+		0.0, 1.0, 0.0, 0.0, 
+		0.0, 0.0, 1.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+
+	check_transform(op, expect); 
+
+	vector<double> inv_expect = {
+		1.0, 0.0, 0.0,-3.0, 
+		0.0, 1.0, 0.0, 0.0, 
+		0.0, 0.0, 1.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	
+	check_inv_transform(op, inv_expect); 
+	
+}
+
+BOOST_FIXTURE_TEST_CASE(test_rot_x, OrientationTestFixture) 
+{
+	C3DOrientationAndPosition op(ior_default, C3DFVector::_0, C3DFVector::_1, 
+				     Quaternion(C3DDVector(0.5 * M_PI, 0, 0)));
+
+	vector<double> expect = {
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 0.0,-1.0, 0.0, 
+		0.0, 1.0, 0.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+
+	check_transform(op, expect); 
+
+	vector<double> inv_expect = {
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 0.0, 1.0, 0.0, 
+		0.0,-1.0, 0.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	
+	check_inv_transform(op, inv_expect); 
+}
+
+
+BOOST_FIXTURE_TEST_CASE(test_scale_y, OrientationTestFixture) 
+{
+	C3DOrientationAndPosition op(ior_default, C3DFVector::_0, C3DFVector(1.0, 2.0, 1), 
+				     Quaternion::_1);
+
+	vector<double> expect = {
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 2.0, 0.0, 0.0, 
+		0.0, 0.0, 1.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	check_transform(op, expect); 
+
+	vector<double> inv_expect = {
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 0.5, 0.0, 0.0, 
+		0.0, 0.0, 1.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	
+	check_inv_transform(op, inv_expect); 
+
+}
+
+BOOST_FIXTURE_TEST_CASE(test_shift_y, OrientationTestFixture) 
+{
+	C3DOrientationAndPosition op(ior_default,  C3DFVector(0.0, 2.0, 0), C3DFVector::_1,
+				     Quaternion::_1);
+
+	vector<double> expect = {
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 1.0, 0.0, 2.0, 
+		0.0, 0.0, 1.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	check_transform(op, expect); 
+
+	vector<double> inv_expect = {
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 1.0, 0.0,-2.0, 
+		0.0, 0.0, 1.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	
+	check_inv_transform(op, inv_expect); 
+
+}
+
+BOOST_FIXTURE_TEST_CASE(test_rot_y, OrientationTestFixture) 
+{
+	C3DOrientationAndPosition op(ior_default, C3DFVector::_0, C3DFVector::_1, 
+				     Quaternion(C3DDVector(0, 0.5 * M_PI, 0)));
+
+	vector<double> expect = {
+		0.0, 0.0, 1.0, 0.0, 
+		0.0, 1.0, 0.0, 0.0, 
+	       -1.0, 0.0, 0.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+
+	check_transform(op, expect); 
+
+	vector<double> inv_expect = {
+		0.0, 0.0,-1.0, 0.0, 
+		0.0, 1.0, 0.0, 0.0, 
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	
+	check_inv_transform(op, inv_expect); 
+	
+}
+
+
+BOOST_FIXTURE_TEST_CASE(test_scale_z, OrientationTestFixture) 
+{
+	C3DOrientationAndPosition op(ior_default, C3DFVector::_0, C3DFVector(1.0, 1.0, 2.0), 
+				     Quaternion::_1);
+
+	vector<double> expect = {
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 1.0, 0.0, 0.0, 
+		0.0, 0.0, 2.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	check_transform(op, expect); 
+
+	vector<double> inv_expect = {
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 1.0, 0.0, 0.0, 
+		0.0, 0.0, 0.5, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	
+	check_inv_transform(op, inv_expect); 
+
+}
+
+BOOST_FIXTURE_TEST_CASE(test_shift_z, OrientationTestFixture) 
+{
+	C3DOrientationAndPosition op(ior_default, C3DFVector(0.0, 0.0, 7.0), C3DFVector::_1, 
+				     Quaternion::_1);
+
+	vector<double> expect = {
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 1.0, 0.0, 0.0, 
+		0.0, 0.0, 1.0, 7.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	check_transform(op, expect); 
+
+	vector<double> inv_expect = {
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 1.0, 0.0, 0.0, 
+		0.0, 0.0, 1.0,-7.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	
+	check_inv_transform(op, inv_expect); 
+
+}
+
+BOOST_FIXTURE_TEST_CASE(test_rot_z, OrientationTestFixture) 
+{
+	C3DOrientationAndPosition op(ior_default, C3DFVector::_0, C3DFVector::_1, 
+				     Quaternion(C3DDVector(0, 0, 0.5 * M_PI)));
+
+	vector<double> expect = {
+		0.0,-1.0, 0.0, 0.0, 
+		1.0, 0.0, 0.0, 0.0, 
+	        0.0, 0.0, 1.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+
+	check_transform(op, expect); 
+
+	vector<double> inv_expect = {
+		0.0, 1.0, 0.0, 0.0, 
+	       -1.0, 0.0, 0.0, 0.0, 
+	        0.0, 0.0, 1.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	
+	check_inv_transform(op, inv_expect); 
+	
+}
+
+
+
+// this is the left handed rotation 
+BOOST_FIXTURE_TEST_CASE(test_rot_xyz, OrientationTestFixture) 
+{
+	C3DOrientationAndPosition op(ior_default, C3DFVector::_0, C3DFVector::_1, 
+				     Quaternion(C3DDVector(M_PI / 6.0, M_PI / 3.0, 3 * M_PI/4.0)));
+
+	double cos_psi = -sqrt(2.0) / 2.0; 
+	double sin_psi = sqrt(2.0) / 2.0; 
+
+	double cos_theta = 0.5; 
+	double sin_theta = sqrt(3)/2.0; 
+
+	double cos_phi = sqrt(3)/2.0; 
+	double sin_phi = 0.5; 
+
+	double a11 = cos_theta * cos_psi; 
+	double a12 = - cos_phi * sin_psi + sin_phi * sin_theta * cos_psi; 
+	double a13 = sin_phi * sin_psi + cos_phi * sin_theta * cos_psi; 
+	
+	double a21 = cos_theta * sin_psi; 
+	double a22 = cos_phi * cos_psi + sin_phi * sin_theta * sin_psi; 
+	double a23 = - sin_phi * cos_psi + cos_phi * sin_theta * sin_psi; 
+	
+	double a31 = - sin_theta; 
+	double a32 = sin_phi * cos_theta;
+	double a33 = cos_phi * cos_theta;
+
+
+	vector<double> expect = {
+		a11, a12, a13, 0.0, 
+		a21, a22, a23, 0.0, 
+		a31, a32, a33, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+
+	check_transform(op, expect); 
+
+	vector<double> inv_expect = {
+		1.0, 0.0, 0.0, 0.0, 
+		0.0, 0.0, 1.0, 0.0, 
+		0.0,-1.0, 0.0, 0.0, 
+		0.0, 0.0, 0.0, 1.0, 
+	};
+	
+//	check_inv_transform(op, inv_expect); 
+}
+
+
+void OrientationTestFixture::check_transform(const C3DOrientationAndPosition& op, const vector<double>& expect)
+{
+	CDoubleVector params(16); 
+	op.get_transform_parameters(params); 
+	check(params, expect); 
+}
+
+void OrientationTestFixture::check_inv_transform(const C3DOrientationAndPosition& op, const vector<double>& expect)
+{
+	CDoubleVector params(16); 
+	op.get_inverse_transform_parameters(params); 
+	check(params, expect); 
+}
+
+void OrientationTestFixture::check(const CDoubleVector& params, const vector<double>& expect)
+{
+	for (int i = 0; i < 16; ++i) {
+		cvdebug() << "[" << i << "]=" <<  params[i] << ", expect " << expect[i] << "\n"; 
+		if (expect[i] == 0.0) {
+			BOOST_CHECK_SMALL(params[i], 1e-5); 
+		}else{
+			BOOST_CHECK_CLOSE(params[i], expect[i], 1e-5);
+		}
+	}
+}
diff --git a/mia/3d/test_ppmatrix.cc b/mia/3d/test_ppmatrix.cc
index e000427..6883394 100644
--- a/mia/3d/test_ppmatrix.cc
+++ b/mia/3d/test_ppmatrix.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,8 +23,6 @@
 
 NS_MIA_USE;
 
-CSplineKernelTestPath splinekernel_init_path; 
-
 struct TransformSplineFixtureFieldBase {
 	TransformSplineFixtureFieldBase():
 		range(1.0), 
@@ -260,7 +258,65 @@ BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_10_4, TransformSplineFixtureMixed )
 	cvinfo() << "gradcurl / testcurl = " << gradcurl / testcurl << "\n"; 
 }
 
-#if 1
+
+BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_20_4, TransformSplineFixtureMixed )
+{
+	init(20, 4, ip_bspline4);
+
+	const T3DConvoluteInterpolator<C3DFVector>& interp = 
+		dynamic_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
+	
+	auto coeffs = interp.get_coefficients(); 
+	const double testdiv = 7.0 * pow(M_PI, 1.5) / sqrt(2.0); 
+	const double testcurl = testdiv / 4.0; 
+
+	C3DPPDivcurlMatrix div(field.get_size(), field_range, *ipf->get_kernel(), 1.0, 0.0);
+	double graddiv = div  * coeffs; 
+	BOOST_CHECK_CLOSE( graddiv, testdiv, 0.1); 	
+
+
+	C3DPPDivcurlMatrix divcurl(field.get_size(), field_range, *ipf->get_kernel(), 1.0, 1.0);
+	double graddivcurl = divcurl  * coeffs; 
+	BOOST_CHECK_CLOSE( graddivcurl, testdiv + testcurl, 0.1); 	
+	
+
+	C3DPPDivcurlMatrix rot(field.get_size(), field_range, *ipf->get_kernel(), 0.0, 1.0);
+	double gradcurl = rot  * coeffs; 
+	BOOST_CHECK_CLOSE( gradcurl, testcurl, 0.1); 	
+
+	cvinfo() << "graddiv  / testdiv= " << graddiv  / testdiv << "\n"; 
+	cvinfo() << "gradcurl / testcurl = " << gradcurl / testcurl << "\n"; 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_20_7, TransformSplineFixtureMixed )
+{
+	init(20, 7, ip_bspline4);
+
+	const T3DConvoluteInterpolator<C3DFVector>& interp = 
+		dynamic_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
+	
+	auto coeffs = interp.get_coefficients(); 
+	const double testdiv = 7.0 * pow(M_PI, 1.5) / sqrt(2.0); 
+	const double testcurl = testdiv / 4.0; 
+
+	C3DPPDivcurlMatrix div(field.get_size(), field_range, *ipf->get_kernel(), 1.0, 0.0);
+	double graddiv = div  * coeffs; 
+	BOOST_CHECK_CLOSE( graddiv, testdiv, 0.1); 	
+
+
+	C3DPPDivcurlMatrix divcurl(field.get_size(), field_range, *ipf->get_kernel(), 1.0, 1.0);
+	double graddivcurl = divcurl  * coeffs; 
+	BOOST_CHECK_CLOSE( graddivcurl, testdiv + testcurl, 0.1); 	
+	
+
+	C3DPPDivcurlMatrix rot(field.get_size(), field_range, *ipf->get_kernel(), 0.0, 1.0);
+	double gradcurl = rot  * coeffs; 
+	BOOST_CHECK_CLOSE( gradcurl, testcurl, 0.1); 	
+
+	cvinfo() << "graddiv  / testdiv= " << graddiv  / testdiv << "\n"; 
+	cvinfo() << "gradcurl / testcurl = " << gradcurl / testcurl << "\n"; 
+}
+
 BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_10_4_grad, TransformSplineFixtureMixed )
 {
 	init(4, 2, ip_bspline3);
@@ -322,9 +378,6 @@ BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_10_4_grad, TransformSplineFixtureMixe
 	
 }
 
-#endif
-
-
 
 
 struct TransformSplineFixtureFieldNonuniform {
diff --git a/mia/3d/test_quaternion.cc b/mia/3d/test_quaternion.cc
index 8768330..8272328 100644
--- a/mia/3d/test_quaternion.cc
+++ b/mia/3d/test_quaternion.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -83,6 +83,7 @@ BOOST_FIXTURE_TEST_CASE( test_quaternion_prod, QuaternionFixture)
 	BOOST_CHECK_EQUAL(q1, prod); 
 }
 
+
 static void CHECK_Quaternion_CLOSE(const Quaternion& a, const Quaternion& b, double tol)
 {
 	BOOST_CHECK_CLOSE(a.w(), b.w(), tol); 
@@ -114,6 +115,106 @@ BOOST_FIXTURE_TEST_CASE( test_from_euler, QuaternionFixture)
 	
 }
 
+struct QuaternionMatrixEqualFixture {
+	void check(const C3DDVector& euler, const C3DFMatrix& m); 
+}; 
+
+BOOST_FIXTURE_TEST_CASE(test_get_3x3matrix_rotz, QuaternionMatrixEqualFixture )
+{
+	C3DDVector rotz(0.0, 0.0, M_PI/3.0); 
+	check(rotz, C3DFMatrix(C3DFVector(0.5, -sqrt(3.0)/2.0, 0), 
+			       C3DFVector(sqrt(3.0)/2.0, 0.5, 0), 
+			       C3DFVector(0.0, 0.0, 1.0)
+		      )
+		);
+}
+
+BOOST_FIXTURE_TEST_CASE(test_get_3x3matrix_roty, QuaternionMatrixEqualFixture )
+{
+
+	C3DDVector roty(0.0, M_PI/3.0, 0.0); 
+	check(roty, C3DFMatrix(C3DFVector( 0.5,            0,  sqrt(3.0)/2.0), 
+			       C3DFVector( 0.0,          1.0,            0.0), 
+			       C3DFVector(-sqrt(3.0)/2.0,  0,            0.5)));
+
+}
+BOOST_FIXTURE_TEST_CASE(test_get_3x3matrix_rotx, QuaternionMatrixEqualFixture )
+{
+
+	C3DDVector rotx(M_PI/3.0, 0.0, 0.0); 
+	check(rotx, C3DFMatrix(C3DFVector(1.0, 0.0,  0.0), 
+			       C3DFVector(0, 0.5,  -sqrt(3.0)/2.0), 
+			       C3DFVector(0, sqrt(3.0)/2.0, 0.5)));
+}
+
+BOOST_AUTO_TEST_CASE(test_from_3x3matrix_z )
+{
+	C3DDVector rotz(0.0, 0.0, M_PI/3.0); 
+	
+	C3DFMatrix m(C3DFVector(0.5, -sqrt(3.0)/2.0, 0), 
+		     C3DFVector(sqrt(3.0)/2.0, 0.5, 0), 
+		     C3DFVector(0.0, 0.0, 1.0)
+		); 
+	
+	
+	Quaternion a(m); 
+	Quaternion b(rotz);
+
+	cvdebug() << a << ", " << b << "\n"; 
+
+	BOOST_CHECK_CLOSE(a.w(), b.w(), 0.1); 
+	BOOST_CHECK_CLOSE(a.x(), b.x(), 0.1); 
+	BOOST_CHECK_CLOSE(a.y(), b.y(), 0.1); 
+	BOOST_CHECK_CLOSE(a.z(), b.z(), 0.1); 
+
+
+	cvdebug() << "From Matrix:" << a.get_rotation_matrix() << "\n"; 
+
+	cvdebug() << "From Quaternion:" << b.get_rotation_matrix() << "\n"; 
+	
+
+
+}
+
+BOOST_AUTO_TEST_CASE(test_from_3x3matrix_y )
+{
+	
+	C3DDVector roty(0.0, M_PI/3.0, 0.0); 
+	C3DFMatrix m(C3DFVector( 0.5,            0,  sqrt(3.0)/2.0), 
+		     C3DFVector( 0.0,          1.0,            0.0), 
+		     C3DFVector(-sqrt(3.0)/2.0,  0,            0.5));
+
+	
+	Quaternion a(m); 
+	Quaternion b(roty);
+
+	BOOST_CHECK_CLOSE(a.w(), b.w(), 0.1); 
+	BOOST_CHECK_CLOSE(a.x(), b.x(), 0.1); 
+	BOOST_CHECK_CLOSE(a.y(), b.y(), 0.1); 
+	BOOST_CHECK_CLOSE(a.z(), b.z(), 0.1); 
+
+}
+
+BOOST_AUTO_TEST_CASE(test_from_3x3matrix_x )
+{
+	
+	C3DDVector rotx(M_PI/3.0, 0.0, 0.0); 
+	C3DFMatrix m(C3DFVector(1.0, 0.0,  0.0), 
+		     C3DFVector(0, 0.5,  -sqrt(3.0)/2.0), 
+		     C3DFVector(0, sqrt(3.0)/2.0, 0.5));
+
+	
+	Quaternion a(m); 
+	Quaternion b(rotx);
+
+	BOOST_CHECK_CLOSE(a.w(), b.w(), 0.1); 
+	BOOST_CHECK_CLOSE(a.x(), b.x(), 0.1); 
+	BOOST_CHECK_CLOSE(a.y(), b.y(), 0.1); 
+	BOOST_CHECK_CLOSE(a.z(), b.z(), 0.1); 
+
+}
+
+
 #if 0
 BOOST_FIXTURE_TEST_CASE( test_euler, QuaternionFixture) 
 {
@@ -135,6 +236,132 @@ BOOST_FIXTURE_TEST_CASE( test_euler, QuaternionFixture)
 #endif
 
 
+BOOST_FIXTURE_TEST_CASE( test_from_rot_matrix_x, QuaternionFixture) 
+{
+	float rx = M_PI/3.0; 
+	float sx, cx; 
+	sincosf(rx, &sx, &cx); 
+	
+	const C3DFMatrix rotx(C3DFVector(  1,  0,   0), 
+			      C3DFVector(  0, cx, -sx), 
+			      C3DFVector(  0, sx, cx)); 
+	
+	Quaternion qx(rotx);
+	CHECK_Quaternion_CLOSE(qx, Quaternion(sqrt(3.0)/2.0, 0.5, 0, 0),0.1);
+}
+
+BOOST_FIXTURE_TEST_CASE( test_from_rot_matrix_y, QuaternionFixture) 
+{
+	float r = M_PI/3.0; 
+	float s, c; 
+	sincosf(r, &s, &c);
+	
+	const C3DFMatrix rot(C3DFVector( c, 0, -s), 
+			     C3DFVector( 0, 1,  0), 
+			     C3DFVector( s, 0, c)); 
+	
+	Quaternion q(rot);
+	CHECK_Quaternion_CLOSE(q, Quaternion(sqrt(3.0)/2.0, 0, -0.5, 0),0.1);
+}
+
+BOOST_FIXTURE_TEST_CASE( test_from_rot_matrix_z, QuaternionFixture) 
+{
+	float r = M_PI/3.0; 
+	float s, c; 
+	sincosf(r, &s, &c);
+	
+	const C3DFMatrix rot(C3DFVector( c,-s, 0), 
+			     C3DFVector( s, c, 0), 
+			     C3DFVector( 0, 0, 1)); 
+	
+	Quaternion q(rot);
+	CHECK_Quaternion_CLOSE(q, Quaternion(sqrt(3.0)/2.0, 0, 0, 0.5),0.1);
+}
+
+BOOST_FIXTURE_TEST_CASE( test_get_rot_matrix_z, QuaternionFixture) 
+{
+	Quaternion q(sqrt(3.0)/2.0, 0, 0, 0.5); 
+	C3DFMatrix rot = q.get_rotation_matrix(); 
+	
+
+	float r = M_PI/3.0; 
+	float s, c; 
+	sincosf(r, &s, &c);
+	
+	BOOST_CHECK_CLOSE(rot.x.x, c, 0.1); 
+	BOOST_CHECK_CLOSE(rot.x.y, -s, 0.1); 
+	BOOST_CHECK_CLOSE(rot.y.x,  s, 0.1); 
+	BOOST_CHECK_CLOSE(rot.y.y, c, 0.1); 
+	BOOST_CHECK_CLOSE(rot.z.z, 1.0, 0.1); 
+
+	BOOST_CHECK_SMALL(rot.x.z,0.0001f); 
+	BOOST_CHECK_SMALL(rot.y.z,0.0001f); 
+	BOOST_CHECK_SMALL(rot.z.x,0.0001f); 
+	BOOST_CHECK_SMALL(rot.z.y,0.0001f); 
+
+}
+
+BOOST_FIXTURE_TEST_CASE( test_get_rot_matrix_y, QuaternionFixture) 
+{
+	Quaternion q(sqrt(3.0)/2.0, 0, -0.5, 0); 
+	C3DFMatrix rot = q.get_rotation_matrix(); 
+	
+
+	float r = M_PI/3.0; 
+	float s, c; 
+	sincosf(r, &s, &c);
+	
+	BOOST_CHECK_CLOSE(rot.x.x, c, 0.1); 
+	BOOST_CHECK_CLOSE(rot.x.z, -s, 0.1); 
+	BOOST_CHECK_CLOSE(rot.z.x,  s, 0.1); 
+	BOOST_CHECK_CLOSE(rot.z.z, c, 0.1); 
+	BOOST_CHECK_CLOSE(rot.y.y, 1.0, 0.1); 
+
+	BOOST_CHECK_SMALL(rot.x.y,0.0001f); 
+	BOOST_CHECK_SMALL(rot.y.z,0.0001f); 
+	BOOST_CHECK_SMALL(rot.y.x,0.0001f); 
+	BOOST_CHECK_SMALL(rot.z.y,0.0001f); 
+
+}
+
+BOOST_FIXTURE_TEST_CASE( test_get_rot_matrix_x, QuaternionFixture) 
+{
+	Quaternion q(sqrt(3.0)/2.0, 0.5, 0, 0); 
+	C3DFMatrix rot = q.get_rotation_matrix(); 
+	
+
+	float r = M_PI/3.0; 
+	float s, c; 
+	sincosf(r, &s, &c);
+	
+	BOOST_CHECK_CLOSE(rot.x.x, 1, 0.1); 
+	BOOST_CHECK_CLOSE(rot.y.z,-s, 0.1); 
+	BOOST_CHECK_CLOSE(rot.z.y, s, 0.1); 
+	BOOST_CHECK_CLOSE(rot.z.z, c, 0.1); 
+	BOOST_CHECK_CLOSE(rot.y.y, c, 0.1); 
+
+	BOOST_CHECK_SMALL(rot.x.y,0.0001f); 
+	BOOST_CHECK_SMALL(rot.x.z,0.0001f); 
+	BOOST_CHECK_SMALL(rot.y.x,0.0001f); 
+	BOOST_CHECK_SMALL(rot.z.x,0.0001f); 
+
+}
+
+BOOST_FIXTURE_TEST_CASE( test_get_rot_matrix, QuaternionFixture) 
+{
+	Quaternion q(sqrt(3.0)/2.0, 0.5, 1.9, 40.0); 
+	q.normalize(); 
+	C3DFMatrix rot = q.get_rotation_matrix(); 
+
+	Quaternion q2(rot); 
+
+	BOOST_CHECK_CLOSE(q2.x(), q.x(), 0.1); 
+	BOOST_CHECK_CLOSE(q2.y(), q.y(), 0.1); 
+	BOOST_CHECK_CLOSE(q2.z(), q.z(), 0.1); 
+	BOOST_CHECK_CLOSE(q2.w(), q.w(), 0.1); 
+
+}
+
 QuaternionFixture::QuaternionFixture():
 	q1(1, 2, 3, 4), 
 	q2(2, 4, 2, 1)
@@ -142,4 +369,24 @@ QuaternionFixture::QuaternionFixture():
 }
 
 
+void QuaternionMatrixEqualFixture::check(const C3DDVector& euler, const C3DFMatrix& t)
+{
+
+	Quaternion q(euler); 
+	C3DFMatrix m = q.get_rotation_matrix(); 	
+
+	BOOST_CHECK_CLOSE(m.x.x, t.x.x, 0.1); 
+	BOOST_CHECK_CLOSE(m.x.y, t.x.y, 0.1); 
+	BOOST_CHECK_CLOSE(m.x.z, t.x.z, 0.1); 
+
+	BOOST_CHECK_CLOSE(m.y.x, t.y.x, 0.1); 
+	BOOST_CHECK_CLOSE(m.y.y, t.y.y, 0.1); 
+	BOOST_CHECK_CLOSE(m.y.z, t.y.z, 0.1); 
+
+	BOOST_CHECK_CLOSE(m.z.x, t.z.x, 0.1); 
+	BOOST_CHECK_CLOSE(m.z.y, t.z.y, 0.1); 
+	BOOST_CHECK_CLOSE(m.z.z, t.z.z, 0.1); 
+
+}
+
 
diff --git a/mia/3d/test_regplugins.cc b/mia/3d/test_regplugins.cc
index 83ab8d4..3de2d65 100644
--- a/mia/3d/test_regplugins.cc
+++ b/mia/3d/test_regplugins.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_rigidregister.cc b/mia/3d/test_rigidregister.cc
index 7ea6547..040021f 100644
--- a/mia/3d/test_rigidregister.cc
+++ b/mia/3d/test_rigidregister.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,8 +36,6 @@ NS_MIA_USE
 using namespace std; 
 namespace bfs=boost::filesystem;
 
-PrepareTestPluginPath g_prepare_pluginpath; 
-
 class RigidRegisterFixture {
 protected: 
 	RigidRegisterFixture(); 
diff --git a/mia/3d/test_rot.cc b/mia/3d/test_rot.cc
new file mode 100644
index 0000000..89e658e
--- /dev/null
+++ b/mia/3d/test_rot.cc
@@ -0,0 +1,167 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <mia/3d/rot.hh>
+
+NS_MIA_USE
+
+using std::unique_ptr; 
+
+struct RotIdentityTestFixture {
+
+	void check_matrix(const C3DDMatrix& matrix) const; 
+	void check_quaternion(const Quaternion& q) const; 
+
+	void check_matrix(const C3DDMatrix& matrix, const C3DDMatrix& expect) const; 
+	void check_quaternion(const Quaternion& q, const Quaternion& expect) const; 
+
+	void check_small_or_close(double x, double e) const; 
+}; 
+
+
+BOOST_FIXTURE_TEST_CASE( test_identity_from_matrix_string, RotIdentityTestFixture) 
+{
+	C3DRotation  identity("rot-matrix=1,0,0;0,1,0;0,0,1");
+
+	check_matrix(identity.as_matrix_3x3()); 
+	
+	check_quaternion(identity.as_quaternion()); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_copying_around, RotIdentityTestFixture ) 
+{
+	Quaternion q1(0.5,0.5,0.5,0.5); 
+	Quaternion q2(-0.5,0.5,-0.5,0.5); 
+	
+	C3DRotation  r1(q1);
+	C3DRotation  r2(q2);
+
+	C3DRotation r1c(r1); 
+
+	check_quaternion(r1c.as_quaternion(), q1); 
+	
+	r1c = r2;
+	
+	check_quaternion(r1c.as_quaternion(), q2); 
+	
+	r1 = r1c; 
+	check_quaternion(r1.as_quaternion(), q2);
+
+	r2 = r1c; 
+
+}
+
+BOOST_FIXTURE_TEST_CASE( test_identity_from_quaternion_string, RotIdentityTestFixture) 
+{
+	C3DRotation  identity("rot-quaternion=1,0,0,0");
+
+	check_matrix(identity.as_matrix_3x3()); 
+	
+	check_quaternion(identity.as_quaternion()); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_base_from_string, RotIdentityTestFixture) 
+{
+	C3DRotation  identity("rot-identity");
+	check_matrix(identity.as_matrix_3x3()); 
+	check_quaternion(identity.as_quaternion()); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_matrix_to_from_string, RotIdentityTestFixture) 
+{
+	Quaternion q(0.5,0.5,0.5,0.5); 
+	C3DRotation mr(q.get_rotation_matrix()); 
+	
+	C3DRotation  rmr(mr.as_string());
+
+	check_matrix(rmr.as_matrix_3x3(), mr.as_matrix_3x3()); 
+	
+	check_quaternion(rmr.as_quaternion(), q); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_quaternion_to_from_string, RotIdentityTestFixture) 
+{
+	Quaternion q(0.5,0.5,0.5,0.5); 
+	C3DRotation qr(q); 
+	
+	C3DRotation  rqr(qr.as_string());
+
+	check_matrix(rqr.as_matrix_3x3(), qr.as_matrix_3x3()); 
+	
+	check_quaternion(rqr.as_quaternion(), q); 
+}
+
+
+void RotIdentityTestFixture::check_matrix(const C3DDMatrix& matrix) const
+{
+	BOOST_CHECK_EQUAL(matrix.x.x, 1.0); 
+	BOOST_CHECK_EQUAL(matrix.y.y, 1.0); 
+	BOOST_CHECK_EQUAL(matrix.z.z, 1.0); 
+
+	BOOST_CHECK_SMALL(matrix.x.y, 1e-8); 
+	BOOST_CHECK_SMALL(matrix.x.z, 1e-8); 
+	BOOST_CHECK_SMALL(matrix.y.x, 1e-8); 
+	BOOST_CHECK_SMALL(matrix.y.z, 1e-8); 
+	BOOST_CHECK_SMALL(matrix.z.x, 1e-8); 
+	BOOST_CHECK_SMALL(matrix.z.y, 1e-8); 
+}
+
+void RotIdentityTestFixture::check_quaternion(const Quaternion& q) const
+{
+	BOOST_CHECK_CLOSE(q.w(), 1.0, 1e-8); 
+	BOOST_CHECK_SMALL(q.x(), 1e-5); 
+	BOOST_CHECK_SMALL(q.y(), 1e-5); 
+	BOOST_CHECK_SMALL(q.z(), 1e-5); 
+	
+}
+
+void RotIdentityTestFixture::check_small_or_close(double x, double e) const
+{
+	if (e == 0.0) 
+		BOOST_CHECK_SMALL(x, 1e-7); 
+	else 
+		BOOST_CHECK_CLOSE(x, e, 1e-5); 
+}
+
+void RotIdentityTestFixture::check_matrix(const C3DDMatrix& matrix, const C3DDMatrix& expect) const
+{
+	check_small_or_close(matrix.x.x, expect.x.x); 
+	check_small_or_close(matrix.x.y, expect.x.y); 
+	check_small_or_close(matrix.x.z, expect.x.z); 
+
+	check_small_or_close(matrix.z.z, expect.z.z); 
+	check_small_or_close(matrix.y.y, expect.y.y); 
+	check_small_or_close(matrix.y.z, expect.y.z); 
+
+
+	check_small_or_close(matrix.z.x, expect.z.x); 
+	check_small_or_close(matrix.z.y, expect.z.y); 
+	check_small_or_close(matrix.z.z, expect.z.z); 
+}
+
+void RotIdentityTestFixture::check_quaternion(const Quaternion& q, const Quaternion& expect) const
+{
+	check_small_or_close(q.x(), expect.x()); 
+	check_small_or_close(q.y(), expect.y()); 
+	check_small_or_close(q.z(), expect.z()); 
+	check_small_or_close(q.w(), expect.w());
+}
+
diff --git a/mia/3d/test_shape.cc b/mia/3d/test_shape.cc
index 4ed9f4a..7e83651 100644
--- a/mia/3d/test_shape.cc
+++ b/mia/3d/test_shape.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_similarity_profile.cc b/mia/3d/test_similarity_profile.cc
index 9f6543a..bacd618 100644
--- a/mia/3d/test_similarity_profile.cc
+++ b/mia/3d/test_similarity_profile.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,7 +28,6 @@
 namespace bfs=::boost::filesystem;
 NS_MIA_USE; 
 
-CSplineKernelTestPath splinekernel_init_path; 
 struct SimityProfileFixture {
 	SimityProfileFixture(); 
 
@@ -41,7 +40,7 @@ struct SimityProfileFixture {
 BOOST_FIXTURE_TEST_CASE (test_C3DSimilarityProfile_ref10, SimityProfileFixture) 
 {
 	
-	C3DSimilarityProfile sp(cost, series, 10); 
+	C3DSimilarityProfile sp(cost, series, 10, 0); 
 	// test value obtained by using octave 
 	BOOST_CHECK_CLOSE(sp.get_peak_frequency(), 108.98704, 0.1);
 	
@@ -51,22 +50,6 @@ BOOST_FIXTURE_TEST_CASE (test_C3DSimilarityProfile_ref10, SimityProfileFixture)
 
 SimityProfileFixture::SimityProfileFixture()
 {
-	CPathNameArray cost_plugpath;
-	cost_plugpath.push_back(bfs::path("cost"));
-	C3DImageCostPluginHandler::set_search_path(cost_plugpath);
-
-	CPathNameArray filter_plugpath;
-	filter_plugpath.push_back(bfs::path("filter"));
-	C3DFilterPluginHandler::set_search_path(filter_plugpath);
-
-	CPathNameArray io_plugpath;
-	io_plugpath.push_back(bfs::path("io"));
-	C3DImageIOPluginHandler::set_search_path(io_plugpath);
-
-	CPathNameArray fullcost_plugpath;
-	fullcost_plugpath.push_back(bfs::path("fullcost"));
-	C3DFullCostPluginHandler::set_search_path(fullcost_plugpath);
-
 
 	cost = C3DFullCostPluginHandler::instance().produce("image");
 
diff --git a/mia/3d/test_splinetransformpenalty.cc b/mia/3d/test_splinetransformpenalty.cc
index 76cbd35..f22e1bb 100644
--- a/mia/3d/test_splinetransformpenalty.cc
+++ b/mia/3d/test_splinetransformpenalty.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@ NS_MIA_USE;
 class C3DSplinePenaltyMock: public C3DSplineTransformPenalty {
 public: 
 	
-	C3DSplinePenaltyMock(double weight); 
+	C3DSplinePenaltyMock(double weight, bool normalize); 
 	
 private: 
 	void do_initialize(); 
@@ -44,7 +44,7 @@ private:
 
 BOOST_AUTO_TEST_CASE( weight_1_1_1_1p5_2p9_bspline3 )
 {
-	C3DSplinePenaltyMock penalty(1.0); 
+	C3DSplinePenaltyMock penalty(1.0, false); 
 	C3DBounds size(1,1,1); 
 	penalty.initialize(size, C3DFVector(1.5,2.9, 2.0), produce_spline_kernel("bspline:d=2"));
 
@@ -70,10 +70,38 @@ BOOST_AUTO_TEST_CASE( weight_1_1_1_1p5_2p9_bspline3 )
 	
 }
 
+BOOST_AUTO_TEST_CASE( weight_2_2_2_1p5_2p9_bspline3_normalize )
+{
+	C3DSplinePenaltyMock penalty(1.0, true); 
+	C3DBounds size(2,2,2); 
+	penalty.initialize(size, C3DFVector(2.0, 2.0, 2.0), produce_spline_kernel("bspline:d=2"));
+
+	C3DFVectorfield coef(size); 
+	coef(0,0,0) = C3DFVector(1.0/2.0,1.0, 1.0/4.0); 
+	
+	BOOST_CHECK_CLOSE(penalty.value(coef), 1.75/ 8.0, 0.1); 
+
+	CDoubleVector grad(24); 
+	BOOST_CHECK_CLOSE(penalty.value_and_gradient(coef, grad), 1.75 / 8.0, 0.1); 
+
+	BOOST_CHECK_CLOSE(grad[0], 0.5 / 8.0, 0.1); 
+	BOOST_CHECK_CLOSE(grad[1], 1.0 / 8.0, 0.1); 
+	BOOST_CHECK_CLOSE(grad[2], 0.25 / 8.0, 0.1); 
+
+	std::unique_ptr<C3DSplineTransformPenalty> penalty2(penalty.clone()); 
+	
+	BOOST_CHECK_CLOSE(penalty2->value(coef), 1.75 / 8.0, 0.1); 
+	BOOST_CHECK_CLOSE(penalty2->value_and_gradient(coef, grad), 1.75 / 8.0, 0.1); 
+	BOOST_CHECK_CLOSE(grad[0], 0.5 / 8.0, 0.1); 
+	BOOST_CHECK_CLOSE(grad[1], 1.0 / 8.0, 0.1); 
+	BOOST_CHECK_CLOSE(grad[2], 0.25 / 8.0, 0.1); 
+	
+}
+
 
 BOOST_AUTO_TEST_CASE( weight_0p5_1_1_1p5_2p9_bspline3 )
 {
-	C3DSplinePenaltyMock penalty(0.5); 
+	C3DSplinePenaltyMock penalty(0.5, false); 
 	C3DBounds size(1,1,1); 
 	penalty.initialize(size, C3DFVector(1.5,2.9, 2.0), produce_spline_kernel("bspline:d=2"));
 
@@ -100,7 +128,7 @@ BOOST_AUTO_TEST_CASE( weight_0p5_1_1_1p5_2p9_bspline3 )
 
 BOOST_AUTO_TEST_CASE( weight_0p5_2_3_2_3_bspline3 )
 {
-	C3DSplinePenaltyMock penalty(0.5); 
+	C3DSplinePenaltyMock penalty(0.5, false); 
 	C3DBounds size(2,3,1); 
 	penalty.initialize(size, C3DFVector(2,3,1), produce_spline_kernel("bspline:d=2"));
 
@@ -173,8 +201,8 @@ BOOST_AUTO_TEST_CASE( weight_0p5_2_3_2_3_bspline3 )
 
 }
 
-C3DSplinePenaltyMock::C3DSplinePenaltyMock(double weight):
-C3DSplineTransformPenalty(weight)
+C3DSplinePenaltyMock::C3DSplinePenaltyMock(double weight, bool normalize):
+C3DSplineTransformPenalty(weight, normalize)
 {
 }
 
@@ -225,17 +253,12 @@ double C3DSplinePenaltyMock::do_value_and_gradient(const C3DFVectorfield&  coeff
 
 C3DSplineTransformPenalty *C3DSplinePenaltyMock::do_clone() const
 {
-	C3DSplineTransformPenalty *result =  new C3DSplinePenaltyMock(get_weight());
+	C3DSplineTransformPenalty *result =  new C3DSplinePenaltyMock(get_weight(), get_normalize());
 	result->initialize(get_size(), get_range(), get_kernel()); 
 	return result; 
 }
   
 
-CSplineKernelTestPath kernel_test_path; 
-
-
-C3DSplineTransformPenaltyPluginHandlerTest penalty_plug_path; 
-
 BOOST_AUTO_TEST_CASE(test_available_plugins)
 {
 	std::set<std::string> test_data = {"divcurl"}; 
diff --git a/mia/3d/test_stackdisttrans.cc b/mia/3d/test_stackdisttrans.cc
index f061d03..36ef5d3 100644
--- a/mia/3d/test_stackdisttrans.cc
+++ b/mia/3d/test_stackdisttrans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_trackpoint.cc b/mia/3d/test_trackpoint.cc
index 128e3f1..b7c8c50 100644
--- a/mia/3d/test_trackpoint.cc
+++ b/mia/3d/test_trackpoint.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,9 +26,6 @@
 using namespace std; 
 using namespace mia; 
 
-C3DTransformCreatorHandlerTestPath test_creator_path; 
-
-
 const char test_input[] = 
 	"1;12;10;5;12;some text\n"
 	"2;13;7;5;2;other text\n"
diff --git a/mia/3d/test_transform.cc b/mia/3d/test_transform.cc
index cffebdf..386f62f 100644
--- a/mia/3d/test_transform.cc
+++ b/mia/3d/test_transform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,9 +29,6 @@
 NS_MIA_USE; 
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath spline_test_path; 
-
-
 class Cost3DMock {
 public: 
 	Cost3DMock(const C3DBounds& size); 
@@ -121,7 +118,7 @@ BOOST_FIXTURE_TEST_CASE (test_rigid_Gradient_center_shifted, TransformGradientFi
 {
 	const C3DTransformCreatorHandler::Instance& handler =
 		C3DTransformCreatorHandler::instance();
-	P3DTransformationFactory creater = handler.produce("rigid:rot-center=[<0.5,0.4,0.6>]");
+	P3DTransformationFactory creater = handler.produce("rigid:origin=[<0.5,0.4,0.6>]");
 	P3DTransformation transform = creater->create(size);
 	run_test(*transform); 
 }
@@ -142,54 +139,11 @@ BOOST_FIXTURE_TEST_CASE (test_rotation_Gradient_center_shifted, TransformGradien
 {
 	const C3DTransformCreatorHandler::Instance& handler =
 		C3DTransformCreatorHandler::instance();
-	P3DTransformationFactory creater = handler.produce("rotation:rot-center=[<0.5,0.4,0.6>]");
+	P3DTransformationFactory creater = handler.produce("rotation:origin=[<0.5,0.4,0.6>]");
 	P3DTransformation transform = creater->create(size);
 	run_test(*transform); 
 }
 
-
-
-#if 0 
-BOOST_FIXTURE_TEST_CASE (test_vf_Gradient, TransformGradientFixture) 
-{
-	const C3DTransformCreatorHandler::Instance& handler =
-		C3DTransformCreatorHandler::instance();
-	P3DTransformationFactory creater = handler.produce("vf");
-	P3DTransformation transform = creater->create(size);
-
-	run_test(*transform, 2.0); 
-}
-
-#endif
-
-#if 0
-// this is actually tested in the spline.cc
-BOOST_FIXTURE_TEST_CASE (test_spline_Gradient, TransformGradientFixture) 
-{
-	const C3DTransformCreatorHandler::Instance& handler =
-		C3DTransformCreatorHandler::instance();
-	P3DTransformationFactory creater = handler.produce("spline:rate=2");
-	P3DTransformation transform = creater->create(size);
-	transform->set_debug(); 
-
-	run_test(*transform, 10.0); 
-}
-#endif
-
-
-struct TransformPluginPathFixture {
-	TransformPluginPathFixture(); 
-}; 
-
-TransformPluginPathFixture::TransformPluginPathFixture()
-{
-	CPathNameArray kernelsearchpath;
-	kernelsearchpath.push_back(bfs::path("transform"));
-	C3DTransformCreatorHandler::set_search_path(kernelsearchpath);
-}
-
-TransformPluginPathFixture transform_plugin_test_path_init; 
-
 TransformGradientFixture::TransformGradientFixture():
 	size(20, 28, 16), 
 	cost(size),
@@ -299,7 +253,3 @@ double Cost3DMock::ref_value(const C3DFVector& x)const
 }
 
 
-BOOST_AUTO_TEST_CASE (test_iterator_range) 
-{
-	
-}
diff --git a/mia/3d/test_transformfactory.cc b/mia/3d/test_transformfactory.cc
index 4a514f2..9e57d23 100644
--- a/mia/3d/test_transformfactory.cc
+++ b/mia/3d/test_transformfactory.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,8 +31,6 @@ using namespace ::boost;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath splinekernel_init_path; 
-
 struct HandlerTestFixture {
 	HandlerTestFixture();
 
@@ -50,9 +48,9 @@ BOOST_FIXTURE_TEST_CASE(test_handler, HandlerTestFixture)
 {
 	const C3DTransformCreatorHandler::Instance& handler =
 		C3DTransformCreatorHandler::instance();
-	BOOST_CHECK_EQUAL(handler.size(), 6u);
+	BOOST_CHECK_EQUAL(handler.size(), 9u);
 	BOOST_CHECK_EQUAL(handler.get_plugin_names(),
-			  "affine rigid rotation spline translate vf ");
+			  "affine axisrot raffine rigid rotation rotbend spline translate vf ");
 }
 
 BOOST_FIXTURE_TEST_CASE(test_translate_creator, HandlerTestFixture)
diff --git a/mia/3d/test_transio.cc b/mia/3d/test_transio.cc
index f2e7726..42664bd 100644
--- a/mia/3d/test_transio.cc
+++ b/mia/3d/test_transio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,9 +27,6 @@
 NS_MIA_USE; 
 using namespace std; 
 
-CSplineKernelTestPath splinekernel_init_path; 
-C3DTransformCreatorHandlerTestPath transform_creator_test_path; 
-
 
 namespace bfs=::boost::filesystem; 
 class PrepareTransIOTests {
@@ -74,6 +71,7 @@ BOOST_AUTO_TEST_CASE(test_transform_io)
 		for (size_t k = 0; k < params.size(); ++k) 
 			params[k] = k + 1; 
 		tr->set_parameters(params);
+		tr->set_attribute("string_attr", "string"); 
 		
 		for (size_t i = 0; i < n_io; ++i) {
 			stringstream fname; 
@@ -90,6 +88,10 @@ BOOST_AUTO_TEST_CASE(test_transform_io)
 			BOOST_CHECK_EQUAL(lparams.size(), params.size()); 
 			for (size_t k = 0; k < lparams.size(); ++k) 
 				BOOST_CHECK_EQUAL(lparams[k], k + 1); 
+			
+			BOOST_REQUIRE(t_loaded->has_attribute("string_attr")); 
+			BOOST_CHECK_EQUAL(t_loaded->get_attribute_as<string>("string_attr"), "string"); 
+
 			unlink( fname.str().c_str()); 
 
 		}
diff --git a/mia/3d/test_vector.cc b/mia/3d/test_vector.cc
index 6651711..c2dc577 100644
--- a/mia/3d/test_vector.cc
+++ b/mia/3d/test_vector.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,7 +21,6 @@
 #include <sstream>
 #include <climits>
 
-#include <boost/test/unit_test_suite.hpp>
 #include <boost/test/unit_test.hpp>
 
 
@@ -31,7 +30,7 @@
 using namespace std;
 NS_MIA_USE
 
-static void test_3dvectors()
+BOOST_AUTO_TEST_CASE( test_3dvectors )
 {
 
 	C3DFVector a(1.0f, 2.0f, 3.0f);
@@ -100,7 +99,7 @@ static void test_3dvectors()
 
 }
 
-static void test_float_vector_option()
+BOOST_AUTO_TEST_CASE( test_float_vector_option)
 {
 	C3DFVector v(1,2,3);
 
@@ -124,7 +123,7 @@ static void test_float_vector_option()
 	}
 }
 
-void test_size_vector_option()
+BOOST_AUTO_TEST_CASE( test_size_vector_option)
 {
 	C3DBounds v(1,2,3);
 
@@ -149,7 +148,7 @@ void test_size_vector_option()
 	}
 }
 
-static void test_swizzle()
+BOOST_AUTO_TEST_CASE( test_swizzle )
 {
 	T3DVector<int> test(1,2,3);
 
@@ -163,7 +162,7 @@ static void test_swizzle()
 
 }
 
-static void test_fill()
+BOOST_AUTO_TEST_CASE( test_fill )
 {
 	T3DVector<int> test;
 
@@ -179,12 +178,15 @@ static void test_fill()
 
 }
 
-
-void add_3dvector_tests(boost::unit_test::test_suite* suite)
+BOOST_AUTO_TEST_CASE( test_minus )
 {
-	suite->add( BOOST_TEST_CASE( &test_3dvectors));
-	suite->add( BOOST_TEST_CASE( &test_float_vector_option));
-	suite->add( BOOST_TEST_CASE( &test_size_vector_option));
-	suite->add( BOOST_TEST_CASE( &test_swizzle ));
-	suite->add( BOOST_TEST_CASE( &test_fill ));
+	T3DVector<int> test(1,-2,3);
+	T3DVector<int> mtest = -test; 
+
+	BOOST_CHECK_EQUAL(mtest.x, -1);
+	BOOST_CHECK_EQUAL(mtest.y,  2);
+	BOOST_CHECK_EQUAL(mtest.z, -3);
+
+
 }
+
diff --git a/mia/3d/test_vectorfield.cc b/mia/3d/test_vectorfield.cc
index e800c23..9cdc411 100644
--- a/mia/3d/test_vectorfield.cc
+++ b/mia/3d/test_vectorfield.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/test_vfio.cc b/mia/3d/test_vfio.cc
index 50aa52a..09d0cce 100644
--- a/mia/3d/test_vfio.cc
+++ b/mia/3d/test_vfio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/timestep.cc b/mia/3d/timestep.cc
index fce009b..6e914b5 100644
--- a/mia/3d/timestep.cc
+++ b/mia/3d/timestep.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -94,7 +94,6 @@ C3DRegTimeStepPlugin::C3DRegTimeStepPlugin(const char *name):
 	m_min(0.1),
 	m_max(2.0)
 {
-	typedef CParamList::PParameter PParameter;
 	add_parameter("min", new CFloatParameter(m_min, 0.001, std::numeric_limits<float>::max(),
 							   false, "minimum time step allowed"));
 	add_parameter("max", new CFloatParameter(m_max, 0.002, std::numeric_limits<float>::max(),
diff --git a/mia/3d/timestep.hh b/mia/3d/timestep.hh
index 443dc30..56a8ec4 100644
--- a/mia/3d/timestep.hh
+++ b/mia/3d/timestep.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/trackpoint.cc b/mia/3d/trackpoint.cc
index 0fa17dd..f9ea1ae 100644
--- a/mia/3d/trackpoint.cc
+++ b/mia/3d/trackpoint.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/trackpoint.hh b/mia/3d/trackpoint.hh
index 009711f..47b3948 100644
--- a/mia/3d/trackpoint.hh
+++ b/mia/3d/trackpoint.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/trait.hh b/mia/3d/trait.hh
index 9820220..b0b4b71 100644
--- a/mia/3d/trait.hh
+++ b/mia/3d/trait.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/transform.cc b/mia/3d/transform.cc
index f566d5c..8ac47b2 100644
--- a/mia/3d/transform.cc
+++ b/mia/3d/transform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -234,11 +234,28 @@ const C3DFVector  *C3DTransformation::const_iterator::operator ->() const
 	return &m_holder->get_value(); 
 }
 
+const C3DBounds& C3DTransformation::const_iterator::pos() const
+{
+	assert(m_holder); 
+	return m_holder->get_pos(); 
+}
+
+const C3DBounds& C3DTransformation::const_iterator::get_size()const
+{
+	assert(m_holder); 
+	return m_holder->get_size(); 
+}
+
 bool C3DTransformation::refine()
 {
 	return false; 
 }
 
+C3DBounds C3DTransformation::get_minimal_supported_image_size() const
+{
+	return C3DBounds::_1; 
+}
+
 template <typename T> 
 struct F3DTransformer {
 	F3DTransformer(const C3DTransformation& _trans, 
@@ -264,11 +281,26 @@ struct F3DTransform : public TFilter<P3DImage> {
 		
 		auto *timage = new T3DImage<T>(m_trans.get_size(), image);
 		P3DImage result(timage);
+		
+		if (m_trans.has_attribute(C3DTransformation::input_spacing_attr) && 
+		    m_trans.has_attribute(C3DTransformation::output_spacing_attr)) {
+			C3DFVector in_voxel = m_trans.get_attribute_as<C3DFVector>(C3DTransformation::input_spacing_attr);
+			C3DFVector out_voxel = m_trans.get_attribute_as<C3DFVector>(C3DTransformation::output_spacing_attr);
+			if (image.get_voxel_size() != in_voxel) {
+				cvwarn() << "C3DTransform: your input image voxel spacing [" 
+					 << image.get_voxel_size() << "] differs from voxel spacing, this transformation expects [" 
+					 << in_voxel << "], output voxel spacing not reliable\n"; 
+			}
+			timage->set_voxel_size(out_voxel); 
+		}
 
 		std::unique_ptr<T3DConvoluteInterpolator<T> > interp(m_ipf.create(image.data()));
 
 		F3DTransformer<T> worker(m_trans, *interp, *timage); 
 		tbb::parallel_for(tbb::blocked_range<int>( 0, timage->get_size().z), worker);
+
+		// if the transformation provides a forced output pixel spacing, 
+		// set it here 
 		return result;
 	}
 private:
diff --git a/mia/3d/transform.hh b/mia/3d/transform.hh
index a711c07..9f34a28 100644
--- a/mia/3d/transform.hh
+++ b/mia/3d/transform.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -163,6 +163,14 @@ public:
 		/// return pointer to current value of the transformation 
 		const C3DFVector  *operator ->() const;
 
+		/// return the current position in 3D space 
+ 		const C3DBounds& pos()const; 
+
+
+		/// @returns the size of the supported domain 
+		const C3DBounds& get_size()const; 
+		
+
 	private: 
 		std::unique_ptr<iterator_impl> m_holder;
 
@@ -328,37 +336,32 @@ public:
 	 */
 	virtual float get_jacobian(const C3DFVectorfield& v, float delta) const = 0;
 
-
 	/**
-	   Evaluate the grad div ^2 + grad rot ^2 value and its gradient for the 
-	   transformtion 
-	   @param wd weight of the divergence
-	   @param wr weight of the rotation 
-	   \param[out] gradient vector to hold the resulting gradient 
-	   @returns cost function value 
+	   Increase the number of coefficients along the axis according to the 
+	   maximum given by the c-rate. This is the complemantary step to upscaling the 
+	   transformation. 
+	   \returns true if an actual refinment was done. 
 	 */
-	virtual double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const = 0; 
+	virtual bool refine(); 
 
 	/**
-	   Evaluate the grad div ^2 + grad rot ^2 value for the transformtion 
-	   @param wd weight of the divergence
-	   @param wr weight of the rotation 
-	   @returns cost function value 
+	   Enable some additional debugging.  
 	 */
+	void set_debug(); 
 
-	virtual double get_divcurl_cost(double wd, double wr) const = 0; 
-
+	/* Attributes */
 	/**
-	   If applicaple the transformation model is refined (e.g. splines 
-	   are converted to a denser coefficient distribution. 
-	   @returns \a true if refinement was applied, and \a false otherwise
+	   This attribute defines the voxel spacing of the input data of this transform. 
 	 */
-	virtual bool refine(); 
+	static constexpr const char *input_spacing_attr = "in-voxel-spacing"; 
 
 	/**
-	   Enable some additional debugging.  
+	   This attribute defines the output voxel spacing of this transform. 
 	 */
-	void set_debug(); 
+	static constexpr const char *output_spacing_attr = "out-voxel-spacing"; 
+
+
+	virtual C3DBounds get_minimal_supported_image_size() const; 
 protected: 
 	/// @returns information about the debug state 
 	bool get_debug()const; 
diff --git a/mia/3d/transform/CMakeLists.txt b/mia/3d/transform/CMakeLists.txt
index bbaa7df..9768307 100644
--- a/mia/3d/transform/CMakeLists.txt
+++ b/mia/3d/transform/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -16,7 +16,10 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 
-SET(transforms affine rigid rotation spline translate vectorfield) 
+SET(transforms affine axisrot raffine rigid rotbend rotation translate) 
 PLUGINGROUP_WITH_TEST_AND_PREFIX2("3dimage" "transform" "${transforms}" 
   "${MIA3DLIBS}"
   )
+
+SET(nonlinear_src spline.cc  vectorfield.cc) 
+PLUGIN_WITH_TEST_MULTISOURCE("nonlinear" "3dimage" "transform" "${nonlinear_src}" "${MIA3DLIBS}") 
diff --git a/mia/3d/transform/affine.cc b/mia/3d/transform/affine.cc
index 23b3e3a..d4c162e 100644
--- a/mia/3d/transform/affine.cc
+++ b/mia/3d/transform/affine.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -138,41 +138,6 @@ void C3DAffineTransformation::set_parameters(const CDoubleVector& params)
 
 }
 
-double C3DAffineTransformation::get_divcurl_cost(double, double, CDoubleVector&) const
-{
-	return 0.0; 
-}
-
-double C3DAffineTransformation::get_divcurl_cost(double, double) const
-{
-	return 0.0; 
-}
-
-
-float C3DAffineTransformation::divergence() const
-{
-	assert(0 && "not implemented");
-	return m_t[0] + m_t[1] + m_t[3] + m_t[4] - 2.0f;
-}
-
-float C3DAffineTransformation::grad_divergence() const
-{
-	return 0.0;
-}
-
-
-float C3DAffineTransformation::grad_curl() const
-{
-	return 0.0;
-}
-
-
-float C3DAffineTransformation::curl() const
-{
-	assert(0 && "not implemented");
-	return m_t[1] + m_t[4] - m_t[0] - m_t[3];
-}
-
 const C3DBounds& C3DAffineTransformation::get_size() const
 {
 	return m_size;
diff --git a/mia/3d/transform/affine.hh b/mia/3d/transform/affine.hh
index a3e5478..f9e0b84 100644
--- a/mia/3d/transform/affine.hh
+++ b/mia/3d/transform/affine.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -80,14 +80,6 @@ public:
 	virtual C3DFVector operator () (const C3DFVector& x) const;
 	virtual float get_jacobian(const C3DFVectorfield& v, float delta) const;
 	C3DFVector transform(const C3DFVector& x)const;
-
-	// these should go away 
-	virtual float divergence() const;
-	virtual float curl() const;
-	float grad_divergence() const;
-	float grad_curl() const;
-	double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	double get_divcurl_cost(double wd, double wr) const; 
 private:
 	virtual C3DTransformation *do_clone() const;
 	C3DAffineTransformation(const C3DAffineTransformation& other);
diff --git a/mia/3d/transform/axisrot.cc b/mia/3d/transform/axisrot.cc
new file mode 100644
index 0000000..870c773
--- /dev/null
+++ b/mia/3d/transform/axisrot.cc
@@ -0,0 +1,345 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <fstream>
+#include <cmath>
+#include <mia/core/msgstream.hh>
+#include <mia/3d/transform/axisrot.hh>
+
+namespace mia_3dtransform_axisrot {
+
+using namespace mia; 
+using namespace std;
+
+
+
+C3DFVector C3DAxisrotTransformation::apply(const C3DFVector& x) const
+{
+	return transform(x);
+}
+
+
+
+C3DFVector C3DAxisrotTransformation::transform(const C3DFVector& x)const
+{
+	return m_matrix * x;
+}
+
+C3DAxisrotTransformation::C3DAxisrotTransformation(const C3DBounds& size, const C3DFVector& orig, 
+						   const C3DFVector& rot_axis, 
+						   const C3DInterpolatorFactory& ipf):
+	C3DTransformation(ipf), 
+        m_angle(0.0), 
+        m_relative_origin(orig), 
+	m_rotation_center(C3DFVector(size) * m_relative_origin), 
+	m_rotation_axis(rot_axis), 
+	m_size(size), 
+	m_y_align_rot_needed(false)
+{
+	cvinfo() << "Transform: center=" << m_rotation_center << " of size=" << m_size << "\n"; 
+	double n = m_rotation_axis.norm(); 
+	if (n == 0.0)
+		throw invalid_argument("C3DAxisrotTransformation: rotation axis has zero length"); 
+
+	m_rotation_axis /= n; 
+	
+	// create a pre-post rotation quaternion to get the afs-pfs line into alignment with the 
+	// y axis. 
+
+	// one vector is 0,1,0, the other is m_rotation_axis
+	C3DFVector help_axis(-m_rotation_axis.z, 0, m_rotation_axis.x); 
+	if (help_axis.norm2() > 0.0) {
+		help_axis /= help_axis.norm(); 
+		m_y_align_rot_needed = true; 
+		double angle = acos(m_rotation_axis.y) / 2.0; 
+		double sina, cosa; 
+		sincos(angle, &sina, &cosa); 
+		m_y_align_rot = Quaternion( cosa, sina * help_axis.x, 0, sina * help_axis.z); 
+		cvinfo() << "Align-rotation = " << m_y_align_rot << "\n"; 
+
+		m_y_align_rot_inverse = m_y_align_rot.inverse(); 
+		
+	}
+	m_matrix.identity();
+}
+
+C3DTransformation *C3DAxisrotTransformation::do_clone()const
+{
+	return new C3DAxisrotTransformation(*this);
+}
+
+C3DTransformation *C3DAxisrotTransformation::invert()const
+{
+	C3DAxisrotTransformation *result = new C3DAxisrotTransformation(*this);
+        
+        assert(0 && "not implemented"); 
+
+	return result; 
+}
+
+size_t C3DAxisrotTransformation::degrees_of_freedom() const
+{
+	return 1;
+}
+
+void C3DAxisrotTransformation::update(float /*step*/, const C3DFVectorfield& /*a*/)
+{
+	assert(0 && "not implemented");
+}
+
+CDoubleVector C3DAxisrotTransformation::get_parameters() const
+{
+	CDoubleVector result(degrees_of_freedom());
+	result[0] = m_angle;
+	return result;
+}
+
+void C3DAxisrotTransformation::apply_parameters()
+{
+	m_matrix.identity(); 
+        m_matrix.translate( -1.0f * m_rotation_center); 
+
+	if (m_y_align_rot_needed) {
+		m_matrix.rotate(m_y_align_rot); 
+	}
+
+	m_matrix.rotate_y(m_angle); 
+	
+	if (m_y_align_rot_needed) {
+		m_matrix.rotate(m_y_align_rot_inverse); 
+	}
+
+	
+        m_matrix.translate(m_rotation_center); 
+}
+
+void C3DAxisrotTransformation::set_parameters(const CDoubleVector& params)
+{
+	assert(degrees_of_freedom() == params.size());
+	m_angle = params[0]; 
+	apply_parameters(); 
+}
+
+const C3DBounds& C3DAxisrotTransformation::get_size() const
+{
+	return m_size;
+}
+
+P3DTransformation C3DAxisrotTransformation::do_upscale(const C3DBounds& size) const
+{
+	auto result = new C3DAxisrotTransformation(size, m_relative_origin, 
+						   m_rotation_axis, get_interpolator_factory()); 
+	result->apply_parameters();
+	return P3DTransformation(result);
+}
+
+
+C3DFMatrix C3DAxisrotTransformation::derivative_at(const C3DFVector& MIA_PARAM_UNUSED(x)) const
+{
+	assert(0 && "not implemented"); 
+}
+
+C3DFMatrix C3DAxisrotTransformation::derivative_at(int /*x*/, int /*y*/, int /*z*/) const
+{
+	assert(0 && "not implemented"); 
+}
+
+void C3DAxisrotTransformation::set_identity()
+{
+	cvdebug() << "set identity\n";
+	m_matrix.identity(); 
+}
+
+float C3DAxisrotTransformation::get_max_transform() const
+{
+	C3DFVector corners[7] = {
+		C3DFVector(get_size().x, 0, 0), 
+		C3DFVector(get_size().x, get_size().y,            0), 
+		C3DFVector(           0, get_size().y,            0), 
+		C3DFVector(           0, get_size().y, get_size().z), 
+		C3DFVector(get_size().x,            0, get_size().z), 
+		C3DFVector(           0,            0, get_size().z), 
+		C3DFVector(get_size())
+	};
+
+	float result = apply(C3DFVector()).norm2(); 
+	for(int i = 0; i < 7; ++i) {
+		float h = (apply(corners[i]) - corners[i]).norm2(); 
+		if (result < h) 
+			result = h; 
+	}
+
+	return sqrt(result);
+}
+
+
+C3DFVector C3DAxisrotTransformation::operator () (const C3DFVector& x) const
+{
+	return apply(x); 
+}
+
+float C3DAxisrotTransformation::get_jacobian(const C3DFVectorfield& /*v*/, float /*delta*/) const
+{
+	DEBUG_ASSERT_RELEASE_THROW(false, "C3DAxisrotTransformation doesn't implement a jacobian."); 
+}
+
+void C3DAxisrotTransformation::translate(const C3DFVectorfield& gradient, CDoubleVector& params) const
+{
+	assert(0 && !"not yet implemented"); 
+	assert(gradient.get_size() == m_size);
+	assert(params.size() == degrees_of_freedom());
+
+	vector<double> r(params.size(), 0.0);
+
+	auto g = gradient.begin();
+	for (size_t z = 0; z < m_size.z; ++z) {
+		double fy =  - m_rotation_center.y; 
+		for (size_t y = 0; y < m_size.y; ++y, fy += 1.0) {
+			double fx =  - m_rotation_center.x;
+			for (size_t x = 0; x < m_size.x; ++x, ++g, fx += 1.0) {
+				r[0] += -fy * g->x + fx * g->y;
+			}
+		}
+	}
+	std::copy(r.begin(), r.end(), params.begin());
+}
+
+
+
+C3DAxisrotTransformation::iterator_impl::iterator_impl(const C3DBounds& pos, const C3DBounds& size, 
+						      const C3DAxisrotTransformation& trans):
+	C3DTransformation::iterator_impl(pos, size),
+	m_trans(trans), 
+	m_value(trans.apply(C3DFVector(pos)))
+{
+	m_dx = m_trans.apply(C3DFVector(pos.x + 1.0, pos.y, pos.z)) - m_value;
+}
+
+C3DAxisrotTransformation::iterator_impl::iterator_impl(const C3DBounds& pos, const C3DBounds& begin, 
+						      const C3DBounds& end, const C3DBounds& size, 
+						      const C3DAxisrotTransformation& trans):
+	C3DTransformation::iterator_impl(pos, begin, end, size),
+	m_trans(trans), 
+	m_value(trans.apply(C3DFVector(pos)))
+{
+	m_dx = m_trans.apply(C3DFVector(pos.x + 1.0, pos.y, pos.z)) - m_value;
+}
+
+C3DTransformation::iterator_impl * C3DAxisrotTransformation::iterator_impl::clone() const
+{
+	return new iterator_impl(*this); 
+}
+
+const C3DFVector&  C3DAxisrotTransformation::iterator_impl::do_get_value()const
+{
+	return m_value; 
+}
+
+void C3DAxisrotTransformation::iterator_impl::do_x_increment()
+{
+	m_value += m_dx; 
+}
+
+void C3DAxisrotTransformation::iterator_impl::do_y_increment()
+{
+	m_value = m_trans.apply(C3DFVector(get_pos())); 
+	m_dx = m_trans.apply(C3DFVector(get_pos().x + 1.0, get_pos().y, get_pos().z)) - m_value;
+}
+
+void C3DAxisrotTransformation::iterator_impl::do_z_increment()
+{
+	m_value = m_trans.apply(C3DFVector(get_pos())); 
+	m_dx = m_trans.apply(C3DFVector(get_pos().x + 1.0, get_pos().y, get_pos().z)) - m_value;
+}
+
+
+C3DTransformation::const_iterator C3DAxisrotTransformation::begin() const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(C3DBounds(0,0,0), get_size(), *this)); 
+}
+
+C3DTransformation::const_iterator C3DAxisrotTransformation::end() const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(get_size(), get_size(), *this)); 
+}
+
+C3DTransformation::const_iterator C3DAxisrotTransformation::begin_range(const C3DBounds& begin, const C3DBounds& end) const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(begin, begin, end, get_size(), *this)); 
+}
+
+C3DTransformation::const_iterator C3DAxisrotTransformation::end_range(const C3DBounds& begin, const C3DBounds& end) const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(end, begin, end, get_size(), *this)); 
+}
+
+
+
+float C3DAxisrotTransformation::pertuberate(C3DFVectorfield& /*v*/) const
+{
+	DEBUG_ASSERT_RELEASE_THROW(false, "C3DAxisrotTransformation doesn't implement pertuberate."); 
+}
+
+C3DAxisrotTransformCreator::C3DAxisrotTransformCreator(const C3DFVector& origin, 
+						       const C3DFVector& rot_axis, 
+						       const C3DInterpolatorFactory& ipf):
+C3DTransformCreator(ipf), 
+	m_origin(origin), 
+	m_rotation_axis(rot_axis)
+{
+}
+
+P3DTransformation C3DAxisrotTransformCreator::do_create(const C3DBounds& size, 
+							const C3DInterpolatorFactory& ipf) const
+{
+	return P3DTransformation(new C3DAxisrotTransformation(size, m_origin, m_rotation_axis, ipf));
+}
+
+
+
+
+C3DAxisrotTransformCreatorPlugin::C3DAxisrotTransformCreatorPlugin():
+	C3DTransformCreatorPlugin("axisrot")
+{
+	add_parameter("origin", new C3DFVectorParameter(m_origin, true, "center of the transformation"));
+	add_parameter("axis", new C3DFVectorParameter(m_rotation_axis, true, "rotation axis"));
+}
+
+
+C3DTransformCreator *C3DAxisrotTransformCreatorPlugin::do_create(const C3DInterpolatorFactory& ipf) const
+{
+	return new C3DAxisrotTransformCreator(m_origin, m_rotation_axis, ipf);
+}
+
+const std::string C3DAxisrotTransformCreatorPlugin::do_get_descr() const
+{
+	return "Restricted rotation transformation (1 degrees of freedom). "
+		"The transformation is restricted to the rotation around the given "
+		"axis about the given rotation center";
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C3DAxisrotTransformCreatorPlugin();
+}
+
+
+
+}
diff --git a/mia/3d/transform/axisrot.hh b/mia/3d/transform/axisrot.hh
new file mode 100644
index 0000000..c5dd4c5
--- /dev/null
+++ b/mia/3d/transform/axisrot.hh
@@ -0,0 +1,128 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_axisrottransform_hh
+#define mia_3d_axisrottransform_hh
+
+#include <iterator>
+#include <mia/3d/transform.hh>
+#include <mia/3d/transformfactory.hh>
+#include <mia/3d/affine_matrix.hh>
+
+
+namespace mia_3dtransform_axisrot {
+
+
+
+class EXPORT_3D C3DAxisrotTransformation : public mia::C3DTransformation {
+public:
+	C3DAxisrotTransformation(const mia::C3DBounds& size, const mia::C3DFVector& orig, 
+				 const mia::C3DFVector& rot_axis, 
+				 const mia::C3DInterpolatorFactory& ipf); 
+	
+	mia::C3DFVector apply(const mia::C3DFVector& x) const;
+
+	class EXPORT_3D iterator_impl: public mia::C3DTransformation::iterator_impl  {
+	public:
+		iterator_impl(const mia::C3DBounds& pos, const mia::C3DBounds& size, 
+			      const C3DAxisrotTransformation& trans); 
+
+		iterator_impl(const mia::C3DBounds& pos, const mia::C3DBounds& begin, 
+			      const mia::C3DBounds& end, const mia::C3DBounds& size, 
+			      const C3DAxisrotTransformation& trans); 
+	private: 
+		virtual mia::C3DTransformation::iterator_impl * clone() const; 
+		virtual const mia::C3DFVector&  do_get_value()const; 
+		virtual void do_x_increment(); 
+		virtual void do_y_increment(); 
+		virtual void do_z_increment(); 
+
+		const C3DAxisrotTransformation& m_trans;
+		mia::C3DFVector m_value;
+		mia::C3DFVector m_dx;
+
+	};
+
+	const_iterator begin() const;
+	const_iterator end() const;
+	const_iterator begin_range(const mia::C3DBounds& begin, const mia::C3DBounds& end) const; 
+	const_iterator end_range(const mia::C3DBounds& begin, const mia::C3DBounds& end) const; 
+
+
+	virtual const mia::C3DBounds& get_size() const;
+	virtual mia::C3DTransformation *invert() const;
+	virtual mia::P3DTransformation do_upscale(const mia::C3DBounds& size) const;
+	virtual void translate(const mia::C3DFVectorfield& gradient, mia::CDoubleVector& params) const;
+	virtual size_t degrees_of_freedom() const;
+	virtual void update(float step, const mia::C3DFVectorfield& a);
+	virtual mia::C3DFMatrix derivative_at(const mia::C3DFVector& x) const; 
+	virtual mia::C3DFMatrix derivative_at(int x, int y, int z) const;
+	virtual mia::CDoubleVector get_parameters() const;
+	virtual void set_parameters(const mia::CDoubleVector& params);
+	virtual void set_identity();
+	virtual float get_max_transform() const;
+	virtual float pertuberate(mia::C3DFVectorfield& v) const;
+	virtual mia::C3DFVector operator () (const mia::C3DFVector& x) const;
+	virtual float get_jacobian(const mia::C3DFVectorfield& v, float delta) const;
+	mia::C3DFVector transform(const mia::C3DFVector& x)const;
+
+private:
+	void apply_parameters(); 
+	virtual mia::C3DTransformation *do_clone() const;
+	C3DAxisrotTransformation(const C3DAxisrotTransformation& other) = default;
+	C3DAxisrotTransformation& operator =(const C3DAxisrotTransformation& other)  = default;
+	double m_angle;
+	mia::CAffinTransformMatrix m_matrix;
+        mia::C3DFVector m_relative_origin;
+        mia::C3DFVector m_rotation_center;
+	mia::C3DFVector m_rotation_axis; 
+	mia::C3DBounds m_size;
+	mia::Quaternion m_y_align_rot; 
+	mia::Quaternion m_y_align_rot_inverse; 
+	bool m_y_align_rot_needed; 
+};
+
+
+class C3DAxisrotTransformCreator: public mia::C3DTransformCreator {
+public: 
+	C3DAxisrotTransformCreator(const mia::C3DFVector& origin, 
+				   const mia::C3DFVector& rot_axis,
+				   const mia::C3DInterpolatorFactory& ipf); 
+private: 
+	virtual mia::P3DTransformation do_create(const mia::C3DBounds& size, 
+						 const mia::C3DInterpolatorFactory& ipf) const;
+	mia::C3DFVector m_origin; 
+	mia::C3DFVector m_rotation_axis; 
+};
+
+class C3DAxisrotTransformCreatorPlugin: public mia::C3DTransformCreatorPlugin {
+public:
+	C3DAxisrotTransformCreatorPlugin(); 
+	virtual mia::C3DTransformCreator *do_create(const mia::C3DInterpolatorFactory& ipf) const;
+	const std::string do_get_descr() const;
+private:
+	mia::C3DFVector m_origin; 
+	mia::C3DFVector m_rotation_axis; 
+};
+
+
+
+}
+#endif
diff --git a/mia/3d/transform/raffine.cc b/mia/3d/transform/raffine.cc
new file mode 100644
index 0000000..6845efe
--- /dev/null
+++ b/mia/3d/transform/raffine.cc
@@ -0,0 +1,357 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <fstream>
+#include <cmath>
+#include <mia/core/msgstream.hh>
+#include <mia/3d/transform/raffine.hh>
+
+namespace mia_3dtransform_raffine {
+
+using namespace mia; 
+using namespace std;
+
+
+
+C3DFVector C3DRAffineTransformation::apply(const C3DFVector& x) const
+{
+	return transform(x);
+}
+
+
+
+C3DFVector C3DRAffineTransformation::transform(const C3DFVector& x)const
+{
+	return m_matrix * x;
+}
+
+C3DRAffineTransformation::C3DRAffineTransformation(const C3DBounds& size, const C3DFVector& orig, 
+						   const C3DFVector& rot_axis, 
+						   const C3DInterpolatorFactory& ipf):
+	C3DTransformation(ipf), 
+        m_params(3), 
+        m_relative_origin(orig), 
+	m_rotation_center(C3DFVector(size) * m_relative_origin), 
+	m_rotation_axis(rot_axis), 
+	m_size(size), 
+	m_y_align_rot_needed(false)
+{
+	cvinfo() << "Transform: center=" << m_rotation_center << " of size=" << m_size << "\n"; 
+	double n = m_rotation_axis.norm(); 
+	if (n == 0.0)
+		throw invalid_argument("C3DRAffineTransformation: rotation axis has zero length"); 
+
+	m_rotation_axis /= n; 
+	
+	// create a pre-post rotation quaternion to get the afs-pfs line into alignment with the 
+	// y axis. 
+
+	// one vector is 0,1,0, the other is m_rotation_axis
+	C3DFVector help_axis(-m_rotation_axis.z, 0, m_rotation_axis.x); 
+	if (help_axis.norm2() > 0.0) {
+		help_axis /= help_axis.norm(); 
+		m_y_align_rot_needed = true; 
+		double angle = acos(m_rotation_axis.y) / 2.0; 
+		double sina, cosa; 
+		sincos(angle, &sina, &cosa); 
+		m_y_align_rot = Quaternion( cosa, sina * help_axis.x, 0, sina * help_axis.z); 
+		cvinfo() << "Align-rotation = " << m_y_align_rot << "\n"; 
+
+		m_y_align_rot_inverse = m_y_align_rot.inverse(); 
+		
+	}
+	m_matrix.identity();
+}
+
+C3DTransformation *C3DRAffineTransformation::do_clone()const
+{
+	return new C3DRAffineTransformation(*this);
+}
+
+C3DTransformation *C3DRAffineTransformation::invert()const
+{
+	C3DRAffineTransformation *result = new C3DRAffineTransformation(*this);
+        
+        assert(0 && "not implemented"); 
+
+	return result; 
+}
+
+size_t C3DRAffineTransformation::degrees_of_freedom() const
+{
+	return m_params.size();
+}
+
+void C3DRAffineTransformation::update(float /*step*/, const C3DFVectorfield& /*a*/)
+{
+	assert(0 && "not implemented");
+}
+
+CDoubleVector C3DRAffineTransformation::get_parameters() const
+{
+	CDoubleVector result(degrees_of_freedom());
+	copy(m_params.begin(), m_params.end(), result.begin());
+	return result;
+}
+
+void C3DRAffineTransformation::set_parameters(const CDoubleVector& params)
+{
+	assert(degrees_of_freedom() == params.size());
+	copy(params.begin(), params.end(), m_params.begin());
+         
+        m_matrix.identity(); 
+        m_matrix.translate( -1.0f * m_rotation_center); 
+
+	if (m_y_align_rot_needed) {
+		m_matrix.rotate(m_y_align_rot); 
+	}
+
+	m_matrix.rotate_y(m_params[0]); 
+        m_matrix.shear(C3DFVector(0, m_params[1], m_params[2])); 
+	
+	if (m_y_align_rot_needed) {
+		m_matrix.rotate(m_y_align_rot_inverse); 
+	}
+
+	
+        m_matrix.translate(m_rotation_center); 
+}
+
+const C3DBounds& C3DRAffineTransformation::get_size() const
+{
+	return m_size;
+}
+
+P3DTransformation C3DRAffineTransformation::do_upscale(const C3DBounds& size) const
+{
+	auto result = new C3DRAffineTransformation(size, m_relative_origin, 
+						   m_rotation_axis, get_interpolator_factory()); 
+	result->set_parameters(m_params); 
+	return P3DTransformation(result);
+}
+
+
+C3DFMatrix C3DRAffineTransformation::derivative_at(const C3DFVector& MIA_PARAM_UNUSED(x)) const
+{
+	assert(0 && "not implemented"); 
+}
+
+C3DFMatrix C3DRAffineTransformation::derivative_at(int /*x*/, int /*y*/, int /*z*/) const
+{
+	assert(0 && "not implemented"); 
+}
+
+void C3DRAffineTransformation::set_identity()
+{
+	cvdebug() << "set identity\n";
+	m_matrix.identity(); 
+}
+
+float C3DRAffineTransformation::get_max_transform() const
+{
+	C3DFVector corners[7] = {
+		C3DFVector(get_size().x, 0, 0), 
+		C3DFVector(get_size().x, get_size().y,            0), 
+		C3DFVector(           0, get_size().y,            0), 
+		C3DFVector(           0, get_size().y, get_size().z), 
+		C3DFVector(get_size().x,            0, get_size().z), 
+		C3DFVector(           0,            0, get_size().z), 
+		C3DFVector(get_size())
+	};
+
+	float result = apply(C3DFVector()).norm2(); 
+	for(int i = 0; i < 7; ++i) {
+		float h = (apply(corners[i]) - corners[i]).norm2(); 
+		if (result < h) 
+			result = h; 
+	}
+
+	return sqrt(result);
+}
+
+
+C3DFVector C3DRAffineTransformation::operator () (const C3DFVector& x) const
+{
+	return apply(x); 
+}
+
+float C3DRAffineTransformation::get_jacobian(const C3DFVectorfield& /*v*/, float /*delta*/) const
+{
+	DEBUG_ASSERT_RELEASE_THROW(false, "C3DRAffineTransformation doesn't implement a jacobian."); 
+}
+
+void C3DRAffineTransformation::translate(const C3DFVectorfield& gradient, CDoubleVector& params) const
+{
+	
+	assert(0 && !"not yet implemented"); 
+	assert(gradient.get_size() == m_size);
+	assert(params.size() == degrees_of_freedom());
+
+	vector<double> r(params.size(), 0.0);
+
+	auto g = gradient.begin();
+	for (size_t z = 0; z < m_size.z; ++z) {
+		double fy =  - m_rotation_center.y; 
+		for (size_t y = 0; y < m_size.y; ++y, fy += 1.0) {
+			double fx =  - m_rotation_center.x;
+			for (size_t x = 0; x < m_size.x; ++x, ++g, fx += 1.0) {
+				r[0] += -fy * g->x + fx * g->y;
+				
+				// scaling 
+				r[1] += 0; 
+				r[2] += 0;
+				
+
+
+				// shear 
+				r[3] += 0; 
+				r[4] += 0; 
+				r[5] += 0; 
+
+				
+			}
+		}
+	}
+	std::copy(r.begin(), r.end(), params.begin());
+}
+
+
+
+C3DRAffineTransformation::iterator_impl::iterator_impl(const C3DBounds& pos, const C3DBounds& size, 
+						      const C3DRAffineTransformation& trans):
+	C3DTransformation::iterator_impl(pos, size),
+	m_trans(trans), 
+	m_value(trans.apply(C3DFVector(pos)))
+{
+	m_dx = m_trans.apply(C3DFVector(pos.x + 1.0, pos.y, pos.z)) - m_value;
+}
+
+C3DRAffineTransformation::iterator_impl::iterator_impl(const C3DBounds& pos, const C3DBounds& begin, 
+						      const C3DBounds& end, const C3DBounds& size, 
+						      const C3DRAffineTransformation& trans):
+	C3DTransformation::iterator_impl(pos, begin, end, size),
+	m_trans(trans), 
+	m_value(trans.apply(C3DFVector(pos)))
+{
+	m_dx = m_trans.apply(C3DFVector(pos.x + 1.0, pos.y, pos.z)) - m_value;
+}
+
+C3DTransformation::iterator_impl * C3DRAffineTransformation::iterator_impl::clone() const
+{
+	return new iterator_impl(*this); 
+}
+
+const C3DFVector&  C3DRAffineTransformation::iterator_impl::do_get_value()const
+{
+	return m_value; 
+}
+
+void C3DRAffineTransformation::iterator_impl::do_x_increment()
+{
+	m_value += m_dx; 
+}
+
+void C3DRAffineTransformation::iterator_impl::do_y_increment()
+{
+	m_value = m_trans.apply(C3DFVector(get_pos())); 
+	m_dx = m_trans.apply(C3DFVector(get_pos().x + 1.0, get_pos().y, get_pos().z)) - m_value;
+}
+
+void C3DRAffineTransformation::iterator_impl::do_z_increment()
+{
+	m_value = m_trans.apply(C3DFVector(get_pos())); 
+	m_dx = m_trans.apply(C3DFVector(get_pos().x + 1.0, get_pos().y, get_pos().z)) - m_value;
+}
+
+
+C3DTransformation::const_iterator C3DRAffineTransformation::begin() const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(C3DBounds(0,0,0), get_size(), *this)); 
+}
+
+C3DTransformation::const_iterator C3DRAffineTransformation::end() const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(get_size(), get_size(), *this)); 
+}
+
+C3DTransformation::const_iterator C3DRAffineTransformation::begin_range(const C3DBounds& begin, const C3DBounds& end) const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(begin, begin, end, get_size(), *this)); 
+}
+
+C3DTransformation::const_iterator C3DRAffineTransformation::end_range(const C3DBounds& begin, const C3DBounds& end) const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(end, begin, end, get_size(), *this)); 
+}
+
+
+
+float C3DRAffineTransformation::pertuberate(C3DFVectorfield& /*v*/) const
+{
+	DEBUG_ASSERT_RELEASE_THROW(false, "C3DRAffineTransformation doesn't implement pertuberate."); 
+}
+
+C3DRAffineTransformCreator::C3DRAffineTransformCreator(const C3DFVector& origin, 
+						       const C3DFVector& rot_axis, 
+						       const C3DInterpolatorFactory& ipf):
+C3DTransformCreator(ipf), 
+	m_origin(origin), 
+	m_rotation_axis(rot_axis)
+{
+}
+
+P3DTransformation C3DRAffineTransformCreator::do_create(const C3DBounds& size, 
+							const C3DInterpolatorFactory& ipf) const
+{
+	return P3DTransformation(new C3DRAffineTransformation(size, m_origin, m_rotation_axis, ipf));
+}
+
+
+
+
+C3DRAffineTransformCreatorPlugin::C3DRAffineTransformCreatorPlugin():
+	C3DTransformCreatorPlugin("raffine")
+{
+	add_parameter("origin", new C3DFVectorParameter(m_origin, true, "center of the transformation"));
+	add_parameter("axis", new C3DFVectorParameter(m_rotation_axis, true, "rotation axis"));
+}
+
+
+C3DTransformCreator *C3DRAffineTransformCreatorPlugin::do_create(const C3DInterpolatorFactory& ipf) const
+{
+	return new C3DRAffineTransformCreator(m_origin, m_rotation_axis, ipf);
+}
+
+const std::string C3DRAffineTransformCreatorPlugin::do_get_descr() const
+{
+	return "Restricted affine transformation (3 degrees of freedom). "
+		"The transformation is restricted to the rotation around the given "
+		"axis and shearing along the two axis perpendicular to "
+		"the given one";
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C3DRAffineTransformCreatorPlugin();
+}
+
+
+
+}
diff --git a/mia/3d/transform/raffine.hh b/mia/3d/transform/raffine.hh
new file mode 100644
index 0000000..8886e65
--- /dev/null
+++ b/mia/3d/transform/raffine.hh
@@ -0,0 +1,127 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_raffinetransform_hh
+#define mia_3d_raffinetransform_hh
+
+#include <iterator>
+#include <mia/3d/transform.hh>
+#include <mia/3d/transformfactory.hh>
+#include <mia/3d/affine_matrix.hh>
+
+
+namespace mia_3dtransform_raffine {
+
+
+
+class EXPORT_3D C3DRAffineTransformation : public mia::C3DTransformation {
+public:
+	C3DRAffineTransformation(const mia::C3DBounds& size, const mia::C3DFVector& orig, 
+				 const mia::C3DFVector& rot_axis, 
+				 const mia::C3DInterpolatorFactory& ipf); 
+	
+	mia::C3DFVector apply(const mia::C3DFVector& x) const;
+
+	class EXPORT_3D iterator_impl: public mia::C3DTransformation::iterator_impl  {
+	public:
+		iterator_impl(const mia::C3DBounds& pos, const mia::C3DBounds& size, 
+			      const C3DRAffineTransformation& trans); 
+
+		iterator_impl(const mia::C3DBounds& pos, const mia::C3DBounds& begin, 
+			      const mia::C3DBounds& end, const mia::C3DBounds& size, 
+			      const C3DRAffineTransformation& trans); 
+	private: 
+		virtual mia::C3DTransformation::iterator_impl * clone() const; 
+		virtual const mia::C3DFVector&  do_get_value()const; 
+		virtual void do_x_increment(); 
+		virtual void do_y_increment(); 
+		virtual void do_z_increment(); 
+
+		const C3DRAffineTransformation& m_trans;
+		mia::C3DFVector m_value;
+		mia::C3DFVector m_dx;
+
+	};
+
+	const_iterator begin() const;
+	const_iterator end() const;
+	const_iterator begin_range(const mia::C3DBounds& begin, const mia::C3DBounds& end) const; 
+	const_iterator end_range(const mia::C3DBounds& begin, const mia::C3DBounds& end) const; 
+
+
+	virtual const mia::C3DBounds& get_size() const;
+	virtual mia::C3DTransformation *invert() const;
+	virtual mia::P3DTransformation do_upscale(const mia::C3DBounds& size) const;
+	virtual void translate(const mia::C3DFVectorfield& gradient, mia::CDoubleVector& params) const;
+	virtual size_t degrees_of_freedom() const;
+	virtual void update(float step, const mia::C3DFVectorfield& a);
+	virtual mia::C3DFMatrix derivative_at(const mia::C3DFVector& x) const; 
+	virtual mia::C3DFMatrix derivative_at(int x, int y, int z) const;
+	virtual mia::CDoubleVector get_parameters() const;
+	virtual void set_parameters(const mia::CDoubleVector& params);
+	virtual void set_identity();
+	virtual float get_max_transform() const;
+	virtual float pertuberate(mia::C3DFVectorfield& v) const;
+	virtual mia::C3DFVector operator () (const mia::C3DFVector& x) const;
+	virtual float get_jacobian(const mia::C3DFVectorfield& v, float delta) const;
+	mia::C3DFVector transform(const mia::C3DFVector& x)const;
+
+private:
+	virtual mia::C3DTransformation *do_clone() const;
+	C3DRAffineTransformation(const C3DRAffineTransformation& other) = default;
+	C3DRAffineTransformation& operator =(const C3DRAffineTransformation& other)  = default;
+	mia::CDoubleVector m_params;
+	mia::CAffinTransformMatrix m_matrix;
+        mia::C3DFVector m_relative_origin;
+        mia::C3DFVector m_rotation_center;
+	mia::C3DFVector m_rotation_axis; 
+	mia::C3DBounds m_size;
+	mia::Quaternion m_y_align_rot; 
+	mia::Quaternion m_y_align_rot_inverse; 
+	bool m_y_align_rot_needed; 
+};
+
+
+class C3DRAffineTransformCreator: public mia::C3DTransformCreator {
+public: 
+	C3DRAffineTransformCreator(const mia::C3DFVector& origin, 
+				   const mia::C3DFVector& rot_axis,
+				   const mia::C3DInterpolatorFactory& ipf); 
+private: 
+	virtual mia::P3DTransformation do_create(const mia::C3DBounds& size, 
+						 const mia::C3DInterpolatorFactory& ipf) const;
+	mia::C3DFVector m_origin; 
+	mia::C3DFVector m_rotation_axis; 
+};
+
+class C3DRAffineTransformCreatorPlugin: public mia::C3DTransformCreatorPlugin {
+public:
+	C3DRAffineTransformCreatorPlugin(); 
+	virtual mia::C3DTransformCreator *do_create(const mia::C3DInterpolatorFactory& ipf) const;
+	const std::string do_get_descr() const;
+private:
+	mia::C3DFVector m_origin; 
+	mia::C3DFVector m_rotation_axis; 
+};
+
+
+
+}
+#endif
diff --git a/mia/3d/transform/rigid.cc b/mia/3d/transform/rigid.cc
index e10a45f..f2d9d01 100644
--- a/mia/3d/transform/rigid.cc
+++ b/mia/3d/transform/rigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -174,40 +174,6 @@ void C3DRigidTransformation::set_parameters(const CDoubleVector& params)
 	m_matrix_valid = false;
 }
 
-float C3DRigidTransformation::divergence() const
-{
-	return 0.0;
-}
-
-float C3DRigidTransformation::grad_divergence() const
-{
-	return 0.0;
-}
-
-
-float C3DRigidTransformation::grad_curl() const
-{
-	return 0.0;
-}
-
-
-float C3DRigidTransformation::curl() const
-{
-	// this is not right
-	return 0.0;
-}
-
-double C3DRigidTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/, CDoubleVector& /*gradient*/) const
-{
-	return 0.0; 
-}
-
-double C3DRigidTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/) const
-{
-	return 0.0; 
-}
-
-
 const C3DBounds& C3DRigidTransformation::get_size() const
 {
 	return m_size;
@@ -482,8 +448,9 @@ C3DRigidTransformCreatorPlugin::C3DRigidTransformCreatorPlugin():
 	C3DTransformCreatorPlugin("rigid"), 
 	m_relative_rot_center(0,0,0)
 {
-	add_parameter("rot-center", make_param(m_relative_rot_center, false, "Relative rotation center, i.e.  <0.5,0.5,0.5> corresponds "
-					       "to the center of the volume"));
+	add_parameter("origin", make_param(m_relative_rot_center, false, 
+					   "Relative rotation center, i.e.  <0.5,0.5,0.5> corresponds "
+					   "to the center of the volume"));
 }
 
 C3DTransformCreator *C3DRigidTransformCreatorPlugin::do_create(const C3DInterpolatorFactory& ipf) const
diff --git a/mia/3d/transform/rigid.hh b/mia/3d/transform/rigid.hh
index c5119c2..f9b690e 100644
--- a/mia/3d/transform/rigid.hh
+++ b/mia/3d/transform/rigid.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -86,12 +86,6 @@ public:
 	virtual float pertuberate(C3DFVectorfield& v) const;
 	virtual C3DFVector operator () (const C3DFVector& x) const;
 	virtual float get_jacobian(const C3DFVectorfield& v, float delta) const;
-	virtual float divergence() const;
-	virtual float curl() const;
-	float grad_divergence() const;
-	float grad_curl() const;
-	double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	double get_divcurl_cost(double wd, double wr) const; 
 private:
 	virtual C3DTransformation *do_clone() const;
 	void evaluate_matrix() const;
diff --git a/mia/3d/transform/rotation.cc b/mia/3d/transform/rotation.cc
index 51a5c01..291c23f 100644
--- a/mia/3d/transform/rotation.cc
+++ b/mia/3d/transform/rotation.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -146,40 +146,6 @@ void C3DRotationTransformation::set_parameters(const CDoubleVector& params)
 	m_matrix_valid = false;
 }
 
-float C3DRotationTransformation::divergence() const
-{
-	return 0.0;
-}
-
-float C3DRotationTransformation::grad_divergence() const
-{
-	return 0.0;
-}
-
-
-float C3DRotationTransformation::grad_curl() const
-{
-	return 0.0;
-}
-
-
-float C3DRotationTransformation::curl() const
-{
-	// this is not right
-	return 0.0;
-}
-
-double C3DRotationTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/, CDoubleVector& /*gradient*/) const
-{
-	return 0.0; 
-}
-
-double C3DRotationTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/) const
-{
-	return 0.0; 
-}
-
-
 const C3DBounds& C3DRotationTransformation::get_size() const
 {
 	return m_size;
@@ -418,7 +384,8 @@ private:
 C3DRotationTransformCreatorPlugin::C3DRotationTransformCreatorPlugin():
 	C3DTransformCreatorPlugin("rotation")
 {
-	add_parameter("rot-center", make_param(m_relative_rot_center, false, "Relative rotation center, i.e.  <0.5,0.5,0.5> corresponds "
+	add_parameter("origin", make_param(m_relative_rot_center, false, 
+					       "Relative rotation center, i.e.  <0.5,0.5,0.5> corresponds "
 					       "to the center of the volume"));
 
 }
diff --git a/mia/3d/transform/rotation.hh b/mia/3d/transform/rotation.hh
index df35758..08cde6c 100644
--- a/mia/3d/transform/rotation.hh
+++ b/mia/3d/transform/rotation.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -86,12 +86,6 @@ public:
 	virtual C3DFVector operator () (const C3DFVector& x) const;
 	virtual float get_jacobian(const C3DFVectorfield& v, float delta) const;
 	C3DFVector transform(const C3DFVector& x)const;
-	virtual float divergence() const;
-	virtual float curl() const;
-	float grad_divergence() const;
-	float grad_curl() const;
-	double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	double get_divcurl_cost(double wd, double wr) const; 
 private:
 	virtual C3DTransformation *do_clone() const;
 	void evaluate_matrix() const;
diff --git a/mia/3d/transform/rotbend.cc b/mia/3d/transform/rotbend.cc
new file mode 100644
index 0000000..2ee935c
--- /dev/null
+++ b/mia/3d/transform/rotbend.cc
@@ -0,0 +1,334 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <fstream>
+#include <cmath>
+#include <mia/core/msgstream.hh>
+#include <mia/3d/transform/rotbend.hh>
+
+namespace mia_3dtransform_rotbend {
+
+using namespace mia; 
+using namespace std;
+
+
+
+C3DFVector C3DRotBendTransformation::apply(const C3DFVector& x) const
+{
+	return transform(x);
+}
+
+
+
+C3DFVector C3DRotBendTransformation::transform(const C3DFVector& x)const
+{
+	auto y = m_pre_matrix * x; 
+
+	if (y.x > 0) {
+		const float max_distance = get_size().x - m_rotation_center.x; 
+		y.z += y.x * y.x * m_params[2] / (max_distance * max_distance + 1); 
+	} 
+	else if (y.x < 0) {
+		const float max_distance = m_rotation_center.x; 
+		y.z += y.x * y.x * m_params[3] / (max_distance * max_distance + 1); 
+	}
+
+	return m_post_matrix * y;
+}
+
+C3DRotBendTransformation::C3DRotBendTransformation(const C3DBounds& size, const C3DFVector& orig, 
+						   const C3DInterpolatorFactory& ipf):
+	C3DTransformation(ipf), 
+        m_params(4), 
+        m_relative_origin(orig), 
+	m_rotation_center(C3DFVector(size) * m_relative_origin), 
+	m_size(size)
+{
+	m_pre_matrix.identity();
+	m_post_matrix.identity();
+}
+
+C3DTransformation *C3DRotBendTransformation::do_clone()const
+{
+	return new C3DRotBendTransformation(*this);
+}
+
+C3DTransformation *C3DRotBendTransformation::invert()const
+{
+	C3DRotBendTransformation *result = new C3DRotBendTransformation(*this);
+        
+        assert(0 && "not implemented"); 
+
+	return result; 
+}
+
+size_t C3DRotBendTransformation::degrees_of_freedom() const
+{
+	return m_params.size();
+}
+
+void C3DRotBendTransformation::update(float /*step*/, const C3DFVectorfield& /*a*/)
+{
+	assert(0 && "not implemented");
+}
+
+CDoubleVector C3DRotBendTransformation::get_parameters() const
+{
+	CDoubleVector result(degrees_of_freedom());
+	copy(m_params.begin(), m_params.end(), result.begin());
+	return result;
+}
+
+void C3DRotBendTransformation::set_parameters(const CDoubleVector& params)
+{
+	assert(degrees_of_freedom() == params.size());
+	copy(params.begin(), params.end(), m_params.begin());
+	cvmsg() <<"Params: "<< m_params << "\n"; 
+         
+        m_pre_matrix.identity(); 
+	m_post_matrix.identity(); 
+	m_pre_matrix.translate( -1.0f * m_rotation_center); 
+
+	m_pre_matrix.rotate_x(m_params[0]); 
+	m_pre_matrix.rotate_y(m_params[1]); 
+
+        m_post_matrix.translate(m_rotation_center); 
+}
+
+const C3DBounds& C3DRotBendTransformation::get_size() const
+{
+	return m_size;
+}
+
+P3DTransformation C3DRotBendTransformation::do_upscale(const C3DBounds& size) const
+{
+	auto result = new C3DRotBendTransformation(size, m_relative_origin, get_interpolator_factory()); 
+	result->set_parameters(m_params); 
+	return P3DTransformation(result);
+}
+
+
+C3DFMatrix C3DRotBendTransformation::derivative_at(const C3DFVector& MIA_PARAM_UNUSED(x)) const
+{
+	assert(0 && "not implemented"); 
+}
+
+C3DFMatrix C3DRotBendTransformation::derivative_at(int /*x*/, int /*y*/, int /*z*/) const
+{
+	assert(0 && "not implemented"); 
+}
+
+void C3DRotBendTransformation::set_identity()
+{
+	cvdebug() << "set identity\n";
+	m_pre_matrix.identity(); 
+	m_post_matrix.identity(); 
+	fill(m_params.begin(), m_params.end(), 0.0); 
+}
+
+float C3DRotBendTransformation::get_max_transform() const
+{
+	C3DFVector corners[7] = {
+		C3DFVector(get_size().x, 0, 0), 
+		C3DFVector(get_size().x, get_size().y,            0), 
+		C3DFVector(           0, get_size().y,            0), 
+		C3DFVector(           0, get_size().y, get_size().z), 
+		C3DFVector(get_size().x,            0, get_size().z), 
+		C3DFVector(           0,            0, get_size().z), 
+		C3DFVector(get_size())
+	};
+
+	float result = apply(C3DFVector()).norm2(); 
+	for(int i = 0; i < 7; ++i) {
+		float h = (apply(corners[i]) - corners[i]).norm2(); 
+		if (result < h) 
+			result = h; 
+	}
+
+	return sqrt(result);
+}
+
+
+C3DFVector C3DRotBendTransformation::operator () (const C3DFVector& x) const
+{
+	return apply(x); 
+}
+
+float C3DRotBendTransformation::get_jacobian(const C3DFVectorfield& /*v*/, float /*delta*/) const
+{
+	DEBUG_ASSERT_RELEASE_THROW(false, "C3DRotBendTransformation doesn't implement a jacobian."); 
+}
+
+void C3DRotBendTransformation::translate(const C3DFVectorfield& gradient, CDoubleVector& params) const
+{
+	
+	assert(0 && !"not yet implemented"); 
+	assert(gradient.get_size() == m_size);
+	assert(params.size() == degrees_of_freedom());
+
+	vector<double> r(params.size(), 0.0);
+
+	auto g = gradient.begin();
+	for (size_t z = 0; z < m_size.z; ++z) {
+		double fy =  - m_rotation_center.y; 
+		for (size_t y = 0; y < m_size.y; ++y, fy += 1.0) {
+			double fx =  - m_rotation_center.x;
+			for (size_t x = 0; x < m_size.x; ++x, ++g, fx += 1.0) {
+				r[0] += -fy * g->x + fx * g->y;
+				
+				// scaling 
+				r[1] += 0; 
+				r[2] += 0;
+				
+
+
+				// shear 
+				r[3] += 0; 
+				r[4] += 0; 
+				r[5] += 0; 
+
+				
+			}
+		}
+	}
+	std::copy(r.begin(), r.end(), params.begin());
+}
+
+
+
+C3DRotBendTransformation::iterator_impl::iterator_impl(const C3DBounds& pos, const C3DBounds& size, 
+						      const C3DRotBendTransformation& trans):
+	C3DTransformation::iterator_impl(pos, size),
+	m_trans(trans), 
+	m_value(trans.apply(C3DFVector(pos)))
+{
+	m_dx = m_trans.apply(C3DFVector(pos.x + 1.0, pos.y, pos.z)) - m_value;
+}
+
+C3DRotBendTransformation::iterator_impl::iterator_impl(const C3DBounds& pos, const C3DBounds& begin, 
+						      const C3DBounds& end, const C3DBounds& size, 
+						      const C3DRotBendTransformation& trans):
+	C3DTransformation::iterator_impl(pos, begin, end, size),
+	m_trans(trans), 
+	m_value(trans.apply(C3DFVector(pos)))
+{
+	m_dx = m_trans.apply(C3DFVector(pos.x + 1.0, pos.y, pos.z)) - m_value;
+}
+
+C3DTransformation::iterator_impl * C3DRotBendTransformation::iterator_impl::clone() const
+{
+	return new iterator_impl(*this); 
+}
+
+const C3DFVector&  C3DRotBendTransformation::iterator_impl::do_get_value()const
+{
+	return m_value; 
+}
+
+void C3DRotBendTransformation::iterator_impl::do_x_increment()
+{
+	m_value += m_dx; 
+}
+
+void C3DRotBendTransformation::iterator_impl::do_y_increment()
+{
+	m_value = m_trans.apply(C3DFVector(get_pos())); 
+	m_dx = m_trans.apply(C3DFVector(get_pos().x + 1.0, get_pos().y, get_pos().z)) - m_value;
+}
+
+void C3DRotBendTransformation::iterator_impl::do_z_increment()
+{
+	m_value = m_trans.apply(C3DFVector(get_pos())); 
+	m_dx = m_trans.apply(C3DFVector(get_pos().x + 1.0, get_pos().y, get_pos().z)) - m_value;
+}
+
+
+C3DTransformation::const_iterator C3DRotBendTransformation::begin() const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(C3DBounds(0,0,0), get_size(), *this)); 
+}
+
+C3DTransformation::const_iterator C3DRotBendTransformation::end() const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(get_size(), get_size(), *this)); 
+}
+
+C3DTransformation::const_iterator C3DRotBendTransformation::begin_range(const C3DBounds& begin, const C3DBounds& end) const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(begin, begin, end, get_size(), *this)); 
+}
+
+C3DTransformation::const_iterator C3DRotBendTransformation::end_range(const C3DBounds& begin, const C3DBounds& end) const
+{
+	return C3DTransformation::const_iterator(new iterator_impl(end, begin, end, get_size(), *this)); 
+}
+
+
+
+float C3DRotBendTransformation::pertuberate(C3DFVectorfield& /*v*/) const
+{
+	DEBUG_ASSERT_RELEASE_THROW(false, "C3DRotBendTransformation doesn't implement pertuberate."); 
+}
+
+C3DRotBendTransformCreator::C3DRotBendTransformCreator(const C3DFVector& origin, 
+						       const C3DInterpolatorFactory& ipf):
+C3DTransformCreator(ipf), 
+	m_origin(origin)
+{
+}
+
+P3DTransformation C3DRotBendTransformCreator::do_create(const C3DBounds& size, 
+							const C3DInterpolatorFactory& ipf) const
+{
+	return P3DTransformation(new C3DRotBendTransformation(size, m_origin, ipf));
+}
+
+
+
+
+C3DRotBendTransformCreatorPlugin::C3DRotBendTransformCreatorPlugin():
+        C3DTransformCreatorPlugin("rotbend")
+{
+	add_parameter("origin", new C3DFVectorParameter(m_origin, true, "center of the transformation"));
+}
+
+
+C3DTransformCreator *C3DRotBendTransformCreatorPlugin::do_create(const C3DInterpolatorFactory& ipf) const
+{
+	return new C3DRotBendTransformCreator(m_origin, ipf);
+}
+
+const std::string C3DRotBendTransformCreatorPlugin::do_get_descr() const
+{
+	return "Restricted transformation (4 degrees of freedom). "
+		"The transformation is restricted to the rotation around the x and y axis "
+		"and a bending along the x axis, independedn in each direction, with the bending "
+		"increasing with the squared distance from the rotation axis."
+		;
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C3DRotBendTransformCreatorPlugin();
+}
+
+
+
+}
diff --git a/mia/3d/transform/rotbend.hh b/mia/3d/transform/rotbend.hh
new file mode 100644
index 0000000..40ec14a
--- /dev/null
+++ b/mia/3d/transform/rotbend.hh
@@ -0,0 +1,120 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_rotbendtransform_hh
+#define mia_3d_rotbendtransform_hh
+
+#include <iterator>
+#include <mia/3d/transform.hh>
+#include <mia/3d/transformfactory.hh>
+#include <mia/3d/affine_matrix.hh>
+
+
+namespace mia_3dtransform_rotbend {
+
+
+
+class EXPORT_3D C3DRotBendTransformation : public mia::C3DTransformation {
+public:
+	C3DRotBendTransformation(const mia::C3DBounds& size, const mia::C3DFVector& orig, 
+				 const mia::C3DInterpolatorFactory& ipf); 
+	
+	mia::C3DFVector apply(const mia::C3DFVector& x) const;
+
+	class EXPORT_3D iterator_impl: public mia::C3DTransformation::iterator_impl  {
+	public:
+		iterator_impl(const mia::C3DBounds& pos, const mia::C3DBounds& size, 
+			      const C3DRotBendTransformation& trans); 
+
+		iterator_impl(const mia::C3DBounds& pos, const mia::C3DBounds& begin, 
+			      const mia::C3DBounds& end, const mia::C3DBounds& size, 
+			      const C3DRotBendTransformation& trans); 
+	private: 
+		virtual mia::C3DTransformation::iterator_impl * clone() const; 
+		virtual const mia::C3DFVector&  do_get_value()const; 
+		virtual void do_x_increment(); 
+		virtual void do_y_increment(); 
+		virtual void do_z_increment(); 
+
+		const C3DRotBendTransformation& m_trans;
+		mia::C3DFVector m_value;
+		mia::C3DFVector m_dx;
+
+	};
+
+	const_iterator begin() const;
+	const_iterator end() const;
+	const_iterator begin_range(const mia::C3DBounds& begin, const mia::C3DBounds& end) const; 
+	const_iterator end_range(const mia::C3DBounds& begin, const mia::C3DBounds& end) const; 
+
+
+	virtual const mia::C3DBounds& get_size() const;
+	virtual mia::C3DTransformation *invert() const;
+	virtual mia::P3DTransformation do_upscale(const mia::C3DBounds& size) const;
+	virtual void translate(const mia::C3DFVectorfield& gradient, mia::CDoubleVector& params) const;
+	virtual size_t degrees_of_freedom() const;
+	virtual void update(float step, const mia::C3DFVectorfield& a);
+	virtual mia::C3DFMatrix derivative_at(const mia::C3DFVector& x) const; 
+	virtual mia::C3DFMatrix derivative_at(int x, int y, int z) const;
+	virtual mia::CDoubleVector get_parameters() const;
+	virtual void set_parameters(const mia::CDoubleVector& params);
+	virtual void set_identity();
+	virtual float get_max_transform() const;
+	virtual float pertuberate(mia::C3DFVectorfield& v) const;
+	virtual mia::C3DFVector operator () (const mia::C3DFVector& x) const;
+	virtual float get_jacobian(const mia::C3DFVectorfield& v, float delta) const;
+	mia::C3DFVector transform(const mia::C3DFVector& x)const;
+
+private:
+	virtual mia::C3DTransformation *do_clone() const;
+	C3DRotBendTransformation(const C3DRotBendTransformation& other) = default;
+	C3DRotBendTransformation& operator =(const C3DRotBendTransformation& other)  = default;
+	mia::CDoubleVector m_params;
+	mia::CAffinTransformMatrix m_pre_matrix;
+	mia::CAffinTransformMatrix m_post_matrix;
+        mia::C3DFVector m_relative_origin;
+        mia::C3DFVector m_rotation_center;
+	mia::C3DBounds m_size;
+};
+
+
+class C3DRotBendTransformCreator: public mia::C3DTransformCreator {
+public: 
+	C3DRotBendTransformCreator(const mia::C3DFVector& origin, 
+				   const mia::C3DInterpolatorFactory& ipf); 
+private: 
+	virtual mia::P3DTransformation do_create(const mia::C3DBounds& size, 
+						 const mia::C3DInterpolatorFactory& ipf) const;
+	mia::C3DFVector m_origin; 
+};
+
+class C3DRotBendTransformCreatorPlugin: public mia::C3DTransformCreatorPlugin {
+public:
+	C3DRotBendTransformCreatorPlugin(); 
+	virtual mia::C3DTransformCreator *do_create(const mia::C3DInterpolatorFactory& ipf) const;
+	const std::string do_get_descr() const;
+private:
+	mia::C3DFVector m_origin; 
+};
+
+
+
+}
+#endif
diff --git a/mia/3d/transform/spline.cc b/mia/3d/transform/spline.cc
index 21e3be1..738fda2 100644
--- a/mia/3d/transform/spline.cc
+++ b/mia/3d/transform/spline.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
 #include <cmath>
 #include <sstream>
 #include <mia/3d/transform/spline.hh>
+#include <mia/3d/transform/vectorfield.hh>
 #include <mia/3d/transformfactory.hh>
 #include <mia/3d/imageio.hh>
 #include <mia/core/index.hh>
@@ -158,6 +159,11 @@ C3DSplineTransformation::~C3DSplineTransformation()
 {
 }
 
+C3DBounds C3DSplineTransformation::get_minimal_supported_image_size() const
+{
+	return C3DBounds(ceil(m_target_c_rate.x), ceil(m_target_c_rate.y), ceil(m_target_c_rate.z))  + C3DBounds::_1; 
+}
+
 void C3DSplineTransformation::set_coefficients(const C3DFVectorfield& field)
 {
 	TRACE_FUNCTION;
@@ -1020,42 +1026,6 @@ bool C3DSplineTransformation::do_has_energy_penalty() const
 	return m_penalty.operator bool(); 
 }
 
-double C3DSplineTransformation::get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const
-{
-	TRACE_FUNCTION;
-//	FUNCTION_NOT_TESTED;
-	reinit(); 
-
-	// create PP matrices or adapt size 
-	if (!m_divcurl_matrix) 
-		m_divcurl_matrix.reset(new C3DPPDivcurlMatrix(m_coefficients.get_size(), 
-							       C3DFVector(m_range), 
-							       *m_kernel, wd, wr)); 
-	else 
-		m_divcurl_matrix->reset(m_coefficients.get_size(), C3DFVector(m_range), 
-					 *m_kernel, wd, wr); 
-	
-	
-	return m_divcurl_matrix->evaluate(m_coefficients, gradient); 
-}
-
-double C3DSplineTransformation::get_divcurl_cost(double wd, double wr) const
-{
-	TRACE_FUNCTION;
-
-	reinit(); 
-	// create PP matrices or adapt size 
-	if (!m_divcurl_matrix) 
-		m_divcurl_matrix.reset(new C3DPPDivcurlMatrix(m_coefficients.get_size(), C3DFVector(m_range), 
-							       *m_kernel, wd, wr)); 
-	else 
-		m_divcurl_matrix->reset(m_coefficients.get_size(), C3DFVector(m_range), 
-					 *m_kernel, wd, wr); 
-	
-
-	return *m_divcurl_matrix * m_coefficients; 
-}
-
 
 class C3DSplinebigTransformCreator: public C3DTransformCreator {
 public:
@@ -1153,7 +1123,9 @@ const std::string C3DSplineTransformCreatorPlugin::do_get_descr() const
 
 extern "C" EXPORT CPluginBase *get_plugin_interface()
 {
-	return new C3DSplineTransformCreatorPlugin();
+	auto p = new C3DGridTransformCreatorPlugin();
+	p->append_interface(new C3DSplineTransformCreatorPlugin()); 
+	return p; 
 }
 
 NS_MIA_END
diff --git a/mia/3d/transform/spline.hh b/mia/3d/transform/spline.hh
index b120b7e..f405e13 100644
--- a/mia/3d/transform/spline.hh
+++ b/mia/3d/transform/spline.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -92,9 +92,7 @@ public:
 	virtual float pertuberate(C3DFVectorfield& v) const;
 	virtual float get_jacobian(const C3DFVectorfield& v, float delta) const;
 	virtual C3DFVector operator () (const C3DFVector& x) const;
-
-	virtual double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	virtual double get_divcurl_cost(double wd, double wr) const; 
+	virtual C3DBounds get_minimal_supported_image_size() const; 
 
 	C3DFVector on_grid(const mia::C3DBounds& x) const; 
 
@@ -129,7 +127,6 @@ private:
 	mutable C3DFVector m_inv_scale;
 	mutable bool m_scales_valid;
 
-	mutable std::shared_ptr<C3DPPDivcurlMatrix> m_divcurl_matrix; 
 	mutable std::vector<std::vector<double> > m_x_weights; 
 	mutable std::vector<int> m_x_indices; 
 	mutable std::vector<std::vector<double> > m_y_weights; 
diff --git a/mia/3d/transform/test_affine.cc b/mia/3d/transform/test_affine.cc
index 43b338b..c865ada 100644
--- a/mia/3d/transform/test_affine.cc
+++ b/mia/3d/transform/test_affine.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,8 +30,6 @@ using namespace ::boost;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath kernel_test_path; 
-
 struct ipfFixture {
 	ipfFixture():
 		ipf("bspline:d=3", "mirror")
diff --git a/mia/3d/transform/test_axisrot.cc b/mia/3d/transform/test_axisrot.cc
new file mode 100644
index 0000000..19cf458
--- /dev/null
+++ b/mia/3d/transform/test_axisrot.cc
@@ -0,0 +1,173 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <cmath>
+#include <mia/internal/autotest.hh>
+
+#include <mia/3d/transform/axisrot.hh>
+
+NS_MIA_USE
+
+
+using namespace mia_3dtransform_axisrot;
+using namespace std;
+using namespace ::boost;
+using namespace boost::unit_test;
+namespace bfs=boost::filesystem;
+
+struct ipfFixture {
+	ipfFixture():
+		ipf("bspline:d=3", "mirror")
+		{
+		} 
+	C3DInterpolatorFactory ipf; 
+}; 
+
+
+struct Axis1Fixture : public ipfFixture {
+
+        Axis1Fixture(); 
+
+        void check_transformed_is_same(int idx, double param, const C3DFVector& v); 
+
+        void check_transformed_is_expected(int idx, double param, const C3DFVector& v, const C3DFVector& expect); 
+
+        C3DFVector m_origin; 
+        C3DFVector m_axis; 
+        C3DBounds m_size; 
+        C3DAxisrotTransformation m_transform; 
+}; 
+
+
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_rotation_is_fixed, Axis1Fixture )
+{
+        check_transformed_is_same(0, 0.0, m_origin); 
+        check_transformed_is_same(0, 1.0, m_origin); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_rotation_origin_plus_minus_axis_is_same, Axis1Fixture )
+{
+        check_transformed_is_same(0, 1.0, m_origin - m_axis);
+        check_transformed_is_same(0, 1.0, m_origin + m_axis); 
+}
+
+
+// the test values are evaluated with octave helper programs 
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_rotation, Axis1Fixture )
+{
+	check_transformed_is_expected(0, M_PI/2.0, m_origin +  C3DFVector(-0.5, 0.5, -0.2 ), 
+				      m_origin + C3DFVector(0.3454, 0.08835,  -0.6426));
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_affine3d_iterator, ipfFixture )
+{
+	C3DBounds size(10,20,15);
+
+	C3DAxisrotTransformation t1(size, C3DFVector(5,9.0f,7.5f), C3DFVector(0,1.0f,1.0f), ipf);
+	C3DAxisrotTransformation::const_iterator ti = t1.begin();
+	
+	for (size_t z = 0; z < size.z; ++z)
+		for (size_t y = 0; y < size.y; ++y)
+			for (size_t x = 0; x < size.x; ++x, ++ti) {
+				BOOST_CHECK_EQUAL(*ti, C3DFVector(x, y, z));
+			}
+	
+	BOOST_CHECK(ti == t1.end());
+}
+
+BOOST_FIXTURE_TEST_CASE( test_affine3d_ranged_iterator, ipfFixture)
+{
+	C3DBounds size(10,20,30);
+	C3DBounds delta(1,2,3); 
+
+	C3DAxisrotTransformation t1(size, C3DFVector(5,9.0f,15.5f), C3DFVector(0,1.0f,1.0f), ipf);
+	auto ti = t1.begin_range(delta, size - delta);
+
+	for (size_t z = delta.z; z < size.z - delta.z; ++z)
+		for (size_t y = delta.y; y < size.y - delta.y; ++y)
+			for (size_t x = delta.x; x < size.x - delta.x; ++x, ++ti) {
+				BOOST_CHECK_EQUAL(*ti, C3DFVector(x, y, z));
+			}
+	BOOST_CHECK(ti == t1.end_range(delta, size - delta));
+}
+
+
+Axis1Fixture::Axis1Fixture():
+m_origin(12,23,32), 
+        m_axis(0.7, 0.9, 0.5), 
+        m_size(25, 47, 70), 
+        m_transform(m_size, m_origin / C3DFVector(m_size), m_axis, ipf)
+{
+
+}
+
+void Axis1Fixture::check_transformed_is_same(int idx,  double param, const C3DFVector& v)
+{
+        check_transformed_is_expected(idx, param, v, v); 
+}
+
+
+void Axis1Fixture::check_transformed_is_expected(int idx, double param, 
+						 const C3DFVector& v, const C3DFVector& expect)
+{
+        cvdebug() << "Check param[" << idx << "] = " << param << " and v = " << v << "\n";
+	CDoubleVector p(1, true); 
+        p[idx] = param; 
+        m_transform.set_parameters(p); 
+
+        auto vt = m_transform(v);
+        
+        BOOST_CHECK_CLOSE(vt.x, expect.x, 0.01); 
+        BOOST_CHECK_CLOSE(vt.y, expect.y, 0.01); 
+        BOOST_CHECK_CLOSE(vt.z, expect.z, 0.01); 
+	
+}
+
+#if 0 
+BOOST_FIXTURE_TEST_CASE (test_invers, ipfFixture)
+{
+	C3DBounds size(10,20, 30); 
+	C3DAxisrotTransformation trans(size, C3DFVector(5,9.0f,17.5f), ipf); 
+
+	auto params = trans.get_parameters(); 
+	BOOST_REQUIRE(params.size()== 1); 
+
+	const float init_matrix[6] = {1,2,3,4, 2,3}; 
+	const float inv_matrix[6]  = { 
+		-4.0f/13.0f, -2.0f/13.0f,  7.0f/13.0f,   6.0f/13.0f, 
+		 1.0f/13.0f,  7.0f/13.0f, -5.0f/13.0f,  -8.0f/13.0f, 
+		 5.0f/13.0f, -4.0f/13.0f,  1.0f/13.0f, -14.0f/13.0f
+	}; 
+	copy(init_matrix, init_matrix+6, params.begin()); 
+
+	
+	trans.set_parameters(params); 
+	
+	unique_ptr<C3DTransformation> inverse( trans.invert()); 
+	BOOST_CHECK_EQUAL(inverse->get_size(), size);
+
+	params = inverse->get_parameters(); 
+	BOOST_REQUIRE(params.size()== 6); 
+	for(int i = 0; i < 6; ++i) 
+		BOOST_CHECK_CLOSE(params[i], inv_matrix[i], 0.1); 
+	
+}
+#endif 
diff --git a/mia/3d/transform/test_nonlinear.cc b/mia/3d/transform/test_nonlinear.cc
new file mode 100644
index 0000000..e4293f2
--- /dev/null
+++ b/mia/3d/transform/test_nonlinear.cc
@@ -0,0 +1,25 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+
+#include "test_spline.cc"
+#include "test_vectorfield.cc"
+
diff --git a/mia/3d/transform/test_raffine.cc b/mia/3d/transform/test_raffine.cc
new file mode 100644
index 0000000..1e5438f
--- /dev/null
+++ b/mia/3d/transform/test_raffine.cc
@@ -0,0 +1,231 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <cmath>
+#include <mia/internal/autotest.hh>
+
+#include <mia/3d/transform/raffine.hh>
+
+NS_MIA_USE
+
+using namespace mia_3dtransform_raffine;
+using namespace std;
+using namespace ::boost;
+using namespace boost::unit_test;
+namespace bfs=boost::filesystem;
+
+struct ipfFixture {
+	ipfFixture():
+		ipf("bspline:d=3", "mirror")
+		{
+		} 
+	C3DInterpolatorFactory ipf; 
+}; 
+
+
+struct Axis1Fixture : public ipfFixture {
+
+        Axis1Fixture(); 
+
+        void check_transformed_is_same(int idx, double param, const C3DFVector& v); 
+
+        void check_transformed_is_expected(int idx, double param, const C3DFVector& v, const C3DFVector& expect); 
+
+        C3DFVector m_origin; 
+        C3DFVector m_axis; 
+        C3DBounds m_size; 
+        C3DRAffineTransformation m_transform; 
+}; 
+
+
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_rotation_is_fixed, Axis1Fixture )
+{
+        check_transformed_is_same(0, 0.0, m_origin); 
+        check_transformed_is_same(0, 1.0, m_origin); 
+        check_transformed_is_same(1, 1.0, m_origin); 
+        check_transformed_is_same(2, 1.0, m_origin); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_rotation_origin_plus_minus_axis_is_same, Axis1Fixture )
+{
+        check_transformed_is_same(0, 1.0, m_origin - m_axis);
+        check_transformed_is_same(0, 1.0, m_origin + m_axis); 
+}
+
+#if 0 
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_scaley_origin_plus_minus_axis_is_same, Axis1Fixture )
+{
+        check_transformed_is_same(1, 1.0, m_origin - m_axis);
+        check_transformed_is_same(1, 1.0, m_origin + m_axis); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_scalez_origin_plus_minus_axis_is_same, Axis1Fixture )
+{
+        check_transformed_is_same(2, 1.0, m_origin - m_axis);
+        check_transformed_is_same(2, 1.0, m_origin + m_axis); 
+}
+#endif 
+
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_sheary_origin_plus_minus_axis_is_same, Axis1Fixture )
+{
+        check_transformed_is_same(1, 1.0, m_origin - m_axis);
+        check_transformed_is_same(1, 1.0, m_origin + m_axis); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_shearz_origin_plus_minus_axis_is_same, Axis1Fixture )
+{
+        check_transformed_is_same(2, 1.0, m_origin - m_axis);
+        check_transformed_is_same(2, 1.0, m_origin + m_axis); 
+}
+
+
+// the test values are evaluated with octave helper programs 
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_rotation, Axis1Fixture )
+{
+	check_transformed_is_expected(0, M_PI/2.0, m_origin +  C3DFVector(-0.5, 0.5, -0.2 ), 
+				      m_origin + C3DFVector(0.3454, 0.08835,  -0.6426));
+}
+
+
+#if 0 
+// note that the scaling parameters are added to the matrix diagonal elements 
+// in order to ensure that zero change is indicated by a zero parameter 
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_scalex, Axis1Fixture )
+{
+	check_transformed_is_expected(1, 1.0, m_origin +  C3DFVector(-0.5, 0.5, -0.2 ), 
+				      m_origin + C3DFVector(-1.041, 0.8729, -0.1131));
+	
+}
+
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_scalez, Axis1Fixture )
+{
+	check_transformed_is_expected(2, 1.0, m_origin +  C3DFVector(-0.5, 0.5, -0.2 ), 
+				      m_origin + C3DFVector(-0.4585, 0.6271, -0.4869));
+	
+}
+#endif 
+
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_sheary, Axis1Fixture )
+{
+	check_transformed_is_expected(1, 1.0, m_origin +  C3DFVector(-0.5, 0.5, -0.2), 
+				      m_origin + C3DFVector( - 0.678, 0.2712, - 0.3271));
+}
+
+BOOST_FIXTURE_TEST_CASE( test_raffine3d_shearz, Axis1Fixture )
+{
+	check_transformed_is_expected(2, 1.0, m_origin +  C3DFVector(-0.5, 0.5, -0.2), 
+				      m_origin + C3DFVector(-0.4131, 0.7663,  -0.8011));
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_affine3d_iterator, ipfFixture )
+{
+	C3DBounds size(10,20,15);
+
+	C3DRAffineTransformation t1(size, C3DFVector(5,9.0f,7.5f), C3DFVector(0,1.0f,1.0f), ipf);
+	C3DRAffineTransformation::const_iterator ti = t1.begin();
+	
+	for (size_t z = 0; z < size.z; ++z)
+		for (size_t y = 0; y < size.y; ++y)
+			for (size_t x = 0; x < size.x; ++x, ++ti) {
+				BOOST_CHECK_EQUAL(*ti, C3DFVector(x, y, z));
+			}
+	
+	BOOST_CHECK(ti == t1.end());
+}
+
+BOOST_FIXTURE_TEST_CASE( test_affine3d_ranged_iterator, ipfFixture)
+{
+	C3DBounds size(10,20,30);
+	C3DBounds delta(1,2,3); 
+
+	C3DRAffineTransformation t1(size, C3DFVector(5,9.0f,15.5f), C3DFVector(0,1.0f,1.0f), ipf);
+	auto ti = t1.begin_range(delta, size - delta);
+
+	for (size_t z = delta.z; z < size.z - delta.z; ++z)
+		for (size_t y = delta.y; y < size.y - delta.y; ++y)
+			for (size_t x = delta.x; x < size.x - delta.x; ++x, ++ti) {
+				BOOST_CHECK_EQUAL(*ti, C3DFVector(x, y, z));
+			}
+	BOOST_CHECK(ti == t1.end_range(delta, size - delta));
+}
+
+
+Axis1Fixture::Axis1Fixture():
+m_origin(12,23,32), 
+        m_axis(0.7, 0.9, 0.5), 
+        m_size(25, 47, 70), 
+        m_transform(m_size, m_origin / C3DFVector(m_size), m_axis, ipf)
+{
+
+}
+
+void Axis1Fixture::check_transformed_is_same(int idx,  double param, const C3DFVector& v)
+{
+        check_transformed_is_expected(idx, param, v, v); 
+}
+
+
+void Axis1Fixture::check_transformed_is_expected(int idx, double param, 
+						 const C3DFVector& v, const C3DFVector& expect)
+{
+        cvdebug() << "Check param[" << idx << "] = " << param << " and v = " << v << "\n";
+	CDoubleVector p(3, true); 
+        p[idx] = param; 
+        m_transform.set_parameters(p); 
+
+        auto vt = m_transform(v);
+        
+        BOOST_CHECK_CLOSE(vt.x, expect.x, 0.01); 
+        BOOST_CHECK_CLOSE(vt.y, expect.y, 0.01); 
+        BOOST_CHECK_CLOSE(vt.z, expect.z, 0.01); 
+	
+}
+
+#if 0 
+BOOST_FIXTURE_TEST_CASE (test_invers, ipfFixture)
+{
+	C3DBounds size(10,20, 30); 
+	C3DRAffineTransformation trans(size, C3DFVector(5,9.0f,17.5f), ipf); 
+
+	auto params = trans.get_parameters(); 
+	BOOST_REQUIRE(params.size()== 3); 
+
+	const float init_matrix[6] = {1,2,3,4, 2,3}; 
+	const float inv_matrix[6]  = { 
+		-4.0f/13.0f, -2.0f/13.0f,  7.0f/13.0f,   6.0f/13.0f, 
+		 1.0f/13.0f,  7.0f/13.0f, -5.0f/13.0f,  -8.0f/13.0f, 
+		 5.0f/13.0f, -4.0f/13.0f,  1.0f/13.0f, -14.0f/13.0f
+	}; 
+	copy(init_matrix, init_matrix+6, params.begin()); 
+
+	
+	trans.set_parameters(params); 
+	
+	unique_ptr<C3DTransformation> inverse( trans.invert()); 
+	BOOST_CHECK_EQUAL(inverse->get_size(), size);
+
+	params = inverse->get_parameters(); 
+	BOOST_REQUIRE(params.size()== 6); 
+	for(int i = 0; i < 6; ++i) 
+		BOOST_CHECK_CLOSE(params[i], inv_matrix[i], 0.1); 
+	
+}
+#endif 
diff --git a/mia/3d/transform/test_rigid.cc b/mia/3d/transform/test_rigid.cc
index e801e6b..1f57fd1 100644
--- a/mia/3d/transform/test_rigid.cc
+++ b/mia/3d/transform/test_rigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,9 +31,6 @@ using namespace ::boost;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem;
 
-
-CSplineKernelTestPath kernel_test_path; 
-
 struct ipfFixture {
 	ipfFixture():
 		ipf("bspline:d=3", "mirror")
diff --git a/mia/3d/transform/test_rotation.cc b/mia/3d/transform/test_rotation.cc
index 6f30d0f..27afded 100644
--- a/mia/3d/transform/test_rotation.cc
+++ b/mia/3d/transform/test_rotation.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,9 +31,6 @@ using namespace ::boost;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem;
 
-
-CSplineKernelTestPath kernel_test_path; 
-
 struct ipfFixture {
 	ipfFixture():
 		ipf("bspline:d=3", "mirror")
diff --git a/mia/3d/transform/test_rotbend.cc b/mia/3d/transform/test_rotbend.cc
new file mode 100644
index 0000000..4ee2b05
--- /dev/null
+++ b/mia/3d/transform/test_rotbend.cc
@@ -0,0 +1,178 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <cmath>
+#include <mia/internal/autotest.hh>
+
+#include <mia/3d/transform/rotbend.hh>
+
+NS_MIA_USE
+
+using namespace mia_3dtransform_rotbend;
+using namespace std;
+using namespace ::boost;
+using namespace boost::unit_test;
+namespace bfs=boost::filesystem;
+
+struct ipfFixture {
+	ipfFixture():
+		ipf("bspline:d=3", "mirror")
+		{
+		} 
+	C3DInterpolatorFactory ipf; 
+}; 
+
+
+struct Axis1Fixture : public ipfFixture {
+
+        Axis1Fixture(); 
+
+        void check_transformed_is_same(int idx, double param, const C3DFVector& v); 
+
+        void check_transformed_is_expected(int idx, double param, const C3DFVector& v, const C3DFVector& expect); 
+
+        C3DFVector m_origin; 
+        C3DBounds m_size; 
+        C3DRotBendTransformation m_transform; 
+}; 
+
+
+BOOST_FIXTURE_TEST_CASE( test_rotbend3d_rotation_is_fixed, Axis1Fixture )
+{
+        check_transformed_is_same(0, 0.0, m_origin); 
+        check_transformed_is_same(0, 1.0, m_origin); 
+        check_transformed_is_same(1, 1.0, m_origin); 
+        check_transformed_is_same(2, 1.0, m_origin); 
+        check_transformed_is_same(3, 1.0, m_origin); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_rotbend3d_x_rotation_origin_plus_minus_some_x_is_same, Axis1Fixture )
+{
+        check_transformed_is_same(0, 1.0, m_origin - C3DFVector(1,0,0));
+        check_transformed_is_same(0, 1.0, m_origin + C3DFVector(1,0,0)); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_rotbend3d_y_rotation_origin_plus_minus_some_y_is_same, Axis1Fixture )
+{
+        check_transformed_is_same(1, 1.0, m_origin - C3DFVector(0, 1, 0));
+        check_transformed_is_same(1, 1.0, m_origin + C3DFVector(0, 1, 0)); 
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_rotbend3d_shear_left_origin_plus_minus_y_is_same, Axis1Fixture )
+{
+        check_transformed_is_same(2, 1.0, m_origin - C3DFVector(0, 1, 0));
+        check_transformed_is_same(2, 1.0, m_origin + C3DFVector(0, 1, 0)); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_rotbend3d_shear_right_origin_plus_minus_y_is_same, Axis1Fixture )
+{
+        check_transformed_is_same(3, 1.0, m_origin - C3DFVector(0, 1, 0));
+        check_transformed_is_same(3, 1.0, m_origin + C3DFVector(0, 1, 0)); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_rotbend3d_rotation_y, Axis1Fixture )
+{
+	check_transformed_is_expected(0, M_PI/2.0, m_origin +  C3DFVector(-0.5, 0.5, -0.2 ), 
+				      m_origin + C3DFVector(-0.5, 0.2,  0.5));
+}
+
+BOOST_FIXTURE_TEST_CASE( test_rotbend3d_rotation_x, Axis1Fixture )
+{
+	check_transformed_is_expected(1, M_PI/2.0, m_origin +  C3DFVector(-0.5, 0.5, -0.2 ), 
+				      m_origin + C3DFVector(0.2, 0.5,  -0.5));
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_rotbend3d_bend_left, Axis1Fixture )
+{
+	check_transformed_is_expected(2, 2.0, m_origin +  C3DFVector(1, 2, -0.2), 
+				      m_origin + C3DFVector(1, 2, -0.2 + 2.0/(13*13+1) ));
+}
+
+BOOST_FIXTURE_TEST_CASE( test_rotbend3d__bend_right, Axis1Fixture )
+{
+	check_transformed_is_expected(3, 3.0, m_origin +  C3DFVector(-3, 2, -0.2), 
+				      m_origin + C3DFVector(-3, 2, -0.2 + 27.0 / (12*12+1)));
+}
+
+BOOST_FIXTURE_TEST_CASE( test_affine3d_iterator, ipfFixture )
+{
+	C3DBounds size(10,20,15);
+
+	C3DRotBendTransformation t1(size, C3DFVector(5,9.0f,7.5f), ipf);
+	C3DRotBendTransformation::const_iterator ti = t1.begin();
+	
+	for (size_t z = 0; z < size.z; ++z)
+		for (size_t y = 0; y < size.y; ++y)
+			for (size_t x = 0; x < size.x; ++x, ++ti) {
+				BOOST_CHECK_EQUAL(*ti, C3DFVector(x, y, z));
+			}
+	
+	BOOST_CHECK(ti == t1.end());
+}
+
+BOOST_FIXTURE_TEST_CASE( test_affine3d_ranged_iterator, ipfFixture)
+{
+	C3DBounds size(10,20,30);
+	C3DBounds delta(1,2,3); 
+
+	C3DRotBendTransformation t1(size, C3DFVector(5,9.0f,15.5f), ipf);
+	auto ti = t1.begin_range(delta, size - delta);
+
+	for (size_t z = delta.z; z < size.z - delta.z; ++z)
+		for (size_t y = delta.y; y < size.y - delta.y; ++y)
+			for (size_t x = delta.x; x < size.x - delta.x; ++x, ++ti) {
+				BOOST_CHECK_EQUAL(*ti, C3DFVector(x, y, z));
+			}
+	BOOST_CHECK(ti == t1.end_range(delta, size - delta));
+}
+
+
+Axis1Fixture::Axis1Fixture():
+m_origin(12,23,32), 
+        m_size(25, 47, 70), 
+        m_transform(m_size, m_origin / C3DFVector(m_size), ipf)
+{
+
+}
+
+void Axis1Fixture::check_transformed_is_same(int idx,  double param, const C3DFVector& v)
+{
+        check_transformed_is_expected(idx, param, v, v); 
+}
+
+
+void Axis1Fixture::check_transformed_is_expected(int idx, double param, 
+						 const C3DFVector& v, const C3DFVector& expect)
+{
+        cvdebug() << "Check param[" << idx << "] = " << param << " and v = " << v << "\n";
+	CDoubleVector p(4, true); 
+        p[idx] = param; 
+        m_transform.set_parameters(p); 
+
+        auto vt = m_transform(v);
+        
+        BOOST_CHECK_CLOSE(vt.x, expect.x, 0.01); 
+        BOOST_CHECK_CLOSE(vt.y, expect.y, 0.01); 
+        BOOST_CHECK_CLOSE(vt.z, expect.z, 0.01); 
+	
+}
+
diff --git a/mia/3d/transform/test_spline.cc b/mia/3d/transform/test_spline.cc
index c6015ae..9a27632 100644
--- a/mia/3d/transform/test_spline.cc
+++ b/mia/3d/transform/test_spline.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,7 +20,6 @@
 
 #include <cmath>
 #include <fstream>
-#include <mia/internal/autotest.hh>
 
 #include <mia/core/spacial_kernel.hh>
 #include <mia/3d/interpolator.hh>
@@ -34,8 +33,6 @@ using namespace ::boost;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem;
 
-CSplineKernelTestPath splinekernel_init_path; 
-
 struct ipfFixture {
 	ipfFixture():
 		ipf("bspline:d=3", "mirror")
@@ -1100,29 +1097,6 @@ struct TransformSplineFixtureMixed: public TransformSplineFixtureFieldBase2 {
 	double graddiv2(double x, double y, double z)const;
 };
 
-BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_10_4, TransformSplineFixtureMixed )
-{
-	init(10, 4);
-
-
-	const double testdiv = 7.0 * pow(M_PI, 1.5) / sqrt(2.0); 
-	const double testcurl = testdiv / 4.0; 
-
-	double divval = transform->get_divcurl_cost(1.0, 0.0);
-	BOOST_CHECK_CLOSE( divval, testdiv, 0.1); 	
-
-	
-	double graddivcurl = transform->get_divcurl_cost(1.0, 1.0);
-	BOOST_CHECK_CLOSE( graddivcurl, testdiv + testcurl, 0.1); 	
-	
-
-	double gradcurl = transform->get_divcurl_cost(0.0, 1.0);
-	BOOST_CHECK_CLOSE( gradcurl, testcurl, 0.1); 	
-
-	cvinfo() << "divval  / testdiv= " << divval  / testdiv << "\n"; 
-	cvinfo() << "gradcurl / testcurl = " << gradcurl / testcurl << "\n"; 
-}
-
 double TransformSplineFixtureMixed::fx(double x, double y, double z)const 
 {
 	return x * exp(-x*x-y*y-z*z);
diff --git a/mia/3d/transform/test_translate.cc b/mia/3d/transform/test_translate.cc
index 6e2be08..b9773f3 100644
--- a/mia/3d/transform/test_translate.cc
+++ b/mia/3d/transform/test_translate.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,8 +26,6 @@
 NS_MIA_USE
 using namespace std; 
 
-CSplineKernelTestPath splinekernel_init_path; 
-
 struct ipfFixture {
 	ipfFixture():
 		ipf("bspline:d=3", "mirror")
diff --git a/mia/3d/transform/test_vectorfield.cc b/mia/3d/transform/test_vectorfield.cc
index de024d1..d64ddfb 100644
--- a/mia/3d/transform/test_vectorfield.cc
+++ b/mia/3d/transform/test_vectorfield.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,7 +19,6 @@
  */
 
 #include <cmath>
-#include <mia/internal/plugintester.hh>
 
 #include <mia/core/spacial_kernel.hh>
 #include <mia/3d/transform/vectorfield.hh>
@@ -30,8 +29,6 @@ using namespace std;
 using namespace ::boost;
 using namespace boost::unit_test;
 
-CSplineKernelTestPath kernel_path_init; 
-
 struct GridTransformFixture {
 	GridTransformFixture():
 		size(64, 32, 48),
diff --git a/mia/3d/transform/translate.cc b/mia/3d/transform/translate.cc
index debdb90..3e45ffd 100644
--- a/mia/3d/transform/translate.cc
+++ b/mia/3d/transform/translate.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -226,37 +226,6 @@ C3DFVector C3DTranslateTransformation::transform(const C3DFVector& x)const
 	return x + m_transform;
 }
 
-float C3DTranslateTransformation::divergence() const
-{
-	return 0.0;
-}
-
-float C3DTranslateTransformation::curl() const
-{
-	return 0.0;
-}
-
-float C3DTranslateTransformation::grad_divergence() const
-{
-	return 0.0;
-}
-
-float C3DTranslateTransformation::grad_curl() const
-{
-	return 0.0;
-}
-
-double C3DTranslateTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/, 
-						    CDoubleVector& /*gradient*/) const
-{
-	return 0.0;
-}
-
-double C3DTranslateTransformation::get_divcurl_cost(double /*wd*/, double /*wr*/) const
-{
-	return 0.0;
-}
-
 
 class C3DTranslateTransformCreator: public C3DTransformCreator {
 public: 
diff --git a/mia/3d/transform/translate.hh b/mia/3d/transform/translate.hh
index f71ab1e..7617dac 100644
--- a/mia/3d/transform/translate.hh
+++ b/mia/3d/transform/translate.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -77,12 +77,6 @@ public:
 	virtual C3DFVector operator () (const C3DFVector& x) const;
 	virtual float get_jacobian(const C3DFVectorfield& v, float delta) const;
 	C3DFVector transform(const C3DFVector& x)const;
-	virtual float divergence() const;
-	virtual float curl() const;
-	float grad_divergence() const;
-	float grad_curl() const;
-	virtual double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	virtual double get_divcurl_cost(double wd, double wr) const; 
 	using C3DTransformation::operator ();
 private:
 	virtual C3DTransformation *do_clone() const;
diff --git a/mia/3d/transform/vectorfield.cc b/mia/3d/transform/vectorfield.cc
index 0f28072..59c57c7 100644
--- a/mia/3d/transform/vectorfield.cc
+++ b/mia/3d/transform/vectorfield.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -363,16 +363,6 @@ float C3DGridTransformation::pertuberate(C3DFVectorfield& v) const
 }
 
 
-double C3DGridTransformation::get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const
-{
-	DEBUG_ASSERT_RELEASE_THROW(false, "C3DGridTransformation::get_divcurl_cost not implemented."); 
-}
-
-double C3DGridTransformation::get_divcurl_cost(double wd, double wr) const
-{
-	DEBUG_ASSERT_RELEASE_THROW(false, "C3DGridTransformation::get_divcurl_cost not implemented."); 
-}
-
 
 float C3DGridTransformation::get_jacobian(const C3DFVectorfield& v, float delta) const
 {
@@ -453,11 +443,5 @@ const std::string C3DGridTransformCreatorPlugin::do_get_descr() const
 		"each point of the grid defining the domain of the transformation.";
 }
 
-extern "C" EXPORT CPluginBase *get_plugin_interface()
-{
-	return new C3DGridTransformCreatorPlugin();
-}
-
-
 
 NS_MIA_END
diff --git a/mia/3d/transform/vectorfield.hh b/mia/3d/transform/vectorfield.hh
index 5629026..d5d624b 100644
--- a/mia/3d/transform/vectorfield.hh
+++ b/mia/3d/transform/vectorfield.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -98,9 +98,6 @@ public:
 	virtual float get_jacobian(const C3DFVectorfield& v, float delta) const;
 	C3DFVector operator ()(const  C3DFVector& x) const;
 
-	double get_divcurl_cost(double wd, double wr, CDoubleVector& gradient) const; 
-	double get_divcurl_cost(double wd, double wr) const; 
-
 private:
 	virtual C3DTransformation *do_clone() const;
 	virtual C3DFMatrix field_derivative_at(int x, int y, int z) const;
diff --git a/mia/3d/transformfactory.cc b/mia/3d/transformfactory.cc
index 33ecfbd..0b0e3ce 100644
--- a/mia/3d/transformfactory.cc
+++ b/mia/3d/transformfactory.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,14 +26,6 @@
 
 NS_MIA_BEGIN
 
-C3DTransformCreatorHandlerTestPath::C3DTransformCreatorHandlerTestPath()
-{
-	CPathNameArray kernelsearchpath;
-	kernelsearchpath.push_back(bfs::path(MIA_BUILD_ROOT"/mia/3d/transform"));
-	C3DTransformCreatorHandler::set_search_path(kernelsearchpath);
-}
-
-
 
 template <> const char *  const 
 TPluginHandler<C3DTransformCreatorPlugin>::m_help =  
diff --git a/mia/3d/transformfactory.hh b/mia/3d/transformfactory.hh
index fad5199..c6f372f 100644
--- a/mia/3d/transformfactory.hh
+++ b/mia/3d/transformfactory.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -51,7 +51,7 @@ typedef TTransformCreatorPlugin<C3DTransformation>  C3DTransformCreatorPlugin;
    \brief Transform creator plugin handler 
 */
 typedef THandlerSingleton<TFactoryPluginHandler<C3DTransformCreatorPlugin> > C3DTransformCreatorHandler;
-
+ 
 
 /**
    Create a transformation creator from the given description
@@ -64,19 +64,6 @@ P3DTransformationFactory produce_3dtransform_factory(const std::string& descr)
 	return C3DTransformCreatorHandler::instance().produce(descr); 
 }
 
-/** 
-    @cond INTERNAL 
-    @ingroup test 
-    @brief class to initialize the plug-in path for tests on the uninstalled library 
-*/
-struct EXPORT_3D C3DTransformCreatorHandlerTestPath {
-	C3DTransformCreatorHandlerTestPath(); 
-private: 
-	CSplineKernelTestPath spktp; 
-	CSplineBoundaryConditionTestPath spctp;
-}; 
-/// @endcond
-
 /// @cond NEVER 
 FACTORY_TRAIT(C3DTransformCreatorHandler); 
 /// @endcond
diff --git a/mia/3d/transformio.cc b/mia/3d/transformio.cc
index 3644681..d383acc 100644
--- a/mia/3d/transformio.cc
+++ b/mia/3d/transformio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,16 +28,21 @@
 
 NS_MIA_BEGIN
 
+C3DTransformIOPluginHandlerImpl::C3DTransformIOPluginHandlerImpl()
+{
+	TTranslator<C3DFVector>::register_for(C3DTransformation::input_spacing_attr);
+	TTranslator<C3DFVector>::register_for(C3DTransformation::output_spacing_attr);
+
+}
+
 template <> const char *  const 
 	TPluginHandler<C3DTransformationIO>::m_help =  
        "These plug-ins implement support for loading and saving 3D transformations to various file types.";
 
 
 template class TIOPlugin<C3DTransformation>;
-template class THandlerSingleton<TIOPluginHandler<C3DTransformationIO> >;
+template class THandlerSingleton<C3DTransformIOPluginHandlerImpl>;
 template class TIOPluginHandler<C3DTransformationIO>;
 template class TPluginHandler<C3DTransformationIO>;
 
 NS_MIA_END
-
-
diff --git a/mia/3d/transformio.hh b/mia/3d/transformio.hh
index a123fee..ddb778a 100644
--- a/mia/3d/transformio.hh
+++ b/mia/3d/transformio.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,9 +35,21 @@ typedef TIOPlugin<C3DTransformation> C3DTransformationIO;
 
 /**
    \ingroup io
+   \brief The non-singleton plug-in handler for 3D transformations 
+*/
+
+
+class EXPORT_3D C3DTransformIOPluginHandlerImpl: public TIOPluginHandler<C3DTransformationIO> {
+protected:  
+	C3DTransformIOPluginHandlerImpl(); 
+};
+
+extern template class EXPORT_3D THandlerSingleton< C3DTransformIOPluginHandlerImpl >; 
+/**
+   \ingroup io
    \brief Plug-in handler for the transformation IO plug-ins 
 */
-typedef THandlerSingleton< TIOPluginHandler<C3DTransformationIO> > C3DTransformationIOPluginHandler;
+typedef THandlerSingleton< C3DTransformIOPluginHandlerImpl > C3DTransformationIOPluginHandler;
 
 /**
    \ingroup io
diff --git a/mia/3d/transformmock.cc b/mia/3d/transformmock.cc
index b87152d..cf7f3ec 100644
--- a/mia/3d/transformmock.cc
+++ b/mia/3d/transformmock.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/transformmock.hh b/mia/3d/transformmock.hh
index 25e1ae4..858e5f0 100644
--- a/mia/3d/transformmock.hh
+++ b/mia/3d/transformmock.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/transio/CMakeLists.txt b/mia/3d/transio/CMakeLists.txt
index 9db08ba..df0e651 100644
--- a/mia/3d/transio/CMakeLists.txt
+++ b/mia/3d/transio/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/transio/bbs.cc b/mia/3d/transio/bbs.cc
index 33d6dc1..eb8fe82 100644
--- a/mia/3d/transio/bbs.cc
+++ b/mia/3d/transio/bbs.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/transio/serialization.hh b/mia/3d/transio/serialization.hh
index 05b9ef9..c09b2fe 100644
--- a/mia/3d/transio/serialization.hh
+++ b/mia/3d/transio/serialization.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
 #include <boost/serialization/vector.hpp>
 #include <boost/serialization/string.hpp>
 #include <boost/serialization/version.hpp>
+#include <boost/serialization/map.hpp>
 #include <boost/serialization/split_free.hpp>
 #include <mia/3d/transformfactory.hh>
 
@@ -36,6 +37,13 @@ void save(Archive & ar, const mia::C3DTransformation& t, unsigned int )
 	ar << make_nvp("size_x", t.get_size().x); 
 	ar << make_nvp("size_y", t.get_size().y); 
 	ar << make_nvp("size_z", t.get_size().z); 
+
+	std::map<std::string, std::string> attr; 
+	for (auto i = t.begin_attributes(); i != t.end_attributes(); ++i) {
+		attr.insert(std::make_pair(i->first, i->second->as_string())); 
+	}
+	ar << make_nvp("attributes", attr);
+
 	auto params = t.get_parameters(); 
 	std::vector<double> help(params.size()); 
 	std::copy(params.begin(), params.end(), help.begin()); 
@@ -53,6 +61,10 @@ void load(Archive & ar, mia::P3DTransformation & t, unsigned int )
 	ar >> make_nvp("size_x",size.x); 
 	ar >> make_nvp("size_y",size.y); 
 	ar >> make_nvp("size_z",size.z); 
+
+	std::map<std::string, std::string> attr; 
+	ar >> make_nvp("attributes", attr); 
+
 	ar >> make_nvp("params", help); 
 
 	auto creator = mia::C3DTransformCreatorHandler::instance().produce(init);  
@@ -61,6 +73,11 @@ void load(Archive & ar, mia::P3DTransformation & t, unsigned int )
 	assert(params.size() == help.size()); 
 	std::copy(help.begin(), help.end(), params.begin()); 
 	t->set_parameters(params); 
+
+	for(auto i = attr.begin(); i != attr.end(); ++i) {
+		t->set_attribute(i->first, mia::CStringAttrTranslatorMap::instance().to_attr(i->first, i->second)); 
+	}
+
 }
 
 /*
diff --git a/mia/3d/transio/xml.cc b/mia/3d/transio/xml.cc
index 4793293..c023664 100644
--- a/mia/3d/transio/xml.cc
+++ b/mia/3d/transio/xml.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/valueattributetranslator.hh b/mia/3d/valueattributetranslator.hh
new file mode 100644
index 0000000..c43b065
--- /dev/null
+++ b/mia/3d/valueattributetranslator.hh
@@ -0,0 +1,111 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_3d_valueattributetranslator_hh
+#define mia_3d_valueattributetranslator_hh
+
+#include <mia/core/attributes.hh>
+#include <mia/3d/vector.hh>
+#include <mia/3d/defines3d.hh>
+
+NS_MIA_BEGIN
+
+/**
+   @ingroup basic 
+   @brief a translater for 3D vectors to and from a std::string
+*/
+template <typename T>
+class EXPORT_3D C3DValueAttributeTranslator: public CAttrTranslator {
+public:
+	static  bool register_for(const std::string& key);
+private:
+	PAttribute do_from_string(const std::string& value) const;
+};
+
+/**
+   This class is a hack to work around the vista voxel size stringyfied  value. 
+   Normaly one would write "x,y,z" but in vista it is "x y z", which means a different 
+   translator is needed as compared to a T3DVector. 
+   For everything else the T3DVector interpretation is used (based on type_id); 
+   
+
+   @ingroup basic 
+   @brief a 3D vector value used in attributes 
+   @tparam T the data type of the vector elements 
+*/
+template <typename T>
+class EXPORT_3D C3DValueAttribute : public CAttribute {
+public:
+
+	/**
+	   Constructor to initialize the attribute by using a 3D Vector value 
+	   @param value 
+	 */
+	C3DValueAttribute(const T3DVector<T>& value);
+	
+	/// \returns the value of the attribute as 3D vector 
+	operator T3DVector<T>()const;
+
+	/**
+	   Obtain a run-time unique type description of the value type 
+	   @returns the typeid of the T3DVector<T>
+	 */
+	const char *typedescr() const	{
+		return typeid(T3DVector<T>).name();
+	}
+	
+	// 
+	int type_id() const {
+		return 	 attribute_type<T3DVector<T>>::value; 
+	}
+private:
+	std::string do_as_string() const;
+	bool do_is_equal(const CAttribute& other) const;
+	bool do_is_less(const CAttribute& other) const;
+	T3DVector<T> m_value;
+};
+
+/**
+   @ingroup basic 
+   @brief a 3D floating point vector used for the voxel size attribute 
+*/
+typedef C3DValueAttribute<float> CVoxelAttribute;
+
+/**
+   @ingroup basic 
+   @brief attribute translator for a 3D floating point vector used for the voxel size
+*/
+typedef C3DValueAttributeTranslator<float> CVoxelAttributeTranslator;
+
+/**
+   @ingroup basic 
+   @brief a 3D integer vector
+*/
+typedef C3DValueAttribute<int> C3DIntAttribute;
+
+/**
+   @ingroup basic 
+   @brief attribute translator for a 3D integer vector
+*/
+typedef C3DValueAttributeTranslator<int> C3DIntAttributeTranslator;
+
+NS_MIA_END
+
+#endif 
diff --git a/mia/3d/vector.hh b/mia/3d/vector.hh
index 578a8a2..6ce25b7 100644
--- a/mia/3d/vector.hh
+++ b/mia/3d/vector.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA 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 +31,8 @@
 
 #include <mia/core/defines.hh>
 #include <mia/core/type_traits.hh>
+#include <mia/core/attributetype.hh>
+#include <mia/3d/defines3d.hh>
 
 NS_MIA_BEGIN
 
@@ -180,6 +182,10 @@ public:
 		return *this;
 	}
 
+	T3DVector operator -() const {
+		return 	T3DVector<T>(-x, -y, -z);
+	}
+
 	/// print out the formatted vector to the stream
 	void write(std::ostream& os)const {
 		os  << x << "," << y << "," << z; 
@@ -278,6 +284,21 @@ public:
 };
 
 
+struct EAttributeType_3d : public EAttributeType {
+	
+	static const int vector_3d_bit = 0x40000; 
+	
+	static bool is_vector3d(int type) {
+		return type & vector_3d_bit; 
+        }
+}; 
+
+template <typename T> 
+struct attribute_type<T3DVector<T>> : public EAttributeType_3d {
+        static const int value = attribute_type<T>::value | vector_3d_bit;
+}; 
+
+
 /// @cond NEVER  
 template <typename T> 
 struct atomic_data<T3DVector<T> > {
@@ -404,7 +425,7 @@ inline const T3DVector<T> operator /(const T3DVector<T>& a,double f)
 template <class T>
 inline const T3DVector<T> operator / (const T3DVector<T>& a, const T3DVector<T>& b)
 {
-	assert(b.x != 0.0 && b.x != 0.0 && b.x != 0.0);
+	assert(b.x != 0.0 && b.y != 0.0 && b.z != 0.0);
 	return T3DVector<T>(a.x/b.x, a.y/b.y, a.z/b.z); 
 }
 
diff --git a/mia/3d/vectorfield.cc b/mia/3d/vectorfield.cc
index 73ba329..d7ca642 100644
--- a/mia/3d/vectorfield.cc
+++ b/mia/3d/vectorfield.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,9 +56,11 @@ EXPORT_3D C3DFVectorfield& operator += (C3DFVectorfield& a, const C3DFVectorfiel
 }
 
 #define INSTANCIATE(TYPE) \
-	template class  EXPORT_3D T3DDatafield<TYPE>;			\
-	template class  EXPORT_3D range3d_iterator<T3DDatafield<TYPE>::iterator>; \
-	template class  EXPORT_3D range3d_iterator<T3DDatafield<TYPE>::const_iterator>; 
+	template class  T3DDatafield<TYPE>;			\
+	template class  range3d_iterator<T3DDatafield<TYPE>::iterator>; \
+	template class  range3d_iterator<T3DDatafield<TYPE>::const_iterator>; \
+	template class  range3d_iterator_with_boundary_flag<T3DDatafield<TYPE>::iterator>; \
+	template class  range3d_iterator_with_boundary_flag<T3DDatafield<TYPE>::const_iterator>; 
 
 #define INSTANCIATE2D(TYPE)						\
 	template class  EXPORT_3D T2DDatafield<TYPE>;			\
@@ -71,8 +73,8 @@ INSTANCIATE2D(C3DDVector);
 
 INSTANCIATE(C3DFVector);
 INSTANCIATE(C3DDVector);
-template class EXPORT_3D T3DVectorfield<C3DFVector>;
-template class EXPORT_3D T3DVectorfield<C3DDVector>;
+template class T3DVectorfield<C3DFVector>;
+template class T3DVectorfield<C3DDVector>;
 
 
 
diff --git a/mia/3d/vectorfield.hh b/mia/3d/vectorfield.hh
index de83251..f2b822e 100644
--- a/mia/3d/vectorfield.hh
+++ b/mia/3d/vectorfield.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,11 +21,14 @@
 #ifndef mia_3d_3dvectorfield_hh
 #define mia_3d_3dvectorfield_hh
 
-#include <mia/core/attributes.hh>
+#include <mia/3d/valueattributetranslator.hh>
 #include <mia/3d/datafield.hh>
 
 NS_MIA_BEGIN
 
+extern template class EXPORT_3D T3DDatafield<C3DFVector>;
+extern template class EXPORT_3D T3DDatafield<C3DDVector>;
+
 /**
    @ingroup basic 
    @brief a 3D vector field 
@@ -36,7 +39,14 @@ NS_MIA_BEGIN
 template <typename T>
 class T3DVectorfield: public T3DDatafield<T>, public CAttributedData {
 public:
-	T3DVectorfield(){};
+	T3DVectorfield()  = default;
+	T3DVectorfield(const T3DVectorfield<T>& org):
+		T3DDatafield<T>(org),
+		CAttributedData(org)
+		{
+		}
+	
+	
 	T3DVectorfield(const C3DBounds& size):
 		T3DDatafield<T>(size) {};
 
@@ -52,7 +62,37 @@ public:
 	{
 	}
 
+	C3DFVector get_voxel_size() const {
+		const PAttribute attr = get_attribute("voxel");
+		if (!attr) {
+			cvinfo() << "T3DVectorfield<T>::get_voxel_size(): "
+				"voxel size not defined, default to <1,1,1>\n";
+			return C3DFVector(1,1,1);
+		}
+
+		const CVoxelAttribute * vs = dynamic_cast<const CVoxelAttribute *>(attr.get());
+		if (!vs){
+			cvinfo() << "T3DImage<T>::get_voxel_size(): voxel size wrong type, "
+				"default to <1,1,1>\n";
+			return C3DFVector(1,1,1);
+		}
+		return *vs;
+	}
+
+	void set_voxel_size(const C3DFVector& voxel){
+		set_attribute("voxel", PAttribute(new CVoxelAttribute(voxel)));
+	}
+
 };
+
+extern template class EXPORT_3D T3DVectorfield<C3DFVector>;
+extern template class EXPORT_3D T3DVectorfield<C3DDVector>;
+extern template class EXPORT_3D range3d_iterator<T3DDatafield<C3DFVector>::iterator>;
+extern template class EXPORT_3D range3d_iterator_with_boundary_flag<T3DDatafield<C3DFVector>::iterator>;
+extern template class EXPORT_3D range3d_iterator<T3DDatafield<C3DFVector>::const_iterator>;
+extern template class EXPORT_3D range3d_iterator_with_boundary_flag<T3DDatafield<C3DFVector>::const_iterator>;
+
+
 /**
    @ingroup basic 
    @brief a 3D field of floating point single accuracy 3D vectors 
diff --git a/mia/3d/vfio.cc b/mia/3d/vfio.cc
index 15dd086..b1cb14d 100644
--- a/mia/3d/vfio.cc
+++ b/mia/3d/vfio.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -60,6 +60,7 @@ template <> const char *  const
 TPluginHandler<C3DVFIOPlugin>::m_help =  
    "These plug-ins implement loading and saving of vector fields to certain file formats.";
 
+template class TPlugin<io_3dvf_data, io_plugin_type>;
 template class TIOPlugin<io_3dvf_data>;
 template class THandlerSingleton<TIOPluginHandler<C3DVFIOPlugin> >;
 template class TIOPluginHandler<C3DVFIOPlugin>;
diff --git a/mia/3d/vfio.hh b/mia/3d/vfio.hh
index 3d145fe..de7bfe1 100644
--- a/mia/3d/vfio.hh
+++ b/mia/3d/vfio.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -65,6 +65,12 @@ struct io_3dvf_data {
 */
 typedef TIOPlugin<io_3dvf_data> C3DVFIOPlugin;
 
+template <> const char *  const TPluginHandler<C3DVFIOPlugin>::m_help; 
+
+extern template class EXPORT_3D TPlugin<io_3dvf_data, io_plugin_type>;
+extern template class EXPORT_3D TIOPlugin<io_3dvf_data>;
+extern template class EXPORT_3D TIOPluginHandler<C3DVFIOPlugin>; 
+extern template class EXPORT_3D THandlerSingleton<TIOPluginHandler<C3DVFIOPlugin> >; 
 /**
    @ingroup io 
    @brief Plug-in handler for vector field IO 
diff --git a/mia/3d/vfiotest.cc b/mia/3d/vfiotest.cc
index 25541a3..ba18e62 100644
--- a/mia/3d/vfiotest.cc
+++ b/mia/3d/vfiotest.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/3d/vfiotest.hh b/mia/3d/vfiotest.hh
index a090fa9..4bb3405 100644
--- a/mia/3d/vfiotest.hh
+++ b/mia/3d/vfiotest.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/CMakeLists.txt b/mia/CMakeLists.txt
index 776dff0..5a7d79b 100644
--- a/mia/CMakeLists.txt
+++ b/mia/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/core.hh b/mia/core.hh
index 6c6c634..3a10e60 100644
--- a/mia/core.hh
+++ b/mia/core.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,8 +36,6 @@
 #include <mia/core/optparam.hh>
 #include <mia/core/spacial_kernel.hh>
 #include <mia/core/streamredir.hh>
-#include <mia/core/testplugin.hh>
 #include <mia/core/watch.hh>
 
-
 #endif
diff --git a/mia/core/CMakeLists.txt b/mia/core/CMakeLists.txt
index a3befe6..ea13993 100644
--- a/mia/core/CMakeLists.txt
+++ b/mia/core/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
 
 SET(MIACORE_SRC_BASE 
   attributes.cc 
+  attribute_names.cc 
   boundary_conditions.cc
   callback.cc 
   cost.cc 
@@ -52,6 +53,7 @@ SET(MIACORE_SRC_BASE
   module.cc
   msgstream.cc 
   minimizer.cc
+  nccsum.cc 
   noisegen.cc 
   optionparser.cc 
   optparam.cc 
@@ -84,12 +86,15 @@ SET(MIACORE_SRC_BASE
 
 SET(MIACORE_HEADER_BASE
   attributes.hh
+  attribute_names.hh 
+  attributetype.hh
   boundary_conditions.hh
   bfsv23dispatch.hh
   callback.hh
   cmdbooloption.hh
   cmdlineparser.hh
   cmdoption.hh
+  cmdoptionflags.hh
   cmdstringoption.hh
   combiner.hh
   cost.hh
@@ -122,7 +127,6 @@ SET(MIACORE_HEADER_BASE
   history.hh
   histogram.hh
   index.hh
-  splinekernel.hh
   import_handler.hh
   iodata.hh
   iohandler.cxx iohandler.hh
@@ -135,6 +139,7 @@ SET(MIACORE_HEADER_BASE
   msgstream.hh
   minimizer.hh
   noisegen.hh
+  nccsum.hh
   optionparser.hh
   optparam.hh
   parameter.cxx parameter.hh
@@ -150,15 +155,18 @@ SET(MIACORE_HEADER_BASE
   scaler1d.hh
   shape.hh shape.cxx
   seriesstats.hh
+  singular_refobj.hh
   slopestatistics.hh
   slopeclassifier.hh
   slopevector.hh
+  splinekernel.hh
   splineparzenmi.hh
   spacial_kernel.hh
   sparse_solver.hh
   sqmin.hh
   statistics.hh
   streamredir.hh
+  svector.hh
   testplugin.hh
   threadedmsg.hh
   tools.hh
@@ -278,6 +286,7 @@ NEW_TEST(Vector miacore)
 NEW_TEST(attributes miacore)
 NEW_TEST(boundary_conditions  miacore)
 NEW_TEST(callback miacore)
+NEW_TEST(cmdoptionflags miacore)
 NEW_TEST(cmdlineparser miacore)
 NEW_TEST(datapool miacore)
 NEW_TEST(delayedparameter miacore)
@@ -296,10 +305,12 @@ NEW_TEST(iohandler miacore)
 NEW_TEST(kmeans miacore)
 NEW_TEST(labelmap miacore)
 NEW_TEST(meanvar  miacore)
+NEW_TEST(nccsum  miacore)
 NEW_TEST(productcache  miacore)
 NEW_TEST(property_flags  miacore)
 NEW_TEST(scaler1d miacore)
 NEW_TEST(seriesstats miacore)
+NEW_TEST(singular_refobj miacore)
 NEW_TEST(shape miacore)
 NEW_TEST(simpson miacore)
 NEW_TEST(slopeclassifier miacore)
@@ -307,6 +318,7 @@ NEW_TEST(slopestatistics miacore)
 NEW_TEST(sparse_solver miacore)
 NEW_TEST(splinekernel miacore)
 NEW_TEST(splineparzenmi miacore)
+NEW_TEST(streamvector miacore)
 NEW_TEST(statistics miacore)
 NEW_TEST(threadedmsg miacore)
 NEW_TEST(tools miacore)
diff --git a/mia/core/attribute_names.cc b/mia/core/attribute_names.cc
new file mode 100644
index 0000000..db535f8
--- /dev/null
+++ b/mia/core/attribute_names.cc
@@ -0,0 +1,66 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/attribute_names.hh>
+
+NS_MIA_BEGIN
+
+
+EXPORT_CORE const char * IDAcquisitionDate =   "AcquisitionDate";
+EXPORT_CORE const char * IDImageType =         "ImageType";
+EXPORT_CORE const char * IDAcquisitionNumber = "AcquisitionNumber";
+EXPORT_CORE const char * IDInstanceNumber =    "InstanceNumber";
+EXPORT_CORE const char * IDSliceLocation = "SliceLocation";
+EXPORT_CORE const char * IDSeriesNumber = "SeriesNumber";
+EXPORT_CORE const char * IDModality =          "Modality";
+EXPORT_CORE const char * IDPatientOrientation ="PatientOrientation";
+EXPORT_CORE const char * IDPatientPosition = "PatientPosition";
+EXPORT_CORE const char * IDSmallestImagePixelValue = "SmallestImagePixelValue";
+EXPORT_CORE const char * IDLargestImagePixelValue = "LargestImagePixelValue";
+EXPORT_CORE const char * IDStudyID = "StudyID";
+EXPORT_CORE const char * IDProtocolName = "ProtocolName"; 
+
+EXPORT_CORE const char * IDMediaStorageSOPClassUID= "MediaStorageSOPClassUID";
+EXPORT_CORE const char * IDStudyDescription = "StudyDescription";
+EXPORT_CORE const char * IDSamplesPerPixel = "IDSamplesPerPixel";
+EXPORT_CORE const char * IDSeriesDescription = "SeriesDescription";
+
+EXPORT_CORE const char * IDTestValue = "TestValue";
+EXPORT_CORE const char * IDTransferSyntaxUID = "TransferSyntaxUID";
+EXPORT_CORE const char * IDSOPClassUID = "SOPClassUID";
+
+
+EXPORT_CORE const char * IDAcquisitionTime = "AcquisitionTime";
+
+EXPORT_CORE const char * IDPositionerPrimaryAngle = "PositionerPrimaryAngle"; 
+EXPORT_CORE const char * IDPositionerSecondaryAngle = "PositionerSecondaryAngle"; 
+EXPORT_CORE const char * IDImagerPixelSpacing = "ImagerPixelSpacing"; 
+EXPORT_CORE const char * IDDistanceSourceToDetector = "DistanceSourceToDetector"; 
+EXPORT_CORE const char * IDDistanceSourceToPatient = "DistanceSourceToPatient"; 
+EXPORT_CORE const char * IDPixelIntensityRelationship = "PixelIntensityRelationship"; 
+
+EXPORT_CORE const char * IDPositionerPrimaryAngleIncrement = "PositionerPrimaryAngleIncrement"; 
+EXPORT_CORE const char * IDPositionerSecondaryAngleIncrement = "PositionerSecondaryAngleIncrement"; 
+EXPORT_CORE const char * IDSliceThickness = "SliceThickness"; 
+EXPORT_CORE const char * IDPhotometricInterpretation = "PhotometricInterpretation";
+
+EXPORT_CORE const char * IDAttrPixelSizeIsImager = "PixelSizeIsImagerSize"; 
+
+NS_MIA_END
diff --git a/mia/core/attribute_names.hh b/mia/core/attribute_names.hh
new file mode 100644
index 0000000..e35e24a
--- /dev/null
+++ b/mia/core/attribute_names.hh
@@ -0,0 +1,71 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_core_attribute_names_hh
+#define mia_core_attribute_names_hh
+
+#include <mia/core/defines.hh>
+
+NS_MIA_BEGIN
+
+/**
+   some DICOM tags that may be used 
+   \cond DICOM_TAGS 
+ */
+extern EXPORT_CORE const char * IDModality;
+extern EXPORT_CORE const char * IDPatientOrientation;
+extern EXPORT_CORE const char * IDPatientPosition;
+extern EXPORT_CORE const char * IDAcquisitionDate;
+extern EXPORT_CORE const char * IDAcquisitionNumber;
+extern EXPORT_CORE const char * IDImageType;
+extern EXPORT_CORE const char * IDInstanceNumber;
+
+extern EXPORT_CORE const char * IDSeriesNumber;
+extern EXPORT_CORE const char * IDSliceLocation;
+extern EXPORT_CORE const char * IDStudyID;
+extern EXPORT_CORE const char * IDSmallestImagePixelValue;
+extern EXPORT_CORE const char * IDLargestImagePixelValue;
+extern EXPORT_CORE const char * IDProtocolName; 
+
+
+extern EXPORT_CORE const char * IDMediaStorageSOPClassUID;
+extern EXPORT_CORE const char * IDStudyDescription;
+extern EXPORT_CORE const char * IDSeriesDescription;
+extern EXPORT_CORE const char * IDSamplesPerPixel;
+extern EXPORT_CORE const char * IDTestValue;
+extern EXPORT_CORE const char * IDSOPClassUID;
+extern EXPORT_CORE const char * IDAcquisitionTime;
+extern EXPORT_CORE const char * IDPositionerPrimaryAngle; 
+extern EXPORT_CORE const char * IDPositionerSecondaryAngle; 
+extern EXPORT_CORE const char * IDImagerPixelSpacing; 
+extern EXPORT_CORE const char * IDDistanceSourceToDetector; 
+extern EXPORT_CORE const char * IDDistanceSourceToPatient; 
+extern EXPORT_CORE const char * IDPixelIntensityRelationship;
+extern EXPORT_CORE const char * IDPositionerPrimaryAngleIncrement; 
+extern EXPORT_CORE const char * IDPositionerSecondaryAngleIncrement; 
+extern EXPORT_CORE const char * IDSliceThickness; 
+extern EXPORT_CORE const char * IDPhotometricInterpretation; 
+
+extern EXPORT_CORE const char * IDAttrPixelSizeIsImager; 
+/// @endcond 
+
+NS_MIA_END
+
+#endif 
diff --git a/mia/core/attributes.cc b/mia/core/attributes.cc
index 4c04105..35718a2 100644
--- a/mia/core/attributes.cc
+++ b/mia/core/attributes.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -128,6 +128,11 @@ void CAttributedData::set_attribute(const std::string& name, const std::string&
 	set_attribute(name, attr);
 }
 
+void CAttributedData::set_attribute(const std::string& key, const char* value)
+{
+	set_attribute(key, string(value)); 
+}
+
 const string CAttributedData::get_attribute_as_string(const std::string& name)const
 {
 	CAttributeMap::const_iterator i = m_attr->find(name);
@@ -152,22 +157,23 @@ CStringAttrTranslatorMap::CStringAttrTranslatorMap()
 }
 
 
-void CStringAttrTranslatorMap::add(const string& key, const CAttrTranslator* const t)
+bool CStringAttrTranslatorMap::add(const string& key, CAttrTranslator* t)
 {
 	CMap::const_iterator k = m_translators.find(key);
 	if ( k != m_translators.end()) {
 		if ( typeid(*t) != typeid(*k->second))
 			throw invalid_argument(string("translator with key '") + key + ("' already defined otherwise"));
 		else
-			return;
+			return false;
 	}
 	cvdebug() << "add translator type '" << typeid(*t).name() << "' for '" << key << "'\n";
-	m_translators.insert(pair<string, const CAttrTranslator* const>(key,t));
+	m_translators.insert(make_pair(key,shared_ptr<CAttrTranslator>(t))); 
+	return true;
 }
 
 PAttribute CStringAttrTranslatorMap::to_attr(const string& key, const string& value) const
 {
-	map<string, const CAttrTranslator * const>::const_iterator i = m_translators.find(key);
+	auto i = m_translators.find(key);
 	if ( i != m_translators.end())
 		return i->second->from_string(value);
 	else
@@ -189,9 +195,9 @@ CAttrTranslator::CAttrTranslator()
 {
 }
 
-void CAttrTranslator::do_register(const std::string& key)
+bool CAttrTranslator::do_register(const std::string& key)
 {
-	CStringAttrTranslatorMap::instance().add(key, this);
+	return CStringAttrTranslatorMap::instance().add(key, this);
 }
 
 bool operator == (const CAttributeMap& am, const CAttributeMap& bm)
@@ -211,7 +217,9 @@ bool operator == (const CAttributeMap& am, const CAttributeMap& bm)
 		}
 
 		if (!ai->second->is_equal(*bi->second)) {
-			cvdebug() << "Attribute '"<< ai->first << "' has a different value\n";
+			cvdebug() << "Attribute '"<< ai->first << "' has a different value: '"
+				  << ai->second->as_string() << "', expect '" <<  bi->second->as_string()
+				  << "'\n";
 			return false;
 		}
 
@@ -224,13 +232,6 @@ bool EXPORT_CORE operator == (const CAttributedData& a, const CAttributedData& b
 	return  *a.m_attr == *b.m_attr;
 }
 
-template <>
-void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& name, const char * value)
-{
-	cvdebug() << "add attribute (instance) " << name << " of type 'const char*' and value '" << value << "'\n";
-	attributes[name] = PAttribute(new TAttribute<string>(value));
-}
-
 
 template class EXPORT_CORE  TTranslator<double>;
 template class EXPORT_CORE  TTranslator<std::vector<double> >;
diff --git a/mia/core/attributes.hh b/mia/core/attributes.hh
index bcbe088..22cb46e 100644
--- a/mia/core/attributes.hh
+++ b/mia/core/attributes.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@
 #include <stdexcept>
 #include <boost/any.hpp>
 #include <boost/ref.hpp>
-#include <mia/core/defines.hh>
+#include <mia/core/attributetype.hh>
 
 NS_MIA_BEGIN
 
@@ -65,10 +65,13 @@ public:
 	    \a do_is_less
 
 	 */
-	bool is_less(const CAttribute& other) const;
+	bool is_less(const CAttribute& other) const; 
 
 	/// \returns a descriptive name of the type
 	virtual const char *typedescr() const = 0;
+
+	/// \returns a  type is
+	virtual int type_id() const = 0; 
 private:
 	virtual std::string do_as_string() const = 0;
 
@@ -89,21 +92,10 @@ inline bool operator == (const CAttribute& a, const CAttribute& b)
 	return a.is_equal(b);
 }
 
-inline bool operator < (const CAttribute& a, const CAttribute& b)
-{
-	return a.is_less(b);
-}
 
 /// define the shared pointer wrapped attribute pointer
 typedef std::shared_ptr<CAttribute > PAttribute;
 
-struct pattr_less {
-	bool operator () (PAttribute const& a, PAttribute const& b)
-	{
-		return *a < *b;
-	}
-};
-
 /** 
    \ingroup basic
 
@@ -138,6 +130,8 @@ public:
 
 	/// \returns typeid(T).name(), and is, therefore, dependend on the compiler
 	virtual const char *typedescr() const;
+
+	virtual int type_id() const; 
 protected:
 	/// @returns the value of the attribute 
 	const T& get_value() const;
@@ -219,6 +213,12 @@ typedef TAttribute<std::vector<std::string> > CVStringAttribute;
 */
 typedef std::map<std::string, PAttribute> CAttributeMap;
 
+template <> 
+struct attribute_type<CAttributeMap> : public EAttributeType { 
+        static const int value = 1000;
+}; 
+
+
 /** 
     \ingroup basic 
     \brief providing the possibility to nest attribute lists
@@ -308,6 +308,24 @@ public:
 	 */
 	void set_attribute(const std::string& key, const std::string& value);
 
+
+        /**
+	   Set an attribute, generic version.  
+	   \tparam T type of the attribute value to be set 
+	   \param key
+	   \param value
+	 */
+	template <typename T> 
+	void set_attribute(const std::string& key, const T& value);
+
+	/**
+	   Set an attribute using one of the defined translators
+	   \param key
+	   \param value
+	 */
+	void set_attribute(const std::string& key, const char* value);
+
+	
 	/// returns the requested attribute as string, returns an empty string if attribute doesn't exist
 	const std::string get_attribute_as_string(const std::string& key)const;
 
@@ -323,6 +341,17 @@ public:
 	const T get_attribute_as(const std::string& key)const;
 
 	/**
+	   Look for a certain attribute and try to cast it to the output type. 
+	   If the attribute is not found, or the cast goes wrong use the default value
+	   In the latter case a warning is written out. 
+	   @param key the key of the attribute to look up. 
+	   @param default_value the default value 
+	   @returns the value of the attribute 
+	*/
+	template <typename T>
+	const T get_attribute_as(const std::string& key, T default_value)const;
+
+	/**
 	   Delete the attribute with a given key from the list 
 	   @param key 
 	 */
@@ -339,11 +368,22 @@ public:
 	/// @cond FRIENDSDOC
 	friend EXPORT_CORE bool operator == (const CAttributedData& a, const CAttributedData& b);
 	/// @endcond 
+
+	void print(std::ostream& os) const  {
+		os << *m_attr; 
+	}
 private:
 	PAttributeMap m_attr;
 };
 
 
+inline std::ostream& operator << (std::ostream& os, const CAttributedData& data)
+{
+	data.print(os); 
+	return os; 
+}
+
+
 
 /**
    \ingroup basic 
@@ -382,7 +422,7 @@ protected:
 	   Register this translator to handle attributes with the given key 
 	   @param key 
 	 */
-	void do_register(const std::string& key);
+	bool do_register(const std::string& key);
 };
 
 /**
@@ -416,9 +456,9 @@ private:
 	   \param t the translator object
 	 */
 
-	void add(const std::string& key, const CAttrTranslator *  const t);
+	bool add(const std::string& key, CAttrTranslator * t);
 
-	typedef std::map<std::string, const CAttrTranslator *  const> CMap;
+	typedef std::map<std::string, std::shared_ptr<CAttrTranslator>> CMap;
 	CMap m_translators;
 };
 
@@ -441,16 +481,15 @@ void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& key
 	attributes[key] = PAttribute(new TAttribute<T>(value));
 }
 
-/**
-   \ingroup basic 
-   convenience function to set an string attribute from a C-string in an attribute map:
-   \tparam type of the attribute value to be added
-   \param attributes map to set the value in
-   \param key
-   \param value
- */
 template <>
-void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& key, const char * value);
+inline void EXPORT_CORE add_attribute(CAttributeMap& attributes, const std::string& key, const char *value)
+{
+	attributes[key] =  CStringAttrTranslatorMap::instance().to_attr(key, value);
+	cvdebug() << "add_attribute '"  << key
+		  << "' to '" << value << "' of type '"
+		  << attributes[key]->typedescr() << "'\n";
+}
+
 
 
 /** 
@@ -472,7 +511,7 @@ public:
 	   Any translator type can be registered multiple times but keys must be different
 	   if the target translation type is different.
 	 */
-	static  void register_for(const std::string& key);
+	static  bool register_for(const std::string& key);
 private:
 	virtual PAttribute do_from_string(const std::string& value) const;
 };
@@ -504,6 +543,15 @@ const char *TAttribute<T>::typedescr() const
 	return typeid(T).name();
 }
 
+template <typename T>
+int TAttribute<T>::type_id() const
+{
+	static_assert(attribute_type<T>::value != EAttributeType::attr_unknown, 
+		      "You must provide a type specialization for attribute_type<T>"); 
+	
+	return attribute_type<T>::value; 
+}
+
 /**
    @cond INTERNAL 
    @ingroup traits 
@@ -511,6 +559,7 @@ const char *TAttribute<T>::typedescr() const
    A trait to translate between a string and a value  
    \remark this should replace the parameter translation methods 
 */
+
 template <typename T>
 struct dispatch_attr_string {
 	static std::string val2string(const typename ::boost::reference_wrapper<T>::type value) {
@@ -637,6 +686,13 @@ struct dispatch_attr_string<CAttributeMap> {
 
 /// @endcond
 
+template <typename T> 
+void CAttributedData::set_attribute(const std::string& key, const T& value)
+{
+	add_attribute(*m_attr, key, value); 
+}
+
+
 template <typename T>
 std::string TAttribute<T>::do_as_string() const
 {
@@ -666,29 +722,15 @@ bool TAttribute<T>::do_is_less(const CAttribute& other) const
 	return strcmp(typedescr(), other.typedescr()) < 0;
 }
 
-#if 0
 template <typename T>
-TVAttribute<T>::TVAttribute(const std::vector<T>& value):
-	TAttribute<std::vector<T> >(value)
+bool TTranslator<T>::register_for(const std::string& key)
 {
-}
-
-template <typename T>
-bool TVAttribute<T>::do_is_equal(const CAttribute& other) const
-{
-	const TVAttribute<T>* o = dynamic_cast<const TVAttribute<T> *>(&other);
-	if (!o)
-		return false;
-	return o->get_value().size() == this->get_value().size() &&
-		std::equal(this->get_value().begin(), this->get_value().end(), o->get_value().begin());
-};
-#endif
-
-template <typename T>
-void TTranslator<T>::register_for(const std::string& key)
-{
-	static TTranslator<T> me;
-	me.do_register(key);
+	TTranslator<T> * me = new TTranslator<T>();
+	if (!me->do_register(key)) {
+		delete me; 
+		return false; 
+	}
+	return true; 
 }
 
 template <typename T>
@@ -707,6 +749,19 @@ const T CAttributedData::get_attribute_as(const std::string& key)const
 		throw create_exception<std::invalid_argument>("CAttributedData: no attribute '", key, "' found");
 }
 
+template <typename T>
+const T CAttributedData::get_attribute_as(const std::string& key, T default_value)const
+{
+	PAttribute pattr = get_attribute(key);
+	if (!pattr) 
+		return default_value; 
+	auto attr = dynamic_cast<const TAttribute<T> *>(pattr.get());
+	if (!attr) {
+		cvwarn() << "Attribute '" << key << "'exists but is not of the expected type, returning default\n";
+		return default_value; 
+	}
+	return *attr; 
+}
 
 
 typedef TTranslator<double> CDoubleTranslator;
diff --git a/mia/core/attributetype.hh b/mia/core/attributetype.hh
new file mode 100644
index 0000000..afb5766
--- /dev/null
+++ b/mia/core/attributetype.hh
@@ -0,0 +1,101 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_core_attributetype_hh
+#define mia_core_attributetype_hh
+
+#include <vector>
+#include <mia/core/defines.hh>
+#include <miaconfig.h>
+
+
+NS_MIA_BEGIN
+
+struct EAttributeType {
+        static const int attr_unknown =    0; 
+        static const int attr_bool    =    1; 
+        static const int attr_uchar   =    2; 
+        static const int attr_schar   =    3; 
+        static const int attr_ushort  =    4; 
+        static const int attr_sshort  =    5; 
+        static const int attr_uint    =    6; 
+        static const int attr_sint    =    7; 
+        static const int attr_ulong   =    8; 
+        static const int attr_slong   =    9; 
+        static const int attr_float   =   10; 
+        static const int attr_double  =   11; 
+        static const int attr_string  =   12; 
+
+        static const int vector_bit = 0x80000000; 
+
+        static int scalar_type(int type) {
+                return type & scalar_mask; 
+        }; 
+
+        static bool is_vector(int type) {
+                return type & vector_bit; 
+        }
+
+private: 
+        static const int scalar_mask  =0x7FFFFFFF; 
+
+}; 
+
+template <typename T> 
+struct attribute_type : public EAttributeType { 
+        static const int value = EAttributeType::attr_unknown;
+}; 
+
+#define ATTR_TYPEID(T, ID)                                      \
+        template <>                                             \
+        struct attribute_type<T> : public EAttributeType{       \
+                static const int value = ID;  \
+        };
+
+ATTR_TYPEID(bool, attr_bool); 
+ATTR_TYPEID(unsigned char, attr_uchar); 
+ATTR_TYPEID(signed char, attr_schar); 
+
+ATTR_TYPEID(unsigned short, attr_ushort); 
+ATTR_TYPEID(signed short, attr_sshort); 
+
+ATTR_TYPEID(unsigned int, attr_uint); 
+ATTR_TYPEID(signed int, attr_sint); 
+
+#ifdef LONG_64BIT
+ATTR_TYPEID(unsigned long, attr_ulong); 
+ATTR_TYPEID(signed long, attr_slong); 
+#endif
+
+ATTR_TYPEID(float, attr_float); 
+ATTR_TYPEID(double, attr_double); 
+
+ATTR_TYPEID(std::string, attr_string); 
+
+#undef ATTR_TYPEID
+
+template <typename T> 
+struct attribute_type<std::vector<T>> : public EAttributeType{
+        static const int value = attribute_type<T>::value | EAttributeType::vector_bit;
+}; 
+
+NS_MIA_END
+        
+#endif 
diff --git a/mia/core/bfsv23dispatch.hh b/mia/core/bfsv23dispatch.hh
index 75be767..153dbc9 100644
--- a/mia/core/bfsv23dispatch.hh
+++ b/mia/core/bfsv23dispatch.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/boundary_conditions.cc b/mia/core/boundary_conditions.cc
index 3c952c3..d2e867b 100644
--- a/mia/core/boundary_conditions.cc
+++ b/mia/core/boundary_conditions.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -124,13 +124,6 @@ CSplineBoundaryCondition *CSplineBoundaryConditionPlugin::do_create() const
 }
 
 
-using boost::filesystem::path; 
-CSplineBoundaryConditionTestPath::CSplineBoundaryConditionTestPath()
-{
-	CSplineBoundaryConditionPluginHandler::set_search_path({path(MIA_BUILD_ROOT"/mia/core/splinebc")}); 
-	
-}
-
 EXPORT_CORE PSplineBoundaryCondition produce_spline_boundary_condition(const std::string& descr, int width)
 {
 	auto bc = produce_spline_boundary_condition(descr); 
@@ -143,6 +136,7 @@ template<>
 const char * const TPluginHandler<CSplineBoundaryConditionPlugin>::m_help = "These plug-ins provide various boundary "
 			       "conditions for spline based interpolation."; 
 
+
 EXPLICIT_INSTANCE_DERIVED_FACTORY_HANDLER(CSplineBoundaryCondition, CSplineBoundaryConditionPlugin); 
 
 NS_MIA_END
diff --git a/mia/core/boundary_conditions.hh b/mia/core/boundary_conditions.hh
index c042ad7..a866094 100644
--- a/mia/core/boundary_conditions.hh
+++ b/mia/core/boundary_conditions.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -154,11 +154,16 @@ private:
 
 	int m_width; 
 }; 
+
+
+
 /**  \ingroup interpol 
      Pointer type of the boundary conditions. 
 */
 typedef CSplineBoundaryCondition::Pointer PSplineBoundaryCondition; 
 
+extern template class EXPORT_CORE TFactory<CSplineBoundaryCondition>; 
+
 /**  \ingroup interpol 
      \brief Base plugin for spline boundary conditions
 */
@@ -177,25 +182,19 @@ private:
 	int m_width; 
 }; 
 
+
+
 /**
    \ingroup interpol 
    Plugin handler for the creation of spline boundary conditions
 */
 typedef THandlerSingleton<TFactoryPluginHandler<CSplineBoundaryConditionPlugin> > CSplineBoundaryConditionPluginHandler;
 
+extern template class EXPORT_CORE THandlerSingleton<TFactoryPluginHandler<CSplineBoundaryConditionPlugin> >; 
 
 /// make spline boundary conditions parsable by the command line 
 FACTORY_TRAIT(CSplineBoundaryConditionPluginHandler); 
 
-/**   
-      \ingroup tests 
-      Class to set up the plug-in search path for boundary conditions when running tests
-      in the build tree 
-*/
-struct EXPORT_CORE CSplineBoundaryConditionTestPath {
-	CSplineBoundaryConditionTestPath(); 
-}; 
-
 
 /**
    Create a specific instance of a spline interpolation boundary condition. 
diff --git a/mia/core/callback.cc b/mia/core/callback.cc
index 42e3186..52eddc9 100644
--- a/mia/core/callback.cc
+++ b/mia/core/callback.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/callback.hh b/mia/core/callback.hh
index 1c396e7..76e01e6 100644
--- a/mia/core/callback.hh
+++ b/mia/core/callback.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/cmdbooloption.cc b/mia/core/cmdbooloption.cc
index da6ef74..3117072 100644
--- a/mia/core/cmdbooloption.cc
+++ b/mia/core/cmdbooloption.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/cmdbooloption.hh b/mia/core/cmdbooloption.hh
index 57d4b1c..ebc2d36 100644
--- a/mia/core/cmdbooloption.hh
+++ b/mia/core/cmdbooloption.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/cmdlineparser.cc b/mia/core/cmdlineparser.cc
index 8e2d345..138bd1f 100644
--- a/mia/core/cmdlineparser.cc
+++ b/mia/core/cmdlineparser.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
 #include <cstring>
 #include <iostream>
 #include <iomanip>
+#include <fstream>
 #include <map>
 #include <ctype.h>
 #include <stdexcept>
@@ -52,6 +53,7 @@ NS_MIA_BEGIN
 extern char const *get_revision(); 
 
 using std::ostream;
+using std::ofstream;
 using std::ostringstream;
 using std::string;
 using std::invalid_argument; 
@@ -81,7 +83,7 @@ struct CCmdOptionListData {
 	vector<string> remaining;
 
 	bool help;
-	bool help_xml; 
+	string help_xml; 
 	bool usage;
 	bool version; 
 	bool copyright;
@@ -151,14 +153,13 @@ string CCmdOptionListData::set_description_value(EProgramDescriptionEntry entry,
 const char *g_help_optiongroup="Help & Info"; 
 const char *g_default_author = "Gert Wollny"; 
 const char *g_basic_copyright1 = "This software is Copyright (c) "; 
-const char *g_basic_copyright2 = " 1999-2013 Leipzig, Germany and Madrid, Spain. "
+const char *g_basic_copyright2 = " 1999-2014 Leipzig, Germany and Madrid, Spain. "
 	      "It comes with ABSOLUTELY NO WARRANTY and you may redistribute it "
 	      "under the terms of the GNU GENERAL PUBLIC LICENSE Version 3 (or later). "
 	      "For more information run the program with the option '--copyright'.\n"; 
 
 CCmdOptionListData::CCmdOptionListData(const SProgramDescription& description):
 	help(false),
-	help_xml(false), 
 	usage(false),
 	version(false), 
 	copyright(false),
@@ -301,12 +302,7 @@ void CCmdOptionListData::print_help_xml(const char *name_help, const CPluginHand
 			if (opt.get_long_option() == string("help-xml")) 
 				continue; 
 			
-			Element* option = group->add_child("option"); 
-			option->set_attribute("short", to_string<char>(opt.get_short_option()));
-			option->set_attribute("long", opt.get_long_option());
-			option->set_attribute("required", to_string<bool>(opt.is_required())); 
-			option->set_attribute("default", opt.get_value_as_string()); 
-			option->set_child_text(opt.get_long_help_xml(*option, handler_help_map));
+			opt.add_option_xml(*group, handler_help_map); 
 			
 			if (opt.is_required()) {
 				if (opt.get_short_option())
@@ -340,8 +336,10 @@ void CCmdOptionListData::print_help_xml(const char *name_help, const CPluginHand
 	Element* cr = nodeRoot->add_child("Author");
 	cr->set_child_text(m_author); 
 
-	*m_log << doc->write_to_string_formatted();
-	*m_log << "\n"; 
+	ofstream xmlfile(help_xml.c_str());  
+	
+	xmlfile << doc->write_to_string_formatted();
+	xmlfile << "\n"; 
 }
 
 /**
@@ -710,7 +708,7 @@ CCmdOptionList::do_parse(size_t argc, const char *args[], bool has_additional,
 	if (m_impl->help) {
 		m_impl->print_help(name_help, has_additional);
 		return hr_help;
-	}else if (m_impl->help_xml) {
+	}else if (!m_impl->help_xml.empty()) {
 		m_impl->print_help_xml(name_help, additional_help);
 		return hr_help_xml;
 	} else if (m_impl->usage) {
@@ -779,7 +777,7 @@ CHistoryRecord CCmdOptionList::get_values() const
 }
 
 CHelpOption::CHelpOption(Callback *cb, char short_opt, const char *long_opt, const char *long_help):
-	CCmdOption(short_opt, long_opt, long_help, NULL, false), 
+	CCmdOption(short_opt, long_opt, long_help, NULL, CCmdOptionFlags::none), 
 	m_callback(cb)
 {
 }
@@ -817,7 +815,7 @@ void CHelpOption::do_write_value(std::ostream& /*os*/) const
 CCmdFlagOption::CCmdFlagOption(int& val, const CFlagString& map, char short_opt, 
 			       const char *long_opt, const char *long_help, 
 			       const char *short_help, 
-			       bool flags):
+			       CCmdOptionFlags flags):
 	CCmdOption(short_opt, long_opt, long_help,short_help, flags),
 	m_value(val),
 	m_map(map)
@@ -853,7 +851,7 @@ size_t CCmdFlagOption::do_get_needed_args() const
 
 PCmdOption EXPORT_CORE make_opt(int& value, const CFlagString& map, const char *long_opt, 
 				char short_opt,const char *long_help, 
-				const char *short_help, bool flags)
+				const char *short_help, CCmdOptionFlags flags)
 {
 	return PCmdOption(new CCmdFlagOption(value, map, short_opt, long_opt,
                           long_help, short_help, flags ));
@@ -867,10 +865,10 @@ PCmdOption EXPORT_CORE make_help_opt(const char *long_opt, char short_opt,
 }
 
 PCmdOption EXPORT_CORE make_opt(std::string& value, const char *long_opt, char short_opt, const char *long_help, 
-				bool required, const CPluginHandlerBase *plugin_hint)
+				CCmdOptionFlags flags, const CPluginHandlerBase *plugin_hint)
 {
 	return PCmdOption(new CCmdStringOption(value, short_opt, long_opt, long_help, 
-					       required, plugin_hint)); 
+					       flags, plugin_hint)); 
 }
 
 PCmdOption EXPORT_CORE make_opt(bool& value, const char *long_opt, char short_opt, const char *help)
diff --git a/mia/core/cmdlineparser.hh b/mia/core/cmdlineparser.hh
index 41e7a88..773d5ef 100644
--- a/mia/core/cmdlineparser.hh
+++ b/mia/core/cmdlineparser.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -114,7 +114,7 @@ public:
 	    \param flags support options like required 
         */
 	TCmdOption(T& val, char short_opt, const char *long_opt, const char *long_help,
-                   const char *short_help, bool flags = false);
+                   const char *short_help, CCmdOptionFlags flags = CCmdOptionFlags::none);
 
 private:
 	virtual void do_get_long_help_xml(std::ostream& os, xmlpp::Element& parent, HandlerHelpMap& handler_map) const; 
@@ -144,7 +144,8 @@ public:
 	    the option is really set
 	*/
 	CCmdFlagOption(int& val, const CFlagString& map, char short_opt, const char *long_opt,
-                       const char *long_help, const char *short_help, bool flags = false);
+                       const char *long_help, const char *short_help, 
+		       CCmdOptionFlags flags  = CCmdOptionFlags::none);
 private:
 	virtual bool do_set_value(const char *str_value);
 	virtual size_t do_get_needed_args() const;
@@ -534,7 +535,8 @@ struct __dispatch_opt<std::string> {
 //
 template <typename T>
 TCmdOption<T>::TCmdOption(T& val, char short_opt, const char *long_opt, 
-			  const char *long_help, const char *short_help, bool flags):
+			  const char *long_help, const char *short_help, 
+			  CCmdOptionFlags flags):
         CCmdOption(short_opt, long_opt, long_help, short_help, flags),
         m_value(val)
 {
@@ -591,9 +593,10 @@ const std::string TCmdOption<T>::do_get_value_as_string() const
 */
 template <typename T>
 PCmdOption make_opt(T& value, const char *long_opt, char short_opt, 
-		    const char *help, bool flags = false)
+		    const char *help, CCmdOptionFlags flags = CCmdOptionFlags::none)
 {
-	return PCmdOption(new CParamOption( short_opt, long_opt, new CTParameter<T>(value, flags, help))); 
+	bool required = has_flag(flags, CCmdOptionFlags::required); 
+	return PCmdOption(new CParamOption( short_opt, long_opt, new CTParameter<T>(value, required, help))); 
 }
 
 /**
@@ -615,10 +618,11 @@ PCmdOption make_opt(T& value, const char *long_opt, char short_opt,
 */
 template <typename T, typename Tmin, typename Tmax>
 PCmdOption make_opt(T& value, Tmin min, Tmax max,  const char *long_opt, char short_opt, 
-		    const char *help, bool flags = false)
+		    const char *help, CCmdOptionFlags flags = CCmdOptionFlags::none)
 {
+	bool required = has_flag(flags, CCmdOptionFlags::required); 
 	return PCmdOption(new CParamOption( short_opt, long_opt, 
-					    new TRangeParameter<T>(value, min, max, flags, help)));
+					    new TRangeParameter<T>(value, min, max, required, help)));
 }
 
 /**
@@ -633,17 +637,17 @@ PCmdOption make_opt(T& value, Tmin min, Tmax max,  const char *long_opt, char sh
    \param long_opt long option name (must not be NULL)
    \param short_opt short option name (or 0)
    \param help help string (must not be NULL)
-   \param required  set to true if the option is required to be set 
+   \param flags option flags indicating whether the option is required 
    \remark be aware that localization of the decimal separator of floating point values is not supported, 
    it is always the full stop ".". 
 */
 
 template <typename T>
 PCmdOption make_opt(std::vector<T>& value, const char *long_opt, char short_opt, 
-		    const char *help, bool required = false)
+		    const char *help, CCmdOptionFlags flags = CCmdOptionFlags::none)
 {
 	return PCmdOption(new TCmdOption<std::vector<T> >(value, short_opt, long_opt, help, 
-							  long_opt, required ));
+							  long_opt, flags ));
 }
 
 /**
@@ -704,7 +708,7 @@ PCmdOption make_opt(T& value, const TDictMap<T>& map,
 PCmdOption   make_opt(int& value, const CFlagString& map, const char *long_opt,
 				 char short_opt, const char *long_help, 
 				 const char *short_help, 
-				 bool flags = false);
+				 CCmdOptionFlags flags = CCmdOptionFlags::none);
 
 
 /**
@@ -717,13 +721,13 @@ PCmdOption   make_opt(int& value, const CFlagString& map, const char *long_opt,
    \param long_opt long option name (must not be NULL)
    \param short_opt short option name (or 0)
    \param long_help long help string (must not be NULL)
-   \param required set to true if the option is required to be set 
+   \param flags add flags like whether the optionis required to be set 
    \param plugin_hint if the string will later be used to create an object by using plug-in then pass 
 	   a pointer to the corresponding plug-in handler to give a hint the help system about this connection.
    \returns the option warped into a \a boost::shared_ptr
  */
 PCmdOption  make_opt(std::string& value, const char *long_opt, char short_opt, const char *long_help, 
-				bool required = false, const CPluginHandlerBase *plugin_hint = NULL); 
+		     CCmdOptionFlags flags = CCmdOptionFlags::none, const CPluginHandlerBase *plugin_hint = NULL); 
 
 
 
@@ -739,15 +743,16 @@ PCmdOption  make_opt(std::string& value, const char *long_opt, char short_opt, c
    \param long_opt long option name (must not be NULL)
    \param short_opt short option name (or 0)
    \param help long help string (must not be NULL)
-   \param required set  true if the optionis required to be set 
+   \param flags option flags indicating whether the option is required 
    \returns the option warped into a \a boost::shared_ptr
  */
 template <typename T> 
 PCmdOption  make_opt(T& value, const std::set<T>& valid_set,
-                                const char *long_opt, char short_opt, 
-				const char *help, 
-				bool required = false)
+		     const char *long_opt, char short_opt, 
+		     const char *help, 
+		     CCmdOptionFlags flags = CCmdOptionFlags::none)
 {
+	bool required = has_flag(flags, CCmdOptionFlags::required);
 	return PCmdOption(new CParamOption( short_opt, long_opt, 
 					    new  CSetParameter<T>(value, valid_set, help, required))); 
 }
@@ -767,15 +772,17 @@ PCmdOption  make_opt(T& value, const std::set<T>& valid_set,
    \param long_opt long option name
    \param short_opt short option char, set to 0 of none givn
    \param help the help string for thie option
-   \param required set  true if the optionis required to be set 
+   \param flags indicates whether theoption is required 
    \remark although passing in an initialized pointer and and empty default_value would act like the the initializer string 
    was used for the pointer, it is better to pass an empty shared pointer in order to avoid unnecessary initializations 
    of the pointer is later overwritten.
 */
 template <typename T>
 PCmdOption make_opt(typename std::shared_ptr<T>& value, const char *default_value, const char *long_opt, 
-		    char short_opt,  const char *help, bool required = false)
+		    char short_opt,  const char *help,  
+		    CCmdOptionFlags flags = CCmdOptionFlags::none)
 {
+	bool required = has_flag(flags, CCmdOptionFlags::required);
 	typedef typename FactoryTrait<T>::type F;  
 	return PCmdOption(new CParamOption( short_opt, long_opt, 
 					    new TFactoryParameter<F>(value, default_value, required, help))); 
@@ -794,15 +801,16 @@ PCmdOption make_opt(typename std::shared_ptr<T>& value, const char *default_valu
    \param long_opt long option name
    \param short_opt short option char, set to 0 of none givn
    \param help the help string for thie option
-   \param required set  true if the optionis required to be set 
+   \param flags option flags indicating whether the option is required 
    \remark although passing in an initialized pointer and and empty default_value would act like the the initializer string 
    was used for the pointer, it is better to pass an empty shared pointer in order to avoid unnecessary initializations 
    of the pointer is later overwritten.
 */
 template <typename T>
 PCmdOption make_opt(typename std::unique_ptr<T>& value, const char *default_value, const char *long_opt, 
-		    char short_opt,  const char *help, bool required = false)
+		    char short_opt,  const char *help, CCmdOptionFlags flags = CCmdOptionFlags::none)
 {
+	bool required = has_flag(flags, CCmdOptionFlags::required);
 	typedef typename FactoryTrait<T>::type F;  
 	return PCmdOption(new CParamOption( short_opt, long_opt, 
 					    new TFactoryParameter<F>(value, default_value, required, help))); 
diff --git a/mia/core/cmdoption.cc b/mia/core/cmdoption.cc
index f92d8d6..005b727 100644
--- a/mia/core/cmdoption.cc
+++ b/mia/core/cmdoption.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
 #include <stdexcept>
 #include <mia/core/msgstream.hh>
 #include <mia/core/cmdoption.hh>
+#include <mia/core/tools.hh>
 
 using std::ostream; 
 using std::string; 
@@ -30,16 +31,28 @@ using std::invalid_argument;
 
 NS_MIA_BEGIN
 
-const bool CCmdOption::not_required = false; 
-const bool CCmdOption::required = true; 
-
 CCmdOption::CCmdOption(char short_opt, const char *long_opt, 
 		       const char *long_help, const char *short_help, bool required):
 	m_short_opt(short_opt), 
 	m_long_opt(long_opt),
 	m_long_help(long_help), 
 	m_short_help(short_help),
-	m_flags(required)
+	m_flags(required ? CCmdOptionFlags::required : CCmdOptionFlags::none)
+{
+	TRACE_FUNCTION; 
+	cvdebug() << "Create option '" << long_opt << "'\n"; 
+        assert(long_opt);
+        assert(long_help);
+
+}
+
+CCmdOption::CCmdOption(char short_opt, const char *long_opt, 
+		       const char *long_help, const char *short_help, CCmdOptionFlags flags):
+	m_short_opt(short_opt), 
+	m_long_opt(long_opt),
+	m_long_help(long_help), 
+	m_short_help(short_help),
+	m_flags(flags)
 {
 	TRACE_FUNCTION; 
 	cvdebug() << "Create option '" << long_opt << "'\n"; 
@@ -48,6 +61,7 @@ CCmdOption::CCmdOption(char short_opt, const char *long_opt,
 
 }
 
+
 CCmdOption::~CCmdOption()
 {
 }
@@ -109,12 +123,12 @@ const char *CCmdOption::get_long_option() const
 
 void CCmdOption::clear_required()
 {
-	m_flags = false; 
+	m_flags -= CCmdOptionFlags::required; 
 }
 
 bool CCmdOption::is_required() const
 {
-	return m_flags; 
+	return (m_flags & CCmdOptionFlags::required) == CCmdOptionFlags::required; 
 }
 
 void CCmdOption::get_opt_help(std::ostream& os) const
@@ -196,18 +210,57 @@ void CCmdOption::do_add_option(CShortoptionMap& sm, CLongoptionMap& lm)
 {
 	TRACE_FUNCTION;
 	if (get_short_option() != 0) {
-		assert(sm.find(get_short_option()) == sm.end() &&
-		       "don't add the same short option twice" );
+		auto so = sm.find(get_short_option()); 
+		if ( so != sm.end()) {
+			cverr() << "Trying to add the short option '" << get_short_option() << "' twice\n"; 
+			if (get_long_option()) {
+				if (so->second) 
+					cverr() << "corresponding long options are '" << get_long_option() 
+						<< "' and '"  << so->second->get_long_option() << "'\n";
+			}
+			assert(0 && "don't add the same short option twice" );
+		}
 		sm[get_short_option()] = this;
 	}
 
 	if (get_long_option() != 0) {
-		assert(lm.find(get_long_option()) == lm.end() &&
-		       "don't add the same long option twice");
+		if (lm.find(get_long_option()) != lm.end()) {
+			cverr() << "Trying to add the long option '" << get_long_option() << "' twice\n"; 
+			assert(0 && "don't add the same long option twice");
+		}
 		lm[get_long_option()] = this;
 	}
 }
 
+void CCmdOption::add_option_xml(xmlpp::Element& parent, HandlerHelpMap& handler_map) const
+{
+	TRACE_FUNCTION;
+	auto option = parent.add_child("option"); 
+	option->set_attribute("short", to_string<char>(get_short_option()));
+	option->set_attribute("long", get_long_option());
+	option->set_attribute("required", to_string<bool>(is_required())); 
+	option->set_attribute("default", get_value_as_string()); 
+	
+	auto flagstring = get_flag_string(); 
+	if (!flagstring.empty()) {
+		auto flags = option->add_child("flags"); 
+		flags->set_child_text(flagstring);
+	}
+	option->set_child_text(get_long_help_xml(*option, handler_map));
+}
+
+string CCmdOption::get_flag_string()const 
+{
+	ostringstream ss; 
+        if (mia::has_flag(m_flags, CCmdOptionFlags::input))
+		ss << "input "; 
+        if (mia::has_flag(m_flags, CCmdOptionFlags::output))
+		ss << "output "; 
+        if (mia::has_flag(m_flags, CCmdOptionFlags::required))
+		ss << "required ";
+	return ss.str(); 
+}
+
 void CCmdOption::post_set()
 {
 	do_post_set(); 
@@ -217,4 +270,10 @@ void CCmdOption::do_post_set()
 {
 }
 
+bool CCmdOption::has_flag(CCmdOptionFlags test_flags) const
+{
+        return mia::has_flag(m_flags, test_flags);
+}
+
+
 NS_MIA_END
diff --git a/mia/core/cmdoption.hh b/mia/core/cmdoption.hh
index dce3276..b9adedd 100644
--- a/mia/core/cmdoption.hh
+++ b/mia/core/cmdoption.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@
 #include <string>
 #include <memory>
 #include <iostream>
-#include <mia/core/defines.hh>
+#include <mia/core/cmdoptionflags.hh>
 #include <mia/core/handlerbase.hh>
 #include <libxml++/libxml++.h>
 
@@ -49,12 +49,7 @@ typedef std::map<std::string,  CCmdOption *> CLongoptionMap;
 */
 class EXPORT_CORE CCmdOption  {
 public:
-
-	/// readability constant to show that an option is not required 
-	static const bool not_required; 
 	
-	/// readability constant to show that an option is required 
-	static const bool required; 
 	
         /** The constructor
 	    \param short_opt the short option character 
@@ -64,7 +59,11 @@ public:
 	    \param required set to true if the option must be set by the user 
         */
 	CCmdOption(char short_opt, const char *long_opt, const char *long_help, 
-		   const char *short_help, bool required);
+		   const char *short_help, bool required)__attribute__((deprecated));
+
+	CCmdOption(char short_opt, const char *long_opt, const char *long_help, 
+		   const char *short_help, CCmdOptionFlags flags);
+	
 
         /// ensure virtual destruction
 	virtual ~CCmdOption();
@@ -134,6 +133,14 @@ public:
 	    complex initialization like done for factory based command line parameters 
 	 */
 	void post_set(); 
+
+	/**
+	   Adds the option description to the given parent node and adds
+	   used plug-in handlers to the helper map
+	   \param[in,out] parent the parent xml node to which to add documentation 
+	   \param[in,out] handler_map the map of possibely recoursively called plug-in handlers 
+	*/
+	void add_option_xml(xmlpp::Element& parent, HandlerHelpMap& handler_map) const;
 protected:
 
 	/// clear the "required" flag 
@@ -144,7 +151,10 @@ protected:
 	    \param os the output stream 
 	*/
 	virtual void do_get_long_help(std::ostream& os) const;
+
+	bool has_flag(CCmdOptionFlags test_flags) const; 
 private:
+	std::string get_flag_string() const; 
 	const char *get_short_help() const;
 
 	virtual void do_add_option(CShortoptionMap& sm, CLongoptionMap& lm);
@@ -164,7 +174,7 @@ private:
 	const char *m_long_opt;
 	const char *m_long_help;
 	const char *m_short_help;
-	bool m_flags;
+	CCmdOptionFlags  m_flags;
 };
 
 /// a shared pointer definition of the Option
diff --git a/mia/core/cmdoptionflags.hh b/mia/core/cmdoptionflags.hh
new file mode 100644
index 0000000..3c615c2
--- /dev/null
+++ b/mia/core/cmdoptionflags.hh
@@ -0,0 +1,77 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_core_cmdoption_flags_hh
+#define mia_core_cmdoption_flags_hh
+
+#include <mia/core/defines.hh>
+
+NS_MIA_BEGIN
+
+enum class CCmdOptionFlags : int {
+        none = 0, 
+        required = 1, 
+        input = 2, 
+        output = 4, 
+        required_input = 3, 
+	required_output = 5,
+	validate = 8	
+}; 
+
+inline CCmdOptionFlags operator | (CCmdOptionFlags lhs, CCmdOptionFlags rhs) 
+{
+        return static_cast<CCmdOptionFlags>(  static_cast<int>(lhs) | static_cast<int>(rhs)); 
+}
+
+inline CCmdOptionFlags operator  & (CCmdOptionFlags lhs, CCmdOptionFlags rhs) 
+{
+        return static_cast<CCmdOptionFlags>(  static_cast<int>(lhs) & static_cast<int>(rhs)); 
+}
+
+inline CCmdOptionFlags operator -= (CCmdOptionFlags& lhs, CCmdOptionFlags rhs) 
+{
+        lhs = static_cast<CCmdOptionFlags>(  static_cast<int>(lhs) & ~static_cast<int>(rhs)); 
+        return lhs; 
+}
+
+inline bool has_flag(CCmdOptionFlags flags, CCmdOptionFlags test) 
+{
+	return (flags & test) == test; 
+}
+
+inline std::ostream& operator << (std::ostream& os, CCmdOptionFlags flags) 
+{
+        switch (flags) {
+        case CCmdOptionFlags::none: os << "CCmdOptionFlags::none"; break; 
+        case CCmdOptionFlags::required: os << "CCmdOptionFlags::required"; break; 
+        case CCmdOptionFlags::input: os << "CCmdOptionFlags::input"; break; 
+        case CCmdOptionFlags::output: os << "CCmdOptionFlags::output"; break; 
+        case CCmdOptionFlags::required_input: os << "CCmdOptionFlags::required_input"; break; 
+        case CCmdOptionFlags::required_output: os << "CCmdOptionFlags::required_output"; break; 
+        case CCmdOptionFlags::validate: os << "CCmdOptionFlags::validate"; break; 
+
+        default: os << "CCmdOptionFlags::<undefined>"; 
+        }; 
+        return os; 
+}
+
+NS_MIA_END
+
+#endif 
diff --git a/mia/core/cmdstringoption.cc b/mia/core/cmdstringoption.cc
index afd4457..b112511 100644
--- a/mia/core/cmdstringoption.cc
+++ b/mia/core/cmdstringoption.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,12 +28,12 @@ NS_MIA_BEGIN
 using std::string; 
 
 CCmdStringOption::CCmdStringOption(std::string& value, char short_opt, const char *long_opt, 
-				   const char *long_help, bool required, const CPluginHandlerBase *plugin_hint):
-	CCmdOption(short_opt, long_opt, long_help, long_opt, required), 
+				   const char *long_help,  CCmdOptionFlags flags, const CPluginHandlerBase *plugin_hint):
+	CCmdOption(short_opt, long_opt, long_help, long_opt, flags), 
 	m_value(value), 
 	m_plugin_hint(plugin_hint)
 {
-	if (!value.empty() && required) 
+        if (!value.empty() && mia::has_flag(flags, CCmdOptionFlags::required) )
 		cvwarn() << "CCmdStringOption:option '" << long_opt << "' has a default value '"
 			 << value
 			 <<"' but is also marked as required. This doesn't make mzúch sense."; 
@@ -41,8 +41,11 @@ CCmdStringOption::CCmdStringOption(std::string& value, char short_opt, const cha
 
 bool CCmdStringOption::do_set_value(const char *str_value)
 {
+	bool retval = true; 
 	m_value.assign(str_value); 
-	return true; 
+	if (m_plugin_hint && has_flag(CCmdOptionFlags::validate)) 
+		retval = m_plugin_hint->validate_parameter_string(m_value);  
+	return retval; 
 }
 
 const string CCmdStringOption::do_get_value_as_string() const
diff --git a/mia/core/cmdstringoption.hh b/mia/core/cmdstringoption.hh
index 2ab23c5..d87112f 100644
--- a/mia/core/cmdstringoption.hh
+++ b/mia/core/cmdstringoption.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,12 +44,12 @@ class EXPORT_CORE CCmdStringOption : public CCmdOption {
 	   \param short_opt the one letter command line option 
 	   \param long_opt the long command line option 
 	   \param long_help the full help string that describes the option completely 
-	   \param required  set to true if the parameter must be given by the user 
+	   \param flags CCmdOptionFlags for this option 
 	   \param plugin_hint if the string will later be used to create an object by using plug-in then pass 
 	   a pointer to the corresponding plug-in handler to give a hint the help system about this connection.
 	 */
 	CCmdStringOption(std::string& value, char short_opt, const char *long_opt, const char *long_help, 
-			 bool required, const CPluginHandlerBase *plugin_hint);
+			 CCmdOptionFlags flags, const CPluginHandlerBase *plugin_hint);
  private: 
 	bool do_set_value(const char *str_value);
 	void do_write_value(std::ostream& os) const;
diff --git a/mia/core/combiner.cc b/mia/core/combiner.cc
index 8a37232..8e8e434 100644
--- a/mia/core/combiner.cc
+++ b/mia/core/combiner.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/combiner.hh b/mia/core/combiner.hh
index 0835abd..c968a76 100644
--- a/mia/core/combiner.hh
+++ b/mia/core/combiner.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/cost.cc b/mia/core/cost.cc
index acf245f..506b88b 100644
--- a/mia/core/cost.cc
+++ b/mia/core/cost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,10 +21,12 @@
 #include <mia/core/export_handler.hh>
 
 #include <mia/core/cost.hh>
+#include <mia/template/masked_cost.hh>
 
 NS_MIA_BEGIN
 
 const char *cost_type::type_descr = "cost";
+const char *masked_cost_type::type_descr = "maskedcost";
 
 NS_MIA_END
 
diff --git a/mia/core/cost.cxx b/mia/core/cost.cxx
index 364a2e6..2663212 100644
--- a/mia/core/cost.cxx
+++ b/mia/core/cost.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/cost.hh b/mia/core/cost.hh
index 3f62cc6..c4ccb17 100644
--- a/mia/core/cost.hh
+++ b/mia/core/cost.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -117,6 +117,5 @@ private:
 	PData m_reference; 
 };
 
-
 NS_MIA_END
 #endif
diff --git a/mia/core/creator.cc b/mia/core/creator.cc
index 7774a2e..6a6e68b 100644
--- a/mia/core/creator.cc
+++ b/mia/core/creator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/creator.hh b/mia/core/creator.hh
index c091946..165f53d 100644
--- a/mia/core/creator.hh
+++ b/mia/core/creator.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/cstplan.hh b/mia/core/cstplan.hh
index d2f2523..4f7ba5d 100644
--- a/mia/core/cstplan.hh
+++ b/mia/core/cstplan.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/datapool.cc b/mia/core/datapool.cc
index 873e7db..52eb7d6 100644
--- a/mia/core/datapool.cc
+++ b/mia/core/datapool.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/datapool.hh b/mia/core/datapool.hh
index ea42031..56bfba8 100644
--- a/mia/core/datapool.hh
+++ b/mia/core/datapool.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/defines.hh b/mia/core/defines.hh
index c050c8d..818a0d7 100644
--- a/mia/core/defines.hh
+++ b/mia/core/defines.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -102,7 +102,6 @@ NS_MIA_END
 #define MIA_PARAM_UNUSED(x) x __attribute__((unused))
 #endif 
 
-
 #ifdef miacore_EXPORTS
 /// Macro to manage Visual C++ style dllimport/dllexport 
 #  define EXPORT_CORE DO_EXPORT
diff --git a/mia/core/delayedparameter.hh b/mia/core/delayedparameter.hh
index 66311c7..372418e 100644
--- a/mia/core/delayedparameter.hh
+++ b/mia/core/delayedparameter.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -72,6 +72,8 @@ public:
 	   \returns true if the key is valid 
 	*/
 	bool key_is_valid() const; 
+
+	const std::string& get_key() const;
 private:
 	std::string m_key;
 }; 
@@ -107,6 +109,12 @@ bool TDelayedParameter<T>::key_is_valid() const
 	return !m_key.empty(); 
 }
 
+template <typename T>
+const std::string& TDelayedParameter<T>::get_key() const
+{
+	return m_key; 
+}
+
 NS_MIA_END
 
 #endif
diff --git a/mia/core/dictmap.hh b/mia/core/dictmap.hh
index d5a6d68..9355d92 100644
--- a/mia/core/dictmap.hh
+++ b/mia/core/dictmap.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/distance.cc b/mia/core/distance.cc
index 4e45562..518ac2d 100644
--- a/mia/core/distance.cc
+++ b/mia/core/distance.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/distance.hh b/mia/core/distance.hh
index b6f43f5..1e1eef4 100644
--- a/mia/core/distance.hh
+++ b/mia/core/distance.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/dlloader.cc b/mia/core/dlloader.cc
index dbf713f..600e050 100644
--- a/mia/core/dlloader.cc
+++ b/mia/core/dlloader.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/dlloader.hh b/mia/core/dlloader.hh
index c2b2b02..1d97539 100644
--- a/mia/core/dlloader.hh
+++ b/mia/core/dlloader.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/dummyhandler.cc b/mia/core/dummyhandler.cc
index a4a9b6e..15f1664 100644
--- a/mia/core/dummyhandler.cc
+++ b/mia/core/dummyhandler.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -47,6 +47,8 @@ CTestIOPlugin::CTestIOPlugin(const char *name):
 template<> const char * const 
 TPluginHandler<CTestIOPlugin>::m_help = "These are some dummy plug-ins for IO handler testing."; 
 
+
+template class TPlugin<test_io_data,io_plugin_type>; 
 template class TPluginHandler<CTestIOPlugin>;
 template class TIOPlugin<test_io_data>; 
 template class TIOPluginHandler<CTestIOPlugin>;
diff --git a/mia/core/dummyhandler.hh b/mia/core/dummyhandler.hh
index 01811d2..f427688 100644
--- a/mia/core/dummyhandler.hh
+++ b/mia/core/dummyhandler.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -39,6 +39,9 @@ struct test_io_data {
 	static const char *data_descr;
 };
 
+extern template class EXPORT_CORE TPlugin<test_io_data,io_plugin_type>; 
+extern template class EXPORT_CORE TIOPlugin<test_io_data>; 
+
 
 class EXPORT_CORE CTestIOPlugin : public TIOPlugin<test_io_data> {
 public:
diff --git a/mia/core/errormacro.hh b/mia/core/errormacro.hh
index 409fa59..5dfa42d 100644
--- a/mia/core/errormacro.hh
+++ b/mia/core/errormacro.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/export_handler.hh b/mia/core/export_handler.hh
index 75d98de..8fbc48f 100644
--- a/mia/core/export_handler.hh
+++ b/mia/core/export_handler.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/factory.hh b/mia/core/factory.hh
index c9d850b..51a6f10 100644
--- a/mia/core/factory.hh
+++ b/mia/core/factory.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -149,11 +149,16 @@ private:
 	std::string get_handler_type_string_and_help(std::ostream& os) const; 
 	
 	std::string do_get_handler_type_string() const; 
-	
+
+        virtual bool do_validate_parameter_string(const std::string& s) const;
+
 	typename I::Product *produce_raw(const std::string& plugindescr) const;
 
 	mutable TProductCache<ProductPtr> m_cache; 
 
+	template <typename Handler, typename Chained, bool chainable> 
+		friend struct create_plugin; 
+
 }; 
 
 /*
@@ -240,6 +245,93 @@ std::string TFactoryPluginHandler<I>::do_get_handler_type_string() const
 {
 	return "factory"; 
 }
+
+template <typename  I>
+bool TFactoryPluginHandler<I>::do_validate_parameter_string(const std::string& s) const
+{
+	cvdebug() << "Check whether factory '" << this->get_descriptor() << "' can understand '" << s << "'\n"; 
+        // find the part describing the plug-in name and check whether it
+        // is available
+        auto colon_pos = s.find(':');
+        auto plugin_name = s.substr(0, colon_pos);
+        if (this->plugin(plugin_name.c_str())) 
+                return true;
+        return false;
+}
+
+template <typename Handler, typename Chained, bool chainable> 
+struct create_plugin {
+	typedef typename Handler::Product Product; 
+	static Product *apply(const Handler& h, const CComplexOptionParser& param_list, const std::string& params) {
+		if (param_list.size() > 1) {
+			throw create_exception<std::invalid_argument>( "Factory " , h.get_descriptor(), 
+								       ": No chaining supported but ", param_list.size(), 
+								       " plugin descriptors were given. "
+								       "If the description contains a '+' sign as part "
+								       "of a parameter you must protect it by enclosing the "
+								       "value in square brackets like this: [1e+6]");
+		}
+		
+		cvdebug() << "TFactoryPluginHandler<P>::produce use '" << param_list.begin()->first << "'\n"; 
+		const std::string& factory_name = param_list.begin()->first; 
+		
+		if (factory_name == plugin_help) {
+			cvdebug() << "print help\n"; 
+			cvmsg() << "\n"; 
+			h.print_help(cverb);
+			return nullptr; 
+		}
+		
+		cvdebug() << "TFactoryPluginHandler<>::produce: Create plugin from '" << factory_name << "'\n"; 
+		
+		auto factory = h.plugin(factory_name.c_str());
+		if (!factory) 
+			throw create_exception<std::invalid_argument>("Unable to find plugin for '", factory_name.c_str(), "'");
+		return factory->create(param_list.begin()->second,params.c_str());
+	}
+}; 
+
+template <typename Handler, typename ProductChained> 
+struct create_plugin<Handler, ProductChained, true> {
+	typedef typename Handler::Product Product; 
+	
+	static Product *apply(const Handler& h, const CComplexOptionParser& param_list, const std::string& params) {
+		
+		if (param_list.size() == 1) 
+			return create_plugin<Handler, ProductChained, false>::apply(h, param_list, params); 
+
+		ProductChained *result = new ProductChained();
+		try {
+			for (auto ipl = param_list.begin(); ipl != param_list.end(); ++ipl) {
+				
+				const std::string& factory_name = ipl->first; 
+				cvdebug() << "TFactoryPluginHandler<P>::produce use '" << factory_name << "\n"; 
+				
+				if (factory_name == plugin_help) {
+					cvdebug() << "print help\n"; 
+					cvmsg() << "\n"; 
+					h.print_help(cverb);
+					return nullptr; 
+				}
+				
+				auto factory = h.plugin(factory_name.c_str());
+				if (!factory) {
+					throw create_exception<std::invalid_argument>("Unable to find plugin for '", factory_name.c_str(), "'");
+				}
+				
+				auto r = factory->create(ipl->second,params.c_str());
+				result->push_back(typename Product::Pointer(r)); 
+			}
+			result->set_init_string(params.c_str()); 
+		}
+		catch (std::exception& x) {
+			delete result; 
+			throw x; 
+		}
+		return result; 
+	}
+}; 
+
 	
 template <typename  I>
 typename I::Product *TFactoryPluginHandler<I>::produce_raw(const std::string& params)const
@@ -258,24 +350,10 @@ typename I::Product *TFactoryPluginHandler<I>::produce_raw(const std::string& pa
 		      "Supported plug-ins are '" , this->get_plugin_names() , "'. " 
 		      "Set description to 'help' for more information."); 
 	}
-		
-	cvdebug() << "TFactoryPluginHandler<P>::produce use '" << param_list.begin()->first << "'\n"; 
-	const std::string& factory_name = param_list.begin()->first; 
-	
-	if (factory_name == plugin_help) {
-		cvdebug() << "print help\n"; 
-		cvmsg() << "\n"; 
-		this->print_help(cverb);
-		return NULL; 
-	}
-
-	cvdebug() << "TFactoryPluginHandler<>::produce: Create plugin from '" << factory_name << "'\n"; 
-
-	auto factory = this->plugin(factory_name.c_str());
-	if (!factory) 
-		throw create_exception<std::invalid_argument>("Unable to find plugin for '", factory_name.c_str(), "'");
-	return factory->create(param_list.begin()->second,params.c_str());
 
+	return create_plugin<TFactoryPluginHandler<I>, 
+			     typename plugin_can_chain<I>::Chained, 
+			     plugin_can_chain<I>::value>::apply(*this, param_list, params); 
 }
 
 /**     
diff --git a/mia/core/factory_trait.hh b/mia/core/factory_trait.hh
index 04e8f1c..74f6bb7 100644
--- a/mia/core/factory_trait.hh
+++ b/mia/core/factory_trait.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/fft1d_r2c.cc b/mia/core/fft1d_r2c.cc
index 22c8f1f..46da06a 100644
--- a/mia/core/fft1d_r2c.cc
+++ b/mia/core/fft1d_r2c.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/fft1d_r2c.hh b/mia/core/fft1d_r2c.hh
index 715e725..a3dcacd 100644
--- a/mia/core/fft1d_r2c.hh
+++ b/mia/core/fft1d_r2c.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/fftslopeclassifier.cc b/mia/core/fftslopeclassifier.cc
index 77f28d4..4e6b129 100644
--- a/mia/core/fftslopeclassifier.cc
+++ b/mia/core/fftslopeclassifier.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/fftslopeclassifier.hh b/mia/core/fftslopeclassifier.hh
index 1603e68..a346f77 100644
--- a/mia/core/fftslopeclassifier.hh
+++ b/mia/core/fftslopeclassifier.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/fifofilter.cxx b/mia/core/fifofilter.cxx
index 5583ae3..0a2e6bc 100644
--- a/mia/core/fifofilter.cxx
+++ b/mia/core/fifofilter.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/fifofilter.hh b/mia/core/fifofilter.hh
index 49082e7..f405a3e 100644
--- a/mia/core/fifofilter.hh
+++ b/mia/core/fifofilter.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/file.cc b/mia/core/file.cc
index 992ea42..e2d7e10 100644
--- a/mia/core/file.cc
+++ b/mia/core/file.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -47,10 +47,14 @@ CFile::CFile(const string& filename, bool from_stdio, bool write):
 	string pipe;
 	if (suffix == string(".gz")) {
 		m_is_pipe = true;
-		pipe = (write ? string("gzip >") : string("cat ")) + filename.c_str() + string("| zcat ");
+		pipe = (write ? string("gzip >") : string("zcat ")) + filename.c_str();
 	}else if (suffix == string(".bz2")) {
 		m_is_pipe = true;
 		pipe = (write ? string("bzip2 >") : string("bzcat ")) + filename.c_str();
+	}else if (suffix == string(".xz")) {
+		m_is_pipe = true;
+		pipe = (write ? string("xz >") : string("xzcat ")) + filename.c_str();
+
 	}else if (suffix == string(".Z")) {
 		m_is_pipe = true;
 		pipe = (write ? string("compress >") : string("zcat ")) + filename.c_str();
diff --git a/mia/core/file.hh b/mia/core/file.hh
index 4d7f363..b5b7516 100644
--- a/mia/core/file.hh
+++ b/mia/core/file.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/filetools.cc b/mia/core/filetools.cc
index 072c928..812a03b 100644
--- a/mia/core/filetools.cc
+++ b/mia/core/filetools.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/filetools.hh b/mia/core/filetools.hh
index afface9..c4a2138 100644
--- a/mia/core/filetools.hh
+++ b/mia/core/filetools.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/filter.cc b/mia/core/filter.cc
index 4c927f4..d146173 100644
--- a/mia/core/filter.cc
+++ b/mia/core/filter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/filter.hh b/mia/core/filter.hh
index c4bd201..1c17820 100644
--- a/mia/core/filter.hh
+++ b/mia/core/filter.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -109,11 +109,38 @@ public:
 	   \param pimage must be of a type D that has Binder trait defined. 
 	 */ 
 	result_type filter(std::shared_ptr<D> pimage) const;
+
 private:
 	virtual result_type do_filter(const Image& image) const = 0;
 	virtual result_type do_filter(std::shared_ptr<D> image) const;
+
 };
 
+template <class D>
+class EXPORT_HANDLER TDataFilterChained: public TDataFilter<D> {
+	typedef typename TDataFilter<D>::result_type result_type; 
+public: 
+	typedef typename TDataFilter<D>::Pointer Pointer; 
+	
+	void push_back(Pointer f) {
+		m_chain.push_back(f); 
+	}
+private: 
+	virtual result_type do_filter(const D& image) const {
+		assert(m_chain.size() > 0); 
+		
+		cvdebug() << "Run chained filter '" << m_chain[0]->get_init_string() << "'\n"; 
+		result_type result = m_chain[0]->filter(image); 
+		for(auto f = m_chain.begin() + 1; f != m_chain.end(); ++f)  {
+		cvdebug() << "Run chained filter '" << (*f)->get_init_string() << "'\n"; 
+			result = (*f)->filter(*result); 
+		}
+		return result; 
+	}
+	std::vector<Pointer> m_chain; 
+}; 
+
+
 /**
    \ingroup filtering
 
@@ -135,6 +162,13 @@ public:
 	{}
 };
 
+template <typename D>
+struct plugin_can_chain<TDataFilterPlugin<D>> {
+	static constexpr bool value = true; 
+	typedef TDataFilterChained<D> Chained; 
+}; 
+
+
 /**
    @cond INTERNAL 
    \ingroup traits
@@ -287,6 +321,58 @@ static typename F::result_type accumulate(F& f, const B& data)
 	}
 }
 
+template <typename F, typename INOUT, typename IN>
+static typename F::result_type _combine_inplace(const F& f, INOUT& inout, const IN& in)
+{
+	typedef typename Binder<IN>::Derived D;
+	switch (in.get_pixel_type()) {
+	case it_bit:   return f(inout, DC(typename D::Dbool, in));
+	case it_sbyte: return f(inout, DC(typename D::Dsc, in));
+	case it_ubyte: return f(inout, DC(typename D::Duc, in));
+	case it_sshort:return f(inout, DC(typename D::Dss, in));
+	case it_ushort:return f(inout, DC(typename D::Dus, in));
+	case it_sint:  return f(inout, DC(typename D::Dsi, in));
+	case it_uint:	 return f(inout, DC(typename D::Dui, in));
+#ifdef LONG_64BIT
+	case it_slong: return f(inout, DC(typename D::Dsl, in));
+	case it_ulong: return f(inout, DC(typename D::Dul, in));
+#endif
+	case it_float: return f(inout, DC(typename D::Dfloat, in));
+	case it_double:return f(inout, DC(typename D::Ddouble, in));
+	default:
+		assert(!"unsupported pixel type in image");
+		throw std::invalid_argument("mia::filter: unsupported pixel type in image");
+	}
+}
+
+template <typename F, typename INOUT, typename IN>
+static typename F::result_type combine_inplace(const F& f, INOUT& inout, const IN& in)
+{
+	typedef typename Binder<INOUT
+>::Derived D;
+	switch (inout.get_pixel_type()) {
+	case it_bit:   return _combine_inplace(f, DV(typename D::Dbool, inout), in);
+	case it_sbyte: return _combine_inplace(f, DV(typename D::Dsc, inout), in);
+	case it_ubyte: return _combine_inplace(f, DV(typename D::Duc, inout), in);
+	case it_sshort:return _combine_inplace(f, DV(typename D::Dss, inout), in);
+	case it_ushort:return _combine_inplace(f, DV(typename D::Dus, inout), in);
+	case it_sint:  return _combine_inplace(f, DV(typename D::Dsi, inout), in);
+	case it_uint:  return _combine_inplace(f, DV(typename D::Dui, inout), in);
+#ifdef LONG_64BIT
+	case it_slong: return _combine_inplace(f, DV(typename D::Dsl, inout), in);
+	case it_ulong: return _combine_inplace(f, DV(typename D::Dul, inout), in);
+#endif
+	case it_float: return _combine_inplace(f, DV(typename D::Dfloat, inout), in);
+	case it_double:return _combine_inplace(f, DV(typename D::Ddouble, inout), in);
+	default:
+		assert(!"unsupported pixel type in image");
+		throw std::invalid_argument("mia::filter: unsupported pixel type in image");
+	}
+
+	
+}
+
+
 /**
    \ingroup filtering
 
diff --git a/mia/core/fixedwidthoutput.cc b/mia/core/fixedwidthoutput.cc
index 80b8129..089f2a6 100644
--- a/mia/core/fixedwidthoutput.cc
+++ b/mia/core/fixedwidthoutput.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/fixedwidthoutput.hh b/mia/core/fixedwidthoutput.hh
index 0f53ff1..1d7bb30 100644
--- a/mia/core/fixedwidthoutput.hh
+++ b/mia/core/fixedwidthoutput.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/flagstring.cc b/mia/core/flagstring.cc
index d126bdb..81ca02f 100644
--- a/mia/core/flagstring.cc
+++ b/mia/core/flagstring.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/flagstring.hh b/mia/core/flagstring.hh
index f49d4c8..d123e51 100644
--- a/mia/core/flagstring.hh
+++ b/mia/core/flagstring.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/fullstats.cc b/mia/core/fullstats.cc
index 72c664f..3d90f1d 100644
--- a/mia/core/fullstats.cc
+++ b/mia/core/fullstats.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/fullstats.hh b/mia/core/fullstats.hh
index 3c2b691..bd20cd6 100644
--- a/mia/core/fullstats.hh
+++ b/mia/core/fullstats.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/handler.cxx b/mia/core/handler.cxx
index d1472ef..970901e 100644
--- a/mia/core/handler.cxx
+++ b/mia/core/handler.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/handler.hh b/mia/core/handler.hh
index 0b1c0b2..8468c97 100644
--- a/mia/core/handler.hh
+++ b/mia/core/handler.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/handlerbase.cc b/mia/core/handlerbase.cc
index 134ffba..f322e1a 100644
--- a/mia/core/handlerbase.cc
+++ b/mia/core/handlerbase.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -90,4 +90,15 @@ std::string CPluginHandlerBase::do_get_handler_type_string() const
 }
 
 
+bool CPluginHandlerBase::validate_parameter_string(const std::string& s) const
+{
+	return do_validate_parameter_string(s);
+}
+
+bool CPluginHandlerBase::do_validate_parameter_string(const std::string& MIA_PARAM_UNUSED(s)) const
+{
+	return true; 
+}
+
+
 NS_MIA_END
diff --git a/mia/core/handlerbase.hh b/mia/core/handlerbase.hh
index 8c06344..fb6fb38 100644
--- a/mia/core/handlerbase.hh
+++ b/mia/core/handlerbase.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -102,11 +102,26 @@ class EXPORT_CORE CPluginHandlerBase  {
 	void add_dependend_handlers(HandlerHelpMap& handler_map) const;  
 
 	/**
-	   
-	 */
+	   write the XML description of this handler to an XML node 
+	   @param os stream to write additional descriptions to. 
+	   @param root the parent node the information is added to 
+	*/
 	void get_string_help_description_xml(std::ostream& os, xmlpp::Element *root) const; 
-
+	
+	
+	/**
+	   @returns the type name of the plug-in handler 
+	*/
 	std::string get_handler_type_string() const; 
+	
+	
+	/**	  
+	   Validate the given string to see whether anything useful can be done 
+	   with it. The actual way how this is validated depends on the plug-in
+           type.  
+	 */
+	bool validate_parameter_string(const std::string& s) const; 
+
 private: 
 	
 	virtual void do_print_short_help(std::ostream& os) const = 0; 
@@ -115,7 +130,8 @@ private:
 	virtual void do_add_dependend_handlers(HandlerHelpMap& handler_map) const = 0;  
 	virtual std::string get_handler_type_string_and_help(std::ostream& os) const; 
 	virtual std::string do_get_handler_type_string() const; 
-	
+	virtual bool do_validate_parameter_string(const std::string& s) const; 
+
 	std::string m_descriptor; 
 }; 
 
diff --git a/mia/core/histogram.hh b/mia/core/histogram.hh
index e9f3951..7f283df 100644
--- a/mia/core/histogram.hh
+++ b/mia/core/histogram.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/history.cc b/mia/core/history.cc
index 7638454..f96f4fe 100644
--- a/mia/core/history.cc
+++ b/mia/core/history.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/history.hh b/mia/core/history.hh
index d9f10dc..512c360 100644
--- a/mia/core/history.hh
+++ b/mia/core/history.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/ica.cc b/mia/core/ica.cc
index c6e619d..c11c487 100644
--- a/mia/core/ica.cc
+++ b/mia/core/ica.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/ica.hh b/mia/core/ica.hh
index 9b0b017..30c4b8f 100644
--- a/mia/core/ica.hh
+++ b/mia/core/ica.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/ica_template.cxx b/mia/core/ica_template.cxx
index 0f6ccd4..8d05b07 100644
--- a/mia/core/ica_template.cxx
+++ b/mia/core/ica_template.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/ica_template.hh b/mia/core/ica_template.hh
index 31443a4..1706629 100644
--- a/mia/core/ica_template.hh
+++ b/mia/core/ica_template.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/import_handler.hh b/mia/core/import_handler.hh
index cca514c..59e5915 100644
--- a/mia/core/import_handler.hh
+++ b/mia/core/import_handler.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/index.cc b/mia/core/index.cc
index 618f664..b0d0a2a 100644
--- a/mia/core/index.cc
+++ b/mia/core/index.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/index.hh b/mia/core/index.hh
index 517f66d..0c85c2e 100644
--- a/mia/core/index.hh
+++ b/mia/core/index.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/info.cc b/mia/core/info.cc
index 88f6210..ad2d559 100644
--- a/mia/core/info.cc
+++ b/mia/core/info.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
 #include <cstdlib>
 
 static const char info[] = "%s is Copyright %s\n"
-	"    (c) 1999-2013 Leipzig, Germany and Madrid, Spain \n"
+	"    (c) 1999-2014 Leipzig, Germany and Madrid, Spain \n"
 	""
 	"and it comes with  ABSOLUTELY NO WARRANTY. You may redistribute .\n"
 	"it under the terms of the GNU GENERAL PUBLIC LICENSE (see below).\n"
diff --git a/mia/core/interpolator1d.cc b/mia/core/interpolator1d.cc
index fb9ada9..6384048 100644
--- a/mia/core/interpolator1d.cc
+++ b/mia/core/interpolator1d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/interpolator1d.cxx b/mia/core/interpolator1d.cxx
index 80a4a07..6c2266c 100644
--- a/mia/core/interpolator1d.cxx
+++ b/mia/core/interpolator1d.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/interpolator1d.hh b/mia/core/interpolator1d.hh
index ab71e10..ac7a6b2 100644
--- a/mia/core/interpolator1d.hh
+++ b/mia/core/interpolator1d.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/iodata.cc b/mia/core/iodata.cc
index 8b71e6b..3c585fe 100644
--- a/mia/core/iodata.cc
+++ b/mia/core/iodata.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/iodata.hh b/mia/core/iodata.hh
index 3d944c4..e3370ea 100644
--- a/mia/core/iodata.hh
+++ b/mia/core/iodata.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/iohandler.cxx b/mia/core/iohandler.cxx
index ac08d2c..3caec35 100644
--- a/mia/core/iohandler.cxx
+++ b/mia/core/iohandler.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -42,6 +42,7 @@ void TIOPluginHandler<I>::do_initialise()
 		i->second->add_suffixes(m_suffixmap);
 	
 	m_compress_sfx.insert(".Z"); 
+	m_compress_sfx.insert(".xz"); 
 	m_compress_sfx.insert(".gz"); 
 	m_compress_sfx.insert(".bz2"); 
 }
@@ -76,7 +77,7 @@ TIOPluginHandler<I>::preferred_plugin_ptr(const std::string& fname) const
 	CSuffixmap::const_iterator p = m_suffixmap.find(fsuffix);
 	if (p != m_suffixmap.end())
 		return this->plugin(p->second.c_str());
-	return 0; 
+	return nullptr; 
 }
 
 template <class I> 
@@ -273,7 +274,7 @@ TIOPluginHandler<I>::CDatapoolPlugin::CDatapoolPlugin():
 }
 
 template <class I> 
-std::string TIOPluginHandler<I>::CDatapoolPlugin::do_get_preferred_suffix() const
+const std::string TIOPluginHandler<I>::CDatapoolPlugin::do_get_preferred_suffix() const
 {
 	return "@"; 
 }
@@ -306,7 +307,12 @@ const std::string TIOPluginHandler<I>::CDatapoolPlugin::do_get_descr() const
 	return "Virtual IO to and from the internal data pool"; 
 }
 
-
+template <class I>
+bool TIOPluginHandler<I>::do_validate_parameter_string(const std::string& s) const
+{
+	auto p = preferred_plugin_ptr(s); 
+	return p != nullptr ? true : false;  
+}
 
 NS_MIA_END
 
diff --git a/mia/core/iohandler.hh b/mia/core/iohandler.hh
index 31acf39..8bd5e98 100644
--- a/mia/core/iohandler.hh
+++ b/mia/core/iohandler.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -146,6 +146,7 @@ private:
 
 	std::string get_handler_type_string_and_help(std::ostream& os) const; 
 	std::string do_get_handler_type_string() const; 
+        bool do_validate_parameter_string(const std::string& s) const;
 
 	/**
 	   Private plugin to handle the virtual data pool IO  
@@ -158,7 +159,7 @@ private:
 		bool do_save(const std::string& fname, 
 			     const typename Interface::Data& data) const; 
 		const std::string do_get_descr() const;
-		std::string do_get_preferred_suffix() const; 
+		const std::string do_get_preferred_suffix() const; 
 			
 	}; 
 	CDatapoolPlugin *m_pool_plugin; 
@@ -175,6 +176,12 @@ private:
 	template class TPluginHandler<TIOPlugin<IOTYPE>>		\
 
 
+
+template <typename Data> 
+struct IOHandler_of {
+	typedef THandlerSingleton<TIOPluginHandler<TIOPlugin<Data>>> type;
+}; 
+
 /**
    This fakes some load image function 
    \remark what is this for? 
diff --git a/mia/core/ioplugin.cc b/mia/core/ioplugin.cc
index 2378c40..d3e8fa6 100644
--- a/mia/core/ioplugin.cc
+++ b/mia/core/ioplugin.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,5 +27,6 @@ const char * io_plugin_type::type_descr = "io";
 const char * const io_plugin_property_multi_record = "multi-record";
 const char * const io_plugin_property_history_split = "history-split";
 const char * const io_plugin_property_has_attributes = "has_attributes";
+const char * const io_plugin_property_can_pipe = "can-pipe";
 
 NS_MIA_END
diff --git a/mia/core/ioplugin.cxx b/mia/core/ioplugin.cxx
index 42d36ee..e8994a7 100644
--- a/mia/core/ioplugin.cxx
+++ b/mia/core/ioplugin.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -116,13 +116,13 @@ const typename TIOPlugin<D>::SuffixSet& TIOPlugin<D>::get_suffixes() const
 }
 
 template <typename D> 
-std::string TIOPlugin<D>::get_preferred_suffix() const
+const std::string TIOPlugin<D>::get_preferred_suffix() const
 {
 	return 	this->do_get_preferred_suffix(); 
 }
 
 template <typename D> 
-std::string TIOPlugin<D>::do_get_preferred_suffix() const
+const std::string TIOPlugin<D>::do_get_preferred_suffix() const
 {
 	return this->get_name(); 
 }
diff --git a/mia/core/ioplugin.hh b/mia/core/ioplugin.hh
index 7ba496d..ca4bff8 100644
--- a/mia/core/ioplugin.hh
+++ b/mia/core/ioplugin.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -109,7 +109,7 @@ public:
 	   \returns preferred suffix of the file type 
 	   \remark in most cases this is just a pass-through 
 	 */
-	std::string get_preferred_suffix() const; 
+	const std::string get_preferred_suffix() const; 
 protected:
 
 	void add_suffix(const std::string& suffix);  
@@ -139,13 +139,14 @@ private:
 	 */
 	virtual bool do_save(const std::string& fname, const typename D::type& data) const = 0;
 
-	virtual std::string do_get_preferred_suffix() const; 
+	virtual const std::string do_get_preferred_suffix() const; 
 
 };
 
 EXPORT_CORE extern const char * const io_plugin_property_multi_record;
 EXPORT_CORE extern const char * const io_plugin_property_history_split;
 EXPORT_CORE extern const char * const io_plugin_property_has_attributes;
+EXPORT_CORE extern const char * const io_plugin_property_can_pipe;
 
 NS_MIA_END
 
diff --git a/mia/core/kmeans.cc b/mia/core/kmeans.cc
index 746b5aa..a0a06f3 100644
--- a/mia/core/kmeans.cc
+++ b/mia/core/kmeans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/kmeans.hh b/mia/core/kmeans.hh
index bc9ff75..9758738 100644
--- a/mia/core/kmeans.hh
+++ b/mia/core/kmeans.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/labelmap.cc b/mia/core/labelmap.cc
index ec4b7a9..d8f73e5 100644
--- a/mia/core/labelmap.cc
+++ b/mia/core/labelmap.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/labelmap.hh b/mia/core/labelmap.hh
index a49530c..e141fbb 100644
--- a/mia/core/labelmap.hh
+++ b/mia/core/labelmap.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/meanvar.hh b/mia/core/meanvar.hh
index 170db5e..a1a3bc6 100644
--- a/mia/core/meanvar.hh
+++ b/mia/core/meanvar.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/minimizer.cc b/mia/core/minimizer.cc
index 13d631a..2492f25 100644
--- a/mia/core/minimizer.cc
+++ b/mia/core/minimizer.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/minimizer.hh b/mia/core/minimizer.hh
index 818b95f..2fc5cef 100644
--- a/mia/core/minimizer.hh
+++ b/mia/core/minimizer.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/minimizer/CMakeLists.txt b/mia/core/minimizer/CMakeLists.txt
index 9888a85..acc39a2 100644
--- a/mia/core/minimizer/CMakeLists.txt
+++ b/mia/core/minimizer/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -22,4 +22,7 @@ PLUGIN_WITH_TEST_AND_PREFIX2("minimizer" "singlecost" gsl "${GSLOPTLIBS}")
 SET(NEEDED_LIBS miacore "${NEEDED_LIBS}")
 PLUGIN_WITH_TEST_AND_PREFIX2("minimizer" "singlecost" gdsq "${NEEDED_LIBS}")
 
+SET(NEEDED_LIBS miacore "${NEEDED_LIBS}")
+PLUGIN_WITH_TEST_AND_PREFIX2("minimizer" "singlecost" gdas "${NEEDED_LIBS}")
+
 
diff --git a/mia/core/minimizer/gdas.cc b/mia/core/minimizer/gdas.cc
new file mode 100644
index 0000000..e53814c
--- /dev/null
+++ b/mia/core/minimizer/gdas.cc
@@ -0,0 +1,182 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/minimizer/gdas.hh>
+#include <mia/core/errormacro.hh>
+extern "C" {
+#include <cblas.h>
+}
+
+NS_BEGIN(gdas)
+using namespace mia; 
+using namespace std; 
+
+#define SUCCESS_XTOLA 1
+#define SUCCESS_FTOLR 2
+
+CGDSAMinimizer::CGDSAMinimizer(double min_step, double max_step, 
+			       double xtol, double ftolr, 
+			       unsigned int maxiter):
+	m_min_step(min_step), 
+	m_max_step(max_step), 
+        m_ftolr(ftolr),
+	m_xtol( xtol ), 
+	m_maxiter( maxiter )
+{
+        add(property_gradient); 
+        if (max_step <= min_step) {
+                throw create_exception<invalid_argument>("CGDSAMinimizer max_step(", max_step,
+                                       ") must be larger than min_step (", min_step,")"); 
+        }
+}
+
+void CGDSAMinimizer::do_set_problem()
+{
+}
+
+double CGDSAMinimizer::get_gradmax(CDoubleVector& x) 
+{
+        double gmax = 0.0; 
+        for( auto ix = x.begin(); ix != x.end(); ++ix) {
+                const double ax = fabs(*ix);
+                if (ax > gmax) 
+                        gmax = ax;
+        }
+        return gmax; 
+}
+
+int CGDSAMinimizer::do_run(CDoubleVector& x)
+{
+	TRACE_FUNCTION; 
+	CDoubleVector g(x.size()); 
+        CDoubleVector xwork(x.size()); 
+        
+	copy(x.begin(), x.end(), xwork.begin()); 
+	
+	double f_init = get_problem().fdf(xwork, g);
+	double step = 0.5 * (m_max_step - m_min_step); 
+	
+	double f_old = f_init; 
+	unsigned int iter = 0; 
+
+        double gmax = get_gradmax(g); 
+        int success = gmax < m_xtol ? SUCCESS_XTOLA : 0;
+        int tries = 0; 
+        
+        while (iter++ < m_maxiter && !success) {
+		cblas_daxpy(g.size(), -step / gmax, &g[0], 1, &xwork[0], 1);
+                double f = get_problem().fdf(xwork, g);
+                gmax = get_gradmax(g);
+                if (gmax < m_xtol) 
+                        success |= SUCCESS_XTOLA; 
+                
+                
+		if (f < f_old) {
+                        cvinfo() << "Successfull step: [" << iter << "]: f=" << f 
+                                 << ", gmax = " << gmax << ", step=" << step << "\n"; 
+
+                        tries = 0; 
+                        copy(xwork.begin(), xwork.end(), x.begin()); 
+                        
+                        if ( (f < 0.5 * f_old) && (step > m_max_step)) {
+                                step *= 1.5; 
+                                if (step > m_max_step) 
+                                        step = m_max_step; 
+                                cvdebug() << "Increase step size to " << step << " \n";
+                        }
+
+                        double dfrel = (f_old - f)/f_old; 
+                        cvdebug() << "dfrel=" << dfrel << "\n"; 
+                        if (dfrel < m_ftolr) {
+                                success |= SUCCESS_FTOLR; 
+                                break;
+                        }
+                        f_old = f; 
+                } else {
+                        cvinfo() << "Failed step: [" << iter << "]: f=" << f 
+                                 << ", gmax = " << gmax << ", step=" << step << "\n"; 
+                        
+                        if (step > m_min_step) {
+                                // restore last solution 
+                                copy(x.begin(), x.end(), xwork.begin()); 
+                                step /= 2.0; 
+                                if (step < m_min_step)  
+                                        step = m_min_step; 
+                                cvdebug() << "Decrease step size to " << step << " \n";
+                        }else{
+                                if (tries < 5) 
+                                        ++tries;
+                                else {
+                                        cvmsg() << "At minimal stepsize and no improvent, stopping\n"; 
+                                        break; 
+                                }
+                        }
+                }
+	}
+	if (iter == m_maxiter) 
+		cvmsg() << "Iteration stopped because maximum number of iterations was reached\n"; 
+	
+	if (success & SUCCESS_XTOLA) 
+		cvmsg() << "Stop: dx below given limit\n"; 
+		
+	if (success & SUCCESS_FTOLR) 
+		cvmsg() << "Stop: relative cost funtion value decrease below limit "<< m_ftolr << ".\n"; 
+
+	return CMinimizer::success; 
+}
+
+CGDSAMinimizerPlugin::CGDSAMinimizerPlugin():
+	CMinimizerPlugin("gdas"), 
+	m_min_step(0.1), 
+	m_max_step(2.0), 
+        m_ftolr(0.0),
+	m_xtol( 0.01 ), 
+	m_maxiter( 200 )
+{
+	add_parameter("maxiter", new CUIntParameter(m_maxiter, 1, numeric_limits<int>::max(), false, 
+                                                    "Stopping criterion: the maximum number of iterations")); 
+	
+	add_parameter("min-step", new CDoubleParameter(m_min_step, 1e-10, HUGE_VAL, false, "Maximal absolute step size")); 
+	add_parameter("max-step", new CDoubleParameter(m_max_step, 1.0, HUGE_VAL, false, "Minimal absolute step size")); 
+	add_parameter("xtola", new CDoubleParameter(m_xtol, 0.0, HUGE_VAL, false, 
+						    "Stop if the inf-norm of the change applied to x is below this value."));
+	add_parameter("ftolr", new CDoubleParameter(m_ftolr, 0.0, HUGE_VAL, false, 
+						    "Stop if the relative change of the criterion is below."));
+}
+
+
+CMinimizer *CGDSAMinimizerPlugin::do_create() const
+{
+	TRACE_FUNCTION; 
+	return new CGDSAMinimizer(m_min_step, m_max_step, m_xtol, m_ftolr, m_maxiter);
+}
+
+const std::string CGDSAMinimizerPlugin::do_get_descr() const
+{
+	return "Gradient descent with automatic step size correction."; 
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new CGDSAMinimizerPlugin();
+}
+
+
+NS_END
diff --git a/mia/core/minimizer/gdas.hh b/mia/core/minimizer/gdas.hh
new file mode 100644
index 0000000..f444eea
--- /dev/null
+++ b/mia/core/minimizer/gdas.hh
@@ -0,0 +1,61 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/minimizer.hh>
+
+NS_BEGIN(gdas)
+
+class CGDSAMinimizer: public mia::CMinimizer {
+        
+public: 
+        
+        CGDSAMinimizer(double min_step, double max_step, 
+                       double gtol, double ftolr, 
+                       unsigned int maxiter); 
+
+private:         
+        void do_set_problem(); 
+        double get_gradmax(mia::CDoubleVector& x); 
+        int do_run(mia::CDoubleVector& x); 
+
+	double m_min_step; 
+	double m_max_step;
+        double m_ftolr;
+	double m_xtol;
+	unsigned int m_maxiter; 
+
+}; 
+
+class CGDSAMinimizerPlugin: public mia::CMinimizerPlugin {
+public: 
+        CGDSAMinimizerPlugin(); 
+private: 
+        mia::CMinimizer *do_create() const; 
+        const std::string do_get_descr() const; 
+
+	double m_min_step; 
+	double m_max_step;
+        double m_ftolr;
+	double m_xtol;
+	unsigned int  m_maxiter; 
+
+}; 
+
+NS_END
diff --git a/mia/core/minimizer/gdsq.cc b/mia/core/minimizer/gdsq.cc
index d9154ba..a0dba33 100644
--- a/mia/core/minimizer/gdsq.cc
+++ b/mia/core/minimizer/gdsq.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/minimizer/gdsq.hh b/mia/core/minimizer/gdsq.hh
index 3ee148a..aa33fa6 100644
--- a/mia/core/minimizer/gdsq.hh
+++ b/mia/core/minimizer/gdsq.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/minimizer/gsl.cc b/mia/core/minimizer/gsl.cc
index 5686706..f8b9670 100644
--- a/mia/core/minimizer/gsl.cc
+++ b/mia/core/minimizer/gsl.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/minimizer/gsl.hh b/mia/core/minimizer/gsl.hh
index 4d9a4a2..08295ae 100644
--- a/mia/core/minimizer/gsl.hh
+++ b/mia/core/minimizer/gsl.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/minimizer/test_gdas.cc b/mia/core/minimizer/test_gdas.cc
new file mode 100644
index 0000000..6318a0b
--- /dev/null
+++ b/mia/core/minimizer/test_gdas.cc
@@ -0,0 +1,109 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/plugintester.hh>
+#include <mia/core/minimizer/gdas.hh>
+using namespace mia; 
+using namespace gdas;
+
+
+class TestCFDFProblem : public CMinimizer::Problem {
+public:
+	TestCFDFProblem(); 
+private: 
+	virtual double  do_f(const CDoubleVector& x); 
+	virtual void    do_df(const CDoubleVector&  x, CDoubleVector&  g); 
+	virtual double  do_fdf(const CDoubleVector&  x, CDoubleVector&  g); 
+	virtual size_t do_size() const; 
+	std::vector<double> m_p; 
+	size_t m_size; 
+}; 
+
+BOOST_AUTO_TEST_CASE( test_cfdf_multmin ) 
+{
+        auto minimizer = BOOST_TEST_create_from_plugin<CGDSAMinimizerPlugin>("gdas:maxiter=300,min-step=0.00001"
+                                                                             ",max-step=3,xtola=0.0001,ftolr=0.0");
+        
+	CMinimizer::PProblem problem(new TestCFDFProblem); 
+	problem->add(property_gradient); 
+	minimizer->set_problem(problem); 
+	
+	CDoubleVector x(2); 
+	x[0] = 5.0; 
+	x[1] = 7.0; 
+	
+	BOOST_REQUIRE(minimizer->run(x)==  CMinimizer::success); 
+	BOOST_CHECK_CLOSE(x[0], 1.0, 0.1); 
+	BOOST_CHECK_CLOSE(x[1], 2.0, 0.1); 
+}
+
+TestCFDFProblem::TestCFDFProblem():
+	m_p(5), 
+	m_size(2)
+{
+	double p_init[5] = {1.0, 2.0, 10.0, 20.0, 30.0 }; 
+	copy(p_init, p_init+5, m_p.begin()); 
+}
+
+size_t TestCFDFProblem::do_size()const 
+{
+	return m_size; 
+}
+
+double  TestCFDFProblem::do_f(const CDoubleVector&  v)
+{
+
+	const double x = v[0];
+	const double y = v[1];
+	
+	return m_p[2] * (x - m_p[0]) * (x - m_p[0]) +
+		m_p[3] * (y - m_p[1]) * (y - m_p[1]) + m_p[4]; 
+	
+}
+
+void    TestCFDFProblem::do_df(const CDoubleVector&  v, CDoubleVector&  g)
+{
+	const double x = v[0];
+	const double y = v[1];
+      
+	g[0] = 2.0 * m_p[2] * (x - m_p[0]);
+	g[1] = 2.0 * m_p[3] * (y - m_p[1]);
+}
+
+double  TestCFDFProblem::do_fdf(const CDoubleVector&  x, CDoubleVector&  g)
+{
+	do_df(x,g); 
+	return do_f(x); 
+}
+
+
+class TestCFProblem : public CMinimizer::Problem {
+public:
+	TestCFProblem(); 
+private: 
+	virtual double  do_f(const CDoubleVector& x); 
+	virtual void    do_df(const CDoubleVector& x, CDoubleVector&  g); 
+	virtual double  do_fdf(const CDoubleVector& x, CDoubleVector&  g); 
+	virtual size_t do_size() const; 
+	std::vector<double> m_p; 
+	size_t m_size; 
+}; 
+
+
diff --git a/mia/core/minimizer/test_gdsq.cc b/mia/core/minimizer/test_gdsq.cc
index 28f82b1..2df3b7e 100644
--- a/mia/core/minimizer/test_gdsq.cc
+++ b/mia/core/minimizer/test_gdsq.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/minimizer/test_gsl.cc b/mia/core/minimizer/test_gsl.cc
index 5143a8e..71ca187 100644
--- a/mia/core/minimizer/test_gsl.cc
+++ b/mia/core/minimizer/test_gsl.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/mitestimages.cc b/mia/core/mitestimages.cc
index aa97aff..04aff6c 100644
--- a/mia/core/mitestimages.cc
+++ b/mia/core/mitestimages.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/mitestimages.hh b/mia/core/mitestimages.hh
index b9bc917..df3f1db 100644
--- a/mia/core/mitestimages.hh
+++ b/mia/core/mitestimages.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/module.cc b/mia/core/module.cc
index 5f0b9bf..8883b5f 100644
--- a/mia/core/module.cc
+++ b/mia/core/module.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/module.hh b/mia/core/module.hh
index 710fbe6..2adc31f 100644
--- a/mia/core/module.hh
+++ b/mia/core/module.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/msgstream.cc b/mia/core/msgstream.cc
index 7cac307..5d56020 100644
--- a/mia/core/msgstream.cc
+++ b/mia/core/msgstream.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
 NS_MIA_BEGIN
 
 const TDictMap<vstream::Level>::Table verbose_dict[] = {
-#ifndef NDEBUG
+#ifdef ENABLE_DEBUG_MESSAGES
 	{"trace", vstream::ml_trace, "Function call trace"},
 	{"debug", vstream::ml_debug, "Debug output"},
 #endif
@@ -110,10 +110,7 @@ void set_verbose(bool verbose)
 	vstream::instance().set_verbosity(verbose ? vstream::ml_message : vstream::ml_error);
 }
 
-#ifndef NDEBUG
 __thread size_t CTrace::m_depth = 0;
-#endif
-
 __thread std::ostream* vstream::m_output;
 __thread vstream::Level vstream::m_message_level = vstream::ml_fatal; 
 
diff --git a/mia/core/msgstream.hh b/mia/core/msgstream.hh
index 980470a..1c921d0 100644
--- a/mia/core/msgstream.hh
+++ b/mia/core/msgstream.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,8 +27,11 @@
 #include <cassert>
 #include <ostream>
 #include <boost/call_traits.hpp>
+#include <boost/ref.hpp>
+#include <miaconfig.h>
 #include <mia/core/defines.hh>
 #include <mia/core/dictmap.hh>
+#include <mia/core/svector.hh>
 
 NS_MIA_BEGIN
 
@@ -37,16 +40,6 @@ NS_MIA_BEGIN
 #endif
 
 
-template <typename T> 
-std::ostream&  operator << (std::ostream& os, const std::vector<T>& v) 
-{
-	os << "["; 
-	for(auto x: v)
-		os << x << ", "; 
-	os << "]"; 
-	return os; 
-}
-
 /**
    \ingroup logging
    \brief A output stream to enable certain levels of verbosity 
@@ -182,16 +175,39 @@ inline bool vstream::shows(Level l)const
 }
 
 
-#ifdef NDEBUG
+class EXPORT_CORE CTrace {
+public:
+	CTrace(const char *domain):
+		m_domain(domain),
+		m_fill(m_depth, ' ')  {
+		vstream::instance() << vstream::ml_trace
+				    << m_fill << "enter " << m_domain  << "\n";
+		++m_depth;
+	};
+	~CTrace() {
+		vstream::instance() << vstream::ml_trace
+				    << m_fill << "leave " << m_domain  << "\n";
+		--m_depth;
+	}
+private:
+	const char *m_domain;
+	std::string m_fill;
+	// should be thread local, or at least protected by a mutex
+	static __thread size_t m_depth;
+};
+
+
+#ifndef ENABLE_DEBUG_MESSAGES
 #define TRACE(DOMAIN)
 #define TRACE_FUNCTION
 #define FUNCTION_NOT_TESTED
-class CDebugSink {
+class CDebugSink  {
 public:
 	template <class T>
-	CDebugSink& operator << (const T /*val*/) {
+	CDebugSink& operator << (const T& MIA_PARAM_UNUSED(val)) {
 		return *this;
 	}
+
 	CDebugSink & operator<<(std::ostream& (* /*f*/)(std::ostream&)) {
 		return *this;
 	}
@@ -216,26 +232,6 @@ inline vstream& cvdebug()
 	return vstream::instance();
 }
 
-class EXPORT_CORE CTrace {
-public:
-	CTrace(const char *domain):
-		m_domain(domain),
-		m_fill(m_depth, ' ')  {
-		vstream::instance() << vstream::ml_trace
-				    << m_fill << "enter " << m_domain  << "\n";
-		++m_depth;
-	};
-	~CTrace() {
-		vstream::instance() << vstream::ml_trace
-				    << m_fill << "leave " << m_domain  << "\n";
-		--m_depth;
-	}
-private:
-	const char *m_domain;
-	std::string m_fill;
-	// should be thread local, or at least protected by a mutex
-	static __thread size_t m_depth;
-};
 
 /// a macro to trace scopes in a debug built
 #define TRACE(DOMAIN) ::mia::CTrace _xxx_trace(DOMAIN)
diff --git a/mia/core/nccsum.cc b/mia/core/nccsum.cc
new file mode 100644
index 0000000..e893a45
--- /dev/null
+++ b/mia/core/nccsum.cc
@@ -0,0 +1,195 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/msgstream.hh> 
+#include <mia/core/nccsum.hh> 
+
+
+NS_MIA_BEGIN
+
+using std::make_pair; 
+
+#ifdef __SSE2__
+
+double NCCSums::value() const {
+        double  result = 1.0;
+        if (m_n > 0) {
+                v2df sum2 = m_sum2; 
+                v2df nn = {m_n, m_n };
+                v2df mean = m_sum / nn; 
+                v2df delta = m_sum * mean; 
+                sum2 -= delta; 
+		
+                v2df ms2_a = _mm_unpacklo_pd(mean, sum2); 
+                v2df ms2_b = _mm_unpackhi_pd(mean, sum2); 
+                
+                v2df prod = ms2_a * ms2_b;
+		
+// new versiond of gcc can access these array directly 
+
+#ifdef BUILD_SSE_ATTRIBUTE_VECTOR_CAN_USE_SUBSCRIPT
+
+                double sumab = m_sumab - prod[0] * m_n; 
+		
+                if (prod[1] > 1e-10) {
+                        result = 1.0 - sumab * sumab / prod[1]; 
+                }else if (sum2[0] < 1e-5 && sum2[1] < 1e-5) {
+			result = 0.0; 
+		}
+
+#else // !BUILD_SSE_ATTRIBUTE_VECTOR_CAN_USE_SUBSCRIPT
+
+		double __attribute__((aligned(16))) mprod[2]; 
+		_mm_store_pd(mprod, prod); 
+
+                double sumab = m_sumab - mprod[0] * m_n; 
+
+		double __attribute__((aligned(16))) msum2[2]; 
+		_mm_store_pd(msum2, sum2); 
+
+		if (mprod[1] > 1e-10) {
+                        result = 1.0 - sumab * sumab / mprod[1]; 
+                }else if (msum2[0] < 1e-5 && msum2[1] < 1e-5) {
+			result = 0.0; 
+		}
+
+#endif // BUILD_SSE_ATTRIBUTE_VECTOR_CAN_USE_SUBSCRIPT
+ 
+        }
+        return result; 
+}
+        
+std::pair<double, NCCGradHelper> NCCSums::get_grad_helper() const {
+        
+        std::pair<double, NCCGradHelper>  result = std::make_pair(1.0, NCCGradHelper()); 
+        if (m_n > 0) {
+                v2df sum2 = m_sum2; 
+                v2df nn = {m_n, m_n };
+                v2df mean = m_sum / nn; 
+                v2df delta = m_sum * mean; 
+                sum2 -= delta; 
+		
+                v2df ms2_a = _mm_unpacklo_pd(mean, sum2); 
+                v2df ms2_b = _mm_unpackhi_pd(mean, sum2); 
+                
+                v2df prod = ms2_a * ms2_b; 
+
+#ifdef BUILD_SSE_ATTRIBUTE_VECTOR_CAN_USE_SUBSCRIPT
+                double sumab = m_sumab - prod[0] * m_n; 
+
+		if (prod[1] > 1e-5) {
+                        result = make_pair(1.0 - sumab * sumab / prod[1], 
+                                           NCCGradHelper(sumab / prod[1], sumab / sum2[0], mean[0], mean[1])); 
+		} else {
+			if (sum2[0] < 1e-5 && sum2[1] < 1e-5) {
+				result = make_pair(0.0, NCCGradHelper()); 
+			}
+                }
+
+#else // !BUILD_SSE_ATTRIBUTE_VECTOR_CAN_USE_SUBSCRIPT
+
+		double __attribute__((aligned(16))) mprod[2]; 
+		_mm_store_pd(mprod, prod); 
+		
+		double __attribute__((aligned(16))) mmean[2]; 
+		_mm_store_pd(mmean, mean); 
+		
+		double __attribute__((aligned(16))) msum2[2]; 
+		_mm_store_pd(msum2, sum2); 
+		
+		double sumab = m_sumab - mprod[0] * m_n; 
+		
+		if (mprod[1] > 1e-5) {
+			result = make_pair(1.0 - sumab * sumab / mprod[1], 
+                                           NCCGradHelper(sumab / mprod[1], sumab / msum2[0], mmean[0], mmean[1])); 
+		} else {
+			if (msum2[0] < 1e-5 && msum2[1] < 1e-5) {
+				result = make_pair(0.0, NCCGradHelper()); 
+			}
+                }
+#endif  // BUILD_SSE_ATTRIBUTE_VECTOR_CAN_USE_SUBSCRIPT
+	}
+        return result; 
+}
+
+#else // !__SSE2__
+
+double NCCSums::value() const
+{
+        double  result = 1.0;
+        if (m_n > 0) {
+                
+                double mean_a = m_suma / m_n; 
+                double mean_b = m_sumb / m_n; 
+                
+                double delta_a = m_suma * mean_a; 
+                double delta_b = m_sumb * mean_b; 
+
+                double suma2 = m_suma2 - delta_a; 
+                double sumb2 = m_sumb2 - delta_b; 
+
+                double help_0 = mean_a * mean_b; 
+                double help_1 = suma2 * sumb2; 
+                        
+                double sumab = m_sumab - help_0 * m_n; 
+                
+                if (help_1 > 1e-5) {
+			result = 1.0 - sumab * sumab / help_1; 
+		} else if (suma2 < 1e-5 &&  sumb2 < 1e-5) {
+			result = 0.0; 
+		}
+        }
+        return result; 
+        
+}
+
+std::pair<double, NCCGradHelper> NCCSums::get_grad_helper() const
+{
+        std::pair<double, NCCGradHelper>  result = std::make_pair(1.0, NCCGradHelper()); 
+        if (m_n > 0) {
+                
+                double mean_a = m_suma / m_n; 
+                double mean_b = m_sumb / m_n; 
+
+                double delta_a = m_suma * mean_a; 
+                double delta_b = m_sumb * mean_b; 
+                
+                double suma2 = m_suma2 - delta_a; 
+                double sumb2 = m_sumb2 - delta_b; 
+
+                double help_0 = mean_a * mean_b; 
+                double help_1 = suma2 * sumb2; 
+                double sumab = m_sumab - help_0 * m_n; 
+                
+                if (help_1 > 1e-10) {
+                        result = make_pair(1.0 - sumab * sumab / help_1, 
+                                           NCCGradHelper(sumab / help_1, sumab / suma2, mean_a, mean_b)); 
+                }else{
+			if (suma2 < 1e-5 && sumb2 < 1e-5) {
+				result = make_pair(0.0, NCCGradHelper()); 
+			}
+		}
+        }
+        return result; 
+}
+
+#endif // __SSE2__
+
+NS_MIA_END
diff --git a/mia/core/nccsum.hh b/mia/core/nccsum.hh
new file mode 100644
index 0000000..e776a1b
--- /dev/null
+++ b/mia/core/nccsum.hh
@@ -0,0 +1,162 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_core_nccsum_hh
+#define mia_core_nccsum_hh
+
+#include <utility> 
+#include <mia/core/defines.hh>
+
+#if defined(__SSE2__)
+#include <emmintrin.h>
+#endif
+
+NS_MIA_BEGIN
+
+class EXPORT_CORE NCCGradHelper  {
+public: 
+        NCCGradHelper():
+                m_sumab_by_a2b2(0.0), m_sumab_by_suma2(0.0), 
+                m_mean_a(0.0), m_mean_b(0.0)
+        {
+        }
+
+        NCCGradHelper(double sumab_by_a2b2, double sumab_by_suma2, double mean_a, double mean_b):
+                m_sumab_by_a2b2(2.0 * sumab_by_a2b2), m_sumab_by_suma2(sumab_by_suma2), 
+                m_mean_a(mean_a), m_mean_b(mean_b)
+        {
+        }
+                
+        float get_gradient_scale(double a, double b) const {
+                return m_sumab_by_a2b2 * ( m_sumab_by_suma2 * ( a  - m_mean_a ) - (b - m_mean_b));
+        }
+
+
+private: 
+        double m_sumab_by_a2b2;
+        double m_sumab_by_suma2; 
+        double m_mean_a;
+        double m_mean_b; 
+}; 
+
+#ifdef __SSE2__
+
+
+class EXPORT_CORE NCCSums {
+        typedef double v2df __attribute__ ((vector_size (16)));
+public: 
+	NCCSums():m_sumab(0.0), m_n(0.0) {
+                double zero[2] = {0.0, 0.0}; 
+                m_sum = _mm_load_pd(zero); 
+                m_sum2 = m_sum; 
+        }
+        
+        void add(double a, double b) {
+                v2df val = {static_cast<double>(a), static_cast<double>(b)}; 
+                v2df sq = val * val;	
+                m_sum += val; 
+                m_sum2 +=  sq; 
+                m_sumab += a * b; 
+                m_n += 1.0; 
+        }
+        
+        NCCSums& operator += (const NCCSums& other) {
+                m_sum += other.m_sum; 
+                m_sum2 +=  other.m_sum2; 
+                m_sumab += other.m_sumab; 
+                m_n += other.m_n; 
+                return *this;
+        }
+
+	bool has_samples() const {
+		return m_n > 0; 
+	}
+
+        double value() const; 
+        
+        std::pair<double, NCCGradHelper> get_grad_helper() const; 
+
+private: 
+        v2df m_sum; 
+        v2df m_sum2; 
+        double m_sumab; 
+        double m_n;
+
+}; 
+
+#else 
+
+class EXPORT_CORE NCCSums {
+public: 
+	NCCSums():m_suma(0.0), m_sumb(0.0), 
+                  m_suma2(0.0), m_sumb2(0.0), 
+                  m_sumab(0.0), m_n(0.0) {
+        }
+
+        void add(double a, double b) {
+                m_suma += a; 
+                m_sumb += b; 
+                m_suma2 +=  a * a; 
+                m_sumb2 +=  b * b; 
+                m_sumab += a * b; 
+                m_n += 1.0; 
+        }
+        
+        NCCSums& operator += (const NCCSums& other) {
+                m_suma += other.m_suma; 
+                m_sumb += other.m_sumb; 
+                m_suma2 +=  other.m_suma2; 
+                m_sumb2 +=  other.m_sumb2; 
+                m_sumab += other.m_sumab; 
+                m_n += other.m_n; 
+                return *this;
+        }
+
+        double value() const; 
+        
+        std::pair<double, NCCGradHelper> get_grad_helper() const; 
+
+
+	bool has_samples() const {
+		return m_n > 0; 
+	}
+private: 
+        double m_suma; 
+        double m_sumb; 
+        double m_suma2; 
+        double m_sumb2; 
+        double m_sumab; 
+        double m_n;
+}; 
+
+
+#endif 
+
+
+inline NCCSums operator + (const NCCSums& lhs, const NCCSums& rhs) 
+{
+        NCCSums result(lhs); 
+        result += rhs; 
+        return result; 
+}
+
+NS_MIA_END
+
+#endif 
diff --git a/mia/core/noise/CMakeLists.txt b/mia/core/noise/CMakeLists.txt
index 47c8500..22c2a5f 100644
--- a/mia/core/noise/CMakeLists.txt
+++ b/mia/core/noise/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/core/noise/gauss.cc b/mia/core/noise/gauss.cc
index c640eb8..b2905ec 100644
--- a/mia/core/noise/gauss.cc
+++ b/mia/core/noise/gauss.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/noise/gauss.hh b/mia/core/noise/gauss.hh
index 2bcc702..bff7619 100644
--- a/mia/core/noise/gauss.hh
+++ b/mia/core/noise/gauss.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/noise/test_gauss.cc b/mia/core/noise/test_gauss.cc
index 4989f99..1a229e7 100644
--- a/mia/core/noise/test_gauss.cc
+++ b/mia/core/noise/test_gauss.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/noise/test_uniform.cc b/mia/core/noise/test_uniform.cc
index abe77c5..76f1902 100644
--- a/mia/core/noise/test_uniform.cc
+++ b/mia/core/noise/test_uniform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/noise/uniform.cc b/mia/core/noise/uniform.cc
index e59a35e..686c53e 100644
--- a/mia/core/noise/uniform.cc
+++ b/mia/core/noise/uniform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/noise/uniform.hh b/mia/core/noise/uniform.hh
index 2f885b8..4ed99df 100644
--- a/mia/core/noise/uniform.hh
+++ b/mia/core/noise/uniform.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/noisegen.cc b/mia/core/noisegen.cc
index 14a0f39..991d7cd 100644
--- a/mia/core/noisegen.cc
+++ b/mia/core/noisegen.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -59,15 +59,10 @@ double CNoiseGenerator::ranf() const
 	return x / RAND_MAX;
 }
 
-using boost::filesystem::path; 
-CNoiseGeneratorPluginHandlerTestPath::CNoiseGeneratorPluginHandlerTestPath()
-{
-	CNoiseGeneratorPluginHandler::set_search_path({path(MIA_BUILD_ROOT"/mia/core/noise")}); 
-}
-
 template<> const char * const 
 TPluginHandler<TFactory<CNoiseGenerator>>::m_help = "These plug-ins provide various noise generators.";
 
+
 EXPLICIT_INSTANCE_HANDLER(CNoiseGenerator); 
 
 NS_MIA_END
diff --git a/mia/core/noisegen.hh b/mia/core/noisegen.hh
index 20954e2..f464eb5 100644
--- a/mia/core/noisegen.hh
+++ b/mia/core/noisegen.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -82,16 +82,6 @@ typedef TFactory<CNoiseGenerator> CNoiseGeneratorPlugin;
 typedef THandlerSingleton<TFactoryPluginHandler<CNoiseGeneratorPlugin> > 
       CNoiseGeneratorPluginHandler;
 
-/** 
-    @cond INTERNAL  
-    \ingroup test 
-    \brief Class to initialiaze the plug-in search path fot testing without installing the plug-ins 
-*/
-struct EXPORT_CORE CNoiseGeneratorPluginHandlerTestPath {
-	CNoiseGeneratorPluginHandlerTestPath(); 
-}; 
-/// @endcond 
-
 /// @cond never
 FACTORY_TRAIT(CNoiseGeneratorPluginHandler); 
 /// @endcond 
diff --git a/mia/core/optionparser.cc b/mia/core/optionparser.cc
index 8e9b8b5..949fcda 100644
--- a/mia/core/optionparser.cc
+++ b/mia/core/optionparser.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -70,7 +70,7 @@ CComplexOptionParser::CComplexOptionParser(const string& param)
 			options.insert(next_option);
 		}
 		cvdebug() << "CComplexOptionParser: add '" << part.first << "'\n";
-		m_Parts.insert(CParts::value_type(part.first, options));
+		m_Parts.push_back(make_pair(part.first, options));
 
 		++i;
 	}
diff --git a/mia/core/optionparser.hh b/mia/core/optionparser.hh
index 537efd3..ae760a4 100644
--- a/mia/core/optionparser.hh
+++ b/mia/core/optionparser.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
 #include <list>
 #include <map>
 #include <string>
+#include <vector>
 
 #include <mia/core/defines.hh>
 
@@ -59,7 +60,7 @@ public:
 	typedef char SSeperators[];
 
 	/// Type for a map of parts of a complex option 
-	typedef std::multimap<std::string, CParsedOptions> CParts;
+	typedef std::vector<std::pair<std::string, CParsedOptions> > CParts;
 
 	/// the iterator over the parts of a complex option 
 	typedef CParts::const_iterator const_iterator;
diff --git a/mia/core/optparam.cc b/mia/core/optparam.cc
index fb98f49..24dc05f 100644
--- a/mia/core/optparam.cc
+++ b/mia/core/optparam.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/optparam.hh b/mia/core/optparam.hh
index 81e160a..9f3c305 100644
--- a/mia/core/optparam.hh
+++ b/mia/core/optparam.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/parameter.cc b/mia/core/parameter.cc
index ab80fd4..0df6019 100644
--- a/mia/core/parameter.cc
+++ b/mia/core/parameter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -128,15 +128,14 @@ std::string CParameter::get_default_value() const
 	return do_get_default_value(); 
 }
 
-
-CStringParameter::CStringParameter(std::string& value, bool required, const char *descr, 
+CStringParameter::CStringParameter(std::string& value,CCmdOptionFlags flags , const char *descr, 
 				   const CPluginHandlerBase *plugin_hint):
-	CParameter(__type_descr<std::string>::value, required, descr),
+	CParameter(__type_descr<std::string>::value, has_flag(flags, CCmdOptionFlags::required), descr),
 	m_value(value), 
 	m_default_value(value), 
+	m_flags(flags), 
 	m_plugin_hint(plugin_hint)
 {
-	
 }
 
 void CStringParameter::do_reset()
@@ -175,6 +174,18 @@ void CStringParameter::do_get_help_xml(xmlpp::Element& self) const
 		dict->set_attribute("name", m_plugin_hint->get_descriptor());
 		self.set_attribute("type", type); 
 	}
+	if (m_flags != CCmdOptionFlags::none) {
+		auto flags = self.add_child("flags");
+		
+		ostringstream ss; 
+		if (has_flag(m_flags, CCmdOptionFlags::input))
+			ss << "input "; 
+		if (has_flag(m_flags, CCmdOptionFlags::output))
+			ss << "output "; 
+		if (has_flag(m_flags, CCmdOptionFlags::required))
+			ss << "required ";
+		flags->set_child_text(ss.str());
+	}
 }
 
 void CStringParameter::do_add_dependend_handler(HandlerHelpMap& handler_map)const
diff --git a/mia/core/parameter.cxx b/mia/core/parameter.cxx
index 076e751..39058b6 100644
--- a/mia/core/parameter.cxx
+++ b/mia/core/parameter.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -68,6 +68,41 @@ struct __dispatch_parameter_do_set {
 	}
 };  
 
+template <typename T>
+struct __dispatch_parameter_do_set<std::vector<T> >  {
+	static bool apply (const std::string& str_value, std::vector<T>& value) {
+
+		std::string h(str_value);
+		unsigned int n = 1; 
+		
+		// count input values 
+		for(auto hb = h.begin(); hb != h.end(); ++hb)
+			if (*hb == ',') {
+				*hb = ' ';
+				++n; 
+			}
+		
+		if (!value.empty()) {
+			if (n > value.size()) {
+				throw create_exception<std::invalid_argument>("Expect only ", value.size(),  
+									      " coma separated values, but '", 
+									      str_value, "' provides ", n);
+			}
+		}else{
+			value.resize(n); 
+		}
+
+				
+                std::istringstream sval(h);
+		auto i =  value.begin(); 
+		while (!sval.eof()) {
+			sval >> *i;
+			++i; 
+		}
+                return sval.eof();
+	}
+};  
+
 template <>
 struct __dispatch_parameter_do_set<std::string> {
 	static bool apply (const std::string& str_value, std::string& value) {
diff --git a/mia/core/parameter.hh b/mia/core/parameter.hh
index 69962a7..359f511 100644
--- a/mia/core/parameter.hh
+++ b/mia/core/parameter.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,12 +24,13 @@
 #include <string>
 #include <map>
 #include <ostream>
+#include <istream>
 #include <sstream>
 #include <mia/core/dictmap.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/core/handlerbase.hh>
 #include <mia/core/factory_trait.hh>
-
+#include <mia/core/cmdoptionflags.hh>
 
 namespace xmlpp {
 	class Element; 
@@ -395,8 +396,8 @@ private:
 /// an string parameter
 class EXPORT_CORE CStringParameter: public  CParameter {
 public: 
-	CStringParameter(std::string& value, bool required, const char *descr, 
-			 const CPluginHandlerBase *plugin_hint = NULL); 
+	CStringParameter(std::string& value, CCmdOptionFlags flags, const char *descr, 
+			 const CPluginHandlerBase *plugin_hint = nullptr); 
 
 private: 
 	virtual void do_reset();
@@ -411,6 +412,7 @@ private:
 
 	std::string& m_value;
 	std::string m_default_value; 
+	CCmdOptionFlags m_flags; 
 	const CPluginHandlerBase *m_plugin_hint; 
 }; 
 
diff --git a/mia/core/paramoption.cc b/mia/core/paramoption.cc
index 5cb299b..5bbd4b3 100644
--- a/mia/core/paramoption.cc
+++ b/mia/core/paramoption.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@ using std::ostringstream;
 CParamOption::CParamOption(char short_opt, const char *long_opt, CParameter *param):
 	CCmdOption(short_opt, long_opt, "", 
 		   long_opt, 
-		   param->required_set() ? CCmdOption::required : CCmdOption::not_required), 
+		   param->required_set() ? CCmdOptionFlags::required : CCmdOptionFlags::none), 
 	m_param(param)
 {
 	
diff --git a/mia/core/paramoption.hh b/mia/core/paramoption.hh
index 17495a2..16fc356 100644
--- a/mia/core/paramoption.hh
+++ b/mia/core/paramoption.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/pixeltype.cc b/mia/core/pixeltype.cc
index 585b4be..83363f0 100644
--- a/mia/core/pixeltype.cc
+++ b/mia/core/pixeltype.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/pixeltype.hh b/mia/core/pixeltype.hh
index 97144dd..300494d 100644
--- a/mia/core/pixeltype.hh
+++ b/mia/core/pixeltype.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/plugin_base.cc b/mia/core/plugin_base.cc
index e8e8dcf..6b395ba 100644
--- a/mia/core/plugin_base.cc
+++ b/mia/core/plugin_base.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -176,7 +176,7 @@ const char *g_plugin_root = nullptr;
 
 PrepareTestPluginPath::PrepareTestPluginPath()
 {
-	g_plugin_root = PLUGIN_TEST_ROOT "/" PLUGIN_INSTALL_PATH; 
+	g_plugin_root = MIA_BUILD_ROOT "/plugintest/" PLUGIN_INSTALL_PATH; 
 }
 
 PrepareTestPluginPath::~PrepareTestPluginPath()
@@ -185,6 +185,7 @@ PrepareTestPluginPath::~PrepareTestPluginPath()
 }
 
 #ifdef WIN32
+
 EXPORT_CORE const string get_plugin_root()
 {
 	static string result;
@@ -223,9 +224,8 @@ EXPORT_CORE const string get_plugin_root()
 	}
 	return result;
 }
-#else
-
 
+#else
 
 const string EXPORT_CORE get_plugin_root()
 {
@@ -239,6 +239,7 @@ const string EXPORT_CORE get_plugin_root()
 		return string(plugin_root); 
 	return string(PLUGIN_SEARCH_PATH);
 }
+
 #endif
 
 NS_MIA_END
diff --git a/mia/core/plugin_base.cxx b/mia/core/plugin_base.cxx
index 22b4dd8..6b2e254 100644
--- a/mia/core/plugin_base.cxx
+++ b/mia/core/plugin_base.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/plugin_base.hh b/mia/core/plugin_base.hh
index 08f9359..1c6f51a 100644
--- a/mia/core/plugin_base.hh
+++ b/mia/core/plugin_base.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -160,7 +160,6 @@ public:
 	 */
 	void add_dependend_handlers(HandlerHelpMap& handler_map); 
 
-protected:
 	/**
 	   Add a porperty to the map of supported properties
 	   \param property a named property
@@ -241,6 +240,16 @@ public:
 
 };
 
+/**
+   Some plug-ins can be chained directly at creation time. 
+   To make the factory aware of this interface, this trait is used. 
+*/
+
+template <typename Plugin> 
+struct plugin_can_chain {
+	static constexpr bool value = false; 
+	typedef void Chained; 
+}; 
 
 NS_MIA_END
 
diff --git a/mia/core/plugin_test.cc b/mia/core/plugin_test.cc
index ecd65b6..12a1e14 100644
--- a/mia/core/plugin_test.cc
+++ b/mia/core/plugin_test.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/probmap.cc b/mia/core/probmap.cc
index 4ca5090..798a602 100644
--- a/mia/core/probmap.cc
+++ b/mia/core/probmap.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/probmap.hh b/mia/core/probmap.hh
index 2b464a7..13f8c92 100644
--- a/mia/core/probmap.hh
+++ b/mia/core/probmap.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/product_base.cc b/mia/core/product_base.cc
index 21e2a36..0244f73 100644
--- a/mia/core/product_base.cc
+++ b/mia/core/product_base.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/product_base.hh b/mia/core/product_base.hh
index 81e65ad..7ca1254 100644
--- a/mia/core/product_base.hh
+++ b/mia/core/product_base.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/productcache.cc b/mia/core/productcache.cc
index 32746e6..f132a00 100644
--- a/mia/core/productcache.cc
+++ b/mia/core/productcache.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/productcache.hh b/mia/core/productcache.hh
index f7df0f7..e98ec2c 100644
--- a/mia/core/productcache.hh
+++ b/mia/core/productcache.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/property_flags.cc b/mia/core/property_flags.cc
index ef47d55..5b0e092 100644
--- a/mia/core/property_flags.cc
+++ b/mia/core/property_flags.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/property_flags.hh b/mia/core/property_flags.hh
index 74cc49a..b5185aa 100644
--- a/mia/core/property_flags.hh
+++ b/mia/core/property_flags.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/pwh.cc b/mia/core/pwh.cc
index 97d5511..42ab901 100644
--- a/mia/core/pwh.cc
+++ b/mia/core/pwh.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/pwh.hh b/mia/core/pwh.hh
index f25fb27..b202bc2 100644
--- a/mia/core/pwh.hh
+++ b/mia/core/pwh.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/refholder.hh b/mia/core/refholder.hh
index 7da1c0c..2827506 100644
--- a/mia/core/refholder.hh
+++ b/mia/core/refholder.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -17,6 +17,8 @@
  * along with MIA; if not, see <http://www.gnu.org/licenses/>.
  *
  */
+#ifndef mia_core_refholder_hh
+#define mia_core_refholder_hh
 
 #include <mia/core/defines.hh>
 #include <memory> 
@@ -56,3 +58,5 @@ private:
 }; 
 
 NS_MIA_END
+
+#endif 
diff --git a/mia/core/regmodel.cc b/mia/core/regmodel.cc
index 802916b..af856e5 100644
--- a/mia/core/regmodel.cc
+++ b/mia/core/regmodel.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/regmodel.hh b/mia/core/regmodel.hh
index 5a0aa4b..af72ea6 100644
--- a/mia/core/regmodel.hh
+++ b/mia/core/regmodel.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/revision.cc b/mia/core/revision.cc
index 29d48b5..be385c3 100644
--- a/mia/core/revision.cc
+++ b/mia/core/revision.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/scaler1d.cc b/mia/core/scaler1d.cc
index 46775b4..fb8cb1f 100644
--- a/mia/core/scaler1d.cc
+++ b/mia/core/scaler1d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/scaler1d.hh b/mia/core/scaler1d.hh
index f10e0be..4f9f91f 100644
--- a/mia/core/scaler1d.hh
+++ b/mia/core/scaler1d.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/seriesstats.cc b/mia/core/seriesstats.cc
index 9c4ff7c..3dc64bb 100644
--- a/mia/core/seriesstats.cc
+++ b/mia/core/seriesstats.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/seriesstats.hh b/mia/core/seriesstats.hh
index 597769d..8c8b44e 100644
--- a/mia/core/seriesstats.hh
+++ b/mia/core/seriesstats.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/shape.cc b/mia/core/shape.cc
index 1c6463b..6421d19 100644
--- a/mia/core/shape.cc
+++ b/mia/core/shape.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/shape.cxx b/mia/core/shape.cxx
index 48de1b0..faac0fc 100644
--- a/mia/core/shape.cxx
+++ b/mia/core/shape.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/shape.hh b/mia/core/shape.hh
index bdf2937..2a622ac 100644
--- a/mia/core/shape.hh
+++ b/mia/core/shape.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/simpson.hh b/mia/core/simpson.hh
index d768725..c5c7e52 100644
--- a/mia/core/simpson.hh
+++ b/mia/core/simpson.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/singular_refobj.hh b/mia/core/singular_refobj.hh
new file mode 100644
index 0000000..74422a7
--- /dev/null
+++ b/mia/core/singular_refobj.hh
@@ -0,0 +1,194 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_singular_refobj_hh
+#define mia_singular_refobj_hh
+
+
+#include <mia/core/defines.hh>
+#include <cassert>
+
+NS_MIA_BEGIN
+
+
+
+/**
+   \brief a singulater reference counted object that gets destroyed when the refount goes to zero 
+
+   This template handles singular objects that must no be copied (e.g. a resource)  
+   but that do also not fit the sigleton pattern. An example use are the HDF5 file, group, and 
+   dataset handles. 
+
+   \tparam T type of the data to be hold
+   \tparam D type of a functor that frees the resource. It must provide a static method 
+         static void apply(T& data) that frees the resource. 
+
+*/
+
+
+template <typename T> 
+class TSingleReferencedObject {
+public: 
+	struct Destructor {
+		Destructor(){}
+		virtual void operator ()(T& MIA_PARAM_UNUSED(data)) const = 0;
+	}; 
+
+	struct EmptyDestructor : public Destructor{
+		EmptyDestructor(){}
+		virtual void operator ()(T& MIA_PARAM_UNUSED(data))const {}
+	};
+
+	static const EmptyDestructor empty_destructor; 
+
+	TSingleReferencedObject(); 
+
+        TSingleReferencedObject(T data, const Destructor& d = empty_destructor);
+        
+        TSingleReferencedObject(const TSingleReferencedObject<T>& other);
+
+        TSingleReferencedObject& operator = (const TSingleReferencedObject<T>& other);
+
+        ~TSingleReferencedObject(); 
+
+        operator T()const; 
+
+        unsigned get_refcount()const; 
+        
+private: 
+        class TheObject {
+        public: 
+                TheObject(T data, const TSingleReferencedObject::Destructor& d); 
+                ~TheObject();
+                void add_ref(); 
+                bool del_ref();
+                T get() const; 
+
+                unsigned get_refcount()const; 
+        private: 
+                TheObject(const TheObject& data) = delete; 
+                TheObject& operator = (const TheObject& data) = delete; 
+                T m_data; 
+                unsigned m_refcount; 
+		const Destructor& m_destructor; 
+        }; 
+        TheObject *m_object; 
+}; 
+
+template <typename T> 
+const typename TSingleReferencedObject<T>::EmptyDestructor TSingleReferencedObject<T>::empty_destructor; 
+
+
+template <typename T> 
+TSingleReferencedObject<T>::TSingleReferencedObject():
+	m_object(nullptr)
+{
+}
+
+template <typename T> 
+TSingleReferencedObject<T>::TSingleReferencedObject(T data, const Destructor& d)
+{
+        m_object = new TheObject(data, d); 
+}
+
+template <typename T> 
+TSingleReferencedObject<T>::TSingleReferencedObject(const TSingleReferencedObject<T>& other)
+{
+        m_object = other.m_object; 
+        if (m_object)
+                m_object->add_ref(); 
+}
+
+template <typename T> 
+TSingleReferencedObject<T>& TSingleReferencedObject<T>::operator = (const TSingleReferencedObject<T>& other)
+{
+        if (m_object)
+                m_object->del_ref(); 
+        m_object = other.m_object; 
+        if (m_object)
+                m_object->add_ref(); 
+	return *this; 
+}
+
+template <typename T> 
+TSingleReferencedObject<T>::~TSingleReferencedObject()
+{
+        if (m_object)
+                if (m_object->del_ref()) 
+                        delete m_object; 
+}
+
+template <typename T> 
+TSingleReferencedObject<T>::operator T() const 
+{
+        return m_object->get();
+}
+
+template <typename T> 
+unsigned TSingleReferencedObject<T>::get_refcount()const
+{
+        if (m_object) 
+                return m_object->get_refcount(); 
+        else 
+                return 0; 
+}
+
+template <typename T> 
+TSingleReferencedObject<T>::TheObject::TheObject(T data, const Destructor& d):
+        m_data(data), 
+        m_refcount(1), 
+	m_destructor(d)
+{
+}
+
+template <typename T> 
+TSingleReferencedObject<T>::TheObject::~TheObject()
+{
+	assert(m_refcount == 0); 
+	m_destructor(m_data); 
+}
+                
+template <typename T> 
+void TSingleReferencedObject<T>::TheObject::add_ref()
+{
+        ++m_refcount; 
+}
+
+template <typename T> 
+bool TSingleReferencedObject<T>::TheObject::del_ref()
+{
+        --m_refcount; 
+        return (m_refcount <= 0); 
+}
+
+template <typename T> 
+unsigned TSingleReferencedObject<T>::TheObject::get_refcount()const
+{
+	return m_refcount; 
+}
+
+template <typename T> 
+T TSingleReferencedObject<T>::TheObject::get() const 
+{
+        return m_data; 
+}
+
+NS_MIA_END
+#endif 
diff --git a/mia/core/slopeclassifier.cc b/mia/core/slopeclassifier.cc
index e46a07b..323167b 100644
--- a/mia/core/slopeclassifier.cc
+++ b/mia/core/slopeclassifier.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/slopeclassifier.hh b/mia/core/slopeclassifier.hh
index 4625f29..f3d19e9 100644
--- a/mia/core/slopeclassifier.hh
+++ b/mia/core/slopeclassifier.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/slopestatistics.cc b/mia/core/slopestatistics.cc
index bc95b64..32203de 100644
--- a/mia/core/slopestatistics.cc
+++ b/mia/core/slopestatistics.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -64,6 +64,7 @@ struct CSlopeStatisticsImpl {
 	int get_index() const; 
 	std::pair<size_t, float>  get_gradient_peak(int start_movement) const; 
 	float get_level_change(size_t center) const; 
+	int get_max_frequency_slot() const; 
 private:
 
 	void evaluate_curve_length() const;
@@ -87,6 +88,8 @@ private:
 	mutable int m_start_movement;
 	mutable bool m_gradient_peak_valid;
 	mutable bool m_wt_valid;
+	mutable int m_max_freq_slot; 
+
 
 	mutable pair<size_t, float>  m_first_peak;
 	mutable pair<size_t, float>  m_gradient_peak;
@@ -272,10 +275,23 @@ float CSlopeStatisticsImpl::get_positive_time_mean() const
 }
 
 
+int CSlopeStatistics::get_max_frequency_slot() const
+{
+	assert(impl); 
+	return impl->get_max_frequency_slot(); 
+}
 
+int CSlopeStatisticsImpl::get_max_frequency_slot() const
+{
+	if (!m_mean_freq_valid)
+		evaluate_frequency(); 
+	return m_max_freq_slot; 
+}
 
 void CSlopeStatisticsImpl::evaluate_frequency() const
 {
+	float max_slot_energy = 0.0; 
+	m_max_freq_slot = 0; 
 	m_mean_freq = 0.0;
 	m_energy = 0.0;
 	CFFT1D_R2C fft(m_series.size());
@@ -287,6 +303,10 @@ void CSlopeStatisticsImpl::evaluate_frequency() const
 		float snorm = sqrt(n);
 		m_mean_freq += k * snorm;
 		m_energy += snorm;
+		if (max_slot_energy < snorm) {
+			max_slot_energy = snorm; 
+			m_max_freq_slot = k; 
+		}
 	}
 	m_mean_freq /= m_energy;
 	m_mean_freq_valid = true;
@@ -472,7 +492,12 @@ float CSlopeStatistics::get_level_change(size_t center) const
 
 float CSlopeStatisticsImpl::get_level_change(size_t center) const
 {
-	assert(center < m_series.size() - 1 && center > 0);
+	if (center >= m_series.size() - 1) {
+		return -(accumulate(m_series.begin(), m_series.begin(), 0.0f) / m_series.size()); 
+	}
+	if  (center <= 0) {
+		return (accumulate(m_series.begin(), m_series.begin(), 0.0f) / m_series.size()); 
+	}
 	
 	float before = accumulate(m_series.begin(), m_series.begin() + center, 0.0f) / center; 
 	float after = accumulate(m_series.begin() + center + 1, m_series.end(), 0.0f) / (m_series.size() - center - 1);
diff --git a/mia/core/slopestatistics.hh b/mia/core/slopestatistics.hh
index 4b368fc..17b1df6 100644
--- a/mia/core/slopestatistics.hh
+++ b/mia/core/slopestatistics.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -71,6 +71,10 @@ public:
 	/// \returns the mean of the norms of the positive terms of the FFT of this curve
 	float get_mean_frequency() const;
 
+	/// \returns the index of the maximum frequency energy  slot
+	int get_max_frequency_slot() const;
+
+
 	/// \returns the sum of the mean of the norms of the positive terms of the FFT of this curve
 	float get_energy() const; 
 	
diff --git a/mia/core/slopevector.hh b/mia/core/slopevector.hh
index 4bd791d..dd96f7c 100644
--- a/mia/core/slopevector.hh
+++ b/mia/core/slopevector.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/spacial_kernel.cc b/mia/core/spacial_kernel.cc
index 6a96fd0..759a9cd 100644
--- a/mia/core/spacial_kernel.cc
+++ b/mia/core/spacial_kernel.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -119,14 +119,9 @@ size_t C1DFoldingKernel::do_size()const
 
 
 
-using boost::filesystem::path; 
-C1DSpacialKernelPluginHandlerTestPath::C1DSpacialKernelPluginHandlerTestPath()
-{
-	C1DSpacialKernelPluginHandler::set_search_path({path(MIA_BUILD_ROOT"/mia/core/spacialkernel")}); 
-}
-
 template<>  const char * const 
-TPluginHandler<TFactory<C1DFoldingKernel>>::m_help = "These plug-ins provide folding kernel(s) for spacial separable filtering.";
+TPluginHandler<TFactory<C1DFoldingKernel>>::m_help = 
+	"These plug-ins provide folding kernel(s) for spacial separable filtering.";
 
 EXPLICIT_INSTANCE_HANDLER(C1DFoldingKernel); 
 
diff --git a/mia/core/spacial_kernel.hh b/mia/core/spacial_kernel.hh
index 88f73dd..703a34d 100644
--- a/mia/core/spacial_kernel.hh
+++ b/mia/core/spacial_kernel.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -173,17 +173,6 @@ inline P1DSpacialKernel produce_spacial_kernel(const std::string& descr)
 	return C1DSpacialKernelPluginHandler::instance().produce(descr); 
 }
 
-/** 
-    @cond INTERNAL  
-    \ingroup test 
-    \brief Class to initialiaze the plug-in search path fot testing without installing the plug-ins 
-*/
-class EXPORT_CORE C1DSpacialKernelPluginHandlerTestPath {
-public: 
-	C1DSpacialKernelPluginHandlerTestPath(); 
-}; 
-/// @endcond
-
 /// @cond NEVER
 FACTORY_TRAIT(C1DSpacialKernelPluginHandler); 
 /// @endcond
diff --git a/mia/core/spacialkernel/CMakeLists.txt b/mia/core/spacialkernel/CMakeLists.txt
index 3f87e86..bfa3a61 100644
--- a/mia/core/spacialkernel/CMakeLists.txt
+++ b/mia/core/spacialkernel/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/core/spacialkernel/gauss.cc b/mia/core/spacialkernel/gauss.cc
index 5f64a26..7c956e6 100644
--- a/mia/core/spacialkernel/gauss.cc
+++ b/mia/core/spacialkernel/gauss.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/spacialkernel/gauss.hh b/mia/core/spacialkernel/gauss.hh
index 64d3637..7438403 100644
--- a/mia/core/spacialkernel/gauss.hh
+++ b/mia/core/spacialkernel/gauss.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/spacialkernel/test_gauss.cc b/mia/core/spacialkernel/test_gauss.cc
index b4ff741..b4e07de 100644
--- a/mia/core/spacialkernel/test_gauss.cc
+++ b/mia/core/spacialkernel/test_gauss.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/sparse_solver.hh b/mia/core/sparse_solver.hh
index 56a0318..382fe03 100644
--- a/mia/core/sparse_solver.hh
+++ b/mia/core/sparse_solver.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/splinebc/CMakeLists.txt b/mia/core/splinebc/CMakeLists.txt
index 02a4e76..1778fbc 100644
--- a/mia/core/splinebc/CMakeLists.txt
+++ b/mia/core/splinebc/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/core/splinebc/bc.cc b/mia/core/splinebc/bc.cc
index ddc5942..468b96b 100644
--- a/mia/core/splinebc/bc.cc
+++ b/mia/core/splinebc/bc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/splinebc/bc.hh b/mia/core/splinebc/bc.hh
index 17bef68..13cff19 100644
--- a/mia/core/splinebc/bc.hh
+++ b/mia/core/splinebc/bc.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/splinebc/test_bc.cc b/mia/core/splinebc/test_bc.cc
index 85025a3..d558097 100644
--- a/mia/core/splinebc/test_bc.cc
+++ b/mia/core/splinebc/test_bc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,8 +32,6 @@ using std::vector;
 using std::setprecision; 
 using std::invalid_argument; 
 
-CSplineKernelTestPath kernel_test_path; 
-
 BOOST_AUTO_TEST_CASE( test_mirror_on_boundary_needed ) 
 {
 	CSplineKernel::VIndex index  = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; 
diff --git a/mia/core/splinekernel.cc b/mia/core/splinekernel.cc
index 14013ae..a0a50dc 100644
--- a/mia/core/splinekernel.cc
+++ b/mia/core/splinekernel.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -129,7 +129,9 @@ void CSplineKernel::get_cached(double x, SCache& cache)const
 	
 	// start index is same and inside the image, we can keep the new weights 
 	// only zero-boundary conditions must check if weights were changed 
-	if (start_idx == cache.start_idx && // cache.boundary_condition.is_zero() 
+	// for ABI compatibility we check only the range here, later it should go as
+	// virtual function into boundary_condition
+	if (start_idx == cache.start_idx && // !cache.boundary_condition.is_zero() 
 	    start_idx >= 0 && 
 	    cache.start_idx <=  cache.index_limit ) 
 		return; 
@@ -302,12 +304,6 @@ double  EXPORT_CORE integrate2(const CSplineKernel& spline, double s1, double s2
 	return sum * n;
 }
 
-using boost::filesystem::path; 
-CSplineKernelTestPath::CSplineKernelTestPath()
-{
-	CSplineKernelPluginHandler::set_search_path({path(MIA_BUILD_ROOT"/mia/core/splinekernel")}); 
-	
-}
 template<>  const char * const 
 TPluginHandler<TFactory<CSplineKernel>>::m_help = 
 	"These plug-ins provide various kernels that evaluate the wights in spline-based interpolation.";
diff --git a/mia/core/splinekernel.hh b/mia/core/splinekernel.hh
index e8c0ee1..d31c2c5 100644
--- a/mia/core/splinekernel.hh
+++ b/mia/core/splinekernel.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -312,16 +312,6 @@ inline PSplineKernel produce_spline_kernel(const std::string& descr)
 
 FACTORY_TRAIT(CSplineKernelPluginHandler); 
 
-
-/**   
-      \ingroup tests 
-      Class to set up the plug-in search path for spline kernels when running tests
-      in the build tree 
-*/
-struct EXPORT_CORE CSplineKernelTestPath {
-	CSplineKernelTestPath(); 
-}; 
-
 /**
    @cond INTERNAL 
    @ingroup traits 
diff --git a/mia/core/splinekernel/CMakeLists.txt b/mia/core/splinekernel/CMakeLists.txt
index b792308..96fddce 100644
--- a/mia/core/splinekernel/CMakeLists.txt
+++ b/mia/core/splinekernel/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/core/splinekernel/bspline.cc b/mia/core/splinekernel/bspline.cc
index c95ee53..99297e0 100644
--- a/mia/core/splinekernel/bspline.cc
+++ b/mia/core/splinekernel/bspline.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/splinekernel/bspline.hh b/mia/core/splinekernel/bspline.hh
index 182877a..027b6b9 100644
--- a/mia/core/splinekernel/bspline.hh
+++ b/mia/core/splinekernel/bspline.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/splinekernel/test_bspline.cc b/mia/core/splinekernel/test_bspline.cc
index 62a0a48..a7d936d 100644
--- a/mia/core/splinekernel/test_bspline.cc
+++ b/mia/core/splinekernel/test_bspline.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,8 +33,6 @@ using std::invalid_argument;
 
 namespace bmpl=boost::mpl;
 
-CSplineBoundaryConditionTestPath bc_path; 
-
 template <typename T, bool is_float>
 struct __dispatch_compare {
 	static void apply(T a, T b) {
diff --git a/mia/core/splineparzenmi.cc b/mia/core/splineparzenmi.cc
index 218203b..95a6eec 100644
--- a/mia/core/splineparzenmi.cc
+++ b/mia/core/splineparzenmi.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/splineparzenmi.hh b/mia/core/splineparzenmi.hh
index 7ca4c24..aa41596 100644
--- a/mia/core/splineparzenmi.hh
+++ b/mia/core/splineparzenmi.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -76,6 +76,25 @@ public:
 
 
 	/**
+	   Fill the histogram structures and caches by using a mask 
+	   @tparam MovIterator forward iterator type for moving image 
+	   @tparam RefIterator forward iterator type for reference image 
+	   @param mov_begin begin of moving image range 
+	   @param mov_end end of moving image range 
+	   @param ref_begin begin of reference image range 
+	   @param ref_end end of reference image range 
+	   @param mask_begin begin of mask image range 
+	   @param mask_end end of mask image range 
+	   
+	 */
+
+	template <typename MovIterator, typename RefIterator, typename MaskIterator>
+		void fill(MovIterator mov_begin, MovIterator mov_end, 
+			  RefIterator ref_begin, RefIterator ref_end, 
+			  MaskIterator mask_begin, MaskIterator mask_end);
+	
+
+	/**
 	   @returns the value of the mutual information that is maximized if the 
 	   given input images are equal. 
 	 */
@@ -142,6 +161,13 @@ private:
 	
 	template <typename Iterator>
 	std::pair<double,double> get_reduced_range(Iterator begin, Iterator end)const; 
+
+	template <typename DataIterator, typename MaskIterator>
+        std::pair<double,double> 
+		get_reduced_range_masked(DataIterator dbegin, 
+					 DataIterator dend, 
+					 MaskIterator mbegin)const; 
+		
 };   
 
 template <typename MovIterator, typename RefIterator>
@@ -216,6 +242,85 @@ BOOST_CONCEPT_REQUIRES( ((::boost::ForwardIterator<MovIterator>))
 	evaluate_log_cache(); 
 }
 
+
+template <typename MovIterator, typename RefIterator, typename MaskIterator>
+void CSplineParzenMI::fill(MovIterator mov_begin, MovIterator mov_end, 
+			   RefIterator ref_begin, RefIterator ref_end, 
+			   MaskIterator mask_begin, MaskIterator mask_end)
+{
+	std::fill(m_joined_histogram.begin(), m_joined_histogram.end(), 0.0); 
+
+	assert(mov_begin != mov_end); 
+	assert(ref_begin != ref_end); 
+	
+	// no mask 
+	if (mask_begin == mask_end) 
+		fill(mov_begin, mov_end, ref_begin, ref_end); 
+	
+	if (m_mov_max < m_mov_min) {
+		// (re)evaluate the ranges 
+		
+		auto mov_range = get_reduced_range_masked(mov_begin, mov_end, mask_begin); 
+		if (mov_range.second  ==  mov_range.first) 
+			throw std::invalid_argument("relevant moving image intensity range is zero"); 
+		m_mov_min = mov_range.first; 
+		m_mov_max = mov_range.second;
+		m_mov_scale = (m_mov_bins - 1) / (m_mov_max - m_mov_min); 
+		cvdebug() << "Mov Range = [" << m_mov_min << ", " << m_mov_max << "]\n"; 
+	}
+
+
+	if (m_ref_max < m_ref_min) {
+
+		auto ref_range = get_reduced_range_masked(ref_begin, ref_end, mask_begin); 
+		if (ref_range.second  ==  ref_range.first) 
+			throw std::invalid_argument("relevant reference image intensity range is zero"); 
+		
+		m_ref_min = ref_range.first; 
+		m_ref_max = ref_range.second; 
+		m_ref_scale = (m_ref_bins - 1) / (m_ref_max - m_ref_min); 
+		cvdebug() << "Ref Range = [" << m_ref_min << ", " << m_ref_max << "]\n"; 
+	}
+
+       
+	std::vector<double> mweights(m_mov_kernel->size()); 
+        std::vector<double> rweights(m_ref_kernel->size()); 
+	
+	size_t N = 0;         
+	while (ref_begin != ref_end && mov_begin != mov_end) {
+
+		if (*mask_begin) {
+			const double mov = scale_moving(*mov_begin); 
+			const double ref = scale_reference(*ref_begin); 
+			
+			const int mov_start = m_mov_kernel->get_start_idx_and_value_weights(mov, mweights) + m_mov_border; 
+			const int ref_start = m_ref_kernel->get_start_idx_and_value_weights(ref, rweights) + m_ref_border;  
+			
+			for (size_t r = 0; r < m_ref_kernel->size(); ++r) {
+				auto inbeg = m_joined_histogram.begin() + 
+					m_mov_real_bins * (ref_start + r) + mov_start; 
+				double rw = rweights[r]; 
+				std::transform(mweights.begin(), mweights.end(), inbeg, inbeg, 
+					       [rw](double mw, double jhvalue){ return mw * rw + jhvalue;});
+			}
+			
+			++N; 
+		}
+		++mask_begin; 
+		++mov_begin; 
+		++ref_begin; 
+	}
+
+	cvdebug() << "CSplineParzenMI::fill: counted " << N << " pixels\n"; 
+	// normalize joined histogram 
+	const double nscale = 1.0/N; 
+	transform(m_joined_histogram.begin(), m_joined_histogram.end(), m_joined_histogram.begin(), 
+		  [&nscale](double jhvalue){return jhvalue * nscale;}); 
+	
+	evaluate_histograms();  
+	evaluate_log_cache(); 
+}
+
 template <typename Iterator>
 std::pair<double,double> CSplineParzenMI::get_reduced_range(Iterator begin, Iterator end)const
 {
@@ -227,7 +332,58 @@ std::pair<double,double> CSplineParzenMI::get_reduced_range(Iterator begin, Iter
 	cvinfo() << "CSplineParzenMI: reduce range by "<< m_cut_histogram
 		<<"% from [" << *range.first << ", " << *range.second 
 		<< "] to [" << reduced_range.first << ", " << reduced_range.second << "]\n"; 
-	return std::pair<double,double>(reduced_range.first, reduced_range.second); 
+	return std::make_pair(reduced_range.first, reduced_range.second); 
+       
+}
+
+template <typename DataIterator, typename MaskIterator>
+std::pair<double,double> 
+CSplineParzenMI::get_reduced_range_masked(DataIterator dbegin, 
+					  DataIterator dend, 
+					  MaskIterator mbegin)const
+{
+	auto ib = dbegin; 
+	auto im = mbegin; 
+	
+	while (! *im++ && ib != dend) 
+		++ib; 
+	
+	if (ib == dend) 
+		throw std::runtime_error("CSplineParzenMI: empty mask"); 
+	
+	double range_max = *ib; 
+	double range_min = *ib; 
+	++ib; ++im; 
+	
+	while (ib != dend)  {
+		if (*im) {
+			if (*ib < range_min) 
+				range_min = *ib; 
+			if (*ib > range_max) 
+				range_max = *ib; 
+		}
+		++ib; 
+		++im; 
+	}
+	
+	
+	typedef THistogramFeeder<typename DataIterator::value_type> Feeder; 
+	THistogram<Feeder> h(Feeder(range_min, range_max, 4096));
+
+	ib = dbegin; 
+	im = mbegin; 
+	while (ib != dend)  {
+		if (*im)
+			h.push(*ib); 
+		++ib; 
+		++im; 
+	}
+
+	auto reduced_range = h.get_reduced_range(m_cut_histogram); 
+	cvinfo() << "CSplineParzenMI: reduce range by "<< m_cut_histogram
+		 << "% from [" << range_min << ", " << range_max
+		 << "] to [" << reduced_range.first << ", " << reduced_range.second << "]\n"; 
+	return std::make_pair(reduced_range.first, reduced_range.second); 
        
 }
 
diff --git a/mia/core/sqmin.cc b/mia/core/sqmin.cc
index 8e83e1c..b5e0d59 100644
--- a/mia/core/sqmin.cc
+++ b/mia/core/sqmin.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/sqmin.hh b/mia/core/sqmin.hh
index daf2f76..6df20ae 100644
--- a/mia/core/sqmin.hh
+++ b/mia/core/sqmin.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/statistics.hh b/mia/core/statistics.hh
index 2e07c09..96ac893 100644
--- a/mia/core/statistics.hh
+++ b/mia/core/statistics.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/streamredir.cc b/mia/core/streamredir.cc
index 7fb311e..7a128e3 100644
--- a/mia/core/streamredir.cc
+++ b/mia/core/streamredir.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/streamredir.hh b/mia/core/streamredir.hh
index a685d87..64367e2 100644
--- a/mia/core/streamredir.hh
+++ b/mia/core/streamredir.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/svector.hh b/mia/core/svector.hh
new file mode 100644
index 0000000..67ba31c
--- /dev/null
+++ b/mia/core/svector.hh
@@ -0,0 +1,93 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_core_svector_hh
+#define mia_core_svector_hh
+
+#include <istream>
+#include <ostream>
+#include <sstream>
+#include <vector>
+#include <stdexcept>
+
+#include <mia/core/errormacro.hh>
+#include <mia/core/typedescr.hh>
+
+NS_MIA_BEGIN
+
+template <typename T> 
+std::ostream&  operator << (std::ostream& os, const std::vector<T>& v) 
+{
+	for(auto x: v)
+		os << x << ","; 
+	return os; 
+}
+
+template <typename T> 
+struct __dispatch_translate {
+	static bool apply(const std::string& str, T& v){
+		char c; 
+		std::istringstream s(str); 
+		s >> v;
+		while (!s.eof() && s.peek() == ' ') 
+			s >> c; 
+		return s.eof(); 
+	}
+}; 
+
+template <> 
+struct __dispatch_translate<std::string> {
+	static bool apply(const std::string& s, std::string& str){
+		str = s; 
+		return true; 
+	}
+}; 
+
+
+template <typename T> 
+std::istream&  operator >> (std::istream& is, std::vector<T>& v)
+{
+	std::vector<T> values; 
+	std::string token; 
+	T val; 
+	
+	while(std::getline(is, token, ',')) {
+		if (__dispatch_translate<T>::apply(token, val))
+			values.push_back(val); 
+		else {
+			throw create_exception<std::invalid_argument>("Reading vector: value, '", token, 
+								      "' could not be translate to ", 
+								      mia::__type_descr<T>::value);
+		}
+	}
+	
+	if (!v.empty() && v.size() != values.size()) {
+			throw create_exception<std::invalid_argument>("Reading vector: expected ", 
+								 v.size(), " values, but got ", values.size()); 
+	}
+	v.swap(values); 
+	return is; 
+}
+
+
+NS_MIA_END
+
+#endif 
+
diff --git a/mia/core/test_Vector.cc b/mia/core/test_Vector.cc
index ff95155..fc325b7 100644
--- a/mia/core/test_Vector.cc
+++ b/mia/core/test_Vector.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_attributes.cc b/mia/core/test_attributes.cc
index 2a4f5bb..905496e 100644
--- a/mia/core/test_attributes.cc
+++ b/mia/core/test_attributes.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,9 +34,6 @@
 #include <mia/core/msgstream.hh>
 
 #include <boost/mpl/vector.hpp>
-//#include <boost/test/unit_test_suite.hpp>
-//#include <boost/test/test_case_template.hpp>
-//#include <boost/test/test_tools.hpp>
 
 NS_MIA_USE
 using namespace std;
@@ -162,6 +159,8 @@ void test_type_attribute()
 	attr = dynamic_cast<TAttribute<T>*>(attr_list["one"].get());
 	BOOST_REQUIRE(attr);
 	BOOST_REQUIRE(*attr == 1);
+
+	
 }
 
 
@@ -303,7 +302,7 @@ BOOST_AUTO_TEST_CASE( test_lists_equal )
 
 
 template <typename T>
-void check_add_and_read(CAttributeMap& map, const char *name, T value)
+void check_add_and_read(CAttributeMap& map, const char *name, T value, int id)
 {
 	typedef const TAttribute<T> * PAttr;
 	add_attribute(map, name, value);
@@ -312,10 +311,12 @@ void check_add_and_read(CAttributeMap& map, const char *name, T value)
 	BOOST_REQUIRE(attr);
 	T test_value = *attr;
 	BOOST_CHECK_EQUAL(value, test_value);
+
+	BOOST_CHECK_EQUAL(attr->type_id(), id); 
 }
 
 template <>
-void check_add_and_read(CAttributeMap& map, const char *name, const char *value)
+void check_add_and_read(CAttributeMap& map, const char *name, const char *value, int id)
 {
 	typedef const TAttribute<string>& PAttr;
 	add_attribute(map, name, value);
@@ -324,39 +325,40 @@ void check_add_and_read(CAttributeMap& map, const char *name, const char *value)
 	PAttr attr = dynamic_cast<PAttr>(*map[name].get());
 	string test_value = attr;
 	BOOST_CHECK_EQUAL(string(value), test_value);
+	BOOST_CHECK_EQUAL(map[name]->type_id(), id); 
 }
 
 BOOST_AUTO_TEST_CASE( test_add_attribute_int )
 {
 	CAttributeMap map;
-	check_add_and_read(map, "int", 10);
+	check_add_and_read(map, "int", 10, EAttributeType::attr_sint);
 }
 
 BOOST_AUTO_TEST_CASE( test_add_attribute_short )
 {
 	CAttributeMap map;
-	check_add_and_read(map, "short", (short)20);
+	check_add_and_read(map, "short", (short)20, EAttributeType::attr_sshort);
 }
 BOOST_AUTO_TEST_CASE( test_add_attribute_cstring )
 {
 	CAttributeMap map;
-	check_add_and_read(map, "char*", "char*_value");
+	check_add_and_read(map, "char*", "char*_value", EAttributeType::attr_string);
 }
 BOOST_AUTO_TEST_CASE( test_add_attribute_string )
 {
 	CAttributeMap map;
-	check_add_and_read(map, "string", string("string_value"));
+	check_add_and_read(map, "string", string("string_value"), EAttributeType::attr_string);
 }
 BOOST_AUTO_TEST_CASE( test_add_attribute_float )
 {
 	CAttributeMap map;
-	check_add_and_read(map, "float", 1.0f);
+	check_add_and_read(map, "float", 1.0f, EAttributeType::attr_float);
 }
 
 BOOST_AUTO_TEST_CASE( test_add_attribute )
 {
 	CAttributeMap map;
-	check_add_and_read(map, "double", 1.0);
+	check_add_and_read(map, "double", 1.0, EAttributeType::attr_double);
 
 }
 
@@ -395,43 +397,6 @@ bool operator==(PAttribute const & a, PAttribute const & b)
 	return *a == *b;
 }
 
-BOOST_AUTO_TEST_CASE( test_attribute_compare )
-{
-	PAttribute t1(new TAttribute<string>("testwert1"));
-	PAttribute t2(new TAttribute<string>("testwert2"));
-	PAttribute t3(new TAttribute<int>(1));
-	PAttribute t4(new TAttribute<int>(2));
-
-	BOOST_CHECK(*t1 < *t2);
-	BOOST_CHECK(*t2 < *t3);
-	BOOST_CHECK(*t3 < *t4);
-
-	BOOST_CHECK(!(*t4 < *t4));
-}
-
-BOOST_AUTO_TEST_CASE( test_attribute_as_map_key )
-{
-	map<PAttribute, string, pattr_less> testmap;
-
-	PAttribute t1(new CStringAttribute("testwert1"));
-	PAttribute t2(new CStringAttribute("testwert2"));
-	PAttribute t3(new CIntAttribute(1));
-	PAttribute t4(new CIntAttribute(1));
-
-	testmap[t1] = "stringvalue1";
-	testmap[t2] = "stringvalue2";
-	testmap[t3] = "intvalue1";
-
-	BOOST_CHECK_EQUAL(testmap[t3], "intvalue1");
-
-	testmap[t4] = "intvalue2";
-
-	BOOST_CHECK_EQUAL(testmap[t4], "intvalue2");
-	BOOST_CHECK_EQUAL(testmap[t3], "intvalue2");
-
-
-}
-
 BOOST_AUTO_TEST_CASE( test_get_attribute_as_non_existent )
 {
 	CAttributedData data;
diff --git a/mia/core/test_boundary_conditions.cc b/mia/core/test_boundary_conditions.cc
index dfda508..6c55a7e 100644
--- a/mia/core/test_boundary_conditions.cc
+++ b/mia/core/test_boundary_conditions.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,8 +25,6 @@
 using namespace mia; 
 using std::vector; 
 
-CSplineBoundaryConditionTestPath  bc_test_path; 
-
 BOOST_AUTO_TEST_CASE( test_BoundaryConditionsPlugins ) 
 {
 	const auto& handler = CSplineBoundaryConditionPluginHandler::instance();
diff --git a/mia/core/test_callback.cc b/mia/core/test_callback.cc
index e3f5f08..c4eb7d0 100644
--- a/mia/core/test_callback.cc
+++ b/mia/core/test_callback.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_cmdlineparser.cc b/mia/core/test_cmdlineparser.cc
index 07376ee..3d1dda1 100644
--- a/mia/core/test_cmdlineparser.cc
+++ b/mia/core/test_cmdlineparser.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -437,7 +437,7 @@ BOOST_FIXTURE_TEST_CASE( test_parser_help_output, CmdlineParserFixture )
 			  "                          fatal: Report only fatal errors\n"
 			  "     --copyright        print copyright information\n"
 			  "  -h --help             print this help\n"
-			  "     --help-xml         print help formatted as XML\n"
+			  "     --help-xml=NULL    print help formatted as XML\n"
 			  "  -? --usage            print a short help\n"
 			  "     --version          print the version number and exit\n\n"
 			  "Processing               \n"
@@ -455,7 +455,7 @@ BOOST_FIXTURE_TEST_CASE( test_parser_help_output, CmdlineParserFixture )
 			  "Example usage:\n  Example text\n"
 			  "    \n    test-program Example command\n\n"
 			  "Copyright:\n"
-			  "  This software is Copyright (c) Gert Wollny 1999-2013 Leipzig, \n"
+			  "  This software is Copyright (c) Gert Wollny 1999-2014 Leipzig, \n"
 			  "  Germany and Madrid, Spain. It comes with ABSOLUTELY NO WARRANTY and\n"
 			  "  you may redistribute it under the terms of the GNU GENERAL PUBLIC \n"
 			  "  LICENSE Version 3 (or later). For more information run the program \n"
diff --git a/mia/core/test_cmdoptionflags.cc b/mia/core/test_cmdoptionflags.cc
new file mode 100644
index 0000000..bf3fc05
--- /dev/null
+++ b/mia/core/test_cmdoptionflags.cc
@@ -0,0 +1,47 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/internal/autotest.hh>
+#include <mia/core/cmdoptionflags.hh>
+
+
+NS_MIA_USE; 
+
+BOOST_AUTO_TEST_CASE( test_some_combinations ) 
+{
+        BOOST_CHECK_EQUAL(CCmdOptionFlags::required_output & CCmdOptionFlags::output, CCmdOptionFlags::output); 
+        BOOST_CHECK_EQUAL(CCmdOptionFlags::required_input & CCmdOptionFlags::input, CCmdOptionFlags::input); 
+
+        BOOST_CHECK_EQUAL(CCmdOptionFlags::input | CCmdOptionFlags::required, CCmdOptionFlags::required_input);
+        BOOST_CHECK_EQUAL(CCmdOptionFlags::output | CCmdOptionFlags::required, CCmdOptionFlags::required_output);
+
+
+        BOOST_CHECK(has_flag(CCmdOptionFlags::required_output, CCmdOptionFlags::output)); 
+        BOOST_CHECK(has_flag(CCmdOptionFlags::required_input, CCmdOptionFlags::input)); 
+
+}
+
+BOOST_AUTO_TEST_CASE( test_some_ops ) 
+{
+        CCmdOptionFlags flags = CCmdOptionFlags::required_output; 
+        
+        flags -= CCmdOptionFlags::output; 
+        BOOST_CHECK_EQUAL(flags, CCmdOptionFlags::required); 
+}
diff --git a/mia/core/test_core.cc b/mia/core/test_core.cc
index a1f22ac..3a564ea 100644
--- a/mia/core/test_core.cc
+++ b/mia/core/test_core.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_cost.cc b/mia/core/test_cost.cc
index 42556b4..428e6f0 100644
--- a/mia/core/test_cost.cc
+++ b/mia/core/test_cost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_cstplan.cc b/mia/core/test_cstplan.cc
index 480d0e7..53dd875 100644
--- a/mia/core/test_cstplan.cc
+++ b/mia/core/test_cstplan.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_datapool.cc b/mia/core/test_datapool.cc
index 6db8727..1914cac 100644
--- a/mia/core/test_datapool.cc
+++ b/mia/core/test_datapool.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_delayedparameter.cc b/mia/core/test_delayedparameter.cc
index 72c0101..6065d60 100644
--- a/mia/core/test_delayedparameter.cc
+++ b/mia/core/test_delayedparameter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_dictmap.cc b/mia/core/test_dictmap.cc
index 6c2001e..dd23c38 100644
--- a/mia/core/test_dictmap.cc
+++ b/mia/core/test_dictmap.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_distance.cc b/mia/core/test_distance.cc
index 859d499..fba7914 100644
--- a/mia/core/test_distance.cc
+++ b/mia/core/test_distance.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_factoryoption.cc b/mia/core/test_factoryoption.cc
index 57d08d4..14852d2 100644
--- a/mia/core/test_factoryoption.cc
+++ b/mia/core/test_factoryoption.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -122,6 +122,28 @@ BOOST_AUTO_TEST_CASE( test_a2_factory_option )
 	BOOST_CHECK_EQUAL(option->get_value_as_string(), "lala"); 
 }
 
+BOOST_AUTO_TEST_CASE( test_string_factory_hint_check_valide)
+{
+        string value;
+        PCmdOption popt(make_opt(value, "string", 's', "a string option",
+                                 CCmdOptionFlags::validate, &CFactoryHandlerMock::instance() ));
+
+
+        BOOST_CHECK_NO_THROW(popt->set_value("lala:stuff=no"));
+
+}
+
+BOOST_AUTO_TEST_CASE( test_string_factory_hint_check_fail)
+{
+        string value;
+        PCmdOption popt(make_opt(value, "string", 's', "a string option",
+                                 CCmdOptionFlags::validate, &CFactoryHandlerMock::instance() ));
+
+
+        BOOST_CHECK_THROW(popt->set_value("lalo:stuff=no"), invalid_argument);
+}
+
+
 BOOST_AUTO_TEST_CASE( test_a2_factory_option_unique )
 {
 
diff --git a/mia/core/test_fft1d.cc b/mia/core/test_fft1d.cc
index d6a6699..8e9a7cc 100644
--- a/mia/core/test_fft1d.cc
+++ b/mia/core/test_fft1d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_fftslopeclassifier.cc b/mia/core/test_fftslopeclassifier.cc
index 2965a7d..22b494f 100644
--- a/mia/core/test_fftslopeclassifier.cc
+++ b/mia/core/test_fftslopeclassifier.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_fifofilter.cc b/mia/core/test_fifofilter.cc
index 888ec96..291f077 100644
--- a/mia/core/test_fifofilter.cc
+++ b/mia/core/test_fifofilter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_filetools.cc b/mia/core/test_filetools.cc
index a3343d7..5dc6e3c 100644
--- a/mia/core/test_filetools.cc
+++ b/mia/core/test_filetools.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_filter.cc b/mia/core/test_filter.cc
index e5bf7df..107a806 100644
--- a/mia/core/test_filter.cc
+++ b/mia/core/test_filter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_fixedwidthoutput.cc b/mia/core/test_fixedwidthoutput.cc
index bc6dad8..db392af 100644
--- a/mia/core/test_fixedwidthoutput.cc
+++ b/mia/core/test_fixedwidthoutput.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_flagstring.cc b/mia/core/test_flagstring.cc
index f0f0d81..9964b7f 100644
--- a/mia/core/test_flagstring.cc
+++ b/mia/core/test_flagstring.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_fullstats.cc b/mia/core/test_fullstats.cc
index 201842d..e362fa6 100644
--- a/mia/core/test_fullstats.cc
+++ b/mia/core/test_fullstats.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_handler.cc b/mia/core/test_handler.cc
index 80aeb8b..fff2ca4 100644
--- a/mia/core/test_handler.cc
+++ b/mia/core/test_handler.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -46,7 +46,6 @@ namespace bfs = ::boost::filesystem;
 BOOST_AUTO_TEST_CASE( test_dummy_plugin_handler_parallel )
 {
 	CTestPluginHandler::set_search_path({bfs::path("testplug")});
-
 	auto callback = [](const tbb::blocked_range<int>& range, int init){
 		
 		CThreadMsgStream thread_stream;
@@ -88,6 +87,8 @@ BOOST_AUTO_TEST_CASE( test_dummy_plugin_handler_parallel )
 
 BOOST_AUTO_TEST_CASE( test_dummy_plugin_handler )
 {
+	CTestPluginHandler::set_search_path({bfs::path("testplug")});
+	
 	const CTestPluginHandler::Instance& handler = CTestPluginHandler::instance();
 
 	BOOST_CHECK(handler.size() == 3);
diff --git a/mia/core/test_helpers.hh b/mia/core/test_helpers.hh
index 2c32b54..7747bb5 100644
--- a/mia/core/test_helpers.hh
+++ b/mia/core/test_helpers.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_histogram.cc b/mia/core/test_histogram.cc
index e1e2e2a..5d00c42 100644
--- a/mia/core/test_histogram.cc
+++ b/mia/core/test_histogram.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -209,8 +209,6 @@ BOOST_AUTO_TEST_CASE ( test_histogram_gauss_noise )
 
 	vector<double> data;
 
-	CNoiseGeneratorPluginHandler::set_search_path({bfs::path("noise")});
-
 	const CNoiseGeneratorPluginHandler::Instance&  ngp = CNoiseGeneratorPluginHandler::instance();
 
 	auto ng = ngp.produce("gauss:mu=127,sigma=16,seed=1");
diff --git a/mia/core/test_history.cc b/mia/core/test_history.cc
index d89e318..172c640 100644
--- a/mia/core/test_history.cc
+++ b/mia/core/test_history.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_ica.cc b/mia/core/test_ica.cc
index 8f6e47c..ad7855e 100644
--- a/mia/core/test_ica.cc
+++ b/mia/core/test_ica.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_index.cc b/mia/core/test_index.cc
index 8982d91..2bb8c63 100644
--- a/mia/core/test_index.cc
+++ b/mia/core/test_index.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_interpol.cc b/mia/core/test_interpol.cc
index 8d5839c..f1728c9 100644
--- a/mia/core/test_interpol.cc
+++ b/mia/core/test_interpol.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_interpolator1d.cc b/mia/core/test_interpolator1d.cc
index f904387..e73f29c 100644
--- a/mia/core/test_interpolator1d.cc
+++ b/mia/core/test_interpolator1d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,8 +29,6 @@ using namespace std;
 using namespace mia;
 namespace bfs=boost::filesystem; 
 
-CSplineBoundaryConditionTestPath bc_path; 
-
 struct InterpolatorIDFixture  {
 
 	double f(double x) const;
@@ -41,14 +39,6 @@ struct InterpolatorIDFixture  {
 
 };
 
-struct Initialiaze {
-	Initialiaze() {
-		CSplineKernelPluginHandler::set_search_path({bfs::path("splinekernel")}); 
-	}
-}; 
-
-Initialiaze set_path; 
-
 BOOST_FIXTURE_TEST_CASE( test_linear, InterpolatorIDFixture)
 {
 
diff --git a/mia/core/test_iohandler.cc b/mia/core/test_iohandler.cc
index f2744e2..ffbf83a 100644
--- a/mia/core/test_iohandler.cc
+++ b/mia/core/test_iohandler.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -97,3 +97,17 @@ BOOST_FIXTURE_TEST_CASE(  test_datapool_io, DummyPluginFixture )
 	}
 }
 
+BOOST_FIXTURE_TEST_CASE(  test_dummy_valid_file_name, DummyPluginFixture )
+{
+	const auto&  handler = CTestIOPluginHandler::instance();
+	
+	
+	BOOST_CHECK(handler.validate_parameter_string("somefile.@")); 
+	BOOST_CHECK(handler.validate_parameter_string("somefile.hey")); 
+	BOOST_CHECK(!handler.validate_parameter_string("somefile.nonsense")); 
+	
+	// the data pool should not allow gzip extension 
+	// BOOST_CHECK(!handler.validate_parameter_string("somefile. at .gz")); 
+	
+	
+}
diff --git a/mia/core/test_kernels.cc b/mia/core/test_kernels.cc
index 178617b..59127b7 100644
--- a/mia/core/test_kernels.cc
+++ b/mia/core/test_kernels.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_kmeans.cc b/mia/core/test_kmeans.cc
index 40bcf1f..7922790 100644
--- a/mia/core/test_kmeans.cc
+++ b/mia/core/test_kmeans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_labelmap.cc b/mia/core/test_labelmap.cc
index 34cfbb5..23aac0c 100644
--- a/mia/core/test_labelmap.cc
+++ b/mia/core/test_labelmap.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_meanvar.cc b/mia/core/test_meanvar.cc
index e88b971..6c2461c 100644
--- a/mia/core/test_meanvar.cc
+++ b/mia/core/test_meanvar.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_minimizer.cc b/mia/core/test_minimizer.cc
index 318978d..95a198a 100644
--- a/mia/core/test_minimizer.cc
+++ b/mia/core/test_minimizer.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -54,9 +54,6 @@ const char *minimizer_property = "CMinimizerMock";
 
 BOOST_AUTO_TEST_CASE( test_load_minimizer_plugins )	
 {
-	CPathNameArray  searchpath({bfs::path("minimizer")}); 
-	CMinimizerPluginHandler::set_search_path(searchpath); 
-
 	const CMinimizerPluginHandler::Instance& handler = CMinimizerPluginHandler::instance();
 
 	BOOST_CHECK_EQUAL(handler.size(), 3u); 
diff --git a/mia/core/test_nccsum.cc b/mia/core/test_nccsum.cc
new file mode 100644
index 0000000..5277309
--- /dev/null
+++ b/mia/core/test_nccsum.cc
@@ -0,0 +1,174 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <mia/internal/plugintester.hh>
+#include <mia/core/nccsum.hh>
+
+using namespace mia; 
+
+BOOST_AUTO_TEST_CASE( test_nccsum_has_samples ) 
+{
+	NCCSums sums; 
+	BOOST_CHECK(!sums.has_samples()); 
+	sums.add(1,2); 
+	BOOST_CHECK(sums.has_samples()); 
+}
+
+BOOST_AUTO_TEST_CASE( test_nccsum_equal ) 
+{
+        const float src_data[4] = { 1, 1, 1, 3 }; 
+
+
+        NCCSums sums_equal; 
+        
+        for (int i = 0; i < 4; ++i) 
+                sums_equal.add(src_data[i], src_data[i]); 
+
+        BOOST_CHECK_SMALL(sums_equal.value(), 1e-5); 
+
+        std::pair<double, NCCGradHelper> vgh = sums_equal.get_grad_helper(); 
+
+        BOOST_CHECK_SMALL(vgh.first, 1e-5); 
+
+        for (int i = 0; i < 4; ++i) 
+                BOOST_CHECK_SMALL(vgh.second.get_gradient_scale(src_data[i], src_data[i]), 1e-5f);
+}
+
+BOOST_AUTO_TEST_CASE( test_nccsum_no_corr ) 
+{
+        const float src_data[4] = { 1, 1, 1, 1 }; 
+        const float ref_data[4] = { 0, 2, 2, 0 }; 
+
+
+        NCCSums sums_equal; 
+        
+        for (int i = 0; i < 4; ++i) 
+                sums_equal.add(src_data[i], ref_data[i]); 
+
+        BOOST_CHECK_CLOSE(sums_equal.value(), 1.0, 1e-5); 
+
+        std::pair<double, NCCGradHelper> vgh = sums_equal.get_grad_helper(); 
+
+        BOOST_CHECK_CLOSE(vgh.first, 1.0, 1e-5); 
+
+        // the correlation is at its minimum (and the cost function at the max) 
+        // therefore the gradient is zero. 
+        for (int i = 0; i < 4; ++i) 
+                BOOST_CHECK_SMALL(vgh.second.get_gradient_scale(src_data[i], ref_data[i]), 1e-5f);
+}
+
+BOOST_AUTO_TEST_CASE( test_nccsum_summed ) 
+{
+	const float src_data1[4] = { 1, 1, 1, 4 }; 
+        const float ref_data1[4] = { 2, 2, 2, 8 }; 
+	const float src_data2[4] = { 2, 3, 1, 2 }; 
+        const float ref_data2[4] = { 1, 2, 4, 3 }; 
+	
+	NCCSums sums1; 
+	NCCSums sums2; 
+	NCCSums sum; 
+	
+	for (int i = 0; i < 4; ++i) {
+                sums1.add(src_data1[i], ref_data1[i]); 
+                sums2.add(src_data2[i], ref_data2[i]); 
+		sum.add(src_data1[i], ref_data1[i]); 
+		sum.add(src_data2[i], ref_data2[i]); 
+	}
+
+	NCCSums sump = sums1 + sums2; 
+	BOOST_CHECK_CLOSE(sump.value(), sum.value(), 0.01); 
+
+}
+
+BOOST_AUTO_TEST_CASE( test_nccsum_double ) 
+{
+        const float src_data[4] = { 1, 1, 1, 4 }; 
+        const float ref_data[4] = { 2, 2, 2, 8 }; 
+
+
+        NCCSums sums_equal; 
+        
+        for (int i = 0; i < 4; ++i) 
+                sums_equal.add(src_data[i], ref_data[i]); 
+
+        BOOST_CHECK_SMALL(sums_equal.value(), 1e-5); 
+
+        std::pair<double, NCCGradHelper> vgh = sums_equal.get_grad_helper(); 
+
+        BOOST_CHECK_SMALL(vgh.first, 1e-5); 
+
+        // the correlation is at its minimum (and the cost function at the max) 
+        // therefore the gradient is zero. 
+        for (int i = 0; i < 4; ++i) 
+                BOOST_CHECK_SMALL(vgh.second.get_gradient_scale(src_data[i], ref_data[i]), 1e-5f);
+}
+
+
+BOOST_AUTO_TEST_CASE( test_nccsum_zero_with_corr ) 
+{
+        const float src_data[4] = { 1, 1, 1, 1 }; 
+
+
+        NCCSums sums_equal; 
+        
+        for (int i = 0; i < 4; ++i) 
+                sums_equal.add(src_data[i], src_data[i]); 
+
+        BOOST_CHECK_SMALL(sums_equal.value(), 1e-5); 
+
+        std::pair<double, NCCGradHelper> vgh = sums_equal.get_grad_helper(); 
+
+        BOOST_CHECK_SMALL(vgh.first, 1e-5); 
+
+        // the correlation is at its minimum (and the cost function at the max) 
+        // therefore the gradient is zero. 
+        for (int i = 0; i < 4; ++i) 
+                BOOST_CHECK_SMALL(vgh.second.get_gradient_scale(src_data[i], src_data[i]), 1e-5f);
+}
+
+
+BOOST_AUTO_TEST_CASE( test_nccsum_some_corr ) 
+{
+        const float src_data[4] = { 1, 1, 2, 1 }; 
+        const float ref_data[4] = { 0, 2, 2, 1 }; 
+
+
+        NCCSums sums_equal; 
+        
+        for (int i = 0; i < 4; ++i) 
+                sums_equal.add(src_data[i], ref_data[i]); 
+
+        BOOST_CHECK_CLOSE(sums_equal.value(), 1.0 - 0.27272727, 1e-5); 
+
+        std::pair<double, NCCGradHelper> vgh = sums_equal.get_grad_helper(); 
+
+        BOOST_CHECK_CLOSE(vgh.first, 1.0 - 0.27272727, 1e-5); 
+
+        // the correlation is at its minimum (and the cost function at the max) 
+        // therefore the gradient is zero. 
+        float v0 = 0.7272727272; 
+        float v1 = -0.7272727272; 
+        BOOST_CHECK_CLOSE(vgh.second.get_gradient_scale(src_data[0], ref_data[0]), v0, 0.1);
+        BOOST_CHECK_CLOSE(vgh.second.get_gradient_scale(src_data[1], ref_data[1]), v1, 0.1);
+        BOOST_CHECK_SMALL(vgh.second.get_gradient_scale(src_data[2], ref_data[2]), 1e-5f);
+        BOOST_CHECK_SMALL(vgh.second.get_gradient_scale(src_data[3], ref_data[3]), 1e-5f);
+        
+}
diff --git a/mia/core/test_noisegen.cc b/mia/core/test_noisegen.cc
index 9ba1f19..48431f1 100644
--- a/mia/core/test_noisegen.cc
+++ b/mia/core/test_noisegen.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_optionparser.cc b/mia/core/test_optionparser.cc
index f69f263..b33d5e5 100644
--- a/mia/core/test_optionparser.cc
+++ b/mia/core/test_optionparser.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -69,12 +69,11 @@ BOOST_AUTO_TEST_CASE( test_parsing)
 
 	CComplexOptionParser::CParts parts;
 	CParsedOptions option;
-	typedef CComplexOptionParser::CParts::value_type CValue;
 
 	option["x1"] = string("value1");
 	option["x2"] = string("value2");
 
-	parts.insert(CValue("alpha", option));
+	parts.push_back(make_pair("alpha", option));
 
 	option.clear();
 
@@ -83,7 +82,7 @@ BOOST_AUTO_TEST_CASE( test_parsing)
 	option["x3"] = string("v3");
 	option["x4"] = string("v4");
 
-	parts.insert(CValue("beta", option));
+	parts.push_back(make_pair("beta", option));
 
 	option.clear();
 
@@ -92,10 +91,10 @@ BOOST_AUTO_TEST_CASE( test_parsing)
 	option["z3"] = string("value3");
 	option["z4"] = string("v4");
 
-	parts.insert(CValue("alpha", option));
+	parts.push_back(make_pair("alpha", option));
 
 	option.clear();
-	parts.insert(CValue("gamma", option));
+	parts.push_back(make_pair("gamma", option));
 
 	string param = parts2string(parts.begin(), parts.end());
 	CComplexOptionParser scanner(param);
@@ -134,3 +133,32 @@ BOOST_AUTO_TEST_CASE( test_parsing_exponents )
 	BOOST_CHECK( a != part->second.end()); 
 	BOOST_CHECK_EQUAL(a->second, "1e+6"); 
 }
+
+BOOST_AUTO_TEST_CASE( test_parsing_chain )
+{
+	const char *paramstr="ssd:c=[1e+6]+mi:b=12,c=3";
+	CComplexOptionParser scanner(paramstr);
+	BOOST_REQUIRE(scanner.size() == 2);
+
+	auto part = scanner.begin();
+
+	BOOST_CHECK_EQUAL(part->first, "ssd");
+	BOOST_CHECK_EQUAL(part->second.size(), 1);
+	auto a = part->second.find("c"); 
+	BOOST_CHECK( a != part->second.end()); 
+	BOOST_CHECK_EQUAL(a->second, "1e+6"); 
+
+	++part; 
+
+	BOOST_CHECK_EQUAL(part->first, "mi");
+	BOOST_CHECK_EQUAL(part->second.size(), 2);
+	a = part->second.find("c"); 
+	BOOST_REQUIRE( a != part->second.end()); 
+	BOOST_CHECK_EQUAL(a->second, "3"); 
+
+
+	a = part->second.find("b"); 
+	BOOST_REQUIRE( a != part->second.end()); 
+	BOOST_CHECK_EQUAL(a->second, "12"); 
+	
+}
diff --git a/mia/core/test_optparam.cc b/mia/core/test_optparam.cc
index 299bc77..d996674 100644
--- a/mia/core/test_optparam.cc
+++ b/mia/core/test_optparam.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,7 +50,8 @@ void try_parsing_and_setting(const char *options, const params& expect)
 	pm["kill"] =  CParamList::PParameter(new CBoolParameter(read.kill, false, "a bool value"));
 	pm["min"] =   CParamList::PParameter(new CFloatParameter(read.min, -100, 20, true, "a float value"));
 	pm["max"] =   CParamList::PParameter(new CFloatParameter(read.max, -10, 200, true, "a float value"));
-	pm["nana"] =  CParamList::PParameter(new CStringParameter(read.nana, true, "a string value"));
+	pm["nana"] =  CParamList::PParameter(new CStringParameter(read.nana, CCmdOptionFlags::required,
+								  "a string value"));
 	pm["n"] =     CParamList::PParameter(new CIntParameter(read.n, -200, 100, true, "an int value"));
 
 	CComplexOptionParser cpo(options);
@@ -73,7 +74,7 @@ void try_parsing_and_setting(const char *options, const params& expect, params r
 	pm["kill"] =  CParamList::PParameter(new CBoolParameter(read.kill, false, "a bool value"));
 	pm["min"] =   CParamList::PParameter(new CFloatParameter(read.min, -100, 20, false, "a float value"));
 	pm["max"] =   CParamList::PParameter(new CFloatParameter(read.max, -10, 200, false, "a float value"));
-	pm["nana"] =  CParamList::PParameter(new CStringParameter(read.nana, false, "a string value"));
+	pm["nana"] =  CParamList::PParameter(new CStringParameter(read.nana, CCmdOptionFlags::none, "a string value"));
 	pm["n"] =     CParamList::PParameter(new CIntParameter(read.n, -200, 100, false, "an int value"));
 
 	CComplexOptionParser cpo(options);
@@ -155,7 +156,7 @@ BOOST_AUTO_TEST_CASE( test_reset )
 		pm["kill"] =  CParamList::PParameter(new CBoolParameter(read.kill, false, "a bool value"));
 		pm["min"] =   CParamList::PParameter(new CFloatParameter(read.min, -100, 20, false, "a float value"));
 		pm["max"] =   CParamList::PParameter(new CFloatParameter(read.max, -10, 200, false, "a float value"));
-		pm["nana"] =  CParamList::PParameter(new CStringParameter(read.nana, false, "a string value"));
+		pm["nana"] =  CParamList::PParameter(new CStringParameter(read.nana, CCmdOptionFlags::none, "a string value"));
 		pm["n"] =     CParamList::PParameter(new CIntParameter(read.n, -200, 100, false, "an int value"));
 		
 		CComplexOptionParser cpo("plugin:kill=0,min=1.1,nana=ping,max=3.1,n=1");
diff --git a/mia/core/test_parameter.cc b/mia/core/test_parameter.cc
index d9a3412..628b773 100644
--- a/mia/core/test_parameter.cc
+++ b/mia/core/test_parameter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA 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 +31,7 @@
 #include <mia/core/parameter.hh>
 #include <mia/core/msgstream.hh>
 
+#include <mia/core/parameter.cxx>
 
 NS_MIA_USE
 
@@ -46,7 +47,7 @@ BOOST_AUTO_TEST_CASE( test_params )
 
 	CIntParameter   param_int(int_val, -2, 5, true, "an integer value");
 	CFloatParameter param_float(float_val, -10, 200, true, "a float value");
-	CStringParameter param_string(string_val, true, "a string value");
+	CStringParameter param_string(string_val, CCmdOptionFlags::required, "a string value");
 	CBoolParameter   param_bool(bool_val, false, "a bool value");
 
 	BOOST_CHECK_THROW( CIntParameter(int_val, 5, -2, false, "impossible"), std::invalid_argument);
@@ -143,6 +144,20 @@ BOOST_AUTO_TEST_CASE( test_set_params)
 	BOOST_CHECK_THROW(!testp1.set("gjhgjhdf"), std::invalid_argument);
 }
 
+BOOST_AUTO_TEST_CASE( test_vector_param)
+{
+	vector<int> val; 
+	CTParameter<vector<int>> testp1(val, false, "some vector valued parameter");
+	
+	BOOST_CHECK(testp1.set("2,3,1,2"));
+	BOOST_CHECK_EQUAL(val.size(), 4u);
+
+	BOOST_CHECK_EQUAL(val[0], 2); 
+	BOOST_CHECK_EQUAL(val[1], 3); 
+	BOOST_CHECK_EQUAL(val[2], 1); 
+	BOOST_CHECK_EQUAL(val[3], 2); 
+}
+
 
 
 
diff --git a/mia/core/test_parseroutput.cc b/mia/core/test_parseroutput.cc
index 3d08826..e434d3a 100644
--- a/mia/core/test_parseroutput.cc
+++ b/mia/core/test_parseroutput.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_pixeltype.cc b/mia/core/test_pixeltype.cc
index 2f09c5a..1608f48 100644
--- a/mia/core/test_pixeltype.cc
+++ b/mia/core/test_pixeltype.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_probmap.cc b/mia/core/test_probmap.cc
index f9a6d94..cf3a445 100644
--- a/mia/core/test_probmap.cc
+++ b/mia/core/test_probmap.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_productcache.cc b/mia/core/test_productcache.cc
index cd80865..fc829a1 100644
--- a/mia/core/test_productcache.cc
+++ b/mia/core/test_productcache.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_property_flags.cc b/mia/core/test_property_flags.cc
index 5642029..7bb58a0 100644
--- a/mia/core/test_property_flags.cc
+++ b/mia/core/test_property_flags.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_pwh.cc b/mia/core/test_pwh.cc
index 911a7f3..9db20e9 100644
--- a/mia/core/test_pwh.cc
+++ b/mia/core/test_pwh.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_register.cc b/mia/core/test_register.cc
index d4e52f3..ec7f6db 100644
--- a/mia/core/test_register.cc
+++ b/mia/core/test_register.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_scaler1d.cc b/mia/core/test_scaler1d.cc
index 11ae531..00572f9 100644
--- a/mia/core/test_scaler1d.cc
+++ b/mia/core/test_scaler1d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -39,8 +39,6 @@ using namespace std;
 using namespace boost::unit_test;
 namespace bfs = ::boost::filesystem;
 
-CSplineBoundaryConditionTestPath bc_path; 
-
 struct Scaler1DFixture  {
 	Scaler1DFixture(); 
 
@@ -130,9 +128,6 @@ Scaler1DFixture::Scaler1DFixture():
 	data(256, false)
 {
 
-	CPathNameArray  sksearchpath({bfs::path("splinekernel")});
-	CSplineKernelPluginHandler::set_search_path(sksearchpath); 
-	
 	const double intervall = 2 * M_PI / 255.0; 
 
 	for(size_t x = 0; x < 256; ++x)
diff --git a/mia/core/test_seriesstats.cc b/mia/core/test_seriesstats.cc
index 416398e..f60b857 100644
--- a/mia/core/test_seriesstats.cc
+++ b/mia/core/test_seriesstats.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_shape.cc b/mia/core/test_shape.cc
index 8adb6ee..d563777 100644
--- a/mia/core/test_shape.cc
+++ b/mia/core/test_shape.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_simpson.cc b/mia/core/test_simpson.cc
index e858bf8..896f6cd 100644
--- a/mia/core/test_simpson.cc
+++ b/mia/core/test_simpson.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_singular_refobj.cc b/mia/core/test_singular_refobj.cc
new file mode 100644
index 0000000..dd28152
--- /dev/null
+++ b/mia/core/test_singular_refobj.cc
@@ -0,0 +1,66 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/singular_refobj.hh>
+#include <mia/internal/autotest.hh>
+
+using namespace mia; 
+
+BOOST_AUTO_TEST_CASE ( test_singlular_refobj )
+{
+        TSingleReferencedObject<int> myobj1(1); 
+        TSingleReferencedObject<int> myobj2(2); 
+
+        TSingleReferencedObject<int> myotherobje(myobj1); 
+        
+        BOOST_CHECK_EQUAL(myotherobje, 1); 
+        BOOST_CHECK_EQUAL(myobj1.get_refcount(), 2u); 
+
+        myotherobje = myobj2; 
+        BOOST_CHECK_EQUAL(myobj1.get_refcount(), 1u); 
+        
+        BOOST_CHECK_EQUAL(myotherobje, 2);
+        BOOST_CHECK_EQUAL(myobj2.get_refcount(), 2u); 
+        
+}
+
+BOOST_AUTO_TEST_CASE ( test_singlular_refobj_empty )
+{
+	TSingleReferencedObject<int> myobj; 
+	BOOST_CHECK_EQUAL(myobj.get_refcount(), 0u); 
+
+	TSingleReferencedObject<int> myobj2(myobj); 
+	BOOST_CHECK_EQUAL(myobj.get_refcount(), 0u); 
+}
+
+BOOST_AUTO_TEST_CASE ( test_singlular_refobj_empty_then_copy )
+{
+	TSingleReferencedObject<int> myobj; 
+	BOOST_CHECK_EQUAL(myobj.get_refcount(), 0u); 
+
+	TSingleReferencedObject<int> myobj2(1); 
+	myobj = myobj2; 
+	BOOST_CHECK_EQUAL(myobj.get_refcount(), 2u); 
+
+	myobj2 = TSingleReferencedObject<int>(); 
+	BOOST_CHECK_EQUAL(myobj2.get_refcount(), 0u);
+	BOOST_CHECK_EQUAL(myobj.get_refcount(), 1u); 
+	
+}
diff --git a/mia/core/test_slopeclassifier.cc b/mia/core/test_slopeclassifier.cc
index 8f97aa9..eb9f7dc 100644
--- a/mia/core/test_slopeclassifier.cc
+++ b/mia/core/test_slopeclassifier.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_slopestatistics.cc b/mia/core/test_slopestatistics.cc
index 2576e53..eb19d25 100644
--- a/mia/core/test_slopestatistics.cc
+++ b/mia/core/test_slopestatistics.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_sparse_solver.cc b/mia/core/test_sparse_solver.cc
index d37eed6..aabb184 100644
--- a/mia/core/test_sparse_solver.cc
+++ b/mia/core/test_sparse_solver.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_splinekernel.cc b/mia/core/test_splinekernel.cc
index 5ac1405..bf5c6c9 100644
--- a/mia/core/test_splinekernel.cc
+++ b/mia/core/test_splinekernel.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,9 +34,6 @@ NS_MIA_USE
 using namespace std;
 using namespace boost;
 
-CSplineKernelTestPath init_path; 
-CSplineBoundaryConditionTestPath bc_path; 
-
 BOOST_AUTO_TEST_CASE( test_plugin_availability ) 
 {
 	const auto& handler = CSplineKernelPluginHandler::instance();
diff --git a/mia/core/test_splineparzenmi.cc b/mia/core/test_splineparzenmi.cc
index 7856ae2..e9abb7e 100644
--- a/mia/core/test_splineparzenmi.cc
+++ b/mia/core/test_splineparzenmi.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,8 +34,6 @@ using namespace std;
 using namespace boost::unit_test;
 namespace bfs=boost::filesystem; 
 
-CNoiseGeneratorPluginHandlerTestPath noise_kernel_init_path; 
-
 struct SplineMutualInformationFixture  {
 	SplineMutualInformationFixture();
 
@@ -295,8 +293,3 @@ BOOST_FIXTURE_TEST_CASE( test_MI_76_13, CSplineParzenMIFixture )
 	double test_grad = dm(13, 76 ); 
 	BOOST_CHECK_CLOSE(grad, test_grad, 0.1); 
 }
-
-
-
-
-
diff --git a/mia/core/test_sqmin.cc b/mia/core/test_sqmin.cc
index a4c6aac..517bb3d 100644
--- a/mia/core/test_sqmin.cc
+++ b/mia/core/test_sqmin.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_statistics.cc b/mia/core/test_statistics.cc
index 6968d6f..9653809 100644
--- a/mia/core/test_statistics.cc
+++ b/mia/core/test_statistics.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_streamredir.cc b/mia/core/test_streamredir.cc
index 70e8601..1118c62 100644
--- a/mia/core/test_streamredir.cc
+++ b/mia/core/test_streamredir.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_streamvector.cc b/mia/core/test_streamvector.cc
new file mode 100644
index 0000000..7450397
--- /dev/null
+++ b/mia/core/test_streamvector.cc
@@ -0,0 +1,100 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <sstream>
+#include <vector>
+
+#include <mia/internal/autotest.hh>
+#include <mia/core/svector.hh>
+
+using namespace std; 
+using namespace mia; 
+
+BOOST_AUTO_TEST_CASE( test_read_strings_to_empty_vector ) 
+{
+	istringstream is("test1,test2,test3"); 
+	
+	vector<string> result; 
+	is >> result; 
+
+	BOOST_REQUIRE(result.size() == 3u); 
+	
+	BOOST_CHECK_EQUAL(result[0], "test1"); 
+	BOOST_CHECK_EQUAL(result[1], "test2"); 
+	BOOST_CHECK_EQUAL(result[2], "test3");
+}
+
+BOOST_AUTO_TEST_CASE( test_read_strings_to_presized_vector ) 
+{
+	istringstream is("test1,test2,test3"); 
+	
+	vector<string> result(3); 
+	is >> result; 
+
+	BOOST_REQUIRE(result.size() == 3u); 
+	BOOST_CHECK_EQUAL(result[0], "test1"); 
+	BOOST_CHECK_EQUAL(result[1], "test2"); 
+	BOOST_CHECK_EQUAL(result[2], "test3");
+
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_read_strings_to_presized_vector_too_many ) 
+{
+	istringstream is("test1,test2,test3"); 
+	
+	vector<string> result(2); 
+	BOOST_CHECK_THROW(is >> result, invalid_argument); 
+}
+
+BOOST_AUTO_TEST_CASE( test_read_strings_to_presized_vector_throw_not_enough ) 
+{
+	istringstream is("test1,test2,test3"); 
+	
+	vector<string> result(4); 
+	BOOST_CHECK_THROW(is >> result, invalid_argument); 
+}
+
+BOOST_AUTO_TEST_CASE( test_read_float ) 
+{
+	istringstream is("1.0,1e-10,3.0"); 
+	
+	vector<float> result; 
+	is >> result; 
+
+	BOOST_REQUIRE(result.size() == 3u); 
+	BOOST_CHECK_EQUAL(result[0], 1.0f); 
+	BOOST_CHECK_EQUAL(result[1], 1e-10f); 
+	BOOST_CHECK_EQUAL(result[2], 3.0f);
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_read_float_fail ) 
+{
+	istringstream is("1.0f,1e-10,3.0"); 
+	
+	vector<float> result; 
+	BOOST_CHECK_THROW(is >> result, invalid_argument); 
+}
+
+
+
+
diff --git a/mia/core/test_threadedmsg.cc b/mia/core/test_threadedmsg.cc
index e768ef4..9f0b68f 100644
--- a/mia/core/test_threadedmsg.cc
+++ b/mia/core/test_threadedmsg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_tools.cc b/mia/core/test_tools.cc
index 7fe51b4..3f84d51 100644
--- a/mia/core/test_tools.cc
+++ b/mia/core/test_tools.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_utils.cc b/mia/core/test_utils.cc
index e358973..8a093bd 100644
--- a/mia/core/test_utils.cc
+++ b/mia/core/test_utils.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_watch.cc b/mia/core/test_watch.cc
index 44780a5..390e756 100644
--- a/mia/core/test_watch.cc
+++ b/mia/core/test_watch.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/test_waveletslopeclassifier.cc b/mia/core/test_waveletslopeclassifier.cc
index 4c370e6..56a5020 100644
--- a/mia/core/test_waveletslopeclassifier.cc
+++ b/mia/core/test_waveletslopeclassifier.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -61,7 +61,7 @@ void SlopeClassifierFixture::run(size_t length, size_t components, const float *
 		for (size_t c = 0; c < components; ++c, ++i)
 			columns[c][r]  = *i;
 
-	CWaveletSlopeClassifier c(columns, mean_stripped);
+	CWaveletSlopeClassifier c(columns, mean_stripped, -1);
 	check_equal(c.get_movement_idx(), result.periodic_idx, "periodic index"); 
 	check_equal(c.get_RV_idx(), result.RV_idx, "RV index");
 	
@@ -427,7 +427,7 @@ BOOST_FIXTURE_TEST_CASE( test_classifier_5_O1a , SlopeClassifierFixture )
 		2.08701,   4.45134,  -1.44584,  -4.01091,  -4.37968,
 		4.04924,   3.69677,-0.0889484,  -9.95966, -0.413756,
 		0.585227,   2.99372, -0.863572,  -4.15864,   8.00943,
-		-1.20131,   3.27061,-0.0777571,  -2.53295,   8.29044,
+		-1.20141,   3.27061,-0.0777571,  -2.53295,   8.29044,
 		-0.711145,   4.17774,   1.73297,  -1.58116,  -4.50367,
 		2.30682,   3.01388,   2.83435,  -5.12192,  -5.33368,
 		0.669934,   2.71462,   3.84647,  -8.90214,   1.42903,
@@ -529,7 +529,7 @@ BOOST_FIXTURE_TEST_CASE( test_classifier_5_O1b , SlopeClassifierFixture )
 		-0.847239,   11.0478,   2.29227,  0.515116,  -0.50884,
 		0.904234,    5.8041,    1.0846,  -10.7599,  0.766765,
 		0.602109,  -1.42075,   1.70485,  -7.12815, -0.957428,
-		0.20139,  -2.01366,   1.93427,  0.956927,  -1.35333,
+		0.20149,  -2.01366,   1.93427,  0.956927,  -1.35333,
 		-0.358474,   4.57577,   1.49353,    5.6365,  -2.09492,
 		0.70094,   7.10685,   1.04098,  -8.12112,  -1.63661,
 		1.09538,   2.19787,  0.563649,  -11.1879,  0.513716,
diff --git a/mia/core/testplug/CMakeLists.txt b/mia/core/testplug/CMakeLists.txt
index f606d62..c5b1854 100644
--- a/mia/core/testplug/CMakeLists.txt
+++ b/mia/core/testplug/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/core/testplug/dummy1.cc b/mia/core/testplug/dummy1.cc
index 378f5f1..d83e746 100644
--- a/mia/core/testplug/dummy1.cc
+++ b/mia/core/testplug/dummy1.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/testplug/dummy2.cc b/mia/core/testplug/dummy2.cc
index fc751db..d8ac527 100644
--- a/mia/core/testplug/dummy2.cc
+++ b/mia/core/testplug/dummy2.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/testplug/lala.cc b/mia/core/testplug/lala.cc
index aeb8108..c63b0c7 100644
--- a/mia/core/testplug/lala.cc
+++ b/mia/core/testplug/lala.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,13 +30,14 @@ private:
 	PData do_load(const string& fname) const;
 	bool do_save(const string& fname, const Data& data) const;
 	const string do_get_descr() const;
-	std::string do_get_preferred_suffix() const; 
+	const std::string do_get_preferred_suffix() const; 
 };
 
 CLalaIOPlugin::CLalaIOPlugin():
 	CTestIOPlugin("la")
 {
 	add_suffix(".la"); 
+	add_suffix(".hey"); 
 }
 
 CLalaIOPlugin::PData  CLalaIOPlugin::do_load(const string& /*fname*/) const
@@ -55,7 +56,7 @@ const string CLalaIOPlugin::do_get_descr() const
 	return "a dummy plugin to test io-plugin handling";
 }
 
-std::string CLalaIOPlugin::do_get_preferred_suffix() const
+const std::string CLalaIOPlugin::do_get_preferred_suffix() const
 {
 	return "hey"; 
 }
diff --git a/mia/core/testplug/lolo.cc b/mia/core/testplug/lolo.cc
index 3efd594..e777699 100644
--- a/mia/core/testplug/lolo.cc
+++ b/mia/core/testplug/lolo.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/testplugin.cc b/mia/core/testplugin.cc
index 9cc73ce..9562451 100644
--- a/mia/core/testplugin.cc
+++ b/mia/core/testplugin.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -72,6 +72,7 @@ CTestPlugin *CTestPluginHandlerImpl::get_plugin(const char *name) const
 template<> 
 const char * const TPluginHandler<CTestPlugin>::m_help = "This is a handler for the test plug-ins"; 
 
+template class TPlugin<test_plugin_data, test_plugin_type>; 
 template class TPluginHandler<CTestPlugin>;
 template class THandlerSingleton<CTestPluginHandlerImpl>;
 
diff --git a/mia/core/testplugin.hh b/mia/core/testplugin.hh
index 4cdc314..cfc4125 100644
--- a/mia/core/testplugin.hh
+++ b/mia/core/testplugin.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,11 +32,14 @@ struct test_plugin_data;
 /// constant defining a test property 
 EXPORT_CORE extern const char *const test_property;
 
+extern template class EXPORT_CORE TPlugin<test_plugin_data, test_plugin_type>; 
+
 /**
    \ingroup test 
    \brief Class to test plugin handling. 
 */
 
+
 class EXPORT_CORE CTestPlugin: public TPlugin<test_plugin_data, test_plugin_type>  {
 public:
 	/// Construct the test plugin with the given name 
@@ -47,6 +50,10 @@ public:
 };
 
 
+template <> const char * const TPluginHandler<CTestPlugin>::m_help; 
+
+extern template class EXPORT_CORE TPluginHandler<CTestPlugin>;
+
 /**
    \ingroup test 
    \brief Class to test plugin handling. 
@@ -69,6 +76,11 @@ public:
 };
 
 
+
+
+extern template class EXPORT_CORE THandlerSingleton<CTestPluginHandlerImpl>;
+
+
 /** \ingroup test  
     Test plugin handler, only used internally for thesing the plugin handler 
 */
diff --git a/mia/core/threadedmsg.cc b/mia/core/threadedmsg.cc
index eb5deca..cffca9d 100644
--- a/mia/core/threadedmsg.cc
+++ b/mia/core/threadedmsg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/threadedmsg.hh b/mia/core/threadedmsg.hh
index 51772c6..0d97d38 100644
--- a/mia/core/threadedmsg.hh
+++ b/mia/core/threadedmsg.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/tools.hh b/mia/core/tools.hh
index 595bbcc..79aec9a 100644
--- a/mia/core/tools.hh
+++ b/mia/core/tools.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/traits.hh b/mia/core/traits.hh
index 24d8118..bd91bc9 100644
--- a/mia/core/traits.hh
+++ b/mia/core/traits.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/transformation.hh b/mia/core/transformation.hh
index 34369c5..bd9a645 100644
--- a/mia/core/transformation.hh
+++ b/mia/core/transformation.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -67,6 +67,13 @@ public:
 	*/
 	std::shared_ptr<D> operator () (const D& input) const; 
 
+	/** Apply the transformation to the input data 
+	    \param input 
+	    \param ipf_override overide the image interpolator 
+	    \returns a shared pointer to the transformed input data
+	*/
+	std::shared_ptr<D> operator () (const D& input, const I& ipf_override) const; 
+	
 	/**
 	   Set the interpolator factory 
 	   \param ipf the new interpolator factory 
@@ -140,6 +147,12 @@ const I& Transformation<D, I>::get_interpolator_factory() const
 }
 
 template <typename D, typename I>
+std::shared_ptr<D> Transformation<D,I>::operator () (const D& input, const I& ipf_override) const
+{
+	return do_transform(input, ipf_override); 
+}
+
+template <typename D, typename I>
 std::shared_ptr<D > Transformation<D,I>::operator() (const D& input) const
 {
 	return do_transform(input, m_ipf); 
diff --git a/mia/core/type_traits.hh b/mia/core/type_traits.hh
index e65569f..6da2428 100644
--- a/mia/core/type_traits.hh
+++ b/mia/core/type_traits.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/typedescr.cc b/mia/core/typedescr.cc
index 06088e5..346f0ff 100644
--- a/mia/core/typedescr.cc
+++ b/mia/core/typedescr.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/typedescr.hh b/mia/core/typedescr.hh
index e898ac6..ed7c62d 100644
--- a/mia/core/typedescr.hh
+++ b/mia/core/typedescr.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/utils.cc b/mia/core/utils.cc
index f786d4b..53c5b4c 100644
--- a/mia/core/utils.cc
+++ b/mia/core/utils.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/utils.hh b/mia/core/utils.hh
index 925a6b4..792350e 100644
--- a/mia/core/utils.hh
+++ b/mia/core/utils.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,6 +24,7 @@
 #include <limits>
 #include <string>
 #include <sstream>
+#include <iostream>
 #include <vector>
 #include <cmath>
 #include <stdexcept>
@@ -182,6 +183,15 @@ T mia_round_clamped(double x)
 	return __round_clamped<T, is_floating_point>::apply(x); 
 }
 
+
+inline void eat_char( std::istream& is, char expect_val, const char *message) 
+{
+	char c; 
+	is >> c; 
+	if ( c != expect_val)
+		throw std::runtime_error(message); 
+}
+
 NS_MIA_END
 
 #endif
diff --git a/mia/core/vector.hh b/mia/core/vector.hh
index 982113a..b148e35 100644
--- a/mia/core/vector.hh
+++ b/mia/core/vector.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
 #include <memory>
 #include <cstring>
 #include <cassert>
+#include <ostream>
 
 NS_MIA_BEGIN
 
@@ -235,6 +236,17 @@ private:
 }; 
 
 
+template <typename T> 
+std::ostream&  operator << (std::ostream& os, const Vector<T>& v) 
+{
+        os << "["; 
+        for(auto i: v) 
+                os << i << ", "; 
+        os << "]"; 
+        return os; 
+}
+
+
 /** 
     \ingroup misc
     
diff --git a/mia/core/watch.cc b/mia/core/watch.cc
index 1f53784..e48f584 100644
--- a/mia/core/watch.cc
+++ b/mia/core/watch.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/watch.hh b/mia/core/watch.hh
index ad74794..1a4e9e0 100644
--- a/mia/core/watch.hh
+++ b/mia/core/watch.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/core/waveletslopeclassifier.cc b/mia/core/waveletslopeclassifier.cc
index 5139b56..80b69b6 100644
--- a/mia/core/waveletslopeclassifier.cc
+++ b/mia/core/waveletslopeclassifier.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -55,16 +55,16 @@ struct CWaveletSlopeClassifierImpl {
 	typedef vector<float>::const_iterator position;
 	typedef pair<position, position> extrems;
 	typedef pair<size_t, size_t> extrems_pos;
-	CWaveletSlopeClassifierImpl(const CWaveletSlopeClassifier::Columns& series, bool mean_stripped);
+	CWaveletSlopeClassifierImpl(const CWaveletSlopeClassifier::Columns& series, bool mean_stripped, float min_freq);
 	CWaveletSlopeClassifierImpl(); 
 };
 
 
-CWaveletSlopeClassifier::CWaveletSlopeClassifier(const CWaveletSlopeClassifier::Columns& m, bool mean_stripped)
+CWaveletSlopeClassifier::CWaveletSlopeClassifier(const CWaveletSlopeClassifier::Columns& m, bool mean_stripped, float min_freq)
 {
 	if (m.size() < 3)
 		throw invalid_argument("CWaveletSlopeClassifier: require at least 3 curves");
-	impl = new CWaveletSlopeClassifierImpl(m, mean_stripped);
+	impl = new CWaveletSlopeClassifierImpl(m, mean_stripped, min_freq);
 }
 
 CWaveletSlopeClassifier::CWaveletSlopeClassifier(const CWaveletSlopeClassifier& other):
@@ -75,7 +75,7 @@ CWaveletSlopeClassifier::CWaveletSlopeClassifier():
 	impl(new CWaveletSlopeClassifierImpl())
 {
 }
-		     
+	     
 CWaveletSlopeClassifier& CWaveletSlopeClassifier::operator =(const CWaveletSlopeClassifier& other)
 {
 	if (this != &other) {
@@ -160,7 +160,7 @@ CWaveletSlopeClassifierImpl::CWaveletSlopeClassifierImpl():
 {
 }
 
-CWaveletSlopeClassifierImpl::CWaveletSlopeClassifierImpl(const CWaveletSlopeClassifier::Columns& series, bool mean_stripped):
+CWaveletSlopeClassifierImpl::CWaveletSlopeClassifierImpl(const CWaveletSlopeClassifier::Columns& series, bool mean_stripped, float min_freq):
 	RV_peak(-1), 
 	LV_peak(-1), 
 	RV_idx(-1), 
@@ -172,6 +172,7 @@ CWaveletSlopeClassifierImpl::CWaveletSlopeClassifierImpl(const CWaveletSlopeClas
 	max_movment_energy(0.0), 
 	n_movement_components(0), 
 	result(CWaveletSlopeClassifier::wsc_fail)
+
 {
 	vector<PSlopeStatistics> vstats; 
 	for (unsigned int i = 0; i < series.size(); ++i)
@@ -194,17 +195,25 @@ CWaveletSlopeClassifierImpl::CWaveletSlopeClassifierImpl(const CWaveletSlopeClas
 
 
 	cvdebug() << "Movement coeff weights:" << movement_pos << "\n"; 
-	bool ifree_breathing = ((movement_pos[CSlopeStatistics::ecp_center] > movement_pos[CSlopeStatistics::ecp_begin]) &&
-				(movement_pos[CSlopeStatistics::ecp_center] > movement_pos[CSlopeStatistics::ecp_end]));
-
-	// handle free breathing and series that only end with breath holding in the same way 
-	if  ((!ifree_breathing) && (movement_pos[CSlopeStatistics::ecp_end] < movement_pos[CSlopeStatistics::ecp_begin]))
-		ifree_breathing = true; 
 	
-	if (ifree_breathing) 
+	int skip_idx = 0; 
+	bool ifree_breathing = false; 
+	if (min_freq != 0.0) {
+		((movement_pos[CSlopeStatistics::ecp_center] > movement_pos[CSlopeStatistics::ecp_begin]) &&
+		 (movement_pos[CSlopeStatistics::ecp_center] > movement_pos[CSlopeStatistics::ecp_end]));
+		
+		// handle free breathing and series that only end with breath holding in the same way 
+		if  ((!ifree_breathing) && (movement_pos[CSlopeStatistics::ecp_end] < movement_pos[CSlopeStatistics::ecp_begin]))
+			ifree_breathing = true; 
+	}else 
+		skip_idx = 1; 
+	
+
+	if (ifree_breathing) {
 		cvmsg() << "Detected data set with (initial) free breathing.\n"; 
-	else 
+	}else {
 		cvmsg() << "Detected data set with initial breath holding.\n"; 
+	}
 	
 	int low_energy_start_idx = 1; //ifree_breathing ? 0 : 1;
 	
@@ -217,6 +226,7 @@ CWaveletSlopeClassifierImpl::CWaveletSlopeClassifierImpl(const CWaveletSlopeClas
 	int min_range_idx = -1; 
 	float min_range  = numeric_limits<float>::max(); 
 
+	bool got_movement = false; 
 	vector<bool> is_high_freq(series.size()); 
 	for (size_t i = 0; i < series.size(); ++i) {
 		auto e = vstats[i]->get_level_coefficient_sums(); 
@@ -225,7 +235,7 @@ CWaveletSlopeClassifierImpl::CWaveletSlopeClassifierImpl(const CWaveletSlopeClas
 			  << " end= " << movement_idx - 1
 			  << "\n"; 
 
-		float low_freq = accumulate(e.begin() + low_energy_start_idx, e.begin() + movement_idx, 0.0); 
+		float low_freq = accumulate(e.begin() + low_energy_start_idx, e.begin() + movement_idx-skip_idx, 0.0); 
 		float high_freq = e[movement_idx] + e[movement_idx + 1];
 		
 		if (min_range > vstats[i]->get_range()) {
@@ -248,8 +258,25 @@ CWaveletSlopeClassifierImpl::CWaveletSlopeClassifierImpl(const CWaveletSlopeClas
 				is_high_freq[i] = false; 
 			}
 		}
+		got_movement |= is_high_freq[i]; 
 	}
-
+	
+	// got no movement, try with frequency analysis 
+	if (!got_movement && min_freq > 0.0f) {
+		for (size_t i = 0; i < series.size(); ++i) {
+			is_high_freq[i] = vstats[i]->get_mean_frequency() > min_freq; 
+			if (is_high_freq[i]) {
+				if (vstats[i]->get_mean_energy_position() == CSlopeStatistics::ecp_begin) {
+					cvinfo() << "c=" << i << ":override motion because we assume it's RV enhacement\n";
+					is_high_freq[i] = false; 
+				}
+				cvinfo() << "Slope " << i << " << detected as movement based on mean frequency slot " << vstats[i]->get_mean_frequency() << "\n"; 
+			}else 
+				cvinfo() << "Slope " << i << " << rejected as movement based on mean frequency slot " << vstats[i]->get_mean_frequency() << "\n"; 
+		}
+	}
+	
+	
 
 	// if the mean is stripped, the baseline vanishes 
 	if (mean_stripped) {
diff --git a/mia/core/waveletslopeclassifier.hh b/mia/core/waveletslopeclassifier.hh
index db80686..29e8268 100644
--- a/mia/core/waveletslopeclassifier.hh
+++ b/mia/core/waveletslopeclassifier.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,8 +56,9 @@ public:
 	   Initialize the classifier with the given curves and the information whether the means were stripped 
 	   @param m matrix of curves 
 	   @param mean_stripped
+	   @param min_freq minimum breatjing frequency to consider movement, set to <0 to diable this test 
 	 */
-	CWaveletSlopeClassifier(const Columns& m, bool mean_stripped);
+	CWaveletSlopeClassifier(const Columns& m, bool mean_stripped, float min_freq);
 
 	/** copy constructor */
 	CWaveletSlopeClassifier(const CWaveletSlopeClassifier& other);
@@ -98,7 +99,7 @@ public:
 
 	/** @returns the general result of the identification */
 	EAnalysisResult result() const; 
-	
+
 private:
 	struct CWaveletSlopeClassifierImpl *impl;
 };
diff --git a/mia/internal/autotest.hh b/mia/internal/autotest.hh
index d65977c..eef1447 100644
--- a/mia/internal/autotest.hh
+++ b/mia/internal/autotest.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,6 +38,7 @@
 
 #include <miaconfig.h>
 #include <mia/core/cmdlineparser.hh>
+#include <mia/core/plugin_base.hh>
 #include <mia/internal/main.hh>
 
 const mia::SProgramDescription description = {
@@ -48,12 +49,22 @@ const mia::SProgramDescription description = {
 	{mia::pdi_example_code, ""}
 };
 
+void test_pluginsets(const std::set< std::string >& plugins, const std::set<std::string>& test_data) 
+{
+	BOOST_CHECK_EQUAL(plugins.size(), test_data.size()); 
+	for (auto p = plugins.begin(); p != plugins.end(); ++p) {
+		BOOST_CHECK_MESSAGE(test_data.find(*p) != test_data.end(), "unexpected plugin '" << *p << "' found"); 
+	}
+	
+	for (auto p = test_data.begin(); p != test_data.end(); ++p)
+		BOOST_CHECK_MESSAGE(plugins.find(*p) != plugins.end(), "expected plugin '" << *p << "' not found"); 
+}
+
 
 int BOOST_TEST_CALL_DECL
 do_main( int argc, char* argv[] )
 {
-	// set the plug-in path for tests 
-	setenv("MIA_PLUGIN_TESTPATH", MIA_BUILD_ROOT "/plugintest/" PLUGIN_INSTALL_PATH ,1);
+	mia::PrepareTestPluginPath prepare_plugin_path; 
 #ifdef WIN32
 	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
 	_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
diff --git a/mia/internal/main.hh b/mia/internal/main.hh
index e15a4da..7428739 100644
--- a/mia/internal/main.hh
+++ b/mia/internal/main.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/internal/pluginsettest.hh b/mia/internal/pluginsettest.hh
index 866733e..0c6fce9 100644
--- a/mia/internal/pluginsettest.hh
+++ b/mia/internal/pluginsettest.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/internal/plugintester.hh b/mia/internal/plugintester.hh
index 1cb17ed..f755059 100644
--- a/mia/internal/plugintester.hh
+++ b/mia/internal/plugintester.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,6 +36,7 @@
 #include <miaconfig.h>
 #include <mia/core/factory.hh>
 #include <mia/core/cmdlineparser.hh>
+#include <mia/core/plugin_base.hh>
 #include <mia/internal/main.hh>
 
 NS_MIA_BEGIN 
@@ -66,7 +67,7 @@ const mia::SProgramDescription description = {
 int BOOST_TEST_CALL_DECL
 do_main( int argc, char* argv[] )
 {
-	setenv("MIA_PLUGIN_TESTPATH", MIA_BUILD_ROOT "/plugintest/" PLUGIN_INSTALL_PATH,1);
+	mia::PrepareTestPluginPath prepare_plugin_path; 
 #ifdef WIN32
 	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
 	_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );
diff --git a/mia/mesh.hh b/mia/mesh.hh
index 55216ac..606c51c 100644
--- a/mia/mesh.hh
+++ b/mia/mesh.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/CMakeLists.txt b/mia/mesh/CMakeLists.txt
index 20bd870..6fee581 100644
--- a/mia/mesh/CMakeLists.txt
+++ b/mia/mesh/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/clist.hh b/mia/mesh/clist.hh
index a7e3939..e7409fc 100644
--- a/mia/mesh/clist.hh
+++ b/mia/mesh/clist.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/filter.cc b/mia/mesh/filter.cc
index cde8eed..989d390 100644
--- a/mia/mesh/filter.cc
+++ b/mia/mesh/filter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -49,15 +49,6 @@ PTriangleMesh  EXPORT_MESH run_filter(const CTriangleMesh& mesh, const char *fil
 	return f->filter(mesh);
 }
 
-using boost::filesystem::path; 
-CMeshFilterPluginHandlerTestPath::CMeshFilterPluginHandlerTestPath()
-{
-	CPathNameArray sksearchpath({path(MIA_BUILD_ROOT"/mia/mesh/filter")});
-	CMeshFilterPluginHandler::set_search_path(sksearchpath); 
-}
-
-
-
 template<> const  char * const 
 TPluginHandler<CMeshFilterPlugin>::m_help = 
    "These plug-ins provide mesh filters. Unless otherwise noted, "
diff --git a/mia/mesh/filter.hh b/mia/mesh/filter.hh
index 05ad87e..3bd2ab5 100644
--- a/mia/mesh/filter.hh
+++ b/mia/mesh/filter.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -51,15 +51,6 @@ typedef std::shared_ptr<CMeshFilter > PMeshFilter;
 */
 typedef THandlerSingleton<TFactoryPluginHandler<CMeshFilterPlugin> > CMeshFilterPluginHandler;
 
-/** @cond INTERNAL  
-    \ingroup test 
-    \brief Class to initialiaze the plug-in search path fot testing without installing the plug-ins 
-*/
-struct EXPORT_MESH CMeshFilterPluginHandlerTestPath {
-	CMeshFilterPluginHandlerTestPath(); 
-}; 
-/// @endcond 
-
 /// @cond NEVER 
 FACTORY_TRAIT(CMeshFilterPluginHandler); 
 /// @endcond 
diff --git a/mia/mesh/filter/CMakeLists.txt b/mia/mesh/filter/CMakeLists.txt
index 503acc7..a007107 100644
--- a/mia/mesh/filter/CMakeLists.txt
+++ b/mia/mesh/filter/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/filter/scale.cc b/mia/mesh/filter/scale.cc
index a2aec4f..2cb7036 100644
--- a/mia/mesh/filter/scale.cc
+++ b/mia/mesh/filter/scale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/filter/scale.hh b/mia/mesh/filter/scale.hh
index 72cabd1..2bd1054 100644
--- a/mia/mesh/filter/scale.hh
+++ b/mia/mesh/filter/scale.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/filter/test_scale.cc b/mia/mesh/filter/test_scale.cc
index 9c1ffa9..5895e1a 100644
--- a/mia/mesh/filter/test_scale.cc
+++ b/mia/mesh/filter/test_scale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/filter/test_vtxsort.cc b/mia/mesh/filter/test_vtxsort.cc
index afa9102..db4cafd 100644
--- a/mia/mesh/filter/test_vtxsort.cc
+++ b/mia/mesh/filter/test_vtxsort.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/filter/vtxsort.cc b/mia/mesh/filter/vtxsort.cc
index 34cc449..138bbeb 100644
--- a/mia/mesh/filter/vtxsort.cc
+++ b/mia/mesh/filter/vtxsort.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/filter/vtxsort.hh b/mia/mesh/filter/vtxsort.hh
index f48bc23..0c803a7 100644
--- a/mia/mesh/filter/vtxsort.hh
+++ b/mia/mesh/filter/vtxsort.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/io/CMakeLists.txt b/mia/mesh/io/CMakeLists.txt
index 7547a43..a3a6a53 100644
--- a/mia/mesh/io/CMakeLists.txt
+++ b/mia/mesh/io/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/io/gts.cc b/mia/mesh/io/gts.cc
index fda176c..db0fc9c 100644
--- a/mia/mesh/io/gts.cc
+++ b/mia/mesh/io/gts.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/io/off.cc b/mia/mesh/io/off.cc
index 8338f2c..8c8749b 100644
--- a/mia/mesh/io/off.cc
+++ b/mia/mesh/io/off.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/io/ply.cc b/mia/mesh/io/ply.cc
index b1deb6b..ea1cc02 100644
--- a/mia/mesh/io/ply.cc
+++ b/mia/mesh/io/ply.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/io/stl.cc b/mia/mesh/io/stl.cc
index 0cfa4b7..1e39daa 100644
--- a/mia/mesh/io/stl.cc
+++ b/mia/mesh/io/stl.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/test_triangulate.cc b/mia/mesh/test_triangulate.cc
index 5e68a48..d613d69 100644
--- a/mia/mesh/test_triangulate.cc
+++ b/mia/mesh/test_triangulate.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/triangularMesh.cc b/mia/mesh/triangularMesh.cc
index c06c08d..393ad29 100644
--- a/mia/mesh/triangularMesh.cc
+++ b/mia/mesh/triangularMesh.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/triangularMesh.hh b/mia/mesh/triangularMesh.hh
index f90f19e..cdc2223 100644
--- a/mia/mesh/triangularMesh.hh
+++ b/mia/mesh/triangularMesh.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/mesh/triangulate.hh b/mia/mesh/triangulate.hh
index a57dd17..c8a6f91 100644
--- a/mia/mesh/triangulate.hh
+++ b/mia/mesh/triangulate.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/CMakeLists.txt b/mia/template/CMakeLists.txt
index 84a261c..3afb8d0 100644
--- a/mia/template/CMakeLists.txt
+++ b/mia/template/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -21,6 +21,8 @@ bandpass.cxx
 bandpass.hh
 binarize.cxx
 binarize.hh
+combiner.hh
+combiner_filter.hh
 convert.cxx
 convert.hh
 cvd_io_trait.hh
@@ -33,7 +35,10 @@ fullcost.hh
 invert.cxx
 invert.hh
 lsd.hh
+masked_cost.hh
+masked_cost.cxx
 mi.hh
+mi_masked.hh
 multicost.cxx
 multicost.hh
 nonrigidregister.cxx
diff --git a/mia/template/bandpass.cxx b/mia/template/bandpass.cxx
index 78ab5e1..2b1c8f4 100644
--- a/mia/template/bandpass.cxx
+++ b/mia/template/bandpass.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/bandpass.hh b/mia/template/bandpass.hh
index 049f2fc..e142a86 100644
--- a/mia/template/bandpass.hh
+++ b/mia/template/bandpass.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/binarize.cxx b/mia/template/binarize.cxx
index bf5e234..6175c83 100644
--- a/mia/template/binarize.cxx
+++ b/mia/template/binarize.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/binarize.hh b/mia/template/binarize.hh
index 0f9cc76..aa8c8f7 100644
--- a/mia/template/binarize.hh
+++ b/mia/template/binarize.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/combiner.cxx b/mia/template/combiner.cxx
new file mode 100644
index 0000000..3850413
--- /dev/null
+++ b/mia/template/combiner.cxx
@@ -0,0 +1,30 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+NS_MIA_BEGIN
+
+template <typename Image>
+typename TImageCombiner<Image>::result_type TImageCombiner<Image>::combine( const Image& a, const Image& b) const
+{
+	return do_combine(a,b);
+}
+
+NS_MIA_END
diff --git a/mia/template/combiner.hh b/mia/template/combiner.hh
new file mode 100644
index 0000000..82ed855
--- /dev/null
+++ b/mia/template/combiner.hh
@@ -0,0 +1,56 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#ifndef mia_template_combiner_hh
+#define mia_template_combiner_hh
+
+#include <mia/core/filter.hh>
+#include <mia/core/import_handler.hh>
+
+NS_MIA_BEGIN
+
+template <typename Image> 
+class EXPORT_HANDLER TImageCombiner : public TFilter< typename Image::Pointer > ,
+				   public CProductBase {
+public:
+	/// data type for plug-in serachpath component 
+	typedef Image plugin_data; 
+	/// plug-in type for plug-in serachpath component 
+	typedef combiner_type plugin_type; 
+	
+        typedef typename TFilter< typename Image::Pointer >::result_type result_type; 
+
+	/**
+	   Combine two images by a given operator 
+	   @param a 
+	   @param b 
+	   @returns combined image 
+	   
+	 */
+	result_type combine( const Image& a, const Image& b) const;
+private:
+	virtual result_type do_combine( const Image& a, const Image& b) const = 0;
+};
+
+
+NS_MIA_END
+
+#endif 
diff --git a/mia/template/combiner_filter.hh b/mia/template/combiner_filter.hh
new file mode 100644
index 0000000..c3d8906
--- /dev/null
+++ b/mia/template/combiner_filter.hh
@@ -0,0 +1,110 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_template_combiner_filter_hh
+#define mia_template_combiner_filter_hh
+
+
+#include <mia/template/combiner.hh>
+#include <mia/core/iohandler.hh>
+
+
+
+NS_MIA_BEGIN
+
+template <typename Image> 
+class TImageCombinerFilter: public TDataFilter<Image> {
+public: 
+        TImageCombinerFilter(std::shared_ptr<TImageCombiner<Image>> combiner, 
+			     const std::string& other_image_file,  bool reverse); 
+
+        typename Image::Pointer do_filter(const Image& image) const; 
+
+        std::shared_ptr<TImageCombiner<Image>> m_combiner; 
+        std::string m_other_image; 
+        bool m_reverse; 
+
+}; 
+
+
+template <class Image> 
+class TImageCombinerFilterPlugin: public TDataFilterPlugin<Image>  {
+public: 
+	TImageCombinerFilterPlugin();
+	virtual TDataFilter<Image> *do_create()const;
+	virtual const std::string do_get_descr()const; 
+private: 
+        std::shared_ptr<TImageCombiner<Image>> m_combiner; 
+        std::string m_other_image; 
+        bool m_reverse; 
+
+};
+
+template <typename Image> 
+TImageCombinerFilter<Image>::TImageCombinerFilter(std::shared_ptr<TImageCombiner<Image>> combiner, 
+                                                  const std::string& other_image_file,  bool reverse):
+        m_combiner(combiner), 
+        m_other_image(other_image_file), 
+        m_reverse(reverse)
+{
+        
+}
+
+template <typename Image> 
+typename Image::Pointer TImageCombinerFilter<Image>::do_filter(const Image& image) const
+{
+
+        auto other_image = load_image<typename Image::Pointer>(m_other_image); 
+        if (m_reverse)
+                return m_combiner->combine(*other_image, image); 
+        else 
+                return m_combiner->combine(image, *other_image);
+}
+
+
+template <typename Image> 
+TImageCombinerFilterPlugin<Image>::TImageCombinerFilterPlugin():
+	TDataFilterPlugin<Image>("combiner"), 
+        m_reverse(false)
+{
+        typedef typename IOHandler_of<Image>::type IOHandler; 
+        this->add_parameter("op", make_param(m_combiner, "",  true, "Image combiner to be applied to the images")); 
+        this->add_parameter("image", new CStringParameter(m_other_image, CCmdOptionFlags::required_input, "second image that is needed in the combiner", 
+                                                          &IOHandler::instance())); 
+        this->add_parameter("reverse", new CBoolParameter(m_reverse, false, "reverse the order in which the images passed to the combiner")); 
+}
+
+template <typename Image> 
+TDataFilter<Image> *TImageCombinerFilterPlugin<Image>::do_create()const
+{
+        return new TImageCombinerFilter<Image>(m_combiner, m_other_image, m_reverse); 
+}
+
+template <typename Image> 
+const std::string TImageCombinerFilterPlugin<Image>::do_get_descr()const
+{
+return "Combine two images with the given combiner operator. if 'reverse' is set to false, the first "
+"operator is the image passed through the filter pipeline, and the second image is loaded "
+	"from the file given with the 'image' parameter the moment the filter is run."; 
+}
+
+NS_MIA_END
+
+#endif 
diff --git a/mia/template/convert.cxx b/mia/template/convert.cxx
index 5b43a55..aa225c0 100644
--- a/mia/template/convert.cxx
+++ b/mia/template/convert.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/convert.hh b/mia/template/convert.hh
index f395a7d..5d7ae93 100644
--- a/mia/template/convert.hh
+++ b/mia/template/convert.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/cvd_io_trait.hh b/mia/template/cvd_io_trait.hh
index c9889ee..f54f246 100644
--- a/mia/template/cvd_io_trait.hh
+++ b/mia/template/cvd_io_trait.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/dimtrait.hh b/mia/template/dimtrait.hh
index c6c7843..fe6880f 100644
--- a/mia/template/dimtrait.hh
+++ b/mia/template/dimtrait.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/divcurl.cxx b/mia/template/divcurl.cxx
index aacc0a9..89ccc31 100644
--- a/mia/template/divcurl.cxx
+++ b/mia/template/divcurl.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/divcurl.hh b/mia/template/divcurl.hh
index 4adfc6b..7dd587c 100644
--- a/mia/template/divcurl.hh
+++ b/mia/template/divcurl.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/filter_chain.hh b/mia/template/filter_chain.hh
index 4506618..9710d71 100644
--- a/mia/template/filter_chain.hh
+++ b/mia/template/filter_chain.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/filtertest.hh b/mia/template/filtertest.hh
index 4ab82ab..960b673 100644
--- a/mia/template/filtertest.hh
+++ b/mia/template/filtertest.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/fullcost.cxx b/mia/template/fullcost.cxx
index c7ea3e6..403c23b 100644
--- a/mia/template/fullcost.cxx
+++ b/mia/template/fullcost.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/fullcost.hh b/mia/template/fullcost.hh
index 10ebddd..7868037 100644
--- a/mia/template/fullcost.hh
+++ b/mia/template/fullcost.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/invert.cxx b/mia/template/invert.cxx
index df4f322..ffafc33 100644
--- a/mia/template/invert.cxx
+++ b/mia/template/invert.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/invert.hh b/mia/template/invert.hh
index 462d6f9..815c5d8 100644
--- a/mia/template/invert.hh
+++ b/mia/template/invert.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/lsd.hh b/mia/template/lsd.hh
index bf9f220..fda8020 100644
--- a/mia/template/lsd.hh
+++ b/mia/template/lsd.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/masked_cost.cxx b/mia/template/masked_cost.cxx
new file mode 100644
index 0000000..0f1a37b
--- /dev/null
+++ b/mia/template/masked_cost.cxx
@@ -0,0 +1,55 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/template/masked_cost.hh>
+
+NS_MIA_BEGIN
+
+template <typename T, typename M, typename V>
+TMaskedCost<T,M,V>::~TMaskedCost()
+{
+
+}
+
+template <typename T, typename M, typename V>
+double TMaskedCost<T,M,V>::value(const T& a, const M& mask) const
+{
+	return do_value(a, *m_reference, mask); 
+}
+
+template <typename T, typename M, typename V>
+double TMaskedCost<T,M,V>::evaluate_force(const T& a, const M& mask, V& force) const
+{
+	return do_evaluate_force(a,  *m_reference, mask, force); 
+}
+
+template <typename T, typename M, typename V>
+void TMaskedCost<T,M,V>::set_reference(const T& ref)
+{
+	m_reference.reset(new RData(ref));
+	post_set_reference(ref); 
+}
+
+template <typename T, typename M, typename V>
+void TMaskedCost<T,M,V>::post_set_reference(const T& /*ref*/)
+{
+}
+
+NS_MIA_END
diff --git a/mia/template/masked_cost.hh b/mia/template/masked_cost.hh
new file mode 100644
index 0000000..f13c0ef
--- /dev/null
+++ b/mia/template/masked_cost.hh
@@ -0,0 +1,126 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_template_masked_cost_hh
+#define mia_template_masked_cost_hh
+
+#include <mia/core/factory.hh>
+#include <mia/core/refholder.hh>
+
+
+#ifndef EXPORT_HANDLER
+#  ifdef WIN32
+#     define EXPORT_HANDLER __declspec(dllimport)
+#  else
+#     define EXPORT_HANDLER
+#  endif
+#endif
+
+NS_MIA_BEGIN
+
+/// plugin helper type
+struct EXPORT_CORE masked_cost_type {
+	/// plugin path helper variable 
+	static const char *type_descr;
+};
+
+
+/**
+   \ingroup registration 
+
+   \brief The generic cost function interface. 
+
+   The class defines an abstract interface for a cost function between two entities of the same 
+   type. 
+   The pure virtual functions 
+    -double do_value(const T& a, const T& b) const, and 
+    -double do_evaluate_force(const T& a, const T& b, float scale, V& force) const
+    have to be implemented in the derived class to make it a real cost function. 
+    The virtual function 
+    - void post_set_reference(const T& ref)
+    may be overwritten in order to prepare the reference data for the implemented cost function.
+    \tparam T the data type of the objects that the cost evaluation is based on 
+    \tparam V the type of the gradient force field created by this cost function 
+*/
+
+template <typename T, typename M, typename V>
+class EXPORT_HANDLER TMaskedCost : public CProductBase{
+public:
+	/// typedef for generic programming: The data type used by the cost function 
+	typedef T Data;
+
+	/// typedef for generic programming: The data type used by the cost function 
+	typedef M Mask;
+	
+	/// typedef for generic programming: The gradient forca type create by the cost function 
+	typedef V Force;
+
+	/// Const reference holder TRefHolder of the cost function data 
+	typedef TRefHolder<T> RData; 
+	
+	/// Pointer to const reference holder TRefHolder of the cost function data 
+	typedef typename RData::Pointer PData;
+
+	/// plugin searchpath helper type 
+	typedef T plugin_data; 
+	
+	/// plugin searchpath helper type 
+	typedef masked_cost_type plugin_type; 
+
+	/// ensure virtual destruction, since we have virtual functions
+	virtual ~TMaskedCost();
+
+	/**
+	   Evaluate the value of the cost function petreen the given moving image and 
+	   the reference that was set by calling set_reference(const T& ref). 
+	   \param mov the moving image 
+	   \param mask the mask to be applied when evaluating the cost function 
+	   \returns the cost function value 
+	 */
+	double value(const T& mov, const M& mask) const;
+
+	/**
+	   Evaluate the value of the cost function and its gradient with respect 
+	   to the given moving image and  the reference that was set by 
+           calling set_reference(const T& ref). 
+	   \param mov the moving image 
+	   \param mask the mask to be applied when evaluating the cost function 
+	   \param[out] force gradient force 
+	   \returns the cost function value 
+	 */
+	double evaluate_force(const T& mov, const M& mask, V& force) const;
+	
+	/**
+	   Set the new reference of the cost function. The virtual private function  
+	   post_set_reference(const T& ref) is then called to run possible preparations 
+	   on the reference image. 
+	 */
+	void set_reference(const T& ref);
+private:
+	virtual double do_value(const T& a, const T& b, const M& mask) const = 0;
+	virtual double do_evaluate_force(const T& a, const T& b, const M& mask, V& force) const = 0;
+	virtual void post_set_reference(const T& ref); 
+	
+	PData m_reference; 
+};
+
+
+NS_MIA_END
+#endif
diff --git a/mia/template/mi.hh b/mia/template/mi.hh
index fbc2637..c306b30 100644
--- a/mia/template/mi.hh
+++ b/mia/template/mi.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/mi_masked.cxx b/mia/template/mi_masked.cxx
new file mode 100644
index 0000000..00a59c8
--- /dev/null
+++ b/mia/template/mi_masked.cxx
@@ -0,0 +1,161 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/filter.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/core/parameter.hh>
+
+#include <mia/core/property_flags.hh>
+
+#include <numeric>
+#include <limits>
+
+
+NS_BEGIN(NS)
+
+template <typename Mask>
+struct FEvalMI : public mia::TFilter<double> {
+	FEvalMI( mia::CSplineParzenMI& parzen_mi, const Mask& m):
+		m_parzen_mi(parzen_mi), 
+		m_mask(m)
+		{}
+	
+
+	template <typename  T, typename  R>
+	FEvalMI::result_type operator () (const T& a, const R& b) const {
+		m_parzen_mi.fill(a.begin(), a.end(), b.begin(), b.end(), m_mask.begin(), m_mask.end()); 
+		return  m_parzen_mi.value(); 
+	}
+	mia::CSplineParzenMI& m_parzen_mi; 
+	const Mask& m_mask; 
+}; 
+
+
+template <typename T> 
+TMIMaskedImageCost<T>::TMIMaskedImageCost(size_t rbins, mia::PSplineKernel rkernel, size_t mbins, 
+			      mia::PSplineKernel mkernel, double cut):
+	m_parzen_mi(rbins, rkernel, mbins,  mkernel, cut)
+	
+{
+	this->add(::mia::property_gradient);
+}
+
+template <typename T> 
+double TMIMaskedImageCost<T>::do_value(const Data& a, const Data& b, const Mask& m) const
+{
+	FEvalMI<Mask> essd(m_parzen_mi, m); 
+	return filter(essd, a, b); 
+}
+
+template <typename Force, typename Mask>
+struct FEvalForce: public mia::TFilter<float> {
+	FEvalForce(Force& force, mia::CSplineParzenMI& parzen_mi, const Mask& m):
+		m_force(force), 
+		m_parzen_mi(parzen_mi), 
+		m_mask(m)
+		{
+		}
+	template <typename T, typename R> 
+	float operator ()( const T& a, const R& b) const {
+		Force gradient = get_gradient(a); 
+		m_parzen_mi.fill(a.begin(), a.end(), 
+				 b.begin(), b.end(), 
+				 m_mask.begin(), m_mask.end()); 
+		auto ai = a.begin();
+		auto bi = b.begin();
+		auto mi = m_mask.begin();
+	
+		for (size_t i = 0; i < a.size(); ++i, ++ai, ++bi, ++mi) {
+			if (*mi) {
+				float delta = -m_parzen_mi.get_gradient_slow(*ai, *bi); 
+				m_force[i] = gradient[i] * delta;
+			}
+		}
+		return m_parzen_mi.value(); 
+	}
+private: 
+	Force& m_force; 
+	mia::CSplineParzenMI& m_parzen_mi;
+	const Mask& m_mask;
+}; 
+		
+
+/**
+   This is the force evaluation routine of the cost function   
+*/
+template <typename T> 
+double TMIMaskedImageCost<T>::do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const
+{
+	assert(a.get_size() == b.get_size()); 
+	assert(a.get_size() == m.get_size()); 
+	assert(a.get_size() == force.get_size()); 
+	FEvalForce<Force, Mask> ef(force, m_parzen_mi, m); 
+	return filter(ef, a, b); 
+}
+
+template <typename T> 
+void TMIMaskedImageCost<T>::post_set_reference(const Data& MIA_PARAM_UNUSED(ref))
+{
+	m_parzen_mi.reset(); 
+}
+
+template <typename CP, typename C> 
+TMIMaskedImageCostPlugin<CP,C>::TMIMaskedImageCostPlugin():
+	CP("mi"), 
+	m_rbins(64), 
+	m_mbins(64), 
+	m_histogram_cut(0.0)
+{
+	TRACE("TMIMaskedImageCostPlugin<CP,C>::TMIMaskedImageCostPlugin()"); 
+	this->add_property(::mia::property_gradient); 
+	this->add_parameter("rbins", new mia::CUIntParameter(m_rbins, 1, 256, false, 
+				     "Number of histogram bins used for the reference image")); 
+
+	this->add_parameter("mbins", new mia::CUIntParameter(m_mbins, 1, 256, false, 
+				     "Number of histogram bins used for the moving image")); 
+	
+	this->add_parameter("rkernel", mia::make_param(m_rkernel, "bspline:d=0", false, 
+						  "Spline kernel for reference image parzen hinstogram")); 
+	
+	this->add_parameter("mkernel", mia::make_param(m_mkernel, "bspline:d=3", false, 
+						  "Spline kernel for moving image parzen hinstogram"));  
+
+	this->add_parameter("cut", new mia::CFloatParameter(m_histogram_cut, 0.0f, 40.0f, false, 
+							    "Percentage of pixels to cut at high and low "
+							    "intensities to remove outliers")); 
+}
+
+/**
+   The creator routine is also generic
+*/
+template <typename CP, typename C> 
+C *TMIMaskedImageCostPlugin<CP,C>::do_create() const
+{
+	return new TMIMaskedImageCost<C>(m_rbins, m_rkernel, m_mbins,  m_mkernel, m_histogram_cut); 
+}
+
+template <typename CP, typename C> 
+const std::string TMIMaskedImageCostPlugin<CP,C>::do_get_descr() const
+{
+	return "Spline parzen based mutual information with masking.";  
+	
+}
+
+NS_END
diff --git a/mia/template/mi_masked.hh b/mia/template/mi_masked.hh
new file mode 100644
index 0000000..1075170
--- /dev/null
+++ b/mia/template/mi_masked.hh
@@ -0,0 +1,71 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_template_mi_masked_hh
+#define mia_template_mi_masked_hh
+
+#include <mia/core/splineparzenmi.hh>
+
+NS_BEGIN(NS)
+
+///  @cond DOC_PLUGINS 
+
+template <typename T> 
+class TMIMaskedImageCost: public T {
+public: 	
+	typedef typename T::Data Data; 
+	typedef typename T::Mask Mask; 
+	typedef typename T::Force Force; 
+
+	TMIMaskedImageCost(size_t fbins, mia::PSplineKernel fkernel, size_t rbins, mia::PSplineKernel rkernel, double cut); 
+private: 
+	virtual double do_value(const Data& a, const Data& b, const Mask& m) const; 
+	virtual double do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const; 
+	virtual void post_set_reference(const Data& ref); 
+	mutable mia::CSplineParzenMI m_parzen_mi; 
+
+};
+
+
+
+/**
+   This is the plug-in declaration - the actual plugin needs to define the 
+   cost plugin type and the data type (this could be unified) 
+   do_test and do_get_descr need to be implemented 
+*/
+template <typename CP, typename C> 
+class TMIMaskedImageCostPlugin: public CP {
+public: 
+	TMIMaskedImageCostPlugin();
+	C *do_create()const;
+private: 
+	const std::string do_get_descr() const; 
+	unsigned int m_rbins;  
+	unsigned int m_mbins;  
+	mia::PSplineKernel m_mkernel; 
+	mia::PSplineKernel m_rkernel;
+	float m_histogram_cut; 
+};
+
+
+///  @endcond
+NS_END
+
+#endif 
diff --git a/mia/template/multicost.cxx b/mia/template/multicost.cxx
index 93288bf..69e4c4d 100644
--- a/mia/template/multicost.cxx
+++ b/mia/template/multicost.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/multicost.hh b/mia/template/multicost.hh
index 64f88c1..6c47bfe 100644
--- a/mia/template/multicost.hh
+++ b/mia/template/multicost.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/nonrigidregister.cxx b/mia/template/nonrigidregister.cxx
index e6af1aa..1ab333a 100644
--- a/mia/template/nonrigidregister.cxx
+++ b/mia/template/nonrigidregister.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -197,7 +197,7 @@ TNonrigidRegisterImpl<dim>::run(PImage src, PImage ref) const
 
 	PTransformation transform;
 
-	// convert the images to float ans scale to range [-1,1]
+	// convert the images to float ans scale to a mean=0, sigma=1 intensity distribution
 	// this should be replaced by some kind of general pre-filter plug-in 
 	FScaleFilterCreator<dim> fc; 
 	auto tofloat_converter = ::mia::filter(fc, *src, *ref); 
@@ -240,14 +240,16 @@ TNonrigidRegisterImpl<dim>::run(PImage src, PImage ref) const
 
 		int scale_factor = 1 << shift; 
 		Size local_size = global_size / scale_factor; 
-
+		
+		cvinfo() << "scale_factor = " << scale_factor << " from shift " << shift 
+			 << ", global size = " << global_size << "\n"; 
 
 		if (transform) {
-			cvinfo() << "Upscale transform\n"; 
+			cvinfo() << "Upscale transform to " << local_size << " \n"; 
 			transform = transform->upscale(local_size);
 			cvinfo() << "done\n"; 
 		}else{
-			cvinfo() << "Create transform\n"; 
+			cvinfo() << "Create transform with size " << local_size << "\n"; 
 			transform = m_transform_creator->create(local_size);
 			cvinfo() << "done\n"; 
 		}
@@ -333,6 +335,7 @@ TNonrigidRegisterImpl<dim>::run() const
 
 		auto x = transform->get_parameters();
 
+		cvmsg() << "Registration at " << local_size << " with " << x.size() <<  " parameters\n";
 		m_minimizer->run(x);
 		cvmsg() << "\ndone\n";
 		transform->set_parameters(x);
@@ -381,13 +384,12 @@ double  TNonrigRegGradientProblem<dim>::do_f(const CDoubleVector& x)
 	if (!m_func_evals && !m_grad_evals) 
 		m_start_cost = result; 
 	
-	char endline = (cverb.get_level() < vstream::ml_message) ? '\n' : '\r'; 
 	m_func_evals++; 
 	cvmsg() << "Cost[fg=" << std::setw(4) << m_grad_evals 
 		<< ",fe=" << std::setw(4) << m_func_evals<<"]=" 
 		<< std::setw(20) << std::setprecision(12) << result 
 		<< "ratio:" << std::setw(20) << std::setprecision(12) 
-		<< result / m_start_cost  << endline; 
+		<< result / m_start_cost  << "\n"; 
 	return result; 
 }
 
@@ -427,12 +429,10 @@ double  TNonrigRegGradientProblem<dim>::evaluate_fdf(const CDoubleVector& x, CDo
 	if (!m_func_evals && !m_grad_evals) 
 		m_start_cost = result; 
 
-	char endline = (cverb.get_level() < vstream::ml_message) ? '\n' : '\r'; 
-
 	cvmsg() << "Cost[fg="<<std::setw(4)<<m_grad_evals 
 		<< ",fe="<<std::setw(4)<<m_func_evals<<"]= with " 
 		<< std::setw(20) << std::setprecision(12) << result 
-		<< " ratio:" << std::setw(20) << std::setprecision(12) << result / m_start_cost <<  endline; 
+		<< " ratio:" << std::setw(20) << std::setprecision(12) << result / m_start_cost <<  "\n"; 
 	return result; 
 }
 
diff --git a/mia/template/nonrigidregister.hh b/mia/template/nonrigidregister.hh
index e888cbc..c52c00e 100644
--- a/mia/template/nonrigidregister.hh
+++ b/mia/template/nonrigidregister.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/normalize.hh b/mia/template/normalize.hh
index 77a43f6..d789f0e 100644
--- a/mia/template/normalize.hh
+++ b/mia/template/normalize.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/seededwatershed.hh b/mia/template/seededwatershed.hh
index e1588c7..49055db 100644
--- a/mia/template/seededwatershed.hh
+++ b/mia/template/seededwatershed.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -291,7 +291,7 @@ TSeededWSFilterPlugin<dim>::TSeededWSFilterPlugin():
 	m_with_borders(false), 
 	m_input_is_gradient(false)
 {
-	this->add_parameter("seed", new CStringParameter(m_seed_image_file, true, 
+	this->add_parameter("seed", new CStringParameter(m_seed_image_file, CCmdOptionFlags::required_input, 
 						   "seed input image containing the lables for the initial regions"));
 	this->add_parameter("n", make_param(m_neighborhood, "sphere:r=1", false, "Neighborhood for watershead region growing")); 
 	this->add_parameter("mark", new CBoolParameter(m_with_borders, false, "Mark the segmented watersheds with a special gray scale value")); 
diff --git a/mia/template/similarity_profile.cxx b/mia/template/similarity_profile.cxx
index e1efb42..49e53ea 100644
--- a/mia/template/similarity_profile.cxx
+++ b/mia/template/similarity_profile.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,10 +27,11 @@ NS_MIA_BEGIN
 template <int dim>
 TSimilarityProfile<dim>::TSimilarityProfile(PFullCost cost, 
 					    const ImageSeries& images, 
-					    size_t _reference):
-	m_reference(_reference),
+					    size_t _reference, size_t max_delta):
 	m_peak_freq(-1),
-	m_peak_freq_valid(false)
+	m_peak_freq_valid(false), 
+	m_reference(_reference),
+	m_max_delta(max_delta > 0 ? max_delta : images.size())
 {
 	// +-2 makes sure that the implementation of get_periodic_subset works
 	assert(m_reference < images.size() - 2 && m_reference >= 2); 
@@ -49,11 +50,12 @@ TSimilarityProfile<dim>::TSimilarityProfile(PFullCost cost,
 
 template <int dim>
 TSimilarityProfile<dim>::TSimilarityProfile(const TSimilarityProfile<dim>& other):
+	m_peak_freq(other.m_peak_freq), 
+	m_peak_freq_valid(other.m_peak_freq_valid), 
 	m_reference(other.m_reference), 
+	m_max_delta(other.m_max_delta), 
 	m_cost_values(other.m_cost_values)
 {
-	m_peak_freq = other.m_peak_freq;
-	m_peak_freq_valid = other.m_peak_freq_valid; 
 }
 
 template <int dim>
@@ -61,6 +63,7 @@ TSimilarityProfile<dim>& TSimilarityProfile<dim>::operator = (const TSimilarityP
 {
 	if (this != &other) {
 		m_reference = other.m_reference; 
+		m_max_delta = other.m_max_delta;  
 		m_cost_values = other.m_cost_values; 
 		m_peak_freq = other.m_peak_freq;
 		m_peak_freq_valid = other.m_peak_freq_valid; 
@@ -96,31 +99,38 @@ std::vector<size_t> TSimilarityProfile<dim>::get_periodic_subset() const
 	cvinfo()  << "Similarity profile["<< m_reference <<"]:" 
 		  << m_cost_values << "\n"; 
 
+	unsigned delta = 0; 
 	while (i > 2) {
-		if (m_cost_values[i] < m_cost_values[i + 1] 
-		    && m_cost_values[i] < m_cost_values[i + 2]
-		    && m_cost_values[i] < m_cost_values[i - 1]
-		    && m_cost_values[i] < m_cost_values[i - 2])  {
+		if ((m_cost_values[i] < m_cost_values[i + 1] && 
+		     m_cost_values[i] < m_cost_values[i + 2] && 
+		     m_cost_values[i] < m_cost_values[i - 1] && 
+		     m_cost_values[i] < m_cost_values[i - 2]) || (delta > m_max_delta))  {
 			result.push_back(i); 
 			i -= 3; 
-		}else
+			delta = 0; 
+		}else {
+			++delta; 
 			--i; 
+		}
 	}
 	result.push_back(0); 
+	delta = 0; 
 		
 	i = m_reference + 1; 
 	while (i < m_cost_values.size() - 2) {
-		if (m_cost_values[i] < m_cost_values[i + 1] 
-		    && m_cost_values[i] < m_cost_values[i + 2]
-		    && m_cost_values[i] < m_cost_values[i - 1]
-		    && m_cost_values[i] < m_cost_values[i - 2]) {
+		if ((m_cost_values[i] < m_cost_values[i + 1] && 
+		     m_cost_values[i] < m_cost_values[i + 2] && 
+		     m_cost_values[i] < m_cost_values[i - 1] && 
+		     m_cost_values[i] < m_cost_values[i - 2]) || (delta > m_max_delta)) {
 			result.push_back(i); 
 			i += 3; 
-		}
-		else
+			delta = 0; 
+		}else {
+			++delta; 
 			++i; 
+		}
 	}
-	// append butlast if better then last 
+	// append the one before the last if better then last 
 	// a the the end of the series the changes in intesnity should 
 	// not be so big 
 	while (i < m_cost_values.size() - 1) {
@@ -133,7 +143,7 @@ std::vector<size_t> TSimilarityProfile<dim>::get_periodic_subset() const
 		else
 			++i; 
 	}
-	// not yet past the end, therefore, we may want t o add the last image
+	// not yet past the end, therefore, we may want to add the last image
 	while (i < m_cost_values.size()) {
 		if (m_cost_values[i] < m_cost_values[i - 1]
 		    && m_cost_values[i] < m_cost_values[i - 2]) {
diff --git a/mia/template/similarity_profile.hh b/mia/template/similarity_profile.hh
index 14f237e..ed1aedc 100644
--- a/mia/template/similarity_profile.hh
+++ b/mia/template/similarity_profile.hh
@@ -1,7 +1,8 @@
+
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -52,12 +53,13 @@ public:
 	/**
 	   Contruct and prepare the similarity profile. Throws an std::invalid_argument exception 
 	   on failure. 
-	   \param cost 
-	   \param images
-	   \param reference
+	   \param cost image similarity to evaluate the similarity series 
+	   \param images the image series 
+	   \param reference the reference to use for evaluating the similarity series 
+	   \param max_delta  the maximum temporal delta for the subset 
 	 */
 	TSimilarityProfile(PFullCost cost, const ImageSeries& images, 
-			     size_t reference); 
+			   size_t reference, size_t max_delta); 
 	
 	/// copy constructor 
 	TSimilarityProfile(const TSimilarityProfile<dim>& org); 
@@ -73,9 +75,10 @@ public:
 	std::vector<size_t> get_periodic_subset() const; 
 private: 
 	size_t m_skip; 
-	size_t m_reference; 
 	mutable float m_peak_freq;
 	mutable bool m_peak_freq_valid; 
+	size_t m_reference; 
+	size_t m_max_delta; 
 	std::vector<CFFT1D_R2C::Real> m_cost_values; 
 }; 
 
diff --git a/mia/template/ssd-automask.cxx b/mia/template/ssd-automask.cxx
new file mode 100644
index 0000000..4e0dabf
--- /dev/null
+++ b/mia/template/ssd-automask.cxx
@@ -0,0 +1,190 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/filter.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/core/parameter.hh>
+#include <mia/core/property_flags.hh>
+#include <tbb/parallel_reduce.h>
+#include <tbb/blocked_range.h>
+
+#include <numeric>
+#include <limits>
+
+NS_BEGIN(NS)
+
+
+struct SRA {
+	size_t n; 
+	double sum;
+}; 
+
+struct FEvalSSDAuto : public mia::TFilter<double> {
+	FEvalSSDAuto(double src_mask_thresh, double ref_mask_thresh):
+		m_src_mask_thresh(src_mask_thresh),
+		m_ref_mask_thresh(ref_mask_thresh){
+	}
+	
+	template <typename  T, typename  R>
+	FEvalSSDAuto::result_type operator () (const T& a, const R& b) const {
+		SRA result_accumulator = {0, 0.0}; 
+		
+		SRA  result = 
+			tbb::parallel_reduce(tbb::blocked_range<size_t>(0, a.size()), result_accumulator, 
+				     [this, &a, &b](const tbb::blocked_range<size_t>& range, SRA acc)->SRA {
+					     for (auto ir = range.begin(); ir !=range.end(); ++ir){
+						     double va = a[ir]; 
+						     if (va >= m_src_mask_thresh) { 
+							     double vb = b[ir];
+							     if (vb >= m_ref_mask_thresh) {
+								     ++acc.n; 
+								     double d = va - vb; 
+								     acc.sum += d * d; 
+							     }
+						     }
+					     }
+					     return acc; 
+				     }, 
+				     [](const SRA& lhs, const SRA& rhs) -> SRA {
+					     SRA result;
+					     result.n = lhs.n + rhs.n; 
+					     result.sum = lhs.sum + rhs.sum; 
+					     return result; 
+				     }
+			); 
+		mia::cvdebug() << "sum=" << result.sum << ", n=" <<  result.n << "\n"; 
+		return result.n > 0 ? 0.5 * result.sum / result.n : 0.0; 
+	}
+	double m_src_mask_thresh;
+	double m_ref_mask_thresh; 
+
+}; 
+
+
+template <typename TCost> 
+TSSDAutomaskCost<TCost>::TSSDAutomaskCost():
+	m_src_mask_thresh(0.0), 
+	m_ref_mask_thresh(0.0)
+{
+	this->add(::mia::property_gradient);
+}
+
+template <typename TCost> 
+TSSDAutomaskCost<TCost>::TSSDAutomaskCost(double src_mask_thresh, double ref_thresh_mask):
+	m_src_mask_thresh(src_mask_thresh), 
+	m_ref_mask_thresh(ref_thresh_mask)
+{
+	this->add(::mia::property_gradient);
+}
+
+template <typename TCost> 
+double TSSDAutomaskCost<TCost>::do_value(const Data& a, const Data& b) const
+{
+	FEvalSSDAuto essd(m_src_mask_thresh, m_ref_mask_thresh); 
+	return mia::filter(essd, a, b); 
+}
+
+template <typename Force>
+struct FEvalForceAuto: public mia::TFilter<float> {
+	typedef typename Force::value_type force_type; 
+	FEvalForceAuto(Force& force, double src_mask_thresh, double ref_mask_thresh):
+		m_force(force), 
+		m_src_mask_thresh(src_mask_thresh), 
+		m_ref_mask_thresh(ref_mask_thresh)
+		{
+		}
+	template <typename T, typename R> 
+	float operator ()( const T& a, const R& b) const {
+		Force gradient = get_gradient(a); 
+		float cost = 0.0; 
+		auto ai = a.begin();
+		auto bi = b.begin();
+		auto fi = m_force.begin(); 
+		auto gi = gradient.begin(); 
+
+		size_t n = 0;
+		
+		for (size_t i = 0; i < a.size(); ++i, ++ai, ++bi, ++fi, ++gi) {
+			if ((*ai >= m_src_mask_thresh) && (*bi >= m_ref_mask_thresh)) {
+				float delta = float(*ai) - float(*bi); 
+				*fi = *gi * delta ;
+				cost += delta * delta; 
+				++n; 
+			}else 
+				*fi = force_type(); 
+		}
+		double scale = 0.0; 
+		if (n > 0) 
+			scale = 1.0 / n; 
+		
+		transform(m_force.begin(), m_force.end(), m_force.begin(), 
+			  [scale](const force_type& v){return scale * v;});  
+		
+		return 0.5 * scale * cost;
+	}
+private: 
+	Force& m_force; 
+	double m_src_mask_thresh;
+	double m_ref_mask_thresh; 
+}; 
+		
+
+/**
+   This is the force evaluation routine of the cost function   
+*/
+template <typename TCost> 
+double TSSDAutomaskCost<TCost>::do_evaluate_force(const Data& a, const Data& b, Force& force) const
+{
+	assert(a.get_size() == b.get_size()); 
+	assert(a.get_size() == force.get_size()); 
+	FEvalForceAuto<Force> ef(force, m_src_mask_thresh, m_ref_mask_thresh); 
+	return mia::filter(ef, a, b); 
+}
+
+
+/**
+   This plugin will alwasy be "ssd" 
+*/
+template <typename CP, typename C> 
+TSSDAutomaskCostPlugin<CP,C>::TSSDAutomaskCostPlugin():
+	CP("ssd-automask")
+{
+	TRACE("TSSDAutomaskCostPlugin<CP,C>::TSSDAutomaskCostPlugin()"); 
+	this->add_property(::mia::property_gradient); 
+	const double limits = std::numeric_limits<double>::max(); 
+	this->add_parameter("rthresh", new mia::CDoubleParameter(m_ref_mask_thresh, -limits, limits, false, 
+								 "Threshold intensity value for reference image")); 
+
+	this->add_parameter("sthresh", new mia::CDoubleParameter(m_src_mask_thresh, -limits, limits, false, 
+								    "Threshold intensity value for source image")); 
+
+}
+
+/**
+   The creator routine is also generic
+*/
+template <typename CP, typename C> 
+C *TSSDAutomaskCostPlugin<CP,C>::do_create() const
+{
+	return new TSSDAutomaskCost<C>(m_src_mask_thresh, m_ref_mask_thresh);
+}
+
+/// @endcond 
+NS_END
diff --git a/mia/template/ssd-automask.hh b/mia/template/ssd-automask.hh
new file mode 100644
index 0000000..a3a1ee9
--- /dev/null
+++ b/mia/template/ssd-automask.hh
@@ -0,0 +1,73 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/filter.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/core/parameter.hh>
+#include <mia/core/property_flags.hh>
+#include <tbb/parallel_reduce.h>
+#include <tbb/blocked_range.h>
+
+#include <numeric>
+#include <limits>
+
+NS_BEGIN(NS)
+
+///  @cond DOC_PLUGINS 
+
+/**
+
+   @ingroup registation 
+*/
+template <typename TCost> 
+class TSSDAutomaskCost: public TCost {
+public: 	
+	typedef typename TCost::Data Data; 
+	typedef typename TCost::Force Force; 
+
+	TSSDAutomaskCost(); 
+	TSSDAutomaskCost(double src_mask_thresh, double ref_mask_thresh); 
+private: 
+	virtual double do_value(const Data& a, const Data& b) const; 
+	virtual double do_evaluate_force(const Data& a, const Data& b, Force& force) const; 
+	double m_src_mask_thresh;
+	double m_ref_mask_thresh; 
+};
+
+
+/**
+   This is the plug-in declaration - the actual plugin needs to define the 
+   cost plugin type and the data type (this could be unified) 
+   do_test and do_get_descr need to be implemented 
+*/
+template <typename CP, typename C> 
+class TSSDAutomaskCostPlugin: public CP {
+public: 
+	TSSDAutomaskCostPlugin();
+	C *do_create()const;
+private: 
+	double m_src_mask_thresh;
+	double m_ref_mask_thresh; 
+
+};
+
+
+/// @endcond 
+NS_END
diff --git a/mia/template/ssd.hh b/mia/template/ssd.hh
index c8a1cde..725c9df 100644
--- a/mia/template/ssd.hh
+++ b/mia/template/ssd.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,16 +41,18 @@ public:
 	typedef typename TCost::Force Force; 
 
 	TSSDCost(); 
-	TSSDCost(bool normalize); 
+	TSSDCost(bool normalize, float automask_thresh); 
 private: 
 	virtual double do_value(const Data& a, const Data& b) const; 
 	virtual double do_evaluate_force(const Data& a, const Data& b, Force& force) const; 
 	bool m_normalize; 
+	float m_automask_thresh; 
 };
 
 
 struct FEvalSSD : public mia::TFilter<double> {
-	FEvalSSD(bool normalize):m_normalize(normalize){}
+	FEvalSSD(bool normalize, float automask_thresh):
+		m_normalize(normalize), m_automask_thresh(automask_thresh){}
 	
 	template <typename T, typename R>
 	struct SQD {
@@ -63,23 +65,44 @@ struct FEvalSSD : public mia::TFilter<double> {
 	template <typename  T, typename  R>
 	FEvalSSD::result_type operator () (const T& a, const R& b) const {
 		double scale = m_normalize ? 0.5 / a.size() : 0.5; 
-		return scale * inner_product(a.begin(), a.end(), b.begin(), 0.0,  ::std::plus<double>(), 
-					     SQD<typename T::value_type , typename R::value_type >()); 
+		if (m_automask_thresh == 0.0f) 
+			return scale * inner_product(a.begin(), a.end(), b.begin(), 0.0,  ::std::plus<double>(), 
+						     SQD<typename T::value_type , typename R::value_type >()); 
+		else {
+			auto ia = a.begin(); 
+			auto ib = b.begin(); 
+			auto ie = a.end(); 
+			long n = 0; 
+			double sum = 0.0; 
+			while (ia != ie) {
+				if (*ia > m_automask_thresh) {
+					double d = (double)*ia - (double)*ib; 
+					sum += d*d; 
+					++n; 
+				}
+				++ia; ++ib; 
+			}
+			// high penalty if the mask don't overlap at all 
+			return n > 0 ?  0.5 * sum / n : std::numeric_limits<float>::max(); 
+		}
 	}
 	bool m_normalize; 
+	float m_automask_thresh; 
 }; 
 
 
 template <typename TCost> 
 TSSDCost<TCost>::TSSDCost():
-	m_normalize(true)
+	m_normalize(true), 
+	m_automask_thresh(0.0)
 {
 	this->add(::mia::property_gradient);
 }
 
 template <typename TCost> 
-TSSDCost<TCost>::TSSDCost(bool normalize):
-	m_normalize(normalize)
+TSSDCost<TCost>::TSSDCost(bool normalize, float automask_thresh):
+        m_normalize(normalize), 
+        m_automask_thresh(automask_thresh)
 {
 	this->add(::mia::property_gradient);
 }
@@ -87,15 +110,16 @@ TSSDCost<TCost>::TSSDCost(bool normalize):
 template <typename TCost> 
 double TSSDCost<TCost>::do_value(const Data& a, const Data& b) const
 {
-	FEvalSSD essd(m_normalize); 
+	FEvalSSD essd(m_normalize, m_automask_thresh); 
 	return filter(essd, a, b); 
 }
 
 template <typename Force>
 struct FEvalForce: public mia::TFilter<float> {
-	FEvalForce(Force& force, bool normalize):
+	FEvalForce(Force& force, bool normalize, float automask_thresh):
 		m_force(force), 
-		m_normalize(normalize)
+		m_normalize(normalize),
+		m_automask_thresh(automask_thresh)
 		{
 		}
 	template <typename T, typename R> 
@@ -107,18 +131,39 @@ struct FEvalForce: public mia::TFilter<float> {
 		auto fi = m_force.begin(); 
 		auto gi = gradient.begin(); 
 
-		float scale = m_normalize ? 1.0 / a.size() : 1.0; 
-		
-		for (size_t i = 0; i < a.size(); ++i, ++ai, ++bi, ++fi, ++gi) {
-			float delta = float(*ai) - float(*bi); 
-			*fi = *gi * delta  * scale;
-			cost += delta * delta * scale; 
+		if (m_automask_thresh == 0.0f) {
+			float scale = m_normalize ? 1.0 / a.size() : 1.0; 
+			
+			for (size_t i = 0; i < a.size(); ++i, ++ai, ++bi, ++fi, ++gi) {
+				float delta = float(*ai) - float(*bi); 
+				*fi = *gi * delta  * scale;
+				cost += delta * delta * scale; 
+			}
+			return 0.5 * cost; 
+		}else{
+			long n = 0;
+			for (size_t i = 0; i < a.size(); ++i, ++ai, ++bi, ++fi, ++gi) {
+				if (*ai > m_automask_thresh) {
+					float delta = float(*ai) - float(*bi); 
+					*fi = *gi * delta;
+					cost += delta * delta; 
+					++n; 
+				}
+			}
+			if ( n > 0) {
+				float  scale = 1.0f / n; 
+				transform(m_force.begin(), m_force.end(), m_force.begin(),
+					  [scale](const typename Force::value_type&  x){return scale * x;}); 
+				return 0.5 * cost  *scale;
+			}else{
+				return std::numeric_limits<float>::max(); 
+			}
 		}
-		return 0.5 * cost; 
 	}
 private: 
 	Force& m_force; 
 	bool m_normalize; 
+	float m_automask_thresh; 
 }; 
 		
 
@@ -130,7 +175,7 @@ double TSSDCost<TCost>::do_evaluate_force(const Data& a, const Data& b, Force& f
 {
 	assert(a.get_size() == b.get_size()); 
 	assert(a.get_size() == force.get_size()); 
-	FEvalForce<Force> ef(force, m_normalize); 
+	FEvalForce<Force> ef(force, m_normalize, m_automask_thresh); 
 	return filter(ef, a, b); 
 }
 
@@ -147,6 +192,7 @@ public:
 	C *do_create()const;
 private:
 	bool m_normalize; 
+	float m_automask_thresh; 
 };
 
 
@@ -156,12 +202,17 @@ private:
 template <typename CP, typename C> 
 TSSDCostPlugin<CP,C>::TSSDCostPlugin():
 	CP("ssd"), 
-	m_normalize(false)
+	m_normalize(false), 
+	m_automask_thresh(0)
 {
 	TRACE("TSSDCostPlugin<CP,C>::TSSDCostPlugin()"); 
 	this->add_property(::mia::property_gradient); 
 	this->add_parameter("norm", new mia::CBoolParameter(m_normalize, false, 
-			    "Set whether the metric should be normalized by the number of image pixels")); 
+			    "Set whether the metric should be normalized by the number of image pixels")
+		); 
+	this->add_parameter("autothresh", new mia::CFloatParameter(m_automask_thresh, 0, 1000, false, 
+			"Use automatic masking of the moving image by only takeing intensity values "
+								   "into accound that are larger than the given threshold"));  
 
 }
 
@@ -171,7 +222,7 @@ TSSDCostPlugin<CP,C>::TSSDCostPlugin():
 template <typename CP, typename C> 
 C *TSSDCostPlugin<CP,C>::do_create() const
 {
-	return new TSSDCost<C>(m_normalize);
+	return new TSSDCost<C>(m_normalize, m_automask_thresh);
 }
 
 /// @endcond 
diff --git a/mia/template/ssd_masked.cxx b/mia/template/ssd_masked.cxx
new file mode 100644
index 0000000..ec3f8e5
--- /dev/null
+++ b/mia/template/ssd_masked.cxx
@@ -0,0 +1,163 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/core/filter.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/core/parameter.hh>
+#include <mia/core/property_flags.hh>
+
+#include <numeric>
+#include <limits>
+
+
+NS_BEGIN(NS)
+
+template <typename Mask>
+struct FEvalSSD : public mia::TFilter<double> {
+	FEvalSSD(const Mask& m):m_mask(m)
+		{}
+	
+	template <typename T, typename R>
+	struct SQD {
+		double operator ()(T a, R b) const {
+			double d = (double)a - (double)b; 
+			return d * d;
+		}
+	}; 
+	
+	template <typename  T, typename  R>
+	FEvalSSD::result_type operator () (const T& a, const R& b) const {
+		auto ia = a.begin(); 
+		auto ib = b.begin(); 
+		auto ie = a.end(); 
+		auto im = m_mask.begin(); 
+		const long n = a.size(); 
+		double sum = 0.0; 
+		while (ia != ie) {
+			if (*im) {
+				double d = (double)*ia - (double)*ib; 
+				sum += d*d; 
+			}
+			++ia; ++ib; ++im; 
+		}
+		// If masks don't overlap the cost is zero, this is bad!!
+		return n > 0 ?  0.5 * sum / n : 0.0;
+	}
+private: 
+	const Mask& m_mask; 
+}; 
+
+
+template <typename TCost> 
+TSSDMaskedImageCost<TCost>::TSSDMaskedImageCost()
+{
+	this->add(::mia::property_gradient);
+}
+
+template <typename TCost> 
+double TSSDMaskedImageCost<TCost>::do_value(const Data& a, const Data& b, const Mask& m) const
+{
+	FEvalSSD<Mask> essd(m); 
+	return filter(essd, a, b); 
+}
+
+template <typename Force, typename Mask>
+struct FEvalForce: public mia::TFilter<float> {
+	FEvalForce(Force& force, const Mask& m):
+		m_force(force), 
+		m_mask(m)
+		{
+		}
+	template <typename T, typename R> 
+	float operator ()( const T& a, const R& b) const {
+		Force gradient = get_gradient(a); 
+		float cost = 0.0; 
+		auto ai = a.begin();
+		auto bi = b.begin();
+		auto fi = m_force.begin(); 
+		auto im = m_mask.begin(); 
+		auto gi = gradient.begin(); 
+
+		long n = a.size();
+		for (size_t i = 0; i < a.size(); ++i, ++ai, ++bi, ++fi, ++gi, ++im) {
+			if (*im) {
+				float delta = float(*ai) - float(*bi); 
+				*fi = *gi * delta;
+				cost += delta * delta; 
+			}
+		}
+		if ( n > 0) {
+			float  scale = 1.0f / n; 
+			transform(m_force.begin(), m_force.end(), m_force.begin(),
+				  [scale](const typename Force::value_type&  x){return scale * x;}); 
+			return 0.5 * cost  *scale;
+		}else{
+			return 0.0; 
+		}
+	}
+private: 
+	Force& m_force; 
+	const Mask& m_mask;
+}; 
+		
+
+/**
+   This is the force evaluation routine of the cost function   
+*/
+template <typename TCost> 
+double TSSDMaskedImageCost<TCost>::do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const
+{
+	assert(a.get_size() == b.get_size()); 
+	assert(a.get_size() == force.get_size()); 
+	FEvalForce<Force, Mask> ef(force, m); 
+	return filter(ef, a, b); 
+}
+
+
+
+/**
+   This plugin will alwasy be "ssd" 
+*/
+template <typename CP, typename C> 
+TSSDMaskedImageCostPlugin<CP,C>::TSSDMaskedImageCostPlugin():
+	CP("ssd")
+{
+	TRACE("TSSDCostPlugin<CP,C>::TSSDCostPlugin()"); 
+	this->add_property(::mia::property_gradient); 
+}
+
+/**
+   The creator routine is also generic
+*/
+template <typename CP, typename C> 
+C *TSSDMaskedImageCostPlugin<CP,C>::do_create() const
+{
+	return new TSSDMaskedImageCost<C>();
+}
+
+template <typename CP, typename C> 
+const std::string TSSDMaskedImageCostPlugin<CP,C>::do_get_descr() const
+{
+	return "Sum of squared differences with masking.";  
+	
+}
+
+
+NS_END
diff --git a/mia/template/ssd_masked.hh b/mia/template/ssd_masked.hh
new file mode 100644
index 0000000..21c4584
--- /dev/null
+++ b/mia/template/ssd_masked.hh
@@ -0,0 +1,65 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef mia_template_ssd_masked_hh
+#define mia_template_ssd_masked_hh
+
+
+NS_BEGIN(NS)
+
+///  @cond DOC_PLUGINS 
+
+/**
+
+   @ingroup registation 
+*/
+template <typename TCost> 
+class TSSDMaskedImageCost: public TCost {
+public: 	
+	typedef typename TCost::Data Data; 
+	typedef typename TCost::Mask Mask; 
+	typedef typename TCost::Force Force; 
+
+	TSSDMaskedImageCost(); 
+private: 
+	virtual double do_value(const Data& a, const Data& b, const Mask& m) const; 
+	virtual double do_evaluate_force(const Data& a, const Data& b, const Mask& m, Force& force) const; 
+};
+
+
+/**
+   This is the plug-in declaration - the actual plugin needs to define the 
+   cost plugin type and the data type (this could be unified) 
+   do_test and do_get_descr need to be implemented 
+*/
+template <typename CP, typename C> 
+class TSSDMaskedImageCostPlugin: public CP {
+public: 
+	TSSDMaskedImageCostPlugin();
+private:
+	C *do_create()const;
+	const std::string do_get_descr() const; 
+};
+
+/// @endcond 
+NS_END
+
+#endif 
+
diff --git a/mia/template/trackpoint.cxx b/mia/template/trackpoint.cxx
index 540eabc..cbecc09 100644
--- a/mia/template/trackpoint.cxx
+++ b/mia/template/trackpoint.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/trackpoint.hh b/mia/template/trackpoint.hh
index ca2bad9..0f50f03 100644
--- a/mia/template/trackpoint.hh
+++ b/mia/template/trackpoint.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/transformfactory.cxx b/mia/template/transformfactory.cxx
index 5bb3859..1ef2dbc 100644
--- a/mia/template/transformfactory.cxx
+++ b/mia/template/transformfactory.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/transformfactory.hh b/mia/template/transformfactory.hh
index 8b915ce..d81869a 100644
--- a/mia/template/transformfactory.hh
+++ b/mia/template/transformfactory.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/template/watershed.hh b/mia/template/watershed.hh
index 70134e6..38b071c 100644
--- a/mia/template/watershed.hh
+++ b/mia/template/watershed.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia/test/testhelpers.hh b/mia/test/testhelpers.hh
index 099be15..736bdd9 100644
--- a/mia/test/testhelpers.hh
+++ b/mia/test/testhelpers.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/mia3d.pc.cmake b/mia3d.pc.cmake
index 4f50174..22940e4 100644
--- a/mia3d.pc.cmake
+++ b/mia3d.pc.cmake
@@ -12,6 +12,6 @@ Name: mia3d
 Description: A library for 3D grayscale image processing 
 Version: @PACKAGE_VERSION@
 Conflicts:
-Requires: mia2d- at VERSION@
+Requires: mia2d- at VERSION@ eigen3
 Libs: -lmia3d- at VERSION@ -L${prefix}/@LIBRARY_INSTALL_PATH@
 Cflags: -I${prefix}/@INCLUDE_INSTALL_PATH@ -I${prefix}/@LIB_INCLUDE_INSTALL_PATH@
diff --git a/miaconfig.h.cmake b/miaconfig.h.cmake
index 793d8e7..79e6d73 100644
--- a/miaconfig.h.cmake
+++ b/miaconfig.h.cmake
@@ -3,6 +3,10 @@
 #cmakedefine WORDS_BIGENDIAN 1
 #cmakedefine ICA_ALWAYS_USE_SYMM 1 
 
+#cmakedefine BUILD_SSE_ATTRIBUTE_VECTOR_CAN_USE_SUBSCRIPT 1
+
+#cmakedefine ENABLE_DEBUG_MESSAGES 1
+
 #define SOURCE_ROOT "@SOURCE_ROOT@"
 #define PLUGIN_SEARCH_PATH  "@PLUGIN_SEARCH_PATH@"
 #define PLUGIN_INSTALL_PATH  "@PLUGIN_INSTALL_PATH@"
diff --git a/miacore.pc.cmake b/miacore.pc.cmake
index feefd63..36acef1 100644
--- a/miacore.pc.cmake
+++ b/miacore.pc.cmake
@@ -12,6 +12,6 @@ Name: miacore
 Description: A library for 2D/3D grayscale image processing 
 Version: @PACKAGE_VERSION@
 Conflicts:
-Requires: @PKG_CONFIG_DEPS@ 
-Libs: -lmiacore- at VERSION@ @MIA_DEPEND_LIBRARIES@ -L${prefix}/@LIBRARY_INSTALL_PATH@
+Requires.private: @PKG_CONFIG_DEPS@ 
+Libs: -lmiacore- at VERSION@  -L${prefix}/@LIBRARY_INSTALL_PATH@
 Cflags: -I${prefix}/@INCLUDE_INSTALL_PATH@ -I at LIB_INCLUDE_INSTALL_PATH@
diff --git a/octave/CMakeLists.txt b/octave/CMakeLists.txt
index 8cb8b8a..44ff1c3 100644
--- a/octave/CMakeLists.txt
+++ b/octave/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/octave/miaoct.cc b/octave/miaoct.cc
index f57d282..52becc5 100644
--- a/octave/miaoct.cc
+++ b/octave/miaoct.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/2davgmasked.cc b/src/2davgmasked.cc
index 65ea59e..3c3bcad 100644
--- a/src/2davgmasked.cc
+++ b/src/2davgmasked.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -100,8 +100,10 @@ int do_main( int argc, char *argv[] )
 	const auto& image2dio = C2DImageIOPluginHandler::instance();
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( in_filename, "in-files", 'i', "input image(s)", CCmdOption::required, &image2dio));
-	options.add(make_opt( mask_filename, "mask-file", 'm', "mask image, must be of type byte", CCmdOption::required, &image2dio));
+	options.add(make_opt( in_filename, "in-files", 'i', "input image(s)", 
+			      CCmdOptionFlags::required_input, &image2dio));
+	options.add(make_opt( mask_filename, "mask-file", 'm', "mask image, must be of type byte", 
+			      CCmdOptionFlags::required_input, &image2dio));
 
 	if (options.parse(argc, argv, "image") != CCmdOptionList::hr_no) 
 		return EXIT_SUCCESS; 
diff --git a/src/2dbinarycombine.cc b/src/2dbinarycombine.cc
index 327b9ca..a3d0251 100644
--- a/src/2dbinarycombine.cc
+++ b/src/2dbinarycombine.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -113,12 +113,11 @@ int do_main( int argc, char *argv[] )
 
 	const auto& imageio = C2DImageIOPluginHandler::instance();
 	CCmdOptionList options(g_description);
-	options.add(make_opt( filename1, "file1", '1', "input mask image 1", CCmdOption::required, &imageio)); 
-	options.add(make_opt( filename2, "file2", '2', "input input mask image 2", CCmdOption::required, &imageio)); 
-	options.add(make_opt(op, g_binops_dict, "operation", 'p', "Operation to be applied")); 
-	options.add(make_opt( out_filename, "out-file", 'o', "output mask image", CCmdOption::required, &imageio)); 
-
-
+	options.add(make_opt( filename1, "file1", '1', "input mask image 1", CCmdOptionFlags::required_input, &imageio)); 
+	options.add(make_opt( filename2, "file2", '2', "input mask image 2", CCmdOptionFlags::required_input, &imageio)); 
+	options.add(make_opt( out_filename, "out-file", 'o', "output mask image", CCmdOptionFlags::required_output, &imageio)); 
+	
+	options.add(make_opt( op, g_binops_dict, "operation", 'p', "Operation to be applied")); 
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no) 
 		return EXIT_SUCCESS; 
diff --git a/src/2dcost.cc b/src/2dcost.cc
index 1cc1af2..fa92a10 100644
--- a/src/2dcost.cc
+++ b/src/2dcost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/2ddeform.cc b/src/2ddeform.cc
index ce16fd2..121270f 100644
--- a/src/2ddeform.cc
+++ b/src/2ddeform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,10 +50,10 @@ int do_main(int argc, char **argv)
 	string vf_filename;
 	PSplineKernel interpolator_kernel;
 
-	options.add(make_opt( src_filename, "in-file", 'i', "input image", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out-file", 'o', "transformed  image", CCmdOption::required, &imageio));
+	options.add(make_opt( src_filename, "in-file", 'i', "input image", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out-file", 'o', "transformed  image", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( vf_filename, "transformation", 't', "transformation vector field", 
-			      CCmdOption::required, &C2DVFIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_input, &C2DVFIOPluginHandler::instance()));
 	options.add(make_opt( interpolator_kernel ,"bspline:d=3", "interpolator", 'p', "image interpolator kernel"));
 
 
diff --git a/src/2ddistance.cc b/src/2ddistance.cc
index 79762d9..e81f755 100644
--- a/src/2ddistance.cc
+++ b/src/2ddistance.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -142,9 +142,9 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_general_help);
 	options.add(make_opt( in_filename, "in-file", 'i', "input image", 
-			      CCmdOption::required, &imageio)); 
+			      CCmdOptionFlags::required_input, &imageio)); 
 	options.add(make_opt( dist_filename, "distance-file", 'd', "distance field image (floating point)", 
-			      CCmdOption::required, &imageio)); 
+			      CCmdOptionFlags::required_output, &imageio)); 
 	options.add(make_opt( scale, "scale", 's', "distance scaling factor")); 
 	options.add(make_opt( method, combine_option, "method", 'm', "distance measuring method")); 
 	
diff --git a/src/2deval-transformquantity.cc b/src/2deval-transformquantity.cc
index 76d8dfc..1fcef72 100644
--- a/src/2deval-transformquantity.cc
+++ b/src/2deval-transformquantity.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -163,12 +163,12 @@ int do_main( int argc, char *argv[] )
 	options.add(make_opt( in_filename, "in-file", 'i', 
 			      "input point set, if this parameter is given a sparse evaluation "
 			      "of the quantity will be done, otherwise the quantity is evalutated "
-			      "for each grid point of the transformation range."));
+			      "for each grid point of the transformation range.", CCmdOptionFlags::required_input));
 	options.add(make_opt( out_filename, "out-file", 'o', 
-			      "output strains file, for a format description see above.", CCmdOption::required)); 
+			      "output strains file, for a format description see above.", CCmdOptionFlags::required_output)); 
 	
 	options.add(make_opt( trans_filename, "transformation", 't', "transformation of which the quantity will be evaluated.", 
-			      CCmdOption::required, &C2DTransformationIOPluginHandler::instance())); 
+			      CCmdOptionFlags::required_input, &C2DTransformationIOPluginHandler::instance())); 
 
 	options.set_group("\nParameters"); 
 	options.add(make_opt( quantity, tqmap, "quantity", 'q', 
diff --git a/src/2dforce.cc b/src/2dforce.cc
index e3ca22d..581ec6a 100644
--- a/src/2dforce.cc
+++ b/src/2dforce.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -70,10 +70,11 @@ int do_main(int argc, char **argv)
 
 	const auto& imageio = C2DImageIOPluginHandler::instance();
 
-	options.add(make_opt( src_filename, "src-file", 'i', "input image", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out-file", 'o', "output force norm image", CCmdOption::required, &imageio));
-	options.add(make_opt( ref_filename, "ref-file", 'r', "reference image", CCmdOption::required, &imageio));
-	options.add(make_opt( cost_descr, "cost", 'c', "cost function to use", CCmdOption::required));
+	options.add(make_opt( src_filename, "src-file", 'i', "input image", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( ref_filename, "ref-file", 'r', "reference image", CCmdOptionFlags::required_input, &imageio));
+	
+	options.add(make_opt( out_filename, "out-file", 'o', "output force norm image", CCmdOptionFlags::required_output, &imageio));
+	options.add(make_opt( cost_descr, "cost", 'c', "cost function to use", CCmdOptionFlags::required));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/2dfuzzysegment.cc b/src/2dfuzzysegment.cc
index 3a95706..a20e107 100644
--- a/src/2dfuzzysegment.cc
+++ b/src/2dfuzzysegment.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -64,16 +64,18 @@ int do_main( int argc, char *argv[] )
 
 
 	CCmdOptionList options(g_description);
+	options.set_group("File-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i',
-			      "input image(s) to be segmenetd", CCmdOption::required, &imageio));
+			      "input image(s) to be segmenetd", CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( cls_filename, "cls-file", 'c',
 			      "output class probability images (floating point values and multi-image)", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::output, &imageio));
 	options.add(make_opt( out_filename, "b0-file", 'o', "image corrected for intensity non-uniformity", 
-			      CCmdOption::not_required, &imageio ));
+			      CCmdOptionFlags::output, &imageio ));
 	options.add(make_opt( gain_filename, "gain-file", 'g', "gain field (floating point valued)", 
-			      CCmdOption::required, &imageio ));
+			      CCmdOptionFlags::output, &imageio ));
 
+	options.set_group("Parameters"); 
 	options.add(make_opt( noOfClasses, "no-of-classes", 'n',
 			      "number of classes"));
 	options.add(make_opt( params.residuum, "residuum", 'r', "relative residuum"));
diff --git a/src/2dgrayimage-combine-to-rgb.cc b/src/2dgrayimage-combine-to-rgb.cc
index 7f48f9b..3498ca9 100644
--- a/src/2dgrayimage-combine-to-rgb.cc
+++ b/src/2dgrayimage-combine-to-rgb.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -88,13 +88,13 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_general_help);
 	options.add(make_opt( blue_filename, "blue", 'b', "input image for blue channel", 
-			      CCmdOption::not_required, &imageio));
+			      CCmdOptionFlags::input, &imageio));
 	options.add(make_opt( green_filename, "green", 'g', "input image for green channel", 
-			      CCmdOption::not_required, &imageio));
+			      CCmdOptionFlags::input, &imageio));
 	options.add(make_opt( red_filename, "red", 'r', "input image for red channel", 
-			      CCmdOption::not_required, &imageio));
+			      CCmdOptionFlags::input, &imageio));
 
-	options.add(make_opt( out_filename, "out-file", 'o', "combined output image", CCmdOption::required, &imageio));
+	options.add(make_opt( out_filename, "out-file", 'o', "combined output image", CCmdOptionFlags::required_input, &imageio));
 	
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS;
diff --git a/src/2dgroundtruthreg.cc b/src/2dgroundtruthreg.cc
index 87c7ca5..3988b97 100644
--- a/src/2dgroundtruthreg.cc
+++ b/src/2dgroundtruthreg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@
 #include <mia/2d/filter.hh>
 #include <mia/2d/ground_truth_evaluator.hh>
 #include <mia/2d/nonrigidregister.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/transformfactory.hh>
 #include <mia/2d/fullcost.hh>
 #include <mia/2d/similarity_profile.hh>
@@ -152,8 +152,8 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.set_group("\nFile-IO"); 
-	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output perfusion data set", CCmdOption::required));
+	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output perfusion data set", CCmdOptionFlags::required_output));
 	options.add(make_opt( registered_filebase, "registered", 'r', "file name base for registered files")); 
 
 	options.set_group("\nPreconditions"); 
@@ -162,11 +162,11 @@ int do_main( int argc, char *argv[] )
 
 	options.set_group("\nPseudo-Ground-Thruth"); 
 	options.add(make_opt( pgt_params.alpha, "alpha", 'A', "spacial neighborhood penalty weight", 
-				    CCmdOption::required));
+				    CCmdOptionFlags::required));
 	options.add(make_opt( pgt_params.beta, "beta", 'B', "temporal second derivative penalty weight", 
-				    CCmdOption::required));
+				    CCmdOptionFlags::required));
 	options.add(make_opt( pgt_params.rho_thresh, "rho_thresh", 'R', 
-				    "crorrelation threshhold for neighborhood analysis", CCmdOption::required));
+				    "crorrelation threshhold for neighborhood analysis", CCmdOptionFlags::required));
 
 
 	
diff --git a/src/2dimagecombine-dice.cc b/src/2dimagecombine-dice.cc
index 90130d5..fd36e58 100644
--- a/src/2dimagecombine-dice.cc
+++ b/src/2dimagecombine-dice.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -88,8 +88,10 @@ int do_main( int argc, char *argv[] )
 	string in_filename2;
 	
 	CCmdOptionList options(g_general_help);
-	options.add(make_opt( in_filename1, "in-file-1", '1', "input image 1", CCmdOption::required, &imageio)); 
-	options.add(make_opt( in_filename2, "in-file-2", '2', "input image 1", CCmdOption::required, &imageio)); 
+	options.add(make_opt( in_filename1, "in-file-1", '1', "input image 1", 
+			      CCmdOptionFlags::required_input, &imageio)); 
+	options.add(make_opt( in_filename2, "in-file-2", '2', "input image 2", 
+			      CCmdOptionFlags::required_input, &imageio)); 
 
 	
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/2dimagecombiner.cc b/src/2dimagecombiner.cc
index fbcebbf..8a6a880 100644
--- a/src/2dimagecombiner.cc
+++ b/src/2dimagecombiner.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -53,11 +53,11 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in1_filename, "in-file-1", '1', 
-			      "first input image to be combined", CCmdOption::required, &imageio));
+			      "first input image to be combined", CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( in2_filename, "in-file-2", '2', 
-				    "second input image to be combined", CCmdOption::required, &imageio));
+			      "second input image to be combined", CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o',
-				    "output image(s) that have been filtered", CCmdOption::required, &imageio));
+			      "output image(s) that have been filtered", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( combiner, "absdiff", "operation", 'p', "operation to be applied"));
 	
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no) 
diff --git a/src/2dimagecreator.cc b/src/2dimagecreator.cc
index 8819af3..4052234 100644
--- a/src/2dimagecreator.cc
+++ b/src/2dimagecreator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -52,10 +52,10 @@ int do_main(int argc, char *argv[])
 	CCmdOptionList options(g_description);
 
 	options.add(make_opt( out_filename, "out-file", 'o', "output file for create object", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( size, "size", 's', "size of the object"));
 	options.add(make_opt( pixel_type, CPixelTypeDict, "repn", 'r',"input pixel type "));
-	options.add(make_opt( creator, "", "object", 'j', "object to be created", CCmdOption::required));
+	options.add(make_opt( creator, "", "object", 'j', "object to be created", CCmdOptionFlags::required));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no) 
 		return EXIT_SUCCESS; 
diff --git a/src/2dimagefilter.cc b/src/2dimagefilter.cc
index 11eaa7a..847e884 100644
--- a/src/2dimagefilter.cc
+++ b/src/2dimagefilter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -51,9 +51,9 @@ int do_main( int argc, char *argv[] )
 	
 	CCmdOptionList options(g_general_help);
 	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o', "output image(s) that have been filtered", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_output, &imageio));
 	options.set_group(g_help_optiongroup); 
 	options.add(make_help_opt( "help-filters", 0,
 				   "give some help about the filter plugins", 
diff --git a/src/2dimagefilterstack.cc b/src/2dimagefilterstack.cc
index bb316b2..4d0ea07 100644
--- a/src/2dimagefilterstack.cc
+++ b/src/2dimagefilterstack.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -71,9 +71,11 @@ int do_main( int argc, char *argv[] )
 	CCmdOptionList options(g_general_help);
 
 	options.set_group("File IO"); 
-	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", CCmdOption::required, &imageio));
+	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", 
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o', "output file name base, the file type is set "
-			      " accurding to the 'type' option", CCmdOption::required, &imageio));
+			      " accurding to the 'type' option", 
+			      CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( out_type, imageio.get_supported_suffix_set(), "type", 't',"output file type, if "
 			      "not given the input type is used"));
 
diff --git a/src/2dimagefullstats.cc b/src/2dimagefullstats.cc
index abf4a1e..35aceb3 100644
--- a/src/2dimagefullstats.cc
+++ b/src/2dimagefullstats.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -53,7 +53,7 @@ int do_main( int argc, char *argv[] )
 	string in_filename;
 	CCmdOptionList options(g_general_help);
 	options.add(make_opt( in_filename, "in-file", 'i', "input image", 
-			      CCmdOption::required, &C2DImageIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_input, &C2DImageIOPluginHandler::instance()));
 	
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/2dimageregistration.cc b/src/2dimageregistration.cc
index f9fb769..a4eb449 100644
--- a/src/2dimageregistration.cc
+++ b/src/2dimageregistration.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -54,16 +54,19 @@ int do_main( int argc, char *argv[] )
 	const auto& imageio = C2DImageIOPluginHandler::instance(); 
 
 	CCmdOptionList options(g_general_help);
-	options.add(make_opt( src_filename, "in", 'i', "test image", CCmdOption::required, &imageio));
-	options.add(make_opt( ref_filename, "ref", 'r', "reference image", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out", 'o', "registered output image", CCmdOption::required, &imageio));
+	
+	options.set_group("File-IO"); 
+	options.add(make_opt( src_filename, "in", 'i', "test image", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( ref_filename, "ref", 'r', "reference image", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out", 'o', "registered output image", CCmdOptionFlags::output, &imageio));
 	options.add(make_opt( trans_filename, "trans", 't', "output transformation", 
-			      CCmdOption::required, &C2DTransformationIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_output, &C2DTransformationIOPluginHandler::instance()));
+
+	options.set_group("Parameters"); 
 	options.add(make_opt( mg_levels, "levels", 'l', "multi-resolution levels"));
 	options.add(make_opt( minimizer, "gsl:opt=gd,step=0.1", "optimizer", 'O', "Optimizer used for minimization"));
 	options.add(make_opt( refinement_minimizer, "", "refiner", 'R',
 			      "optimizer used for refinement after the main optimizer was called"));
-	
 	options.add(make_opt( transform_creator, "spline", "transForm", 'f', "transformation type"));
 
 	if (options.parse(argc, argv, "cost", &C2DFullCostPluginHandler::instance()) != CCmdOptionList::hr_no)
diff --git a/src/2dimageselect.cc b/src/2dimageselect.cc
index 6817c8c..25e6016 100644
--- a/src/2dimageselect.cc
+++ b/src/2dimageselect.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,9 +50,9 @@ int do_main( int argc, char *argv[])
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i',
-				    "input images", CCmdOption::required, &imageio));
+				    "input images", CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o',
-				    "output image", CCmdOption::required, &imageio));
+				    "output image", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( num, "number", 'n',  "image number to be selected"));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/2dimageseries-maximum-intensity-projection.cc b/src/2dimageseries-maximum-intensity-projection.cc
new file mode 100644
index 0000000..27f3317
--- /dev/null
+++ b/src/2dimageseries-maximum-intensity-projection.cc
@@ -0,0 +1,111 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+#include <sstream>
+#include <stdexcept>
+
+#include <mia/core.hh>
+#include <mia/core/revision.hh>
+#include <mia/2d/imageio.hh>
+
+
+
+NS_MIA_USE
+using namespace std;
+using namespace boost;
+
+const SProgramDescription g_description = {
+	{pdi_group, "Analysis, filtering, combining, and segmentation of 2D images"}, 
+	{pdi_short, "Evaluate maximum per-pixel intensities of an image series."}, 
+	{pdi_description, "This program is used to evaluate the per-pixel maximum intensity "
+         "of an image series."}, 
+}; 
+
+struct C2DMax : public TFilter<bool> {
+
+	C2DMax()
+	{
+	}
+
+	template <typename T>
+	bool operator ()(const T2DImage<T>& image, T2DImage<T>& inout) const 
+	{
+		if (image.get_size() != inout.get_size())
+			throw invalid_argument("Input images differ in size");
+
+                auto iio = inout.begin();
+		auto ii = image.begin();
+		auto ei = image.end();
+
+		while (ii != ei) {
+                        if (*iio < *ii) 
+                                *iio = *ii; 
+                        ++iio; 
+                        ++ii; 
+                }
+                return true;
+	}
+};
+
+int do_main( int argc, char *argv[] )
+{
+
+	string out_filename;
+
+	const auto& image2dio = C2DImageIOPluginHandler::instance();
+
+	CCmdOptionList options(g_description);
+	options.add(make_opt( out_filename, "out-file", 'o', "output image", CCmdOptionFlags::required_output, &image2dio));
+
+	if (options.parse(argc, argv, "image") != CCmdOptionList::hr_no) 
+		return EXIT_SUCCESS; 
+
+	if (options.get_remaining().empty())
+		throw runtime_error("You must give the image to be combined as free parameters");
+
+        if (options.get_remaining().size() < 2)
+                throw runtime_error("You must give at least two images to combine");
+
+
+	CHistory::instance().append(argv[0], LIBMIA_REVISION, options);
+	char new_line = cverb.show_debug() ? '\n' : '\r';
+
+	C2DMax max_op; 
+
+        P2DImage result = load_image2d(options.get_remaining()[0]); 
+
+
+	for (auto iname = options.get_remaining().begin() + 1; iname != options.get_remaining().end(); ++iname) {
+                auto image = load_image2d(*iname); 
+                cvmsg() << "Combine image '" << *iname << new_line; 
+                mia::filter_equal_inplace(max_op, *image, *result); 
+	}
+	cvmsg() << "\n";
+
+        save_image(out_filename, result); 
+
+	return EXIT_SUCCESS;
+}
+
+#include <mia/internal/main.hh>
+MIA_MAIN(do_main); 
diff --git a/src/2dimagestats.cc b/src/2dimagestats.cc
index 7a9b845..fad4618 100644
--- a/src/2dimagestats.cc
+++ b/src/2dimagestats.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -101,7 +101,7 @@ int do_main( int argc, char *argv[] )
 	
 	CCmdOptionList options(g_general_help);
 	options.add(make_opt( in_filename, "in-file", 'i', "input image to be analyzed", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( thresh, "thresh", 't', "intensity thresh to ignore"));
 	options.add(make_opt( high_thresh, "high-thresh", 'g', "upper histogram percentage to ignore"));
 	
diff --git a/src/2dlerp.cc b/src/2dlerp.cc
index d7f2230..e16cf62 100644
--- a/src/2dlerp.cc
+++ b/src/2dlerp.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -139,14 +139,14 @@ int do_main(int argc, char **argv)
 	const auto& imageio = C2DImageIOPluginHandler::instance();
 
 	options.add(make_opt( src1_filename, "first", '1', "first input image ", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( src2_filename, "second", '2', "second input image ", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o', "output vector field", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( positions, "positions", 'p', 
-				    "image series positions (first, target, second)", 
-			      CCmdOption::required));
+			      "image series positions (first, target, second)", 
+			      CCmdOptionFlags::required));
 	options.add(make_opt( self_test, "self-test", 0, "run a self test of the tool"));
 	
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/2dmany2one-nonrigid.cc b/src/2dmany2one-nonrigid.cc
index 4598bd3..45dc3db 100644
--- a/src/2dmany2one-nonrigid.cc
+++ b/src/2dmany2one-nonrigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -139,10 +139,10 @@ int do_main( int argc, char *argv[] )
 	
 	options.set_group("\nFile-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i', 
-				    "input perfusion data set", CCmdOption::required));
+			      "input perfusion data set", CCmdOptionFlags::required_input));
 	options.add(make_opt( registered_filebase, "out-file", 'o', 
-				    "file name for registered images, numbering and pattern are deducted from the input data")); 
-	
+			      "file name for registered images, numbering and pattern are deducted from the input data", 
+			      CCmdOptionFlags::required)); 
 	
 	options.set_group("\nRegistration"); 
 	options.add(make_opt( minimizer, "optimizer", 'O', "Optimizer used for minimization"));
diff --git a/src/2dmulti-force.cc b/src/2dmulti-force.cc
index df639e5..a3f6c4b 100644
--- a/src/2dmulti-force.cc
+++ b/src/2dmulti-force.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -58,7 +58,7 @@ int do_main(int argc, char **argv)
 	const auto& imageio = C2DImageIOPluginHandler::instance();
 	const auto& costcreator = C2DFullCostPluginHandler::instance(); 
 
-	options.add(make_opt( out_filename, "out-file", 'o', "output norm image", CCmdOption::required, &imageio));
+	options.add(make_opt( out_filename, "out-file", 'o', "output norm image", CCmdOptionFlags::required_input, &imageio));
 
 	if (options.parse(argc, argv, "cost", &costcreator) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/2dmulti-nrreg.cc b/src/2dmulti-nrreg.cc
index fbd229f..1dbf119 100644
--- a/src/2dmulti-nrreg.cc
+++ b/src/2dmulti-nrreg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/2dmultiimageto3d.cc b/src/2dmultiimageto3d.cc
index 3bc979f..9e74af4 100644
--- a/src/2dmultiimageto3d.cc
+++ b/src/2dmultiimageto3d.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -52,14 +52,14 @@ int do_main( int argc, char *argv[])
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i',
-				    "input images", CCmdOption::required, &imageio2d));
+				    "input images", CCmdOptionFlags::required_input, &imageio2d));
 	options.add(make_opt( out_filename, "out-file", 'o',
-				    "output image", CCmdOption::required, &imageio3d));
+				    "output image", CCmdOptionFlags::required_output, &imageio3d));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
 
-
+	
 	// read image
 	C2DImageIOPluginHandler::Instance::PData  in_image_list = imageio2d.load(in_filename);
 	if (!in_image_list)
diff --git a/src/2dmultiimagevar.cc b/src/2dmultiimagevar.cc
index 4f2cadf..ffb837b 100644
--- a/src/2dmultiimagevar.cc
+++ b/src/2dmultiimagevar.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -92,7 +92,8 @@ int do_main( int argc, char *argv[] )
 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( out_filename, "out-file", 'o', "output image ", CCmdOption::required, &imageio));
+	options.add(make_opt( out_filename, "out-file", 'o', "output image ", 
+			      CCmdOptionFlags::required_output, &imageio));
 
 	if (options.parse(argc, argv, "image", &imageio) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/2dmyocard-ica.cc b/src/2dmyocard-ica.cc
index 025d7ce..94243fe 100644
--- a/src/2dmyocard-ica.cc
+++ b/src/2dmyocard-ica.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -364,7 +364,7 @@ int do_main( int argc, char *argv[] )
 	
 	CCmdOptionList options(g_description); 
 	options.add(make_opt( src_name, "in-base", 'i', "input file name ofolloing pattern nameXXXX.ext X=numbers" , 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( coefs_name, "coefs", 0, "output mixing coefficients to this file"));
 	options.add(make_opt( out_name, "out-base", 'o', "output file name base"));
 
diff --git a/src/2dmyocard-icaseries.cc b/src/2dmyocard-icaseries.cc
index a09cb0b..4d5e349 100644
--- a/src/2dmyocard-icaseries.cc
+++ b/src/2dmyocard-icaseries.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -37,7 +37,7 @@
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 #include <mia/2d/ica.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/perfusion.hh>
 #include <mia/2d/transformfactory.hh>
 NS_MIA_USE;
@@ -87,7 +87,7 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.set_group("File-IO"); 
-	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOption::required));
+	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOptionFlags::required_input));
 	options.add(make_opt( reference_filename, "references", 'r', "File name base for the reference images. "
 			      "Image type and numbering scheme are taken from the input images.")); 
 	options.add(make_opt( cropped_filename, "save-cropped", 'c', "save cropped set of the original set to this file, "
diff --git a/src/2dmyocard-segment.cc b/src/2dmyocard-segment.cc
index 55121db..2b8804a 100644
--- a/src/2dmyocard-segment.cc
+++ b/src/2dmyocard-segment.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,7 +38,7 @@
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 #include <mia/2d/ica.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/fuzzyseg.hh>
 #include <mia/2d/perfusion.hh>
 #include <mia/2d/transformfactory.hh>
@@ -426,10 +426,12 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.set_group("File-IO"); 
-	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOption::required));
+	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", 
+			      CCmdOptionFlags::required_input));
 	options.add(make_opt( out_filename, "out-file", 'o', "output myocardial mask", 
-			      CCmdOption::required, &imageio));
-	options.add(make_opt( save_feature, "save-features", 'f', "save ICA features to files with this name base")); 
+			      CCmdOptionFlags::required_output, &imageio));
+	options.add(make_opt( save_feature, "save-features", 'f', "save ICA features to files with this name base", 
+			      CCmdOptionFlags::output)); 
 
 	options.set_group("ICA");
 	options.add(make_opt( components, "components", 'C', "ICA components 0 = automatic estimation testing 4 and 5"));
diff --git a/src/2dmyocard-upsloap.cc b/src/2dmyocard-upsloap.cc
index f64e053..100e77f 100644
--- a/src/2dmyocard-upsloap.cc
+++ b/src/2dmyocard-upsloap.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,7 +36,7 @@
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 #include <mia/2d/ica.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/perfusion.hh>
 #include <mia/2d/transformfactory.hh>
 NS_MIA_USE;
@@ -103,8 +103,8 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.set_group("File-IO"); 
-	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output file with curves", CCmdOption::required));
+	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output file with curves", CCmdOptionFlags::required_output));
 
 	options.set_group("ICA");
 	options.add(make_opt( components, "components", 'C', "ICA components 0 = automatic estimation"));
diff --git a/src/2dmyoica-full.cc b/src/2dmyoica-full.cc
new file mode 100644
index 0000000..72adefe
--- /dev/null
+++ b/src/2dmyoica-full.cc
@@ -0,0 +1,664 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define VSTREAM_DOMAIN "2dmyoica-full"
+
+#include <fstream>
+#include <itpp/signal/fastica.h>
+
+#include <mia/core/msgstream.hh>
+#include <mia/core/threadedmsg.hh>
+#include <mia/core/cmdlineparser.hh>
+#include <mia/core/errormacro.hh>
+#include <mia/core/minimizer.hh>
+#include <mia/core/bfsv23dispatch.hh>
+#include <mia/core/attribute_names.hh>
+#include <mia/2d/nonrigidregister.hh>
+#include <mia/2d/perfusion.hh>
+#include <mia/2d/imageio.hh>
+#include <mia/2d/segsetwithimages.hh>
+#include <mia/2d/transformfactory.hh>
+
+#include <tbb/parallel_for.h>
+#include <tbb/parallel_reduce.h>
+#include <tbb/blocked_range.h>
+using namespace tbb;
+
+using namespace std;
+using namespace mia;
+
+namespace bfs=boost::filesystem; 
+
+const SProgramDescription g_description = {
+
+	{pdi_group, "Registration of series of 2D images"}, 
+	{pdi_short, "Run a registration of a series of 2D images."}, 
+	{pdi_description, "This program implements the 2D version of the motion compensation algorithm "
+	 "described in Wollny G, Kellman P, Santos A, Ledesma-Carbayo M-J, \"Automatic Motion "
+	 "Compensation of Free Breathing acquired Myocardial Perfusion Data by using Independent "
+	 "Component Analysis\", Medical Image Analysis, 2012, DOI:10.1016/j.media.2012.02.004. "
+         "The software may first run a linear registration and then a non-linear registration or "
+         "just one of the both." 
+	 "This version of the program may run all registrations in parallel."}, 
+
+	{pdi_example_descr, "Register the perfusion series given in 'segment.set' by using automatic "
+	 "ICA estimation. Skip two images at the beginning and otherwiese use the default parameters. "
+	 "Store the result in 'registered.set'."}, 
+
+	{pdi_example_code, "  -i segment.set -o registered.set -k 2"}
+}; 
+
+
+C2DFullCostList create_costs(const string& imagecostbase, int idx)
+{
+	stringstream cost_descr; 
+	cost_descr << imagecostbase << ",src=src" << idx << ".@,ref=ref" << idx << ".@"; 
+	auto imagecost = C2DFullCostPluginHandler::instance().produce(cost_descr.str()); 
+
+	C2DFullCostList result; 
+	result.push(imagecost); 
+	return result; 
+}
+
+P2DTransformationFactory create_spline_transform_creator(size_t c_rate, double divcurlweight)
+{
+	stringstream transf; 
+	transf << "spline:rate=" << c_rate << ",imgboundary=mirror,imgkernel=[bspline:d=3]"
+	       << ",penalty=[divcurl:weight=" << divcurlweight << "]"; 
+	return C2DTransformCreatorHandler::instance().produce(transf.str()); 
+}
+
+C2DBounds segment_and_crop_input(CSegSetWithImages&  input_set, 
+			    const C2DPerfusionAnalysis& ica, 
+			    float box_scale, 
+			    C2DPerfusionAnalysis::EBoxSegmentation segmethod, 
+			    C2DImageSeries& references, 
+			    const string& save_crop_feature)
+{
+	C2DBounds crop_start = C2DBounds::_0; 
+	auto cropper = ica.get_crop_filter(box_scale, crop_start, 
+					   segmethod, save_crop_feature); 
+	if (!cropper) {
+		cvwarn() << "Cropping was requested, but segmentation failed - continuing at full image size\n";
+		return crop_start; 
+	}
+	
+	C2DImageSeries input_images = input_set.get_images(); 
+	for(auto i = input_images.begin(); i != input_images.end(); ++i)
+		*i = cropper->filter(**i); 
+	
+	for (auto i = references.begin(); i != references.end(); ++i) 
+		*i = cropper->filter(**i); 
+	
+	auto tr_creator = C2DTransformCreatorHandler::instance().produce("translate");
+	P2DTransformation shift = tr_creator->create(C2DBounds(1,1)); 
+	auto p = shift->get_parameters(); 
+	p[0] = crop_start.x; 
+	p[1] = crop_start.y; 
+	shift->set_parameters(p); 
+	
+	input_set.transform(*shift);
+	input_set.set_images(input_images);  
+        return crop_start; 
+}
+
+
+struct SeriesRegistration {
+	C2DImageSeries& input_images; 
+	CSegSetWithImages::Frames& frames;
+	const C2DImageSeries& references; 
+	string minimizer; 
+	size_t mg_levels; 
+	P2DTransformationFactory transform_creator; 
+	string imagecostbase; 
+	int skip_images; 
+        int global_reference; 
+	
+	SeriesRegistration(C2DImageSeries& _input_images, 
+			   CSegSetWithImages::Frames& _frames,
+			   const C2DImageSeries& _references, 
+			   const string& _minimizer, 
+			   size_t _mg_levels, 
+			   P2DTransformationFactory _transform_creator, 
+			   string _imagecostbase, 
+			   int _skip_images, 
+                           int _global_reference):
+		input_images(_input_images), 
+		frames(_frames), 
+		references(_references), 
+		minimizer(_minimizer), 
+		mg_levels(_mg_levels), 
+                transform_creator(_transform_creator), 
+		imagecostbase(_imagecostbase), 
+		skip_images(_skip_images), 
+                global_reference(_global_reference)
+		{
+		}
+	P2DTransformation operator()( const blocked_range<int>& range, P2DTransformation init) const {
+		CThreadMsgStream thread_stream;
+		TRACE_FUNCTION; 
+                P2DTransformation result = init; 
+                
+		auto m =  CMinimizerPluginHandler::instance().produce(minimizer);
+		for( int i=range.begin(); i!=range.end(); ++i ) {
+			auto costs  = create_costs(imagecostbase, i); 
+			C2DNonrigidRegister nrr(costs, m,  transform_creator, mg_levels, i);
+                        if (i + skip_images != global_reference) {
+				cvmsg() << "image size ["<< i << "]= " << input_images[i + skip_images]->get_size() << ":" << references[i]->get_size() << "\n"; 
+                                P2DTransformation transform = nrr.run(input_images[i + skip_images], references[i]);
+                                input_images[i + skip_images] = (*transform)(*input_images[i + skip_images]);
+                                frames[i + skip_images].inv_transform(*transform);
+                        }else {
+                                result = nrr.run(references[i], input_images[i + skip_images]);
+                        }
+		}
+                return result; 
+	}
+};  
+
+
+void run_registration_pass(CSegSetWithImages& input_set, 
+			   const C2DImageSeries& references,  
+			   int skip_images,  const string& minimizer, 
+			   size_t mg_levels, P2DTransformationFactory transform_creator, 
+			   const string&   imagecost, int global_reference) 
+{
+	C2DImageSeries input_images = input_set.get_images(); 
+	CSegSetWithImages::Frames& frames = input_set.get_frames();
+	
+	
+	SeriesRegistration sreg(input_images, frames, references, minimizer, 
+				mg_levels, transform_creator, 
+				imagecost, skip_images, global_reference); 
+        
+        P2DTransformation init; 
+	P2DTransformation inv_transf = parallel_reduce(blocked_range<int>( 0, references.size()), init, sreg, 
+                                                       [](P2DTransformation a, P2DTransformation b) {
+                                                               if (a) 
+                                                                       return a; 
+                                                               return b; 
+                                                       });
+
+        // apply inverse to all images 
+        if (inv_transf) {
+		cvmsg() << "Apply inverse for reference correction\n"; 
+                const C2DTransformation& inv_transf_ref = * inv_transf; 
+                parallel_for(blocked_range<int>( 0, references.size()), 
+                             [&inv_transf_ref, &frames, skip_images, global_reference, &input_images](const blocked_range<int>& range){
+				     CThreadMsgStream thread_stream;
+                                     for( int i=range.begin(); i!=range.end(); ++i ) {
+                                             if (i != global_reference - skip_images) {
+                                                     input_images[i + skip_images] = inv_transf_ref(*input_images[i + skip_images]);
+                                                     frames[i + skip_images].inv_transform(inv_transf_ref);
+                                             }
+                                     }
+                             });
+        }
+        input_set.set_images(input_images);
+}
+
+void run_nonlinear_registration_passes (CSegSetWithImages& input_set, 
+                                        C2DImageSeries& references,  
+                                        int skip_images,  int components, bool normalize, bool no_meanstrip, int max_ica_iterations, 
+                                        const string& minimizer, 
+                                        size_t mg_levels, double c_rate, double c_rate_divider, 
+                                        double divcurlweight, double divcurlweight_divider, 
+                                        int max_pass, const string& imagecost, int global_reference, float min_rel_frequency)
+{
+        int current_pass = 0; 
+	bool do_continue=true; 
+	bool lastpass = false; 
+	vector<C2DFImage> references_float; 
+	do {
+		++current_pass; 
+		cvmsg() << "Registration pass " << current_pass << "\n"; 
+                
+                auto transform_creator = create_spline_transform_creator(c_rate, divcurlweight); 
+
+
+                run_registration_pass(input_set, references,  
+                                      skip_images,  minimizer, mg_levels, transform_creator, 
+                                      imagecost, global_reference); 
+
+		if (lastpass) 
+			break; 
+                
+		C2DPerfusionAnalysis ica2(components, normalize, !no_meanstrip); 
+		if (max_ica_iterations) 
+			ica2.set_max_ica_iterations(max_ica_iterations); 
+		if (min_rel_frequency >= 0)
+			ica2.set_min_movement_frequency(min_rel_frequency); 
+	
+                vector<C2DFImage> series(input_set.get_images().size() - skip_images); 
+		transform(input_set.get_images().begin() + skip_images, 
+			  input_set.get_images().end(), series.begin(), FCopy2DImageToFloatRepn()); 
+
+		if (!ica2.run(series)) {
+			ica2.set_approach(FICA_APPROACH_SYMM); 
+			ica2.run(series); 
+		}
+		
+		divcurlweight /= divcurlweight_divider; 
+		if (c_rate > 1) 
+			c_rate /= c_rate_divider; 
+		references_float = ica2.get_references(); 
+		cvmsg() << "references_float size:" << references_float[0].get_size() << "\n"; 
+		transform(references_float.begin(), references_float.end(), 
+			  references.begin(), FWrapStaticDataInSharedPointer<C2DImage>()); 
+		do_continue =  (!max_pass || current_pass < max_pass) && ica2.has_movement(); 
+		
+		// run one more pass if the limit is not reached and no movement identified
+		lastpass = (!do_continue && (!max_pass || current_pass < max_pass)); 
+		
+	} while (do_continue || lastpass); 
+        
+}
+
+void run_linear_registration_passes (CSegSetWithImages& input_set, 
+                                     C2DImageSeries& references,  
+                                     int components, bool normalize, bool no_meanstrip, int max_ica_iterations, 
+                                     int skip_images,  const string& minimizer, const string& linear_transform, 
+                                     size_t mg_levels, int max_pass, const string& imagecost, int global_reference, 
+				     float min_rel_frequency)
+{
+        int current_pass = 0; 
+	bool do_continue=true; 
+	bool lastpass = false; 
+	vector<C2DFImage> references_float; 
+	do {
+		++current_pass; 
+		cvmsg() << "Registration pass " << current_pass << "\n"; 
+                
+                auto transform_creator = C2DTransformCreatorHandler::instance().produce(linear_transform); 
+
+		cvmsg() << "references_float size:" << references[0]->get_size() << "\n"; 
+                run_registration_pass(input_set, references,  
+                                      skip_images,  minimizer, mg_levels, transform_creator, 
+                                      imagecost, global_reference); 
+
+		if (lastpass) 
+			break; 
+			
+                
+		C2DPerfusionAnalysis ica2(components, normalize, !no_meanstrip); 
+		if (max_ica_iterations) 
+			ica2.set_max_ica_iterations(max_ica_iterations); 
+		if (min_rel_frequency >= 0)
+			ica2.set_min_movement_frequency(min_rel_frequency); 
+	
+                vector<C2DFImage> series(input_set.get_images().size() - skip_images); 
+		transform(input_set.get_images().begin() + skip_images, 
+			  input_set.get_images().end(), series.begin(), FCopy2DImageToFloatRepn()); 
+
+		if (!ica2.run(series)) {
+			ica2.set_approach(FICA_APPROACH_SYMM); 
+			ica2.run(series); 
+		}
+		
+		references_float = ica2.get_references(); 
+		transform(references_float.begin(), references_float.end(), 
+			  references.begin(), FWrapStaticDataInSharedPointer<C2DImage>()); 
+
+		
+		cvmsg() << "references_float size:" << references[0]->get_size() << "\n"; 
+		do_continue =  (!max_pass || current_pass < max_pass) && ica2.has_movement(); 
+		
+		// run one more pass if the limit is not reached and no movement identified
+		lastpass = (!do_continue && (!max_pass || current_pass < max_pass)); 
+		
+	} while (do_continue || lastpass); 
+        
+}
+
+class FInsertData : public TFilter< P2DImage >  {
+public: 
+	FInsertData(const C2DBounds& start, const C2DBounds& end): 
+		m_start(start), m_end(end){}
+	
+	template <typename T>
+	void operator () ( const T2DImage<T>& a, T2DImage<T>& b) const {
+		auto ia = a.begin(); 
+		auto ea = a.end(); 
+		auto ib = b.begin_range(m_start,m_end); 
+		while (ia != ea) {
+			*ib = *ia; 
+			++ia; 
+			++ib; 
+		}
+
+	}
+private: 
+		
+	C2DBounds m_start; 
+	C2DBounds m_end; 
+}; 
+
+float get_relative_min_breathing_frequency(const C2DImageSeries& images, int skip, float min_breathing_frequency)
+{
+	if (min_breathing_frequency < 0) 
+		return -1; 
+	if (min_breathing_frequency == 0) 
+		return 0; 
+	int n_heartbeats = images.size() - skip; 
+	auto image_begin =  images[skip]; 
+	auto image_end = images[images.size() - 1]; 
+
+	if (image_begin->has_attribute("AcquisitionTime") && image_end->has_attribute(IDAcquisitionTime)) {
+		double aq_time = image_end->get_attribute_as<double>(IDAcquisitionTime) - 
+			image_begin->get_attribute_as<double>(IDAcquisitionTime);
+		if (aq_time < 0) 
+			throw create_exception<runtime_error>("Got non-postive aquisition time range ", aq_time, 
+							      ", can't handle this");  
+							      
+		double heart_rate = 60 * n_heartbeats / aq_time; 
+		cvmsg() << "Read a heartbeat rate of " << heart_rate << " beats/min\n";
+		return heart_rate / min_breathing_frequency; 
+	}else 
+		return -1; 
+}
+
+int do_main( int argc, char *argv[] )
+{
+	// IO parameters 
+	string in_filename;
+	string out_filename;
+	string registered_filebase;
+
+	// debug options: save some intermediate steps 
+	string cropped_filename;
+	string save_crop_feature; 
+	string save_ref_filename;
+	string save_reg_filename;
+
+	// non-linear registration parameters
+	string linear_minimizer("gsl:opt=simplex,step=1.0");
+	string nonlinear_minimizer("gsl:opt=gd,step=0.1");
+	string imagecost("image:weight=1,cost=ssd");
+	double c_rate = 16; 
+	double c_rate_divider = 2; 
+	double divcurlweight = 10000.0; 
+	double divcurlweight_divider = 2.0;
+
+        string linear_transform("affine");
+
+	size_t mg_levels = 3; 
+
+	// ICA parameters 
+	size_t components = 0;
+	bool normalize = false; 
+	bool no_meanstrip = false; 
+	float box_scale = 0.0;
+	size_t skip_images = 0; 
+	size_t max_ica_iterations = 400; 
+	C2DPerfusionAnalysis::EBoxSegmentation 
+		segmethod=C2DPerfusionAnalysis::bs_features; 
+
+	float min_breathing_frequency = -1.0f; 
+
+	size_t max_linear_passes = 3; 
+	size_t max_nonlinear_passes = 3; 
+        int global_reference = -1; 
+
+	CCmdOptionList options(g_description);
+	
+	options.set_group("File-IO"); 
+	options.add(make_opt( in_filename, "in-file", 'i', 
+			      "input perfusion data set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', 
+			      "output perfusion data set", CCmdOptionFlags::required_output));
+	options.add(make_opt( registered_filebase, "registered", 'r', 
+			      "File name base for the registered images. Image type and numbering "
+			      "scheme are taken from the input images as given in the input data set.")); 
+	
+	options.add(make_opt( cropped_filename, "save-cropped", 0, 
+			      "save cropped set to this file, the image files will use the stem of the "
+			      "name as file name base", CCmdOptionFlags::output)); 
+	options.add(make_opt( save_crop_feature, "save-feature", 0, 
+			      "save segmentation feature images and initial ICA mixing matrix", CCmdOptionFlags::output)); 
+	
+	options.add(make_opt( save_ref_filename, "save-refs", 0, 
+			      "for each registration pass save the reference images to files with the given name base", 
+			      CCmdOptionFlags::output
+			    )); 
+	options.add(make_opt( save_reg_filename, "save-regs", 0, 
+			      "for each registration pass save intermediate registered images", CCmdOptionFlags::output)); 
+
+
+	
+	options.set_group("Registration"); 
+	options.add(make_opt(linear_minimizer, "linear-optimizer", 'L', 
+                             "Optimizer used for minimization of the linear registration", 
+                             CCmdOptionFlags::none, &CMinimizerPluginHandler::instance()));
+	options.add(make_opt(linear_transform, "linear-transform", 0, 
+                             "linear transform to be used", 
+                             CCmdOptionFlags::none, &C2DTransformCreatorHandler::instance()));
+        
+        options.add(make_opt(nonlinear_minimizer, "non-linear-optimizer", 'O', 
+                             "Optimizer used for minimization in the non-linear registration.", 
+                             CCmdOptionFlags::none, &CMinimizerPluginHandler::instance()));
+	options.add(make_opt( c_rate, "start-c-rate", 'a', 
+                              "start coefficinet rate in spines,"
+                              " gets divided by --c-rate-divider with every pass."));
+	options.add(make_opt( c_rate_divider, "c-rate-divider", 0, 
+                              "Cofficient rate divider for each pass."));
+	options.add(make_opt( divcurlweight, "start-divcurl", 'd',
+                              "Start divcurl weight, gets divided by"
+                              " --divcurl-divider with every pass.")); 
+	options.add(make_opt( divcurlweight_divider, "divcurl-divider", 0,
+                              "Divcurl weight scaling with each new pass.")); 
+	options.add(make_opt( global_reference, "reference", 'R', "Global reference all image should be aligned to. If set "
+			      "to a non-negative value, the images will be aligned to this references, and the cropped "
+                              "output image date will be injected into the original images. Leave at -1 if "
+			      "you don't care. In this case all images with be registered to a mean position of the movement")); 
+        
+	// why do I allow to set this parameter, it should always be image:cost=ssd  
+	options.add(make_opt( imagecost, "imagecost", 'w',
+			      "image cost, do not specify the src and ref parameters, these will be set by the program.",
+			      CCmdOptionFlags::none, &C2DFullCostPluginHandler::instance())); 
+	options.add(make_opt( mg_levels, "mg-levels", 'l', "multi-resolution levels"));
+	options.add(make_opt( max_linear_passes, "linear-passes", 'p', "linear registration passes (0 to disable)")); 
+	options.add(make_opt( max_nonlinear_passes, "nonlinear-passes", 'P', "non-linear registration passes (0 to disable)")); 
+
+	options.set_group("ICA"); 
+	options.add(make_opt( components, "components", 'C', "ICA components 0 = automatic estimation"));
+	options.add(make_opt( normalize, "normalize", 0, "normalized ICs"));
+	options.add(make_opt( no_meanstrip, "no-meanstrip", 0, 
+				    "don't strip the mean from the mixing curves"));
+	options.add(make_opt( box_scale, "segscale", 's', 
+				    "segment and scale the crop box around the LV (0=no segmentation)"));
+	options.add(make_opt( skip_images, "skip", 'k', "skip images at the beginning of the series "
+				    "e.g. because as they are of other modalities")); 
+	options.add(make_opt( max_ica_iterations, "max-ica-iter", 'm', "maximum number of iterations in ICA")); 
+
+	options.add(make_opt(segmethod , C2DPerfusionAnalysis::segmethod_dict, "segmethod", 'E', 
+			     "Segmentation method")); 
+	options.add(make_opt(min_breathing_frequency, "min-breathing-frequency", 'b', 
+			     "minimal mean frequency a mixing curve can have to be considered to stem from brething. "
+			     "A healthy rest breating rate is 12 per minute. A negative value disables the test. "
+			     "A value 0.0 forces the series to be indentified as acquired with initial breath hold.")); 
+	
+
+	if (options.parse(argc, argv) != CCmdOptionList::hr_no) 
+		return EXIT_SUCCESS; 
+
+        
+	// load input data set
+	CSegSetWithImages  input_set(in_filename, true);
+	C2DImageSeries input_images = input_set.get_images(); 
+
+        // copy the original image if the global reference it set, because in this case we
+        // want the original sized data as result
+        
+        C2DImageSeries original_images; 
+        if (global_reference >= 0) 
+                original_images = input_set.get_images(); 
+
+        
+        float rel_min_bf = get_relative_min_breathing_frequency(input_images,  skip_images, min_breathing_frequency); 
+	
+        // now start the first ICA to run the segmentation etc.  
+	cvmsg() << "skipping " << skip_images << " images\n"; 
+	vector<C2DFImage> series(input_images.size() - skip_images); 
+	transform(input_images.begin() + skip_images, input_images.end(), 
+		  series.begin(), FCopy2DImageToFloatRepn()); 
+	
+
+	// run ICA
+	unique_ptr<C2DPerfusionAnalysis> ica(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
+	if (max_ica_iterations) 
+		ica->set_max_ica_iterations(max_ica_iterations); 
+
+	if (rel_min_bf >= 0) 
+		ica->set_min_movement_frequency(rel_min_bf); 
+
+
+	ica->set_approach(FICA_APPROACH_DEFL); 
+	if (!ica->run(series)) {
+		ica.reset(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
+		ica->set_approach(FICA_APPROACH_SYMM); 
+		if (!ica->run(series)) 
+			box_scale = false; 
+	}		
+
+	if( input_set.get_RV_peak() < 0)  {
+		if (ica->get_RV_peak_time() > 0)
+			input_set.set_RV_peak(ica->get_RV_peak_time() + skip_images); 
+	}
+	if( input_set.get_LV_peak() < 0) {
+		if (ica->get_LV_peak_time() > 0) 
+			input_set.set_LV_peak(ica->get_LV_peak_time() + skip_images);
+	}
+
+	bool segentation_possible = ica->get_RV_idx() >= 0 && ica->get_LV_idx() >= 0; 
+	if (!save_crop_feature.empty() && segentation_possible)
+		ica->save_feature_images(save_crop_feature);
+	
+	
+	vector<C2DFImage> references_float = ica->get_references(); 
+	
+	C2DImageSeries references(references_float.size()); 
+	transform(references_float.begin(), references_float.end(), references.begin(), 
+		  FWrapStaticDataInSharedPointer<C2DImage>()); 
+
+	// crop if requested && possible
+        C2DBounds crop_start; 
+	if (box_scale  && segentation_possible) {
+		crop_start = segment_and_crop_input(input_set, *ica, box_scale, segmethod, references, save_crop_feature); 
+		input_images = input_set.get_images(); 
+	}else if (!save_crop_feature.empty()) {
+		stringstream cfile; 
+		cfile << save_crop_feature << ".txt"; 
+		ica->save_coefs(cfile.str()); 
+	}
+
+	// save cropped images if requested
+	if (!cropped_filename.empty()) {
+		bfs::path cf(cropped_filename);
+		cf.replace_extension(); 
+		input_set.rename_base(__bfs_get_filename(cf)); 
+		input_set.save_images(cropped_filename);
+
+		unique_ptr<xmlpp::Document> test_cropset(input_set.write());
+		ofstream outfile(cropped_filename, ios_base::out );
+		if (outfile.good())
+			outfile << test_cropset->write_to_string_formatted();
+		else 
+			throw create_exception<runtime_error>("unable to save to '", cropped_filename, "'"); 
+
+	}
+
+        if (max_linear_passes > 0) 
+
+                run_linear_registration_passes (input_set, references,  
+                                                components, normalize, no_meanstrip,  max_ica_iterations, 
+                                                skip_images,  linear_minimizer, linear_transform, 
+                                                mg_levels, max_linear_passes, imagecost, global_reference, rel_min_bf); 
+
+        if (max_nonlinear_passes > 0) {
+		// if we come from the linear registration, then the references must be re-generated
+		vector<C2DFImage> references_float; 
+		if (max_linear_passes > 0) {
+			C2DPerfusionAnalysis ica2(components, normalize, !no_meanstrip); 
+			if (max_ica_iterations) 
+				ica2.set_max_ica_iterations(max_ica_iterations); 
+			if (rel_min_bf >= 0)
+				ica2.set_min_movement_frequency(rel_min_bf); 
+			
+			vector<C2DFImage> series(input_set.get_images().size() - skip_images); 
+			transform(input_set.get_images().begin() + skip_images, 
+				  input_set.get_images().end(), series.begin(), FCopy2DImageToFloatRepn()); 
+			
+			if (!ica2.run(series)) {
+				ica2.set_approach(FICA_APPROACH_SYMM); 
+				ica2.run(series); 
+			}
+			
+			references_float = ica2.get_references(); 
+			transform(references_float.begin(), references_float.end(), 
+				  references.begin(), FWrapStaticDataInSharedPointer<C2DImage>()); 
+			
+		}
+                run_nonlinear_registration_passes (input_set, references,  
+                                                   components,  normalize, no_meanstrip, max_ica_iterations, 
+                                                   skip_images,  nonlinear_minimizer, 
+                                                   mg_levels, c_rate, c_rate_divider, 
+                                                   divcurlweight, divcurlweight_divider, 
+                                                   max_nonlinear_passes, imagecost, global_reference, rel_min_bf); 
+	}
+	cvmsg() << "Registration finished\n"; 
+
+	// copy the data back to the original images if requested 
+        	// re-insert the registered sub-images if we have a global reference
+	if (global_reference >= 0 && box_scale &&  input_set.get_images()[0]->get_size() != original_images[0]->get_size()) {
+		cvmsg() << "Put cropped and aligned data back into the original images\n"; 
+		auto registered_images = input_set.get_images(); 
+		const FInsertData id(crop_start, crop_start + registered_images[0]->get_size()); 
+		transform(original_images.begin(), original_images.end(), registered_images.begin(), 
+			  original_images.begin(), 
+			  [&id](P2DImage orig, P2DImage part) {
+				  filter_equal_inplace(id, *part, *orig); 
+				  return orig; 
+			  }); 
+		
+                auto tr_creator = C2DTransformCreatorHandler::instance().produce("translate"); 
+		P2DTransformation shift = tr_creator->create(C2DBounds(1,1)); 
+		auto p = shift->get_parameters(); 
+		p[0] = -(float)crop_start.x; 
+		p[1] = -(float)crop_start.y; 
+		shift->set_parameters(p); 
+		
+		input_set.transform(*shift);
+		input_set.set_images(original_images);  
+
+	}
+	cvmsg() << "Save registered images\n"; 
+	input_set.save_images(out_filename); 
+	
+	unique_ptr<xmlpp::Document> outset(input_set.write());
+	ofstream outfile(out_filename.c_str(), ios_base::out );
+	if (outfile.good())
+		outfile << outset->write_to_string_formatted();
+	
+	return outfile.good() ? EXIT_SUCCESS : EXIT_FAILURE;
+
+}
+
+#include <mia/internal/main.hh>
+MIA_MAIN(do_main); 
diff --git a/src/2dmyoica-nonrigid-parallel.cc b/src/2dmyoica-nonrigid-parallel.cc
index eb0a4fe..6cb539f 100644
--- a/src/2dmyoica-nonrigid-parallel.cc
+++ b/src/2dmyoica-nonrigid-parallel.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,10 +31,11 @@
 #include <mia/core/errormacro.hh>
 #include <mia/core/minimizer.hh>
 #include <mia/core/bfsv23dispatch.hh>
+#include <mia/core/attribute_names.hh>
 #include <mia/2d/nonrigidregister.hh>
 #include <mia/2d/perfusion.hh>
 #include <mia/2d/imageio.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/transformfactory.hh>
 
 #include <tbb/parallel_for.h>
@@ -188,6 +189,29 @@ void save_references(const string& save_ref, int current_pass, int skip_images,
 	}
 }
 
+float get_relative_min_breathing_frequency(const C2DImageSeries& images, int skip, float min_breathing_frequency)
+{
+	if (min_breathing_frequency <= 0) 
+		return -1; 
+	int n_heartbeats = images.size() - skip; 
+	auto image_begin =  images[skip]; 
+	auto image_end = images[images.size() - 1]; 
+
+	if (image_begin->has_attribute("AcquisitionTime") && image_end->has_attribute(IDAcquisitionTime)) {
+		double aq_time = image_end->get_attribute_as<double>(IDAcquisitionTime) - 
+			image_begin->get_attribute_as<double>(IDAcquisitionTime);
+		if (aq_time < 0) 
+			throw create_exception<runtime_error>("Got non-postive aquisition time range ", aq_time, 
+							      ", can't handle this");  
+							      
+		double heart_rate = 60 * n_heartbeats / aq_time; 
+		cvmsg() << "Read a heartbeat rate of " << heart_rate << " beats/min\n";
+		return heart_rate / min_breathing_frequency; 
+	}else 
+		return -1; 
+}
+
+
 int do_main( int argc, char *argv[] )
 {
 	// IO parameters 
@@ -225,6 +249,8 @@ int do_main( int argc, char *argv[] )
 	C2DPerfusionAnalysis::EBoxSegmentation 
 		segmethod=C2DPerfusionAnalysis::bs_features; 
 
+	float min_breathing_frequency = -1.0f; 
+
 	size_t current_pass = 0; 
 	size_t pass = 3; 
 
@@ -233,29 +259,31 @@ int do_main( int argc, char *argv[] )
 	
 	options.set_group("File-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i', 
-				    "input perfusion data set", CCmdOption::required));
+			      "input perfusion data set", CCmdOptionFlags::required_input));
 	options.add(make_opt( out_filename, "out-file", 'o', 
-				    "output perfusion data set", CCmdOption::required));
+			      "output perfusion data set", CCmdOptionFlags::required_output));
 	options.add(make_opt( registered_filebase, "registered", 'r', 
 			      "File name base for the registered images. Image type and numbering "
 			      "scheme are taken from the input images as given in the input data set.")); 
 	
 	options.add(make_opt( cropped_filename, "save-cropped", 0, 
 			      "save cropped set to this file, the image files will use the stem of the "
-			      "name as file name base")); 
+			      "name as file name base", CCmdOptionFlags::output)); 
 	options.add(make_opt( save_crop_feature, "save-feature", 0, 
-			      "save segmentation feature images and initial ICA mixing matrix")); 
+			      "save segmentation feature images and initial ICA mixing matrix", CCmdOptionFlags::output)); 
 	
 	options.add(make_opt( save_ref_filename, "save-refs", 0, 
-			      "for each registration pass save the reference images to files with the given name base")); 
+			      "for each registration pass save the reference images to files with the given name base", 
+			      CCmdOptionFlags::output
+			    )); 
 	options.add(make_opt( save_reg_filename, "save-regs", 0, 
-			      "for each registration pass save intermediate registered images")); 
+			      "for each registration pass save intermediate registered images", CCmdOptionFlags::output)); 
 
 
 	
 	options.set_group("Registration"); 
-	options.add(make_opt( minimizer, "optimizer", 'O', "Optimizer used for minimization.", CCmdOption::not_required, 
-			      &CMinimizerPluginHandler::instance()));
+	options.add(make_opt( minimizer, "optimizer", 'O', "Optimizer used for minimization.", 
+			      CCmdOptionFlags::none, &CMinimizerPluginHandler::instance()));
 	options.add(make_opt( c_rate, "start-c-rate", 'a', 
 				    "start coefficinet rate in spines,"
 				    " gets divided by --c-rate-divider with every pass."));
@@ -270,7 +298,7 @@ int do_main( int argc, char *argv[] )
 	// why do I allow to set this parameter, it should always be image:cost=ssd  
 	options.add(make_opt( imagecost, "imagecost", 'w',
 			      "image cost, do not specify the src and ref parameters, these will be set by the program.",
-			      CCmdOption::not_required, &C2DFullCostPluginHandler::instance())); 
+			      CCmdOptionFlags::none, &C2DFullCostPluginHandler::instance())); 
 	options.add(make_opt( mg_levels, "mg-levels", 'l', "multi-resolution levels"));
 	options.add(make_opt( pass, "passes", 'P', "registration passes")); 
 
@@ -286,7 +314,11 @@ int do_main( int argc, char *argv[] )
 	options.add(make_opt( max_ica_iterations, "max-ica-iter", 'm', "maximum number of iterations in ICA")); 
 
 	options.add(make_opt(segmethod , C2DPerfusionAnalysis::segmethod_dict, "segmethod", 'E', 
-				   "Segmentation method")); 
+			     "Segmentation method")); 
+	options.add(make_opt(min_breathing_frequency, "min-breathing-frequency", 'b', 
+			     "minimal mean frequency a mixing curve can have to be considered to stem from brething. "
+			     "A healthy rest breating rate is 12 per minute. A negative value disables the test.")); 
+	
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no) 
 		return EXIT_SUCCESS; 
@@ -296,6 +328,8 @@ int do_main( int argc, char *argv[] )
 	// load input data set
 	CSegSetWithImages  input_set(in_filename, override_src_imagepath);
 	C2DImageSeries input_images = input_set.get_images(); 
+
+	float rel_min_bf = get_relative_min_breathing_frequency(input_images,  skip_images, min_breathing_frequency); 
 	
 	cvmsg() << "skipping " << skip_images << " images\n"; 
 	vector<C2DFImage> series(input_images.size() - skip_images); 
@@ -308,6 +342,10 @@ int do_main( int argc, char *argv[] )
 	if (max_ica_iterations) 
 		ica->set_max_ica_iterations(max_ica_iterations); 
 
+	if (rel_min_bf > 0) 
+		ica->set_min_movement_frequency(rel_min_bf); 
+
+
 	ica->set_approach(FICA_APPROACH_DEFL); 
 	if (!ica->run(series)) {
 		ica.reset(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
@@ -326,7 +364,8 @@ int do_main( int argc, char *argv[] )
 			input_set.set_LV_peak(ica->get_LV_peak_time() + skip_images);
 	}
 
-	if (!save_crop_feature.empty())
+	bool segentation_possible = ica->get_RV_idx() >= 0 && ica->get_LV_idx() >= 0; 
+	if (!save_crop_feature.empty() && segentation_possible)
 		ica->save_feature_images(save_crop_feature);
 	
 	
@@ -336,15 +375,14 @@ int do_main( int argc, char *argv[] )
 	transform(references_float.begin(), references_float.end(), references.begin(), 
 		  FWrapStaticDataInSharedPointer<C2DImage>()); 
 
-	// crop if requested
-	if (box_scale) {
+	// crop if requested && possible
+	if (box_scale  && segentation_possible) {
 		segment_and_crop_input(input_set, *ica, box_scale, segmethod, references, save_crop_feature); 
 		input_images = input_set.get_images(); 
 	}else if (!save_crop_feature.empty()) {
 		stringstream cfile; 
-		cfile << save_crop_feature << "-coeff.txt"; 
+		cfile << save_crop_feature << ".txt"; 
 		ica->save_coefs(cfile.str()); 
-		
 	}
 
 	// save cropped images if requested
diff --git a/src/2dmyoica-nonrigid.cc b/src/2dmyoica-nonrigid.cc
index 9c11958..768e7f4 100644
--- a/src/2dmyoica-nonrigid.cc
+++ b/src/2dmyoica-nonrigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,10 +31,11 @@
 #include <mia/core/errormacro.hh>
 #include <mia/core/minimizer.hh>
 #include <mia/core/bfsv23dispatch.hh>
+#include <mia/core/attribute_names.hh>
 #include <mia/2d/nonrigidregister.hh>
 #include <mia/2d/perfusion.hh>
 #include <mia/2d/imageio.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/transformfactory.hh>
 
 
@@ -152,6 +153,28 @@ void save_references(const string& save_ref, int current_pass, int skip_images,
 	}
 }
 
+float get_relative_min_breathing_frequency(const C2DImageSeries& images, int skip, float min_breathing_frequency)
+{
+	if (min_breathing_frequency <= 0) 
+		return -1; 
+	int n_heartbeats = images.size() - skip; 
+	auto image_begin =  images[skip]; 
+	auto image_end = images[images.size() - 1]; 
+
+	if (image_begin->has_attribute("AcquisitionTime") && image_end->has_attribute(IDAcquisitionTime)) {
+		double aq_time = image_end->get_attribute_as<double>(IDAcquisitionTime) - 
+			image_begin->get_attribute_as<double>(IDAcquisitionTime);
+		if (aq_time < 0) 
+			throw create_exception<runtime_error>("Got non-postive aquisition time range ", aq_time, 
+							      ", can't handle this");  
+							      
+		double heart_rate = 60 * n_heartbeats / aq_time; 
+		cvmsg() << "Read a heartbeat rate of " << heart_rate << " beats/min\n";
+		return heart_rate / min_breathing_frequency; 
+	}else 
+		return -1; 
+}
+
 int do_main( int argc, char *argv[] )
 {
 	// IO parameters 
@@ -190,6 +213,8 @@ int do_main( int argc, char *argv[] )
 	C2DPerfusionAnalysis::EBoxSegmentation 
 		segmethod=C2DPerfusionAnalysis::bs_features; 
 
+	float min_breathing_frequency = -1.0f; 
+
 	size_t current_pass = 0; 
 	size_t pass = 5; 
 
@@ -197,63 +222,68 @@ int do_main( int argc, char *argv[] )
 	
 	options.set_group("File-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i', 
-				    "input perfusion data set", CCmdOption::required));
+				    "input perfusion data set", CCmdOptionFlags::required_input));
 	options.add(make_opt( out_filename, "out-file", 'o', 
-				    "output perfusion data set", CCmdOption::required));
+				    "output perfusion data set", CCmdOptionFlags::required_output));
 	options.add(make_opt( registered_filebase, "registered", 'r', 
 				    "file name base for registered fiels")); 
 	
 	options.add(make_opt( cropped_filename, "save-cropped", 0, 
-				    "save cropped set to this file")); 
+			      "save cropped set to this file")); 
 	options.add(make_opt( save_crop_feature, "save-feature", 0, "save the features images resulting from the ICA and "
 			      "some intermediate images used for the RV-LV segmentation with the given file name base to PNG files. "
 			      "Also save the coefficients of the initial best and the final IC mixing matrix.")); 
-
+	
 	options.add(make_opt( save_ref_filename, "save-refs", 0, 
-				    "save synthetic reference images")); 
+			      "save synthetic reference images")); 
 	options.add(make_opt( save_reg_filename, "save-regs", 0, 
-				    "save intermediate registered images")); 
-
-
+			      "save intermediate registered images")); 
+	
+	
 	
 	options.set_group("Registration"); 
 	options.add(make_opt( minimizer, "gsl:opt=gd,step=0.1", "optimizer", 'O', "Optimizer used for minimization"));
 	options.add(make_opt( refinement_minimizer, "", "refiner", 'R',
 			      "optimizer used for refinement after the main optimizer was called"));
 	options.add(make_opt( c_rate, "start-c-rate", 'a', 
-				    "start coefficinet rate in spines,"
-				    " gets divided by --c-rate-divider with every pass"));
+			      "start coefficinet rate in spines,"
+			      " gets divided by --c-rate-divider with every pass"));
 	options.add(make_opt( c_rate_divider, "c-rate-divider", 0, 
-				    "cofficient rate divider for each pass"));
+			      "cofficient rate divider for each pass"));
 	options.add(make_opt( divcurlweight, "start-divcurl", 'd',
-				    "start divcurl weight, gets divided by"
-				    " --divcurl-divider with every pass")); 
+			      "start divcurl weight, gets divided by"
+			      " --divcurl-divider with every pass")); 
 	options.add(make_opt( divcurlweight_divider, "divcurl-divider", 0,
-				    "divcurl weight scaling with each new pass")); 
+			      "divcurl weight scaling with each new pass")); 
 	options.add(make_opt( imagecost, "image:weight=1,cost=ssd", "imagecost", 'w', "image cost")); 
 	options.add(make_opt( mg_levels, "mg-levels", 'l', "multi-resolution levels"));
 	options.add(make_opt( pass, "passes", 'P', "registration passes")); 
-
+	
 	options.set_group("ICA"); 
 	options.add(make_opt( components, "components", 'C', "ICA components 0 = automatic estimation"));
 	options.add(make_opt( normalize, "normalize", 0, "normalized ICs"));
 	options.add(make_opt( no_meanstrip, "no-meanstrip", 0, 
-				    "don't strip the mean from the mixing curves"));
+			      "don't strip the mean from the mixing curves"));
 	options.add(make_opt( box_scale, "segscale", 's', 
-				    "segment and scale the crop box around the LV (0=no segmentation)"));
+			      "segment and scale the crop box around the LV (0=no segmentation)"));
 	options.add(make_opt( skip_images, "skip", 'k', "skip images at the beginning of the series "
-				    "e.g. because as they are of other modalities")); 
+			      "e.g. because as they are of other modalities")); 
 	options.add(make_opt( max_ica_iterations, "max-ica-iter", 'm', "maximum number of iterations in ICA")); 
-
+	
 	options.add(make_opt(segmethod , C2DPerfusionAnalysis::segmethod_dict, "segmethod", 'E', 
 				   "Segmentation method")); 
-
+	options.add(make_opt(min_breathing_frequency, "min-breathing-frequency", 'b', 
+			     "minimal mean frequency a mixing curve can have to be considered to stem from brething. "
+			     "A healthy rest breating rate is 12 per minute. A negative value disables the test.")); 
+ 	
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no) 
 		return EXIT_SUCCESS; 
 
 	// load input data set
 	CSegSetWithImages  input_set(in_filename, override_src_imagepath);
 	C2DImageSeries input_images = input_set.get_images(); 
+
+	float rel_min_bf = get_relative_min_breathing_frequency(input_images,  skip_images, min_breathing_frequency); 
 	
 	cvmsg() << "skipping " << skip_images << " images\n"; 
 	vector<C2DFImage> series(input_images.size() - skip_images); 
@@ -266,6 +296,9 @@ int do_main( int argc, char *argv[] )
 	if (max_ica_iterations) 
 		ica->set_max_ica_iterations(max_ica_iterations); 
 
+	if (rel_min_bf > 0) 
+		ica->set_min_movement_frequency(rel_min_bf); 
+
 	ica->set_approach(FICA_APPROACH_DEFL); 
 	if (!ica->run(series)) {
 		ica.reset(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
diff --git a/src/2dmyoica-nonrigid2.cc b/src/2dmyoica-nonrigid2.cc
index e5c637f..938a387 100644
--- a/src/2dmyoica-nonrigid2.cc
+++ b/src/2dmyoica-nonrigid2.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@
 #include <mia/core/bfsv23dispatch.hh>
 #include <mia/2d/nonrigidregister.hh>
 #include <mia/2d/perfusion.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/transformfactory.hh>
 
 using namespace std;
@@ -174,18 +174,18 @@ int do_main( int argc, char *argv[] )
 	
 	options.set_group("\nFile-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i', 
-				    "input perfusion data set", CCmdOption::required));
+			      "input perfusion data set", CCmdOptionFlags::required_input));
 	options.add(make_opt( out_filename, "out-file", 'o', 
-				    "output perfusion data set", CCmdOption::required));
+			      "output perfusion data set", CCmdOptionFlags::required_output));
 	options.add(make_opt( registered_filebase, "registered", 'r', 
-				    "file name base for registered fiels")); 
+			      "file name base for registered fiels")); 
 	
 	options.add(make_opt( cropped_filename, "save-cropped", 0, 
-				    "save cropped set to this file")); 
+			      "save cropped set to this file")); 
 	options.add(make_opt( save_crop_feature, "save-feature", 0, 
-				    "save segmentation feature images"
-				    " and initial ICA mixing matrix")); 
-
+			      "save segmentation feature images"
+			      " and initial ICA mixing matrix")); 
+	
 	
 	options.set_group("\nRegistration"); 
 	options.add(make_opt( minimizer, "gsl:opt=gd,step=0.1", "optimizer", 'O', "Optimizer used for minimization"));
diff --git a/src/2dmyoicapgt.cc b/src/2dmyoicapgt.cc
new file mode 100644
index 0000000..425a1c4
--- /dev/null
+++ b/src/2dmyoicapgt.cc
@@ -0,0 +1,629 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#define VSTREAM_DOMAIN "2dmyoica-pgt"
+
+#include <fstream>
+#include <itpp/signal/fastica.h>
+
+#include <mia/core/msgstream.hh>
+#include <mia/core/threadedmsg.hh>
+#include <mia/core/cmdlineparser.hh>
+#include <mia/core/errormacro.hh>
+#include <mia/core/minimizer.hh>
+#include <mia/core/bfsv23dispatch.hh>
+#include <mia/core/attribute_names.hh>
+#include <mia/2d/nonrigidregister.hh>
+#include <mia/2d/perfusion.hh>
+#include <mia/2d/imageio.hh>
+#include <mia/2d/segsetwithimages.hh>
+#include <mia/2d/transformfactory.hh>
+#include <mia/2d/ground_truth_evaluator.hh>
+
+#include <tbb/parallel_for.h>
+#include <tbb/parallel_reduce.h>
+#include <tbb/blocked_range.h>
+using namespace tbb;
+
+using namespace std;
+using namespace mia;
+
+namespace bfs=boost::filesystem; 
+
+const SProgramDescription g_description = {
+
+	{pdi_group, "Registration of series of 2D images"}, 
+	{pdi_short, "Run a registration of a series of 2D images."}, 
+	{pdi_description, "This program implements a two passs motion compensation algorithm. "
+	 "First a linear registration is run based on a variation of Gupta et~al. \"Fully automatic "
+	 "registration and segmentation of first-pass myocardial perfusion MR image sequences\", "
+	 "Academic Radiology 17, 1375-1385 as described in in Wollny G, Kellman P, Santos A, "
+	 "Ledesma-Carbayo M-J, \"Automatic Motion "
+	 "Compensation of Free Breathing acquired Myocardial Perfusion Data by using Independent "
+	 "Component Analysis\", Medical Image Analysis, 2012, DOI:10.1016/j.media.2012.02.004, "
+	 "followed by a non-linear registration based Chao Li and Ying Sun, 'Nonrigid Registration "
+	 "of Myocardial Perfusion MRI Using Pseudo Ground Truth' , In Proc. Medical Image Computing "
+	 "and Computer-Assisted Intervention MICCAI 2009, 165-172, 2009. Note that for this nonlinear "
+	 "motion correction a preceding linear registration step is usually required. "
+	 "This version of the program may run all registrations in parallel."}, 
+
+	{pdi_example_descr, "Register the perfusion series given in 'segment.set' by first using automatic "
+	 "ICA estimation to run the linear registration and then the PGT registration. Skip two images at "
+	 "the beginning and otherwiese use the default parameters. Store the result in 'registered.set'."}, 
+
+	{pdi_example_code, "  -i segment.set -o registered.set -k 2"}
+}; 
+
+
+C2DFullCostList create_costs(const string& imagecostbase, int idx)
+{
+	stringstream cost_descr; 
+	cost_descr << imagecostbase << ",src=src" << idx << ".@,ref=ref" << idx << ".@"; 
+	auto imagecost = C2DFullCostPluginHandler::instance().produce(cost_descr.str()); 
+
+	C2DFullCostList result; 
+	result.push(imagecost); 
+	return result; 
+}
+
+P2DTransformationFactory create_spline_transform_creator(size_t c_rate, double divcurlweight)
+{
+	stringstream transf; 
+	transf << "spline:rate=" << c_rate << ",imgboundary=mirror,imgkernel=[bspline:d=3]"
+	       << ",penalty=[divcurl:weight=" << divcurlweight << "]"; 
+	return C2DTransformCreatorHandler::instance().produce(transf.str()); 
+}
+
+C2DBounds segment_and_crop_input(CSegSetWithImages&  input_set, 
+			    const C2DPerfusionAnalysis& ica, 
+			    float box_scale, 
+			    C2DPerfusionAnalysis::EBoxSegmentation segmethod, 
+			    C2DImageSeries& references, 
+			    const string& save_crop_feature)
+{
+	C2DBounds crop_start = C2DBounds::_0; 
+	auto cropper = ica.get_crop_filter(box_scale, crop_start, 
+					   segmethod, save_crop_feature); 
+	if (!cropper) {
+		cvwarn() << "Cropping was requested, but segmentation failed - continuing at full image size\n";
+		return crop_start; 
+	}
+	
+	C2DImageSeries input_images = input_set.get_images(); 
+	for(auto i = input_images.begin(); i != input_images.end(); ++i)
+		*i = cropper->filter(**i); 
+	
+	for (auto i = references.begin(); i != references.end(); ++i) 
+		*i = cropper->filter(**i); 
+	
+	auto tr_creator = C2DTransformCreatorHandler::instance().produce("translate");
+	P2DTransformation shift = tr_creator->create(C2DBounds(1,1)); 
+	auto p = shift->get_parameters(); 
+	p[0] = crop_start.x; 
+	p[1] = crop_start.y; 
+	shift->set_parameters(p); 
+	
+	input_set.transform(*shift);
+	input_set.set_images(input_images);  
+        return crop_start; 
+}
+
+
+struct SeriesRegistration {
+	C2DImageSeries& input_images; 
+	CSegSetWithImages::Frames& frames;
+	const C2DImageSeries& references; 
+	string minimizer; 
+	size_t mg_levels; 
+	P2DTransformationFactory transform_creator; 
+	string imagecostbase; 
+	int skip_images; 
+        int global_reference; 
+	
+	SeriesRegistration(C2DImageSeries& _input_images, 
+			   CSegSetWithImages::Frames& _frames,
+			   const C2DImageSeries& _references, 
+			   const string& _minimizer, 
+			   size_t _mg_levels, 
+			   P2DTransformationFactory _transform_creator, 
+			   string _imagecostbase, 
+			   int _skip_images, 
+                           int _global_reference):
+		input_images(_input_images), 
+		frames(_frames), 
+		references(_references), 
+		minimizer(_minimizer), 
+		mg_levels(_mg_levels), 
+                transform_creator(_transform_creator), 
+		imagecostbase(_imagecostbase), 
+		skip_images(_skip_images), 
+                global_reference(_global_reference)
+		{
+		}
+	P2DTransformation operator()( const blocked_range<int>& range, P2DTransformation init) const {
+		CThreadMsgStream thread_stream;
+		TRACE_FUNCTION; 
+                P2DTransformation result = init; 
+                
+		auto m =  CMinimizerPluginHandler::instance().produce(minimizer);
+		for( int i=range.begin(); i!=range.end(); ++i ) {
+			auto costs  = create_costs(imagecostbase, i); 
+			C2DNonrigidRegister nrr(costs, m,  transform_creator, mg_levels, i);
+                        if (i + skip_images != global_reference) {
+                                P2DTransformation transform = nrr.run(input_images[i + skip_images], references[i]);
+                                input_images[i + skip_images] = (*transform)(*input_images[i + skip_images]);
+                                frames[i + skip_images].inv_transform(*transform);
+                        }else {
+                                result = nrr.run(references[i], input_images[i + skip_images]);
+                        }
+		}
+                return result; 
+	}
+};  
+
+
+void run_registration_pass(CSegSetWithImages& input_set, 
+			   const C2DImageSeries& references,  
+			   int skip_images,  const string& minimizer, 
+			   size_t mg_levels, P2DTransformationFactory transform_creator, 
+			   const string&   imagecost, int global_reference) 
+{
+	C2DImageSeries input_images = input_set.get_images(); 
+	CSegSetWithImages::Frames& frames = input_set.get_frames();
+	
+	
+	SeriesRegistration sreg(input_images, frames, references, minimizer, 
+				mg_levels, transform_creator, 
+				imagecost, skip_images, global_reference); 
+        
+        P2DTransformation init; 
+	P2DTransformation inv_transf = parallel_reduce(blocked_range<int>( 0, references.size()), init, sreg, 
+                                                       [](P2DTransformation a, P2DTransformation b) {
+                                                               if (a) 
+                                                                       return a; 
+                                                               return b; 
+                                                       });
+
+        // apply inverse to all images 
+        if (inv_transf) {
+		cvmsg() << "Apply inverse for reference correction\n"; 
+                const C2DTransformation& inv_transf_ref = * inv_transf; 
+                parallel_for(blocked_range<int>( 0, references.size()), 
+                             [&inv_transf_ref, &frames, skip_images, global_reference, &input_images](const blocked_range<int>& range){
+                                     for( int i=range.begin(); i!=range.end(); ++i ) {
+                                             if (i != global_reference - skip_images) {
+                                                     input_images[i + skip_images] = inv_transf_ref(*input_images[i + skip_images]);
+                                                     frames[i + skip_images].inv_transform(inv_transf_ref);
+                                             }
+                                     }
+                             });
+        }
+        input_set.set_images(input_images);
+}
+
+void run_nonlinear_registration_passes (CSegSetWithImages& input_set, 
+                                        double pgt_alpha, double pgt_beta, double pgt_rho_thresh, 
+                                        int skip_images,  const string& minimizer, 
+                                        size_t mg_levels, double c_rate, double c_rate_divider, 
+                                        double divcurlweight, double divcurlweight_divider, 
+                                        int max_pass, const string& imagecost, int global_reference)
+{
+        int current_pass = 0; 
+
+	C2DGroundTruthEvaluator gte(pgt_alpha, pgt_beta, pgt_rho_thresh);
+	C2DImageSeries pgt;
+	
+	vector<P2DImage> series(input_set.get_images().size() - skip_images);
+
+	do {
+		++current_pass; 
+		copy(input_set.get_images().begin() + skip_images, input_set.get_images().end(), series.begin()); 
+		gte(series, pgt);
+                auto transform_creator = create_spline_transform_creator(c_rate, divcurlweight); 
+
+		run_registration_pass(input_set, pgt,  skip_images,  minimizer, 
+				      mg_levels, transform_creator, 
+				      imagecost, global_reference);  
+		
+		divcurlweight /= divcurlweight_divider; 
+		if (c_rate > 1) 
+			c_rate /= c_rate_divider; 
+	} while (current_pass < max_pass); 
+        
+}
+
+void run_linear_registration_passes (CSegSetWithImages& input_set, 
+                                     C2DImageSeries& references,  
+                                     int components, bool normalize, bool no_meanstrip, int max_ica_iterations, 
+                                     int skip_images,  const string& minimizer, const string& linear_transform, 
+                                     size_t mg_levels, int max_pass, const string& imagecost, int global_reference, 
+				     float min_rel_frequency)
+{
+        int current_pass = 0; 
+	bool do_continue=true; 
+	bool lastpass = false; 
+	vector<C2DFImage> references_float; 
+	do {
+		++current_pass; 
+		cvmsg() << "Registration pass " << current_pass << "\n"; 
+                
+                auto transform_creator = C2DTransformCreatorHandler::instance().produce(linear_transform); 
+
+		cvmsg() << "references_float size:" << references[0]->get_size() << "\n"; 
+                run_registration_pass(input_set, references,  
+                                      skip_images,  minimizer, mg_levels, transform_creator, 
+                                      imagecost, global_reference); 
+                
+		C2DPerfusionAnalysis ica2(components, normalize, !no_meanstrip); 
+		if (max_ica_iterations) 
+			ica2.set_max_ica_iterations(max_ica_iterations); 
+		if (min_rel_frequency >= 0)
+			ica2.set_min_movement_frequency(min_rel_frequency); 
+	
+                vector<C2DFImage> series(input_set.get_images().size() - skip_images); 
+		transform(input_set.get_images().begin() + skip_images, 
+			  input_set.get_images().end(), series.begin(), FCopy2DImageToFloatRepn()); 
+
+		if (!ica2.run(series)) {
+			ica2.set_approach(FICA_APPROACH_SYMM); 
+			ica2.run(series); 
+		}
+		if (lastpass) 
+			break; 
+		
+		references_float = ica2.get_references(); 
+		transform(references_float.begin(), references_float.end(), 
+			  references.begin(), FWrapStaticDataInSharedPointer<C2DImage>()); 
+		
+		cvmsg() << "references_float size:" << references[0]->get_size() << "\n"; 
+		do_continue =  (!max_pass || current_pass < max_pass) && ica2.has_movement(); 
+		
+		// run one more pass if the limit is not reached and no movement identified
+		lastpass = (!do_continue && (!max_pass || current_pass < max_pass)); 
+		
+	} while (do_continue || lastpass); 
+        
+}
+
+class FInsertData : public TFilter< P2DImage >  {
+public: 
+	FInsertData(const C2DBounds& start, const C2DBounds& end): 
+		m_start(start), m_end(end){}
+	
+	template <typename T>
+	void operator () ( const T2DImage<T>& a, T2DImage<T>& b) const {
+		auto ia = a.begin(); 
+		auto ea = a.end(); 
+		auto ib = b.begin_range(m_start,m_end); 
+		while (ia != ea) {
+			*ib = *ia; 
+			++ia; 
+			++ib; 
+		}
+
+	}
+private: 
+		
+	C2DBounds m_start; 
+	C2DBounds m_end; 
+}; 
+
+float get_relative_min_breathing_frequency(const C2DImageSeries& images, int skip, float min_breathing_frequency)
+{
+	if (min_breathing_frequency < 0) 
+		return -1; 
+	if (min_breathing_frequency == 0) 
+		return 0; 
+	int n_heartbeats = images.size() - skip; 
+	auto image_begin =  images[skip]; 
+	auto image_end = images[images.size() - 1]; 
+
+	if (image_begin->has_attribute("AcquisitionTime") && image_end->has_attribute(IDAcquisitionTime)) {
+		double aq_time = image_end->get_attribute_as<double>(IDAcquisitionTime) - 
+			image_begin->get_attribute_as<double>(IDAcquisitionTime);
+		if (aq_time < 0) 
+			throw create_exception<runtime_error>("Got non-postive aquisition time range ", aq_time, 
+							      ", can't handle this");  
+							      
+		double heart_rate = 60 * n_heartbeats / aq_time; 
+		cvmsg() << "Read a heartbeat rate of " << heart_rate << " beats/min\n";
+		return heart_rate / min_breathing_frequency; 
+	}else 
+		return -1; 
+}
+
+int do_main( int argc, char *argv[] )
+{
+	// IO parameters 
+	string in_filename;
+	string out_filename;
+	string registered_filebase;
+
+	// debug options: save some intermediate steps 
+	string cropped_filename;
+	string save_crop_feature; 
+	string save_ref_filename;
+	string save_reg_filename;
+
+	// non-linear registration parameters
+	string linear_minimizer("gsl:opt=simplex,step=1.0");
+	string nonlinear_minimizer("gsl:opt=gd,step=0.1");
+	string imagecost("image:weight=1,cost=ssd");
+	double c_rate = 16; 
+	double c_rate_divider = 2; 
+	double divcurlweight = 10000.0; 
+	double divcurlweight_divider = 2.0;
+
+        string linear_transform("affine");
+
+	size_t mg_levels = 3; 
+
+	// ICA parameters 
+	size_t components = 0;
+	bool normalize = false; 
+	bool no_meanstrip = false; 
+	float box_scale = 0.0;
+	size_t skip_images = 0; 
+	size_t max_ica_iterations = 400; 
+	C2DPerfusionAnalysis::EBoxSegmentation 
+		segmethod=C2DPerfusionAnalysis::bs_features; 
+
+	float min_breathing_frequency = -1.0f; 
+
+	size_t max_linear_passes = 3; 
+	size_t max_nonlinear_passes = 3; 
+        int global_reference = -1; 
+
+	// Pseudo Ground Thruth estimation parameters 
+	double pgt_alpha = 0.1;
+	double pgt_beta = 4.0;
+	double pgt_rho_thresh = 0.85;
+
+	CCmdOptionList options(g_description);
+	
+	options.set_group("File-IO"); 
+	options.add(make_opt( in_filename, "in-file", 'i', 
+			      "input perfusion data set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', 
+			      "output perfusion data set", CCmdOptionFlags::required_output));
+	options.add(make_opt( registered_filebase, "registered", 'r', 
+			      "File name base for the registered images. Image type and numbering "
+			      "scheme are taken from the input images as given in the input data set.")); 
+	
+	options.add(make_opt( cropped_filename, "save-cropped", 0, 
+			      "save cropped set to this file, the image files will use the stem of the "
+			      "name as file name base", CCmdOptionFlags::output)); 
+	options.add(make_opt( save_crop_feature, "save-feature", 0, 
+			      "save segmentation feature images and initial ICA mixing matrix", CCmdOptionFlags::output)); 
+	
+	options.add(make_opt( save_ref_filename, "save-refs", 0, 
+			      "for each registration pass save the reference images to files with the given name base", 
+			      CCmdOptionFlags::output
+			    )); 
+	options.add(make_opt( save_reg_filename, "save-regs", 0, 
+			      "for each registration pass save intermediate registered images", CCmdOptionFlags::output)); 
+
+
+	
+	options.set_group("Registration"); 
+	options.add(make_opt(linear_minimizer, "linear-optimizer", 'L', 
+                             "Optimizer used for minimization of the linear registration", 
+                             CCmdOptionFlags::none, &CMinimizerPluginHandler::instance()));
+	options.add(make_opt(linear_transform, "linear-transform", 0, 
+                             "linear transform to be used", 
+                             CCmdOptionFlags::none, &C2DTransformCreatorHandler::instance()));
+        
+        options.add(make_opt(nonlinear_minimizer, "non-linear-optimizer", 'O', 
+                             "Optimizer used for minimization in the non-linear registration.", 
+                             CCmdOptionFlags::none, &CMinimizerPluginHandler::instance()));
+	options.add(make_opt( c_rate, "start-c-rate", 'a', 
+                              "start coefficinet rate in spines,"
+                              " gets divided by --c-rate-divider with every pass."));
+	options.add(make_opt( c_rate_divider, "c-rate-divider", 0, 
+                              "Cofficient rate divider for each pass."));
+	options.add(make_opt( divcurlweight, "start-divcurl", 'd',
+                              "Start divcurl weight, gets divided by"
+                              " --divcurl-divider with every pass.")); 
+	options.add(make_opt( divcurlweight_divider, "divcurl-divider", 0,
+                              "Divcurl weight scaling with each new pass.")); 
+	options.add(make_opt( global_reference, "reference", 'R', "Global reference all image should be aligned to. If set "
+			      "to a non-negative value, the images will be aligned to this references, and the cropped "
+                              "output image date will be injected into the original images. Leave at -1 if "
+			      "you don't care. In this case all images with be registered to a mean position of the movement")); 
+        
+	// why do I allow to set this parameter, it should always be image:cost=ssd  
+	options.add(make_opt( imagecost, "imagecost", 'w',
+			      "image cost, do not specify the src and ref parameters, these will be set by the program.",
+			      CCmdOptionFlags::none, &C2DFullCostPluginHandler::instance())); 
+	options.add(make_opt( mg_levels, "mg-levels", 'l', "multi-resolution levels"));
+	options.add(make_opt( max_linear_passes, "linear-passes", 'p', "linear registration passes (0 to disable)")); 
+	options.add(make_opt( max_nonlinear_passes, "nonlinear-passes", 'P', "non-linear registration passes (0 to disable)")); 
+
+	options.set_group("ICA"); 
+	options.add(make_opt( components, "components", 'C', "ICA components 0 = automatic estimation"));
+	options.add(make_opt( normalize, "normalize", 0, "normalized ICs"));
+	options.add(make_opt( no_meanstrip, "no-meanstrip", 0, 
+				    "don't strip the mean from the mixing curves"));
+	options.add(make_opt( box_scale, "segscale", 's', 
+				    "segment and scale the crop box around the LV (0=no segmentation)"));
+	options.add(make_opt( skip_images, "skip", 'k', "skip images at the beginning of the series "
+				    "e.g. because as they are of other modalities")); 
+	options.add(make_opt( max_ica_iterations, "max-ica-iter", 'm', "maximum number of iterations in ICA")); 
+
+	options.add(make_opt(segmethod , C2DPerfusionAnalysis::segmethod_dict, "segmethod", 'E', 
+			     "Segmentation method")); 
+	options.add(make_opt(min_breathing_frequency, "min-breathing-frequency", 'b', 
+			     "minimal mean frequency a mixing curve can have to be considered to stem from brething. "
+			     "A healthy rest breating rate is 12 per minute. A negative value disables the test. "
+			     "A value 0.0 forces the series to be indentified as acquired with initial breath hold.")); 
+	
+	
+	options.set_group("\nPseudo Ground Thruth estimation"); 
+	options.add(make_opt( pgt_alpha, "alpha", 'A', "spacial neighborhood penalty weight"));
+	options.add(make_opt( pgt_beta, "beta", 'B', "temporal second derivative penalty weight"));
+	options.add(make_opt( pgt_rho_thresh, "rho-thresh", 'T', 
+				    "crorrelation threshhold for neighborhood analysis"));
+
+	
+		
+	if (options.parse(argc, argv) != CCmdOptionList::hr_no) 
+		return EXIT_SUCCESS; 
+
+        
+	// load input data set
+	CSegSetWithImages  input_set(in_filename, true);
+	C2DImageSeries input_images = input_set.get_images(); 
+
+        // copy the original image if the global reference it set, because in this case we
+        // want the original sized data as result
+        
+        C2DImageSeries original_images; 
+        if (global_reference >= 0) 
+                original_images = input_set.get_images(); 
+
+        
+        float rel_min_bf = get_relative_min_breathing_frequency(input_images,  skip_images, min_breathing_frequency); 
+	
+        // now start the first ICA to run the segmentation etc.  
+	cvmsg() << "skipping " << skip_images << " images\n"; 
+	vector<C2DFImage> series(input_images.size() - skip_images); 
+	transform(input_images.begin() + skip_images, input_images.end(), 
+		  series.begin(), FCopy2DImageToFloatRepn()); 
+	
+
+	// run ICA
+	unique_ptr<C2DPerfusionAnalysis> ica(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
+	if (max_ica_iterations) 
+		ica->set_max_ica_iterations(max_ica_iterations); 
+
+	if (rel_min_bf >= 0) 
+		ica->set_min_movement_frequency(rel_min_bf); 
+
+
+	ica->set_approach(FICA_APPROACH_DEFL); 
+	if (!ica->run(series)) {
+		ica.reset(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
+		ica->set_approach(FICA_APPROACH_SYMM); 
+		if (!ica->run(series)) 
+			box_scale = false; 
+	}		
+
+	if( input_set.get_RV_peak() < 0)  {
+		if (ica->get_RV_peak_time() > 0)
+			input_set.set_RV_peak(ica->get_RV_peak_time() + skip_images); 
+	}
+	if( input_set.get_LV_peak() < 0) {
+		if (ica->get_LV_peak_time() > 0) 
+			input_set.set_LV_peak(ica->get_LV_peak_time() + skip_images);
+	}
+
+	bool segentation_possible = ica->get_RV_idx() >= 0 && ica->get_LV_idx() >= 0; 
+	if (!save_crop_feature.empty() && segentation_possible)
+		ica->save_feature_images(save_crop_feature);
+	
+	
+	vector<C2DFImage> references_float = ica->get_references(); 
+	
+	C2DImageSeries references(references_float.size()); 
+	transform(references_float.begin(), references_float.end(), references.begin(), 
+		  FWrapStaticDataInSharedPointer<C2DImage>()); 
+
+	// crop if requested && possible
+        C2DBounds crop_start; 
+	if (box_scale  && segentation_possible) {
+		crop_start = segment_and_crop_input(input_set, *ica, box_scale, segmethod, references, save_crop_feature); 
+		input_images = input_set.get_images(); 
+	}else if (!save_crop_feature.empty()) {
+		stringstream cfile; 
+		cfile << save_crop_feature << ".txt"; 
+		ica->save_coefs(cfile.str()); 
+	}
+
+	// save cropped images if requested
+	if (!cropped_filename.empty()) {
+		bfs::path cf(cropped_filename);
+		cf.replace_extension(); 
+		input_set.rename_base(__bfs_get_filename(cf)); 
+		input_set.save_images(cropped_filename);
+
+		unique_ptr<xmlpp::Document> test_cropset(input_set.write());
+		ofstream outfile(cropped_filename, ios_base::out );
+		if (outfile.good())
+			outfile << test_cropset->write_to_string_formatted();
+		else 
+			throw create_exception<runtime_error>("unable to save to '", cropped_filename, "'"); 
+
+	}
+
+        if (max_linear_passes > 0) 
+
+                run_linear_registration_passes (input_set, references,  
+                                                components, normalize, no_meanstrip,  max_ica_iterations, 
+                                                skip_images,  linear_minimizer, linear_transform, 
+                                                mg_levels, max_linear_passes, imagecost, global_reference, rel_min_bf); 
+
+        if (max_nonlinear_passes > 0) 
+                run_nonlinear_registration_passes (input_set,  pgt_alpha, pgt_beta, pgt_rho_thresh,
+                                                   skip_images,  nonlinear_minimizer, 
+                                                   mg_levels, c_rate, c_rate_divider, 
+                                                   divcurlweight, divcurlweight_divider, 
+                                                   max_nonlinear_passes, imagecost, global_reference); 
+        
+	cvmsg() << "Registration finished\n"; 
+        // copy the data back to the original images if requested 
+        	// re-insert the registered sub-images if we have a global reference
+	if (global_reference >= 0 && box_scale && input_set.get_images()[0]->get_size() != original_images[0]->get_size()) {
+		cvmsg() << "Reinsert registered cropped data into original images\n"; 
+		auto registered_images = input_set.get_images(); 
+		const FInsertData id(crop_start, crop_start + registered_images[0]->get_size()); 
+		transform(original_images.begin(), original_images.end(), registered_images.begin(), 
+			  original_images.begin(), 
+			  [&id](P2DImage orig, P2DImage part) {
+				  filter_equal_inplace(id, *part, *orig); 
+				  return orig; 
+			  }); 
+		
+                auto tr_creator = C2DTransformCreatorHandler::instance().produce("translate"); 
+		P2DTransformation shift = tr_creator->create(C2DBounds(1,1)); 
+		auto p = shift->get_parameters(); 
+		p[0] = -(float)crop_start.x; 
+		p[1] = -(float)crop_start.y; 
+		shift->set_parameters(p); 
+		
+		input_set.transform(*shift);
+		input_set.set_images(original_images);  
+
+	}
+	cvmsg() << "Save registered images\n"; 
+	input_set.save_images(out_filename); 
+	
+	unique_ptr<xmlpp::Document> outset(input_set.write());
+	ofstream outfile(out_filename.c_str(), ios_base::out );
+	if (outfile.good())
+		outfile << outset->write_to_string_formatted();
+	if (!outfile.good()) 
+		cverr() << "Unable to saving output to '" << out_filename << "'\n"; 
+
+	return outfile.good() ? EXIT_SUCCESS : EXIT_FAILURE;
+
+}
+
+#include <mia/internal/main.hh>
+MIA_MAIN(do_main); 
diff --git a/src/2dmyomilles.cc b/src/2dmyomilles.cc
index 4dfd21a..732400d 100644
--- a/src/2dmyomilles.cc
+++ b/src/2dmyomilles.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@
 #include <mia/2d/rigidregister.hh>
 #include <mia/2d/perfusion.hh>
 #include <mia/2d/imageio.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/transformfactory.hh>
 
 using namespace std;
@@ -67,18 +67,60 @@ void save_references(const string& save_ref, int current_pass, int skip_images,
 }
 
 
+void run_registration_pass(const C2DRigidRegister& rigid_register, C2DImageSeries& input_images, const C2DImageSeries& references, 
+			   CSegSetWithImages::Frames& frames, 
+			   int skip_images, int global_reference) 
+{
+	P2DTransformation align_to_global; 
+	for (size_t i = 0; i < input_images.size() - skip_images; ++i) {
+		cvmsg() << "Register 1st pass, frame " << i << "\n"; 
+		
+		if ((int) i == global_reference - skip_images) {
+			align_to_global = rigid_register.run(references[i], input_images[i + skip_images]);
+		}else {
+			P2DTransformation transform = rigid_register.run(input_images[i + skip_images], references[i]);
+			input_images[i + skip_images] = (*transform)(*input_images[i + skip_images]);
+			P2DTransformation inverse(transform->invert()); 
+			frames[i + skip_images].transform(*inverse);
+		}
+	}
+	if (align_to_global) {
+		P2DTransformation inverse(align_to_global->invert()); 
+		for (size_t i = 0; i < input_images.size(); ++i) {
+			input_images[i] = (*inverse)(*input_images[i]);
+			frames[i].transform(*inverse);
+		}
+	}
+}
+
+class FInsertData : public TFilter< P2DImage >  {
+public: 
+	FInsertData(const C2DBounds& start, const C2DBounds& end): 
+		m_start(start), m_end(end){}
+	
+	template <typename T>
+	void operator () ( const T2DImage<T>& a, T2DImage<T>& b) const {
+		copy(a.begin(), a.end(), b.begin_range(m_start,m_end));
+	}
+private: 
+		
+	C2DBounds m_start; 
+	C2DBounds m_end; 
+}; 
+
 int do_main( int argc, char *argv[] )
 {
 	// IO parameters 
 	string in_filename;
 	string out_filename;
-	string registered_filebase("reg");
+	string registered_filebase;
 	string ref_filebase;
 
 	// debug options: save some intermediate steps 
 	string cropped_filename;
 	string save_crop_feature; 
 
+	int global_reference = -1; 
 	// this parameter is currently not exported - reading the image data is 
 	// therefore done from the path given in the segmentation set 
 	bool override_src_imagepath = true;
@@ -105,8 +147,8 @@ int do_main( int argc, char *argv[] )
 	CCmdOptionList options(g_description);
 
 	options.set_group("File-IO"); 
-	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output perfusion data set", CCmdOption::required));
+	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output perfusion data set", CCmdOptionFlags::required_output));
 	options.add(make_opt( registered_filebase, "registered", 'r', "file name base for registered files")); 
 	options.add(make_opt( ref_filebase, "save-references", 0, "save synthetic reference images to this file base")); 
 	
@@ -121,7 +163,10 @@ int do_main( int argc, char *argv[] )
 	options.add(make_opt( minimizer, "gsl:opt=simplex,step=1.0", "optimizer", 'O', "Optimizer used for minimization"));
 	options.add(make_opt( transform_creator, "rigid", "transForm", 'f', "transformation type"));
 	options.add(make_opt( mg_levels, "mg-levels", 'l', "multi-resolution levels"));
-
+	options.add(make_opt( global_reference, "reference", 'R', "Global reference all image should be aligned to. If set "
+			      "to a non-negative value, the images will be aligned to this references, and the cropped output image date "
+			      "will be injected into the original images. Leave at -1 if "
+			      "you don't care. In this case all images with be registered to a mean position of the movement")); 
 	options.add(make_opt( pass, "passes", 'P', "registration passes")); 
 
 
@@ -154,11 +199,15 @@ int do_main( int argc, char *argv[] )
 	CSegSetWithImages  input_set(in_filename, override_src_imagepath);
 	C2DImageSeries input_images = input_set.get_images(); 
 	
+	C2DImageSeries original_images; 
+	if (global_reference >= 0) 
+		original_images = input_set.get_images(); 
+
 	cvmsg() << "skipping " << skip_images << " images\n"; 
 	vector<C2DFImage> series(input_images.size() - skip_images); 
 	transform(input_images.begin() + skip_images, input_images.end(), 
 		  series.begin(), FCopy2DImageToFloatRepn()); 
-	
+
 	
 	// run ICA
 	C2DPerfusionAnalysis ica(components, normalize, !no_meanstrip); 
@@ -190,10 +239,11 @@ int do_main( int argc, char *argv[] )
 	C2DImageSeries references(references_float.size()); 
 	transform(references_float.begin(), references_float.end(), references.begin(), 
 		  FWrapStaticDataInSharedPointer<C2DImage>() );
-	
+
+	C2DBounds crop_start; 	
+	auto tr_creator = C2DTransformCreatorHandler::instance().produce("translate");
 	// crop if requested
 	if (box_scale) {
-		C2DBounds crop_start; 
 		auto cropper = ica.get_crop_filter(box_scale, crop_start, segmethod, save_crop_feature); 
 		if (!cropper) {
 			throw create_exception<runtime_error>( "Cropping was requested, but segmentation failed"); 
@@ -205,12 +255,12 @@ int do_main( int argc, char *argv[] )
 		for (auto i = references.begin(); i != references.end(); ++i) 
 			*i = cropper->filter(**i); 
 
-		auto tr_creator = C2DTransformCreatorHandler::instance().produce("translate");
 		P2DTransformation shift = tr_creator->create(C2DBounds(1,1)); 
 		auto p = shift->get_parameters(); 
 		p[0] = (float)crop_start.x; 
 		p[1] = (float)crop_start.y; 
 		shift->set_parameters(p); 
+
 		
 		input_set.transform(*shift);
 		input_set.set_images(input_images);  
@@ -239,13 +289,8 @@ int do_main( int argc, char *argv[] )
 
 	CSegSetWithImages::Frames& frames = input_set.get_frames();
 
-	for (size_t i = 0; i < input_images.size() - skip_images; ++i) {
-		cvmsg() << "Register 1st pass, frame " << i << "\n"; 
-		P2DTransformation transform = rigid_register.run(input_images[i + skip_images], references[i]);
-		input_images[i + skip_images] = (*transform)(*input_images[i + skip_images]);
-		P2DTransformation inverse(transform->invert()); 
-		frames[i + skip_images].transform(*inverse);
-	}
+
+	run_registration_pass(rigid_register, input_images, references, frames, skip_images, global_reference); 
 
 	// run the specified number of passes 
 	// break early if ICA fails
@@ -267,15 +312,8 @@ int do_main( int argc, char *argv[] )
 			if (!ref_filebase.empty())
 				save_references(ref_filebase, current_pass, skip_images, references); 
 
+			run_registration_pass(rigid_register, input_images, references, frames, skip_images, global_reference); 
 			
-			for (size_t i = 0; i < input_images.size() - skip_images; ++i) {
-				cvmsg() << "Register " << current_pass + 1 <<  " pass, frame " << i << "\n"; 
-				P2DTransformation transform = rigid_register.run(input_images[i + skip_images] , 
-										 references[i]); 
-				input_images[i + skip_images] = (*transform)(*input_images[i + skip_images]);
-				P2DTransformation inverse(transform->invert()); 
-				frames[i + skip_images].transform(*inverse);
-			}
 		} else {
 			cvmsg() << "Stopping registration in pass " << current_pass 
 				<< " because ICA didn't return useful results\n"; 
@@ -283,10 +321,32 @@ int do_main( int argc, char *argv[] )
 		}
 	}
 
+	// re-insert the registered sub-images if we have a global reference
+	if (global_reference >= 0 && box_scale) {
+		const FInsertData id(crop_start, crop_start + input_images[0]->get_size()); 
+		transform(original_images.begin(), original_images.end(), input_images.begin(), 
+			  original_images.begin(), 
+			  [&id](P2DImage orig, P2DImage part) {
+				  filter_equal_inplace(id, *part, *orig); 
+				  return orig; 
+			  }); 
+		
+		P2DTransformation shift = tr_creator->create(C2DBounds(1,1)); 
+		auto p = shift->get_parameters(); 
+		p[0] = -(float)crop_start.x; 
+		p[1] = -(float)crop_start.y; 
+		shift->set_parameters(p); 
+		
+		input_set.transform(*shift);
+		input_set.set_images(original_images);  
 
-	input_set.set_images(input_images); 
-	input_set.rename_base(registered_filebase); 
-
+	}else {
+		input_set.set_images(input_images); 
+	}
+	
+	if (!registered_filebase.empty()) 
+		input_set.rename_base(registered_filebase); 
+	
 	input_set.save_images(out_filename); 
 	
 	unique_ptr<xmlpp::Document> outset(input_set.write());
diff --git a/src/2dmyoperiodic-nonrigid.cc b/src/2dmyoperiodic-nonrigid.cc
index 17c5757..f2bdb51 100644
--- a/src/2dmyoperiodic-nonrigid.cc
+++ b/src/2dmyoperiodic-nonrigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@
 #include <mia/core/errormacro.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/nonrigidregister.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/transformfactory.hh>
 #include <mia/2d/fullcost.hh>
 #include <mia/2d/similarity_profile.hh>
@@ -123,6 +123,8 @@ public:
 		size_t mg_levels; 
 		size_t max_candidates; 
 		bool save_ref; 
+		int global_reference; 
+		size_t max_delta; 
 	};
 
 	C2DMyocardPeriodicRegistration(const RegistrationParams& params); 
@@ -186,16 +188,20 @@ vector<size_t>  C2DMyocardPeriodicRegistration::get_high_contrast_candidates(con
 
 vector<size_t> C2DMyocardPeriodicRegistration::get_prealigned_subset(const C2DImageSeries& images) 
 {
-	cvmsg() << "estimate prealigned subset ...\n"; 
-	vector<size_t> candidates = get_high_contrast_candidates(images, 20, images.size()-2); 
-	assert(!candidates.empty()); 
-
-	C2DSimilarityProfile best_series(m_params.series_select_cost, images, candidates[0]); 
+	vector<size_t> candidates; 
+	if (m_params.global_reference < 0) {
+		cvmsg() << "estimate prealigned subset ...\n"; 
+		candidates = get_high_contrast_candidates(images, 20, images.size()-2); 
+		assert(!candidates.empty()); 
+	}else
+		candidates.push_back(m_params.global_reference); 
+
+	C2DSimilarityProfile best_series(m_params.series_select_cost, images, candidates[0], m_params.max_delta); 
 	m_ref = candidates[0]; 	
 
 	// the skip values should be parameters 
 	for (size_t i = 1; i < candidates.size(); ++i) {
-		C2DSimilarityProfile sp(m_params.series_select_cost, images, candidates[i]); 
+		C2DSimilarityProfile sp(m_params.series_select_cost, images, candidates[i], m_params.max_delta); 
 		if (sp.get_peak_frequency() > best_series.get_peak_frequency()) {
 			m_ref = candidates[i]; 
 			best_series = sp; 
@@ -313,7 +319,9 @@ size_t C2DMyocardPeriodicRegistration::get_ref_idx()const
 C2DMyocardPeriodicRegistration::RegistrationParams::RegistrationParams():
 	mg_levels(3),
 	max_candidates(20), 
-	save_ref(false)
+	save_ref(false), 
+	global_reference(-1), 
+	max_delta(0)
 {
 }
 
@@ -326,6 +334,7 @@ int do_main( int argc, char *argv[] )
 	string reference_index_file; 
 
 	size_t skip = 0; 
+
 	
 	// this parameter is currently not exported - reading the image data is 
 	// therefore done from the path given in the segmentation set 
@@ -335,8 +344,8 @@ int do_main( int argc, char *argv[] )
 	CCmdOptionList options(g_general_help);
 	
 	options.set_group("\nFile-IO");
-	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output perfusion data set", CCmdOption::required));
+	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output perfusion data set", CCmdOptionFlags::required_output));
 	options.add(make_opt( registered_filebase, "registered", 'r', 
 				    "file name base for registered fiels")); 
 	options.add(make_opt(params.save_ref,"save-references", 0, 
@@ -351,14 +360,18 @@ int do_main( int argc, char *argv[] )
 	options.add(make_opt(params.series_select_cost, "image:cost=[ngf:eval=ds]", "cost-series", 'S',
 				   "Const function to use for the analysis of the series")); 
 	options.add(make_opt(reference_index_file, "ref-idx", 0, 
-				   "save reference index number to this file"));  
+				   "save reference index number to this file")); 
 
+	options.add(make_opt(params.global_reference, "global-reference", 'R', 
+				   "save reference index number to this file")); 
+	options.add(make_opt(params.max_delta, "max-subset-delta", 'D', 
+			     "Maximum delta between two elements of the prealigned subset")); 
 
 	options.set_group("\nRegistration"); 
 
 
 	options.add(make_opt( params.minimizer, "gsl:opt=gd,step=0.01", "optimizer", 'O', "Optimizer used for minimization"));
-	options.add(make_opt( params.refinement_minimizer, "", "refiner", 'R', "optimizer used for additional minimization"));
+	options.add(make_opt( params.refinement_minimizer, "", "refiner", 0, "optimizer used for additional minimization"));
 	options.add(make_opt( params.mg_levels, "mr-levels", 'l', "multi-resolution levels"));
 
 	options.add(make_opt( params.transform_creator, "spline:rate=16,penalty=[divcurl:weight=0.01]", "transForm", 'f', 
@@ -384,6 +397,14 @@ int do_main( int argc, char *argv[] )
 
 	C2DImageSeries series(in_images.begin() + skip, in_images.end()); 
 
+	if (params.global_reference >= 0) {
+		unsigned gr = params.global_reference; 
+		if (gr <= skip || gr >= in_images.size()) 
+			throw create_exception<invalid_argument>("Invalid global reference ",  params.global_reference, 
+								 " should be in [", skip, ", ",  in_images.size(), ")"); 
+		params.global_reference -= skip; 
+	}
+
 	C2DMyocardPeriodicRegistration mpr(params); 
 	vector<P2DTransformation> transforms = mpr.run(series);
 
diff --git a/src/2dmyopgt-nonrigid.cc b/src/2dmyopgt-nonrigid.cc
index 719646e..358f29a 100644
--- a/src/2dmyopgt-nonrigid.cc
+++ b/src/2dmyopgt-nonrigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@
 #include <mia/2d/filter.hh>
 #include <mia/2d/ground_truth_evaluator.hh>
 #include <mia/2d/nonrigidregister.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/transformfactory.hh>
 
 
@@ -124,8 +124,8 @@ int do_main( int argc, char *argv[] )
 	CCmdOptionList options(g_description);
 
 	options.set_group("\nFile-IO"); 
-	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output perfusion data set", CCmdOption::required));
+	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output perfusion data set", CCmdOptionFlags::required_output));
 	options.add(make_opt( registered_filebase, "registered", 'r', "file name base for registered files, the "
 			      "image file type is the same as given in the input data set"));
 
diff --git a/src/2dmyoserial-nonrigid.cc b/src/2dmyoserial-nonrigid.cc
index 361bab2..71e0db7 100644
--- a/src/2dmyoserial-nonrigid.cc
+++ b/src/2dmyoserial-nonrigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
 #include <mia/core/errormacro.hh>
 #include <mia/2d/nonrigidregister.hh>
 #include <mia/2d/perfusion.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/transformfactory.hh>
 
 using namespace std;
@@ -82,9 +82,9 @@ int do_main( int argc, char *argv[] )
 	
 	options.set_group("\nFile-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i', 
-				    "input perfusion data set", CCmdOption::required));
+			      "input perfusion data set", CCmdOptionFlags::required_input));
 	options.add(make_opt( out_filename, "out-file", 'o', 
-				    "output perfusion data set", CCmdOption::required));
+			      "output perfusion data set", CCmdOptionFlags::required_output));
 	options.add(make_opt( registered_filebase, "registered", 'R', 
 				    "file name base for registered fiels")); 
 	
diff --git a/src/2dmyoseries-compdice.cc b/src/2dmyoseries-compdice.cc
index 5a2809b..056d494 100644
--- a/src/2dmyoseries-compdice.cc
+++ b/src/2dmyoseries-compdice.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@
 #include <mia/core/msgstream.hh>
 #include <mia/internal/main.hh>
 #include <mia/core/cmdlineparser.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <ostream>
 #include <fstream>
 
@@ -72,8 +72,8 @@ int do_main( int argc, char *argv[] )
 	size_t skip = 2; 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( org_filename, "first", '1', "first segmentation set", CCmdOption::required));
-	options.add(make_opt( ref_filename, "second", '2', "second segmentation set", CCmdOption::required));
+	options.add(make_opt( org_filename, "first", '1', "first segmentation set", CCmdOptionFlags::required_input));
+	options.add(make_opt( ref_filename, "second", '2', "second segmentation set", CCmdOptionFlags::required_input));
 	options.add(make_opt( skip, "skip", 'k', "images to skip atthe begin of the series")); 
 	
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/2dmyoseries-dice.cc b/src/2dmyoseries-dice.cc
index ad60bf7..1078847 100644
--- a/src/2dmyoseries-dice.cc
+++ b/src/2dmyoseries-dice.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@
 #include <mia/core/msgstream.hh>
 #include <mia/core/cmdlineparser.hh>
 #include <mia/internal/main.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <ostream>
 #include <fstream>
 
@@ -73,7 +73,7 @@ int do_main( int argc, char *argv[] )
 	size_t reference = 20; 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( org_filename, "input", 'i', "original segmentation set", CCmdOption::required));
+	options.add(make_opt( org_filename, "input", 'i', "original segmentation set", CCmdOptionFlags::required_input));
 	options.add(make_opt( skip, "skip", 'k', "images to skip atthe bgin of the series")); 
 	options.add(make_opt( reference, "reference", 'r', "reference image")); 
 	
diff --git a/src/2dmyoset-all2one-nonrigid.cc b/src/2dmyoset-all2one-nonrigid.cc
index f76fae4..aca1a02 100644
--- a/src/2dmyoset-all2one-nonrigid.cc
+++ b/src/2dmyoset-all2one-nonrigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@
 #include <mia/2d/nonrigidregister.hh>
 #include <mia/2d/transformfactory.hh>
 #include <mia/2d/imageio.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 
 
 #include <tbb/parallel_for.h>
@@ -141,9 +141,9 @@ int do_main( int argc, char *argv[] )
 	
 	options.set_group("\nFile-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i', 
-				    "input perfusion data set", CCmdOption::required));
+				    "input perfusion data set", CCmdOptionFlags::required_input));
 	options.add(make_opt( out_filename, "out-file", 'o', 
-				    "output perfusion data set", CCmdOption::required));
+				    "output perfusion data set", CCmdOptionFlags::required_output));
 	options.add(make_opt( registered_filebase, "out-filebase", 0, "file name basae for registered files, file "
 			      "type is deducted from the image file type in the input data set.")); 
 
diff --git a/src/2dnrreg.cc b/src/2dnrreg.cc
index 50f72c6..83ecd7e 100644
--- a/src/2dnrreg.cc
+++ b/src/2dnrreg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/2dsegcompare.cc b/src/2dsegcompare.cc
index 9142408..7a67f5f 100644
--- a/src/2dsegcompare.cc
+++ b/src/2dsegcompare.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
 #include <libxml++/libxml++.h>
 
 #include <mia/core.hh>
-#include <mia/2d/SegSet.hh>
+#include <mia/2d/segset.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 #include <mia/internal/main.hh>
@@ -65,8 +65,8 @@ int do_main(int argc, char *argv[])
 	string ref_filename;
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
-	options.add(make_opt( ref_filename, "ref-file", 'r', "reference  segmentation set", CCmdOption::required));
+	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOptionFlags::required_input));
+	options.add(make_opt( ref_filename, "ref-file", 'r', "reference  segmentation set", CCmdOptionFlags::required_input));
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
 
diff --git a/src/2dseghausdorff.cc b/src/2dseghausdorff.cc
index 05d70b3..bb1de98 100644
--- a/src/2dseghausdorff.cc
+++ b/src/2dseghausdorff.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
 #include <libxml++/libxml++.h>
 
 #include <mia/core.hh>
-#include <mia/2d/SegSet.hh>
+#include <mia/2d/segset.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 
@@ -59,8 +59,8 @@ int do_main(int argc, char *argv[])
 	int skip = 0; 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
-	options.add(make_opt( reference, "ref-frame", 'r', "reference frame", CCmdOption::required));
+	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOptionFlags::required_input));
+	options.add(make_opt( reference, "ref-frame", 'r', "reference frame", CCmdOptionFlags::required_input));
 	options.add(make_opt( skip, "skip", 'k', "skip frames at the beginning"));
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/2dsegment-ahmed.cc b/src/2dsegment-ahmed.cc
index 6fb5dfe..bb48b7b 100644
--- a/src/2dsegment-ahmed.cc
+++ b/src/2dsegment-ahmed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -443,9 +443,9 @@ int do_main(int argc, char *argv[])
 	const auto& image2dio = C2DImageIOPluginHandler::instance();
 
 	CCmdOptionList opts(g_description);
-	opts.add(make_opt( in_filename, "in-file", 'i', "image to be segmented", CCmdOption::required, &image2dio )); 
+	opts.add(make_opt( in_filename, "in-file", 'i', "image to be segmented", CCmdOptionFlags::required_input, &image2dio )); 
 	opts.add(make_opt( cls_filename, "out-file", 'o', "class probability images, the image type "
-			   "must support multiple images and floating point values", CCmdOption::required, &image2dio )); 
+			   "must support multiple images and floating point values", CCmdOptionFlags::required_output, &image2dio )); 
 	opts.add(make_opt( n_classes, "no-of-classes", 'a', "number of classes"));
 	opts.add(make_opt( bg_correct, "bias-correct", 'b', "apply bias field correction"));
 	opts.add(make_opt( initial_class_centres, "class-centres", 'c', "initial class centers"));
diff --git a/src/2dsegment-fuzzyw.cc b/src/2dsegment-fuzzyw.cc
index 031db25..1cdf8fa 100644
--- a/src/2dsegment-fuzzyw.cc
+++ b/src/2dsegment-fuzzyw.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -355,14 +355,14 @@ int do_main(int argc, char *argv[])
 	
 	CCmdOptionList opts(g_description);
 	opts.set_group("File I/O"); 
-	opts.add(make_opt( in_filename, "in-file", 'i', "image to be segmented", CCmdOption::required , &image2dio)); 
+	opts.add(make_opt( in_filename, "in-file", 'i', "image to be segmented", CCmdOptionFlags::required_input , &image2dio)); 
 	opts.add(make_opt( cls_filename, "cls-file", 'c', "class probability images, the image type must "
-			   "support multiple images and floating point values", CCmdOption::required, &image2dio )); 
-	opts.add(make_opt( out_filename, "out-file", 'o', "B-field corrected image", CCmdOption::not_required , &image2dio)); 
+			   "support multiple images and floating point values", CCmdOptionFlags::output, &image2dio )); 
+	opts.add(make_opt( out_filename, "out-file", 'o', "B-field corrected image", CCmdOptionFlags::output , &image2dio)); 
 	opts.add(make_opt( gain_filename, "gain-log-file", 'g', "Logarithmic gain field, the image type must "
-			   "support floating point values",CCmdOption::not_required , &image2dio)); 
+			   "support floating point values",  CCmdOptionFlags::output , &image2dio)); 
 	
-	opts.set_group("Segmentation");
+	opts.set_group("Segmentation parameters");
 	opts.add(make_opt( n_classes, "no-of-classes", 'n', "number of classes to segment"));
 	opts.add(make_opt( params.class_centres, "class-centres", 'C', "initial class centers"));
 	opts.add(make_opt( params.neighbourhood_filter, "shmean:shape=8n", "neighborhood", 'N', "neighborhood filter for B-field correction"));
@@ -375,7 +375,10 @@ int do_main(int argc, char *argv[])
 	
 	if (opts.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
-
+	
+	if (cls_filename.empty() && out_filename.empty() && gain_filename.empty()) {
+		throw invalid_argument("Not a single output given, processing makes no sense");  
+	}
 
 	auto in_image = load_image2d(in_filename);	
 	
diff --git a/src/2dsegmentcropbox.cc b/src/2dsegmentcropbox.cc
index 1e56267..692ea42 100644
--- a/src/2dsegmentcropbox.cc
+++ b/src/2dsegmentcropbox.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
 #include <libxml++/libxml++.h>
 
 #include <mia/core.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 #include <mia/internal/main.hh>
@@ -79,11 +79,11 @@ int do_main(int argc, char *argv[])
 	float  enlarge_boundary = 5;
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
+	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOptionFlags::required_input));
 	options.add(make_opt( override_src_imagepath, "override-imagepath", 'p',
 			      "Instead of using the path of the image files as given in the "
 			      "segmentation set, assume the files are located in the current directory"));
-	options.add(make_opt( out_filename, "out-file", 'o', "output segmentation set", CCmdOption::required));
+	options.add(make_opt( out_filename, "out-file", 'o', "output segmentation set", CCmdOptionFlags::required_output));
 	options.add(make_opt( image_name, "cropped-base", 'c', "Base name for the cropped image files, the file "
 			      "type and numbering will be based on the input image file type and numbering."));
 	options.add(make_opt( enlarge_boundary, "enlarge", 'e',
diff --git a/src/2dsegseriesstats.cc b/src/2dsegseriesstats.cc
index 8187cc9..9630055 100644
--- a/src/2dsegseriesstats.cc
+++ b/src/2dsegseriesstats.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,7 +23,7 @@
 #include <libxml++/libxml++.h>
 #include <mia/core/msgstream.hh>
 #include <mia/core/cmdlineparser.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/internal/main.hh>
 #include <ostream>
 #include <fstream>
@@ -107,11 +107,18 @@ int do_main( int argc, char *argv[] )
 	int reference = -1; 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( org_filename, "original", 'o', "original segmentation set", CCmdOption::required));
-	options.add(make_opt( reg_filename, "registered", 'g', "registered segmentation set", CCmdOption::required));
+	options.add(make_opt( org_filename, "original", 'o', "original segmentation set", 
+			      CCmdOptionFlags::required_input));
+	options.add(make_opt( reg_filename, "registered", 'g', "registered segmentation set", 
+			      CCmdOptionFlags::required_input));
+	
 	options.add(make_opt( skip, "skip", 'k', "images to skip at the begin of the series, if (k < 0) use RV peak of the registered set if set")); 
-	options.add(make_opt( reference, "reference", 'r', "reference frame for automatic curve extraction. If it is set to -1, the LV peak "
-			      "found in the registered set will be used. if this value is also -1 (i.e. not identified), the lastframe will be used.")); 
+	options.add(make_opt( reference, "reference", 'r', "reference frame for automatic curve extraction. "
+			      "Negative values can be used to indicate specific values (if given in the segmentation set):\n"
+			      "   -3: Middle of the series\n"
+			      "   -2: prefererred reference\n"
+			      "   -1: LV peak\n" 
+			      "if any of the above is not available or the value is < -3, use the last frame of the series.")); 
 	options.add(make_opt( curves_filename, "curves", 'c', "region average value curves, "
 			      "The output files each comprises a table in plain-text format that contains three columns "
 			      "for each section of the LV myocardium: The first column contains the values obtained by "
@@ -143,16 +150,18 @@ int do_main( int argc, char *argv[] )
 	auto original_frames = original.get_frames(); 
 	auto registered_frames = registered.get_frames(); 
 	
+	if (reference == -3)
+		reference = (registered.get_frames().size() - skip) / 2;
 
-	if (reference == -1) {
+	if (reference == -2)
 		reference = registered.get_preferred_reference(); 
-		if (reference == -1) {
-			reference = registered.get_LV_peak(); 
-			if (reference == -1)
-				reference = registered.get_frames().size() - 1;
-		}
-	}
 	
+	if (reference == -1) 
+		reference = registered.get_LV_peak(); 
+	
+	if (reference < 0)
+		reference = registered.get_frames().size() - 1;
+
 	if (original_frames.size() != registered_frames.size()) 
 		throw create_exception<invalid_argument>( "original and reference series must have same size"); 
 	if (reference < skip || reference >= static_cast<long>(original_frames.size()))
diff --git a/src/2dsegshift.cc b/src/2dsegshift.cc
index 32e0752..9b8f36c 100644
--- a/src/2dsegshift.cc
+++ b/src/2dsegshift.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
 #include <libxml++/libxml++.h>
 
 #include <mia/core.hh>
-#include <mia/2d/SegSet.hh>
+#include <mia/2d/segset.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 #include <mia/internal/main.hh>
@@ -72,10 +72,13 @@ int do_main(int argc, char *argv[])
 	size_t skip = 2;
 
 	C2DFVector shift;
+	const auto& imageio = C2DImageIOPluginHandler::instance();
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "input segmentation set", CCmdOption::required));
+	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", 
+			      CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out-file", 'o', "input segmentation set", 
+			      CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( shift_filename, "image-file", 'g', "output image filename base"));
 
 	options.add(make_opt(shift, "shift", 'S', "shift of segmentation"));
diff --git a/src/2dsegshiftperslice.cc b/src/2dsegshiftperslice.cc
index d0042cc..c27be14 100644
--- a/src/2dsegshiftperslice.cc
+++ b/src/2dsegshiftperslice.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@
 
 #include <mia/core.hh>
 #include <mia/core/bfsv23dispatch.hh>
-#include <mia/2d/SegSet.hh>
+#include <mia/2d/segset.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 #include <mia/internal/main.hh>
@@ -85,12 +85,12 @@ int do_main(int argc, char *argv[])
 	string shift_value_filebase("shift");
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output segmentation set", CCmdOption::required));
+	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output segmentation set", CCmdOptionFlags::required_output));
 	options.add(make_opt( shift_filename, "image-file", 'g', "output image filename base"));
 
 	options.add(make_opt( shift_value_filebase, "shift", 'S', "shift of segmentation - base name ", 
-				    CCmdOption::required));
+				    CCmdOptionFlags::required));
 
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/2dseries-mincorr.cc b/src/2dseries-mincorr.cc
index f5d80d0..1a42b56 100644
--- a/src/2dseries-mincorr.cc
+++ b/src/2dseries-mincorr.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@
 #include <mia/internal/main.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/correlation_weight.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 
 NS_MIA_USE;
 using namespace std;
@@ -89,9 +89,9 @@ int do_main( int argc, char *argv[] )
 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_name, "in", 'i', "input segmentation set", CCmdOption::required));
+	options.add(make_opt( src_name, "in", 'i', "input segmentation set", CCmdOptionFlags::required_input));
 	options.add(make_opt( out_name, "out", 'o', "output image of minimal correlation", 
-			      CCmdOption::required,  &C2DImageIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_output,  &C2DImageIOPluginHandler::instance()));
 	options.add(make_opt( skip, "skip", 'k', "skip images at beginning of series"));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/2dseries-sectionmask.cc b/src/2dseries-sectionmask.cc
index d1cf16d..8de3542 100644
--- a/src/2dseries-sectionmask.cc
+++ b/src/2dseries-sectionmask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
 #include <libxml++/libxml++.h>
 
 #include <mia/core.hh>
-#include <mia/2d/SegSet.hh>
+#include <mia/2d/segset.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 #include <mia/internal/main.hh>
@@ -65,9 +65,9 @@ int do_main(int argc, char *argv[])
 	size_t frame = 0; 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
+	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOptionFlags::required_input));
 	options.add(make_opt( out_filename, "out-file", 'o', "output image containing the mask", 
-			      CCmdOption::required, &C2DImageIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_output, &C2DImageIOPluginHandler::instance()));
 	options.add(make_opt( frame, "frame", 'f', "Frame number for which to extract the mask"));
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/2dseries-segdistance.cc b/src/2dseries-segdistance.cc
index 91f5c08..5aff518 100644
--- a/src/2dseries-segdistance.cc
+++ b/src/2dseries-segdistance.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@
 
 #include <mia/core.hh>
 #include <mia/internal/main.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 
@@ -100,8 +100,8 @@ int do_main(int argc, char *argv[])
 	int  skip = 0; 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
-	options.add(make_opt( reference, "reference", 'r', "reference frame", CCmdOption::required));
+	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOptionFlags::required_input));
+	options.add(make_opt( reference, "reference", 'r', "reference frame"));
 	options.add(make_opt( skip, "skip", 'k', "skip images at the beginning"));
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/2dseries2dordermedian.cc b/src/2dseries2dordermedian.cc
index f379e25..df82799 100644
--- a/src/2dseries2dordermedian.cc
+++ b/src/2dseries2dordermedian.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,7 +32,7 @@
 #include <mia/internal/main.hh>
 #include <mia/2d/filterchain.hh>
 #include <mia/2d/imageio.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/core.hh>
 
 using namespace std;
@@ -196,8 +196,8 @@ int do_main( int argc, char *argv[] )
 	const C2DImageIOPluginHandler::Instance& imageio = C2DImageIOPluginHandler::instance();
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( in_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output image name", CCmdOption::required, &imageio));
+	options.add(make_opt( in_filename, "in-file", 'i', "input segmentation set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output image name", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( skip, "skip", 'k', "Skip files at the beginning"));
 	options.add(make_opt( enlarge_boundary,  "enlarge-boundary", 'e', "Enlarge cropbox by number of pixels"));
 	options.add(make_opt( crop, "crop", 'c', "crop image before running statistics"));
diff --git a/src/2dseries2sets.cc b/src/2dseries2sets.cc
index 0754791..8421aff 100644
--- a/src/2dseries2sets.cc
+++ b/src/2dseries2sets.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,8 +23,9 @@
 #include <libxml++/libxml++.h>
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/bfsv23dispatch.hh>
+#include <mia/core/attribute_names.hh>
 #include <mia/2d/imageio.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <boost/filesystem.hpp>
 
 #include <mia/internal/main.hh>
@@ -171,7 +172,7 @@ int do_main( int argc, char *argv[] )
 	
 	CCmdOptionList options(g_description);
 	options.add(make_opt( out_directory, "out", 'o', "output directory (needs to exist and be writable)", 
-				    CCmdOption::required));
+			      CCmdOptionFlags::required_output));
 	options.add(make_opt( no_copy_images, "no-copy", 0, "don't copy image files to output directory"));
 
 	if (options.parse(argc, argv, "image", &C2DImageIOPluginHandler::instance()) != CCmdOptionList::hr_no)
diff --git a/src/2dseriescorr.cc b/src/2dseriescorr.cc
index d1370b9..c01b2b2 100644
--- a/src/2dseriescorr.cc
+++ b/src/2dseriescorr.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -95,13 +95,13 @@ int do_main( int argc, char *argv[] )
 	const auto& image2dio = C2DImageIOPluginHandler::instance();
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_name, "in-base", 'i', "input file name base", CCmdOption::required, &image2dio));
+	options.add(make_opt( src_name, "in-base", 'i', "input file name base", CCmdOptionFlags::required_input, &image2dio));
 	options.add(make_opt( src_name, "outname", 'o', "output file name to save the avarage per-pixel correlation", 
-			      CCmdOption::required, &image2dio));
+			      CCmdOptionFlags::required_output, &image2dio));
 	options.add(make_opt( out_hor_name, "horizontal", 'z', "horiZontal correlation output file name", 
-			    CCmdOption::not_required, &image2dio));
+			      CCmdOptionFlags::output, &image2dio));
 	options.add(make_opt( out_ver_name, "vertical", 't', "verTical  correlation output file name", 
-			      CCmdOption::not_required, &image2dio));
+			      CCmdOptionFlags::output, &image2dio));
 	options.add(make_opt( first, "skip", 'k', "skip images at beginning of series"));
 	options.add(make_opt( last, "end", 'e', "last image in series"));
 
diff --git a/src/2dseriesgradMAD.cc b/src/2dseriesgradMAD.cc
index 9c52f54..bca179c 100644
--- a/src/2dseriesgradMAD.cc
+++ b/src/2dseriesgradMAD.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
 #include <mia/internal/main.hh>
 #include <mia/2d/filterchain.hh>
 #include <mia/2d/imageio.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/core.hh>
 
 using namespace std;
@@ -176,8 +176,8 @@ int do_main( int argc, char *argv[] )
 	const auto& imageio = C2DImageIOPluginHandler::instance();
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( in_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOption::required, &imageio));
+	options.add(make_opt( in_filename, "in-file", 'i', "input segmentation set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( skip, "skip", 'k', "Skip files at the beginning"));
 	options.add(make_opt( enlarge_boundary,  "enlarge-boundary", 'e', 
 				    "Enlarge cropbox by number of pixels"));
diff --git a/src/2dseriesgradvariation.cc b/src/2dseriesgradvariation.cc
index 213c663..3670a21 100644
--- a/src/2dseriesgradvariation.cc
+++ b/src/2dseriesgradvariation.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
 
 #include <mia/2d/filter.hh>
 #include <mia/2d/imageio.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/core.hh>
 
 using namespace std;
@@ -138,8 +138,8 @@ int do_main( int argc, char *argv[] )
 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( in_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOption::required, &imageio));
+	options.add(make_opt( in_filename, "in-file", 'i', "input segmentation set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( skip, "skip", 'k', "Skip files at the beginning"));
 	options.add(make_opt( enlarge_boundary,  "enlarge-boundary", 'e', "Enlarge cropbox by number of pixels"));
 	options.add(make_opt( crop, "crop", 'c', "crop image before running statistics"));
diff --git a/src/2dserieshausdorff.cc b/src/2dserieshausdorff.cc
index e19c2d3..623263d 100644
--- a/src/2dserieshausdorff.cc
+++ b/src/2dserieshausdorff.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
 #include <libxml++/libxml++.h>
 
 #include <mia/core.hh>
-#include <mia/2d/SegSet.hh>
+#include <mia/2d/segset.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 
@@ -57,8 +57,8 @@ int do_main(int argc, char *argv[])
 	int skip = 0; 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
-	options.add(make_opt( ref_filename, "ref-file", 'r', "reference segmentation set", CCmdOption::required));
+	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", CCmdOptionFlags::required_input));
+	options.add(make_opt( ref_filename, "ref-file", 'r', "reference segmentation set", CCmdOptionFlags::required_input));
 	options.add(make_opt( skip, "skip", 'k', "skip images at the beginning"));
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/2dseriessmoothgradMAD.cc b/src/2dseriessmoothgradMAD.cc
index 3738467..87019d5 100644
--- a/src/2dseriessmoothgradMAD.cc
+++ b/src/2dseriessmoothgradMAD.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@
 #include <mia/internal/main.hh>
 #include <mia/2d/filterchain.hh>
 #include <mia/2d/imageio.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/core.hh>
 
 using namespace std;
@@ -192,8 +192,8 @@ int do_main( int argc, char *argv[] )
 	const auto& imageio = C2DImageIOPluginHandler::instance();
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( in_filename, "in-file", 'i', "input segmentation set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOption::required, &imageio));
+	options.add(make_opt( in_filename, "in-file", 'i', "input segmentation set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( skip, "skip", 'k', "Skip files at the beginning"));
 	options.add(make_opt( enlarge_boundary,  "enlarge-boundary", 'e', "Enlarge cropbox by number of pixels"));
 	options.add(make_opt( crop, "crop", 'c', "crop image before running statistics"));
diff --git a/src/2dseriestovolume.cc b/src/2dseriestovolume.cc
index ac6e33c..21ada94 100644
--- a/src/2dseriestovolume.cc
+++ b/src/2dseriestovolume.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@
 #include <libxml++/libxml++.h>
 
 #include <mia/core.hh>
-#include <mia/2d/SegSetWithImages.hh>
+#include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/3d/imageio.hh>
 #include <mia/2d/filter.hh>
@@ -61,15 +61,15 @@ int do_main(int argc, char *argv[])
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( src_filename, "in-file", 'i', "input segmentation set", 
-			      CCmdOption::required));
+			      CCmdOptionFlags::required_input));
 	options.add(make_opt( out_filename, "out-file", 'o', "output 3D image ", 
-			      CCmdOption::required, &C3DImageIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_output, &C3DImageIOPluginHandler::instance()));
 	options.add(make_opt( skip, "skip", 'k', "number of frames to skip at the beginning of the series."));
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
 
 
-	CSegSetWithImages src_segset(src_filename, false); 
+	CSegSetWithImages src_segset(src_filename, true); 
 	const auto& src_frames = src_segset.get_images();
 
 	if (skip >= src_frames.size())
diff --git a/src/2dstackfilter.cc b/src/2dstackfilter.cc
index 7cf7398..64b3e95 100644
--- a/src/2dstackfilter.cc
+++ b/src/2dstackfilter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -120,12 +120,12 @@ int do_main(int argc, char *argv[])
 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", CCmdOption::required, &imageio));
+	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o', "output file name base, the actual names is created "
 			      "by adding the file number based on output order and the extension bysed on the 'type' parameter"
-			      , CCmdOption::required, &imageio));
+			      , CCmdOptionFlags::required, &imageio));
 	options.add(make_opt( out_type, imageio.get_supported_suffix_set(), "type", 't',
-			      "output file type", CCmdOption::required));
+			      "output file type", CCmdOptionFlags::required));
 	options.add(make_help_opt( "help-plugins", 0, 
 				   "give some help about the filter plugins", 
 				   new TPluginHandlerHelpCallback<C2DFifoFilterPluginHandler>)); 
diff --git a/src/2dto3dimage.cc b/src/2dto3dimage.cc
index e1777b7..ee1178b 100644
--- a/src/2dto3dimage.cc
+++ b/src/2dto3dimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -54,8 +54,10 @@ int do_main( int argc, char *argv[] )
 	const C3DImageIOPluginHandler::Instance& image3dio = C3DImageIOPluginHandler::instance();
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be combined", CCmdOption::required, &image2dio));
-	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOption::required, &image3dio));
+	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be combined", 
+			      CCmdOptionFlags::required_input, &image2dio));
+	options.add(make_opt( out_filename, "out-file", 'o', "output file name", 
+			      CCmdOptionFlags::required_output, &image3dio));
 
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
@@ -79,7 +81,7 @@ int do_main( int argc, char *argv[] )
 	for (size_t i = start_filenum; i < end_filenum; ++i) {
 		string src_name = create_filename(src_basename.c_str(), i);
 		cvmsg() << new_line << "Read: " << i <<" out of "<< "[" << start_filenum<< "," << end_filenum << "]" ;
-                auto in_image = load_image2d(in_filename);
+                auto in_image = load_image2d(src_name);
                 ic.add(*in_image); 
 	}
 	cvmsg() << "\n";
diff --git a/src/2dto3dimageb.cc b/src/2dto3dimageb.cc
index b8660e0..6730997 100644
--- a/src/2dto3dimageb.cc
+++ b/src/2dto3dimageb.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -52,7 +52,7 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( out_filename, "out-file", 'o', "output file name", 
-			      CCmdOption::required, &C3DImageIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_output, &C3DImageIOPluginHandler::instance()));
 
 	if (options.parse(argc, argv, "sliceimage", &C2DImageIOPluginHandler::instance()) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/2dtrackpixelmovement.cc b/src/2dtrackpixelmovement.cc
index 6a5b316..95ae4dc 100644
--- a/src/2dtrackpixelmovement.cc
+++ b/src/2dtrackpixelmovement.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -63,11 +63,11 @@ int do_main( int argc, char *argv[] )
 	CCmdOptionList options(g_description);
 	
 	options.set_group("\nFile-IO"); 
-	options.add(make_opt( in_filename, "in-file", 'i', "input point set", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output point set", CCmdOption::required)); 
+	options.add(make_opt( in_filename, "in-file", 'i', "input point set", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output point set", CCmdOptionFlags::required_output)); 
 
 	options.add(make_opt( trans_filename, "transformation", 't', "transformation describing the monitored change", 
-			      CCmdOption::required, &transfio)); 
+			      CCmdOptionFlags::required_input, &transfio)); 
 
         options.set_group("\nParameters"); 
         options.add(make_opt( time_step, "time-step", 'T', 
diff --git a/src/2dtransform.cc b/src/2dtransform.cc
index 88667a6..8e1c3d0 100644
--- a/src/2dtransform.cc
+++ b/src/2dtransform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -53,10 +53,10 @@ int do_main(int argc, char **argv)
 
 	const auto& imageio = C2DImageIOPluginHandler::instance();
 
-	options.add(make_opt( src_filename, "in-file", 'i', "input image", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out-file", 'o', "output image", CCmdOption::required, &imageio));
+	options.add(make_opt( src_filename, "in-file", 'i', "input image", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out-file", 'o', "output image", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( trans_filename, "transformation", 't', "transformation file name", 
-			      CCmdOption::required, &C2DTransformationIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_input, &C2DTransformationIOPluginHandler::instance()));
 
 	options.add(make_opt( interpolator_kernel, "interpolator", 'p', "override the interpolator provided by the transformation"));
 	options.add(make_opt( interpolator_bc, "boundary", 'b', "override the boundary conditions provided by the transformation."
diff --git a/src/2dtransformation-to-strain.cc b/src/2dtransformation-to-strain.cc
index cf86da9..28e9dd4 100644
--- a/src/2dtransformation-to-strain.cc
+++ b/src/2dtransformation-to-strain.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -53,8 +53,9 @@ int do_main(int argc, char **argv)
 	string out_filename;
 
 	options.add(make_opt( trans_filename, "in-file", 'i', "input transformation", 
-			      CCmdOption::required, &C2DTransformationIOPluginHandler::instance()));
-	options.add(make_opt( out_filename, "out-file", 'o', "output Green's strain tensor", CCmdOption::required));
+			      CCmdOptionFlags::required_input, &C2DTransformationIOPluginHandler::instance()));
+	options.add(make_opt( out_filename, "out-file", 'o', "output Green's strain tensor", 
+			      CCmdOptionFlags::required_output));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/3dbinarycombine.cc b/src/3dbinarycombine.cc
index 958eb0c..d3ff303 100644
--- a/src/3dbinarycombine.cc
+++ b/src/3dbinarycombine.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -113,12 +113,10 @@ int do_main( int argc, char *argv[] )
 
 	const auto& imageio = C3DImageIOPluginHandler::instance();
 	CCmdOptionList options(g_description);
-	options.add(make_opt( filename1, "file1", '1', "input mask image 1", CCmdOption::required, &imageio)); 
-	options.add(make_opt( filename2, "file2", '2', "input input mask image 2", CCmdOption::required, &imageio)); 
+	options.add(make_opt( filename1, "file1", '1', "input mask image 1", CCmdOptionFlags::required_input, &imageio)); 
+	options.add(make_opt( filename2, "file2", '2', "input mask image 2", CCmdOptionFlags::required_input, &imageio)); 
 	options.add(make_opt(op, g_binops_dict, "operation", 'p', "Operation to be applied")); 
-	options.add(make_opt( out_filename, "out-file", 'o', "output mask image", CCmdOption::required, &imageio)); 
-
-
+	options.add(make_opt( out_filename, "out-file", 'o', "output mask image", CCmdOptionFlags::required_output, &imageio)); 
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no) 
 		return EXIT_SUCCESS; 
diff --git a/src/3dbrainextractT1.cc b/src/3dbrainextractT1.cc
index b444dfb..abcda8e 100644
--- a/src/3dbrainextractT1.cc
+++ b/src/3dbrainextractT1.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -75,8 +75,8 @@ int do_main( int argc, char *argv[] )
 	
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i',
-			      "input image(s) to be segmented", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out-file", 'o', "brain mask", CCmdOption::required, &imageio));
+			      "input image(s) to be segmented", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out-file", 'o', "brain mask", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( noOfClasses, "no-of-classes", 'n', "number of classes"));
 	options.add(make_opt( wmclass,     "wm-class",      'w', "index of white matter"));
 	options.add(make_opt( wmclassprob, "wm-prob", 'p',
diff --git a/src/3dcombine-mr-segmentations.cc b/src/3dcombine-mr-segmentations.cc
index bae5f31..7fcf6e0 100644
--- a/src/3dcombine-mr-segmentations.cc
+++ b/src/3dcombine-mr-segmentations.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,11 +50,11 @@ int do_main( int argc, char *argv[] )
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i', "input probability images. The number of "
 			      "mask images must correspond to the number of probability images given here.", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 
 	
 	options.add(make_opt( out_filename, "out-file", 'o', "output image that contains the labeling.", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_output, &imageio));
 
 	if (options.parse(argc, argv, "masks", &imageio) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/3dcost-translatedgrad.cc b/src/3dcost-translatedgrad.cc
index 46e4dff..aff25ae 100644
--- a/src/3dcost-translatedgrad.cc
+++ b/src/3dcost-translatedgrad.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -59,14 +59,14 @@ int do_main(int argc, char **argv)
 	
 	const auto & imageio  = C3DImageIOPluginHandler::instance(); 
 	
-	options.add(make_opt( src_filename, "in-file", 'i', "input image ", CCmdOption::required, &imageio));
-	options.add(make_opt( ref_filename, "ref-file", 'r', "reference image ", CCmdOption::required, &imageio));
+	options.add(make_opt( src_filename, "in-file", 'i', "input image ", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( ref_filename, "ref-file", 'r', "reference image ", CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o', "output vector field ", 
-			      CCmdOption::required, &C3DTransformationIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_output, &C3DTransformationIOPluginHandler::instance()));
 	options.add(make_opt( grad_image_filename, "gradimg-file", 'g', "norm image of the spline transformed gradient", 
-			    CCmdOption::not_required, &imageio));
+			      CCmdOptionFlags::output, &imageio));
 	options.add(make_opt( cost_grad_filename, "cost-gradimg-file", 'C', "norm image of the cost gradient", 
-			      CCmdOption::not_required, &imageio));
+			      CCmdOptionFlags::output, &imageio));
 
 	options.add(make_opt( transform_creator, "spline:rate=5", "transForm", 'f', "Transformation the gradient relates to"));
 	options.add(make_opt( cost, "ssd", "cost", 'c', "cost function to use"));
diff --git a/src/3dcost.cc b/src/3dcost.cc
index f1983bb..af4f0fe 100644
--- a/src/3dcost.cc
+++ b/src/3dcost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/3dcrispsegment.cc b/src/3dcrispsegment.cc
index 2f5d521..44fc33f 100644
--- a/src/3dcrispsegment.cc
+++ b/src/3dcrispsegment.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -96,9 +96,9 @@ int do_main( int argc, char *argv[] )
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i', "input class file, should contain multiple images "
 			      "with tissue class probabilities", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o', "output class label image", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_output, &imageio));
 
 	options.add(make_opt( label_offset, "label-offset", 'l', "label offset"));
 
diff --git a/src/3ddeform.cc b/src/3ddeform.cc
index a4f4595..3faa71b 100644
--- a/src/3ddeform.cc
+++ b/src/3ddeform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -53,10 +53,10 @@ int do_main(int argc, char **argv)
 	const auto& imageio = C3DImageIOPluginHandler::instance();
 	const auto& vfioh = C3DVFIOPluginHandler::instance();
 
-	options.add(make_opt( src_filename, "in-image", 'i', "input image", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out-image", 'o', "transformed image", CCmdOption::required, &imageio));
+	options.add(make_opt( src_filename, "in-image", 'i', "input image", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out-image", 'o', "transformed image", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( vf_filename, "transformation", 't', "transformation vector field", 
-			      CCmdOption::required, &vfioh));
+			      CCmdOptionFlags::required_input, &vfioh));
 	options.add(make_opt( interpolator_kernel, "bspline:d=3", "interpolator", 'p', "image interpolator kernel"));
 
 
diff --git a/src/3ddistance-stats.cc b/src/3ddistance-stats.cc
new file mode 100644
index 0000000..c864203
--- /dev/null
+++ b/src/3ddistance-stats.cc
@@ -0,0 +1,225 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
+ *
+ * MIA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MIA; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <mia/3d/imageio.hh>
+#include <mia/3d/filter.hh>
+#include <mia/core.hh>
+#include <mia/core/labelmap.hh>
+
+#include <map>
+#include <set>
+
+using namespace mia; 
+using namespace std; 
+
+const SProgramDescription g_description = {
+        {pdi_group, "Analysis, filtering, combining, and segmentation of 3D images"}, 
+	{pdi_short, "Evaluate distance statistics for two labeled images."}, 
+	{pdi_description, "This program is used to evaluate the distance between equally labelled "
+         "areas in two images. The output file is a csv file containing the distances for "
+         "each labeled coordinate in the test image in the following form:\n"
+         "\n"
+         "  label,n-samples,distance,distance,...\n"
+	 "\nA simple R program to get some per label statistics from this data would look like\n\n"
+	 "    args <- commandArgs(TRUE)\n"
+	 "    data <- read.csv(args[1], header=FALSE)\n"
+         "    for ( i in 1:dim(data)[1] )  {\n"
+	 "        line <- data[i,]\n"
+	 "        label <- as.integer(line[1])\n"
+	 "        end_range <- 2 + as.numeric(line[2])\n"
+	 "        s <- as.numeric(line[3:end_range])\n"
+	 "        result <- sprintf(\"%d %8.4f %8.4f %8.4f %8.4f\\n\"\n"
+	 "            label, mean(s), sqrt(var(s)),  median(s), max(s))\n"
+	 "        cat(result)\n"
+	 "    }\n\n"
+	}, 
+	{pdi_example_descr, "Evaluate the distances for each label availabe in image.v to the "
+         "corresponding labels in the image reference.v ans store the result "
+         "a coma separated list of values, i.e. distances.csv."}, 
+	{pdi_example_code, "-i image.v -r reference.v -o distances.csv" }
+}; 
+
+
+unsigned short translate_label( unsigned short l, const CLabelMap& map)
+{
+        if (map.empty()) 
+                return l; 
+        auto idx = map.find(l); 
+        if (idx != map.end()) 
+                return idx->second; 
+        throw create_exception<runtime_error>("unmapped label '", l, "' encountered"); 
+}
+
+
+
+typedef vector<float> CDistanceResult; 
+
+
+typedef map<unsigned short, CDistanceResult> CDistanceResultMap; 
+
+class  FEvaluateDistances: public TFilter<CDistanceResultMap> {
+public: 
+        FEvaluateDistances(const CLabelMap& lm); 
+        
+        template <typename T, typename S> 
+        CDistanceResultMap operator ()(const T3DImage<T>& test, const T3DImage<S>& ref) const; 
+private: 
+        const CLabelMap m_lm; 
+}; 
+
+template <typename T, typename S, bool, bool> 
+struct __dispatch_filter {
+        static CDistanceResultMap apply(const T3DImage<T>& MIA_PARAM_UNUSED(test), 
+                                        const T3DImage<S>& MIA_PARAM_UNUSED(ref), 
+                                        const CLabelMap& MIA_PARAM_UNUSED(lm)){
+                throw create_exception<invalid_argument>("CDistanceResultMap: input data not supported,"
+                                                         "got ", __type_descr<T>::value, " and ", 
+                                                         __type_descr<S>::value, " but require integral scalar types");
+        }
+}; 
+
+template <typename T> 
+P3DImage get_mask( const T3DImage<T>& image, unsigned short label) 
+{
+        stringstream descr; 
+        descr << "binarize:min=" << label << ",max=" << label; 
+        return  run_filter(image, descr.str().c_str()); 
+}
+
+template <typename T> 
+C3DFImage get_ref_distance(const T3DImage<T>& image, unsigned short label, const C3DFilter& distance)
+{
+        auto mask = get_mask( image, label); 
+        auto d = distance.filter(*mask); 
+        return dynamic_cast<C3DFImage&>(*d); 
+}
+
+
+template <typename T, typename S> 
+struct __dispatch_filter<T,S, true, true> {
+        static CDistanceResultMap apply(const T3DImage<T>& test, const T3DImage<S>& ref, const CLabelMap& lm){
+                set<T> test_labels; 
+                
+                CDistanceResultMap result; 
+                P3DFilter distance = produce_3dimage_filter("distance"); 
+                
+                // add all the test labels 
+                for( auto t: test)
+                        if (t != 0) 
+                                test_labels.insert(t); 
+                
+                for(auto tl: test_labels) {
+                        auto rl = translate_label(tl, lm);
+                        auto test_maskp = get_mask(test, tl); 
+                        const C3DBitImage& test_mask = dynamic_cast<const C3DBitImage&>(*test_maskp); 
+                        C3DFImage ref_mask = get_ref_distance(ref, rl, *distance);
+                        
+                        CDistanceResult distances; 
+                        auto it = test_mask.begin(); 
+                        auto et = test_mask.end(); 
+                        auto ir = ref_mask.begin(); 
+                        
+                        while (it != et) {
+                                if (*it) 
+                                        distances.push_back(*ir); 
+                                ++it; 
+                                ++ir; 
+                        }
+                        result[tl] = distances;
+                }
+                return result; 
+        }
+}; 
+
+FEvaluateDistances::FEvaluateDistances(const CLabelMap& lm):
+        m_lm(lm)
+{
+}
+
+template <typename T, typename S> 
+CDistanceResultMap FEvaluateDistances::operator ()(const T3DImage<T>& test, const T3DImage<S>& ref) const
+{
+        const auto T_integral =is_integral<T>::value;  
+        const auto S_integral =is_integral<S>::value;  
+        
+        return __dispatch_filter<T, S, T_integral, S_integral>::apply(test, ref, m_lm); 
+}
+
+
+int do_main( int argc, char *argv[] )
+{
+	string in_filename;
+	string ref_filename;
+
+	string label_translate_filename;
+
+	string out_filename;
+
+	const auto& imageio = C3DImageIOPluginHandler::instance();
+
+	stringstream filter_names;
+
+	CCmdOptionList options(g_description);
+
+	options.set_group("File-IO"); 
+	options.add(make_opt( in_filename, "in-labels", 'i', "input label image", 
+			      CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( ref_filename, "ref-labels", 'r', "reference label image",
+			      CCmdOptionFlags::required_input, &imageio));
+
+        options.add(make_opt( label_translate_filename, "label-map", 'l', "optional mapping of label numbers", 
+			    CCmdOptionFlags::input));
+
+        options.add(make_opt( out_filename, "out-file", 'o', "output file name to write the distances to. "
+                              "The output file is a csv file, containing distances listed for each label."));
+        
+
+	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
+		return EXIT_SUCCESS; 
+
+        auto test_labels = load_image3d(in_filename); 
+        auto ref_labels = load_image3d(ref_filename);
+        
+        CLabelMap lmap; 
+        if (!label_translate_filename.empty()) {
+                ifstream ifs(label_translate_filename); 
+                lmap = CLabelMap(ifs); 
+        }
+        
+        FEvaluateDistances evaluater(lmap); 
+        auto result = mia::filter(evaluater, *test_labels, *ref_labels); 
+        
+        // save result 
+        ofstream outf(out_filename); 
+        if (outf.bad())
+                throw create_exception<runtime_error>("Error opening file '", out_filename, "' for writing"); 
+        
+        for (auto i : result)
+                outf << i.first << "," << i.second.size() << "," << i.second << "\n";
+
+        if (outf.bad())
+                throw create_exception<runtime_error>("Error opening file '", out_filename, "' for writing"); 
+        outf.close(); 
+	return EXIT_SUCCESS;
+
+}
+
+#include <mia/internal/main.hh>
+MIA_MAIN(do_main)
diff --git a/src/3ddistance.cc b/src/3ddistance.cc
index 8fc509e..7479cb8 100644
--- a/src/3ddistance.cc
+++ b/src/3ddistance.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -471,10 +471,13 @@ int do_main( int argc, char *argv[] )
 	CCmdOptionList options(g_description);
 	options.set_group("File IO"); 
 	options.add(make_opt( src_filename, "in-file", 'i', 
-					"input image(s) that contain the source pixel mask", CCmdOption::required)); 
+			      "input image(s) that contain the source pixel mask", 
+			      CCmdOptionFlags::required_input)); 
 	options.add(make_opt( ref_filename, "ref-file", 'r', 
-					"reference mask to evaluate the distance from", CCmdOption::required)); 
-	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOption::required)); 
+			      "reference mask to evaluate the distance from", 
+			      CCmdOptionFlags::required_input)); 
+	options.add(make_opt( out_filename, "out-file", 'o', "output file name", 
+			      CCmdOptionFlags::required_output)); 
 	
 	options.set_group("Test"); 
 	options.add(make_opt( self_test, "self-test", 0,"run a self test" ));
diff --git a/src/3deval-transformquantity.cc b/src/3deval-transformquantity.cc
index 07b15de..509871e 100644
--- a/src/3deval-transformquantity.cc
+++ b/src/3deval-transformquantity.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -163,12 +163,12 @@ int do_main( int argc, char *argv[] )
 	options.add(make_opt( in_filename, "in-file", 'i', 
 			      "input point set, if this parameter is given a sparse evaluation "
 			      "of the quantity will be done, otherwise the quantity is evalutated "
-			      "for each grid point of the transformation range."));
+			      "for each grid point of the transformation range.", CCmdOptionFlags::input));
 	options.add(make_opt( out_filename, "out-file", 'o', 
-			      "output strains file, for a format description see above.", CCmdOption::required)); 
+			      "output strains file, for a format description see above.", CCmdOptionFlags::required_output)); 
 	
 	options.add(make_opt( trans_filename, "transformation", 't', "transformation of which the quantity will be evaluated.", 
-			      CCmdOption::required, &C3DTransformationIOPluginHandler::instance())); 
+			      CCmdOptionFlags::required_input, &C3DTransformationIOPluginHandler::instance())); 
 
 	options.set_group("\nParameters"); 
 	options.add(make_opt( quantity, tqmap, "quantity", 'q', 
diff --git a/src/3dfield2norm.cc b/src/3dfield2norm.cc
index 0ac8aec..489802b 100644
--- a/src/3dfield2norm.cc
+++ b/src/3dfield2norm.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -46,8 +46,8 @@ int do_main(int argc, char *argv[])
 	
 	CCmdOptionList options(g_description);
 	
-	options.add(make_opt( src_filename, "in", 'i', "input vector field", CCmdOption::required, &C3DVFIOPluginHandler::instance()));
-	options.add(make_opt( out_filename, "out", 'o', "output image", CCmdOption::required, &C3DImageIOPluginHandler::instance()));
+	options.add(make_opt( src_filename, "in", 'i', "input vector field", CCmdOptionFlags::required_input, &C3DVFIOPluginHandler::instance()));
+	options.add(make_opt( out_filename, "out", 'o', "output image", CCmdOptionFlags::required_output, &C3DImageIOPluginHandler::instance()));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/3dforce.cc b/src/3dforce.cc
index feca016..b06bf19 100644
--- a/src/3dforce.cc
+++ b/src/3dforce.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -73,9 +73,9 @@ int do_main(int argc, char **argv)
 
 	const auto& imageio = C3DImageIOPluginHandler::instance();
 
-	options.add(make_opt( src_filename, "src-file", 'i', "input image", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out-file", 'o', "reference image", CCmdOption::required, &imageio));
-	options.add(make_opt( ref_filename, "ref-file", 'r', "output force norm image", CCmdOption::required, &imageio));
+	options.add(make_opt( src_filename, "src-file", 'i', "input image", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( ref_filename, "ref-file", 'r', "output force norm image", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out-file", 'o', "reference image", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( cost, "ssd", "cost", 'c', "cost function to use"));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/3dfuzzysegment.cc b/src/3dfuzzysegment.cc
index 0ec948a..067d878 100644
--- a/src/3dfuzzysegment.cc
+++ b/src/3dfuzzysegment.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -66,24 +66,22 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be segmenetd", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
+	
 	options.add(make_opt( cls_filename, "cls-file", 'c', "output class probability images. Note, the "
 			      "used file format must support multible images (best is to use vista)", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::output, &imageio));
 	options.add(make_opt( out_filename, "b0-file", 'o', "image corrected for intensity non-uniformity", 
-			      CCmdOption::not_required , &imageio));
+			      CCmdOptionFlags::output , &imageio));
 	options.add(make_opt( noOfClasses, "no-of-classes", 'n', "number of classes"));
 	options.add(make_opt( residuum, "residuum", 'r', "relative residuum"));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
 
-	// required options (anything that has no default value)
-	if ( in_filename.empty() )
-		throw runtime_error("'--in-file'  ('i') option required\n");
-	if ( in_filename.empty() )
-		throw runtime_error("'--cls-file' ('c') option required\n");
 
+	if (cls_filename.empty() && out_filename.empty())
+		throw runtime_error("Not a single output file given"); 
 
 
 	C3DImageIOPluginHandler::Instance::PData inImage_list = imageio.load(in_filename);
diff --git a/src/3dgetsize.cc b/src/3dgetsize.cc
index 3b09faa..218541c 100644
--- a/src/3dgetsize.cc
+++ b/src/3dgetsize.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -48,7 +48,7 @@ int do_main( int argc, char *argv[] )
 	
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", 
-			      CCmdOption::required, &imageio3d));
+			      CCmdOptionFlags::required_input, &imageio3d));
 	
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/3dgetslice.cc b/src/3dgetslice.cc
index 57eb1bc..638ea04 100644
--- a/src/3dgetslice.cc
+++ b/src/3dgetslice.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -145,10 +145,10 @@ int do_main( int argc, char *argv[] )
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i', 
 			      "input image(s) to be filtered", 
-			      CCmdOption::required, &C3DImageIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_input, &C3DImageIOPluginHandler::instance()));
 	options.add(make_opt( out_filename, "out-file", 'o', "output image(s) base name, give without "
 			      "extension since this will be based on the '--type' option", 
-			      CCmdOption::required, &imageio2d));
+			      CCmdOptionFlags::required_output, &imageio2d));
 	options.add(make_opt( out_type, imageio2d.get_set(), "type", 't', "output file type"));
 	options.add(make_opt( start_slice, "start", 's',"start slice number"));
 	options.add(make_opt( slice_number, "number", 'n', "number of slices (all=0)"));
diff --git a/src/3dimageaddattributes.cc b/src/3dimageaddattributes.cc
index 2093aa3..7b450ee 100644
--- a/src/3dimageaddattributes.cc
+++ b/src/3dimageaddattributes.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -57,11 +57,11 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o', "output image(s) with the added attributes", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( attr_image, "attr", 'a', "2D image providing the attributes", 
-			      CCmdOption::required, &image2dio));
+			      CCmdOptionFlags::required_input, &image2dio));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/3dimagecombine.cc b/src/3dimagecombine.cc
index 0ba0667..e6c4cad 100644
--- a/src/3dimagecombine.cc
+++ b/src/3dimagecombine.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,8 +34,8 @@ const SProgramDescription g_description = {
         {pdi_group, "Analysis, filtering, combining, and segmentation of 3D images" }, 
 	{pdi_short, "Combine two 3D images."}, 
 	{pdi_description, "This program is used to combine two images using a given image combiner."}, 
-	{pdi_example_descr, "Take two label images l1.v and l2.v and evaluate the label overlap."}, 
-	{pdi_example_code, "-1 l1.v -2 l2.v -c map.txt -c labelxmap"}
+	{pdi_example_descr, "Take two images l1.v and l2.v and evaluate the per-voxel sum."}, 
+	{pdi_example_code, "-1 l1.v -2 l2.v -c sum.v -c add"}
 };  
 
 
@@ -52,12 +52,12 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_image1, "image1", '1', "input image  1 to be combined", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( in_image2, "image2", '2', "input image  2 to be combined", 
-			      CCmdOption::required, &imageio));
-	options.add(make_opt( combiner, "labelxmap", "combiner", 'c', "combiner operation", CCmdOption::required));
-	options.add(make_opt( out_filename, "out", 'o', "output file", CCmdOption::required, &imageio));
-
+			      CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( combiner, "add", "combiner", 'c', "combiner operation", CCmdOptionFlags::required));
+	options.add(make_opt( out_filename, "out", 'o', "output file", CCmdOptionFlags::required_output, &imageio));
+	
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
 
@@ -83,11 +83,12 @@ int do_main( int argc, char *argv[] )
 	if (image2list->size() > 1)
 		cvwarn() << "only first image in " << in_image2 << "will be used\n";
 
-	PCombinerResult combination = combiner->combine(**image1list->begin(), **image2list->begin());
+	auto combination = combiner->combine(**image1list->begin(), **image2list->begin());
 
-	combination->save(out_filename);
+	if (save_image(out_filename, combination)) 
+		return EXIT_SUCCESS; 
 
-	return 0;
+	return EXIT_FAILURE; 
 };
 
 
diff --git a/src/3dimagecreator.cc b/src/3dimagecreator.cc
index a38e5b2..600c783 100644
--- a/src/3dimagecreator.cc
+++ b/src/3dimagecreator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -54,7 +54,7 @@ int do_main(int argc, char *argv[])
 	CCmdOptionList options(g_description);
 
 	options.add(make_opt( out_filename, "out-file", 'o', "output file for create object", 
-			      CCmdOption::required, &C3DImageIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_output, &C3DImageIOPluginHandler::instance()));
 	options.add(make_opt( size, "size", 's', "size of the object"));
 	options.add(make_opt( pixel_type, CPixelTypeDict, "repn", 'r',"input pixel type "));
 	options.add(make_opt( object_creator, "sphere", "object", 'j', "object to be created"));
diff --git a/src/3dimagefilter.cc b/src/3dimagefilter.cc
index 150f9df..cf0a827 100644
--- a/src/3dimagefilter.cc
+++ b/src/3dimagefilter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -54,9 +54,9 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o', "output image(s) that have been filtered", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_output, &imageio));
 	options.add(make_help_opt( "help-plugins", 0, "give some help about the filter plugins", 
 				   new TPluginHandlerHelpCallback<C3DFilterPluginHandler>)); 
 
diff --git a/src/3dimagefilterstack.cc b/src/3dimagefilterstack.cc
index ea7482f..79959a5 100644
--- a/src/3dimagefilterstack.cc
+++ b/src/3dimagefilterstack.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -69,10 +69,11 @@ int do_main( int argc, char *argv[] )
 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out-file", 'o', "output file name base, numbers are added accorfing to the input file pattern, and "
-			      "the file  extension is added according to the 'type' option.", CCmdOption::required, &imageio));
-	options.add(make_opt( out_type, imageio.get_set(), "type", 't',"output file type", CCmdOption::required));
+	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out-file", 'o', "output file name base, numbers are added accorfing to the input "
+			      "file pattern, and the file  extension is added according to the 'type' option.", 
+			      CCmdOptionFlags::required, &imageio));
+	options.add(make_opt( out_type, imageio.get_set(), "type", 't',"output file type", CCmdOptionFlags::required));
 	
 	options.add(make_help_opt( "help-plugins", 0,
 				   "give some help about the filter plugins", 
diff --git a/src/3dimageselect.cc b/src/3dimageselect.cc
index 3b1c94e..7f33f5e 100644
--- a/src/3dimageselect.cc
+++ b/src/3dimageselect.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -51,9 +51,9 @@ int do_main( int argc, char *argv[])
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i',
-			      "input images", CCmdOption::required, &imageio));
+			      "input images", CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o',
-				    "output image", CCmdOption::required, &imageio));
+				    "output image", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( num, "number", 'n',  "image number to be selected"));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/3dimagestats.cc b/src/3dimagestats.cc
index 33a0e4c..868a09b 100644
--- a/src/3dimagestats.cc
+++ b/src/3dimagestats.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -85,7 +85,7 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( thresh, "thresh", 't', "intensity thresh to ignore"));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/3dlandmarks-distances.cc b/src/3dlandmarks-distances.cc
index a34c632..bba662c 100644
--- a/src/3dlandmarks-distances.cc
+++ b/src/3dlandmarks-distances.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -55,8 +55,8 @@ int do_main(int argc, char **argv)
         
 	const auto& lmxio = C3DLandmarklistIOPluginHandler::instance();
 
-	options.add(make_opt( src1_filename, "in-file-1", 'i', "input landmark set 1", CCmdOption::required, &lmxio));
-	options.add(make_opt( src2_filename, "in-file-2", 'o', "input landmark set 2", CCmdOption::required, &lmxio));
+	options.add(make_opt( src1_filename, "in-file-1", 'i', "input landmark set 1", CCmdOptionFlags::required_input, &lmxio));
+	options.add(make_opt( src2_filename, "in-file-2", 'o', "input landmark set 2", CCmdOptionFlags::required_input, &lmxio));
 
 
         if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/3dlandmarks-transform.cc b/src/3dlandmarks-transform.cc
index 9382b49..48c9b90 100644
--- a/src/3dlandmarks-transform.cc
+++ b/src/3dlandmarks-transform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -59,9 +59,9 @@ int do_main(int argc, char **argv)
 	const auto& lmxio = C3DLandmarklistIOPluginHandler::instance();
 	const auto& transio = C3DTransformationIOPluginHandler::instance(); 
 
-	options.add(make_opt( src_filename, "in-file", 'i', "input landmark set", CCmdOption::required, &lmxio));
-	options.add(make_opt( out_filename, "out-file", 'o', "output landmark set", CCmdOption::required, &lmxio));
-	options.add(make_opt( trans_filename, "transformation", 't', "transformation file", CCmdOption::required, &transio));
+	options.add(make_opt( src_filename, "in-file", 'i', "input landmark set", CCmdOptionFlags::required_input, &lmxio));
+	options.add(make_opt( out_filename, "out-file", 'o', "output landmark set", CCmdOptionFlags::required_output, &lmxio));
+	options.add(make_opt( trans_filename, "transformation", 't', "transformation file", CCmdOptionFlags::required_input, &transio));
 
 
         if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/3dlerp.cc b/src/3dlerp.cc
index 4c130d8..96bb6ee 100644
--- a/src/3dlerp.cc
+++ b/src/3dlerp.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -147,11 +147,12 @@ int do_main(int argc, char **argv)
 
 	const auto& imageio = C3DImageIOPluginHandler::instance();
 
-	options.add(make_opt( src1_filename, "first", '1', "first input image ", CCmdOption::required, &imageio));
-	options.add(make_opt( src2_filename, "second", '2', "second input image ", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out-file", 'o', "output vector field", CCmdOption::required, &imageio));
+	options.add(make_opt( src1_filename, "first", '1', "first input image ", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( src2_filename, "second", '2', "second input image ", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out-file", 'o', "linearly interpolated image", 
+			      CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( positions, "positions", 'p', 
-				    "image series positions (first, target, second)", CCmdOption::required));
+				    "image series positions (first, target, second)", CCmdOptionFlags::required));
 	options.add(make_opt( self_test, "self-test", 0, "run a self test of the tool"));
 
 	if (options.parse(argc, (const char **)argv) != CCmdOptionList::hr_no)
diff --git a/src/3dmany2one-nonrigid.cc b/src/3dmany2one-nonrigid.cc
index eced8d0..ef1421c 100644
--- a/src/3dmany2one-nonrigid.cc
+++ b/src/3dmany2one-nonrigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -139,14 +139,12 @@ int do_main( int argc, char *argv[] )
 	
 	options.set_group("\nFile-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", 			      
-			      CCmdOption::required, &C3DImageIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_input, &C3DImageIOPluginHandler::instance()));
 	options.add(make_opt( registered_filebase, "out-file", 'o', "file name for registered files", 
-			      CCmdOption::not_required, &C3DImageIOPluginHandler::instance())); 
+			      CCmdOptionFlags::output, &C3DImageIOPluginHandler::instance())); 
 	
 	options.set_group("\nRegistration"); 
-	options.add(make_opt( minimizer, "optimizer", 'O', "Optimizer used for minimization", 
-			      CCmdOption::not_required, &CMinimizerPluginHandler::instance()
-			    ));
+	options.add(make_opt( minimizer, "optimizer", 'O', "Optimizer used for minimization"));
 	options.add(make_opt( mg_levels, "mg-levels", 'l', "multi-resolution levels"));
 	options.add(make_opt( transform_creator, "spline", "transForm", 'f', "transformation type"));
 	options.add(make_opt( reference_param, "ref", 'r', "reference frame (-1 == use image in the middle)")); 
diff --git a/src/3dmaskseeded.cc b/src/3dmaskseeded.cc
index d2b3669..b6dde98 100644
--- a/src/3dmaskseeded.cc
+++ b/src/3dmaskseeded.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -138,9 +138,9 @@ int do_main(int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out-file", 'o', "output image(s) that have been filtered", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( seed_point, "seed", 's', "seed point"));
 
 	options.add(make_opt( shape, "6n", "neighborhood", 'n', "neighborhood shape"));
diff --git a/src/3dmotioncompica-nonrigid.cc b/src/3dmotioncompica-nonrigid.cc
index 7cc6115..5a1633b 100644
--- a/src/3dmotioncompica-nonrigid.cc
+++ b/src/3dmotioncompica-nonrigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -195,10 +195,10 @@ int do_main( int argc, char *argv[] )
 	
 	options.set_group("File-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i', "input images of consecutively numbered filed (nameXXXX.ext)", 
-			      CCmdOption::required, &image3dio));
+			      CCmdOptionFlags::required_input, &image3dio));
 	options.add(make_opt( registered_filebase, "out-file", 'o', "output image name (as C format string including a %04d "
 			      "in order to define the file numbering)", 
-			      CCmdOption::required, &image3dio));
+			      CCmdOptionFlags::required_output, &image3dio));
 	
 	options.add(make_opt( save_ref_filename, "save-refs", 0, "save reference images, the given string is used as file name base"
 			      ", the number pattern follows the input images, and the output format is always 'vista'")); 
@@ -208,8 +208,7 @@ int do_main( int argc, char *argv[] )
 	options.add(make_opt( save_features, "save-features", 0, "save feature images as PNG")); 
 
 	options.set_group("Registration"); 
-	options.add(make_opt( minimizer, "optimizer", 'O', "Optimizer used for minimization", 
-			      CCmdOption::not_required, &CMinimizerPluginHandler::instance()));
+	options.add(make_opt( minimizer, "optimizer", 'O', "Optimizer used for minimization"));
 	options.add(make_opt( c_rate, "start-c-rate", 'a', 
 			      "start coefficinet rate in spines,"
 			      " gets divided by --c-rate-divider with every pass"));
@@ -220,7 +219,7 @@ int do_main( int argc, char *argv[] )
 			      " --divcurl-divider with every pass")); 
 	options.add(make_opt( divcurlweight_divider, "divcurl-divider", 0,
 			      "divcurl weight scaling with each new pass")); 
-	options.add(make_opt( imagecost, "imagecost", 'w', "image cost", CCmdOption::not_required, &C3DFullCostPluginHandler::instance())); 
+	options.add(make_opt( imagecost, "imagecost", 'w', "image cost")); 
 	options.add(make_opt( mg_levels, "mg-levels", 'l', "multi-resolution levels"));
 	options.add(make_opt( pass, "passes", 'P', "registration passes")); 
 
diff --git a/src/3dmulti-nrreg.cc b/src/3dmulti-nrreg.cc
index acbbd08..02e02aa 100644
--- a/src/3dmulti-nrreg.cc
+++ b/src/3dmulti-nrreg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -59,7 +59,7 @@ int do_main(int argc, char **argv)
 	float epsilon = 0.01;
 
 	options.add(make_opt( out_filename, "out-file", 'o', "output vector field", 
-			      CCmdOption::required));
+			      CCmdOptionFlags::required_output));
 	options.add(make_opt( regmodel, "regmodel", 'm', "registration model"));
 	options.add(make_opt( timestep, "timestep", 't', "time setp"));
 	options.add(make_opt( start_size, "mgsize", 's', "multigrid start size"));
diff --git a/src/3dnonrigidreg-alt.cc b/src/3dnonrigidreg-alt.cc
index afa0bb9..8970882 100644
--- a/src/3dnonrigidreg-alt.cc
+++ b/src/3dnonrigidreg-alt.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -62,7 +62,7 @@ int do_main( int argc, char *argv[] )
 
 	CCmdOptionList options(g_description);
 	options.add(make_opt( trans_filename, "out-transform", 'o', "output transformation", 
-			      CCmdOption::required, &transform3dio));
+			      CCmdOptionFlags::required_output, &transform3dio));
 	options.add(make_opt( mg_levels, "levels", 'l', "multi-resolution levels"));
 	options.add(make_opt( minimizer, "gsl:opt=gd,step=0.1", "optimizer", 'O', "Optimizer used for minimization"));
 	options.add(make_opt( transform_creator, "spline:rate=10", "transForm", 'f', "transformation type"));
diff --git a/src/3dnonrigidreg.cc b/src/3dnonrigidreg.cc
index bf38f38..c4d2df5 100644
--- a/src/3dnonrigidreg.cc
+++ b/src/3dnonrigidreg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -60,13 +60,13 @@ int do_main( int argc, char *argv[] )
 	CCmdOptionList options(g_description);
 	options.set_group("IO"); 
 	options.add(make_opt( src_filename, "in", 'i', "test image", 
-			      CCmdOption::required, &image3dio));
+			      CCmdOptionFlags::required_input, &image3dio));
 	options.add(make_opt( ref_filename, "ref", 'r', "reference image", 
-			      CCmdOption::required, &image3dio));
+			      CCmdOptionFlags::required_input, &image3dio));
 	options.add(make_opt( out_filename, "out", 'o', "registered output image", 
-			      CCmdOption::required, &image3dio));
+			      CCmdOptionFlags::required_output, &image3dio));
 	options.add(make_opt( trans_filename, "trans", 't', "output transformation", 
-			      CCmdOption::not_required, &transform3dio));
+			      CCmdOptionFlags::output, &transform3dio));
 	
 	options.set_group("Registration"); 
 	options.add(make_opt( mg_levels, "levels", 'l', "multi-resolution levels"));
diff --git a/src/3dnrreg.cc b/src/3dnrreg.cc
index aaa7ef9..80750cd 100644
--- a/src/3dnrreg.cc
+++ b/src/3dnrreg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -60,10 +60,10 @@ int do_main(int argc, char **argv)
 
 	const C3DImageCostPluginHandler::Instance&  icph = C3DImageCostPluginHandler::instance();
 
-	options.add(make_opt( src_filename, "in-file", 'i', "input image (floating image)", CCmdOption::required));
-	options.add(make_opt( ref_filename, "ref-file", 'r', "reference image", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output vector field", CCmdOption::required));
-	options.add(make_opt( def_filename, "def-file", 'd', "deformed inpout image"));
+	options.add(make_opt( src_filename, "in-file", 'i', "input image (floating image)", CCmdOptionFlags::required_input));
+	options.add(make_opt( ref_filename, "ref-file", 'r', "reference image", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output vector field", CCmdOptionFlags::required_output));
+	options.add(make_opt( def_filename, "def-file", 'd', "deformed output image", CCmdOptionFlags::output));
 	options.add(make_opt( regmodel, "regmodel", 'm', "registration model"));
 	options.add(make_opt( timestep, "timestep", 't', "time setp"));
 	options.add(make_opt( start_size, "mgsize", 's', "multigrid start size"));
diff --git a/src/3dprealign-nonrigid.cc b/src/3dprealign-nonrigid.cc
index c565bac..5bdea2e 100644
--- a/src/3dprealign-nonrigid.cc
+++ b/src/3dprealign-nonrigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -123,6 +123,8 @@ public:
 		size_t mg_levels; 
 		size_t max_candidates; 
 		bool save_ref; 
+		int global_reference; 
+		size_t max_delta; 
 	};
 
 	C3DMyocardPeriodicRegistration(const RegistrationParams& params); 
@@ -192,15 +194,21 @@ vector<size_t> C3DMyocardPeriodicRegistration::get_prealigned_subset(const C3DIm
 	assert(postskip < images.size()); 
 	assert(preskip < images.size() - postskip); 
 	
-	cvmsg() << "estimate prealigned subset ...\n"; 
-	vector<size_t> candidates = get_high_contrast_candidates(images, preskip, images.size()-2); 
+	vector<size_t> candidates; 
+	if (m_params.global_reference < 0) {
+		cvmsg() << "estimate prealigned subset ...\n"; 
+		candidates = get_high_contrast_candidates(images, preskip, images.size()-2); 
+		assert(!candidates.empty()); 
+	}else
+		candidates.push_back(m_params.global_reference); 
 
-	C3DSimilarityProfile best_series(m_params.series_select_cost, images, candidates[0]); 
+
+	C3DSimilarityProfile best_series(m_params.series_select_cost, images, candidates[0], m_params.max_delta); 
 	m_ref = candidates[0]; 
 
 	// the skip values should be parameters 
 	for (size_t i = 1; i < candidates.size(); ++i) {
-		C3DSimilarityProfile sp(m_params.series_select_cost, images, candidates[i]); 
+		C3DSimilarityProfile sp(m_params.series_select_cost, images, candidates[i], m_params.max_delta); 
 		if (sp.get_peak_frequency() > best_series.get_peak_frequency()) {
 			m_ref = candidates[i]; 
 			best_series = sp; 
@@ -312,14 +320,11 @@ size_t C3DMyocardPeriodicRegistration::get_ref_idx()const
 
 
 C3DMyocardPeriodicRegistration::RegistrationParams::RegistrationParams():
-	minimizer(CMinimizerPluginHandler::instance().produce("gsl:opt=gd,step=0.1")), 
-	pass1_cost(C3DFullCostPluginHandler::instance().produce("image:cost=[ngf:eval=ds]")), 
-	pass2_cost(C3DFullCostPluginHandler::instance().produce("image:cost=ssd")), 
-	series_select_cost(C3DFullCostPluginHandler::instance().produce("image:cost=[ngf:eval=ds]")),
-	transform_creator(C3DTransformCreatorHandler::instance().produce("spline")),
 	mg_levels(3),
 	max_candidates(20), 
-	save_ref(false)
+	save_ref(false), 
+	global_reference(-1), 
+	max_delta(0)
 {
 }
 
@@ -341,10 +346,10 @@ int do_main( int argc, char *argv[] )
 	options.set_group("\nFile-IO");
 	options.add(make_opt( in_filename, "in-file", 'i', 
 			      "input images following the naming pattern nameXXXX.ext", 
-			      CCmdOption::required, &C3DImageIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_input, &C3DImageIOPluginHandler::instance()));
 	options.add(make_opt( registered_filebase, "out-file", 'o', 
 			      "file name base for registered files given as C-format string", 
-			      CCmdOption::required, &C3DImageIOPluginHandler::instance())); 
+			      CCmdOptionFlags::required_output, &C3DImageIOPluginHandler::instance())); 
 	options.add(make_opt(params.save_ref,"save-references", 0, 
 				   "Save synthetic references to files refXXXX.v")); 
 
@@ -365,6 +370,11 @@ int do_main( int argc, char *argv[] )
 			     "Const function to use for the analysis of the series")); 
 	options.add(make_opt(reference_index_file, "ref-idx", 0, 
 			     "save reference index number to this file"));  
+	options.add(make_opt(params.global_reference, "global-reference", 'R', 
+				   "save reference index number to this file")); 
+	options.add(make_opt(params.max_delta, "max-subset-delta", 'D', 
+			     "Maximum delta between two elements of the prealigned subset")); 
+
 
 
 	options.set_group("\nRegistration"); 
diff --git a/src/3drigidreg.cc b/src/3drigidreg.cc
index 0b8fd8c..ef8e272 100644
--- a/src/3drigidreg.cc
+++ b/src/3drigidreg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -62,11 +62,17 @@ int do_main( int argc, char *argv[] )
 	size_t mg_levels = 3;
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_filename, "in", 'i', "test image", CCmdOption::required, &C3DImageIOPluginHandler::instance()));
-	options.add(make_opt( ref_filename, "ref", 'r', "reference image", CCmdOption::required, &C3DImageIOPluginHandler::instance()));
-	options.add(make_opt( out_filename, "out", 'o', "registered output image", CCmdOption::required, &C3DImageIOPluginHandler::instance()));
+	options.set_group("File I/O"); 
+	options.add(make_opt( src_filename, "in", 'i', "test image", 
+			      CCmdOptionFlags::required_input, &C3DImageIOPluginHandler::instance()));
+	options.add(make_opt( ref_filename, "ref", 'r', "reference image", 
+			      CCmdOptionFlags::required_input, &C3DImageIOPluginHandler::instance()));
+	options.add(make_opt( out_filename, "out", 'o', "registered output image", 
+			      CCmdOptionFlags::required_output, &C3DImageIOPluginHandler::instance()));
 	options.add(make_opt( trans_filename, "trans", 't', "transformation output file name", 
-			      CCmdOption::not_required, &C3DTransformationIOPluginHandler::instance() ));
+			      CCmdOptionFlags::output, &C3DTransformationIOPluginHandler::instance() ));
+
+	
 	options.add(make_opt( cost_function, "ssd", "cost", 'c', "cost function")); 
 	options.add(make_opt( mg_levels, "levels", 'l', "multigrid levels"));
 	options.add(make_opt( minimizer, "gsl:opt=simplex,step=1.0", "optimizer", 'O', "Optimizer used for minimization"));
diff --git a/src/3dsegment-ahmed.cc b/src/3dsegment-ahmed.cc
index ece9599..b3bb4d3 100644
--- a/src/3dsegment-ahmed.cc
+++ b/src/3dsegment-ahmed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -443,9 +443,9 @@ int do_main(int argc, char *argv[])
 	const auto& image3dio = C3DImageIOPluginHandler::instance();
 
 	CCmdOptionList opts(g_description);
-	opts.add(make_opt( in_filename, "in-file", 'i', "image to be segmented", CCmdOption::required, &image3dio )); 
+	opts.add(make_opt( in_filename, "in-file", 'i', "image to be segmented", CCmdOptionFlags::required_input, &image3dio )); 
 	opts.add(make_opt( cls_filename, "out-file", 'o', "class probability images, the image type "
-			   "must support multiple images and floating point values", CCmdOption::required, &image3dio )); 
+			   "must support multiple images and floating point values", CCmdOptionFlags::required_output, &image3dio )); 
 	opts.add(make_opt( n_classes, "no-of-classes", 'a', "number of classes"));
 	opts.add(make_opt( bg_correct, "bias-correct", 'b', "apply bias field correction"));
 	opts.add(make_opt( initial_class_centres, "class-centres", 'c', "initial class centers"));
diff --git a/src/3dserial-nonrigid.cc b/src/3dserial-nonrigid.cc
index cd6ab51..1f73f6f 100644
--- a/src/3dserial-nonrigid.cc
+++ b/src/3dserial-nonrigid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -70,8 +70,8 @@ int do_main( int argc, char *argv[] )
 	CCmdOptionList options(g_general_help);
 	
 	options.set_group("\nFile-IO"); 
-	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOption::required));
-	options.add(make_opt( registered_filebase, "out-file", 'o', "file name for registered fiels")); 
+	options.add(make_opt( in_filename, "in-file", 'i', "input perfusion data set", CCmdOptionFlags::required_input));
+	options.add(make_opt( registered_filebase, "out-file", 'o', "file name for registered fiels", CCmdOptionFlags::output)); 
 	
 	
 	options.set_group("\nRegistration"); 
diff --git a/src/3dseries-track-intensity.cc b/src/3dseries-track-intensity.cc
index b676e65..4776bed 100644
--- a/src/3dseries-track-intensity.cc
+++ b/src/3dseries-track-intensity.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -104,7 +104,7 @@ int do_main( int argc, char *argv[] )
 	
 	options.set_group("\nFile-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i', 
-			      "input perfusion data set", CCmdOption::required, &C3DImageIOPluginHandler::instance()));
+			      "input perfusion data set", CCmdOptionFlags::required_input, &C3DImageIOPluginHandler::instance()));
 	options.add(make_opt( out_filename, "out-file", 'o', 
 			      "file name for output intensity slopes")); 
 	
diff --git a/src/3dtrackpixelmovement.cc b/src/3dtrackpixelmovement.cc
index 084d3ee..34e1225 100644
--- a/src/3dtrackpixelmovement.cc
+++ b/src/3dtrackpixelmovement.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -63,13 +63,13 @@ int do_main( int argc, char *argv[] )
 	
 	options.set_group("\nFile-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i', 
-				    "input point set", CCmdOption::required));
+				    "input point set", CCmdOptionFlags::required_input));
 	options.add(make_opt( out_filename, "out-file", 'o', 
-				    "output point set", CCmdOption::required)); 
+				    "output point set", CCmdOptionFlags::required_output)); 
 
 	options.add(make_opt( trans_filename, "transformation", 't', 
 			      "transformation describing the monitored change", 
-			      CCmdOption::required, &C3DTransformationIOPluginHandler::instance())); 
+			      CCmdOptionFlags::required_input, &C3DTransformationIOPluginHandler::instance())); 
 
         options.set_group("\nParameters"); 
         options.add(make_opt( time_step, "time-step", 'T', 
diff --git a/src/3dtransform.cc b/src/3dtransform.cc
index 6e86472..6a596e5 100644
--- a/src/3dtransform.cc
+++ b/src/3dtransform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -59,9 +59,9 @@ int do_main(int argc, char **argv)
 	const auto& imageio = C3DImageIOPluginHandler::instance();
 	const auto& transio = C3DTransformationIOPluginHandler::instance(); 
 
-	options.add(make_opt( src_filename, "in-file", 'i', "input image", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out-file", 'o', "transformed image", CCmdOption::required, &imageio));
-	options.add(make_opt( trans_filename, "transformation", 't', "transformation file", CCmdOption::required, &transio));
+	options.add(make_opt( src_filename, "in-file", 'i', "input image", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out-file", 'o', "transformed image", CCmdOptionFlags::required_output, &imageio));
+	options.add(make_opt( trans_filename, "transformation", 't', "transformation file", CCmdOptionFlags::required_input, &transio));
 	options.add(make_opt( interpolator_kernel, "interpolator", 'p', 
 			      "override the interpolator provided by the transformation"));
 	options.add(make_opt( interpolator_bc, "boundary", 'b', "override the boundary conditions provided "
@@ -76,14 +76,11 @@ int do_main(int argc, char **argv)
 	auto transformation = transio.load(trans_filename);
 	auto source = imageio.load(src_filename);
 
-	if (!source || source->size() < 1) {
-		cerr << "no image found in " << src_filename << "\n";
-		return EXIT_FAILURE;
-	}
+	if (!source || source->size() < 1)
+		throw create_exception<runtime_error>("No image found in '", src_filename, ",");
 
 	if (!transformation) {
-		cerr << "no vector field found in " << trans_filename << "\n";
-		return EXIT_FAILURE;
+		throw create_exception<runtime_error>("No transformation found in '", trans_filename, "'");
 	}
 
 	if (!interpolator_kernel.empty()) { 
diff --git a/src/3dtransform2vf.cc b/src/3dtransform2vf.cc
index 044fad8..b698310 100644
--- a/src/3dtransform2vf.cc
+++ b/src/3dtransform2vf.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -47,9 +47,9 @@ int do_main(int argc, char **argv)
 
 
 	options.add(make_opt( src_filename, "in-file", 'i', "input transformation ", 
-			      CCmdOption::required, &C3DTransformationIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_input, &C3DTransformationIOPluginHandler::instance()));
 	options.add(make_opt( out_filename, "out-file", 'o', "output vector field ", 
-			      CCmdOption::required, &C3DVFIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_output, &C3DVFIOPluginHandler::instance()));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/3dvectorfieldcreate.cc b/src/3dvectorfieldcreate.cc
index 5237d00..d9c7f64 100644
--- a/src/3dvectorfieldcreate.cc
+++ b/src/3dvectorfieldcreate.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -134,7 +134,7 @@ int do_main(int argc, char *argv[])
 	CCmdOptionList options(g_description);
 
 	options.add(make_opt( out_filename, "out-file", 'o', "output file for the vector field", 
-			      CCmdOption::required, &C3DVFIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_output, &C3DVFIOPluginHandler::instance()));
 	options.add(make_opt( Size, "size", 's', "size of the vector field"));
 	options.add(make_opt( fieldtype, "ftype", 'y', "vector field type")); 
 	options.add(make_opt( funfactor, "fun", 'f', "just some parameter to vary the field ;-)")); 
diff --git a/src/3dvf2transform.cc b/src/3dvf2transform.cc
index cd697f3..05de739 100644
--- a/src/3dvf2transform.cc
+++ b/src/3dvf2transform.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -54,9 +54,9 @@ int do_main(int argc, char **argv)
 	PSplineBoundaryCondition image_boundary; 
 
 	options.add(make_opt( src_filename, "in-file", 'i', "input transformation ", 
-			      CCmdOption::required, &C3DVFIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_input, &C3DVFIOPluginHandler::instance()));
 	options.add(make_opt( out_filename, "out-file", 'o', "output vector field ", 
-			      CCmdOption::required, &C3DTransformationIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_output, &C3DTransformationIOPluginHandler::instance()));
 
 	options.add(make_opt( image_interpolator, "bspline:d=3", "imgkernel", 'k', "image interpolator kernel which is "
 			      "used when the transformation is applied to an image"));
diff --git a/src/3dvfcompare.cc b/src/3dvfcompare.cc
index 7f682a8..4ce93a0 100644
--- a/src/3dvfcompare.cc
+++ b/src/3dvfcompare.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -45,8 +45,8 @@ int do_main(int argc, char **argv)
 
 	const auto& vfio =C3DVFIOPluginHandler::instance(); 
 
-	options.add(make_opt( vf1_filename, "in-file-1", '1', "input vector field 1", CCmdOption::required, &vfio));
-	options.add(make_opt( vf2_filename, "in-file-2", '2', "input vector field 2", CCmdOption::required, &vfio));
+	options.add(make_opt( vf1_filename, "in-file-1", '1', "input vector field 1", CCmdOptionFlags::required_input, &vfio));
+	options.add(make_opt( vf2_filename, "in-file-2", '2', "input vector field 2", CCmdOptionFlags::required_input, &vfio));
 	options.add(make_opt( delta, "delta", 'd', "Maximum difference between vector to be ignored"));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 586749b..056743e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -59,6 +59,7 @@ DEFEXE(2dmultiimagevar    mia2d )
 DEFEXE(2dimagefullstats   mia2d )
 DEFEXE(2dbinarycombine    mia2d )
 DEFEXE(2dtransformation-to-strain mia2d)
+DEFEXE(2dimageseries-maximum-intensity-projection mia2d) 
 
 DEFCHKEXE(2dlerp mia2d )
 
@@ -83,6 +84,7 @@ DEFEXE(2dgroundtruthreg       mia2dmyocardperf )
 DEFEXE(2dseries2sets          mia2dmyocardperf )
 DEFEXE(2dseries-segdistance   mia2dmyocardperf )
 DEFEXE(2dseries-mincorr       mia2dmyocardperf )
+
 DEFEXE(2dseries-sectionmask   mia2dmyocardperf )
 DEFEXE(2dmyoseries-dice       mia2dmyocardperf )
 DEFEXE(2dmyoseries-compdice   mia2dmyocardperf )
@@ -91,6 +93,8 @@ DEFEXE(2dmyopgt-nonrigid      mia2dmyocardperf )
 DEFEXE(2dmany2one-nonrigid    mia2dmyocardperf )
 DEFEXE(2dmyoset-all2one-nonrigid    mia2dmyocardperf )
 IF(ITPP_FOUND) 
+  DEFEXE(2dmyoica-full      mia2dmyocardperf )
+  DEFEXE(2dmyoicapgt        mia2dmyocardperf )
   DEFEXE(2dmyomilles            mia2dmyocardperf )
   DEFEXE(2dmyocard-ica          mia2dmyocardperf )
   DEFEXE(2dmyocard-icaseries    mia2dmyocardperf )
@@ -133,7 +137,8 @@ DEFEXE(3dmaskseeded       mia3d )
 DEFEXE(3dfield2norm       mia3d )
 DEFEXE(3dimageselect      mia3d )
 DEFEXE(3dbrainextractT1   mia3d )
-DEFEXE(3dbinarycombine   mia3d )
+DEFEXE(3dbinarycombine    mia3d )
+DEFEXE(3ddistance-stats   mia3d )
 DEFEXE(3dimageaddattributes  mia3d )
 DEFEXE(3dvectorfieldcreate  mia3d )
 DEFEXE(3dserial-nonrigid  mia3d )
diff --git a/src/cmeans.cc b/src/cmeans.cc
index b18dfac..02851d8 100644
--- a/src/cmeans.cc
+++ b/src/cmeans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -350,7 +350,7 @@ void test(double k, bool auto_k)
 		eval_class_centers[i] = i * cstep;
 	
 	
-	CCMeans cmeans(k, false, 0.00001);
+	CCMeans cmeans(k, 0.00001, false);
 	CProbabilityVector eval_pv = cmeans(histogram, eval_class_centers, false, auto_k);
 	for (size_t i = 0; i < Nc; ++i) {
 		if (fabs(eval_class_centers[i] - Nh * class_centers[i]) > 0.5) {
@@ -377,8 +377,10 @@ int do_main(int argc, char *argv[])
 
 	CCmdOptionList options(g_description);
 
-	options.add(make_opt( in_filename, "in-file", 'i', "input file name containing the histogram", CCmdOption::required)); 
-	options.add(make_opt( out_filename, "out-file", 'o', "output file name to store probabilities", CCmdOption::required)); 
+	options.add(make_opt( in_filename, "in-file", 'i', "input file name containing the histogram", 
+			      CCmdOptionFlags::required_input)); 
+	options.add(make_opt( out_filename, "out-file", 'o', "output file name to store probabilities", 
+			      CCmdOptionFlags::required_output)); 
 	
 	options.add(make_opt( nclasses, "nclasses", 'n', "number of classes to partition into")); 
 	options.add(make_opt( max_iter, "max-iter", 'm', "maximum number of iterations")); 
@@ -426,7 +428,7 @@ int do_main(int argc, char *argv[])
 		initialise = true; 
 	}
 		
-	CCMeans cmeans(k, even_start, epsilon); 
+	CCMeans cmeans(k, epsilon, even_start); 
 			
 	CProbabilityVector pv = cmeans(histo, class_centers, initialise, auto_k); 
 		
diff --git a/src/distance-mesh2mask.cc b/src/distance-mesh2mask.cc
index 8d67571..dd5d29b 100644
--- a/src/distance-mesh2mask.cc
+++ b/src/distance-mesh2mask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -85,9 +85,9 @@ int do_main( int argc, char *argv[] )
 	const auto& imageio = C2DImageIOPluginHandler::instance(); 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_filename, "in-mesh", 'i', "input mesh", CCmdOption::required, &meshio));
-	options.add(make_opt( ref_filename, "ref-mask", 'r', "reference binary mask", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out-mesh", 'o', "output mesh", CCmdOption::required, &meshio));
+	options.add(make_opt( src_filename, "in-mesh", 'i', "input mesh", CCmdOptionFlags::required_input, &meshio));
+	options.add(make_opt( ref_filename, "ref-mask", 'r', "reference binary mask", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out-mesh", 'o', "output mesh", CCmdOptionFlags::required_output, &meshio));
 	
 	
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/filenumberpattern.cc b/src/filenumberpattern.cc
index 7cbec02..8bd5501 100644
--- a/src/filenumberpattern.cc
+++ b/src/filenumberpattern.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -47,7 +47,8 @@ int do_main( int argc, char *argv[] )
 {
 	string in_filename;
 	CCmdOptionList options(g_description);
-	options.add(make_opt( in_filename, "in-file", 'i', "input image example name", CCmdOption::required));
+	options.add(make_opt( in_filename, "in-file", 'i', "input image example name", 
+			      CCmdOptionFlags::required_input));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/fluid2d/CMakeLists.txt b/src/fluid2d/CMakeLists.txt
index 03e5aca..25d2213 100644
--- a/src/fluid2d/CMakeLists.txt
+++ b/src/fluid2d/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/src/fluid2d/NR2DMatrix.hh b/src/fluid2d/NR2DMatrix.hh
index a6cc8e1..f39cab8 100644
--- a/src/fluid2d/NR2DMatrix.hh
+++ b/src/fluid2d/NR2DMatrix.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid2d/Pixel.hh b/src/fluid2d/Pixel.hh
index 4e7c1d3..007e031 100644
--- a/src/fluid2d/Pixel.hh
+++ b/src/fluid2d/Pixel.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid2d/elast.cc b/src/fluid2d/elast.cc
index b2fac61..382ba60 100644
--- a/src/fluid2d/elast.cc
+++ b/src/fluid2d/elast.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid2d/elast.hh b/src/fluid2d/elast.hh
index 2510760..793f1e5 100644
--- a/src/fluid2d/elast.hh
+++ b/src/fluid2d/elast.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid2d/helpers.cc b/src/fluid2d/helpers.cc
index afc0c03..5e1ac7a 100644
--- a/src/fluid2d/helpers.cc
+++ b/src/fluid2d/helpers.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid2d/helpers.hh b/src/fluid2d/helpers.hh
index e1b64af..b1bd0c8 100644
--- a/src/fluid2d/helpers.hh
+++ b/src/fluid2d/helpers.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid2d/main.cc b/src/fluid2d/main.cc
index d0d1b15..98f9c63 100644
--- a/src/fluid2d/main.cc
+++ b/src/fluid2d/main.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -111,13 +111,13 @@ int do_main(int argc, char *argv[])
 	
 	options.set_group("File-IO"); 
 	options.add(make_opt( src_filename, "in-image", 'i', "input (model) image to be registered", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( ref_filename, "ref-image", 'r', "reference image", 
-			      CCmdOption::required, &imageio));
+			      CCmdOptionFlags::required_input, &imageio));
 	options.add(make_opt( out_filename, "out", 'o', "output vector field", 
-			      CCmdOption::not_required, &C2DVFIOPluginHandler::instance()));
+			      CCmdOptionFlags::output, &C2DVFIOPluginHandler::instance()));
 	options.add(make_opt( def_filename, "deformed-image", 'd', "deformed registered image", 
-			      CCmdOption::not_required, &imageio));
+			      CCmdOptionFlags::output, &imageio));
 
 	options.set_group("Registration parameters"); 
 	options.add(make_opt( grid_start, "mgstart", 'm', "multigrid start size"));
@@ -128,7 +128,9 @@ int do_main(int argc, char *argv[])
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
-
+	if (out_filename.empty() && def_filename.empty()) {
+		throw invalid_argument("At least one output file must be given"); 
+	}
 
 
 	P2DImage Model = load_image<P2DImage>(src_filename);
diff --git a/src/fluid2d/types.hh b/src/fluid2d/types.hh
index 566ff63..c4e5784 100644
--- a/src/fluid2d/types.hh
+++ b/src/fluid2d/types.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid2d/vfluid.cc b/src/fluid2d/vfluid.cc
index c334874..f5af17e 100644
--- a/src/fluid2d/vfluid.cc
+++ b/src/fluid2d/vfluid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid2d/vfluid.hh b/src/fluid2d/vfluid.hh
index bec4e05..52f828f 100644
--- a/src/fluid2d/vfluid.hh
+++ b/src/fluid2d/vfluid.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid3d/CMakeLists.txt b/src/fluid3d/CMakeLists.txt
index a55e246..05858b7 100644
--- a/src/fluid3d/CMakeLists.txt
+++ b/src/fluid3d/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/src/fluid3d/eqn_solver.cc b/src/fluid3d/eqn_solver.cc
index bbc4889..10a239e 100644
--- a/src/fluid3d/eqn_solver.cc
+++ b/src/fluid3d/eqn_solver.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid3d/eqn_solver.hh b/src/fluid3d/eqn_solver.hh
index 2078575..22c8968 100644
--- a/src/fluid3d/eqn_solver.hh
+++ b/src/fluid3d/eqn_solver.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid3d/main.cc b/src/fluid3d/main.cc
index 23c3dda..fcd587e 100644
--- a/src/fluid3d/main.cc
+++ b/src/fluid3d/main.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -120,13 +120,13 @@ int do_main(int argc, char *argv[])
 	const auto& imageio = C3DImageIOPluginHandler::instance();
 
 	options.set_group("File-IO"); 
-	options.add(make_opt( in_filename, "in-image", 'i', "input image", CCmdOption::required, &imageio ));
-	options.add(make_opt( ref_filename, "ref-image", 'r', "reference image ", CCmdOption::required, &imageio ));
+	options.add(make_opt( in_filename, "in-image", 'i', "input image", CCmdOptionFlags::required_input, &imageio ));
+	options.add(make_opt( ref_filename, "ref-image", 'r', "reference image ", CCmdOptionFlags::required_input, &imageio ));
 	options.add(make_opt( out_filename, "out-deformation", 'o', "output vector field", 
-			      CCmdOption::required, &C3DTransformationIOPluginHandler::instance()));
+			      CCmdOptionFlags::required_output, &C3DTransformationIOPluginHandler::instance()));
 
 	options.add(make_opt(deformed_filename, "deformed-image", 'd', "save deformed image", 
-			     CCmdOption::not_required, &imageio)); 
+			     CCmdOptionFlags::output, &imageio)); 
 
 
 	options.set_group("Registration parameters"); 
diff --git a/src/fluid3d/sor_solver.cc b/src/fluid3d/sor_solver.cc
index 9852017..d3a696c 100644
--- a/src/fluid3d/sor_solver.cc
+++ b/src/fluid3d/sor_solver.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid3d/sor_solver.hh b/src/fluid3d/sor_solver.hh
index a805eef..79890c4 100644
--- a/src/fluid3d/sor_solver.hh
+++ b/src/fluid3d/sor_solver.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid3d/typedefs.hh b/src/fluid3d/typedefs.hh
index f304fcb..7c6b8ae 100644
--- a/src/fluid3d/typedefs.hh
+++ b/src/fluid3d/typedefs.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid3d/vfluid.cc b/src/fluid3d/vfluid.cc
index f1dfff3..6ad1a15 100644
--- a/src/fluid3d/vfluid.cc
+++ b/src/fluid3d/vfluid.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/fluid3d/vfluid.hh b/src/fluid3d/vfluid.hh
index 397f630..8260997 100644
--- a/src/fluid3d/vfluid.hh
+++ b/src/fluid3d/vfluid.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/isosurface/CMakeLists.txt b/src/isosurface/CMakeLists.txt
index f65da45..0b93b38 100644
--- a/src/isosurface/CMakeLists.txt
+++ b/src/isosurface/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/src/isosurface/iso.cc b/src/isosurface/iso.cc
index b7adeef..6f32185 100644
--- a/src/isosurface/iso.cc
+++ b/src/isosurface/iso.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -72,8 +72,8 @@ int do_main (int argc, char * argv[])
 
 	CCmdOptionList options(g_description);
 	options.set_group("File-IO"); 
-	options.add(make_opt(  in_filename, "in-image", 'i', "input image", CCmdOption::required, &imageio )); 
-	options.add(make_opt(  out_filename, "out-image", 'o', "output mesh", CCmdOption::required, &meshio )); 
+	options.add(make_opt(  in_filename, "in-image", 'i', "input image", CCmdOptionFlags::required_input, &imageio )); 
+	options.add(make_opt(  out_filename, "out-image", 'o', "output mesh", CCmdOptionFlags::required_output, &meshio )); 
 
 	options.set_group("Image options"); 
 	options.add(make_opt(  iso_value, "iso-value", 's', "iso-value of iso surface to be extracted")); 
diff --git a/src/isosurface/iso_backend.cc b/src/isosurface/iso_backend.cc
index e375a3d..596a221 100644
--- a/src/isosurface/iso_backend.cc
+++ b/src/isosurface/iso_backend.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/isosurface/iso_from_slices.cc b/src/isosurface/iso_from_slices.cc
index 3734495..6732d07 100644
--- a/src/isosurface/iso_from_slices.cc
+++ b/src/isosurface/iso_from_slices.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -71,8 +71,8 @@ int do_main (int argc, char * argv[])
 
 	CCmdOptionList options(g_description);
 	options.set_group("File-IO"); 
-	options.add(make_opt(  in_filename, "in-image", 'i', "input image filename pattern", CCmdOption::required )); 
-	options.add(make_opt(  out_filename, "out-mesh", 'o', "output mesh", CCmdOption::required )); 
+	options.add(make_opt(  in_filename, "in-image", 'i', "input image filename pattern", CCmdOptionFlags::required_input )); 
+	options.add(make_opt(  out_filename, "out-mesh", 'o', "output mesh", CCmdOptionFlags::required_output )); 
 
 	options.set_group("Image options"); 
 	options.add(make_opt(  iso_value, "iso-value", 's', "iso-value of iso surface to be extracted")); 
diff --git a/src/isosurface/mesh_convert.cc b/src/isosurface/mesh_convert.cc
index f6e99cd..1957c37 100644
--- a/src/isosurface/mesh_convert.cc
+++ b/src/isosurface/mesh_convert.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/src/labelsort.cc b/src/labelsort.cc
index 9e3fa4e..706785d 100644
--- a/src/labelsort.cc
+++ b/src/labelsort.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -60,9 +60,9 @@ int do_main(int argc, char *argv[])
 	CCmdOptionList options(g_description);
 
 	options.add(make_opt( in_filename, "in-file", 'i', "input file name containing the histogram", 
-			      CCmdOption::required)); 
+			      CCmdOptionFlags::required_input)); 
 	options.add(make_opt( out_filename, "out-file", 'o', "output file name to store probabilities", 
-			      CCmdOption::required)); 
+			      CCmdOptionFlags::required_output)); 
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/meshdistance-to-stackmask.cc b/src/meshdistance-to-stackmask.cc
index 0bf580f..420d9f4 100644
--- a/src/meshdistance-to-stackmask.cc
+++ b/src/meshdistance-to-stackmask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -94,9 +94,9 @@ int do_main( int argc, char *argv[] )
 	const auto& imageio = C2DImageIOPluginHandler::instance(); 
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( src_filename, "in-mesh", 'i', "input mesh", CCmdOption::required, &meshio));
-	options.add(make_opt( ref_filename, "ref-mask", 'r', "reference binary mask", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out-mesh", 'o', "output mesh", CCmdOption::required, &meshio));
+	options.add(make_opt( src_filename, "in-mesh", 'i', "input mesh", CCmdOptionFlags::required_input, &meshio));
+	options.add(make_opt( ref_filename, "ref-mask", 'r', "reference binary mask", CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out-mesh", 'o', "output mesh", CCmdOptionFlags::required_output, &meshio));
 	
 	
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/meshfilter.cc b/src/meshfilter.cc
index dc26788..0dfb532 100644
--- a/src/meshfilter.cc
+++ b/src/meshfilter.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -49,8 +49,8 @@ int do_main( int argc, char *argv[] )
 	const auto& meshio = CMeshIOPluginHandler::instance(); 
 
 	CCmdOptionList options(g_general_help);
-	options.add(make_opt( in_filename, "in-file", 'i', "input mesh to be filtered", CCmdOption::required, &meshio));
-	options.add(make_opt( out_filename, "out-file", 'o', "output mesh that have been filtered", CCmdOption::required, &meshio));
+	options.add(make_opt( in_filename, "in-file", 'i', "input mesh to be filtered", CCmdOptionFlags::required_input, &meshio));
+	options.add(make_opt( out_filename, "out-file", 'o', "output mesh that have been filtered", CCmdOptionFlags::required_output, &meshio));
 	options.set_group(g_help_optiongroup); 
 	options.add(make_help_opt( "help-filters", 0,
 				   "give some help about the filter plugins", 
diff --git a/src/multihist.cc b/src/multihist.cc
index 1786b57..32b406c 100644
--- a/src/multihist.cc
+++ b/src/multihist.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -113,8 +113,10 @@ int do_main( int argc, char *argv[] )
 	const C2DImageIOPluginHandler::Instance& imageio = C2DImageIOPluginHandler::instance();
 
 	CCmdOptionList options(g_description);
-	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", CCmdOption::required, &imageio));
-	options.add(make_opt( out_filename, "out", 'o', "output file name", CCmdOption::required));
+	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", 
+			      CCmdOptionFlags::required_input, &imageio));
+	options.add(make_opt( out_filename, "out", 'o', "output file name", 
+			      CCmdOptionFlags::required_output));
 	options.add(make_opt( hmin, "min", 0, "minimum of histogram range"));
 	options.add(make_opt( hmax, "max", 0, "maximum of histogram range"));
 	options.add(make_opt( bins, "bins", 0, "number of histogram bins"));
diff --git a/src/myowavelettest.cc b/src/myowavelettest.cc
index 1a61302..d31dbce 100644
--- a/src/myowavelettest.cc
+++ b/src/myowavelettest.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -65,7 +65,8 @@ int do_main( int argc, char *argv[] )
 
 
 	options.set_group("File-IO"); 
-	options.add(make_opt( in_filename, "in-file", 'i', "input data set", CCmdOption::required));
+	options.add(make_opt( in_filename, "in-file", 'i', "input data set", 
+			      CCmdOptionFlags::required_input));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no) 
 		return EXIT_SUCCESS; 
@@ -111,7 +112,7 @@ int do_main( int argc, char *argv[] )
 			      , i , " has " , table[i].size() , " rows"); 
 		}
 
-	CWaveletSlopeClassifier classifier(table, false);
+	CWaveletSlopeClassifier classifier(table, false, -1);
 	
 	switch (classifier.result()) {
 	case CWaveletSlopeClassifier::wsc_fail: 
diff --git a/src/plugin-help.cc b/src/plugin-help.cc
index b519980..70d28da 100644
--- a/src/plugin-help.cc
+++ b/src/plugin-help.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -56,6 +56,7 @@ map<string, const CPluginHandlerBase*> collect_handlers()
 	ADD(C2DImageCostPluginHandler::instance);
 	ADD(C2DImageCreatorPluginHandler::instance);
 	ADD(C2DImageIOPluginHandler::instance);
+	ADD(C2DMaskedImageCostPluginHandler::instance);
 	ADD(C2DRegModelPluginHandler::instance);
 	ADD(C2DShapePluginHandler::instance);
 	ADD(C2DStackDistanceTransformIOPluginHandler::instance);
@@ -69,12 +70,14 @@ map<string, const CPluginHandlerBase*> collect_handlers()
 	ADD(C3DImageCostPluginHandler::instance);
 	ADD(C3DImageCreatorPluginHandler::instance);
 	ADD(C3DImageIOPluginHandler::instance);
+	ADD(C3DMaskedImageCostPluginHandler::instance);
 	ADD(C3DRegModelPluginHandler::instance);
 	ADD(C2DRegTimeStepPluginHandler::instance);
 	ADD(C3DRegTimeStepPluginHandler::instance);
 	ADD(C3DShapePluginHandler::instance);
 	ADD(C3DTransformationIOPluginHandler::instance);
 	ADD(C3DTransformCreatorHandler::instance);
+	ADD(C3DSplineTransformPenaltyPluginHandler::instance);
 	ADD(C3DVFIOPluginHandler::instance);
 	ADD(CCST2DImgKernelPluginHandler::instance);
 	ADD(CCST2DVectorKernelPluginHandler::instance);
diff --git a/src/raw2image.cc b/src/raw2image.cc
index ad19caa..15563a3 100644
--- a/src/raw2image.cc
+++ b/src/raw2image.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -180,12 +180,12 @@ int do_main(int argc, char *argv[])
 
 	CCmdOptionList options(g_description);
 
-	options.add(make_opt( in_filename, "in-file", 'i', "input file name", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOption::required, &imageio));
+	options.add(make_opt( in_filename, "in-file", 'i', "input file name", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( pixel_type, CPixelTypeDict, "repn", 'r',"input pixel type "));
 	options.add(make_opt( high_endian, "big-endian", 'b', "input data is big endian"));
 	options.add(make_opt( scale, "scale", 'f', "scale of input pixels <FX,FY>"));
-	options.add(make_opt( size, "size", 's', "size of input <NX,NY>", CCmdOption::required));
+	options.add(make_opt( size, "size", 's', "size of input <NX,NY>", CCmdOptionFlags::required));
 	options.add(make_opt( skip, "skip", 'k', "skip number of bytes from beginning of file"));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
diff --git a/src/raw2volume.cc b/src/raw2volume.cc
index 337c1d8..9a0b1ff 100644
--- a/src/raw2volume.cc
+++ b/src/raw2volume.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -160,13 +160,13 @@ int do_main(int argc, char *argv[])
 
 	CCmdOptionList options(g_description);
 
-	options.add(make_opt( in_filename, "in-file", 'i', "input file name", CCmdOption::required));
-	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOption::required, &imageio));
+	options.add(make_opt( in_filename, "in-file", 'i', "input file name", CCmdOptionFlags::required_input));
+	options.add(make_opt( out_filename, "out-file", 'o', "output file name", CCmdOptionFlags::required_output, &imageio));
 	options.add(make_opt( pixel_type, CPixelTypeDict, "repn", 'r',"input pixel type "));
 	options.add(make_opt( high_endian, "big-endian", 'b', "input data is big endian"));
 	options.add(make_opt( scale, "scale", 'f', "scale of input voxels <FX,FY,FZ>"));
 	options.add(make_opt( skip, "skip", 'k', "skip number of bytes from beginning of file"));
-	options.add(make_opt( size, "size", 's', "size of input <NX,NY,NZ>", CCmdOption::required));
+	options.add(make_opt( size, "size", 's', "size of input <NX,NY,NZ>", CCmdOptionFlags::required));
 
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
diff --git a/src/test_plugins_as_installed.cc b/src/test_plugins_as_installed.cc
index d75b6a4..af1275e 100644
--- a/src/test_plugins_as_installed.cc
+++ b/src/test_plugins_as_installed.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,33 +35,34 @@ struct PluginTestFixture {
 
 BOOST_FIXTURE_TEST_CASE(test_C3DFullCostPluginHandler,PluginTestFixture) 
 { 
-	set<string> test_data = { "divcurl", "image", "taggedssd"}; 
+	set<string> test_data = { "image", "maskedimage", "taggedssd"}; 
 
 	test(C3DFullCostPluginHandler::instance().get_set(), test_data); 
 }
 
 BOOST_FIXTURE_TEST_CASE(test_C3DImageCostPluginHandler,PluginTestFixture) 
 { 
-	set<string> test_data = { "ngf", "mi", "ssd"};
+	set<string> test_data = { "lncc", "ncc", "ngf", "mi", "ssd", "ssd-automask"};
 	test(C3DImageCostPluginHandler::instance().get_set(), test_data); 
 }
 
 BOOST_FIXTURE_TEST_CASE(test_C3DFilterPluginHandler,PluginTestFixture) 
 {
 	set<string> test_data = {
-		"binarize", "bandpass", "convert","close", "crop", "dilate", "downscale", 
+		"binarize", "bandpass", "combiner", "convert","close", "crop", "dilate", "distance", "downscale", 
 		"erode", "gauss", "gradnorm", "growmask", "invert", "isovoxel", "kmeans",  
-		"label", "load", "mask", "median", "mlv", "open",  "reorient", "resize",
+		"label", "load", "lvdownscale", "mask", "mean", "median", "mlv", "msnormalizer", "open",  "resize",
 		"sandp", "scale", "selectbig", "sepconv", "sws", "tee", "thinning", 
-		"transform", "ws" 
+		"transform", "variance", "ws" 
 	}; 
+	
 	test(C3DFilterPluginHandler::instance().get_set(), test_data); 
 }
 
 BOOST_FIXTURE_TEST_CASE(test_C3DImageCombinerPluginHandler,PluginTestFixture) 
 {
 	set<string> test_data = {
-		"labelxmap", "absdiff", "add", "sub", "mul", "div"
+	        "absdiff", "add", "sub", "mul", "div"
 	}; 
 	test(C3DImageCombinerPluginHandler::instance().get_set(), test_data); 
 }
@@ -71,6 +72,7 @@ BOOST_FIXTURE_TEST_CASE(test_C3DImageIOPluginHandler,PluginTestFixture)
 	set<string> test_data = {
 		"analyze",  
 		"inria", 
+		"hdf5", 
 		"mhd", 
 		"vff", 
 		"vti", 
@@ -101,7 +103,7 @@ BOOST_FIXTURE_TEST_CASE(test_C3DImageCreatorPluginHandler,PluginTestFixture)
 BOOST_FIXTURE_TEST_CASE(test_C3DTransformCreatorHandler,PluginTestFixture) 
 {
 	set<string> test_data = { 
-		"affine", "rigid", "spline", "translate", "rotation", "vf"
+		"affine", "axisrot", "raffine", "rigid", "spline", "translate", "rotation", "vf"
 	}; 
 	test(C3DTransformCreatorHandler::instance().get_set(), test_data); 
 }
@@ -175,7 +177,7 @@ BOOST_FIXTURE_TEST_CASE(test_CMeshIOPluginHandler,PluginTestFixture)
 BOOST_FIXTURE_TEST_CASE(test_CMinimizerPluginHandler,PluginTestFixture) 
 {
 	set<string> test_data = {
-		"gsl", "gdsq", "nlopt"
+		"gdas", "gsl", "gdsq", "nlopt"
 	}; 
 	test(CMinimizerPluginHandler::instance().get_set(), test_data); 
 }
@@ -215,7 +217,7 @@ BOOST_FIXTURE_TEST_CASE(test_C2DVFIOPluginHandler,PluginTestFixture)
 BOOST_FIXTURE_TEST_CASE(test_C2DFullCostPluginHandler,PluginTestFixture) 
 {
 	set<string> test_data = {
-		"image", "divcurl"
+		"image", "maskedimage"
 	}; 
 	
 	test(C2DFullCostPluginHandler::instance().get_set(), test_data); 
@@ -224,7 +226,7 @@ BOOST_FIXTURE_TEST_CASE(test_C2DFullCostPluginHandler,PluginTestFixture)
 BOOST_FIXTURE_TEST_CASE(test_C2DImageCostPluginHandler,PluginTestFixture) 
 {
 	set<string> test_data =  {
-		"lsd", "ssd", "mi", "ngf"
+		"lncc", "ncc", "lsd", "ssd", "mi", "ngf", "ssd-automask"
 	}; 
 	test(C2DImageCostPluginHandler::instance().get_set(), test_data); 
 }
@@ -255,7 +257,7 @@ BOOST_FIXTURE_TEST_CASE(test_C2DShapePluginHandler,PluginTestFixture)
 BOOST_FIXTURE_TEST_CASE(test_C2DFilterPluginHandler,PluginTestFixture) 
 {
 	set<string> test_data = {
-		"adaptmed", "admean", "aniso", "bandpass", "binarize", 
+		"adaptmed", "admean", "aniso", "bandpass", "binarize", "combiner",
 		"convert", "close", "crop", "dilate", "distance", 
 		"downscale", "erode", "gauss", "gradnorm", "invert", "kmeans", 
 		"label", "labelmap", "load", "mask", "mean", "median", "mlv", 
diff --git a/src/wavelettrans.cc b/src/wavelettrans.cc
index 13bb5f6..c1832b2 100644
--- a/src/wavelettrans.cc
+++ b/src/wavelettrans.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -107,12 +107,14 @@ int do_main( int argc, char *argv[] )
 
 	options.set_group("File-IO"); 
 	options.add(make_opt( in_filename, "in-file", 'i', 
-				    "input data set", CCmdOption::required));
+			      "input data set", CCmdOptionFlags::required_input));
 	options.add(make_opt( out_filename, "out-file", 'o', 
-			      "output data set", CCmdOption::required));
-
+			      "output data set", CCmdOptionFlags::required_output));
+	
 	options.add(make_opt(out2_filenamebase, "save-wave", 's', 
-			     "base name of the output files that will store the wavelet coefficients as matrix")); 
+			     "base name of the output files that will store the wavelet coefficients as matrix", 
+			     CCmdOptionFlags::output
+			    )); 
 
 	options.set_group("Wavelet"); 
 	options.add(make_opt( wt_type, g_wavelet_dict, "wavelet", 'w', "wavelet to be used"));
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 10ddc94..78a2616 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/test/test_ioplugins.cc b/test/test_ioplugins.cc
index a8e53ba..8d107c9 100644
--- a/test/test_ioplugins.cc
+++ b/test/test_ioplugins.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,7 +29,6 @@
 
 using namespace std; 
 using namespace mia; 
-PrepareTestPluginPath g_prepare_pluginpath; 
 
 
 template <typename Handler> 
@@ -203,7 +202,7 @@ void PluginMapFixture<Handler>::test_suffix_from_name_or_suffix(const Expectmap&
 	const auto& io = Handler::instance(); 
 	for_each(map.begin(), map.end(), 
 		[&io](const pair<string, string>& p) {
-			 cvdebug() << "Test '" << p.first << "\n"; 
+			 cvdebug() << "Test '" << p.first << "'\n"; 
 			 BOOST_CHECK_EQUAL(io.get_preferred_suffix(p.first), p.second); 
 		 });
 
diff --git a/test/test_minimizer.cc b/test/test_minimizer.cc
index 3a896ce..a7d14b5 100644
--- a/test/test_minimizer.cc
+++ b/test/test_minimizer.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,9 +35,6 @@ using namespace mia;
 using namespace boost;
 namespace bfs=::boost::filesystem; 
 
-PrepareTestPluginPath g_prepare_pluginpath; 
-
-
 void compare_sets(const set< string >& plugins, const set<string>& test_data)
 {
 	BOOST_CHECK_EQUAL(plugins.size(), test_data.size()); 
@@ -73,7 +70,7 @@ const char *minimizer_property = "CMinimizerMock";
 BOOST_AUTO_TEST_CASE( test_load_minimizer_plugins )	
 {
 
-	set<string> test_data = { "gdsq", "gsl"};
+	set<string> test_data = { "gdsq", "gsl", "gdas"};
 
 #ifdef HAVE_NLOPT
        test_data.insert("nlopt"); 
diff --git a/testdata/CMakeLists.txt b/testdata/CMakeLists.txt
index 00b2d6d..1560b8a 100644
--- a/testdata/CMakeLists.txt
+++ b/testdata/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2013 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # MIA is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/testhelpers/3d-mean-variance-test.ods b/testhelpers/3d-mean-variance-test.ods
new file mode 100644
index 0000000..23d9570
Binary files /dev/null and b/testhelpers/3d-mean-variance-test.ods differ
diff --git a/testhelpers/test_lncc.ods b/testhelpers/test_lncc.ods
new file mode 100644
index 0000000..0f33366
Binary files /dev/null and b/testhelpers/test_lncc.ods differ

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/mia.git



More information about the debian-med-commit mailing list