[med-svn] [mia] 01/06: Imported Upstream version 2.4.1

Gert Wollny gert-guest at moszumanska.debian.org
Sat Jul 23 14:52:56 UTC 2016


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

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

commit 397384e1d2847deefe57e8681149207204d0a239
Author: Gert Wollny <gw.fossdev at gmail.com>
Date:   Sat Jul 23 14:23:24 2016 +0000

    Imported Upstream version 2.4.1
---
 .travis.yml                                        |  38 ++
 CMakeLists.txt                                     | 114 ++--
 ChangeLog                                          |  56 +-
 README.md                                          |   5 +
 addons/dicom/CMakeLists.txt                        |   2 +
 addons/dicom/dcm2d.cc                              |   8 +-
 addons/dicom/dcm2d.hh                              |   2 +-
 addons/dicom/dcm3d.cc                              |  12 +-
 addons/dicom/dcm3d.hh                              |   2 +-
 addons/dicom/dicom4mia.cc                          | 119 ++--
 addons/dicom/dicom4mia.hh                          |   2 +-
 addons/dicom/getset.hh                             |   2 +-
 addons/dicom/test_dcm2d.cc                         |   9 +-
 addons/dicom/test_dcm3d.cc                         |   6 +-
 addons/dicom/test_dicom4mia.cc                     |  20 +-
 addons/hdf5/CMakeLists.txt                         |  11 +-
 addons/hdf5/hdf5_3dimage.cc                        |   6 +-
 addons/hdf5/hdf5_3dimage.hh                        |   2 +-
 addons/hdf5/hdf5a_mia.cc                           |   2 +-
 addons/hdf5/hdf5a_mia.hh                           |   2 +-
 addons/hdf5/hdf5mia.cc                             |   2 +-
 addons/hdf5/hdf5mia.hh                             |  31 +-
 addons/hdf5/test_hdf5_3dimage.cc                   |   3 +-
 addons/hdf5/test_hdf5mia.cc                        |  40 +-
 addons/jpg/CMakeLists.txt                          |   4 +-
 addons/jpg/jpeg-common.hh                          |   2 +-
 addons/jpg/jpg-gray.cc                             |  12 +-
 addons/jpg/jpg-rgb.cc                              |  33 +-
 addons/jpg/test_jpg.cc                             | 159 +++++
 addons/maxflow/2dmaxflow.cc                        |   2 +-
 addons/maxflow/2dmaxflow.hh                        |   2 +-
 addons/maxflow/test_2dmaxflow.cc                   |   2 +-
 addons/nifti/CMakeLists.txt                        |  11 +-
 addons/nifti/niftiimage.cc                         | 283 +++++----
 addons/nifti/niftiimage.hh                         |   2 +-
 addons/nifti/test_niftiimage.cc                    |  11 +-
 addons/nlopt/nlopt.cc                              |   2 +-
 addons/nlopt/nlopt.hh                              |   2 +-
 addons/nlopt/test_nlopt.cc                         |   2 +-
 addons/openexr/2dimgexr.cc                         |   2 +-
 addons/openexr/2dvfexr.cc                          |   2 +-
 addons/openexr/test_openexr.cc                     |  91 ++-
 addons/png/CMakeLists.txt                          |   4 +-
 addons/png/png-gray.cc                             |   2 +-
 addons/png/png-rgb.cc                              |   6 +-
 addons/png/test_png.cc                             | 194 ++++++
 addons/tiff/CMakeLists.txt                         |   4 +-
 addons/tiff/test_tiff.cc                           | 243 +++++++
 addons/tiff/tiff.cc                                |   6 +-
 addons/vistaio/2dtrans.cc                          |   2 +-
 addons/vistaio/2dtrans.hh                          |   2 +-
 addons/vistaio/2dvfvistaio.cc                      |   2 +-
 addons/vistaio/2dvistaio.cc                        |   5 +-
 addons/vistaio/2dvistaio.hh                        |   2 +-
 addons/vistaio/3dtrans.cc                          |   2 +-
 addons/vistaio/3dtrans.hh                          |   2 +-
 addons/vistaio/3dvfvistaio.cc                      |   2 +-
 addons/vistaio/3dvistaio.cc                        |   8 +-
 addons/vistaio/3dvistaio.hh                        |   2 +-
 addons/vistaio/CMakeLists.txt                      |  11 +-
 addons/vistaio/test_2dtrans.cc                     |   2 +-
 addons/vistaio/test_2dvistaio.cc                   |  48 +-
 addons/vistaio/test_3dtrans.cc                     |   2 +-
 addons/vistaio/test_3dvistaio.cc                   |  52 +-
 addons/vistaio/test_vista4mia.cc                   |   6 +-
 addons/vistaio/test_vistaio.cc                     | 378 +++++++++++
 addons/vistaio/vista4mia.cc                        |  17 +-
 addons/vistaio/vista4mia.hh                        |  10 +-
 addons/vistaio/vistamesh.cc                        |  16 +-
 addons/vtk/test_vtkimage.cc                        |   2 +-
 addons/vtk/test_vtkmesh.cc                         |   2 +-
 addons/vtk/test_vtkvf.cc                           |   2 +-
 addons/vtk/vtkimage.cc                             |  12 +-
 addons/vtk/vtkimage.hh                             |   2 +-
 addons/vtk/vtkmesh.cc                              |   2 +-
 addons/vtk/vtkmesh.hh                              |   2 +-
 addons/vtk/vtkvf.cc                                |   2 +-
 addons/vtk/vtkvf.hh                                |   2 +-
 cmake/FindDCMTKnew.cmake                           |  27 +-
 cmake/macros.cmake                                 |  27 +-
 cmake/pluginmacro.cmake                            |  58 +-
 config.h.cmake                                     |   2 +-
 coverage.sh                                        |  20 +
 doc/CMakeLists.txt                                 |  26 +-
 doc/reference.dox.cmake                            |   6 +-
 evaluate_coverage.sh                               |  28 +
 examples/2d/filter/simple.cc                       |   2 +-
 examples/2d/filter/simple.hh                       |   2 +-
 examples/2d/filter/test_simple.cc                  |   2 +-
 gsl++/CMakeLists.txt                               |  53 --
 gsl++/matrix.cc                                    | 102 ---
 gsl++/matrix.hh                                    |  76 ---
 gsl++/test_matrix.cc                               |  61 --
 gsl++/vector.cc                                    |  55 --
 gsl++/vector_template.cxx                          | 143 -----
 gsl++/vector_template.hh                           | 214 -------
 mia.hh                                             |   2 +-
 mia/2d.hh                                          |   2 +-
 mia/2d/CMakeLists.txt                              |   2 -
 mia/2d/angle.cc                                    |   2 +-
 mia/2d/angle.hh                                    |   2 +-
 mia/2d/boundingbox.cc                              |   2 +-
 mia/2d/boundingbox.hh                              |   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                                     |   2 +-
 mia/2d/cost.hh                                     |   2 +-
 mia/2d/cost/gncc.cc                                |  51 +-
 mia/2d/cost/gncc.hh                                |   2 +-
 mia/2d/cost/lncc.cc                                |  26 +-
 mia/2d/cost/lncc.hh                                |   2 +-
 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                                 |  19 +-
 mia/2d/cost/ncc.hh                                 |   2 +-
 mia/2d/cost/ngf.cc                                 |   2 +-
 mia/2d/cost/ngf.hh                                 |   2 +-
 mia/2d/cost/ssd-automask.cc                        |   2 +-
 mia/2d/cost/ssd-automask.hh                        |   2 +-
 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_gncc.cc                           |   2 +-
 mia/2d/cost/test_lncc.cc                           |   2 +-
 mia/2d/cost/test_lsd.cc                            |   2 +-
 mia/2d/cost/test_mi.cc                             |   2 +-
 mia/2d/cost/test_ncc.cc                            |   2 +-
 mia/2d/cost/test_ngf.cc                            |   3 +-
 mia/2d/cost/test_ssd-automask.cc                   |   2 +-
 mia/2d/cost/test_ssd.cc                            |   2 +-
 mia/2d/cost/test_ssd2.cc                           |   2 +-
 mia/2d/creator.cc                                  |   2 +-
 mia/2d/creator.hh                                  |   2 +-
 mia/2d/creator/CMakeLists.txt                      |   4 +-
 mia/2d/creator/circle.cc                           |  24 +-
 mia/{3d/creator/sphere.hh => 2d/creator/circle.hh} |  31 +-
 mia/2d/creator/test_circle.cc                      | 120 ++++
 mia/2d/cstkernel.cc                                |   2 +-
 mia/2d/cstkernel.hh                                |   2 +-
 mia/2d/datafield.cc                                |  13 +-
 mia/2d/datafield.cxx                               |   8 +-
 mia/2d/datafield.hh                                |  37 +-
 mia/2d/defines2d.hh                                |  18 +-
 mia/2d/deformer.hh                                 |   2 +-
 mia/2d/distance.cc                                 |   2 +-
 mia/2d/distance.hh                                 |   2 +-
 mia/2d/distances.cc                                |   2 +-
 mia/2d/fftkernel.cc                                |   2 +-
 mia/2d/fftkernel.hh                                |   2 +-
 mia/2d/filter.cc                                   |   2 +-
 mia/2d/filter.hh                                   |   2 +-
 mia/2d/filter/CMakeLists.txt                       |   5 +-
 mia/2d/filter/adaptmed.cc                          |   5 +-
 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                          |   2 +-
 mia/2d/filter/combiner.hh                          |   2 +-
 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                         |   2 +-
 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                          |   2 +-
 mia/2d/filter/labelmap.hh                          |   2 +-
 mia/2d/filter/labelscale.cc                        |   2 +-
 mia/2d/filter/labelscale.hh                        |   2 +-
 mia/2d/filter/lnfft.cc                             |   2 +-
 mia/2d/filter/load.cc                              |   2 +-
 mia/2d/filter/load.hh                              |   2 +-
 mia/2d/filter/mask.cc                              |   2 +-
 mia/2d/filter/mask.hh                              |   2 +-
 mia/2d/filter/mean.cc                              |  42 +-
 mia/2d/filter/mean.hh                              |   2 +-
 mia/2d/filter/meanvar.cc                           | 175 +++++
 mia/2d/filter/{thresh.hh => meanvar.hh}            |  28 +-
 mia/2d/filter/median.cc                            |   2 +-
 mia/2d/filter/median.hh                            |   2 +-
 mia/2d/filter/medianmad.cc                         | 183 ++++++
 mia/2d/filter/{thresh.hh => medianmad.hh}          |  28 +-
 mia/2d/filter/midpoint.cc                          |   2 +-
 mia/2d/filter/mlv.cc                               |  30 +-
 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                        |   2 +-
 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                           |  45 +-
 mia/2d/filter/sepconv.hh                           |  14 +-
 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                               |   2 +-
 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                     |   2 +-
 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                    |   2 +-
 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_labelscale.cc                   |   2 +-
 mia/2d/filter/test_load.cc                         |   2 +-
 mia/2d/filter/test_mask.cc                         |   2 +-
 mia/2d/filter/test_mean.cc                         |   2 +-
 mia/2d/filter/test_meanvar.cc                      | 134 ++++
 mia/2d/filter/test_median.cc                       |   2 +-
 mia/2d/filter/test_medianmad.cc                    | 130 ++++
 mia/2d/filter/test_mlv.cc                          |   2 +-
 mia/2d/filter/test_morphological.cc                |   2 +-
 mia/2d/filter/test_ngfnorm.cc                      |   2 +-
 mia/2d/filter/test_noise.cc                        |   2 +-
 mia/2d/filter/test_regiongrow.cc                   |   2 +-
 mia/2d/filter/test_scale.cc                        |   2 +-
 mia/2d/filter/test_seededwatershed.cc              |   2 +-
 mia/2d/filter/test_selectbig.cc                    |   2 +-
 mia/2d/filter/test_sepconv.cc                      |  74 ++-
 mia/2d/filter/test_shaped_mean.cc                  |   2 +-
 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                       |   2 +-
 mia/2d/filter/{test_mean.cc => test_tmean.cc}      |  97 +--
 mia/2d/filter/test_transform.cc                    |   2 +-
 mia/2d/filter/test_watershed.cc                    |   2 +-
 mia/2d/filter/thinning.cc                          |   2 +-
 mia/2d/filter/thinning.hh                          |   2 +-
 mia/2d/filter/thresh.cc                            |   8 +-
 mia/2d/filter/thresh.hh                            |   2 +-
 mia/2d/filter/tmean.cc                             | 144 +++++
 mia/2d/filter/{mean.hh => tmean.hh}                |  19 +-
 mia/2d/filter/transform.cc                         |   2 +-
 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                              |  76 ---
 mia/2d/filterchain.hh                              |   4 +-
 mia/2d/filtertest.cc                               |   2 +-
 mia/2d/filtertest.hh                               |   2 +-
 mia/2d/fullcost.cc                                 |   2 +-
 mia/2d/fullcost.hh                                 |   2 +-
 mia/2d/fullcost/image.cc                           |   2 +-
 mia/2d/fullcost/image.hh                           |   2 +-
 mia/2d/fullcost/label.cc                           |   4 +-
 mia/2d/fullcost/label.hh                           |   2 +-
 mia/2d/fullcost/maskedimage.cc                     |   2 +-
 mia/2d/fullcost/maskedimage.hh                     |   2 +-
 mia/2d/fullcost/test_image.cc                      |   2 +-
 mia/2d/fullcost/test_label.cc                      |  13 +-
 mia/2d/fullcost/test_maskedimage.cc                |  99 ++-
 mia/2d/fuzzyclustersolver_cg.cc                    |   2 +-
 mia/2d/fuzzyclustersolver_cg.hh                    |   2 +-
 mia/2d/fuzzyclustersolver_sor.cc                   |  34 +-
 mia/2d/fuzzyclustersolver_sor.hh                   |   2 +-
 mia/2d/fuzzyseg.cc                                 | 218 +------
 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                                    |  16 +-
 mia/2d/image.hh                                    |  13 +-
 mia/2d/imageio.cc                                  |   3 +-
 mia/2d/imageio.hh                                  |   5 +-
 mia/2d/imageiotest.cc                              |   2 +-
 mia/2d/imageiotest.hh                              |   2 +-
 mia/2d/imagetest.cc                                |   2 +-
 mia/2d/imagetest.hh                                |   2 +-
 mia/2d/interpolator.cc                             |  39 +-
 mia/2d/interpolator.cxx                            |   6 +-
 mia/2d/interpolator.hh                             |  12 +-
 mia/2d/io/bmp.cc                                   | 177 +++---
 mia/2d/io/raw.cc                                   |   2 +-
 mia/2d/io/test_xml.cc                              |   2 +-
 mia/2d/io/xml.cc                                   |   2 +-
 mia/2d/io/xml.hh                                   |   2 +-
 mia/2d/iterator.cxx                                |   2 +-
 mia/2d/iterator.hh                                 |   2 +-
 mia/2d/kernel/curv.cc                              |   2 +-
 mia/2d/maskedcost.cc                               |   2 +-
 mia/2d/maskedcost.hh                               |   2 +-
 mia/2d/maskedcost/lncc.cc                          |  23 +-
 mia/2d/maskedcost/lncc.hh                          |   2 +-
 mia/2d/maskedcost/mi.cc                            |   2 +-
 mia/2d/maskedcost/mi.hh                            |   2 +-
 mia/2d/maskedcost/ncc.cc                           |  30 +-
 mia/2d/maskedcost/ncc.hh                           |   2 +-
 mia/2d/maskedcost/ssd.cc                           |   2 +-
 mia/2d/maskedcost/ssd.hh                           |   2 +-
 mia/2d/maskedcost/test_lncc.cc                     |   2 +-
 mia/2d/maskedcost/test_mi.cc                       |   2 +-
 mia/2d/maskedcost/test_ncc.cc                      |   2 +-
 mia/2d/maskedcost/test_ssd.cc                      |   2 +-
 mia/2d/matrix.hh                                   |   2 +-
 mia/2d/model.cc                                    |   2 +-
 mia/2d/model.hh                                    |   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                            |   2 +-
 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                                |  86 ++-
 mia/2d/perfusion.hh                                |  23 +-
 mia/2d/polygon.cc                                  |   2 +-
 mia/2d/polygon.hh                                  |   2 +-
 mia/2d/ppmatrix.cc                                 |  21 +-
 mia/2d/ppmatrix.hh                                 |  18 +-
 mia/2d/register.cc                                 |   2 +-
 mia/2d/register.hh                                 |  12 +-
 mia/2d/rgbimageio.cc                               |   6 +-
 mia/2d/rgbimageio.hh                               |   7 +-
 mia/2d/rgbio/bmp.cc                                | 118 +++-
 mia/2d/rigidregister.cc                            |   2 +-
 mia/2d/rigidregister.hh                            |   2 +-
 mia/2d/segframe.cc                                 |  14 +-
 mia/2d/segframe.hh                                 |   4 +-
 mia/2d/segpoint.cc                                 |  19 +-
 mia/2d/segpoint.hh                                 |   4 +-
 mia/2d/segsection.cc                               |  21 +-
 mia/2d/segsection.hh                               |   6 +-
 mia/2d/segset.cc                                   |  19 +-
 mia/2d/segset.hh                                   |   2 +-
 mia/2d/segsetwithimages.cc                         |   3 +-
 mia/2d/segsetwithimages.hh                         |   5 +-
 mia/2d/segstar.cc                                  |  24 +-
 mia/2d/segstar.hh                                  |   4 +-
 mia/2d/shape.cc                                    |   2 +-
 mia/2d/shape.hh                                    |   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                      |   2 +-
 mia/2d/sparse_image_solver.hh                      |   2 +-
 mia/2d/splinepenalty/divcurl.cc                    |   2 +-
 mia/2d/splinepenalty/divcurl.hh                    |   2 +-
 mia/2d/splinepenalty/test_divcurl.cc               |   2 +-
 mia/2d/splinetransformpenalty.cc                   |   2 +-
 mia/2d/splinetransformpenalty.hh                   |   2 +-
 mia/2d/test_2d.cc                                  |   2 +-
 mia/2d/test_angle.cc                               |   2 +-
 mia/2d/test_boundingbox.cc                         |   2 +-
 mia/2d/test_combiner.cc                            |   2 +-
 mia/2d/test_correlation_weight.cc                  |   2 +-
 mia/2d/test_cost.cc                                |   2 +-
 mia/2d/test_datafield.cc                           |   2 +-
 mia/2d/test_distance.cc                            |   6 +-
 mia/2d/test_divcurlmatrix.cc                       |   2 +-
 mia/2d/test_filter.cc                              | 105 ++-
 mia/2d/test_filter_cast.cc                         |   2 +-
 mia/2d/test_fullcost.cc                            |   2 +-
 mia/2d/test_fullcost_mi_spline.cc                  |   2 +-
 mia/2d/test_groundtruthproblem.cc                  |   2 +-
 mia/2d/test_ica.cc                                 |  25 +-
 mia/2d/test_image.cc                               |  25 +-
 mia/2d/test_imagecostbase.cc                       |   2 +-
 mia/2d/test_imageio.cc                             | 250 +++++++-
 mia/2d/test_interpol.cc                            |  10 +-
 mia/2d/test_iterator.cc                            |   2 +-
 mia/2d/test_matrix.cc                              |   2 +-
 mia/2d/test_modelsolverreg.cc                      |   2 +-
 mia/2d/test_morphshape.cc                          |   2 +-
 mia/2d/test_nfg.cc                                 |   2 +-
 mia/2d/test_nonrigidregister.cc                    |   2 +-
 mia/2d/test_oldnewintegrate.cc                     |   2 +-
 mia/2d/test_param.cc                               |   2 +-
 mia/2d/test_perfusion.cc                           | 298 ++++++++-
 mia/2d/test_polygon.cc                             |   2 +-
 mia/2d/test_ppmatrix.cc                            |  76 +--
 mia/2d/test_register.cc                            |  27 +-
 mia/2d/test_regplugins.cc                          |   2 +-
 mia/2d/test_rigidregister.cc                       |  10 +-
 mia/2d/test_segframe.cc                            |   4 +-
 mia/2d/test_segmentation.cc                        |  15 +-
 mia/2d/test_segpoint.cc                            |   2 +-
 mia/2d/test_shape.cc                               |   2 +-
 mia/2d/test_similarity_profile.cc                  |  27 +-
 mia/2d/test_sparse_image_solver.cc                 |   2 +-
 mia/2d/test_splinetransformpenalty.cc              |   2 +-
 mia/2d/test_trackpoint.cc                          |   2 +-
 mia/2d/test_transform.cc                           |   2 +-
 mia/2d/test_transformfactory.cc                    |   2 +-
 mia/2d/test_transio.cc                             |   2 +-
 mia/2d/test_vector.cc                              |   2 +-
 mia/2d/test_vectorfield_interpolator.cc            |   2 +-
 mia/2d/test_vfio.cc                                |   2 +-
 mia/2d/timestep.cc                                 |   2 +-
 mia/2d/timestep.hh                                 |   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                     |   2 +-
 mia/2d/timestep/test_fluid.cc                      |   2 +-
 mia/2d/trackpoint.cc                               |   2 +-
 mia/2d/trackpoint.hh                               |   2 +-
 mia/2d/trait.hh                                    |   2 +-
 mia/2d/transform.cc                                |   2 +-
 mia/2d/transform.hh                                |   4 +-
 mia/2d/transform/affine.cc                         |   2 +-
 mia/2d/transform/affine.hh                         |   2 +-
 mia/2d/transform/rigid.cc                          |   2 +-
 mia/2d/transform/rigid.hh                          |   2 +-
 mia/2d/transform/rotation.cc                       |   2 +-
 mia/2d/transform/rotation.hh                       |   2 +-
 mia/2d/transform/spline.cc                         |   2 +-
 mia/2d/transform/spline.hh                         |   2 +-
 mia/2d/transform/test_affine.cc                    |   2 +-
 mia/2d/transform/test_nonlinear.cc                 |   2 +-
 mia/2d/transform/test_rigid.cc                     |   2 +-
 mia/2d/transform/test_rotation.cc                  |   2 +-
 mia/2d/transform/test_spline.cc                    |  10 +-
 mia/2d/transform/test_translate.cc                 |   2 +-
 mia/2d/transform/test_vectorfield.cc               |   2 +-
 mia/2d/transform/translate.cc                      |   2 +-
 mia/2d/transform/translate.hh                      |   2 +-
 mia/2d/transform/vectorfield.cc                    |   2 +-
 mia/2d/transform/vectorfield.hh                    |   2 +-
 mia/2d/transformfactory.cc                         |   2 +-
 mia/2d/transformfactory.hh                         |   2 +-
 mia/2d/transformio.cc                              |   4 +-
 mia/2d/transformio.hh                              |   5 +-
 mia/2d/transformmock.cc                            |   2 +-
 mia/2d/transformmock.hh                            |   2 +-
 mia/2d/transio/bbs.cc                              |   2 +-
 mia/2d/transio/pbs.cc                              |   2 +-
 mia/2d/transio/serialization.hh                    |   2 +-
 mia/2d/transio/xml.cc                              |   2 +-
 mia/2d/vector.hh                                   |   2 +-
 mia/2d/vectorfield.cc                              |   2 +-
 mia/2d/vectorfield.hh                              |   2 +-
 mia/2d/vfio.cc                                     |   2 +-
 mia/2d/vfio.hh                                     |   2 +-
 mia/2d/vfiotest.cc                                 |   2 +-
 mia/3d.hh                                          |   2 +-
 mia/3d/2dimagefifofilter.cc                        |   2 +-
 mia/3d/2dimagefifofilter.hh                        |  17 +-
 mia/3d/CMakeLists.txt                              |   9 +-
 mia/3d/affine_matrix.cc                            |   3 +-
 mia/3d/affine_matrix.hh                            |   2 +-
 mia/3d/camera.cc                                   |   2 +-
 mia/3d/camera.hh                                   |   2 +-
 mia/3d/combiner/labelxmap.cc                       |   2 +-
 mia/3d/combiner/labelxmap.hh                       |   2 +-
 mia/3d/combiner/ops.cc                             |   2 +-
 mia/3d/combiner/ops.hh                             |   2 +-
 mia/3d/combiner/plugin.hh                          |   2 +-
 mia/3d/combiner/test_labelxmap.cc                  |   2 +-
 mia/3d/combiner/test_ops.cc                        |   2 +-
 mia/3d/cost.cc                                     |   2 +-
 mia/3d/cost.hh                                     |   2 +-
 mia/3d/cost/lncc.cc                                |  26 +-
 mia/3d/cost/lncc.hh                                |   2 +-
 mia/3d/cost/mi.cc                                  |   2 +-
 mia/3d/cost/mi.hh                                  |   2 +-
 mia/3d/cost/ncc.cc                                 |  30 +-
 mia/3d/cost/ncc.hh                                 |   2 +-
 mia/3d/cost/ngf.cc                                 |   3 +-
 mia/3d/cost/ngf.hh                                 |   2 +-
 mia/3d/cost/ssd-automask.cc                        |   2 +-
 mia/3d/cost/ssd-automask.hh                        |   2 +-
 mia/3d/cost/ssd.cc                                 |   2 +-
 mia/3d/cost/ssd.hh                                 |   2 +-
 mia/3d/cost/test_lncc.cc                           |   2 +-
 mia/3d/cost/test_mi.cc                             |   2 +-
 mia/3d/cost/test_ncc.cc                            |   2 +-
 mia/3d/cost/test_ngf.cc                            |   2 +-
 mia/3d/cost/test_ssd-automask.cc                   |   2 +-
 mia/3d/cost/test_ssd.cc                            |   2 +-
 mia/3d/cost/test_ssdautomask.cc                    |   2 +-
 mia/3d/creator.cc                                  |   2 +-
 mia/3d/creator.hh                                  |   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                      |   2 +-
 mia/3d/creator/test_sphere.cc                      |   2 +-
 mia/3d/critical_point.cc                           |  32 +-
 mia/3d/critical_point.hh                           |  96 ++-
 mia/3d/datafield.cc                                |  11 +-
 mia/3d/datafield.cxx                               |  88 ++-
 mia/3d/datafield.hh                                |  74 ++-
 mia/3d/defines3d.hh                                |   2 +-
 mia/3d/deformer.hh                                 |  11 +-
 mia/3d/distance.cc                                 |   2 +-
 mia/3d/distance.hh                                 |   2 +-
 mia/3d/fifof/byslice.cc                            |   2 +-
 mia/3d/fifof/byslice.hh                            |   2 +-
 mia/3d/fifof/gauss.cc                              |   2 +-
 mia/3d/fifof/gauss.hh                              |   6 +-
 mia/3d/fifof/label.cc                              |   2 +-
 mia/3d/fifof/label.hh                              |   2 +-
 mia/3d/fifof/median.cc                             |  12 +-
 mia/3d/fifof/median.hh                             |   4 +-
 mia/3d/fifof/mlv.cc                                |   7 +-
 mia/3d/fifof/mlv.hh                                |   4 +-
 mia/3d/fifof/morphological.cc                      |   2 +-
 mia/3d/fifof/morphological.hh                      |   4 +-
 mia/3d/fifof/regiongrow.cc                         |   2 +-
 mia/3d/fifof/regiongrow.hh                         |   2 +-
 mia/3d/fifof/rgg.cc                                |   2 +-
 mia/3d/fifof/rgg2pass.cc                           |   2 +-
 mia/3d/fifof/test_byslice.cc                       |   2 +-
 mia/3d/fifof/test_gauss.cc                         |   2 +-
 mia/3d/fifof/test_label.cc                         |   2 +-
 mia/3d/fifof/test_median.cc                        |   2 +-
 mia/3d/fifof/test_mlv.cc                           |   2 +-
 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                                   |   2 +-
 mia/3d/filter.hh                                   |   2 +-
 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                          |   2 +-
 mia/3d/filter/combiner.hh                          |   2 +-
 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                          |  29 +-
 mia/3d/filter/distance.hh                          |   2 +-
 mia/3d/filter/downscale.cc                         |   2 +-
 mia/3d/filter/downscale.hh                         |   2 +-
 mia/3d/filter/gradnorm.cc                          |   2 +-
 mia/3d/filter/gradnorm.hh                          |   2 +-
 mia/3d/filter/growmask.cc                          |   8 +-
 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/labelmap.cc                          |   2 +-
 mia/3d/filter/labelmap.hh                          |   2 +-
 mia/3d/filter/labelscale.cc                        |   2 +-
 mia/3d/filter/labelscale.hh                        |   2 +-
 mia/3d/filter/load.cc                              |   2 +-
 mia/3d/filter/load.hh                              |   2 +-
 mia/3d/filter/lvdownscale.cc                       |   2 +-
 mia/3d/filter/lvdownscale.hh                       |   2 +-
 mia/3d/filter/mask.cc                              |   2 +-
 mia/3d/filter/mask.hh                              |   2 +-
 mia/3d/filter/mean.cc                              |  27 +-
 mia/3d/filter/mean.hh                              |   2 +-
 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                     |  14 +-
 mia/3d/filter/morphological.hh                     |   2 +-
 mia/3d/filter/msnormalizer.cc                      |  20 +-
 mia/3d/filter/msnormalizer.hh                      |   2 +-
 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                             |  19 +-
 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                           |  17 +-
 mia/3d/filter/sepconv.hh                           |   2 +-
 mia/3d/filter/tee.cc                               |   2 +-
 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                     |   2 +-
 mia/3d/filter/test_convert.cc                      |   2 +-
 mia/3d/filter/test_crop.cc                         |   2 +-
 mia/3d/filter/test_distance.cc                     |   2 +-
 mia/3d/filter/test_downscale.cc                    |   2 +-
 mia/3d/filter/test_gradnorm.cc                     |   2 +-
 mia/3d/filter/test_growmask.cc                     |   2 +-
 mia/3d/filter/test_invert.cc                       |   2 +-
 mia/3d/filter/test_kmeans.cc                       |   2 +-
 mia/3d/filter/test_label.cc                        |   2 +-
 mia/3d/filter/test_labelmap.cc                     |   2 +-
 mia/3d/filter/test_labelscale.cc                   |   2 +-
 mia/3d/filter/test_load.cc                         |   2 +-
 mia/3d/filter/test_lvdownscale.cc                  |   2 +-
 mia/3d/filter/test_mask.cc                         |   2 +-
 mia/3d/filter/test_mean.cc                         |   2 +-
 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                 |   2 +-
 mia/3d/filter/test_reorient.cc                     |   2 +-
 mia/3d/filter/test_resize.cc                       |   2 +-
 mia/3d/filter/test_scale.cc                        |   2 +-
 mia/3d/filter/test_seededwatershed.cc              |   2 +-
 mia/3d/filter/test_selectbig.cc                    |   2 +-
 mia/3d/filter/test_sepconv.cc                      |   2 +-
 mia/3d/filter/test_tee.cc                          |   2 +-
 mia/3d/filter/test_thinning.cc                     |   2 +-
 mia/3d/filter/test_transform.cc                    |   2 +-
 mia/3d/filter/test_watershed.cc                    |   2 +-
 mia/3d/filter/thinning.cc                          |   2 +-
 mia/3d/filter/thinning.hh                          |   2 +-
 mia/3d/filter/transform.cc                         |   2 +-
 mia/3d/filter/transform.hh                         |   2 +-
 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/image.cc                           |   2 +-
 mia/3d/fullcost/image.hh                           |   2 +-
 mia/3d/fullcost/label.cc                           |   4 +-
 mia/3d/fullcost/label.hh                           |   2 +-
 mia/3d/fullcost/maskedimage.cc                     |  10 +-
 mia/3d/fullcost/maskedimage.hh                     |   2 +-
 mia/3d/fullcost/taggedssd.cc                       |   2 +-
 mia/3d/fullcost/taggedssd.hh                       |   2 +-
 mia/3d/fullcost/test_image.cc                      |   2 +-
 mia/3d/fullcost/test_label.cc                      |   2 +-
 mia/3d/fullcost/test_maskedimage.cc                | 229 ++++++-
 mia/3d/fullcost/test_taggedssd.cc                  |   2 +-
 mia/3d/fuzzyclustersolver_cg.cc                    |   2 +-
 mia/3d/fuzzyclustersolver_cg.hh                    |   2 +-
 mia/3d/fuzzyseg.cc                                 | 213 +------
 mia/3d/fuzzyseg.hh                                 |   2 +-
 mia/3d/ica.cc                                      |   2 +-
 mia/3d/ica.hh                                      |   2 +-
 mia/3d/image.cc                                    |   9 +-
 mia/3d/image.hh                                    |   7 +-
 mia/3d/imagecollect.cc                             |   2 +-
 mia/3d/imagecollect.hh                             |   2 +-
 mia/3d/imagedraw.cc                                |   2 +-
 mia/3d/imagedraw.cxx                               |   2 +-
 mia/3d/imagedraw.hh                                |   2 +-
 mia/3d/imageio.cc                                  |   3 +-
 mia/3d/imageio.hh                                  |   5 +-
 mia/3d/imageiotest.cc                              |   2 +-
 mia/3d/imageiotest.hh                              |   2 +-
 mia/3d/imagetest.cc                                |   2 +-
 mia/3d/imagetest.hh                                |   2 +-
 mia/3d/interpolator.cc                             | 200 +++---
 mia/3d/interpolator.cxx                            | 150 ++---
 mia/3d/interpolator.hh                             |  32 +-
 mia/3d/io/analyze.cc                               |   2 +-
 mia/3d/io/analyze.hh                               |   2 +-
 mia/3d/io/inria.cc                                 |   2 +-
 mia/3d/io/vff.cc                                   |   2 +-
 mia/3d/iterator.cxx                                |   2 +-
 mia/3d/iterator.hh                                 |   2 +-
 mia/3d/landmark.cc                                 |   2 +-
 mia/3d/landmark.hh                                 |   2 +-
 mia/3d/landmarklist.cc                             |   2 +-
 mia/3d/landmarklist.hh                             |   2 +-
 mia/3d/landmarklistio.cc                           |   3 +-
 mia/3d/landmarklistio.hh                           |  16 +-
 mia/3d/linear_transform.cc                         |   2 +-
 mia/3d/linear_transform.hh                         |   2 +-
 mia/3d/lmio/lmx.cc                                 |  39 +-
 mia/3d/maskedcost.cc                               |   2 +-
 mia/3d/maskedcost.hh                               |   2 +-
 mia/3d/maskedcost/lncc.cc                          |  24 +-
 mia/3d/maskedcost/lncc.hh                          |   2 +-
 mia/3d/maskedcost/mi.cc                            |   2 +-
 mia/3d/maskedcost/mi.hh                            |   2 +-
 mia/3d/maskedcost/ncc.cc                           |  31 +-
 mia/3d/maskedcost/ncc.hh                           |   2 +-
 mia/3d/maskedcost/ssd.cc                           |   2 +-
 mia/3d/maskedcost/ssd.hh                           |   2 +-
 mia/3d/maskedcost/test_lncc.cc                     |   2 +-
 mia/3d/maskedcost/test_mi.cc                       |   2 +-
 mia/3d/maskedcost/test_ncc.cc                      |   2 +-
 mia/3d/maskedcost/test_ssd.cc                      |   2 +-
 mia/3d/matrix.cc                                   |  44 +-
 mia/3d/matrix.hh                                   |  26 +-
 mia/3d/model.cc                                    |   2 +-
 mia/3d/model.hh                                    |   2 +-
 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                              |   6 +-
 mia/3d/orientation.hh                              |  11 +-
 mia/3d/ppmatrix.cc                                 |  16 +-
 mia/3d/ppmatrix.hh                                 |   2 +-
 mia/3d/quaternion.cc                               |   4 +-
 mia/3d/quaternion.hh                               |   9 +-
 mia/3d/reg3d/direct.cc                             |   2 +-
 mia/3d/reg3d/fluid.cc                              |   2 +-
 mia/3d/reg3d/navier.cc                             |   2 +-
 mia/3d/reg3d/naviera.cc                            |   2 +-
 mia/3d/reg3d/navierasse.cc                         |   2 +-
 mia/3d/reg3d/navierpsse.cc                         |   2 +-
 mia/3d/register.cc                                 |   2 +-
 mia/3d/register.hh                                 |   2 +-
 mia/3d/rigidregister.cc                            |   2 +-
 mia/3d/rigidregister.hh                            |   2 +-
 mia/3d/rot.cc                                      |   2 +-
 mia/3d/rot.hh                                      |   2 +-
 mia/3d/shape.cc                                    |   2 +-
 mia/3d/shape.hh                                    |   2 +-
 mia/3d/shapes/CMakeLists.txt                       |  26 +-
 mia/3d/shapes/basic_shapes.cc                      | 115 +---
 .../dummy1.cc => 3d/shapes/basic_shapes.hh}        |  60 +-
 mia/3d/shapes/sphere.cc                            |   2 +-
 mia/3d/shapes/sphere.hh                            |   2 +-
 mia/3d/shapes/test_shapes.cc                       | 100 +++
 mia/3d/similarity_profile.cc                       |   2 +-
 mia/3d/similarity_profile.hh                       |   2 +-
 mia/3d/splinepenalty/divcurl.cc                    |   2 +-
 mia/3d/splinepenalty/divcurl.hh                    |   2 +-
 mia/3d/splinepenalty/test_divcurl.cc               |   2 +-
 mia/3d/splinetransformpenalty.cc                   |   2 +-
 mia/3d/splinetransformpenalty.hh                   |   2 +-
 mia/3d/stackdisttrans.cc                           |   2 +-
 mia/3d/stackdisttrans.hh                           |   2 +-
 mia/3d/test_2dimagefifofilter.cc                   |   2 +-
 mia/3d/test_3d.cc                                  |   2 +-
 mia/3d/test_affine_matrix.cc                       |   2 +-
 mia/3d/test_combiner.cc                            |   2 +-
 mia/3d/test_cost.cc                                |   2 +-
 mia/3d/test_critical_points.cc                     | 177 ++++++
 mia/3d/test_datafield.cc                           |   2 +-
 mia/3d/test_deform.cc                              |  14 +-
 mia/3d/test_distance.cc                            |  14 +-
 mia/3d/test_fullcost.cc                            |   2 +-
 mia/3d/test_ica.cc                                 |  26 +-
 mia/3d/test_image.cc                               |   2 +-
 mia/3d/test_imagecollect.cc                        |   2 +-
 mia/3d/test_imagedraw.cc                           |   2 +-
 mia/3d/test_imageio.cc                             | 126 ++++
 mia/3d/test_interpol.cc                            |  48 +-
 mia/3d/test_iterator.cc                            |   2 +-
 mia/3d/test_landmark.cc                            |   2 +-
 mia/3d/test_landmarklistio.cc                      |   2 +-
 mia/3d/test_matrix.cc                              |   8 +-
 mia/3d/test_nfg.cc                                 |   2 +-
 mia/3d/test_nonrigidregister.cc                    |   4 +-
 mia/3d/test_orientation.cc                         |   4 +-
 mia/3d/test_ppmatrix.cc                            |  46 +-
 mia/3d/test_quaternion.cc                          |   3 +-
 mia/3d/test_regplugins.cc                          |   2 +-
 mia/3d/test_rigidregister.cc                       |   2 +-
 mia/3d/test_rot.cc                                 |   2 +-
 mia/3d/test_shape.cc                               |   2 +-
 mia/3d/test_similarity_profile.cc                  |   2 +-
 mia/3d/test_splinetransformpenalty.cc              |   2 +-
 mia/3d/test_stackdisttrans.cc                      |   2 +-
 mia/3d/test_trackpoint.cc                          |   2 +-
 mia/3d/test_transform.cc                           |   2 +-
 mia/3d/test_transformfactory.cc                    |   2 +-
 mia/3d/test_transio.cc                             |   2 +-
 mia/3d/test_vector.cc                              |  42 +-
 mia/3d/test_vectorfield.cc                         |   2 +-
 mia/3d/test_vfio.cc                                |   2 +-
 mia/3d/timestep.cc                                 |   2 +-
 mia/3d/timestep.hh                                 |   2 +-
 mia/3d/trackpoint.cc                               |   2 +-
 mia/3d/trackpoint.hh                               |   2 +-
 mia/3d/trait.hh                                    |   2 +-
 mia/3d/transform.cc                                |  11 +-
 mia/3d/transform.hh                                |   2 +-
 mia/3d/transform/affine.cc                         |   2 +-
 mia/3d/transform/affine.hh                         |   2 +-
 mia/3d/transform/axisrot.cc                        |   2 +-
 mia/3d/transform/axisrot.hh                        |   2 +-
 mia/3d/transform/raffine.cc                        |   2 +-
 mia/3d/transform/raffine.hh                        |   2 +-
 mia/3d/transform/rigid.cc                          |  15 +-
 mia/3d/transform/rigid.hh                          |   2 +-
 mia/3d/transform/rotation.cc                       |   2 +-
 mia/3d/transform/rotation.hh                       |   2 +-
 mia/3d/transform/rotbend.cc                        |   2 +-
 mia/3d/transform/rotbend.hh                        |   2 +-
 mia/3d/transform/spline.cc                         |  99 +--
 mia/3d/transform/spline.hh                         |   2 +-
 mia/3d/transform/test_affine.cc                    |   2 +-
 mia/3d/transform/test_axisrot.cc                   |   2 +-
 mia/3d/transform/test_nonlinear.cc                 |   2 +-
 mia/3d/transform/test_raffine.cc                   |   2 +-
 mia/3d/transform/test_rigid.cc                     |   2 +-
 mia/3d/transform/test_rotation.cc                  |   2 +-
 mia/3d/transform/test_rotbend.cc                   |   2 +-
 mia/3d/transform/test_spline.cc                    |   4 +-
 mia/3d/transform/test_translate.cc                 |   2 +-
 mia/3d/transform/test_vectorfield.cc               |   2 +-
 mia/3d/transform/translate.cc                      |   2 +-
 mia/3d/transform/translate.hh                      |   2 +-
 mia/3d/transform/vectorfield.cc                    |   2 +-
 mia/3d/transform/vectorfield.hh                    |   2 +-
 mia/3d/transformfactory.cc                         |   2 +-
 mia/3d/transformfactory.hh                         |   2 +-
 mia/3d/transformio.cc                              |   3 +-
 mia/3d/transformio.hh                              |   5 +-
 mia/3d/transformmock.cc                            |   2 +-
 mia/3d/transformmock.hh                            |   2 +-
 mia/3d/transio/bbs.cc                              |   2 +-
 mia/3d/transio/serialization.hh                    |   2 +-
 mia/3d/transio/xml.cc                              |   2 +-
 mia/3d/valueattributetranslator.hh                 |   2 +-
 mia/3d/vector.hh                                   |   2 +-
 mia/3d/vectorfield.cc                              |  10 +-
 mia/3d/vectorfield.hh                              |   2 +-
 mia/3d/vfio.cc                                     |   2 +-
 mia/3d/vfio.hh                                     |   2 +-
 mia/3d/vfiotest.cc                                 |   2 +-
 mia/3d/vfiotest.hh                                 |   2 +-
 mia/3d/vfregularizer/test_sor.cc                   |   2 +-
 mia/core.hh                                        |   2 +-
 mia/core/CMakeLists.txt                            |  88 ++-
 mia/core/attribute_names.cc                        |   7 +-
 mia/core/attribute_names.hh                        |  13 +-
 mia/core/attributes.cc                             |   7 +-
 mia/core/attributes.cxx                            |   2 +-
 mia/core/attributes.hh                             |  45 +-
 mia/core/attributetype.hh                          |   2 +-
 mia/core/boundary_conditions.cc                    |   2 +-
 mia/core/boundary_conditions.hh                    |   8 +-
 mia/core/callback.cc                               |   2 +-
 mia/core/callback.hh                               |   2 +-
 mia/core/cmdbooloption.cc                          |   2 +-
 mia/core/cmdbooloption.hh                          |   2 +-
 mia/core/cmdlineparser.cc                          |  53 +-
 mia/core/cmdlineparser.hh                          | 308 +--------
 mia/core/cmdoption.cc                              |   2 +-
 mia/core/cmdoption.hh                              |   2 +-
 mia/core/cmdoptionflags.hh                         |   2 +-
 mia/core/cmdparamoption.hh                         | 463 ++++++++++++++
 mia/core/cmdstringoption.cc                        |   2 +-
 mia/core/cmdstringoption.hh                        |   2 +-
 mia/core/cmdtranslateroption.cc                    |   2 +-
 mia/core/cmdtranslateroption.hh                    |   2 +-
 mia/core/cmeans.cc                                 | 147 +++--
 mia/core/cmeans.hh                                 | 180 +++++-
 mia/core/cmeansinit/kmeans.cc                      |   8 +-
 mia/core/cmeansinit/kmeans.hh                      |   2 +-
 mia/core/cmeansinit/static.cc                      |   2 +-
 mia/core/cmeansinit/static.hh                      |   2 +-
 mia/core/cmeansinit/test_kmeans.cc                 |   2 +-
 mia/core/cmeansinit/test_static.cc                 |   2 +-
 mia/core/combiner.cc                               |   2 +-
 mia/core/combiner.hh                               |   2 +-
 mia/core/cost.cc                                   |   2 +-
 mia/core/cost.cxx                                  |   2 +-
 mia/core/cost.hh                                   |   2 +-
 mia/core/creator.cc                                |   2 +-
 mia/core/creator.hh                                |   2 +-
 mia/core/cstplan.hh                                |   2 +-
 mia/core/datapool.cc                               |   6 +-
 mia/core/datapool.hh                               |   8 +-
 mia/core/defines.hh                                |  23 +-
 mia/core/delayedparameter.hh                       |   2 +-
 mia/core/dictmap.hh                                |   2 +-
 mia/core/distance.cc                               |   2 +-
 mia/core/distance.hh                               |  32 +-
 mia/core/dlloader.cc                               |   2 +-
 mia/core/dlloader.hh                               |   2 +-
 mia/core/dummyhandler.cc                           |   9 +-
 mia/core/dummyhandler.hh                           |  11 +-
 mia/core/errormacro.hh                             |   2 +-
 mia/core/export_handler.hh                         |   2 +-
 mia/core/factory.hh                                |   2 +-
 mia/core/factory_trait.hh                          |   2 +-
 mia/core/fastica.cc                                | 567 +++++++++++++++++
 mia/core/fastica.hh                                | 231 +++++++
 mia/{mesh/io => core/fastica}/CMakeLists.txt       |  15 +-
 mia/core/fastica/deflationnonlinearity.cc          | 210 ++++++
 mia/core/fastica/deflationnonlinearity.hh          |  92 +++
 mia/core/fastica/test_deflationnonlinearity.cc     | 284 +++++++++
 mia/core/fastica_nonlinearity.cc                   | 150 +++++
 mia/core/fastica_nonlinearity.hh                   | 125 ++++
 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                                   |   2 +-
 mia/core/file.hh                                   |   2 +-
 mia/core/filetools.cc                              |  85 +--
 mia/core/filetools.hh                              |  28 +-
 mia/core/filter.cc                                 |   3 +-
 mia/core/filter.hh                                 |  38 +-
 mia/core/fixedwidthoutput.cc                       |   2 +-
 mia/core/fixedwidthoutput.hh                       |   2 +-
 mia/core/flags.hh                                  |   3 +-
 mia/core/flagstring.cc                             |   2 +-
 mia/core/flagstring.hh                             |   2 +-
 mia/core/fullstats.cc                              |   2 +-
 mia/core/fullstats.hh                              |   2 +-
 gsl++/gsldefines.hh => mia/core/gsl_defines.hh     |   2 +-
 mia/core/gsl_iterator.hh                           | 312 +++++++++
 mia/core/gsl_matrix.cc                             | 420 ++++++++++++
 mia/core/gsl_matrix.hh                             | 475 ++++++++++++++
 mia/core/gsl_matrix_vector_ops.cc                  | 187 ++++++
 .../vector.hh => mia/core/gsl_matrix_vector_ops.hh |  32 +-
 gsl++/multimin.cc => mia/core/gsl_multimin.cc      |  32 +-
 gsl++/multimin.hh => mia/core/gsl_multimin.hh      |  18 +-
 mia/core/gsl_pca.cc                                | 101 +++
 mia/core/gsl_pca.hh                                |  90 +++
 mia/core/gsl_vector.cc                             | 203 ++++++
 mia/core/gsl_vector.hh                             | 272 ++++++++
 .../core/gsl_vector_dispatch.hh                    |   2 +-
 gsl++/wavelet.cc => mia/core/gsl_wavelet.cc        |   7 +-
 gsl++/wavelet.hh => mia/core/gsl_wavelet.hh        |   4 +-
 mia/core/handler.cxx                               |  34 +-
 mia/core/handler.hh                                |   6 +-
 mia/core/handlerbase.cc                            |   2 +-
 mia/core/handlerbase.hh                            |   2 +-
 mia/core/histogram.hh                              |  52 +-
 mia/core/history.cc                                |   2 +-
 mia/core/history.hh                                |   2 +-
 mia/core/ica.cc                                    | 291 ++++-----
 mia/core/ica.hh                                    | 138 ++--
 mia/core/ica_template.cxx                          | 112 ++--
 mia/core/ica_template.hh                           |  33 +-
 mia/core/{shape.cc => icaanalysisbase.cc}          |  17 +-
 mia/core/icaanalysisbase.hh                        | 189 ++++++
 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                         |  40 +-
 mia/core/interpolator1d.cxx                        |  27 +-
 mia/core/interpolator1d.hh                         |   7 +-
 mia/core/iodata.cc                                 |   2 +-
 mia/core/iodata.hh                                 |   2 +-
 mia/core/iohandler.cxx                             |  26 +-
 mia/core/iohandler.hh                              |   4 +-
 mia/core/ioplugin.cc                               |   2 +-
 mia/core/ioplugin.cxx                              |   2 +-
 mia/core/ioplugin.hh                               |   2 +-
 mia/core/kmeans.cc                                 |  26 +-
 mia/core/kmeans.hh                                 | 101 ++-
 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/gdas.cc                         |   8 +-
 mia/core/minimizer/gdas.hh                         |   2 +-
 mia/core/minimizer/gdsq.cc                         |   7 +-
 mia/core/minimizer/gdsq.hh                         |   2 +-
 mia/core/minimizer/gsl.cc                          |   2 +-
 mia/core/minimizer/gsl.hh                          |   2 +-
 mia/core/minimizer/test_gdas.cc                    |   2 +-
 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                              |   2 +-
 mia/core/msgstream.hh                              |  17 +-
 mia/core/nccsum.cc                                 |   2 +-
 mia/core/nccsum.hh                                 |   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                               |   2 +-
 mia/core/noisegen.hh                               |   2 +-
 mia/core/optionparser.cc                           |   2 +-
 mia/core/optionparser.hh                           |   2 +-
 mia/core/optparam.cc                               |   2 +-
 mia/core/optparam.hh                               |   2 +-
 mia/core/parallel.hh                               |  72 +++
 mia/core/{combiner.cc => parallelcxx11.cc}         |  21 +-
 mia/core/parallelcxx11.hh                          | 214 +++++++
 mia/core/parameter.cc                              |   2 +-
 mia/core/parameter.cxx                             |   2 +-
 mia/core/parameter.hh                              |   2 +-
 mia/core/paramoption.cc                            |   2 +-
 mia/core/paramoption.hh                            |   2 +-
 mia/core/paramtranslator.cc                        |   2 +-
 mia/core/paramtranslator.hh                        |   2 +-
 mia/core/pixeltype.cc                              |   2 +-
 mia/core/pixeltype.hh                              |   2 +-
 mia/core/plugin_base.cc                            |   2 +-
 mia/core/plugin_base.cxx                           |   2 +-
 mia/core/plugin_base.hh                            |   2 +-
 mia/core/plugin_test.cc                            |   2 +-
 mia/core/probmap.cc                                |  12 +-
 mia/core/probmap.hh                                |   2 +-
 mia/core/product_base.cc                           |   2 +-
 mia/core/product_base.hh                           |   2 +-
 mia/core/productcache.cc                           |   6 +-
 mia/core/productcache.hh                           |  12 +-
 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                              |   2 +-
 mia/core/regmodel.cc                               |   2 +-
 mia/core/regmodel.hh                               |   2 +-
 mia/core/revision.cc                               |   4 +-
 mia/core/scaler1d.cc                               |   2 +-
 mia/core/scaler1d.hh                               |   2 +-
 mia/core/searchpath.cc                             |   2 +-
 mia/core/searchpath.hh                             |   2 +-
 mia/core/selftestcmdoption.cc                      |   2 +-
 mia/core/selftestcmdoption.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 +-
 .../silence_cmake_missing_source_file_warning.c    |   2 -
 mia/core/simpson.hh                                |   2 +-
 mia/core/singular_refobj.hh                        |   2 +-
 mia/core/slopeclassifier.cc                        |   2 +-
 mia/core/slopeclassifier.hh                        |   2 +-
 mia/core/slopestatistics.cc                        |   4 +-
 mia/core/slopestatistics.hh                        |   2 +-
 mia/core/slopevector.hh                            |   2 +-
 mia/core/spacial_kernel.cc                         |   2 +-
 mia/core/spacial_kernel.hh                         |   2 +-
 mia/core/spacialkernel/cdiff.cc                    |  44 +-
 mia/core/spacialkernel/cdiff.hh                    |  20 +-
 mia/core/spacialkernel/gauss.cc                    |   2 +-
 mia/core/spacialkernel/gauss.hh                    |   2 +-
 mia/core/spacialkernel/test_cdiff.cc               |  51 +-
 mia/core/spacialkernel/test_gauss.cc               |   2 +-
 mia/core/sparse_histogram.cc                       |  59 ++
 mia/core/sparse_histogram.hh                       | 150 +++++
 mia/core/sparse_solver.hh                          |   2 +-
 mia/core/splinebc/bc.cc                            |   8 +-
 mia/core/splinebc/bc.hh                            |   2 +-
 mia/core/splinebc/test_bc.cc                       |  14 +-
 mia/core/splinekernel.cc                           |   2 +-
 mia/core/splinekernel.hh                           |   2 +-
 mia/core/splinekernel/bspline.cc                   |   6 +-
 mia/core/splinekernel/bspline.hh                   |   2 +-
 mia/core/splinekernel/test_bspline.cc              |   2 +-
 mia/core/splineparzenmi.cc                         |   2 +-
 mia/core/splineparzenmi.hh                         |   2 +-
 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                                |  20 +-
 mia/core/test_Vector.cc                            |   2 +-
 mia/core/test_attributes.cc                        |   4 +-
 mia/core/test_boundary_conditions.cc               |   2 +-
 mia/core/test_callback.cc                          |   2 +-
 mia/core/test_cmdlineparser.cc                     | 115 +++-
 mia/core/test_cmdlineparseroutput.cc               | 209 ++++++
 mia/core/test_cmdoptionflags.cc                    |   2 +-
 mia/core/test_cmdparamoption.cc                    |  72 +++
 mia/core/test_cmdtranslatoroption.cc               |   2 +-
 mia/core/test_cmdxmlhelp.cc                        | 213 +++++++
 mia/core/test_cmeans.cc                            |  89 ++-
 mia/core/test_core.cc                              |  27 +-
 mia/core/test_core_combined.cc                     |  16 +
 mia/core/test_cost.cc                              |   2 +-
 mia/core/test_cstplan.cc                           |   2 +-
 mia/core/test_datapool.cc                          |  39 +-
 mia/core/test_delayedparameter.cc                  |   2 +-
 mia/core/test_dictmap.cc                           |   2 +-
 mia/core/test_distance.cc                          |   6 +-
 mia/core/test_factoryoption.cc                     |   2 +-
 mia/core/test_fastica.cc                           | 184 ++++++
 mia/core/test_fft1d.cc                             |   2 +-
 mia/core/test_fftslopeclassifier.cc                |   2 +-
 mia/core/test_fifofilter.cc                        |   4 +-
 mia/core/test_filetools.cc                         |  43 +-
 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_gsl_matrix.cc                        | 707 +++++++++++++++++++++
 mia/core/test_gsl_matrix_vector_ops.cc             | 288 +++++++++
 .../core/test_gsl_multimin.cc                      |  24 +-
 mia/core/test_gsl_pca.cc                           |  83 +++
 .../test_vector.cc => mia/core/test_gsl_vector.cc  | 128 +++-
 mia/core/test_handler.cc                           |  10 +-
 mia/core/test_helpers.hh                           |   2 +-
 mia/core/test_histogram.cc                         |  18 +-
 mia/core/test_history.cc                           |   2 +-
 mia/core/test_ica.cc                               |  54 +-
 mia/core/test_index.cc                             |   2 +-
 mia/core/test_interpol.cc                          |   2 +-
 mia/core/test_interpolator1d.cc                    | 180 +++++-
 mia/core/test_iohandler.cc                         |  26 +-
 mia/core/test_kernels.cc                           |   2 +-
 mia/core/test_kmeans.cc                            |  14 +-
 mia/core/test_labelmap.cc                          |   2 +-
 mia/core/test_meanvar.cc                           |   2 +-
 mia/core/test_minimizer.cc                         |   2 +-
 mia/core/test_nccsum.cc                            |   2 +-
 mia/core/test_noisegen.cc                          |   2 +-
 mia/core/test_optionparser.cc                      |   2 +-
 mia/core/test_optparam.cc                          |  29 +-
 mia/core/test_parallelcxx11.cc                     | 103 +++
 mia/core/test_parameter.cc                         |  33 +-
 mia/core/test_parseroutput.cc                      |   2 +-
 mia/core/test_pixeltype.cc                         |   2 +-
 mia/core/test_probmap.cc                           |   2 +-
 mia/core/test_productcache.cc                      |  47 +-
 mia/core/test_property_flags.cc                    |   2 +-
 mia/core/test_pwh.cc                               |   2 +-
 mia/core/test_register.cc                          |   2 +-
 mia/core/test_scaler1d.cc                          |  28 +-
 mia/core/test_seriesstats.cc                       |   2 +-
 mia/core/test_shape.cc                             |   2 +-
 mia/core/test_simpson.cc                           |   2 +-
 mia/core/test_singular_refobj.cc                   |   2 +-
 mia/core/test_slopeclassifier.cc                   |   2 +-
 mia/core/test_slopestatistics.cc                   |   7 +-
 mia/core/test_sparse_histogram.cc                  | 133 ++++
 mia/core/test_sparse_solver.cc                     |   3 +-
 mia/core/test_splinekernel.cc                      |  11 +-
 mia/core/test_splineparzenmi.cc                    |   2 +-
 mia/core/test_sqmin.cc                             |   2 +-
 mia/core/test_statistics.cc                        |   2 +-
 mia/core/test_streamredir.cc                       |   2 +-
 mia/core/test_streamvector.cc                      |  30 +-
 mia/core/test_threadedmsg.cc                       |  19 +-
 mia/core/test_tools.cc                             |   2 +-
 mia/core/test_utils.cc                             |   6 +-
 mia/core/test_watch.cc                             |   2 +-
 mia/core/test_waveletslopeclassifier.cc            |   2 +-
 mia/core/test_xmlinterface.cc                      |   2 +-
 mia/core/testplug/dummy1.cc                        |   2 +-
 mia/core/testplug/dummy2.cc                        |   2 +-
 mia/core/testplug/lala.cc                          |   2 +-
 mia/core/testplug/lolo.cc                          |   2 +-
 mia/core/testplugin.cc                             |   2 +-
 mia/core/testplugin.hh                             |   4 +-
 mia/core/threadedmsg.cc                            |  12 +-
 mia/core/threadedmsg.hh                            |   2 +-
 mia/core/tools.hh                                  |   2 +-
 mia/core/traits.hh                                 |   2 +-
 mia/core/transformation.hh                         |   2 +-
 mia/core/type_traits.hh                            |  24 +-
 mia/core/typedescr.cc                              |   2 +-
 mia/core/typedescr.hh                              |   2 +-
 mia/core/utils.cc                                  |   6 +-
 mia/core/utils.hh                                  |   6 +-
 mia/core/vector.hh                                 |  36 +-
 mia/core/watch.cc                                  |   2 +-
 mia/core/watch.hh                                  |   2 +-
 mia/core/waveletslopeclassifier.cc                 |   3 +-
 mia/core/waveletslopeclassifier.hh                 |   2 +-
 mia/core/xmlinterface.cc                           |  10 +-
 mia/core/xmlinterface.hh                           |   2 +-
 mia/internal/autotest.hh                           |   2 +-
 mia/internal/main.hh                               |   2 +-
 mia/internal/pluginsettest.hh                      |   2 +-
 mia/internal/plugintester.hh                       |   2 +-
 mia/mesh.hh                                        |   2 +-
 mia/mesh/clist.hh                                  |   2 +-
 mia/mesh/filter.cc                                 |   2 +-
 mia/mesh/filter.hh                                 |   2 +-
 mia/mesh/filter/addscale.cc                        |   2 +-
 mia/mesh/filter/addscale.hh                        |   2 +-
 mia/mesh/filter/deltrianglesbynormal.cc            |  12 +-
 mia/mesh/filter/deltrianglesbynormal.hh            |   2 +-
 mia/mesh/filter/scale.cc                           |   2 +-
 mia/mesh/filter/scale.hh                           |   2 +-
 mia/mesh/filter/selectbig.cc                       |   2 +-
 mia/mesh/filter/selectbig.hh                       |   2 +-
 mia/mesh/filter/test_addscale.cc                   |   2 +-
 mia/mesh/filter/test_deltrianglesbynormal.cc       |   2 +-
 mia/mesh/filter/test_scale.cc                      |   2 +-
 mia/mesh/filter/test_selectbig.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                                 | 447 +++----------
 mia/mesh/io/ply.cc                                 | 332 ++++++++--
 mia/mesh/io/stl.cc                                 |  19 +-
 mia/mesh/io/test_meshio.cc                         | 593 +++++++++++++++++
 mia/mesh/test_triangle_neighbourhood.cc            | 273 +++++++-
 mia/mesh/test_triangulate.cc                       |   2 +-
 mia/mesh/triangle_neighbourhood.cc                 |   2 +-
 mia/mesh/triangle_neighbourhood.hh                 |   2 +-
 mia/mesh/triangularMesh.cc                         |  78 ++-
 mia/mesh/triangularMesh.hh                         |   9 +-
 mia/mesh/triangulate.hh                            |   2 +-
 mia/template/bandpass.cxx                          |   2 +-
 mia/template/bandpass.hh                           |   2 +-
 mia/template/binarize.cxx                          |   2 +-
 mia/template/binarize.hh                           |   2 +-
 mia/template/combiner.cxx                          |   2 +-
 mia/template/combiner.hh                           |   2 +-
 mia/template/combiner_filter.hh                    |   2 +-
 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/labelmap.cxx                          |   2 +-
 mia/template/labelmap.hh                           |   2 +-
 mia/template/lsd.hh                                |   2 +-
 mia/template/masked_cost.cxx                       |   2 +-
 mia/template/masked_cost.hh                        |   2 +-
 mia/template/mi.hh                                 |   2 +-
 mia/template/mi_masked.cxx                         |   2 +-
 mia/template/mi_masked.hh                          |   2 +-
 mia/template/multicost.cxx                         |   2 +-
 mia/template/multicost.hh                          |   2 +-
 mia/template/nonrigidregister.cxx                  |   2 +-
 mia/template/nonrigidregister.hh                   |   2 +-
 mia/template/normalize.hh                          |   2 +-
 mia/template/seededwatershed.hh                    |   2 +-
 mia/template/similarity_profile.cxx                |  41 +-
 mia/template/similarity_profile.hh                 |   6 +-
 mia/template/ssd-automask.cxx                      |  51 +-
 mia/template/ssd-automask.hh                       |   5 +-
 mia/template/ssd.hh                                |   2 +-
 mia/template/ssd_masked.cxx                        |   2 +-
 mia/template/ssd_masked.hh                         |   2 +-
 mia/template/trackpoint.cxx                        |   2 +-
 mia/template/trackpoint.hh                         |   2 +-
 mia/template/transformfactory.cxx                  |   2 +-
 mia/template/transformfactory.hh                   |   2 +-
 mia/template/watershed.hh                          |   4 +-
 mia/test/testhelpers.hh                            |   2 +-
 miaconfig.h.cmake                                  |   3 +-
 octave/miaoct.cc                                   |   2 +-
 src/2davgmasked.cc                                 |   2 +-
 src/2dbinarycombine.cc                             |   2 +-
 src/2dcost.cc                                      |   2 +-
 src/2ddeform.cc                                    |   2 +-
 src/2ddistance.cc                                  |   2 +-
 src/2deval-transformquantity.cc                    |   4 +-
 src/2dforce.cc                                     |   2 +-
 src/2dfuzzysegment.cc                              |   2 +-
 src/2dgrayimage-combine-to-rgb.cc                  |   2 +-
 src/2dgroundtruthreg.cc                            |   5 +-
 src/2dimagecombine-dice.cc                         |   2 +-
 src/2dimagecombiner.cc                             |   2 +-
 src/2dimagecreator.cc                              |   2 +-
 src/2dimagefilter.cc                               |   2 +-
 src/2dimagefilterstack.cc                          |   2 +-
 src/2dimagefullstats.cc                            |   2 +-
 src/2dimageregistration.cc                         |   2 +-
 src/2dimageselect.cc                               |   2 +-
 src/2dimageseries-maximum-intensity-projection.cc  |   2 +-
 src/2dimagestack-cmeans.cc                         | 129 +---
 src/2dimagestats.cc                                |   2 +-
 src/2dlerp.cc                                      |   2 +-
 src/2dmany2one-nonrigid.cc                         |  13 +-
 src/2dmulti-force.cc                               |   2 +-
 src/2dmulti-nrreg.cc                               |   2 +-
 src/2dmultiimageregistration.cc                    |   2 +-
 src/2dmultiimageto3d.cc                            |   2 +-
 src/2dmultiimagevar.cc                             |   2 +-
 src/2dmyocard-ica.cc                               |  33 +-
 src/2dmyocard-icaseries.cc                         |   9 +-
 src/2dmyocard-segment.cc                           |  14 +-
 src/2dmyocard-upsloap.cc                           |   3 +-
 src/2dmyoica-full.cc                               | 191 +++---
 src/2dmyoica-nonrigid-parallel.cc                  |  35 +-
 src/2dmyoica-nonrigid.cc                           |  26 +-
 src/2dmyoica-nonrigid2.cc                          |  20 +-
 src/2dmyoicapgt.cc                                 |  79 ++-
 src/2dmyomilles.cc                                 |  19 +-
 src/2dmyoperiodic-nonrigid.cc                      |   4 +-
 src/2dmyopgt-nonrigid.cc                           |   5 +-
 src/2dmyoserial-nonrigid.cc                        |   4 +-
 src/2dmyoseries-compdice.cc                        |   4 +-
 src/2dmyoseries-dice.cc                            |   4 +-
 src/2dmyoset-all2one-nonrigid.cc                   |  12 +-
 src/2dnrreg.cc                                     |   2 +-
 src/2dsegcompare.cc                                |   2 +-
 src/2dseghausdorff.cc                              |   2 +-
 src/2dsegment-ahmed.cc                             |   6 +-
 src/2dsegment-fuzzyw.cc                            |   3 +-
 src/2dsegment-local-cmeans.cc                      | 438 +++++++++++++
 src/2dsegment-local-kmeans.cc                      | 366 +++++++++++
 src/2dsegment-per-pixel-kmeans.cc                  | 239 +++++++
 src/2dsegmentcropbox.cc                            |   2 +-
 src/2dsegseriesstats.cc                            |   4 +-
 src/2dsegshift.cc                                  |   2 +-
 src/2dsegshiftperslice.cc                          |   2 +-
 src/2dseries-mincorr.cc                            |   3 +-
 src/2dseries-sectionmask.cc                        |   2 +-
 src/2dseries-segdistance.cc                        |   6 +-
 src/2dseries2dordermedian.cc                       |   6 +-
 src/2dseries2sets.cc                               |   3 +-
 src/2dseriescorr.cc                                |   3 +-
 src/2dseriesgradMAD.cc                             |   6 +-
 src/2dseriesgradvariation.cc                       |   4 +-
 src/2dserieshausdorff.cc                           |   2 +-
 src/2dseriessmoothgradMAD.cc                       |   6 +-
 src/2dseriestovolume.cc                            |   2 +-
 src/2dstack-cmeans-presegment.cc                   | 144 +----
 src/2dstackfilter.cc                               |   4 +-
 src/2dto3dimage.cc                                 |   2 +-
 src/2dto3dimageb.cc                                |   2 +-
 src/2dtrackpixelmovement.cc                        |   4 +-
 src/2dtransform.cc                                 |   2 +-
 src/2dtransformation-to-strain.cc                  |   3 +-
 src/3dbinarycombine.cc                             |   2 +-
 src/3dbrainextractT1.cc                            |   2 +-
 src/3dcombine-imageseries.cc                       |   2 +-
 src/3dcombine-mr-segmentations.cc                  |   2 +-
 src/3dcost-translatedgrad.cc                       |   3 +-
 src/3dcost.cc                                      |   2 +-
 src/3dcrispsegment.cc                              |   2 +-
 src/3ddeform.cc                                    |   2 +-
 src/3ddistance-stats.cc                            |   2 +-
 src/3ddistance.cc                                  |   2 +-
 src/3deval-transformquantity.cc                    |   4 +-
 src/3dfield2norm.cc                                |   2 +-
 src/3dforce.cc                                     |   6 +-
 src/3dfuzzysegment.cc                              |   2 +-
 src/3dgetsize.cc                                   |   2 +-
 src/3dgetslice.cc                                  |   2 +-
 src/3dimageaddattributes.cc                        |   2 +-
 src/3dimagecombine.cc                              |   2 +-
 src/3dimagecreator.cc                              |   2 +-
 src/3dimagefilter.cc                               |   2 +-
 src/3dimagefilterstack.cc                          |   2 +-
 src/3dimageselect.cc                               |   2 +-
 src/3dimagestatistics-in-mask.cc                   |   2 +-
 src/3dimagestats.cc                                |   2 +-
 src/3dlandmarks-distances.cc                       |   3 +-
 src/3dlandmarks-transform.cc                       |   3 +-
 src/3dlerp.cc                                      |   6 +-
 src/3dmany2one-nonrigid.cc                         |  13 +-
 src/3dmaskseeded.cc                                |   2 +-
 src/3dmotioncompica-nonrigid.cc                    |  23 +-
 src/3dmulti-nrreg.cc                               |   2 +-
 src/3dnonrigidreg-alt.cc                           |   2 +-
 src/3dnonrigidreg.cc                               |   2 +-
 src/3dnrreg.cc                                     |   2 +-
 src/3dprealign-nonrigid.cc                         |   4 +-
 src/3dpropose-boundingbox.cc                       |   2 +-
 src/3drigidreg.cc                                  |   2 +-
 src/3dsegment-ahmed.cc                             |   6 +-
 src/3dserial-nonrigid.cc                           |   4 +-
 src/3dseries-track-intensity.cc                    |   4 +-
 src/3dtrackpixelmovement.cc                        |   4 +-
 src/3dtransform.cc                                 |   3 +-
 src/3dtransform2vf.cc                              |   3 +-
 src/3dvectorfieldcreate.cc                         |   2 +-
 src/3dvf2transform.cc                              |   3 +-
 src/3dvfcompare.cc                                 |   3 +-
 src/CMakeLists.txt                                 |   9 +-
 src/cmeans.cc                                      |  30 +-
 src/distance-mesh2mask.cc                          |   4 +-
 src/filenumberpattern.cc                           |   5 +-
 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                                |   8 +-
 src/fluid2d/types.hh                               |   2 +-
 src/fluid2d/vfluid.cc                              |   2 +-
 src/fluid2d/vfluid.hh                              |   2 +-
 src/fluid3d/eqn_solver.cc                          |   2 +-
 src/fluid3d/eqn_solver.hh                          |   2 +-
 src/fluid3d/main.cc                                |   2 +-
 src/fluid3d/sor_solver.cc                          |  31 +-
 src/fluid3d/sor_solver.hh                          |   2 +-
 src/fluid3d/typedefs.hh                            |   2 +-
 src/fluid3d/vfluid.cc                              |  51 +-
 src/fluid3d/vfluid.hh                              |   2 +-
 src/isosurface/iso.cc                              |   2 +-
 src/isosurface/iso_backend.cc                      |   2 +-
 src/isosurface/iso_from_slices.cc                  |   2 +-
 src/isosurface/mesh_convert.cc                     |   2 +-
 src/labelsort.cc                                   |   2 +-
 src/mesh-deformable-model.cc                       |  21 +-
 src/mesh-to-maskimage.cc                           |   2 +-
 src/meshdistance-to-stackmask.cc                   |   6 +-
 src/meshfilter.cc                                  |   2 +-
 src/multihist.cc                                   |   2 +-
 src/multiimage-cmeans.cc                           |   2 +-
 src/myowavelettest.cc                              |   6 +-
 src/plugin-help.cc                                 |   2 +-
 src/raw2image.cc                                   |   2 +-
 src/raw2volume.cc                                  |   2 +-
 src/test_plugins_as_installed.cc                   |   9 +-
 src/wavelettrans.cc                                |   7 +-
 test/test_ioplugins.cc                             |   2 +-
 test/test_minimizer.cc                             |   4 +-
 testdata/4D.off                                    |   6 +
 testdata/EnIm1.dcm                                 | Bin 0 -> 266310 bytes
 testdata/ND.off                                    |   7 +
 testdata/binary100x2uc.bmp                         | Bin 0 -> 162 bytes
 testdata/gray100x2c-4bit.bmp                       | Bin 0 -> 158 bytes
 testdata/gray100x2c.bmp                            | Bin 0 -> 1090 bytes
 testdata/gray100x2uc-4bit.bmp                      | Bin 0 -> 242 bytes
 testdata/gray20x20c.bmp                            | Bin 0 -> 1164 bytes
 testdata/gray20x20c.jpg                            | Bin 0 -> 504 bytes
 testdata/gray20x20c.tif                            | Bin 0 -> 319 bytes
 testdata/gray2x3-1.png                             | Bin 0 -> 168 bytes
 testdata/gray2x3-1.tif                             | Bin 0 -> 182 bytes
 testdata/gray2x3-16.png                            | Bin 0 -> 177 bytes
 testdata/gray2x3-16.tif                            | Bin 0 -> 202 bytes
 testdata/gray2x3-multiframe.tif                    | Bin 0 -> 598 bytes
 testdata/gray2x3.bmp                               | Bin 0 -> 1158 bytes
 testdata/gray2x3.c                                 |  12 +
 testdata/gray2x3.jpg                               | Bin 0 -> 239 bytes
 testdata/gray2x3.png                               | Bin 0 -> 155 bytes
 testdata/gray2x3.tif                               | Bin 0 -> 302 bytes
 testdata/octahedron-with-normals-and-color.off     |  17 +
 testdata/octahedron-with-normals-and-color.ply     |  32 +
 testdata/octahedron-with-normals-and-scale.ply     |  30 +
 testdata/octahedron-with-normals.off               |  17 +
 testdata/octahedron-with-normals.ply               |  29 +
 testdata/octahedron.off                            |  17 +
 testdata/octahedron.ply                            |  24 +
 testdata/octahedron.stl                            |  58 ++
 testdata/poly.off                                  |   8 +
 testdata/rgb3x2-24bit.bmp                          | Bin 0 -> 78 bytes
 testdata/rgb3x2-24bit.jpg                          | Bin 0 -> 840 bytes
 testdata/rgb3x2-24bit.png                          | Bin 0 -> 167 bytes
 testdata/vertex_error.off                          |   7 +
 1517 files changed, 19113 insertions(+), 6892 deletions(-)

diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..8dabbaa
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,38 @@
+sudo: required
+dist: trusty
+language: generic
+
+env:
+  matrix: 
+  - COVERAGE=ON EXTRA=OFF 
+  - COVERAGE=OFF EXTRA=ON
+  global:
+  - CTEST_PARALLEL_LEVEL=2 
+  - secure: GJh7knKOeyjofQFswCHI4H1VeRBYDmGrZjBiW/yNoGqLvvAZi32HF2d5gHj2vrsGBqto/5mQrydo1rH6Q85VuZ7ZNZmcmiMVA5htv61WKfxzc50mSrkSfvDTb0MOmR8QcpWpK4YAfCYd4r8drPfpbRdHUvTfEk9tS8I/1LGLuos3cLRU+OojEuvndUC8rGHtCRtDswFmngbc96gkAuHfAd7LiaJ5EY+pqOmHY4xMgi5Ev4FnGdkUczUcpisxee/48QIite9lw5E0pemPepKuhrwUJRvnzb9Tgsp94R42mzymvnKyLsttdUQtUItTQshTqEtWSFf/6GO9GPyUXAgR+BDsQ9ODlxOC6+Cip0HqxCvgDfIZarVaj5/2/ZwiyjocEinhSzFiIJF9SShpqSpP9MUgS/ZL/9y6GMiDXx19zkxBJ9kXP+7vH/G/7qFZ6f1aVuDemgKit5styDQDnLyd/FlBrz3oWftj [...]
+
+install:
+- sudo add-apt-repository ppa:gert-die/trusty-mia -y 
+- sudo apt-get update -qq
+- sudo apt-get install -o APT::Get::Install-Recommends=false -o APT::Get::Install-Suggests=false -y libmaxflow-dev libdcmtk2-dev libeigen3-dev libfftw3-dev libgsl0-dev libgts-dev libhdf5-dev libitpp-dev libnifti-dev libnlopt-dev libopenexr-dev libpng-dev libtbb-dev libtiff-dev libvtk6-dev libvistaio-dev libxml++2.6-dev xsltproc docbook-xsl doxygen  graphviz libblas-dev libboost-filesystem-dev libboost-regex-dev libboost-serialization-dev libboost-system-dev libboost-test-dev python-lxml
+- pip install --user cpp-coveralls
+before_script:
+- mkdir build
+- cd build
+- echo COVERAGE=$COVERAGE EXTRA=$EXTRA
+- cmake .. -DALWAYS_CREATE_DOC=$EXTRA -DSTRICT_DEPENDECIES=ON -DMIA_CREATE_MANPAGES=$EXTRA -DMIA_CREATE_NIPYPE_INTERFACES=$EXTRA -DENABLE_COVERAGE=$COVERAGE -DDISABLE_PROGRAMS=$COVERAGE -DUSE_MATHJAX=YES
+script:
+- make -j2
+after_success:
+- make test
+- cd .. 
+- if test "x$COVERAGE" = "xON"; then coveralls --exclude CMakeFiles --exclude src --gcov-options '\-lp' -b $(pwd)/build 2>&1 >/dev/null ; fi 
+
+addons:
+  coverity_scan:
+    project:
+      name: gerddie/mia
+      version: 2.2.7+
+      description: Medical imaga analysis library
+    notification_email: gw.fossdev at gmail.com
+    build_command: make -j3 
+    branch_pattern: coverity_scan
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 35ac512..5e60eff 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,7 +18,8 @@
 
 PROJECT("mia")
 
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8.5 FATAL_ERROR)
+# now need OBJECT libraries 
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8 FATAL_ERROR)
 
 if(COMMAND cmake_policy)
   cmake_policy(SET CMP0003 NEW)
@@ -51,10 +52,10 @@ include(CheckCXXSourceCompiles)
 SET(VENDOR "Gert Wollny")
 SET(PACKAGE_NAME "mia")
 SET(MAJOR_VERSION 2)
-SET(MINOR_VERSION 2)
-SET(MICRO_VERSION 7)
-SET(INTERFACE_AGE 3)
-SET(BINARY_AGE    3)
+SET(MINOR_VERSION 4)
+SET(MICRO_VERSION 1)
+SET(INTERFACE_AGE 0)
+SET(BINARY_AGE    0)
 
 #
 #SET(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
@@ -78,6 +79,9 @@ OPTION(STRICT_DEPENDECIES "require that all requested optinal dependencies are a
 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)
+OPTION(ENABLE_COVERAGE "Enable code coverage tests" FALSE)
+OPTION(DISABLE_PROGRAMS "Don't build the programs nor documentation (only for testing purposes)" FALSE)
+OPTION(MIA_CREATE_USERDOC "Enable creation of html user documentation" TRUE)
 
 INCLUDE(GNUInstallDirs)
 
@@ -105,6 +109,13 @@ IF(UNIX)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  ${CXX_11_FLAG} -fvisibility=hidden")
 ENDIF(UNIX)
 
+IF (ENABLE_COVERAGE)
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -O0 -g -DMIA_COVERAGE")
+  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
+  set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} --coverage")
+  set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage")
+ENDIF()
+
 INCLUDE (${CMAKE_CURRENT_SOURCE_DIR}/cmake/checkCpp0xAuto.cmake)
 INCLUDE (${CMAKE_CURRENT_SOURCE_DIR}/cmake/checkCpp0xLambda.cmake)
 INCLUDE (${CMAKE_CURRENT_SOURCE_DIR}/cmake/checkSSEAttributeVectorCanUseSubscript.cmake)
@@ -251,14 +262,19 @@ ENDIF (MSYS OR MINGW)
 ################################################################################
 #
 # Intel Threading Building Blocks 
-# 
-FIND_PACKAGE(TBB REQUIRED)
-IF(TBB_FOUND) 
-  include_directories(${TBB_INCLUDE_DIRS})
-  link_directories(${TBB_LIBRARY_DIRS})
-ELSE(TBB_FOUND) 
-  MESSAGE(FATAL " TBB not found")
-ENDIF(TBB_FOUND)
+#
+OPTION(WITH_TBB "Use intel threading building blocks for threading, otherwise use c++11 threads" OFF)
+
+IF(WITH_TBB) 
+  FIND_PACKAGE(TBB REQUIRED)
+  IF(TBB_FOUND) 
+    include_directories(${TBB_INCLUDE_DIRS})
+    link_directories(${TBB_LIBRARY_DIRS})
+    SET(HAVE_TBB 1)
+  ELSE(TBB_FOUND) 
+    MESSAGE(FATAL " TBB not found")
+  ENDIF(TBB_FOUND)
+ENDIF()
 #
 # End Intel Threading Building Blocks 
 #
@@ -267,7 +283,7 @@ ENDIF(TBB_FOUND)
 ################################################################################
 #
 # Intel Threading Building Blocks 
-# 
+# why is this here? 
 
 SET(CMAKE_THREAD_PREFER_PTHREAD ON) 
 FIND_PACKAGE(Threads)
@@ -291,28 +307,11 @@ INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS})
 LINK_DIRECTORIES(${EIGEN3_LIBRARY_DIRS})
 
 
-################################################################################
-# 
-# search for some blas
-# 
-
-FIND_PACKAGE(BLAS)
-IF (NOT BLAS_LIBRARIES) 
-  MESSAGE(FATAL_ERROR "A library that implements the BLAS interface is required") 
-ENDIF(NOT BLAS_LIBRARIES) 
-
 IF(UNIX)
   GET_BOOST_LINKERFLAG(BOOST_LIBFLAG "${BOOST_DEPS}")
-  SET(MIA_DEPEND_LIBRARIES "${BOOST_LIBFLAG} ${BLAS_LIBRARIES} ${TBB_LIBRARIES} ${PTHREADLIB} -ldl")
+  SET(MIA_DEPEND_LIBRARIES "${BOOST_LIBFLAG} ${TBB_LIBRARIES} ${PTHREADLIB} -ldl")
 ENDIF(UNIX)
 
-
-ADD_DEFINITIONS(-DHAVE_BLAS)
-#
-# End BLAS 
-# 
-##################################################################################
-
 ##################################################################################
 #
 # Find gzip for man page compression 
@@ -338,7 +337,7 @@ IF(NOT WIN32)
   IF(DL_NOTFOUND)
     MESSAGE(FATAL_ERROR "non-windows systems without libdl.so are not yet supported")
   ENDIF(DL_NOTFOUND)
-  SET(BASELIBS  ${BOOST_DEPS} ${PTHREADLIB} ${DL})
+  SET(BASELIBS  ${GSL_LIBRARIES} ${BOOST_DEPS} ${PTHREADLIB} ${DL})
 ENDIF(NOT WIN32)
 SET(PLUGSUFFIX ".mia")
 
@@ -377,9 +376,17 @@ ENDIF(WITH_FFTWD)
 ####################################################################################
 #
 # add xml library for loading/storing segmentations and document creation  
+# search it olny once
 #
-pkg_check_modules(XMLPP libxml++-2.6 REQUIRED)
+pkg_check_modules(XMLPP libxml++-3.0)
+
+IF (NOT XMLPP_FOUND)
+  pkg_check_modules(XMLPP libxml++-2.6 REQUIRED)
+ENDIF()
+
 IF (XMLPP_FOUND)
+STRING(REGEX MATCH "[0-9]*" XMLPP_MAJOR_VERSION "${XMLPP_VERSION}")
+  SET(LIBXMLPP_VERSION ${XMLPP_MAJOR_VERSION})
   INCLUDE_DIRECTORIES(${XMLPP_INCLUDE_DIRS})
   LINK_DIRECTORIES(${XMLPP_LIBRARY_DIRS})
 ENDIF (XMLPP_FOUND)
@@ -453,22 +460,29 @@ ENDIF(ALWAYS_CREATE_DOC)
 #
 SET(CREATE_USERDOC FALSE)
 
-FIND_PACKAGE(PythonInterp)
-IF(PYTHONINTERP_FOUND) 
-  EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} -c "import lxml"  RESULT_VARIABLE LXML_ERR)
-  IF(LXML_ERR) 
-    MESSAGE(python found, but no lxml, no user documantation will be created) 
-  ELSE(LXML_ERR)
-    SET(CREATE_USERDOC TRUE)
-  ENDIF(LXML_ERR) 
-ENDIF(PYTHONINTERP_FOUND)
-
+#if no programs are build, no userdoc can be created 
+IF (NOT DISABLE_PROGRAMS) 
+  FIND_PACKAGE(PythonInterp)
+  IF(PYTHONINTERP_FOUND) 
+    EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} -c "import lxml"  RESULT_VARIABLE LXML_ERR)
+    IF(LXML_ERR)
+      MESSAGE(python found, but no lxml, no user documantation will be created) 
+      IF(STRICT_DEPENDECIES)
+        MESSAGE(ERROR ": requested user Html documentation creation, but python-lxml not found")
+      ELSE(STRICT_DEPENDECIES)
+        MESSAGE(python found, but no lxml, no user documantation will be created)
+        SET(MIA_CREATEUSERDOC FALSE)
+      ENDIF(STRICT_DEPENDECIES)
+    ENDIF(LXML_ERR) 
+  ENDIF(PYTHONINTERP_FOUND)
+ENDIF()
 
 #############################################
 #
 # define plug-in related values and directories and add the test directory link target 
 # 
 
+DEFINE_PLUGIN_NAMES( fastica  "deflation;symmetric" ${PLUGIN_INSTALL_PATH})
 DEFINE_PLUGIN_NAMES( 1d  "cmeans;spacialkernel;splinebc;splinekernel" ${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})
@@ -485,7 +499,6 @@ DEFINE_PLUGIN_NAMES( mesh "filter;io" ${PLUGIN_INSTALL_PATH})
 DEFINE_PLUGIN_NAMES( minimizer  "singlecost" ${PLUGIN_INSTALL_PATH})
 DEFINE_PLUGIN_NAMES( rgbimage "io" ${PLUGIN_INSTALL_PATH})
 
-ADD_SUBDIRECTORY(gsl++   )
 ADD_SUBDIRECTORY(mia     )
 ADD_SUBDIRECTORY(addons  )
 ADD_SUBDIRECTORY(testdata)
@@ -534,6 +547,13 @@ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README ${CMAKE_CURRENT_SOURCE_DIR}/COP
  
 ADD_CUSTOM_TARGET(dist bash ${CMAKE_SOURCE_DIR}/create_package "${PACKAGE_NAME}" "${PACKAGE_VERSION}" "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}")
 
-ADD_SUBDIRECTORY(src)
+IF (NOT DISABLE_PROGRAMS)
+  ADD_SUBDIRECTORY(src)
+  ADD_SUBDIRECTORY(doc)
+ELSE()
+  MESSAGE(STATUS "NOT building programs nor documentation as requested")
+ENDIF()
+
 ADD_SUBDIRECTORY(test)
-ADD_SUBDIRECTORY(doc)
+
+
diff --git a/ChangeLog b/ChangeLog
index 3c08f54..457b3de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,53 @@
+2.4.1 
+    * Add additional search path for MathJax
+    * Correct type in VistaIO 
+    * Change file load handling to throw when file is not available 
+
+2.4.0
+
+    * Add support for a repeatable command line option; Closes: #183
+    * Add interface for pixel type filter conversion test; Closes:  #5
+    * Work on enabling compiling against DCMTK that requires ICONV
+    * Make it compile on FreeBSD
+    * Add new filters
+    * Add tests and improve code coverage
+    * Improve fuzzy-segmentation algorithms by using tested code
+      (kmeans, probability estimation)
+    * Add support for piping through the vista plugin interface
+    * correct type of sparse histogram bin value
+    * Add new program that applies a 2D local cmeans segmentaion
+    * Correct Coverity issues
+    * Clean up code of similarity_profiles and add test
+    * Add test for 2D image comparison
+    * Add a sparse histogram implementation
+    * Remove the code for the so-called auto-ICA estimation
+    * install lxml in travis via pip to work around travis-ci/travis-ci#4948
+    * Remove need to use a dummy file for plug-in and test creation
+    * disable unused registration code in build
+    * Prepare mia for compilation with boost-1.60
+    * Correct compilation with g++-6
+    * Correct copyright
+    * remove obsolete create_2dinterpolation_factory function
+    * remove the create_XXinterpolation_factory functions
+    * Correct reading of 24-bit RGB BMP images
+    * Update bmp image io to support compressed 4bit pixel reading
+    * Correct critical point and matrix eigenvalue/vector handlinG
+    * Remove all optimization from coverage build
+    * Remove the src/ directory from coveralls check, can't be tested in time
+    * Add possibility to use installed mathjax files
+    * Add generic get_minmax function to images
+    * Correct code to prepare for auto-threshholding
+    * Enable compilation with libxml++3.0 and libxml-2.6
+    * Start implementing switchable ICA implementations.
+    * Use c++11 threads as default, instead of TBB
+    * Change reading nifti oriention
+    * Update CXDBitImage to not use vector<bool>
+    * Read nifti files without applying the slope transformation
+    * Add SpacingBetweenSlices Attribute to DCMTK IO
+    * More code parallelization
+    * Add const-correctnes to the gsl::matrix class and its iterators. Closes [tickets:#169]
+
+
 2.2.7
 
     * Correct tests that fail on arm64, armhf and ppc64el
@@ -28,7 +78,7 @@
 
   New features:
 
-  * Add programs for 
+  * Add programs for
       - cmeans on sparse input data
       - combining an abitrary number of images with an comutative operation
       - estimating a bounding box around the data in an image
@@ -39,9 +89,9 @@
       - select largest connected mesh part
       - add a scale value taken from a 3D image to each vertex
 
-  * enable use of parallel gzip/xz in IO if available 
+  * enable use of parallel gzip/xz in IO if available
   * Add image filters
-      - 3D labelmap filter 
+      - 3D labelmap filter
       - 3D re-orientation filter re-enabled
       - 2D maxflow/mincut segmentation filter 
       - 2D sobel filter  
diff --git a/README.md b/README.md
index 5e1f7b6..1cecd1f 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,8 @@
+
+[![Build Status](https://travis-ci.org/gerddie/mia.svg?branch=master)](https://travis-ci.org/gerddie/mia)
+[![Coverity Status](https://scan.coverity.com/projects/1013/badge.svg)](https://scan.coverity.com/projects/medical-image-analysis)
+[![Coverage Status](https://coveralls.io/repos/github/gerddie/mia/badge.svg?branch=master)](https://coveralls.io/github/gerddie/mia?branch=master)
+
 This repository is a mirror of the master branch of
 
     git://git.code.sf.net/p/mia/mia2
diff --git a/addons/dicom/CMakeLists.txt b/addons/dicom/CMakeLists.txt
index 835100d..97029ee 100644
--- a/addons/dicom/CMakeLists.txt
+++ b/addons/dicom/CMakeLists.txt
@@ -29,6 +29,8 @@ IF (WITH_DCMTK)
   IF(DCMTK_FOUND)
     DEFINE_PROPERTY(GLOBAL PROPERTY HAVE_DCMTK_PROP BRIEF_DOCS "yeah" FULL_DOCS "yeah")
     SET(dicom4mia_deps mia3d ${DCMTK_LIBRARIES})
+
+   
     MIA_ADD_LIBRARY(dicom4mia "${dicom4mia_SOURCES}" "${dicom4mia_deps}")
     INSTALL_BASE(dicom4mia)
 
diff --git a/addons/dicom/dcm2d.cc b/addons/dicom/dcm2d.cc
index 3eaac03..6f0529a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,11 +41,17 @@ CDicom2DImageIOPlugin::CDicom2DImageIOPlugin():
 	add_supported_type(it_sshort);
 
 	CFloatTranslator::register_for("SliceLocation");
+	CFloatTranslator::register_for(IDSpacingBetweenSlices);
 	CDoubleTranslator::register_for("AcquisitionTime"); 
 	CSITranslator::register_for("SeriesNumber");
 	CSITranslator::register_for("AcquisitionNumber");
 	CSITranslator::register_for("InstanceNumber");
 	CPatientPositionTranslator::register_for(IDPatientPosition);
+
+	CFloatTranslator::register_for(IDRescaleSlope);
+	CFloatTranslator::register_for(IDRescaleIntercept); 
+
+	
 	add_suffix(".dcm");
 	add_suffix(".DCM");
 }
diff --git a/addons/dicom/dcm2d.hh b/addons/dicom/dcm2d.hh
index 753fdb8..b2c052d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/dcm3d.cc b/addons/dicom/dcm3d.cc
index 35a67fe..33f1cf8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,24 +49,29 @@ CDicom3DImageIOPlugin::CDicom3DImageIOPlugin():
 	add_supported_type(it_sshort);
 
 	CFloatTranslator::register_for("SliceLocation");
+	CFloatTranslator::register_for(IDSpacingBetweenSlices);
 	CDoubleTranslator::register_for("AcquisitionTime"); 
 	CSITranslator::register_for("SeriesNumber");
 	CSITranslator::register_for("AcquisitionNumber");
 	CSITranslator::register_for("InstanceNumber");
 	CPatientPositionTranslator::register_for(IDPatientPosition);
+	
+	CFloatTranslator::register_for(IDRescaleSlope);
+	CFloatTranslator::register_for(IDRescaleIntercept); 
+
 	add_suffix(".dcm");
 	add_suffix(".DCM");
 
 }
 
 struct attr_less {
-	bool operator()(const PAttribute& a, const PAttribute& b) {
+	bool operator()(const PAttribute& a, const PAttribute& b) const {
 		return a->is_less(*b);
 	}
 };
 
 struct image_instance_less {
-	bool operator()(const P2DImage& a, const P2DImage& b) {
+	bool operator()(const P2DImage& a, const P2DImage& b) const {
 		return !a->get_attribute(IDInstanceNumber)->is_less(*b->get_attribute(IDInstanceNumber));
 	}
 };
@@ -125,6 +130,7 @@ bool C3DImageCreator::operator() ( const T2DImage<T>& image)
 		if (m_size2d != image.get_size()) {
 			throw invalid_argument("Series input images have different slice size");
 		}
+		// This should use IDSpacingBetweenSlices
 		if (m_has_slice_location) {
 			float new_slice_pos = image.template get_attribute_as<float>(IDSliceLocation);
 			m_delta_z = new_slice_pos - m_slice_pos;
diff --git a/addons/dicom/dcm3d.hh b/addons/dicom/dcm3d.hh
index 6be85c8..ccee824 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/dicom4mia.cc b/addons/dicom/dicom4mia.cc
index 5fad969..4316f90 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ const SLookupInit lookup_init[] = {
 	{IDImageType, DCM_ImageType, false, tr_no, NULL},
 	{IDSliceLocation, DCM_SliceLocation, false, tr_no, NULL},
 	{IDSliceThickness, DCM_SliceThickness, false, tr_no, NULL},
+	{IDSpacingBetweenSlices, DCM_SpacingBetweenSlices, 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},
@@ -100,6 +101,9 @@ const SLookupInit lookup_init[] = {
 	{IDPositionerPrimaryAngleIncrement, DCM_PositionerPrimaryAngleIncrement, false, tr_no, NULL},
 	{IDPositionerSecondaryAngleIncrement, DCM_PositionerSecondaryAngleIncrement, false, tr_no, NULL},
 	{IDPhotometricInterpretation, DCM_PhotometricInterpretation, false, tr_yes_defaulted, "MONOCHROME2"},
+
+	{IDRescaleIntercept, DCM_RescaleIntercept, false, tr_yes_defaulted, "0.0"},
+	{IDRescaleSlope, DCM_RescaleSlope, false, tr_yes_defaulted, "0.0"},
 	
 	{NULL, DcmTagKey(), false, tr_no, NULL}
 };
@@ -131,8 +135,9 @@ struct CDicomReaderData {
 	Uint16 getUint16(const DcmTagKey &tagKey, bool required, Uint16 default_value = 0);
 	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);
+	double getFloat64(const DcmTagKey &tagKey, bool required, double default_value = 0);
 	bool getFloat64ArrayFromString(const DcmTagKey &tagKey, vector<double>& values, const string& msg);
+	bool getFloat64ArrayFromString(const OFString &value_str, 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 = "");
@@ -147,7 +152,7 @@ struct CDicomReaderData {
 
 	void getAcquisitionTimeIfAvailable(CAttributedData& image); 
 
-	C2DFVector getPixelSize();
+	C2DFVector getPixelSize(double *dz);
 
 	C2DFVector getImagePixelSpacing(); 
 	
@@ -203,13 +208,13 @@ C2DBounds CDicomReader::image_size()const
 
 C2DFVector CDicomReader::get_pixel_size() const
 {
-	return impl->getPixelSize();
+	return impl->getPixelSize(nullptr);
 }
 
 C3DFVector CDicomReader::get_voxel_size(bool warn) const
 {
-	auto size2d = impl->getPixelSize();
-	auto thinkness = impl->getFloat64(DCM_SpacingBetweenSlices, false,0); 
+	double thinkness = -1; 
+	auto size2d = impl->getPixelSize(&thinkness);
 	if (thinkness <= 0.0 && warn) 
 		cvwarn() << "DICOM: 3D multiframe image doesn't provide a spacing between slices, most likely "
 			 << "the input file does not constitute a volume"; 
@@ -452,7 +457,7 @@ void CDicomReaderData::getAcquisitionTimeIfAvailable(CAttributedData& image)
 	image.set_attribute(IDAcquisitionTime, of_time.getTimeInSeconds()); 
 }						
 
-float CDicomReaderData::getFloat64(const DcmTagKey &tagKey, bool required, double default_value)
+double CDicomReaderData::getFloat64(const DcmTagKey &tagKey, bool required, double default_value)
 {
 	Float64 value = default_value;
 	OFCondition success = dcm.getDataset()->findAndGetFloat64(tagKey, value);
@@ -464,22 +469,11 @@ float CDicomReaderData::getFloat64(const DcmTagKey &tagKey, bool required, doubl
 	return value;
 }
 
-bool CDicomReaderData::getFloat64ArrayFromString(const DcmTagKey &tagKey, vector<double>& values, const string& msg)
+bool CDicomReaderData::getFloat64ArrayFromString(const OFString &value_str, 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("\\"));
+	vector<string> tockens; 
+	string svalues(value_str.begin(), value_str.end()); 
+        boost::split(tockens, svalues, boost::is_any_of("\\"));
 
 	if (tockens.size() != values.size()) {
 		cvwarn() << "Bogus " << msg << " attribute of " << tockens.size() 
@@ -495,6 +489,19 @@ bool CDicomReaderData::getFloat64ArrayFromString(const DcmTagKey &tagKey, vector
 		}
         }
 	return true; 
+}
+
+
+bool CDicomReaderData::getFloat64ArrayFromString(const DcmTagKey &tagKey, vector<double>& values, const string& msg)
+{
+	OFString help;
+	OFCondition success = dcm.getDataset()->findAndGetOFStringArray(tagKey, help, OFTrue);	
+	if (success.bad()) {
+		cvinfo() << msg << " available but is not a string.\n";
+		return false; 
+	}
+	
+        return getFloat64ArrayFromString(help, values, msg); 
 
 }
 
@@ -631,25 +638,63 @@ C2DFVector CDicomReaderData::getImagePixelSpacing()
 	
 }
 
-C2DFVector CDicomReaderData::getPixelSize()
+C2DFVector CDicomReaderData::getPixelSize(double *dz)
 {
+
+	C2DFVector result = C2DFVector::_1;
 	OFString help;
-	OFCondition success = dcm.getDataset()->findAndGetOFString(DCM_PixelSpacing, help, 0);
-	if (success.bad()) {
-		return getImagePixelSpacing(); 
-	}
-	C2DFVector result;
+	
+	DcmDataset *dataset = dcm.getDataset(); 
+	DcmElement *pixel_spacing_element  = nullptr; 
+	
+	OFCondition success = dataset->findAndGetElement(DCM_PixelSpacing, pixel_spacing_element, OFTrue);
+	
+	if (success.good()) {
+		OFString str_val; 
+		OFCondition read_string = pixel_spacing_element->getOFStringArray (str_val);
+		
+		vector<double> values(2); 
+		bool success = read_string.good() && getFloat64ArrayFromString(str_val, values, "Reading Pixel spacing");
+
+		result.y = values[0];
+		result.x = values[1];
+
+		if (!success) {
+			cvwarn() << "DICOM: Pixel spacing element found, but unable to read its values\n"; 
+		}
+		
+	} else {
+		result = getImagePixelSpacing(); 
+	}
+
+	// do we want thickness? 
+	if (dz) {
+		bool found_dz = false;  
+		DcmElement *slice_distance_element  = nullptr;
+		DcmElement *slice_thickness_element  = nullptr; 
+		OFCondition success_sd = dataset->findAndGetElement(DCM_SpacingBetweenSlices, slice_distance_element, OFTrue);
+		if (success_sd.good() && slice_distance_element) {
+			OFCondition retval = slice_distance_element->getFloat64(*dz, 0);
+			found_dz = retval.good(); 
+		}
 
-	istringstream swidth(help.data());
-	swidth >> result.x;
+		OFCondition success_sth = dataset->findAndGetElement(DCM_SliceThickness, slice_thickness_element, OFTrue);
+		if (success_sth.good() && slice_thickness_element)  {
+			if (found_dz) {
+				cvwarn() << "DICOM file defines slice thickness and distance."
+					 << " Since for volumes the slice distance defines the dimensions, "
+					"the slice thisckness will be ignored here\n";
+			}else{
+				OFCondition retval = slice_thickness_element->getFloat64(*dz, 0);
+				found_dz = retval.good(); 
+			}
 
-	success = dcm.getDataset()->findAndGetOFString(DCM_PixelSpacing, help, 1);
-	if (success.bad()) {
-		throw create_exception<runtime_error>( "Required attribute 'PixelSpacing' not found");
+		}
+		if (!found_dz) {
+			cvwarn() << "DICOM: neither SliceThickness nor SliceDistance were found, defaulting to 1.0mm\n"; 
+		}
 	}
-	istringstream sheight(help.data());
-	sheight >> result.y;
-
+	
 	return result;
 }
 
@@ -857,7 +902,7 @@ void CDicomWriterData::setSize(const C2DBounds& size)
 void CDicomWriterData::setPixelSpacing(const DcmTagKey& key, const C2DFVector& value)
 {
 	stringstream pixelspacing;
-	pixelspacing << value.x << "\\" << value.y;
+	pixelspacing << value.y << "\\" << value.x;
 	setValueString(key, pixelspacing.str(), false);
 }
 
diff --git a/addons/dicom/dicom4mia.hh b/addons/dicom/dicom4mia.hh
index c196917..53ab1ea 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/getset.hh b/addons/dicom/getset.hh
index 3b3395f..61061a7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 313cb9b..9dd319c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -105,7 +105,7 @@ BOOST_FIXTURE_TEST_CASE( test_dicom_load, DicomLoaderFixture )
 	check_attribute("ImageType", "ORIGINAL\\PRIMARY\\M\\ND\\RETRO");
 	check_attribute("SliceLocation", 15.088232007086f);
 	check_attribute("MediaStorageSOPClassUID","1.2.840.10008.5.1.4.1.1.4");
-
+	
 	C2DFVector pixel_size = pimage->get_pixel_size();
 
 	BOOST_CHECK_EQUAL(pixel_size, C2DFVector(1.484375,1.484375));
@@ -135,7 +135,7 @@ protected:
 template  <typename T> 
 void DicomSaveLoadFixture<T>::fill_attributes()
 {
-	org_image->set_attribute(IDMediaStorageSOPClassUID,  "somevalue");
+	org_image->set_attribute(IDMediaStorageSOPClassUID,  "othervalue");
 	org_image->set_attribute(IDSOPClassUID,  "othervalue");
 	org_image->set_pixel_size(C2DFVector(1.45, 2.34));
 
@@ -151,6 +151,9 @@ void DicomSaveLoadFixture<T>::fill_attributes()
 	org_image->set_attribute("StudyID", "786755");
 	org_image->set_attribute("SliceLocation", "12.6755");
 	org_image->set_attribute("ImageType", "ORIGINAL\\PRIMARY\\M\\ND\\RETRO");
+	org_image->set_attribute(IDRescaleIntercept, -1.0f);
+	org_image->set_attribute(IDRescaleSlope, 2.0f);
+
 
 	org_image->set_attribute(IDSmallestImagePixelValue,"0");
 	org_image->set_attribute(IDLargestImagePixelValue,"119");
diff --git a/addons/dicom/test_dcm3d.cc b/addons/dicom/test_dcm3d.cc
index 190a5db..3383f4a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +111,7 @@ void DicomLoaderFixture::check_attribute(const C3DImage& image, const char *name
 template <typename T> 
 void DicomSaveLoadFixture<T>::fill_attributes()
 {
-	org_image->set_attribute("MediaStorageSOPClassUID",  "somevalue");
+	org_image->set_attribute("MediaStorageSOPClassUID",  "othervalue");
 	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));
@@ -130,6 +130,8 @@ void DicomSaveLoadFixture<T>::fill_attributes()
 	org_image->set_attribute(IDSmallestImagePixelValue,"1");
 	org_image->set_attribute(IDLargestImagePixelValue,"20");
 	org_image->set_attribute(IDPhotometricInterpretation,"MONOCHROME2");
+	org_image->set_attribute(IDRescaleIntercept, -1.0f);
+	org_image->set_attribute(IDRescaleSlope, 2.0f);
 
 }
 
diff --git a/addons/dicom/test_dicom4mia.cc b/addons/dicom/test_dicom4mia.cc
index f86d606..e09bed6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +73,24 @@ BOOST_AUTO_TEST_CASE(test_read_dicom_attributes)
 	BOOST_CHECK_EQUAL(pimage->get_attribute_as<double>(IDAcquisitionTime), 32742.072496); 
 }
 
+BOOST_AUTO_TEST_CASE(test_read_dicom_3d)
+{
+        string filename(MIA_SOURCE_ROOT"/testdata/EnIm1.dcm");
+        cvdebug() << "open: " << filename << "\n";
+        CDicomReader reader(filename.c_str());
+	BOOST_CHECK(reader.good());
+	BOOST_REQUIRE(reader.has_3dimage());
+
+	P3DImage pimage = reader.get_3dimage();
+
+	const C3DSSImage& image = dynamic_cast<const C3DSSImage&>(*pimage);
+	
+	BOOST_CHECK_EQUAL(image.get_size(), C3DBounds(256, 128, 4));
+	BOOST_CHECK_EQUAL(image.get_voxel_size(), C3DFVector(0.1f, 0.2f, 1.0f)); 
+
+}
+
+
 struct DicomFixture {
 
 	DicomFixture();
diff --git a/addons/hdf5/CMakeLists.txt b/addons/hdf5/CMakeLists.txt
index 6e3ec0b..bc28bd6 100644
--- a/addons/hdf5/CMakeLists.txt
+++ b/addons/hdf5/CMakeLists.txt
@@ -16,10 +16,10 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 
-OPTION(USE_HDF5 "use hdf5 for data UI" TRUE)
+OPTION(WITH_HDF5 "use hdf5 for data UI" TRUE)
 
 
-IF (USE_HDF5)
+IF (WITH_HDF5)
   if (STRICT_DEPENDECIES)
     find_package(HDF5 REQUIRED)
   else (STRICT_DEPENDECIES)
@@ -31,17 +31,16 @@ IF (USE_HDF5)
     INCLUDE_DIRECTORIES(${HDF5_INCLUDE_DIRS})
     LINK_DIRECTORIES(${HDF5_LIBRARY_DIRS})
     SET(HDF5IO_SRC hdf5mia.cc hdf5a_mia.cc)
-    SET(HDF5MIALIBS miacore ${HDF5_LIBRARIES})
+    SET(HDF5MIALIBS mia3d ${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}")
+    PLUGIN_WITH_TEST_AND_PREFIX2("3dimage" "io" hdf5_3dimage  miahdf5)
 
   ENDIF(HDF5_FOUND)
   
-ENDIF(USE_HDF5)
+ENDIF(WITH_HDF5)
diff --git a/addons/hdf5/hdf5_3dimage.cc b/addons/hdf5/hdf5_3dimage.cc
index bb13aa3..0b6a17e 100644
--- a/addons/hdf5/hdf5_3dimage.cc
+++ b/addons/hdf5/hdf5_3dimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ herr_t hdf5_walk (hid_t loc_id, const char *name, const H5L_info_t *MIA_PARAM_UN
 		P3DImage new_image; 
 		switch (type_id) {
 		case EAttributeType::attr_bool: 
-			new_image = read_image<C3DBitImage>(bsize, dataset); 
+			new_image = read_image<C3DBitImage, bool>(bsize, dataset); 
 			break; 
 		case EAttributeType::attr_uchar: 
 			new_image = read_image<C3DUBImage>(bsize, dataset); 
@@ -213,7 +213,7 @@ void FHDF5Saver::operator ()( const T3DImage<T>& image)
         }
 	cvdebug() << "Add image to '" << path << "'\n"; 
         auto dataset = H5Dataset::create(m_file, path.c_str(), file_type, space);
-        dataset.write(image.begin(), image.end()); 
+        dataset.write_data(image, T()); 
         translate_to_hdf5_attributes(dataset, image); 
 }
 
diff --git a/addons/hdf5/hdf5_3dimage.hh b/addons/hdf5/hdf5_3dimage.hh
index ff8f2fa..7e8493d 100644
--- a/addons/hdf5/hdf5_3dimage.hh
+++ b/addons/hdf5/hdf5_3dimage.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/hdf5/hdf5a_mia.cc b/addons/hdf5/hdf5a_mia.cc
index d85d392..252516a 100644
--- a/addons/hdf5/hdf5a_mia.cc
+++ b/addons/hdf5/hdf5a_mia.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/hdf5/hdf5a_mia.hh b/addons/hdf5/hdf5a_mia.hh
index d4126b7..6207c9a 100644
--- a/addons/hdf5/hdf5a_mia.hh
+++ b/addons/hdf5/hdf5a_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/hdf5/hdf5mia.cc b/addons/hdf5/hdf5mia.cc
index 35be4c5..b0dbd00 100644
--- a/addons/hdf5/hdf5mia.cc
+++ b/addons/hdf5/hdf5mia.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/hdf5/hdf5mia.hh b/addons/hdf5/hdf5mia.hh
index 5b5c16c..6bdeaa6 100644
--- a/addons/hdf5/hdf5mia.hh
+++ b/addons/hdf5/hdf5mia.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -183,11 +183,12 @@ public:
 
 	static H5Dataset open(const H5Base& parent, const char *name);
 
-	template <typename Iterator> 
-	void  write(Iterator begin, Iterator end);
+	template <typename Image, typename T> 
+	void  write_data(const Image& img, T dummy); 
+		
 	
-	template <typename Iterator> 
-	void  read(Iterator begin, Iterator end) const;
+	template <typename Image, typename T> 
+	void  read_data(Image& image, T MIA_PARAM_UNUSED(dummy))const; 
 
 	std::vector <hsize_t> get_size() const; 
 	
@@ -251,7 +252,7 @@ struct Mia_to_h5_types<std::vector<T>>  {
 };
 
 
-template <typename Image> 
+template <typename Image, typename T = typename Image::value_type> 
 typename Image::Pointer read_image(typename Image::dimsize_type& size, const H5Dataset& dataset)
 {
 //	typedef typename Image::dimsize_type Bounds; 
@@ -261,7 +262,7 @@ typename Image::Pointer read_image(typename Image::dimsize_type& size, const H5D
 	typename Image::Pointer presult(result); 
 	
 	dataset.read_and_append_attributes(*result);
-	dataset.read(result->begin(), result->end());
+	dataset.read_data(*result, T());
 	
 	return presult; 
 }
@@ -296,18 +297,18 @@ struct __dispatch_h5dataset_rw<Iterator, bool> {
 }; 
 
 
-template <typename Iterator> 
-void  H5Dataset::write(Iterator begin, Iterator end)
+template <typename Image, typename T> 
+void  H5Dataset::write_data(const Image& image, T MIA_PARAM_UNUSED(dummy))
 {
-	typedef __dispatch_h5dataset_rw<Iterator, typename Iterator::value_type> h5dataset_rw; 
-	h5dataset_rw::apply_write(*this, begin, end); 
+	typedef __dispatch_h5dataset_rw<typename Image::const_iterator, T> h5dataset_rw; 
+	h5dataset_rw::apply_write(*this, image.begin(), image.end()); 
 }
 
-template <typename Iterator> 
-void  H5Dataset::read(Iterator begin, Iterator end)const
+template <typename Image, typename T> 
+void  H5Dataset::read_data(Image& image, T MIA_PARAM_UNUSED(dummy))const
 {
-	typedef __dispatch_h5dataset_rw<Iterator, typename Iterator::value_type> h5dataset_rw; 
-	h5dataset_rw::apply_read(*this, begin, end); 
+	typedef __dispatch_h5dataset_rw<typename Image::iterator, T> h5dataset_rw; 
+	h5dataset_rw::apply_read(*this, image.begin(), image.end()); 
 }
 
 
diff --git a/addons/hdf5/test_hdf5_3dimage.cc b/addons/hdf5/test_hdf5_3dimage.cc
index 3d38405..281211f 100644
--- a/addons/hdf5/test_hdf5_3dimage.cc
+++ b/addons/hdf5/test_hdf5_3dimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,3 +116,4 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_simple_write_read, T, test_pixeltypes )
 }
 
 
+
diff --git a/addons/hdf5/test_hdf5mia.cc b/addons/hdf5/test_hdf5mia.cc
index b40183f..ec7ad3c 100644
--- a/addons/hdf5/test_hdf5mia.cc
+++ b/addons/hdf5/test_hdf5mia.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ BOOST_FIXTURE_TEST_CASE(test_simple_dataset,  HDF5CoreFileFixture)
 		auto space = H5Space::create(2, dims); 
 		auto dataset = H5Dataset::create(get_file(), "/testset", file_type, space);
 		
-		dataset.write(data.begin(), data.end());
+		dataset.write_data(data, int());
 	}
 	// close data set automatically, and now reopen it 
 	{
@@ -121,7 +121,7 @@ BOOST_FIXTURE_TEST_CASE(test_simple_dataset,  HDF5CoreFileFixture)
 
 		vector<int> read_data(6);
 		
-		dataset.read(read_data.begin(), read_data.end()); 
+		dataset.read_data(read_data, int()); 
 
 		for (int i = 0; i < 6; ++i)
 			BOOST_CHECK_EQUAL(read_data[i], data[i]); 
@@ -145,7 +145,7 @@ BOOST_FIXTURE_TEST_CASE(test_bool_dataset,  HDF5CoreFileFixture)
 		auto space = H5Space::create(2, dims); 
 		auto dataset = H5Dataset::create(get_file(), "/testset", file_type, space);
 		
-		dataset.write(data.begin(), data.end());
+		dataset.write_data(data, true);
 	}
 	// close data set automatically, and now reopen it 
 	{
@@ -162,7 +162,7 @@ BOOST_FIXTURE_TEST_CASE(test_bool_dataset,  HDF5CoreFileFixture)
 
 		vector<bool> read_data(6); 
 		
-		dataset.read(read_data.begin(), read_data.end()); 
+		dataset.read_data(read_data, false); 
 
 		for (int i = 0; i < 6; ++i)
 			BOOST_CHECK_EQUAL(read_data[i], data[i]); 
@@ -197,7 +197,7 @@ void TestDatasetFixture<T>::save(const string& path, const std::vector<hsize_t>&
 	
 	auto space = H5Space::create(size); 
 	auto dataset = H5Dataset::create(get_file(), path.c_str(), file_type, space);
-	dataset.write(data.begin(), data.end());
+	dataset.write_data(data, T());
 }
 
 template <typename T> 
@@ -222,7 +222,7 @@ void TestDatasetFixture<T>::read_and_test(const string& path, const std::vector<
 	
 	std::vector<T> read_data(length); 
 	
-	dataset.read(read_data.begin(), read_data.end()); 
+	dataset.read_data(read_data, T()); 
 		
 	for (size_t i = 0; i < length; ++i)
 		BOOST_CHECK_EQUAL(read_data[i], test_data[i]); 
@@ -266,11 +266,19 @@ void TestAttrfixture<T>::run()
 
 	auto pattr = H5AttributeTranslatorMap::instance().translate("attr", h5attr); 
 	int test_type = attribute_type<T>::value; 
-	BOOST_CHECK_EQUAL(pattr->type_id(), test_type); 
+	BOOST_CHECK_EQUAL(pattr->type_id(), test_type);
+	
+
+	
 
-	auto& rattr = dynamic_cast<const TAttribute<T>&>(*pattr); 
+	auto rattr = dynamic_cast<const TAttribute<T>*>(pattr.get());
+	if (!rattr)  {
+		cvdebug() << "cast from'" << typeid(attr.get()).name()
+			  <<"' to '" << typeid(TAttribute<T> *).name() << "' failed\n";		
+	}
+	BOOST_REQUIRE(rattr); 
 	
-	BOOST_CHECK_EQUAL(rattr, value); 
+	BOOST_CHECK_EQUAL(*rattr, value); 
 }
 
 BOOST_AUTO_TEST_CASE_TEMPLATE( test_attributes , T , test_pixel_types )
@@ -297,9 +305,15 @@ void TestVectorAttrfixture<T>::run()
 	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; 
-
+	auto rattr = dynamic_cast<const TAttribute<vector<T> > *>(pattr.get());
+	if (!rattr)  {
+		cvdebug() << "cast from'" << typeid(attr.get()).name()
+			  <<"' to '" << typeid(TAttribute<T> *).name() << "' failed\n";		
+	}
+	BOOST_REQUIRE(rattr); 	
+	
+	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){
diff --git a/addons/jpg/CMakeLists.txt b/addons/jpg/CMakeLists.txt
index 4719ca4..53a77dc 100644
--- a/addons/jpg/CMakeLists.txt
+++ b/addons/jpg/CMakeLists.txt
@@ -28,9 +28,11 @@ ENDIF(WITH_JPEG)
 
 IF(JPEG_FOUND)
   DEFINE_PROPERTY(GLOBAL PROPERTY HAVE_JPG_PROP BRIEF_DOCS "yeah" FULL_DOCS "yeah")
-  SET(JPEG_LINK_LIBS ${MIA2DLIBS} ${JPEG_LIBRARIES})
+  SET(JPEG_LINK_LIBS mia2d ${JPEG_LIBRARIES})
   INCLUDE_DIRECTORIES(${JPEG_INCLUDE_DIR})
 
   PLUGIN_WITH_PREFIX2("2dimage" "io" jpg-gray "${JPEG_LINK_LIBS}")
   PLUGIN_WITH_PREFIX2("rgbimage" "io" jpg-rgb "${JPEG_LINK_LIBS}" "${rgbimage2dio_path}")
+
+  NEW_TEST(jpg mia2d)
 ENDIF(JPEG_FOUND)
diff --git a/addons/jpg/jpeg-common.hh b/addons/jpg/jpeg-common.hh
index 67415b0..d2d573a 100644
--- a/addons/jpg/jpeg-common.hh
+++ b/addons/jpg/jpeg-common.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 69cfd43..deb18ae 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 +90,15 @@ C2DImageIOPlugin::PData CJpeg2DImageIOPlugin::do_load(const string& fname) const
 	jpeg_start_decompress(&decompress.info);
 	// only one component? 
 	if (decompress.info.output_components != 1) {
-		throw create_exception<runtime_error>(":MIA only supports gray scale images, but got an image with ", 
-					    decompress.info.output_components, " color components.");
+		throw create_exception<invalid_argument>("The plugin '",get_descr(),
+							 "' only supports gray scale images, but got an image with ", 
+							 decompress.info.output_components, " color components.");
 	}
 
 	if (decompress.info.data_precision != 8) {
-		throw create_exception<runtime_error>(":MIA only supports 8-bit per pixel images, but got an image with ", 
-						      decompress.info.data_precision, " bits data precision.");
+		throw create_exception<invalid_argument>("The plugin '",get_descr(),"'only supports 8-bit per pixel images, "
+							 "but got an image with ", 
+							 decompress.info.data_precision, " bits data precision.");
 	}
 
 	int row_stride = decompress.info.output_width * decompress.info.output_components;
diff --git a/addons/jpg/jpg-rgb.cc b/addons/jpg/jpg-rgb.cc
index b9d6c53..f0e2860 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,24 +86,39 @@ C2DRGBImageIOPlugin::PData CJpegRGB2DImageIOPlugin::do_load(const string& fname)
 	jpeg_start_decompress(&decompress.info);
 	// only one component? 
 	if (decompress.info.output_components != 3) {
-		throw create_exception<runtime_error>(":MIA this plugin only supports RGB images, but got an image with ", 
+		throw create_exception<invalid_argument>(":MIA this plugin only supports RGB images, but got an image with ", 
 					    decompress.info.output_components, " color components.");
 	}
 
 
-	int row_stride = decompress.info.output_width * decompress.info.output_components * 3;
-	vector<JSAMPLE> buf(row_stride); 
+	int row_stride = decompress.info.output_width * decompress.info.output_components;
+	vector<JSAMPLE> buf(row_stride);
+
+	
+	
+	cvdebug() << "owidth=" << decompress.info.output_width
+		  << ", row_stride="  << row_stride << "\n"; 
 	
 	JSAMPROW buffer[1]; 
-	buffer[0] = &buf[0]; 
-
+	buffer[0] = &buf[0];
+	
+	cvdebug() << "Create image of size "
+		  << decompress.info.output_width <<"x"<< decompress.info.output_height << "\n"; 
+	
 	CRGB2DImage *result = new CRGB2DImage(C2DBounds(decompress.info.output_width, decompress.info.output_height)); 
 	PRGB2DImage presult(result); 
+
+	unsigned char *p = presult->pixel(); 
+	cvdebug() << "output pointer base = " << (long)p << "\n"; 
 	
 	while (decompress.info.output_scanline < decompress.info.output_height) {
-		(void) jpeg_read_scanlines(&decompress.info, buffer, 1);
-		copy(buf.begin(), buf.end(), 
-		     result->pixel() + ((decompress.info.output_scanline - 1) * row_stride));  
+		cvdebug() << "scanline=" << decompress.info.output_scanline
+			  << " - " << decompress.info.output_height
+			  << " outpos = " << decompress.info.output_scanline * row_stride <<"\n"; 
+		jpeg_read_scanlines(&decompress.info, buffer, 1);
+		cvdebug() << "output pointer = " << (long)&p[decompress.info.output_scanline * row_stride] << "\n"; 
+		
+		copy(buf.begin(), buf.end(), &p[(decompress.info.output_scanline-1) * row_stride]);
 	}
 	
 	return presult; 
diff --git a/addons/jpg/test_jpg.cc b/addons/jpg/test_jpg.cc
new file mode 100644
index 0000000..5b3b30b
--- /dev/null
+++ b/addons/jpg/test_jpg.cc
@@ -0,0 +1,159 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 <boost/filesystem/path.hpp>
+
+#include <mia/core/attribute_names.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/2d/imageio.hh>
+#include <mia/2d/rgbimageio.hh>
+
+NS_MIA_USE
+using namespace std; 
+using namespace boost::unit_test;
+namespace bfs = ::boost::filesystem; 
+
+
+BOOST_AUTO_TEST_CASE( test_load_save_8bit_gray )
+{
+	string filename(MIA_SOURCE_ROOT"/testdata/gray2x3.jpg");
+
+
+        auto test_image = load_image2d(filename);
+
+	const C2DUBImage& img = dynamic_cast<const C2DUBImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img(0,0),   0u);
+	BOOST_CHECK_EQUAL(img(1,0),  63u);
+	BOOST_CHECK_EQUAL(img(0,1), 128u);
+	BOOST_CHECK_EQUAL(img(1,1), 190u);
+	BOOST_CHECK_EQUAL(img(0,2), 229u);
+	BOOST_CHECK_EQUAL(img(1,2), 255u);
+
+	save_image("test_image.jpg", test_image);
+
+	auto test2_image = load_image2d("test_image.jpg");
+	
+	const C2DUBImage& img2 = dynamic_cast<const C2DUBImage&>(*test2_image); 
+	BOOST_CHECK_EQUAL(img2.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img2.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img2(0,0),   0u);
+	BOOST_CHECK_EQUAL(img2(1,0),  63u);
+	BOOST_CHECK_EQUAL(img2(0,1), 128u);
+	BOOST_CHECK_EQUAL(img2(1,1), 190u);
+	BOOST_CHECK_EQUAL(img2(0,2), 229u);
+	BOOST_CHECK_EQUAL(img2(1,2), 255u);
+        unlink("test_image.jpg");
+}
+
+
+BOOST_AUTO_TEST_CASE( test_load_jpeg_8bit_rgb )
+{
+	// the image data is lossy 
+        vector<unsigned char> test_data{206, 89, 97, 72, 99, 68, 192, 205, 53,
+                        28, 31, 98, 94, 27, 203, 232, 17, 216};
+        
+        const auto& io = C2DRGBImageIOPluginPluginHandler::instance(); 
+
+        auto test_image = io.load(MIA_SOURCE_ROOT"/testdata/rgb3x2-24bit.jpg");
+
+        const CRGB2DImage& img = *test_image;
+
+        BOOST_CHECK_EQUAL(img.get_size().x, 3);
+        BOOST_CHECK_EQUAL(img.get_size().y, 2);
+        
+        auto pixels = img.pixel();
+        for (int i = 0; i < 18; ++i) {
+                BOOST_CHECK_EQUAL(pixels[i], test_data[i]); 
+        }
+
+}
+
+
+
+BOOST_AUTO_TEST_CASE( test_save_load_8bit_rgb )
+{
+	C2DBounds size(255, 256);
+	
+	CRGB2DImage image(size);
+
+	auto p = image.pixel();
+
+	for (unsigned y = 0; y < size.y; ++y) {
+		for (unsigned x = 0; x < size.x; ++x, p +=3 ) {
+			p[0] = x;
+			p[1] = y;
+			p[2] = (x + y) / 2; 
+		}
+	}
+	
+	
+        const auto& io = C2DRGBImageIOPluginPluginHandler::instance();
+
+	BOOST_REQUIRE(save_image("smooth.jpg", image));
+	
+	auto test_image = io.load("smooth.jpg");
+
+        BOOST_CHECK_EQUAL(test_image->get_size().x, 255);
+        BOOST_CHECK_EQUAL(test_image->get_size().y, 256);
+	
+	
+	p = test_image->pixel();
+
+	for (unsigned y = 0; y < size.y; ++y) {
+		for (unsigned x = 0; x < size.x; ++x, p +=3 ) {
+			unsigned z = (x + y) / 2; 
+			unsigned deltax = p[0] > x ? p[0] -  x : x - p[0];
+			unsigned deltay = p[1] > y ? p[1] -  y : y - p[1];
+			unsigned deltaz = p[2] > z ? p[2] -  z : z - p[2]; 
+
+			// jpeg is lossy so we need to allow for some tolerance
+			BOOST_CHECK_SMALL(deltax, 5u);
+			BOOST_CHECK_SMALL(deltay, 5u);
+			BOOST_CHECK_SMALL(deltaz, 5u); 
+		}
+	}
+
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_rejects )
+{
+        const auto& io = C2DRGBImageIOPluginPluginHandler::instance(); 
+
+	BOOST_CHECK_THROW(io.load(MIA_SOURCE_ROOT"/testdata/gray2x3.jpg"),
+			  invalid_argument);
+	
+	BOOST_CHECK_THROW(io.load(MIA_SOURCE_ROOT"/testdata/nonexistent.jpg"),
+			  runtime_error); 
+
+	
+	BOOST_CHECK_THROW(load_image2d(MIA_SOURCE_ROOT"/testdata/rgb3x2-24bit.jpg"),
+			  invalid_argument);
+	
+	BOOST_CHECK_THROW(load_image2d(MIA_SOURCE_ROOT"/testdata/nonexistent.jpg"),
+			  runtime_error);
+
+}
diff --git a/addons/maxflow/2dmaxflow.cc b/addons/maxflow/2dmaxflow.cc
index ca558e0..1eb8b77 100644
--- a/addons/maxflow/2dmaxflow.cc
+++ b/addons/maxflow/2dmaxflow.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/maxflow/2dmaxflow.hh b/addons/maxflow/2dmaxflow.hh
index e1d2cec..3ef40a1 100644
--- a/addons/maxflow/2dmaxflow.hh
+++ b/addons/maxflow/2dmaxflow.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/maxflow/test_2dmaxflow.cc b/addons/maxflow/test_2dmaxflow.cc
index 2526559..3eac0f0 100644
--- a/addons/maxflow/test_2dmaxflow.cc
+++ b/addons/maxflow/test_2dmaxflow.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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
index 4c78366..aca68eb 100644
--- a/addons/nifti/CMakeLists.txt
+++ b/addons/nifti/CMakeLists.txt
@@ -16,9 +16,9 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 
-OPTION(USE_NIFTI "Use nifti-1 3D image file format" TRUE)
+OPTION(WITH_NIFTI "Use nifti-1 3D image file format" TRUE)
 
-IF (USE_NIFTI)
+IF (WITH_NIFTI)
   SET(NIFTI_FOUND FALSE)
   
   # zlib is required for nifti to function 
@@ -46,13 +46,12 @@ IF (USE_NIFTI)
       SET(NIFTIIO_LIBRARIES 
         ${NIFTIIO_LIBRARY}
         ${NIFTIZNZ_LIBRARY}
-        ${LIBZ_LIBRARIES}
+        ${ZLIB_LIBRARIES}
         m)
+      MESSAGE(STATUS "libz=${ZLIB_LIBRARIES}")
     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")
@@ -65,4 +64,4 @@ IF (USE_NIFTI)
   SET(NIFTI_LINK_LIBS_3D ${NIFTIIO_LIBRARIES} mia3d)
   PLUGIN_WITH_TEST_AND_PREFIX2("3dimage" "io" niftiimage "${NIFTI_LINK_LIBS_3D}")
   
-ENDIF (USE_NIFTI)
+ENDIF (WITH_NIFTI)
diff --git a/addons/nifti/niftiimage.cc b/addons/nifti/niftiimage.cc
index 0a11fde..9deabb9 100644
--- a/addons/nifti/niftiimage.cc
+++ b/addons/nifti/niftiimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 <addons/nifti/niftiimage.hh>
 #include <nifti1_io.h>
 
+#include <mia/core/attribute_names.hh>
 
 using namespace mia; 
 using namespace std; 
@@ -36,10 +37,38 @@ 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 
 
+/*
+  Within MIA the orientation of the images is stored like given in DICOM. 
+  To convert to a nifti-like orientation the following formula is used: 
+  
+  input: 
+     SIZE image seize in pixels 
+     SCALE pixeldim in mm 
+     ORIG_IN location of first pixel in pyhsical space 
+     R_IN    rotation orientation matrix 
+  outut: 
+     ORIG_OUT location of first pixel in pyhsical space (nifti) 
+     R_OUT    rotation orientation matrix (nifti) 
+
+                 / -1, -1,  1 \
+  R_OUT = R_IN * | -1, -1,  1 |
+                 \  1,  1, -1 /
+
+    dz = (SIZE.z - 1) * scale.z; 
+  ORIG_OUT.x = - R_IN.z.x * dz - ORIG_IN.x; 
+  ORIG_OUT.y = - R_IN.z.y * dz - ORIG_IN.y; 
+  ORIG_OUT.z =   R_IN.z.z * dz + ORIG_IN.z; 
+
+  When reading a nifti image the inverse operation is applied. 
+
+*/
+
 
 CNifti3DImageIOPlugin::CNifti3DImageIOPlugin():
 C3DImageIOPlugin("nifti")
@@ -71,6 +100,9 @@ C3DImageIOPlugin("nifti")
 	CFloatTranslator::register_for("nifti-intent_p2"); 
 	CFloatTranslator::register_for("nifti-intent_p3"); 
 
+	CFloatTranslator::register_for(IDRescaleSlope);
+	CFloatTranslator::register_for(IDRescaleIntercept); 
+	
         CFloatTranslator::register_for(AttrID_nifti_toffset); 
 	CSITranslator::register_for(AttrID_nifti_xyz_units);
 	CSITranslator::register_for(AttrID_nifti_time_units);
@@ -91,27 +123,60 @@ void copy_attributes(C3DImage& image, const nifti_image& ni)
         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));
+        } else { // Method 2
+
+                image.set_orientation(ior_xyz);
+                image.set_voxel_size(C3DFVector(ni.dx,  ni.dy, ni.dz));
+
+		mat44 mat = nifti_quatern_to_mat44( ni.quatern_b, ni.quatern_c, ni.quatern_d,
+						    0.0f, 0.0f, 0.0f,
+						    1.0f, 1.0f, 1.0f, ni.qfac);
+
+		C3DDMatrix rot(C3DDVector(-mat.m[0][0],-mat.m[1][0], mat.m[2][0]),
+			       C3DDVector(-mat.m[0][1],-mat.m[1][1], mat.m[2][1]),
+			       C3DDVector( mat.m[0][2], mat.m[1][2],-mat.m[2][2]));
+
+		image.set_rotation(rot);
+		const float dz = (ni.nz - 1) * ni.dz; 
+
+		C3DFVector org(- rot.z.x * dz - ni.qoffset_x, 
+			       - rot.z.y * dz - ni.qoffset_y, 
+			       - rot.z.z * dz + ni.qoffset_z); 
+		
+                image.set_origin(org); 
+		
         }
         
         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]}; 
+				    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_sform_code, ni.sform_code);
+
+		// in this case use s-from for orientation 
+		if (ni.qform_code == 0) {
+			C3DDMatrix rot(C3DDVector(-ni.sto_xyz.m[0][0]/ni.dx,
+						  -ni.sto_xyz.m[1][0]/ni.dy,
+						   ni.sto_xyz.m[2][0]/ni.dz),
+				       C3DDVector(-ni.sto_xyz.m[0][1]/ni.dx,
+						  -ni.sto_xyz.m[1][1]/ni.dy,
+						   ni.sto_xyz.m[2][1]/ni.dz),
+				       C3DDVector( ni.sto_xyz.m[0][2]/ni.dx,
+						   ni.sto_xyz.m[1][2]/ni.dy,
+						  -ni.sto_xyz.m[2][2]/ni.dz));
+			
+			image.set_rotation(rot);
+			const float dz = (ni.nz - 1) * ni.dz; 
+			C3DFVector org(- rot.z.x * dz - ni.qoffset_x, 
+				       - rot.z.y * dz - ni.qoffset_y, 
+				       - rot.z.z * dz + ni.qoffset_z); 
+			image.set_origin(org); 
+		}
         }
         
-
 	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);
@@ -119,7 +184,9 @@ void copy_attributes(C3DImage& image, const nifti_image& ni)
 	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)); 
+	image.set_attribute(AttrID_nifti_intent_name, string(ni.intent_name));
+	image.set_attribute(IDRescaleSlope, ni.scl_slope);
+	image.set_attribute(IDRescaleIntercept, ni.scl_inter); 
 }
 
 
@@ -127,8 +194,11 @@ template <typename Image>
 CNifti3DImageIOPlugin::PData read_images(const C3DBounds& size, const nifti_image& ni)
 {
         int timesteps = 1; 
-	if (ni.ndim == 4) 
-		timesteps = ni.nt; 
+	for (int extra_dims = 4; extra_dims <= ni.ndim; ++extra_dims)
+		timesteps *= ni.dim[extra_dims]; 
+
+	cvdebug() << "Loading " << timesteps << " images\n";
+
 
 	CNifti3DImageIOPlugin::PData result(new C3DImageVector); 
 	result->reserve(timesteps); 
@@ -147,33 +217,6 @@ CNifti3DImageIOPlugin::PData read_images(const C3DBounds& size, const nifti_imag
         
 }
 
-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
 {
@@ -196,50 +239,28 @@ CNifti3DImageIOPlugin::PData CNifti3DImageIOPlugin::do_load(const std::string&
                                                          image->intent_code, " that is not supported by MIA."); 
         }
 
-	
-
-	
-        if (image->ndim < 3 || image->ndim > 4)
+        if (image->ndim < 3 || image->ndim > 5)
 		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); 
+	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); 
+	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");
-                }
-        }
+	default:
+		throw create_exception<invalid_argument>("NIFTI: input format ", image->datatype, " not supported");
+	}
 	
 }
 
@@ -283,6 +304,12 @@ public:
                         throw create_exception<invalid_argument>("NIFTI-IO: image series containing images of varying pixel types is not supported");
                 }
 
+		if (static_cast<unsigned>(m_ni.nx) != image.get_size().x ||
+		    static_cast<unsigned>(m_ni.ny) != image.get_size().y ||
+		    static_cast<unsigned>(m_ni.nz) != image.get_size().z) {
+			throw create_exception<invalid_argument>("NIFTI-IO: image series containing images of varying sizes 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();
@@ -310,8 +337,9 @@ bool CNifti3DImageIOPlugin::do_save(const std::string& fname, const Data& data)
         int datatype = datatype_to_nifti(pixel_type);
         
         if (data.size() > 1) {
-                dims[0] = 4; 
-                dims[4] = data.size(); 
+		cvdebug() << "Saving " << data.size() << " images\n"; 
+                dims[0] = 5; 
+                dims[5] = data.size(); 
         }
 	
         // create the output image
@@ -336,9 +364,8 @@ bool CNifti3DImageIOPlugin::do_save(const std::string& fname, const Data& data)
 	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;
+	output->scl_slope = image.get_attribute_as<float>(IDRescaleSlope, 0.0f);
+	output->scl_inter = image.get_attribute_as<float>(IDRescaleIntercept, 0.0f);
 
 	// need to see whether to support this 
 	output->cal_min = 0.0f;
@@ -347,15 +374,15 @@ bool CNifti3DImageIOPlugin::do_save(const std::string& fname, const Data& data)
 	if (image.has_attribute(AttrID_nifti_qform_code)) {
 		output->qform_code = image.get_attribute_as<int>(AttrID_nifti_qform_code); 
 	} else {
-		output->qform_code = 0; // default to method 2 
+		output->qform_code = 1; // default to method 2 
 	}
 
+	auto org = image.get_origin(); 
 	// Analyze 7.5 like data 
 	if (output->qform_code == 0) {
 		// here starts the orientation insanity 
 		// todo: re-check how this qfac is actually used
 
-		auto org = image.get_origin(); 
 		output->qoffset_x = org.x; 
 		output->qoffset_y = org.y; 
 		output->qoffset_z = org.z; 
@@ -370,15 +397,31 @@ bool CNifti3DImageIOPlugin::do_save(const std::string& fname, const Data& data)
 			cvwarn() << __FUNCTION__ << "FIXME:manual set orientation detected, but ignored\n"; 
 		}
 	} else {
-		output->qfac = (image.get_orientation() == ior_xyz_flipped) ? -1 : 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();
+		output->qform_code = NIFTI_XFORM_SCANNER_ANAT;
+
+		auto rot = image.get_rotation().as_matrix_3x3();
+
+		cvdebug() << "rot-quat= "<< image.get_rotation().as_quaternion() << "\n";
+		cvdebug() << "org= " << org << "\n";
+		cvdebug() << "rot= " << rot << "\n"; 		
+
+		const float dz = (size.z - 1) * scale.z; 
+		output->qoffset_x = - rot.z.x * dz - org.x; 
+		output->qoffset_y = - rot.z.y * dz - org.y; 
+		output->qoffset_z = rot.z.z * dz + org.z;
+
+		// this seems to be the proper transaltion 
+		output->qto_xyz = nifti_make_orthog_mat44( 
+			-rot.x.x, -rot.y.x, rot.z.x,
+			-rot.x.y, -rot.y.y, rot.z.y,
+			 rot.x.z, rot.y.z, -rot.z.z); 
+	
+		nifti_mat44_to_quatern(output->qto_xyz,
+				       &output->quatern_b, &output->quatern_c, &output->quatern_d,
+				       NULL,NULL,NULL,NULL,NULL,NULL,&output->qfac);
+
+		output->pixdim[0] = output->qfac; 
+		
 	}
 	
 	// copy s-form if available 
@@ -395,18 +438,41 @@ bool CNifti3DImageIOPlugin::do_save(const std::string& fname, const Data& data)
 		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->sto_xyz.m[2][0] = am[8]; 
+		output->sto_xyz.m[2][1] = am[9]; 
+		output->sto_xyz.m[2][2] = am[10]; 
+		output->sto_xyz.m[2][3] = am[11]; 
 
-	
+		output->sto_xyz.m[3][0] = am[12]; 
+		output->sto_xyz.m[3][1] = am[13]; 
+		output->sto_xyz.m[3][2] = am[14]; 
+		output->sto_xyz.m[3][3] = am[15]; 
+		
+	}else{ // without a sform code leave it empty (for now)
+		output->sform_code = NIFTI_XFORM_SCANNER_ANAT;
+
+		auto rot = image.get_rotation().as_matrix_3x3();
+		output->sto_xyz.m[0][0] = -rot.x.x * scale.x;
+		output->sto_xyz.m[0][1] = -rot.y.x * scale.y; 
+		output->sto_xyz.m[0][2] =  rot.z.x * scale.z; 
+		output->sto_xyz.m[0][3] = output->qoffset_x; 
+
+		output->sto_xyz.m[1][0] = -rot.x.y * scale.x; 
+		output->sto_xyz.m[1][1] = -rot.y.y * scale.y; 
+		output->sto_xyz.m[1][2] =  rot.z.y * scale.z; 
+		output->sto_xyz.m[1][3] = output->qoffset_y; 
+
+		output->sto_xyz.m[2][0] = rot.x.z * scale.y; 
+		output->sto_xyz.m[2][1] = rot.y.z * scale.y; 
+		output->sto_xyz.m[2][2] = -rot.z.z * scale.z; 
+		output->sto_xyz.m[2][3] = output->qoffset_z; 
+
+		output->sto_xyz.m[3][0] = 0; 
+		output->sto_xyz.m[3][1] = 0; 
+		output->sto_xyz.m[3][2] = 0; 
+		output->sto_xyz.m[3][3] = 1;  
 	}
+	
 	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);
@@ -441,7 +507,8 @@ bool CNifti3DImageIOPlugin::do_save(const std::string& fname, const Data& data)
 
 const std::string CNifti3DImageIOPlugin::do_get_descr() const
 {
-        return "NIFTI-1 3D image IO"; 
+        return "NIFTI-1 3D image IO. The orientation is transformed in the same way like "
+		"it is done with 'dicomtonifti --no-reorder' from the vtk-dicom package."; 
 }
 
 const std::string CNifti3DImageIOPlugin::do_get_preferred_suffix() const
diff --git a/addons/nifti/niftiimage.hh b/addons/nifti/niftiimage.hh
index 51b220c..5c4057f 100644
--- a/addons/nifti/niftiimage.hh
+++ b/addons/nifti/niftiimage.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/test_niftiimage.cc b/addons/nifti/test_niftiimage.cc
index 0f4821d..387ac7a 100644
--- a/addons/nifti/test_niftiimage.cc
+++ b/addons/nifti/test_niftiimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +49,7 @@ typedef bmpl::vector<
 		     > type;
 
 
-BOOST_AUTO_TEST_CASE_TEMPLATE( test_simple_write_read, T, type ) 
+BOOST_AUTO_TEST_CASE_TEMPLATE( test_simple_write_read_with_qform, T, type ) 
 {
         C3DBounds size(2,3,4);
 	T3DImage<T> *image = new T3DImage<T>(size); 
@@ -96,8 +96,11 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_simple_write_read, T, type )
 		++il; 
 	}
 
-	BOOST_CHECK_EQUAL(ploaded.get_voxel_size(), voxel); 
-	BOOST_CHECK_EQUAL(ploaded.get_origin(), origin); 
+	BOOST_CHECK_EQUAL(ploaded.get_voxel_size(), voxel);
+	
+	BOOST_CHECK_CLOSE(ploaded.get_origin().x, origin.x, 0.001);
+	BOOST_CHECK_CLOSE(ploaded.get_origin().y, origin.y, 0.001);
+	BOOST_CHECK_CLOSE(ploaded.get_origin().z, origin.z, 0.001); 
         auto qloaded = ploaded.get_rotation().as_quaternion();
 
         BOOST_CHECK_CLOSE(qloaded.x(), rot.x(), 0.001);
diff --git a/addons/nlopt/nlopt.cc b/addons/nlopt/nlopt.cc
index 2517f89..c2b0727 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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.hh b/addons/nlopt/nlopt.hh
index b5a2deb..96690c8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 36e8212..89f46bd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 5b7134a..d844d13 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 b3543bf..c20d4f4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 1c93d78..07f1b01 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,3 +62,92 @@ BOOST_FIXTURE_TEST_CASE(test_2dimage_plugin, PathInitFixture)
 {
 	test_2dimageio_plugins(); 
 }
+
+BOOST_AUTO_TEST_CASE ( test_2dvfio )
+{
+        C2DBounds size(2,3); 
+        C2DFVectorfield vf(size);
+
+        vector<C2DFVector> test_data = {
+                C2DFVector(2, 3), C2DFVector(3, 4), C2DFVector(4, 5),
+                C2DFVector(5, 6), C2DFVector(6, 7), C2DFVector(8, 9)
+        };
+
+        copy(test_data.begin(), test_data.end(), vf.begin()); 
+
+        C2DIOVectorfield iovf(vf); 
+        BOOST_REQUIRE(C2DVFIOPluginHandler::instance().save("2dvf.exr", iovf));
+
+        auto loaded = C2DVFIOPluginHandler::instance().load("2dvf.exr");
+        BOOST_REQUIRE(loaded);
+        
+        BOOST_CHECK_EQUAL(loaded->get_size(), size);
+        auto i = loaded->begin();
+        auto e = loaded->end();
+        auto t = vf.begin();
+
+        while (i != e) {
+                BOOST_CHECK_EQUAL(*i, *t);
+                ++i; ++t; 
+        }
+}
+
+
+BOOST_AUTO_TEST_CASE ( test_2dimageio_float )
+{
+        C2DBounds size(2,3); 
+        C2DFImage image(size);
+
+        vector<float> test_data = {2.1, 3.3, 3.5, 4.5, 4.6, 5.2};
+
+        copy(test_data.begin(), test_data.end(), image.begin()); 
+
+        
+        BOOST_REQUIRE(save_image("2dimage-f.exr", image));
+
+        auto loaded = load_image2d("2dimage-f.exr");
+        BOOST_REQUIRE(loaded);
+	
+        BOOST_CHECK_EQUAL(loaded->get_size(), size);
+
+	const C2DFImage& float_loaded = dynamic_cast<const C2DFImage&>(*loaded); 
+	
+        auto i = float_loaded.begin();
+        auto e = float_loaded.end();
+        auto t = image.begin();
+
+        while (i != e) {
+                BOOST_CHECK_EQUAL(*i, *t);
+                ++i; ++t; 
+        }
+}
+
+BOOST_AUTO_TEST_CASE ( test_2dimageio_uint )
+{
+        C2DBounds size(2,3); 
+        C2DUIImage image(size);
+
+        vector<float> test_data = {2, 3, 3, 4, 4, 5};
+
+        copy(test_data.begin(), test_data.end(), image.begin()); 
+
+        
+        BOOST_REQUIRE(save_image("2dimage-ui.exr", image));
+
+        auto loaded = load_image2d("2dimage-ui.exr");
+        BOOST_REQUIRE(loaded);
+	
+        BOOST_CHECK_EQUAL(loaded->get_size(), size);
+
+	const C2DUIImage& float_loaded = dynamic_cast<const C2DUIImage&>(*loaded); 
+	
+        auto i = float_loaded.begin();
+        auto e = float_loaded.end();
+        auto t = image.begin();
+
+        while (i != e) {
+                BOOST_CHECK_EQUAL(*i, *t);
+                ++i; ++t; 
+        }
+}
+
diff --git a/addons/png/CMakeLists.txt b/addons/png/CMakeLists.txt
index ddc2b75..ec33c2b 100644
--- a/addons/png/CMakeLists.txt
+++ b/addons/png/CMakeLists.txt
@@ -31,11 +31,13 @@ IF(PNG_FOUND)
 
   DEFINE_PROPERTY(GLOBAL PROPERTY HAVE_PNG_PROP BRIEF_DOCS "yeah" FULL_DOCS "yeah")
 
-  SET(PNG_LINK_LIBS ${MIA2DLIBS} ${PNG_LIBRARIES})
+  SET(PNG_LINK_LIBS mia2d ${PNG_LIBRARIES})
   INCLUDE_DIRECTORIES(${PNG_PNG_INCLUDE_DIR})
 
   PLUGIN_WITH_PREFIX2("2dimage" "io" png-gray "${PNG_LINK_LIBS}")
   PLUGIN_WITH_PREFIX2("rgbimage" "io" png-rgb "${PNG_LINK_LIBS}" )
 
+  NEW_TEST(png mia2d)
+ 
 
 ENDIF(PNG_FOUND)
diff --git a/addons/png/png-gray.cc b/addons/png/png-gray.cc
index d1bac08..d6ec81c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 070045e..f60aeef 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +128,8 @@ CPNG2DImageIOPlugin::PData  CPNG2DImageIOPlugin::do_load(const string& fname) co
 		throw invalid_argument(errmsg.str());
 	}
 
-	if (bit_depth != 24)
-		throw create_exception<invalid_argument>("PNG-RGB: Only 24-bit images are supported, but got ",  bit_depth, " bit");
+	if (bit_depth != 8 )
+		throw create_exception<invalid_argument>("PNG-RGB: Only 8-bit per color components are supported, but got ",  bit_depth, " bit");
 
 	png_read_update_info(png_ptr, info_ptr);
 	
diff --git a/addons/png/test_png.cc b/addons/png/test_png.cc
new file mode 100644
index 0000000..ed70d22
--- /dev/null
+++ b/addons/png/test_png.cc
@@ -0,0 +1,194 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 <boost/filesystem/path.hpp>
+
+#include <mia/core/attribute_names.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/2d/imageio.hh>
+#include <mia/2d/rgbimageio.hh>
+
+NS_MIA_USE
+using namespace std; 
+using namespace boost::unit_test;
+namespace bfs = ::boost::filesystem; 
+
+
+BOOST_AUTO_TEST_CASE( test_load_save_8bit_gray )
+{
+	string filename(MIA_SOURCE_ROOT"/testdata/gray2x3.png");
+
+
+        auto test_image = load_image2d(filename);
+
+	const C2DUBImage& img = dynamic_cast<const C2DUBImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img(0,0),   0u);
+	BOOST_CHECK_EQUAL(img(1,0),  63u);
+	BOOST_CHECK_EQUAL(img(0,1), 128u);
+	BOOST_CHECK_EQUAL(img(1,1), 190u);
+	BOOST_CHECK_EQUAL(img(0,2), 229u);
+	BOOST_CHECK_EQUAL(img(1,2), 255u);
+
+	save_image("test_image.png", test_image);
+
+	auto test2_image = load_image2d("test_image.png");
+	
+	const C2DUBImage& img2 = dynamic_cast<const C2DUBImage&>(*test2_image); 
+	BOOST_CHECK_EQUAL(img2.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img2.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img2(0,0),   0u);
+	BOOST_CHECK_EQUAL(img2(1,0),  63u);
+	BOOST_CHECK_EQUAL(img2(0,1), 128u);
+	BOOST_CHECK_EQUAL(img2(1,1), 190u);
+	BOOST_CHECK_EQUAL(img2(0,2), 229u);
+	BOOST_CHECK_EQUAL(img2(1,2), 255u);
+        unlink("test_image.png"); 	
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_1bit_gray )
+{
+	string filename(MIA_SOURCE_ROOT"/testdata/gray2x3-1.png");
+
+
+        auto test_image = load_image2d(filename);
+
+	const C2DBitImage& img = dynamic_cast<const C2DBitImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img(0,0), 0u);
+	BOOST_CHECK_EQUAL(img(1,0), 0u);
+	BOOST_CHECK_EQUAL(img(0,1), 0u);
+	BOOST_CHECK_EQUAL(img(1,1), 1u);
+	BOOST_CHECK_EQUAL(img(0,2), 1u);
+	BOOST_CHECK_EQUAL(img(1,2), 1u);
+
+	save_image("test_image.png", test_image);
+
+	auto test2_image = load_image2d("test_image.png");
+	
+	const C2DBitImage& img2 = dynamic_cast<const C2DBitImage&>(*test2_image); 
+	BOOST_CHECK_EQUAL(img2.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img2.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img(0,0), 0u);
+	BOOST_CHECK_EQUAL(img(1,0), 0u);
+	BOOST_CHECK_EQUAL(img(0,1), 0u);
+	BOOST_CHECK_EQUAL(img(1,1), 1u);
+	BOOST_CHECK_EQUAL(img(0,2), 1u);
+	BOOST_CHECK_EQUAL(img(1,2), 1u);
+
+        unlink("test_image.png"); 
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_16bit_gray )
+{
+	string filename(MIA_SOURCE_ROOT"/testdata/gray2x3-16.png");
+
+
+        auto test_image = load_image2d(filename);
+
+	const C2DUSImage& img = dynamic_cast<const C2DUSImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img(0,0),   0u);
+	BOOST_CHECK_EQUAL(img(1,0),  63u * 256);
+	BOOST_CHECK_EQUAL(img(0,1), 128u * 256);
+	BOOST_CHECK_EQUAL(img(1,1), 190u * 256);
+	BOOST_CHECK_EQUAL(img(0,2), 229u * 256);
+	BOOST_CHECK_EQUAL(img(1,2), 255u * 256);
+
+	save_image("test_image.png", test_image);
+
+	auto test2_image = load_image2d("test_image.png");
+	
+	const C2DUSImage& img2 = dynamic_cast<const C2DUSImage&>(*test2_image); 
+	BOOST_CHECK_EQUAL(img2.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img2.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img2(0,0),   0u);
+	BOOST_CHECK_EQUAL(img2(1,0),  63u * 256);
+	BOOST_CHECK_EQUAL(img2(0,1), 128u * 256);
+	BOOST_CHECK_EQUAL(img2(1,1), 190u * 256);
+	BOOST_CHECK_EQUAL(img2(0,2), 229u * 256);
+	BOOST_CHECK_EQUAL(img2(1,2), 255u * 256);
+
+        unlink("test_image.png"); 
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_8bit_rgb )
+{
+        vector<unsigned char> test_data{206, 89, 97, 71, 99, 67, 192, 205, 52,
+                        28, 31, 98, 94, 27, 204, 232, 18, 214};
+        
+        const auto& io = C2DRGBImageIOPluginPluginHandler::instance(); 
+
+        auto test_image = io.load(MIA_SOURCE_ROOT"/testdata/rgb3x2-24bit.png");
+
+        const CRGB2DImage& img = *test_image;
+
+        BOOST_CHECK_EQUAL(img.get_size().x, 3);
+        BOOST_CHECK_EQUAL(img.get_size().y, 2);
+        
+        auto pixels = img.pixel();
+        for (int i = 0; i < 18; ++i) {
+                BOOST_CHECK_EQUAL(pixels[i], test_data[i]); 
+        }
+
+        BOOST_REQUIRE(save_image("test_image_rgb.png", *test_image));
+        
+        auto test_image2 = io.load("test_image_rgb.png");
+
+        const CRGB2DImage& img2 = *test_image2;
+
+        BOOST_CHECK_EQUAL(img2.get_size().x, 3);
+        BOOST_CHECK_EQUAL(img2.get_size().y, 2);
+        
+        pixels = img2.pixel();
+        for (int i = 0; i < 18; ++i) {
+                BOOST_CHECK_EQUAL(pixels[i], test_data[i]); 
+        }
+
+        unlink("test_image_rgb.png"); 
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_rejects )
+{
+        const auto& io = C2DRGBImageIOPluginPluginHandler::instance(); 
+
+	BOOST_CHECK_THROW(io.load(MIA_SOURCE_ROOT"/testdata/gray2x3.png"),
+			  invalid_argument);
+	
+	BOOST_CHECK_THROW(io.load(MIA_SOURCE_ROOT"/testdata/nonexistent"),
+			  runtime_error); 
+
+	
+	BOOST_CHECK_THROW(load_image2d(MIA_SOURCE_ROOT"/testdata/rgb3x2-24bit.png"),
+			  invalid_argument);
+}
diff --git a/addons/tiff/CMakeLists.txt b/addons/tiff/CMakeLists.txt
index 3a69a43..67490c1 100644
--- a/addons/tiff/CMakeLists.txt
+++ b/addons/tiff/CMakeLists.txt
@@ -28,8 +28,10 @@ ENDIF(WITH_TIFF)
 
 IF(TIFF_FOUND)
   DEFINE_PROPERTY(GLOBAL PROPERTY HAVE_TIFF_PROP BRIEF_DOCS "yeah" FULL_DOCS "yeah")
-  SET(TIFF_LINK_LIBS ${MIA2DLIBS} ${TIFF_LIBRARIES})
+  SET(TIFF_LINK_LIBS mia2d ${TIFF_LIBRARIES})
   PLUGIN_WITH_PREFIX2("2dimage" "io" tiff "${TIFF_LINK_LIBS}")
   INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR})
+
+  NEW_TEST(tiff mia2d)
 ENDIF(TIFF_FOUND)
 
diff --git a/addons/tiff/test_tiff.cc b/addons/tiff/test_tiff.cc
new file mode 100644
index 0000000..3fa3662
--- /dev/null
+++ b/addons/tiff/test_tiff.cc
@@ -0,0 +1,243 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 <boost/filesystem/path.hpp>
+
+#include <mia/core/attribute_names.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/2d/imageio.hh>
+#include <mia/2d/rgbimageio.hh>
+
+NS_MIA_USE
+using namespace std; 
+using namespace boost::unit_test;
+namespace bfs = ::boost::filesystem; 
+
+
+BOOST_AUTO_TEST_CASE( test_load_save_8bit_gray )
+{
+	string filename(MIA_SOURCE_ROOT"/testdata/gray2x3.tif");
+
+
+        auto test_image = load_image2d(filename);
+
+	const C2DUBImage& img = dynamic_cast<const C2DUBImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img(0,0),   0u);
+	BOOST_CHECK_EQUAL(img(1,0),  63u);
+	BOOST_CHECK_EQUAL(img(0,1), 128u);
+	BOOST_CHECK_EQUAL(img(1,1), 190u);
+	BOOST_CHECK_EQUAL(img(0,2), 229u);
+	BOOST_CHECK_EQUAL(img(1,2), 255u);
+
+	save_image("test_image.tif", test_image);
+
+	auto test2_image = load_image2d("test_image.tif");
+	
+	const C2DUBImage& img2 = dynamic_cast<const C2DUBImage&>(*test2_image); 
+	BOOST_CHECK_EQUAL(img2.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img2.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img2(0,0),   0u);
+	BOOST_CHECK_EQUAL(img2(1,0),  63u);
+	BOOST_CHECK_EQUAL(img2(0,1), 128u);
+	BOOST_CHECK_EQUAL(img2(1,1), 190u);
+	BOOST_CHECK_EQUAL(img2(0,2), 229u);
+	BOOST_CHECK_EQUAL(img2(1,2), 255u);
+        unlink("test_image.tif"); 	
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_1bit_gray )
+{
+	string filename(MIA_SOURCE_ROOT"/testdata/gray2x3-1.tif");
+
+
+        auto test_image = load_image2d(filename);
+
+	const C2DBitImage& img = dynamic_cast<const C2DBitImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img(0,0), 0u);
+	BOOST_CHECK_EQUAL(img(1,0), 0u);
+	BOOST_CHECK_EQUAL(img(0,1), 0u);
+	BOOST_CHECK_EQUAL(img(1,1), 1u);
+	BOOST_CHECK_EQUAL(img(0,2), 1u);
+	BOOST_CHECK_EQUAL(img(1,2), 1u);
+
+	save_image("test_image.tif", test_image);
+
+	auto test2_image = load_image2d("test_image.tif");
+	
+	const C2DBitImage& img2 = dynamic_cast<const C2DBitImage&>(*test2_image); 
+	BOOST_CHECK_EQUAL(img2.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img2.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img(0,0), 0u);
+	BOOST_CHECK_EQUAL(img(1,0), 0u);
+	BOOST_CHECK_EQUAL(img(0,1), 0u);
+	BOOST_CHECK_EQUAL(img(1,1), 1u);
+	BOOST_CHECK_EQUAL(img(0,2), 1u);
+	BOOST_CHECK_EQUAL(img(1,2), 1u);
+
+        unlink("test_image.tif"); 
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_16bit_gray )
+{
+	string filename(MIA_SOURCE_ROOT"/testdata/gray2x3-16.tif");
+
+
+        auto test_image = load_image2d(filename);
+
+	const C2DUSImage& img = dynamic_cast<const C2DUSImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img(0,0),   0u);
+	BOOST_CHECK_EQUAL(img(1,0),  63u * 256);
+	BOOST_CHECK_EQUAL(img(0,1), 128u * 256);
+	BOOST_CHECK_EQUAL(img(1,1), 190u * 256);
+	BOOST_CHECK_EQUAL(img(0,2), 229u * 256);
+	BOOST_CHECK_EQUAL(img(1,2), 255u * 256);
+
+	save_image("test_image.tif", test_image);
+
+	auto test2_image = load_image2d("test_image.tif");
+	
+	const C2DUSImage& img2 = dynamic_cast<const C2DUSImage&>(*test2_image); 
+	BOOST_CHECK_EQUAL(img2.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img2.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img2(0,0),   0u);
+	BOOST_CHECK_EQUAL(img2(1,0),  63u * 256);
+	BOOST_CHECK_EQUAL(img2(0,1), 128u * 256);
+	BOOST_CHECK_EQUAL(img2(1,1), 190u * 256);
+	BOOST_CHECK_EQUAL(img2(0,2), 229u * 256);
+	BOOST_CHECK_EQUAL(img2(1,2), 255u * 256);
+
+        unlink("test_image.tif"); 
+}
+
+#ifdef USE_TIFF_RGB_IO
+BOOST_AUTO_TEST_CASE( test_load_save_8bit_rgb )
+{
+        vector<unsigned char> test_data{206, 89, 97, 71, 99, 67, 192, 205, 52,
+                        28, 31, 98, 94, 27, 204, 232, 18, 214};
+        
+        const auto& io = C2DRGBImageIOPluginPluginHandler::instance(); 
+
+        auto test_image = io.load(MIA_SOURCE_ROOT"/testdata/rgb3x2-24bit.tif");
+
+        const CRGB2DImage& img = *test_image;
+
+        BOOST_CHECK_EQUAL(img.get_size().x, 3);
+        BOOST_CHECK_EQUAL(img.get_size().y, 2);
+        
+        auto pixels = img.pixel();
+        for (int i = 0; i < 18; ++i) {
+                BOOST_CHECK_EQUAL(pixels[i], test_data[i]); 
+        }
+
+        BOOST_REQUIRE(save_image("test_image_rgb.tif", *test_image));
+        
+        auto test_image2 = io.load("test_image_rgb.tif");
+
+        const CRGB2DImage& img2 = *test_image2;
+
+        BOOST_CHECK_EQUAL(img2.get_size().x, 3);
+        BOOST_CHECK_EQUAL(img2.get_size().y, 2);
+        
+        pixels = img2.pixel();
+        for (int i = 0; i < 18; ++i) {
+                BOOST_CHECK_EQUAL(pixels[i], test_data[i]); 
+        }
+
+        unlink("test_image_rgb.tif"); 
+        
+}
+#endif 
+
+BOOST_AUTO_TEST_CASE( test_rejects )
+{
+	try {
+
+	BOOST_CHECK_THROW(load_image2d(MIA_SOURCE_ROOT"/testdata/nonexistent.tif"),
+			  std::runtime_error); 
+	}
+	catch (std::runtime_error& x) {
+		cvwarn() << "Expected exception thrown but BOOST_CHECK_THROW didn't catch it\n";
+	}
+}
+
+
+BOOST_AUTO_TEST_CASE( test_load_save_8bit_gray_multiframe )
+{
+	string filename(MIA_SOURCE_ROOT"/testdata/gray2x3-multiframe.tif");
+
+	const auto& io = C2DImageIOPluginHandler::instance(); 
+	
+        auto test_images = io.load(filename);
+
+	BOOST_CHECK_EQUAL(test_images->size(), 2u);
+
+	vector<vector<unsigned char>> expect{
+		{ 0, 63,128,190,229,255},
+		{68,212,135,190,194,184}};   
+			
+
+	for (unsigned i = 0; i < test_images->size(); ++i) {
+		const C2DUBImage& img = dynamic_cast<const C2DUBImage&>(*(*test_images)[i]); 
+		BOOST_CHECK_EQUAL(img.get_size().x, 2u);
+		BOOST_CHECK_EQUAL(img.get_size().y, 3u);
+		
+		BOOST_CHECK_EQUAL(img(0,0), expect[i][0]);
+		BOOST_CHECK_EQUAL(img(1,0), expect[i][1]);
+		BOOST_CHECK_EQUAL(img(0,1), expect[i][2]);
+		BOOST_CHECK_EQUAL(img(1,1), expect[i][3]);
+		BOOST_CHECK_EQUAL(img(0,2), expect[i][4]);
+		BOOST_CHECK_EQUAL(img(1,2), expect[i][5]);
+	}
+
+	BOOST_REQUIRE(io.save("test_image_multi.tif", *test_images));
+
+	auto test2_images = io.load("test_image_multi.tif");
+	BOOST_CHECK_EQUAL(test2_images->size(), 2u);
+
+	for (unsigned i = 0; i < test_images->size(); ++i) {
+		const C2DUBImage& img2 = dynamic_cast<const C2DUBImage&>(*(*test2_images)[i]);
+		BOOST_CHECK_EQUAL(img2.get_size().x, 2u);
+		BOOST_CHECK_EQUAL(img2.get_size().y, 3u);
+		
+		BOOST_CHECK_EQUAL(img2(0,0), expect[i][0]);
+		BOOST_CHECK_EQUAL(img2(1,0), expect[i][1]);
+		BOOST_CHECK_EQUAL(img2(0,1), expect[i][2]);
+		BOOST_CHECK_EQUAL(img2(1,1), expect[i][3]);
+		BOOST_CHECK_EQUAL(img2(0,2), expect[i][4]);
+		BOOST_CHECK_EQUAL(img2(1,2), expect[i][5]);
+	}
+
+	unlink("test_image_multi.tif"); 	
+}
diff --git a/addons/tiff/tiff.cc b/addons/tiff/tiff.cc
index c487511..6c1bff4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +97,7 @@ private:
 void MyErrorHandler(const char *module, const char *fmt,  va_list ap)
 {
 	char buf[16384];
-	snprintf(buf,16384, fmt, ap);
+	vsnprintf(buf,16384, fmt, ap);
 	throw create_exception<runtime_error>(module, ":", buf);
 }
 
@@ -242,11 +242,11 @@ P2DImage read_strip_pixels(CTiffFile& tif, unsigned int width,
 
 CTiff2DImageIO::PData CTiff2DImageIO::do_load(string const& filename)const
 {
-	CErrorHandlerReplacer error_handing;
 	CTiffFile tif(filename.c_str(), "r");
 	if (!tif)
 		return PData();
 
+	CErrorHandlerReplacer error_handing;
 	// load that stuff
 	uint32 height;
 	uint32 width;
diff --git a/addons/vistaio/2dtrans.cc b/addons/vistaio/2dtrans.cc
index 1fc2504..86e44f9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dtrans.hh b/addons/vistaio/2dtrans.hh
index 45b443b..b01f204 100644
--- a/addons/vistaio/2dtrans.hh
+++ b/addons/vistaio/2dtrans.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dvfvistaio.cc b/addons/vistaio/2dvfvistaio.cc
index 8bbfb1e..575d3c7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dvistaio.cc b/addons/vistaio/2dvistaio.cc
index cf906b2..a3beb4b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +61,7 @@ CVista2DImageIOPlugin::CVista2DImageIOPlugin():
 
 	add_standard_vistaio_properties(*this); 
 
+	add_suffix(".-");
 	add_suffix(".v");
 	add_suffix(".V");
 	add_suffix(".vista");
@@ -160,7 +161,7 @@ struct CVImageCreator: public TFilter <VistaIOImage> {
 template <typename T>
 VistaIOImage CVImageCreator::operator ()( const T2DImage<T>& image) const
 {
-	typedef dispatch_creat_vimage<typename T2DImage<T>::const_iterator, typename vista_repnkind<T>::type> dispatcher;
+	typedef dispatch_creat_vimage<typename T2DImage<T>::const_iterator, T> dispatcher;
 	VistaIOImage result = dispatcher::apply(image.begin(), image.end(), image.get_size().x, image.get_size().y, 1);
 	copy_attr_list(VistaIOImageAttrList(result), image);
 	return result;
diff --git a/addons/vistaio/2dvistaio.hh b/addons/vistaio/2dvistaio.hh
index 353093c..84b72d6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dtrans.cc b/addons/vistaio/3dtrans.cc
index f661f6b..3a1421a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dtrans.hh b/addons/vistaio/3dtrans.hh
index e584880..1a17962 100644
--- a/addons/vistaio/3dtrans.hh
+++ b/addons/vistaio/3dtrans.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dvfvistaio.cc b/addons/vistaio/3dvfvistaio.cc
index 7cdab10..c9fe7f8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dvistaio.cc b/addons/vistaio/3dvistaio.cc
index b95ed5a..ee14c15 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 @@ CVista3DImageIOPlugin::CVista3DImageIOPlugin():
 	add_supported_type(it_double);
 	
 	add_standard_vistaio_properties(*this); 
-	
+
+	add_suffix(".-");
 	add_suffix(".v");
 	add_suffix(".V");
 	add_suffix(".vista");
@@ -149,8 +150,7 @@ struct CVImageCreator: public TFilter <VistaIOImage> {
 template <typename T>
 VistaIOImage CVImageCreator::operator ()( const T3DImage<T>& image) const
 {
-	typedef dispatch_creat_vimage<typename T3DImage<T>::const_iterator,
-		typename vista_repnkind<T>::type> dispatcher;
+	typedef dispatch_creat_vimage<typename T3DImage<T>::const_iterator, T> dispatcher;
 	VistaIOImage result =  dispatcher::apply(image.begin(), image.end(),
 					   image.get_size().x, image.get_size().y, image.get_size().z);
 	copy_attr_list(VistaIOImageAttrList(result), image);
diff --git a/addons/vistaio/3dvistaio.hh b/addons/vistaio/3dvistaio.hh
index b6eb007..40303b0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/CMakeLists.txt b/addons/vistaio/CMakeLists.txt
index 80c6871..1fad07d 100644
--- a/addons/vistaio/CMakeLists.txt
+++ b/addons/vistaio/CMakeLists.txt
@@ -16,10 +16,10 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 
-OPTION(USE_VISTAIO "use libvistaio" TRUE)
+OPTION(WITH_VISTAIO "use libvistaio" TRUE)
 
 
-IF (USE_VISTAIO)
+IF (WITH_VISTAIO)
   if (STRICT_DEPENDECIES)
     pkg_check_modules(VISTAIO REQUIRED libvistaio>=1.2.14)
   else (STRICT_DEPENDECIES)
@@ -48,6 +48,8 @@ IF (USE_VISTAIO)
     PLUGIN_WITH_PREFIX2("mesh" "io" vistamesh "${DEPSMESH}")
     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)
@@ -55,6 +57,9 @@ IF (USE_VISTAIO)
     SET(VISTADEPLIBS vista4mia mia3dtest mia2dtest mia3d mia2d)
     
     TARGET_LINK_LIBRARIES(test-vista4mia ${VISTADEPLIBS} ${BOOST_UNITTEST})
+
+    SET(VISTAIO_TESTLIBS miamesh vista4mia)
+    NEW_TEST(vistaio "${VISTAIO_TESTLIBS}")
     
     SET(INSTALL_TARGETS vista4mia)	
     INSTALL_BASE("${INSTALL_TARGETS}")
@@ -66,4 +71,4 @@ IF (USE_VISTAIO)
     ENDIF(WIN32)
   
   ENDIF( VISTAIO_FOUND )
-ENDIF(USE_VISTAIO)
+ENDIF(WITH_VISTAIO)
diff --git a/addons/vistaio/test_2dtrans.cc b/addons/vistaio/test_2dtrans.cc
index b9dd08d..9c78c52 100644
--- a/addons/vistaio/test_2dtrans.cc
+++ b/addons/vistaio/test_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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_2dvistaio.cc b/addons/vistaio/test_2dvistaio.cc
index b461ec8..4bb4aac 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +35,6 @@ using namespace vista_2d_io;
 namespace bmpl=boost::mpl;
 
 typedef bmpl::vector<
-	bool,  
 	unsigned char,
 	signed short,
 	unsigned short,
@@ -88,3 +87,48 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_simple_write_read, T, type )
 	}
         unlink(filename.str().c_str()); 
 }
+
+BOOST_AUTO_TEST_CASE( test_simple_write_read_bool ) 
+{
+        C2DBounds size(2,3);
+	C2DBitImage *image = new C2DBitImage(size); 
+        P2DImage pimage(image); 
+
+        auto iv = image->begin(); 
+	auto ev = image->end();
+        bool i = false; 
+
+	while (iv != ev) {
+		*iv++ = i;
+		i = !i; 
+	}
+       
+
+	CVista2DImageIOPlugin io; 
+        CVista2DImageIOPlugin::Data images;
+        images.push_back(pimage); 
+
+	stringstream filename; 
+	filename << "testimage-bool.vista2d"; 
+
+	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 C2DBitImage&>(*(*loaded)[0]); 	
+	iv = image->begin(); 
+
+
+	auto il = ploaded.begin(); 
+	
+	while (iv != ev) {
+		BOOST_CHECK_EQUAL(*il, *iv); 
+		++iv; 
+		++il; 
+	}
+        unlink(filename.str().c_str()); 
+}
diff --git a/addons/vistaio/test_3dtrans.cc b/addons/vistaio/test_3dtrans.cc
index aeddbe6..d7bdcf1 100644
--- a/addons/vistaio/test_3dtrans.cc
+++ b/addons/vistaio/test_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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_3dvistaio.cc b/addons/vistaio/test_3dvistaio.cc
index d269a89..48ae716 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +35,6 @@ using namespace vista_3d_io;
 namespace bmpl=boost::mpl;
 
 typedef bmpl::vector<
-	bool,  
 	unsigned char,
 	signed short,
 	unsigned short,
@@ -92,3 +91,52 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_simple_write_read, T, type )
 	}
         unlink(filename.str().c_str()); 
 }
+
+BOOST_AUTO_TEST_CASE( test_simple_write_read_bool ) 
+{
+        C3DBounds size(2,3,4);
+	C3DBitImage *image = new C3DBitImage(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(); 
+	auto ev = image->end();
+        bool i = false; 
+
+	while (iv != ev) {
+		*iv++ = i;
+		i = !i;
+	}
+       
+
+	CVista3DImageIOPlugin io; 
+        CVista3DImageIOPlugin::Data images;
+        images.push_back(pimage); 
+
+	stringstream filename; 
+	filename << "testimage-bool.vista3d"; 
+
+	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; 
+	}
+        unlink(filename.str().c_str()); 
+}
diff --git a/addons/vistaio/test_vista4mia.cc b/addons/vistaio/test_vista4mia.cc
index ed91f51..6cfdd6b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ template <typename T>
 void check_value(const CAttributedData& attr_map, const string& key,  T value)
 {
 	const PAttribute pattr = attr_map.get_attribute(key);
-	cvdebug() << "check_value(" << key << ") = '" << value << "'\n";
+	cvdebug() << "check_value(" << key << ") = '" << value << "' of type " << typeid(T).name() << "\n";
 	const TAttribute<T> * attr = dynamic_cast<const TAttribute<T> *>(pattr.get());
 	BOOST_REQUIRE(attr);
 	T v = *attr;
@@ -117,6 +117,8 @@ BOOST_AUTO_TEST_CASE( check_translation)
         VistaIOSetAttr(vista_list1, "double", NULL, VistaIODoubleRepn, double_value);
         VistaIOSetAttr(vista_list1, "string", NULL, VistaIOStringRepn, string_value.c_str());
 
+	
+	
 	CAttributedData attr_map;
 
 	copy_attr_list(attr_map, vista_list1);
diff --git a/addons/vistaio/test_vistaio.cc b/addons/vistaio/test_vistaio.cc
new file mode 100644
index 0000000..e1ab621
--- /dev/null
+++ b/addons/vistaio/test_vistaio.cc
@@ -0,0 +1,378 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/>.
+ *
+ */
+
+// since vista meshes are not defined elsewhere we only need to test that
+// a loading-saving roundtrip gives the same result
+
+#define VSTREAM_DOMAIN "test_vistavmesh"
+
+#include <mia/internal/autotest.hh>
+#include <mia/mesh/triangularMesh.hh>
+#include <mia/2d/vfio.hh>
+#include <mia/3d/vfio.hh>
+
+#include <set>
+#include <ostream>
+
+
+using namespace mia;
+using namespace std;
+
+
+template <typename V>
+struct vector3d_less {
+	bool operator()( const V& lhs, const V& rhs ) const {
+		return (lhs.x < rhs.x) || (lhs.x == rhs.x && (lhs.y < rhs.y || (lhs.y == rhs.y && lhs.z < rhs.z))); 
+	}
+}; 
+
+set<C3DFVector, vector3d_less<C3DFVector> > test_vertices = {
+        C3DFVector(2,0,0), C3DFVector(-2,0,0), 
+        C3DFVector(0,2,0), C3DFVector(0,-2,0), 
+        C3DFVector(0,0,1), C3DFVector(0,0,-1)
+};
+
+set<C3DFVector, vector3d_less<C3DFVector> > test_normals = {
+        C3DFVector(1,0,0), C3DFVector(-1,0,0), 
+        C3DFVector(0,1,0), C3DFVector(0,-1,0), 
+        C3DFVector(0,0,1), C3DFVector(0,0,-1)
+};
+
+set<C3DFVector, vector3d_less<C3DFVector> > test_colors = {
+        C3DFVector(0.1, 0.5, 0.5), C3DFVector(0.2, 0.6, 0.7), 
+        C3DFVector(0.3, 0.6, 0.7), C3DFVector(0.4, 0.6, 0.7), 
+        C3DFVector(0.5, 0.6, 0.7), C3DFVector(0.6, 0.6, 1)
+};
+
+set<float> test_scale = {
+	0.1, 2.2, 4.3, 3.4, 0.5, 0.6
+};
+
+typedef CTriangleMesh::triangle_type Triangle; 
+
+set<Triangle, vector3d_less<Triangle>>  test_triangles = 
+        {Triangle(4, 0, 2), Triangle(4, 2, 1), 
+         Triangle(4, 1, 3), Triangle(4, 3, 0), 
+         Triangle(5, 2, 0), Triangle(5, 1, 2), 
+         Triangle(5, 3, 1), Triangle(5, 0, 3)};
+
+
+template <typename T>
+ostream& operator << (ostream& os, const set<T, vector3d_less<T>>& s)
+{
+	os << "set:[";
+	for (auto x: s)
+		os << "<" << x << "> ";
+	os << "]\n";
+	return os; 
+}
+
+
+template <typename IT, typename T> 
+void test_set_equal(const IT begin, IT end,
+		    const set<T, vector3d_less<T>>& expect)
+{
+        set<T, vector3d_less<T>> loaded(begin, end);
+        BOOST_CHECK_EQUAL(loaded.size(), expect.size());
+
+	BOOST_CHECK(loaded == expect);
+	cvdebug() << loaded << "\n";
+	cvdebug() << expect << "\n"; 
+        
+}
+
+template <typename IT, typename T> 
+void test_set_equal(const IT begin, IT end,
+		    const set<T>& expect)
+{
+        set<T> loaded(begin, end);
+        BOOST_CHECK_EQUAL(loaded.size(), expect.size());
+
+	BOOST_CHECK(loaded == expect);
+}
+
+struct CVistaMeshtestFixtureV {
+
+        CVistaMeshtestFixtureV();
+
+        virtual void test_loaded( const CTriangleMesh& loaded);  
+
+        void run(const char *testfilename); 
+        
+        PTriangleMesh mesh;
+}; 
+
+CVistaMeshtestFixtureV::CVistaMeshtestFixtureV()
+{
+        auto vertices = CTriangleMesh::PVertexfield(
+                          new CTriangleMesh::CVertexfield(test_vertices.begin(), test_vertices.end()));
+
+        auto triangles = CTriangleMesh::PTrianglefield(
+                          new CTriangleMesh::CTrianglefield(test_triangles.begin(), test_triangles.end()));
+        mesh.reset(new CTriangleMesh(triangles, vertices)); 
+}
+
+void CVistaMeshtestFixtureV::test_loaded( const CTriangleMesh& loaded)
+{
+        BOOST_CHECK_EQUAL(loaded.get_available_data(), mesh->get_available_data()); 
+        
+        test_set_equal(loaded.vertices_begin(), loaded.vertices_end(), test_vertices);
+        test_set_equal(loaded.triangles_begin(), loaded.triangles_end(), test_triangles); 
+}
+
+void CVistaMeshtestFixtureV::run(const char *testfilename)
+{
+        BOOST_REQUIRE(CMeshIOPluginHandler::instance().save(testfilename, *mesh));
+        auto loaded_mesh = CMeshIOPluginHandler::instance().load(testfilename);
+        BOOST_REQUIRE(loaded_mesh);
+        test_loaded(*loaded_mesh); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_vista_meshio_v, CVistaMeshtestFixtureV)
+{
+        run("mesh-v.vmesh"); 
+}
+
+
+struct CVistaMeshtestFixtureVN : public CVistaMeshtestFixtureV{
+        CVistaMeshtestFixtureVN();
+        virtual void test_loaded( const CTriangleMesh& loaded);  
+};
+
+CVistaMeshtestFixtureVN::CVistaMeshtestFixtureVN()
+{
+        copy(test_normals.begin(), test_normals.end(), mesh->normals_begin()); 
+}
+
+void CVistaMeshtestFixtureVN::test_loaded( const CTriangleMesh& loaded)
+{
+        CVistaMeshtestFixtureV::test_loaded(loaded);
+
+        test_set_equal(loaded.normals_begin(), loaded.normals_end(), test_normals);
+}
+
+BOOST_FIXTURE_TEST_CASE( test_vista_meshio_vn, CVistaMeshtestFixtureVN)
+{
+        run("mesh-vn.vmesh"); 
+}
+
+
+
+
+struct CVistaMeshtestFixtureVNC : public CVistaMeshtestFixtureVN{
+        CVistaMeshtestFixtureVNC();
+        virtual void test_loaded( const CTriangleMesh& loaded);  
+};
+
+CVistaMeshtestFixtureVNC::CVistaMeshtestFixtureVNC()
+{
+        copy(test_colors.begin(), test_colors.end(), mesh->color_begin()); 
+}
+
+void CVistaMeshtestFixtureVNC::test_loaded( const CTriangleMesh& loaded)
+{
+        CVistaMeshtestFixtureVN::test_loaded(loaded);
+
+        test_set_equal(loaded.color_begin(), loaded.color_end(), test_colors);
+}
+
+BOOST_FIXTURE_TEST_CASE( test_vista_meshio_vnc, CVistaMeshtestFixtureVNC)
+{
+        run("mesh-vnc.vmesh"); 
+}
+
+
+struct CVistaMeshtestFixtureVC : public CVistaMeshtestFixtureV{
+        CVistaMeshtestFixtureVC();
+        virtual void test_loaded( const CTriangleMesh& loaded);  
+};
+
+CVistaMeshtestFixtureVC::CVistaMeshtestFixtureVC()
+{
+        copy(test_colors.begin(), test_colors.end(), mesh->color_begin()); 
+}
+
+void CVistaMeshtestFixtureVC::test_loaded( const CTriangleMesh& loaded)
+{
+        CVistaMeshtestFixtureV::test_loaded(loaded);
+
+        test_set_equal(loaded.color_begin(), loaded.color_end(), test_colors);
+}
+
+BOOST_FIXTURE_TEST_CASE( test_vista_meshio_vc, CVistaMeshtestFixtureVC)
+{
+        run("mesh-vc.vmesh"); 
+}
+
+
+struct CVistaMeshtestFixtureVS : public CVistaMeshtestFixtureV{
+        CVistaMeshtestFixtureVS();
+        virtual void test_loaded( const CTriangleMesh& loaded);  
+};
+
+CVistaMeshtestFixtureVS::CVistaMeshtestFixtureVS()
+{
+        copy(test_scale.begin(), test_scale.end(), mesh->scale_begin()); 
+}
+
+void CVistaMeshtestFixtureVS::test_loaded( const CTriangleMesh& loaded)
+{
+        CVistaMeshtestFixtureV::test_loaded(loaded);
+
+        test_set_equal(loaded.scale_begin(), loaded.scale_end(), test_scale);
+}
+
+BOOST_FIXTURE_TEST_CASE( test_vista_meshio_vs, CVistaMeshtestFixtureVS)
+{
+        run("mesh-vs.vmesh"); 
+}
+
+
+struct CVistaMeshtestFixtureVCS : public CVistaMeshtestFixtureVC{
+        CVistaMeshtestFixtureVCS();
+        virtual void test_loaded( const CTriangleMesh& loaded);  
+};
+
+CVistaMeshtestFixtureVCS::CVistaMeshtestFixtureVCS()
+{
+        copy(test_scale.begin(), test_scale.end(), mesh->scale_begin()); 
+}
+
+void CVistaMeshtestFixtureVCS::test_loaded( const CTriangleMesh& loaded)
+{
+        CVistaMeshtestFixtureVC::test_loaded(loaded);
+
+        test_set_equal(loaded.scale_begin(), loaded.scale_end(), test_scale);
+}
+
+BOOST_FIXTURE_TEST_CASE( test_vista_meshio_vcs, CVistaMeshtestFixtureVCS)
+{
+        run("mesh-vcs.vmesh"); 
+}
+
+struct CVistaMeshtestFixtureVNCS : public CVistaMeshtestFixtureVNC{
+        CVistaMeshtestFixtureVNCS();
+        virtual void test_loaded( const CTriangleMesh& loaded);  
+};
+
+CVistaMeshtestFixtureVNCS::CVistaMeshtestFixtureVNCS()
+{
+        copy(test_scale.begin(), test_scale.end(), mesh->scale_begin()); 
+}
+
+void CVistaMeshtestFixtureVNCS::test_loaded( const CTriangleMesh& loaded)
+{
+        CVistaMeshtestFixtureVNC::test_loaded(loaded);
+
+        test_set_equal(loaded.scale_begin(), loaded.scale_end(), test_scale);
+}
+
+BOOST_FIXTURE_TEST_CASE( test_vista_meshio_vncs, CVistaMeshtestFixtureVNCS)
+{
+        run("mesh-vncs.vmesh"); 
+}
+
+
+struct CVistaMeshtestFixtureVNS : public CVistaMeshtestFixtureVN {
+        CVistaMeshtestFixtureVNS();
+        virtual void test_loaded( const CTriangleMesh& loaded);  
+};
+
+CVistaMeshtestFixtureVNS::CVistaMeshtestFixtureVNS()
+{
+        copy(test_scale.begin(), test_scale.end(), mesh->scale_begin()); 
+}
+
+void CVistaMeshtestFixtureVNS::test_loaded( const CTriangleMesh& loaded)
+{
+        CVistaMeshtestFixtureVN::test_loaded(loaded);
+
+        test_set_equal(loaded.scale_begin(), loaded.scale_end(), test_scale);
+}
+
+BOOST_FIXTURE_TEST_CASE( test_vista_meshio_vns, CVistaMeshtestFixtureVNS)
+{
+        run("mesh-vns.vmesh"); 
+}
+
+
+
+BOOST_AUTO_TEST_CASE ( test_3dvfio )
+{
+        C3DBounds size(1,2,3); 
+        C3DFVectorfield vf(size);
+
+        vector<C3DFVector> test_data = {
+                C3DFVector(1, 2, 3), C3DFVector(2, 3, 4), C3DFVector(3, 4, 5),
+                C3DFVector(4, 5, 6), C3DFVector(5, 6, 7), C3DFVector(7, 8, 9)
+        };
+
+        copy(test_data.begin(), test_data.end(), vf.begin()); 
+
+        C3DIOVectorfield iovf(vf); 
+        BOOST_REQUIRE(C3DVFIOPluginHandler::instance().save("3d.vf", iovf));
+
+        auto loaded = C3DVFIOPluginHandler::instance().load("3d.vf");
+        BOOST_REQUIRE(loaded);
+        
+        BOOST_CHECK_EQUAL(loaded->get_size(), size);
+        auto i = loaded->begin();
+        auto e = loaded->end();
+        auto t = vf.begin();
+
+        while (i != e) {
+                BOOST_CHECK_EQUAL(*i, *t);
+                ++i; ++t; 
+        }
+}
+
+BOOST_AUTO_TEST_CASE ( test_2dvfio )
+{
+        C2DBounds size(2,3); 
+        C2DFVectorfield vf(size);
+
+        vector<C2DFVector> test_data = {
+                C2DFVector(2, 3), C2DFVector(3, 4), C2DFVector(4, 5),
+                C2DFVector(5, 6), C2DFVector(6, 7), C2DFVector(8, 9)
+        };
+
+        copy(test_data.begin(), test_data.end(), vf.begin()); 
+
+        C2DIOVectorfield iovf(vf); 
+        BOOST_REQUIRE(C2DVFIOPluginHandler::instance().save("2d.vf", iovf));
+
+        auto loaded = C2DVFIOPluginHandler::instance().load("2d.vf");
+        BOOST_REQUIRE(loaded);
+        
+        BOOST_CHECK_EQUAL(loaded->get_size(), size);
+        auto i = loaded->begin();
+        auto e = loaded->end();
+        auto t = vf.begin();
+
+        while (i != e) {
+                BOOST_CHECK_EQUAL(*i, *t);
+                ++i; ++t; 
+        }
+}
+
+
+
+
+
diff --git a/addons/vistaio/vista4mia.cc b/addons/vistaio/vista4mia.cc
index 20013e7..d7cf2f1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,12 +29,21 @@ using namespace boost;
 
 NS_MIA_BEGIN
 
+template <typename T> 
+void vistaio_add_attribute(CAttributedData& attr, const string& name, T value)
+{
+	cvdebug() << "add attribute " << name << " of type 'string' and value '" << value << "'\n";
+	attr.set_attribute(name, PAttribute(new TAttribute<T>(value))); 
+}
+
+template <> 
 void vistaio_add_attribute(CAttributedData& attr, const string& name, VistaIOString value)
 {
 	cvdebug() << "add attribute " << name << " of type 'string' and value '" << value << "'\n";
 	attr.set_attribute(name, CStringAttrTranslatorMap::instance().to_attr(name, value)); 
 }
 
+template <> 
 void vistaio_add_attribute(CAttributedData& attr, const string& name, VistaIOBit value)
 {
 	cvdebug() << "add attribute " << name << " of type " << typeid(VistaIOBit).name() << " and value '" << value << "'\n";
@@ -56,6 +65,10 @@ VISTA4MIA_EXPORT void copy_attr_list(CAttributedData& attributes, const VistaIOA
 	VistaIOFirstAttr(in_list, &pos);
 	while (VistaIOAttrExists(&pos)){
 		std::string name(VistaIOGetAttrName(&pos));
+
+		// actually, vistaio internally stores all scalar values as string
+		// which means most of this switch is dead code.
+		// 
 		cvdebug() << "got " << name << " " << VistaIOGetAttrRepn(&pos) << "\n";
 		switch (VistaIOGetAttrRepn(&pos)) {
 		case VistaIOStringRepn:{
@@ -79,7 +92,7 @@ VISTA4MIA_EXPORT void copy_attr_list(CAttributedData& attributes, const VistaIOA
 			vistaio_add_attribute(attributes, name, f);
 		}break;
 		case VistaIOLongRepn:{
-			long f;
+			int f;
 			VistaIOGetAttrValue(&pos,NULL,VistaIOLongRepn,&f);
 			vistaio_add_attribute(attributes, name, f);
 		}break;
diff --git a/addons/vistaio/vista4mia.hh b/addons/vistaio/vista4mia.hh
index 805e624..19e5236 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,11 +119,11 @@ struct vista_repnkind<std::string> {
 template <typename I, typename O>
 struct dispatch_creat_vimage {
 	static VistaIOImage apply(I begin, I end, size_t x, size_t y, size_t z) {
-		typedef typename std::iterator_traits<I>::value_type pixel_type; 
-		VistaIOImage result = VistaIOCreateImage(z, y, x, vista_repnkind<pixel_type>::value);
+		VistaIOImage result = VistaIOCreateImage(z, y, x, vista_repnkind<O>::value);
+		assert(result); 
 		
 		VistaIOSetAttr(VistaIOImageAttrList(result), "repn-unsigned", NULL, VistaIOBitRepn, 
-			       vista_repnkind<pixel_type>::is_unsigned);
+			       vista_repnkind<O>::is_unsigned);
 
 		std::copy(begin, end, (O *)VistaIOPixelPtr(result,0,0,0));
 		return result;
@@ -146,7 +146,7 @@ VISTA4MIA_EXPORT void copy_attr_list(mia::CAttributedData& attributes, const Vis
 /**
    Helper class to indice atomatic destruction of vista attribute lists. 
  */
-class CVAttrList {
+class VISTA4MIA_EXPORT CVAttrList {
 public: 
 	CVAttrList(VistaIOAttrList list); 
 	~CVAttrList(); 
diff --git a/addons/vistaio/vistamesh.cc b/addons/vistaio/vistamesh.cc
index 0d00fb3..35b8948 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +54,7 @@ CVistaMeshIO::CVistaMeshIO():
 	CMeshIOPlugin(format)
 {
 	//add_property(io_plugin_property_history);
+	add_suffix(".-");
 	add_suffix(".v");
 	add_suffix(".V");
 	add_suffix(".vmesh");
@@ -219,9 +220,11 @@ static CTriangleMesh *read_vcgraph(VistaIOGraph vgraph, VistaIOGraph tgraph)
 	CTriangleMesh::vertex_iterator e = vertices->end();
 	CTriangleMesh::color_iterator c = color->begin();
 
+	cvdebug() << "First color = " << *c << "\n"; 
 	while (node && v != e) {
 		*v++ = node->vertex;
 		*c++ = node->color;
+		cvdebug() << "load: n=" << node->vertex << " c=" << node->color << "\n"; 
 		node = (TVCNodeType<float> *)VistaIOGraphNextNode(vgraph);
 	}
 
@@ -416,7 +419,7 @@ static VistaIOGraph create_vngraph(const CTriangleMesh& mesh)
 	TVNNodeType<float> node;
 	node.type = 2;
 	int pos = 1;
-
+	
 	while (vi != ve) {
 		node.vertex = *vi++;
 		node.normal = *ni++;
@@ -476,12 +479,13 @@ static VistaIOGraph create_vcgraph(const CTriangleMesh& mesh)
 	CTriangleMesh::const_color_iterator  ci  = mesh.color_begin();
 
 	int pos = 1;
-	TVNCNodeType<float> node;
+	TVCNodeType<float> node;
 	node.type = 7;
-
+	
 	while (vi != ve) {
 		node.vertex = *vi++;
 		node.color  = *ci++;
+		cvdebug() << "write: n=" << node.vertex << " c=" << node.color << "\n"; 
 		VistaIOGraphAddNodeAt(result,(VistaIONodestruct*)&node,pos++);
 	}
 	return result;
@@ -782,13 +786,13 @@ bool CVistaMeshIO::do_save(string const &  filename, const CTriangleMesh& mesh)c
 	while (lookup->data_avail && lookup->data_avail != type)
 		++lookup;
 
-	cvdebug() << "will save " << lookup->type_name << "\n";
-
 	if (!lookup->data_avail) {
 		cverr() << "Fatal: unknown data in mesh\n";
 		return false;
 	}
 
+	cvdebug() << "will save " << lookup->type_name << "\n";
+	
 	vertex_graph = lookup->create(mesh);
 
 	if (!vertex_graph) {
diff --git a/addons/vtk/test_vtkimage.cc b/addons/vtk/test_vtkimage.cc
index 5e1818d..9a00e4f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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_vtkmesh.cc b/addons/vtk/test_vtkmesh.cc
index bc6fe62..b929e09 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 4b2af70..4decd75 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 9dbf165..1b93492 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 @@
 #include <vtkSmartPointer.h>
 #include <vtkPoints.h>
 
+#include <type_traits>
+
 using namespace mia; 
 using namespace std; 
 using namespace vtkimage; 
@@ -62,7 +64,7 @@ using namespace vtkimage;
 template <typename T> 
 struct __vtk_data_array {
 	typedef void type;
-        typedef __false_type supported;			\
+        typedef false_type supported;			\
 };  
 
 
@@ -70,7 +72,7 @@ struct __vtk_data_array {
 	template <>			    \
 	struct __vtk_data_array<TYPE> {	    \
 		typedef VTK_TYPE type;	    \
-		typedef __true_type supported; \
+		typedef true_type supported; \
 		static const int value = ID; \
 	};
 
@@ -196,7 +198,7 @@ struct __dispatch_convert {
 }; 
 
 template <typename T> 
-struct __dispatch_convert<T, __true_type> {
+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"; 
@@ -213,7 +215,7 @@ struct __dispatch_convert<T, __true_type> {
 }; 
 
 template <> 
-struct __dispatch_convert<bool, __true_type> {
+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"; 
diff --git a/addons/vtk/vtkimage.hh b/addons/vtk/vtkimage.hh
index 5d4ca67..1206642 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 477ed0c..4da4b29 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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.hh b/addons/vtk/vtkmesh.hh
index fc2d231..5b5693e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 1523aa3..a9807d1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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.hh b/addons/vtk/vtkvf.hh
index bb619c6..0d3da1a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/FindDCMTKnew.cmake b/cmake/FindDCMTKnew.cmake
index e99a700..64a0930 100644
--- a/cmake/FindDCMTKnew.cmake
+++ b/cmake/FindDCMTKnew.cmake
@@ -90,7 +90,32 @@ IF (ZLIB_FOUND)
     SET(DCMTK_LIBS ${DCMTK_REQUIRED_LIBS} ${DCMTK_NEW_LIBS})    
   ENDIF(VERSION_BEFORE_360) 
   
-  SET(DCMTK_LIBRARIES ${DCMTK_LIBS} ${ZLIB_LIBRARIES})
+
+  SET(CMAKE_REQUIRED_INCLUDES ${DCMTK_config_INCLUDE_DIR})
+  SET(CMAKE_REQUIRED_LIBRARIES ofstd)
+  # test if ofstd requires iconv
+  CHECK_CXX_SOURCE_COMPILES(
+    "#include <dcmtk/ofstd/offname.h>
+
+    int main(int argc, char *args[]) 
+  {
+	OFFilenameCreator c; 
+        return 0; 
+  }
+" DCMTK_NO_ICONV)
+
+  IF(DCMTK_NO_ICONV)
+    MESSAGE(STATUS "DCMTK does not need -liconv")
+    SET(DCMTK_LIBRARIES ${DCMTK_LIBS} ${ZLIB_LIBRARIES})
+  ELSE()
+    FIND_LIBRARY(ICONV_LIBRARY NAMES iconv)
+    IF(NOT ICONV_LIBRARY) 
+      SET(DCMTK_LIBRARIES ${DCMTK_LIBS} ${ZLIB_LIBRARIES})
+    ELSE()
+      SET(DCMTK_LIBRARIES ${DCMTK_LIBS} ${ZLIB_LIBRARIES} ${ICONV_LIBRARY})
+      MESSAGE(ERROR "DCMTK required iconv, but it couldn't be found")
+    ENDIF()
+  ENDIF()
 
   IF( DCMTK_config_INCLUDE_DIR AND DCMTK_LIBS )
     
diff --git a/cmake/macros.cmake b/cmake/macros.cmake
index ca47b6a..f70e00b 100644
--- a/cmake/macros.cmake
+++ b/cmake/macros.cmake
@@ -186,6 +186,8 @@ ENDMACRO(CREATE_MANPAGE_FROM_XML)
 
 MACRO(DEFEXE name libraries) 
   ADD_EXECUTABLE(mia-${name} ${name}.cc)
+  SET_TARGET_PROPERTIES(mia-${name} PROPERTIES COMPILE_FLAGS -DVSTREAM_DOMAIN='"${name}"')
+  
   FOREACH(lib ${libraries}) 
     TARGET_LINK_LIBRARIES(mia-${name} ${lib})
   ENDFOREACH(lib)
@@ -197,24 +199,29 @@ MACRO(DEFEXE name libraries)
 ENDMACRO(DEFEXE)
 
 
+
 MACRO(DEFCHKEXE name deps) 
   ADD_EXECUTABLE(mia-${name} ${name}.cc)
   
   FOREACH(lib ${deps}) 
     TARGET_LINK_LIBRARIES(mia-${name} ${lib})
   ENDFOREACH(lib)
-  SET_TARGET_PROPERTIES(mia-${name} PROPERTIES COMPILE_FLAGS -DVSTREAM='\\\"TEST-2D\\\"' COMPILE_FLAGS -DBOOST_TEST_DYN_LINK)
+  SET_TARGET_PROPERTIES(mia-${name} PROPERTIES COMPILE_FLAGS -DVSTREAM_DOMAIN='"${name}"')
+  SET_TARGET_PROPERTIES(mia-${name} PROPERTIES COMPILE_FLAGS -DBOOST_TEST_DYN_LINK)
   TARGET_LINK_LIBRARIES(mia-${name} ${BASELIBS})
   TARGET_LINK_LIBRARIES(mia-${name} ${BOOST_UNITTEST})
   INSTALL(TARGETS mia-${name} RUNTIME DESTINATION "bin")
 
   MIA_EXE_CREATE_DOCU_AND_INTERFACE(mia ${name})
   ADD_DEPENDENCIES(mia-${name} plugin_test_links)
-  ADD_TEST(${name} mia-${name} --selftest)
-ENDMACRO(DEFCHKEXE)
+  ADD_TEST(${name} mia-${name} -- --selftest)
 
+  SET_TESTS_PROPERTIES(${name}
+    PROPERTIES ENVIRONMENT "MIA_PLUGIN_TESTPATH=${PLUGIN_TEST_ROOT}/${PLUGIN_INSTALL_PATH}")
 
-MACRO(NEW_TEST name libs)
+ENDMACRO(DEFCHKEXE)
+
+MACRO(NEW_TEST_BASE name libs)
   SET(EXENAME test-${name})
   
   ADD_EXECUTABLE(${EXENAME} test_${name}.cc)
@@ -223,5 +230,17 @@ MACRO(NEW_TEST name libs)
     TARGET_LINK_LIBRARIES(${EXENAME} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
   ENDIF (NOT WIN32)
   ADD_DEPENDENCIES(${EXENAME} plugin_test_links)
+
+ENDMACRO(NEW_TEST_BASE)
+
+MACRO(NEW_TEST name libs)
+  NEW_TEST_BASE(${name} "${libs}")
   ADD_TEST(${name} ${EXENAME})
 ENDMACRO(NEW_TEST)
+
+MACRO(NEW_TEST_WITH_PARAM name libs param)
+  NEW_TEST_BASE(${name} "${libs}")
+  ADD_TEST(${name} ${EXENAME} ${param})
+  SET_TESTS_PROPERTIES(${name}
+    PROPERTIES ENVIRONMENT "MIA_PLUGIN_TESTPATH=${PLUGIN_TEST_ROOT}/${PLUGIN_INSTALL_PATH}")
+ENDMACRO(NEW_TEST_WITH_PARAM)
diff --git a/cmake/pluginmacro.cmake b/cmake/pluginmacro.cmake
index dce519d..6ca9ff3 100644
--- a/cmake/pluginmacro.cmake
+++ b/cmake/pluginmacro.cmake
@@ -49,33 +49,34 @@ MACRO(PARSE_ARGUMENTS prefix arg_names option_names)
   SET(${prefix}_${current_arg_name} ${current_arg_list})
 ENDMACRO(PARSE_ARGUMENTS)
 
-MACRO(CREATE_PLUGIN_COMMON plugname files libs) 
-  add_library(${plugname}-common STATIC "${files}")
+MACRO(CREATE_PLUGIN_COMMON plugname files) 
+  add_library(${plugname}-common OBJECT "${files}")
   IF(NOT WIN32)
 	set_source_files_properties(${files}  PROPERTIES COMPILE_FLAGS "-fPIC")
 	set_target_properties(${plugname}-common  PROPERTIES COMPILE_FLAGS -DVSTREAM_DOMAIN='"${plugname}"') 
   ENDIF(NOT WIN32)
-  target_link_libraries(${plugname}-common ${libs})
-ENDMACRO(CREATE_PLUGIN_COMMON plugname libs) 
+#  target_link_libraries(${plugname}-common ${libs})
+ENDMACRO(CREATE_PLUGIN_COMMON plugname) 
 
-MACRO(CREATE_PLUGIN_MODULE plugname)
+MACRO(CREATE_PLUGIN_MODULE plugname libs)
 #  add_library(${plugname} MODULE NO_SOURCE_FILES)
-  add_library(${plugname} MODULE ${CMAKE_SOURCE_DIR}/mia/core/silence_cmake_missing_source_file_warning.c)
+  add_library(${plugname} MODULE $<TARGET_OBJECTS:${plugname}-common>)
 #  MESSAGE("Remark: Ignore this warning, calling ADD_LIBRARY without source files was done intentionally.")
   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"
-      )
+#    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)
+  target_link_libraries(${plugname} ${libs})
+#  MESSAGE(STATUS "${plugname} depends on ${libs}")
 ENDMACRO(CREATE_PLUGIN_MODULE plugname)
 
-MACRO(CREATE_PLUGIN_TEST plugname file)
+MACRO(CREATE_PLUGIN_TEST plugname file libs)
   PARSE_ARGUMENTS(PLUGIN "TESTLIBS" "" ${ARGN})
-  add_executable(test-${plugname} ${file})
+  add_executable(test-${plugname} ${file} $<TARGET_OBJECTS:${plugname}-common>)
   IF(NOT WIN32)
     set_target_properties(test-${plugname} PROPERTIES 
       COMPILE_FLAGS -DVSTREAM_DOMAIN='"${plugname}"' 
@@ -84,16 +85,16 @@ MACRO(CREATE_PLUGIN_TEST plugname file)
     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}")
+#  target_link_libraries(test-${plugname} ${plugname}-common)
+  target_link_libraries(test-${plugname} ${libs} ${BOOST_UNITTEST} "${PLUGIN_TESTLIBS}")
   add_test(${plugname} test-${plugname})
 ENDMACRO(CREATE_PLUGIN_TEST plugname file)
 
 MACRO(PLUGIN_WITH_TEST plugname file libs)
   PARSE_ARGUMENTS(PLUGIN "TESTLIBS" "" ${ARGN})
-  CREATE_PLUGIN_COMMON(${plugname} ${file} "${libs}")
-  CREATE_PLUGIN_MODULE(${plugname})
-  CREATE_PLUGIN_TEST(${plugname} test_${file} TESTLIBS "${PLUGIN_TESTLIBS}")
+  CREATE_PLUGIN_COMMON(${plugname} ${file} )
+  CREATE_PLUGIN_MODULE(${plugname} "${libs}")
+  CREATE_PLUGIN_TEST(${plugname} test_${file} "${libs}" TESTLIBS "${PLUGIN_TESTLIBS}")
 ENDMACRO(PLUGIN_WITH_TEST plugname file libs)
 
 MACRO(PLUGIN_WITH_TEST_AND_PREFIX_NOINST prefix plugname libs)
@@ -125,8 +126,8 @@ MACRO(PLUGIN_WITH_PREFIX2 type data plugname libs)
   SET(install_path ${${type}_${data}_dir})
   PARSE_ARGUMENTS(PLUGIN "TESTLIBS" "" ${ARGN})
   SET(name ${${type}_${data}_prefix}-${plugname})
-  CREATE_PLUGIN_COMMON(${name} ${plugname}.cc "${libs}")
-  CREATE_PLUGIN_MODULE(${name})
+  CREATE_PLUGIN_COMMON(${name} ${plugname}.cc)
+  CREATE_PLUGIN_MODULE(${name} "${libs}")
   ADD_CUSTOM_TARGET(${name}_test_link ln -sf "${CMAKE_CURRENT_BINARY_DIR}/${name}.mia" 
     ${PLUGIN_TEST_ROOT}/${install_path}/ DEPENDS ${type}_${data}_testdir ${name})
   ADD_DEPENDENCIES(plugin_test_links ${name}_test_link)
@@ -143,9 +144,9 @@ MACRO(PLUGIN_WITH_TEST_AND_PREFIX2 type data plugname libs)
   PARSE_ARGUMENTS(PLUGIN "TESTLIBS" "" ${ARGN})
 
   SET(name ${${type}_${data}_prefix}-${plugname})
-  CREATE_PLUGIN_COMMON(${name} ${plugname}.cc "${libs}")
-  CREATE_PLUGIN_MODULE(${name})
-  CREATE_PLUGIN_TEST(${name} test_${plugname}.cc TESTLIBS "${PLUGIN_TESTLIBS}")
+  CREATE_PLUGIN_COMMON(${name} ${plugname}.cc)
+  CREATE_PLUGIN_MODULE(${name} "${libs}")
+  CREATE_PLUGIN_TEST(${name} test_${plugname}.cc "${libs}" TESTLIBS "${PLUGIN_TESTLIBS}")
   ADD_CUSTOM_TARGET(${name}_test_link ln -sf "${CMAKE_CURRENT_BINARY_DIR}/${name}.mia" 
     ${PLUGIN_TEST_ROOT}/${install_path}/ DEPENDS ${type}_${data}_testdir ${name})
   ADD_DEPENDENCIES(plugin_test_links ${name}_test_link)
@@ -175,25 +176,24 @@ MACRO(PLUGIN_WITH_TEST_MULTISOURCE name type data src libs)
   SET(plugname ${${type}_${data}_prefix}-${name})
 
   # create common library 
-  ADD_LIBRARY(${plugname}-common STATIC ${src})
+  ADD_LIBRARY(${plugname}-common OBJECT ${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)
+  ADD_LIBRARY(${plugname} MODULE $<TARGET_OBJECTS:${plugname}-common>)
   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")
+#    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)
+  TARGET_LINK_LIBRARIES(${plugname} ${libs})
   
   # create tests
   PARSE_ARGUMENTS(PLUGIN "TESTLIBS" "" ${ARGN})
 
-  add_executable(test-${plugname} test_${name}.cc)
+  add_executable(test-${plugname} $<TARGET_OBJECTS:${plugname}-common> test_${name}.cc)
   IF(NOT WIN32)
     set_target_properties(test-${plugname} PROPERTIES 
       COMPILE_FLAGS -DVSTREAM_DOMAIN='"${plugname}"' 
@@ -202,7 +202,7 @@ MACRO(PLUGIN_WITH_TEST_MULTISOURCE name type data src libs)
     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} ${libs})
   target_link_libraries(test-${plugname} ${BOOST_UNITTEST} "${PLUGIN_TESTLIBS}")
   add_test(${plugname} test-${plugname})
   
diff --git a/config.h.cmake b/config.h.cmake
index 9470ce9..38d01bd 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -32,7 +32,7 @@
 #endif
 
 #cmakedefine HAVE_SYS_IOCTL_H 1
-
+#cmakedefine LIBXMLPP_VERSION @LIBXMLPP_VERSION@
 
 #cmakedefine HAVE_MAXFLOW 1
 
diff --git a/coverage.sh b/coverage.sh
new file mode 100755
index 0000000..17a9230
--- /dev/null
+++ b/coverage.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+make -j8 && make test
+
+if [ "x$?" = "x0" ]; then 
+
+    lcov --base-directory . --directory . -c -o mia.info
+
+    # remove system library files 
+    lcov --remove mia.info "/usr*" -o mia.info
+    lcov --remove mia.info "mia2/src*" -o mia.info
+
+    # generate the html report, note that genhtml may have some problems with a few files
+    # that will currently need to be removed manually
+    rm -rf test-coverage
+
+    genhtml -o test-coverage -t "Mia coverage" --num-spaces 2 mia.info
+else
+    echo build or test failed 
+fi
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 03b7091..2fa031b 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -36,12 +36,12 @@ SET(MIADOCTOOLS_PYTHON_EXE
   miaxml2sgml.py
   )
 
-INSTALL(FILES ${MIADOCTOOLS_FILES} DESTINATION ${MIA_DOCTOOLS_INSTALL_ROOT})
 
-INSTALL(PROGRAMS ${MIADOCTOOLS_PYTHON_EXE} DESTINATION ${MIA_DOCTOOLS_INSTALL_ROOT})
+IF(MIA_CREATE_USERDOC) 
 
-
-IF(CREATE_USERDOC) 
+  INSTALL(FILES ${MIADOCTOOLS_FILES} DESTINATION ${MIA_DOCTOOLS_INSTALL_ROOT})
+  
+  INSTALL(PROGRAMS ${MIADOCTOOLS_PYTHON_EXE} DESTINATION ${MIA_DOCTOOLS_INSTALL_ROOT})
 
   ##################################################################
   #  for html userref xsltproc and the style sheet is needed
@@ -107,7 +107,9 @@ IF(CREATE_USERDOC)
     ENDIF(ALWAYS_CREATE_DOC)     
   ENDIF(HTML_CHUNK_FILEPATH) 
   
-ENDIF(CREATE_USERDOC)
+ENDIF(MIA_CREATE_USERDOC)
+
+OPTION(DOXYGEN_USE_MATHJAX "Use mathjax for formulas in html documentation" ON)
 
 IF (DOXYGEN_FOUND)
   ADD_CUSTOM_TARGET(LibraryDoc echo "creating user library documentation")
@@ -116,6 +118,20 @@ IF (DOXYGEN_FOUND)
   IF(DOXYGEN_DOT_FOUND)
     SET(HAVE_DOT YES)
   ENDIF(DOXYGEN_DOT_FOUND)
+
+  IF(DOXYGEN_USE_MATHJAX)
+    SET(USE_MATHJAX YES)
+    FIND_PATH(MATHJAX_CODEFILE MathJax.js
+      PATHS
+      /usr/share/mathjax/
+      /usr/share/javascript/
+      /usr/share/javascript/mathjax/
+      )
+    IF(NOT MATHJAX_CODEFILE)
+      MESSAGE(STATUS "No mathjax installation found, Doxygen will create the documentation linking to the on-line version") 
+    ENDIF()
+  ENDIF()
+  
   CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/reference.dox.cmake 
     ${CMAKE_CURRENT_BINARY_DIR}/reference.dox)
   
diff --git a/doc/reference.dox.cmake b/doc/reference.dox.cmake
index a6ebad3..1dde5ec 100644
--- a/doc/reference.dox.cmake
+++ b/doc/reference.dox.cmake
@@ -143,7 +143,7 @@ INCLUDE_GRAPH          = YES
 INCLUDED_BY_GRAPH      = YES
 CALL_GRAPH             = NO
 GRAPHICAL_HIERARCHY    = YES
-DOT_IMAGE_FORMAT       = svg
+DOT_IMAGE_FORMAT       = svg 
 DOT_PATH               = 
 DOTFILE_DIRS           = 
 MAX_DOT_GRAPH_DEPTH    = 0
@@ -153,5 +153,5 @@ SEARCHENGINE           = NO
 SHOW_NAMESPACES        = NO
 DOT_GRAPH_MAX_NODES    = 100 
 HTML_TIMESTAMP         = NO
-
-
+USE_MATHJAX  = @USE_MATHJAX@
+MATHJAX_RELPATH = @MATHJAX_CODEFILE@
diff --git a/evaluate_coverage.sh b/evaluate_coverage.sh
new file mode 100644
index 0000000..337cdb3
--- /dev/null
+++ b/evaluate_coverage.sh
@@ -0,0 +1,28 @@
+#!/bin/sh 
+
+mkdir build-coverage
+cd build-coverage
+
+cmake -DALWAYS_CREATE_DOC=OFF -DSTRICT_DEPENDECIES=ON \
+      -DMIA_CREATE_MANPAGES=OFF -DMIA_CREATE_NIPYPE_INTERFACES=OFF \
+      -DENABLE_COVERAGE=ON -DDISABLE_PROGRAMS=ON -DUSE_MATHJAX=YES \
+      -G Ninja ..
+
+ninja
+
+lcov --base-directory . --directory . --zerocounters -q
+
+ninja test
+
+lcov --base-directory . --directory . -c -o mia.info
+
+# remove system library files 
+lcov --remove mia.info "/usr*" -o mia.info
+
+# generate the html report, note that genhtml may have some problems with a few files
+# that will currently need to be removed manually
+genhtml -o test-coverage -t "Mia coverage" --num-spaces 2 mia.info
+
+
+
+
diff --git a/examples/2d/filter/simple.cc b/examples/2d/filter/simple.cc
index f574787..5312fb1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 9e3e88f..fb8be0f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 a24937a..0157c57 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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
deleted file mode 100644
index 17cfd64..0000000
--- a/gsl++/CMakeLists.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
-#
-# 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(GSLPP_SOURCE 
-  matrix.cc
-  multimin.cc
-  vector.cc
-  wavelet.cc
-  )
-
-SET(GSLPP_HEADERS 
-  matrix.hh
-  multimin.hh
-  vector.hh
-  vector_template.hh
-  wavelet.hh
-  gsldefines.hh
-  )
-
-MIA_ADD_LIBRARY(miagsl "${GSLPP_SOURCE}" "${GSL_LIBRARIES}" "${BLAS_LIBRARIES}")
-
-INSTALL_WITH_EXPORT(miagsl)
-
-INSTALL(FILES ${GSLPP_HEADERS} DESTINATION "${INCLUDE_INSTALL_PATH}/gsl++")
-
-MACRO(GSL_TEST name)
-  ADD_EXECUTABLE(test-${name} test_${name}.cc)
-  TARGET_LINK_LIBRARIES(test-${name} miagsl ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
-  ADD_TEST(${name} test-${name})
-ENDMACRO(GSL_TEST name)
-
-IF(Boost_UNIT_TEST_FRAMEWORK_FOUND)
-  GSL_TEST(vector)
-  GSL_TEST(matrix)
-  GSL_TEST(multimin)
-ENDIF(Boost_UNIT_TEST_FRAMEWORK_FOUND)
-
-
diff --git a/gsl++/matrix.cc b/gsl++/matrix.cc
deleted file mode 100644
index 16c7c44..0000000
--- a/gsl++/matrix.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
- *
- * 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 <cassert>
-#include <gsl++/matrix.hh>
-
-namespace gsl {
-
-Matrix::Matrix():m_matrix(NULL)
-{
-}
-
-Matrix::Matrix(size_t rows, size_t columns, bool clean):
-	m_matrix(NULL)
-{
-	m_matrix = clean ? 
-		gsl_matrix_calloc(rows, columns):
-		gsl_matrix_alloc(rows, columns); 
-}
-
-Matrix::Matrix(const Matrix& other)
-{
-	m_matrix = gsl_matrix_alloc(other.rows(), other.cols()); 
-	gsl_matrix_memcpy (m_matrix, other.m_matrix); 
-}
-
-Matrix& Matrix::operator =(const Matrix& other)
-{
-	if (this == &other) 
-		return *this; 
-
-	if (m_matrix && rows() == other.rows() && cols() == other.cols()) {
-		gsl_matrix_memcpy (m_matrix, other.m_matrix);
-		return *this; 
-	}
-	gsl_matrix *help = gsl_matrix_alloc(other.rows(), other.cols()); 
-	gsl_matrix_memcpy (help, other.m_matrix); 
-	if (m_matrix) 
-		gsl_matrix_free(m_matrix);
-	m_matrix = help; 
-	return *this; 
-}
-
-Matrix::~Matrix()
-{
-	if (m_matrix) 
-		gsl_matrix_free(m_matrix);
-}
-
-size_t Matrix::rows()const
-{
-	assert(m_matrix); 
-	return m_matrix->size1; 
-}
-
-size_t Matrix::cols()const
-{
-	assert(m_matrix); 
-	return m_matrix->size2; 
-}
-
-
-void Matrix::set(size_t i, size_t j, double x)
-{
-	gsl_matrix_set(m_matrix, i,j,x); 
-}
-
-double Matrix::operator ()(size_t i, size_t j) const
-{
-	return gsl_matrix_get(m_matrix, i,j);
-}
-
-Matrix::operator gsl_matrix * ()
-{
-	return m_matrix; 
-}
-
-Matrix::operator const gsl_matrix *() const
-{
-	return m_matrix; 
-}
-
-}
-
-
diff --git a/gsl++/matrix.hh b/gsl++/matrix.hh
deleted file mode 100644
index affa811..0000000
--- a/gsl++/matrix.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-2015 Gert Wollny
- *
- * 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 GSLPP_MATRIX_HH
-#define GSLPP_MATRIX_HH
-
-
-#include <gsl/gsl_matrix.h>
-#include <gsl++/gsldefines.hh>
-
-namespace gsl {
-
-
-
-/**
-   This is a wrapper class around the GSL matrix type. It provides 
-   a compatibility to avoid handling de-alloction manually.
-*/
-class EXPORT_GSL Matrix {
-public: 
-	Matrix(); 
-
-	/**
-	   Create a matrix of size rows \f$\times\f$ columns, 
-	   \param rows
-	   \param columns 
-	   \param clean allocate zeroing out all elements 
-	 */
-	Matrix(size_t rows, size_t columns, bool clean); 
-
-	/**
-	   Copy constructor that executes a deep copy 
-	 */
-	Matrix(const Matrix& other); 
-
-
-	/**
-	   Copy operator that executes a deep copy 
-	 */
-	Matrix& operator =(const Matrix& other); 
-
-	~Matrix(); 
-
-	size_t rows()const; 
-	size_t cols()const; 
-	
-	void set(size_t i, size_t j, double x); 
-	double operator ()(size_t i, size_t j) const; 
-	
-	operator gsl_matrix *(); 
-	operator const gsl_matrix *() const; 
-
-private: 
-	gsl_matrix *m_matrix; 
-}; 
-
-} // end namespace 
-
-#endif
diff --git a/gsl++/test_matrix.cc b/gsl++/test_matrix.cc
deleted file mode 100644
index 6eec42e..0000000
--- a/gsl++/test_matrix.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
- *
- * 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 BOOST_TEST_DYN_LINK
-#define BOOST_TEST_DYN_LINK
-#endif
-
-#define BOOST_TEST_MAIN
-#define BOOST_TEST_ALTERNATIVE_INIT_API
-#include <boost/test/unit_test.hpp>
-#include <boost/test/floating_point_comparison.hpp>
-#include <gsl++/matrix.hh>
-
-using namespace gsl; 
-using namespace ::boost;
-using namespace ::boost::unit_test;
-
-
-
-BOOST_AUTO_TEST_CASE( test_matrix_alloc_and_free ) 
-{
-	Matrix m(2,3, true); 
-	BOOST_CHECK_EQUAL(m.rows(), 2u); 
-	BOOST_CHECK_EQUAL(m.cols(), 3u); 
-
-	for(size_t i = 0; i < 2;++i) 
-		for(size_t j = 0; j < 2;++j) 
-			BOOST_CHECK_EQUAL(m(i,j), 0.0); 
-
-	m.set(1,2, 1.0); 
-	BOOST_CHECK_EQUAL(m(1,2), 1.0); 
-	
-	Matrix k(m); 
-	BOOST_CHECK_EQUAL(k.rows(), 2u); 
-	BOOST_CHECK_EQUAL(k.cols(), 3u); 
-	BOOST_CHECK_EQUAL(k(1,2), 1.0); 
-
-	k.set(0,2, 2.0); 
-	BOOST_CHECK_EQUAL(k(0,2), 2.0); 
-
-	m = k; 
-	BOOST_CHECK_EQUAL(k(0,2), 2.0); 
-
-}
diff --git a/gsl++/vector.cc b/gsl++/vector.cc
deleted file mode 100644
index 83350f5..0000000
--- a/gsl++/vector.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
- *
- * 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 <gsl++/vector.hh>
-#include <gsl++/vector_template.cxx>
-#include <gsl++/gsldefines.hh>
-
-namespace gsl {
-
-	template class EXPORT_GSL TVector<double>; 
-	template class EXPORT_GSL TVector<float>; 
-	
-	template class EXPORT_GSL TVector<long>; 
-	template class EXPORT_GSL TVector<int>; 
-	template class EXPORT_GSL TVector<short>; 
-	template class EXPORT_GSL TVector<char>; 
-	
-	template class EXPORT_GSL TVector<ulong>; 
-	template class EXPORT_GSL TVector<uint>; 
-	template class EXPORT_GSL TVector<ushort>; 
-	template class EXPORT_GSL TVector<uchar>; 
-
-#ifdef NDEBUG 
-	class CTurnOffErrorHandler {
-	public: 
-		CTurnOffErrorHandler(); 
-	}; 
-
-
-	CTurnOffErrorHandler::CTurnOffErrorHandler() 
-	{
-		gsl_set_error_handler_off (); 
-	}
-		
-	const CTurnOffErrorHandler gsl_turn_off_error_handler; 		
-#endif 
-
-}
diff --git a/gsl++/vector_template.cxx b/gsl++/vector_template.cxx
deleted file mode 100644
index 756b2aa..0000000
--- a/gsl++/vector_template.cxx
+++ /dev/null
@@ -1,143 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
- *
- * 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 <cassert>
-#include <vector>
-
-namespace gsl {
-template <typename T> 
-TVector<T>::TVector():
-	data(NULL), 
-	cdata(NULL), 
-	owner(false)
-{
-}
-
-template <typename T> 
-TVector<T>::TVector(size_type n, bool clear):
-	owner(true)
-{
-	cdata = data = (vector_type*) (clear ? this->calloc (n) : this->alloc (n));  
-}
-	
-template <typename T> 
-TVector<T>::TVector(const TVector<T>& other):
-	owner(true)
-{
-	assert(other.data); 
-	
-	cdata = data = this->alloc(other.data->size); 
-	std::copy(other.begin(), other.end(), begin());
-}
-
-template <typename T> 
-TVector<T>& TVector<T>::operator = (const TVector<T>& other)
-{
-	if (&other != this) {
-		vector_type *d =  this->alloc(other.data->size); 
-		std::copy(other.begin(), other.end(), d->data);
-		if (owner)  
-			this->free(data); 
-		cdata = data = d; 
-		owner = true; 
-	}
-	return *this; 
-}
-
-template <typename T> 
-TVector<T>::TVector(vector_type *holder):
-	data(holder), 
-	cdata(holder),
-	owner(false)
-{
-}
-
-template <typename T> 
-TVector<T>::TVector(const vector_type *holder):
-	data(NULL), 
-	cdata(holder),
-	owner(false)
-{
-}
-
-template <typename T> 
-TVector<T>::~TVector()
-{
-	if (owner) 
-		this->free(data);
-}
-
-template <typename T> 
-TVector<T>::operator const typename TVector<T>::vector_type *() const
-{
-	return cdata; 
-}
-
-template <typename T> 
-TVector<T>::operator typename TVector<T>::vector_pointer_type ()
-{
-	return data; 
-}
-
-template <typename T> 
-typename TVector<T>::iterator TVector<T>::begin()
-{
-	assert(data); 
-	return data->data; 
-}
-
-template <typename T> 
-typename TVector<T>::iterator TVector<T>::end()
-{
-	assert(data); 
-	return data->data + data->size; 
-}
-
-
-template <typename T> 
-typename TVector<T>::const_iterator TVector<T>::begin()const
-{
-	assert(cdata); 
-	return cdata->data; 
-}
-
-
-template <typename T> 
-typename TVector<T>::const_iterator TVector<T>::end()const
-{
-	assert(cdata); 
-	return cdata->data + cdata->size; 
-}
-
-
-template <typename T> 
-const typename TVector<T>::value_type TVector<T>::operator[](size_t i)const
-{
-	assert(cdata); 
-	return this->get (cdata, i); 
-}
-
-template <typename T> 
-typename TVector<T>::size_type TVector<T>::size() const
-{
-	return this->cdata->size; 
-}
-
-}
diff --git a/gsl++/vector_template.hh b/gsl++/vector_template.hh
deleted file mode 100644
index 3b7a961..0000000
--- a/gsl++/vector_template.hh
+++ /dev/null
@@ -1,214 +0,0 @@
-/* -*- mia-c++  -*-
- *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
- *
- * 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 GSL_VECTOR_TEMPLATE
-#define GSL_VECTOR_TEMPLATE
-
-#include <gsl/gsl_vector.h>
-#include <cassert>
-
-namespace gsl {
-
-
-typedef unsigned long  ulong; 
-typedef unsigned short ushort; 
-typedef unsigned int   uint; 
-typedef unsigned char  uchar; 
-
-
-template <typename T> 
-struct gsl_vector_dispatch {
-	typedef void vector_type; 
-	typedef T value_type;
-	typedef T *iterator;	
-	typedef const T *const_iterator;
-	typedef size_t size_type;
-	typedef T& reference;
-	typedef const T& const_reference;
-
-protected: 
-	static vector_type *alloc(size_t n);
-	static vector_type *alloc_from(vector_type *other);
-	static vector_type *calloc(size_t n);
-	static void gsl_free(vector_type *v);
-	static value_type get(const vector_type *v, size_t i);
-}; 
-
-
-/* because of the C-nameing scheme we need specialications for ceach type */
-#define GSL_VECTOR_DISPATCH(TYPE)		 \
-	template <>						\
-	struct gsl_vector_dispatch<TYPE> {			\
-		typedef TYPE value_type;			\
-		typedef TYPE *iterator;				\
-		typedef const TYPE *const_iterator;		\
-		typedef size_t size_type;			\
-		typedef TYPE& reference;			\
-		typedef const TYPE& const_reference;		\
-								\
-		typedef gsl_vector_##TYPE vector_type;		\
-		typedef gsl_vector_##TYPE *vector_pointer_type; \
-	protected:							\
-	static vector_type *alloc(size_t n) {			\
-		return gsl_vector_##TYPE##_alloc(n);			\
-	}								\
-	static vector_type *calloc(size_t n) {			\
-		return gsl_vector_##TYPE##_calloc(n);			\
-	}								\
-	static vector_type *alloc_from(vector_type *other) {	\
-		return gsl_vector_##TYPE##_alloc_from_vector(other, 0,	\
-							     other->size, 1); \
-	}								\
-	static void free(vector_type *v) {				\
-		gsl_vector_##TYPE##_free(v);				\
-	}								\
-	static value_type get(const vector_type *v, size_t i) {		\
-		return gsl_vector_##TYPE##_get(v,i);			\
-	}								\
-	}; 
-	
-	GSL_VECTOR_DISPATCH(float); 
-	GSL_VECTOR_DISPATCH(long); 
-	GSL_VECTOR_DISPATCH(int); 
-	GSL_VECTOR_DISPATCH(short); 
-	GSL_VECTOR_DISPATCH(char); 
-	GSL_VECTOR_DISPATCH(ulong); 
-	GSL_VECTOR_DISPATCH(uint); 
-	GSL_VECTOR_DISPATCH(ushort); 
-	GSL_VECTOR_DISPATCH(uchar); 
-	
-	
-/* double is a special case named differently */	
-	template <>						
-	struct gsl_vector_dispatch<double> {	
-		
-		typedef double value_type;		
-		typedef double *iterator;			
-		typedef const double *const_iterator;	
-		typedef size_t size_type;		
-		typedef double& reference;		
-		typedef const double& const_reference;	
-		
-		typedef gsl_vector vector_type; 
-		typedef gsl_vector *vector_pointer_type; 
-		
-		protected:						
-		static vector_type *alloc(size_t n) {		
-			return gsl_vector_alloc(n);		
-		}							
-		static vector_type *calloc(size_t n) {		
-			return gsl_vector_calloc(n);		
-		}							
-		static vector_type *alloc_from(vector_type *other) { 
-			return gsl_vector_alloc_from_vector(other, 0, 
-							    other->size, 1); 
-		}							
-		static void free(vector_type *v) {			
-			gsl_vector_free(v);			
-		}							
-		static value_type get(const vector_type *v, size_t i)  { 
-			return gsl_vector_get(v,i);		
-		}							
-	}; 
-
-	/**
-	   This is a wrapper class around the GSL vector type. It provides 
-	   a compatibility layer to make it possible to use STL algorithms and constructs.
-	*/
-template <typename T> 
-class TVector : gsl_vector_dispatch<T> {
-public: 
-	typedef typename gsl_vector_dispatch<T>::iterator iterator; 
-	typedef typename gsl_vector_dispatch<T>::const_iterator const_iterator; 
-	typedef typename gsl_vector_dispatch<T>::size_type size_type; 
-	typedef typename gsl_vector_dispatch<T>::value_type value_type; 
-	typedef typename gsl_vector_dispatch<T>::vector_type vector_type; 
-	typedef typename gsl_vector_dispatch<T>::reference reference;
-	typedef typename gsl_vector_dispatch<T>::const_reference const_reference; 
-	typedef typename gsl_vector_dispatch<T>::vector_pointer_type vector_pointer_type; 
-	
-	/**
-	   Construct an empty vector without allocating the GSL data structures
-	 */
-	TVector();
-
-	/**
-	   Construct a vector of given size
-	   \param size 
-	   \param clear if set to \a true set all values to zero at allocation 
-	 */
-	TVector(size_type size, bool clear);
-
-	/**
-	   Wrap a pre-constructed GSL vector. The passed GSL-vector will not be destroyed 
-	   when the destructor is called. 
-	   The values of the GSL vector can be changed 
-	   \param holder the already allocated GSL vector 
-	   
-	*/
-	TVector(vector_type *holder); 
-	/**
-	   Wrap a pre-constructed GSL vector. The passed GSL-vector will not be destroyed 
-	   when the destructor is called. 
-	   The values of the GSL vector can \a not be changed 
-	   \param holder the already allocated GSL vector 
-	*/
-	TVector(const vector_type *holder); 
-
-	/**
-	   Copy constructor, does a deep copy of the internal data structures. 
-	 */
-	TVector(const TVector<T>& other); 
-
-	/**
-	   Copy operator, does a deep copy of the internal data structures. 
-	 */
-	TVector<T>& operator = (const TVector<T>& other); 
-
-	~TVector(); 
-	
-	iterator begin(); 
-	iterator end(); 
-
-	const_iterator begin()const; 
-	const_iterator end()const; 
-
-	size_type size() const; 
-
-	const value_type operator[](size_t i)const; 
-
-	reference operator[](size_t i){
-		assert(data); 
-		return data->data[i]; 
-	}
-
-	/// read only vector pointer type operator to enable transparent calls to the GSL APL
-	operator const vector_type *() const; 
-	
-	/// vector pointer type operator  to enable transparent calls to the GSL APL
-	operator vector_pointer_type (); 
-private: 
-	vector_type *data; 
-	const vector_type *cdata; 
-	bool owner; 
-}; 
-
-}
-#endif
diff --git a/mia.hh b/mia.hh
index 79d06b2..f777a80 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 fff3e33..4bad3d2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/CMakeLists.txt b/mia/2d/CMakeLists.txt
index 8e0c43a..a4d6198 100644
--- a/mia/2d/CMakeLists.txt
+++ b/mia/2d/CMakeLists.txt
@@ -29,7 +29,6 @@ SET(MIA2D_SRC_BASE
   image.cc
   imageio.cc
   interpolator.cc 
-  filterchain.cc
   fftkernel.cc
   fuzzyseg.cc
   fuzzyclustersolver_sor.cc
@@ -108,7 +107,6 @@ SET(MIA2D_HEADERS_BASE
   deformer.hh
   distance.hh
   fullcost.hh
-  filterchain.hh
   fftkernel.hh
   fuzzyseg.hh
   fuzzyclustersolver_sor.hh
diff --git a/mia/2d/angle.cc b/mia/2d/angle.cc
index 6c65a5d..75df7a4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2380c75..355561b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index e73e944..d8ee67c 100644
--- a/mia/2d/boundingbox.cc
+++ b/mia/2d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/boundingbox.hh
index 48d2b19..47daa8c 100644
--- a/mia/2d/boundingbox.hh
+++ b/mia/2d/boundingbox.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 785d23a..86aa726 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1cc11c4..7b831fd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4520fa1..7f68cd0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 07b307b..c674974 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9021497..ba2dc09 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 87c9eb4..05d9009 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 972180d..3e41e15 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/cost.hh
index 9aa6eb3..4ede905 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/gncc.cc b/mia/2d/cost/gncc.cc
index 0cb42e2..88757e0 100644
--- a/mia/2d/cost/gncc.cc
+++ b/mia/2d/cost/gncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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/2d/cost/gncc.hh>
+#include <mia/core/parallel.hh>
 
 namespace mia_2d_gncc {
           
@@ -35,7 +36,7 @@ CGNCC2DImageCost::CGNCC2DImageCost():
 
 class SumNccPart {
 	SumNccPart(const C2DFImage& mov, const C2DFImage& ref); 
-	NCCSums operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const; 
+	NCCSums operator ()(const C1DParallelRange& range, const NCCSums& sumacc) const; 
 private: 
 	const C2DFImage& m_mov; 
 	const C2DFImage& m_ref; 
@@ -48,7 +49,7 @@ SumNccPart::SumNccPart(const C2DFImage& mov, const C2DFImage& ref):
 }
 	
 	
-NCCSums SumNccPart::operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const
+NCCSums SumNccPart::operator ()(const C1DParallelRange& range, const NCCSums& sumacc) const
 {
 	for (auto y = range.begin(); y != range.end(); ++y) {
 		auto iref = m_ref.begin_at(0,y);
@@ -78,16 +79,16 @@ double CGNCC2DImageCost::do_value(const mia::C2DImage& a,
 
 	
 	NCCSums sum; 
-	sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), sum, sum_part_x, 
-			      [](const NCCSums& x, const NCCSums& y){
-				      return x + y;
-			      });
-
-
-	sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), sum, sum_part_y, 
-			      [](const NCCSums& x, const NCCSums& y){
-				      return x + y;
-			      });
+	sum = preduce(C1DParallelRange(0, mov.get_size().y, 1), sum, sum_part_x, 
+		      [](const NCCSums& x, const NCCSums& y){
+			      return x + y;
+		      });
+	
+	
+	sum = preduce(C1DParallelRange(0, mov.get_size().y, 1), sum, sum_part_y, 
+		      [](const NCCSums& x, const NCCSums& y){
+			      return x + y;
+		      });
 	
 	return sum.value(); 
 }       
@@ -109,18 +110,18 @@ double CGNCC2DImageCost::do_evaluate_force(const mia::C2DImage& a,
 
 	
 	NCCSums sum_x; 
-	sum_x = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), sum_x, sum_part_x, 
-			      [](const NCCSums& x, const NCCSums& y){
-				      return x + y;
-			      });
-
+	sum_x = preduce(C1DParallelRange(0, mov.get_size().y, 1), sum_x, sum_part_x, 
+			[](const NCCSums& x, const NCCSums& y){
+				return x + y;
+			});
+	
 
 	NCCSums sum_y; 
-	sum_y = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), sum_y, sum_part_y, 
-			      [](const NCCSums& x, const NCCSums& y){
-				      return x + y;
-				});
-
+	sum_y = preduce(C1DParallelRange(0, mov.get_size().y, 1), sum_y, sum_part_y, 
+			[](const NCCSums& x, const NCCSums& y){
+				return x + y;
+			});
+	
 	NCCSums sum = sum_x + sum_y; 
 	double retval = sum.value(); 
 	// from here on we evaluate the gradinet 
@@ -131,7 +132,7 @@ double CGNCC2DImageCost::do_evaluate_force(const mia::C2DImage& a,
 	auto ddx = get_gradient(nagx);
 	auto ddy = get_gradient(nagy); 
 
-	auto eval_force = [this, &x_grad_helper, &y_grad_helper, &nagx, & nagy, &ddx, &ddy, &force](const tbb::blocked_range<size_t>& range) -> void {
+	auto eval_force = [this, &x_grad_helper, &y_grad_helper, &nagx, & nagy, &ddx, &ddy, &force](const C1DParallelRange& range) -> void {
 		for (auto y = range.begin(); y != range.end(); ++y) {
 			int offs = nagx.get_size().x * y; 
 			for (auto x = 0; x < nagx.get_size().x; ++x, ++offs) {
@@ -142,7 +143,7 @@ double CGNCC2DImageCost::do_evaluate_force(const mia::C2DImage& a,
 		}
 	}
 
-	parallel_for(tbb::blocked_range<size_t>(0, a.get_size().y, 1), eval_force);
+	pfor(C1DParallelRange(0, a.get_size().y, 1), eval_force);
 
 	return retval; 
 }       
diff --git a/mia/2d/cost/gncc.hh b/mia/2d/cost/gncc.hh
index 4fe1aa9..8028edf 100644
--- a/mia/2d/cost/gncc.hh
+++ b/mia/2d/cost/gncc.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/lncc.cc b/mia/2d/cost/lncc.cc
index 3fd4d0c..5f90c1e 100644
--- a/mia/2d/cost/lncc.cc
+++ b/mia/2d/cost/lncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +22,7 @@
 
 #include <mia/core/threadedmsg.hh>
 #include <mia/core/nccsum.hh>
-#include <tbb/parallel_reduce.h>
-#include <tbb/blocked_range.h>
-
+#include <mia/core/parallel.hh>
 
 NS_BEGIN(NS)
 
@@ -64,7 +62,7 @@ public:
 	
 	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> {
+		auto evaluate_local_cost = [this, &mov, &ref](const C1DParallelRange& range, const pair<float, int>& result) -> pair<float, int> {
 			CThreadMsgStream msks; 
 			float lresult = 0.0; 
 			int count = 0; 
@@ -97,10 +95,10 @@ public:
 		};
 		
 		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);
-					 });	
+		auto r = preduce(C1DParallelRange(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; 
 	}
 }; 
@@ -125,7 +123,7 @@ public:
 	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, 
+		auto evaluate_local_cost_force = [this, &mov, &ref, &ag](const C1DParallelRange& range, 
 									 const pair<float, int>& result) -> pair<float, int> {
 			
 			CThreadMsgStream msks; 		
@@ -165,10 +163,10 @@ public:
 			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);
-					 });
+		auto r = preduce(C1DParallelRange(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; 
 	}
diff --git a/mia/2d/cost/lncc.hh b/mia/2d/cost/lncc.hh
index c21346d..7a7f026 100644
--- a/mia/2d/cost/lncc.hh
+++ b/mia/2d/cost/lncc.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/2d/cost/lsd.cc
index dd2d044..0aee76a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8cbbaaa..a25d9a6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8862a4a..29f1f95 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3f8cefd..7ee95a0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index f3edbbc..f9f7332 100644
--- a/mia/2d/cost/ncc.cc
+++ b/mia/2d/cost/ncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 +22,7 @@
 
 #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>
-
+#include <mia/core/parallel.hh>
 
 NS_BEGIN(NS)
 
@@ -39,7 +36,7 @@ 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; 
+	NCCSums operator ()(const C1DParallelRange& range, const NCCSums& sumacc) const; 
 private: 
 	T m_mov; 
 	S m_ref; 
@@ -54,7 +51,7 @@ FEvaluateNCCSum<T,S>::FEvaluateNCCSum(const T& mov, const S& ref):
 }
 
 template <typename T, typename S> 
-NCCSums FEvaluateNCCSum<T,S>::operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const
+NCCSums FEvaluateNCCSum<T,S>::operator ()(const C1DParallelRange& range, const NCCSums& sumacc) const
 {
 	CThreadMsgStream msks; 
 	
@@ -80,7 +77,7 @@ public:
 
 		FEvaluateNCCSum<T,R> ev(mov, ref); 
 		NCCSums sum; 
-		sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), sum, ev, 
+		sum = preduce(C1DParallelRange(0, mov.get_size().y, 1), sum, ev, 
 				      [](const NCCSums& x, const NCCSums& y){
 					      return x + y;
 				      });
@@ -109,7 +106,7 @@ public:
 		
 		NCCSums sum; 
 		FEvaluateNCCSum<T,R> ev(mov, ref); 
-		sum = parallel_reduce(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), sum, ev, 
+		sum = preduce(C1DParallelRange(0, mov.get_size().y, 1), sum, ev, 
 					 [](const NCCSums& x, const NCCSums& y){
 					      return x + y;
 				      });
@@ -117,7 +114,7 @@ public:
 		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) {
+		auto grad_eval = [this, &mov, &ref, &grad, &geval](const C1DParallelRange& 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); 
@@ -134,7 +131,7 @@ public:
 			}; 
 		}; 
 		
-		parallel_for(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), grad_eval); 
+		pfor(C1DParallelRange(0, mov.get_size().y, 1), grad_eval); 
 
 		return geval.first; 
 	}
diff --git a/mia/2d/cost/ncc.hh b/mia/2d/cost/ncc.hh
index 4a435a1..17f8389 100644
--- a/mia/2d/cost/ncc.hh
+++ b/mia/2d/cost/ncc.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ngf.cc b/mia/2d/cost/ngf.cc
index 98c1a35..a2797ea 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ngf.hh b/mia/2d/cost/ngf.hh
index 6a8c7cb..cb8ca1b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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-automask.cc b/mia/2d/cost/ssd-automask.cc
index 8950607..45999c5 100644
--- a/mia/2d/cost/ssd-automask.cc
+++ b/mia/2d/cost/ssd-automask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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-automask.hh b/mia/2d/cost/ssd-automask.hh
index 82fe637..2dd1ccd 100644
--- a/mia/2d/cost/ssd-automask.hh
+++ b/mia/2d/cost/ssd-automask.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/2d/cost/ssd.cc
index 78feec2..6f59f10 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 caf4468..e23ba43 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 bcfa27d..e362983 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 eb8baf5..13cac5d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a942ed9..406fd12 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6d7ad82..01f3847 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_gncc.cc b/mia/2d/cost/test_gncc.cc
index 6ab0448..7594cf1 100644
--- a/mia/2d/cost/test_gncc.cc
+++ b/mia/2d/cost/test_gncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 8143ae1..c14fe16 100644
--- a/mia/2d/cost/test_lncc.cc
+++ b/mia/2d/cost/test_lncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_lsd.cc b/mia/2d/cost/test_lsd.cc
index f184ce0..3243ba9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 cf553b1..0d8e64a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ncc.cc b/mia/2d/cost/test_ncc.cc
index f475d63..ab09122 100644
--- a/mia/2d/cost/test_ncc.cc
+++ b/mia/2d/cost/test_ncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ngf.cc b/mia/2d/cost/test_ngf.cc
index 87a78f6..0d4c760 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -156,7 +156,6 @@ BOOST_AUTO_TEST_CASE( test_fatngf_2d )
 
 
 	PEvaluator eval(new CCostEvaluatorTest());
-	P2DInterpolatorFactory ipf(create_2dinterpolation_factory(ip_bspline3, bc_mirror_on_bounds));
 
 	C2DNFGImageCost cost(eval);
 	double test_cost = 0.5 * weight * 18 * 36 / 200.0;
diff --git a/mia/2d/cost/test_ssd-automask.cc b/mia/2d/cost/test_ssd-automask.cc
index 367ca88..4554fcc 100644
--- a/mia/2d/cost/test_ssd-automask.cc
+++ b/mia/2d/cost/test_ssd-automask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ssd.cc b/mia/2d/cost/test_ssd.cc
index caf602e..7e075d9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ssd2.cc b/mia/2d/cost/test_ssd2.cc
index 3d2d21b..83d8a56 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4ac1972..c08dc3b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4ae1e30..ed0cb28 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 107b48f..38f00ca 100644
--- a/mia/2d/creator/CMakeLists.txt
+++ b/mia/2d/creator/CMakeLists.txt
@@ -20,8 +20,8 @@ SET(creator2d
 	    circle
 )
 
-PLUGINGROUP_WITH_PREFIX2(
+PLUGINGROUP_WITH_TEST_AND_PREFIX2(
   "2dimage" "creator"
   "${creator2d}" 
-  "${MIA2DLIBS}" 
+  "${MIA2DLIBS}"
 )
diff --git a/mia/2d/creator/circle.cc b/mia/2d/creator/circle.cc
index a5c262b..07773ce 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,23 +24,12 @@
 
 #include <limits>
 #include <cmath>
-#include <mia/2d/creator.hh>
+#include <mia/2d/creator/circle.hh>
 
 NS_BEGIN(creator_circle_2d);
 using namespace mia;
 using namespace std;
 
-class C2DCircleCreator	: public C2DImageCreator {
-public:
-	C2DCircleCreator(float f, float p);
-	virtual P2DImage operator () (const C2DBounds& size, EPixelType type) const;
-private:
-	template <typename T>
- 	P2DImage do_create(const C2DBounds& size) const;
-	float m_f;
-	double m_p;
-};
-
 C2DCircleCreator::C2DCircleCreator(float f, float p):
 	m_f(f),
 	m_p(p)
@@ -115,15 +104,6 @@ P2DImage C2DCircleCreator::do_create(const C2DBounds& size) const
 }
 
 
-class C2DCircleCreatorPlugin : public  C2DImageCreatorPlugin {
-public:
-	C2DCircleCreatorPlugin();
-private:
-	virtual C2DImageCreator *do_create()const;
-	virtual const string do_get_descr()const;
-	float m_f;
-	float m_p;
-};
 
 C2DCircleCreatorPlugin::C2DCircleCreatorPlugin():
 	C2DImageCreatorPlugin("circle"),
diff --git a/mia/3d/creator/sphere.hh b/mia/2d/creator/circle.hh
similarity index 57%
copy from mia/3d/creator/sphere.hh
copy to mia/2d/creator/circle.hh
index 255e754..8766947 100644
--- a/mia/3d/creator/sphere.hh
+++ b/mia/2d/creator/circle.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,35 @@
  *
  */
 
-#include <mia/3d/creator.hh>
+#ifdef _MSC_VER
+#define _USE_MATH_DEFINES
+#endif
 
-NS_BEGIN(creator_sphere_3d);
+#include <limits>
+#include <cmath>
+#include <mia/2d/creator.hh>
 
-class C3DSphereCreator	: public mia::C3DImageCreator {
+NS_BEGIN(creator_circle_2d);
+using namespace mia;
+using namespace std;
+
+class C2DCircleCreator	: public C2DImageCreator {
 public:
-	C3DSphereCreator(float f, float p);
-	virtual mia::P3DImage operator () (const mia::C3DBounds& size, mia::EPixelType type) const;
+	C2DCircleCreator(float f, float p);
+	virtual P2DImage operator () (const C2DBounds& size, EPixelType type) const;
 private:
 	template <typename T>
- 	mia::P3DImage do_create(const mia::C3DBounds& size) const;
+ 	P2DImage do_create(const C2DBounds& size) const;
 	float m_f;
 	double m_p;
 };
 
-
-class C3DSphereCreatorPlugin : public  mia::C3DImageCreatorPlugin {
+class C2DCircleCreatorPlugin : public  C2DImageCreatorPlugin {
 public:
-	C3DSphereCreatorPlugin();
+	C2DCircleCreatorPlugin();
 private:
-	virtual mia::C3DImageCreator *do_create()const;
-	virtual const std::string do_get_descr()const;
+	virtual C2DImageCreator *do_create()const;
+	virtual const string do_get_descr()const;
 	float m_f;
 	float m_p;
 };
diff --git a/mia/2d/creator/test_circle.cc b/mia/2d/creator/test_circle.cc
new file mode 100644
index 0000000..8291d33
--- /dev/null
+++ b/mia/2d/creator/test_circle.cc
@@ -0,0 +1,120 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 <boost/mpl/vector.hpp>
+#include <boost/test/test_case_template.hpp>
+
+#include <mia/2d/creator/circle.hh>
+
+using namespace mia;
+using namespace creator_circle_2d;
+
+
+typedef boost::mpl::vector<bool,
+                           signed char,
+                           unsigned char,
+                           signed short,
+                           unsigned short,
+                           signed int,
+                           unsigned int,
+                           double
+#ifdef HAVE_INT64
+                           mia_int64,
+                           mia_uint64,
+#endif
+                           > type_list;
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE( test_circle_create, T , type_list )
+{
+        auto ccreator = BOOST_TEST_create_from_plugin<C2DCircleCreatorPlugin>("circle:f=2,p=3");
+        
+        C2DBounds size(16,16); 
+        P2DImage image = (*ccreator)(size, pixel_type<T>::value);
+        
+        const T2DImage<T>& cc = dynamic_cast<const T2DImage<T>&>(*image); 
+        
+        BOOST_CHECK_EQUAL(cc.get_size(), size);
+}
+
+/// test the pattern only once, for the float case
+BOOST_AUTO_TEST_CASE( test_circle_create_float )
+{
+        auto ccreator = BOOST_TEST_create_from_plugin<C2DCircleCreatorPlugin>("circle:f=2,p=3");
+	
+        C2DBounds size(16,16); 
+        P2DImage image = (*ccreator)(size, it_float);
+	
+        const C2DFImage& cc = dynamic_cast<const C2DFImage&>(*image); 
+
+        BOOST_CHECK_EQUAL(cc.get_size(), size);
+
+	vector<float> result= {
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0, 
+		0, 0, 0, 0, 0, 0, 0, 0.995185,
+		0.989177, 0.995185, 0, 0, 0, 0, 0, 0, 
+		0, 0, 0, 0, 1, -0.24298, -0.92388, -0.998795,
+		-1, -0.998795, -0.92388, -0.24298, 1, 0, 0, 0, 
+		0, 0, 0, 0, -0.24298, -0.881921, -0.14673, 0.19509,
+		0.24298, 0.19509, -0.14673, -0.881921, -0.24298, 0, 0, 0, 
+		0, 0, 0, 0, -0.92388, -0.14673, 0.707107, 0.903989,
+		0.92388, 0.903989, 0.707107, -0.14673, -0.92388, 0, 0, 0, 
+		0, 0, 0, 0.995185, -0.998795, 0.19509, 0.903989,
+		0.995185, 0.998795, 0.995185, 0.903989, 0.19509, -0.998795, 0.995185, 0, 0, 
+		0, 0, 0, 0.989177, -1, 0.24298, 0.92388, 0.998795,
+		1, 0.998795, 0.92388, 0.24298, -1, 0.989177, 0, 0, 
+		0, 0, 0, 0.995185, -0.998795, 0.19509, 0.903989, 0.995185,
+		0.998795, 0.995185, 0.903989, 0.19509, -0.998795, 0.995185, 0, 0, 
+		0, 0, 0, 0, -0.92388, -0.14673, 0.707107, 0.903989, 0.92388,
+		0.903989, 0.707107, -0.14673, -0.92388, 0, 0, 0, 
+		0, 0, 0, 0, -0.24298, -0.881921, -0.14673, 0.19509, 0.24298,
+		0.19509, -0.14673, -0.881921, -0.24298, 0, 0, 0, 
+		0, 0, 0, 0, 1, -0.24298, -0.92388, -0.998795, -1,
+		-0.998795, -0.92388, -0.24298, 1, 0, 0, 0, 
+		0, 0, 0, 0, 0, 0, 0, 0.995185, 0.989177,
+		0.995185, 0, 0, 0, 0, 0, 0, 
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	}; 
+
+	auto ic = cc.begin();
+	auto ec = cc.end();
+	auto ir = result.begin();
+
+	while (ic != ec) {
+
+		if (fabs(*ir) > 1e-5)
+			BOOST_CHECK_CLOSE(*ic, *ir, 0.1);
+		else
+			BOOST_CHECK_SMALL(*ic, 1e-5f);
+		
+		++ic; ++ir; 
+	}; 
+}
+
+
+
diff --git a/mia/2d/cstkernel.cc b/mia/2d/cstkernel.cc
index 652663b..42f0316 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/cstkernel.hh
index 2bf5e0f..c8994f8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/datafield.cc b/mia/2d/datafield.cc
index 0cd8344..adc2128 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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_BEGIN
 
 #define INSTANCIATE(TYPE) \
-	template class  EXPORT_2D T2DDatafield<TYPE>;			\
+	template class EXPORT_2D 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_with_boundary_flag<T2DDatafield<TYPE>::iterator>; \
@@ -46,17 +46,18 @@ INSTANCIATE(unsigned int);
 INSTANCIATE(signed int);
 INSTANCIATE(unsigned short);
 INSTANCIATE(signed short);
-INSTANCIATE(bool);
 INSTANCIATE(unsigned char);
 INSTANCIATE(signed char);
+template class  EXPORT_2D T2DDatafield<bool>;
 
 DEFINE_TYPE_DESCR2(C2DBounds, "2dbounds"); 
 DEFINE_TYPE_DESCR2(C2DFVector, "2dfvector"); 
 
 
-template class EXPORT_2D  CTParameter<C2DFVector>;
-template class EXPORT_2D  CTParameter<C2DBounds>;
-template class EXPORT_2D  TTranslator<C2DFVector>; 
+template class EXPORT_2D CTParameter<C2DFVector>;
+template class EXPORT_2D CTParameter<C2DBounds>;
+template class EXPORT_2D TTranslator<C2DFVector>; 
+template class EXPORT_2D TAttribute<C2DFVector>; 
 
 NS_MIA_END
 
diff --git a/mia/2d/datafield.cxx b/mia/2d/datafield.cxx
index ebdde2a..0a70fe0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +55,9 @@ T2DDatafield<T>::T2DDatafield(const C2DBounds& size,const T *_data):
 }
 
 template <class T> 
-T2DDatafield<T>::T2DDatafield(const C2DBounds& size, const data_array& data):
+T2DDatafield<T>::T2DDatafield(const C2DBounds& size, const std::vector<T>& data):
 	m_size(size),
-	m_data(new data_array(data))
+	m_data(new data_array(data.begin(), data.end()))
 {
 	assert(m_data->size() == m_size.x * m_size.y); 
 }
@@ -274,7 +274,7 @@ T2DDatafield<T>::end_range(const C2DBounds& begin, const C2DBounds& end)const
 
 
 template <class T> 
-const T T2DDatafield<T>::Zero = T();
+const typename  T2DDatafield<T>::value_type T2DDatafield<T>::Zero = T();
 
 NS_MIA_END
 
diff --git a/mia/2d/datafield.hh b/mia/2d/datafield.hh
index 80e0cd7..ede6ee4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +55,7 @@ class EXPORT_2DDATAFIELD T2DDatafield  {
 public:
 
 	/// type for the flat reprentation of the 2D data field 
-	typedef  ::std::vector<T> data_array;
+	typedef  ::std::vector<typename __holder_type_dispatch<T>::type> data_array;
 
 	/// pointer type 
 	typedef  std::shared_ptr<data_array > data_pointer;
@@ -101,7 +101,7 @@ public:
 	   \param size 
 	   \param data must at least be of size (size.x*size.y)
 	*/
-	T2DDatafield(const C2DBounds& size, const data_array& data);
+	T2DDatafield(const C2DBounds& size, const std::vector<T>& data);
 
 	/** copy constructor, it does a shallow copy of the original, i.e. 
 	    the data is not copied, only the shared pointer increases its reference count.
@@ -292,7 +292,7 @@ public:
 private:
 	C2DBounds  m_size;
 	data_pointer m_data;
-	const static T Zero;
+	const static value_type Zero;
 };
 
 /// 2D scalar field that holds double values 
@@ -340,9 +340,36 @@ typedef TTranslator<C2DFVector> C2DFVectorTranslator;
 
 /// @cond NEVER 
 
+#define DEFINE_2DFIELD_TEMPLATE(TYPE) \
+	extern template class EXPORT_2D EXPORT_2D T2DDatafield<TYPE>;			\
+	extern template class  EXPORT_2D range2d_iterator<T2DDatafield<TYPE>::iterator>; \
+	extern template class  EXPORT_2D range2d_iterator<T2DDatafield<TYPE>::const_iterator>; \
+	extern template class  EXPORT_2D range2d_iterator_with_boundary_flag<T2DDatafield<TYPE>::iterator>; \
+	extern template class  EXPORT_2D range2d_iterator_with_boundary_flag<T2DDatafield<TYPE>::const_iterator>;
+
+DEFINE_2DFIELD_TEMPLATE(float); 
+
+#ifdef LONG_64BIT
+DEFINE_2DFIELD_TEMPLATE(signed long);
+DEFINE_2DFIELD_TEMPLATE(unsigned long);
+#endif
+DEFINE_2DFIELD_TEMPLATE(double);
+DEFINE_2DFIELD_TEMPLATE(unsigned int);
+DEFINE_2DFIELD_TEMPLATE(signed int);
+DEFINE_2DFIELD_TEMPLATE(unsigned short);
+DEFINE_2DFIELD_TEMPLATE(signed short);
+DEFINE_2DFIELD_TEMPLATE(unsigned char);
+DEFINE_2DFIELD_TEMPLATE(signed char);
+
 
 DECLARE_TYPE_DESCR(C2DBounds);
-DECLARE_TYPE_DESCR(C2DFVector); 
+DECLARE_TYPE_DESCR(C2DFVector);
+
+extern template class EXPORT_2D CTParameter<C2DFVector>;
+extern template class EXPORT_2D CTParameter<C2DBounds>;
+extern template class EXPORT_2D TTranslator<C2DFVector>; 
+extern template class EXPORT_2D TAttribute<C2DFVector>; 
+
 /// @endcond
 
 NS_MIA_END
diff --git a/mia/2d/defines2d.hh b/mia/2d/defines2d.hh
index 49d2444..28dcfdf 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,22 @@
 #  endif
 #endif
 
+#ifdef WIN32
+#  ifdef mia2dmyocardperf_EXPORTS
+#    define EXPORT_2D __declspec(dllexport) 
+#  else
+#    define EXPORT_2D __declspec(dllimport) 
+#  endif
+#else
+#  ifdef __GNUC__
+#    define EXPORT_2DMYOCARD __attribute__((visibility("default")))
+#  else
+#    define EXPORT_2D 
+#  endif
+#endif
+
+
+
 #ifdef mia2d_EXPORTS
 #  ifdef VSTREAM 
 #    undef VSTREAM  
diff --git a/mia/2d/deformer.hh b/mia/2d/deformer.hh
index 607ae17..e5e5ac9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 79394a0..f15d828 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e80ada5..e655964 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b9568e1..3d91e45 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6c619cd..33e86c0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 50433fa..529f885 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 cfc0b3c..ecb3692 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/filter.hh
index c030c51..687aa1f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/CMakeLists.txt b/mia/2d/filter/CMakeLists.txt
index 9ed3278..ab5f72f 100644
--- a/mia/2d/filter/CMakeLists.txt
+++ b/mia/2d/filter/CMakeLists.txt
@@ -53,8 +53,10 @@ SET(filters2dNew_base
   labelscale
   load
   mask
-  mean 
+  mean
+  meanvar 
   median
+  medianmad
   mlv
   morphological
   ngfnorm
@@ -69,6 +71,7 @@ SET(filters2dNew_base
   tee
   thinning 
   thresh
+  tmean
   transform
   watershed
 )
diff --git a/mia/2d/filter/adaptmed.cc b/mia/2d/filter/adaptmed.cc
index f39d924..d8c40e6 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-2015 Gert Wollny
+ * This file is part of MIA - a toolbox for medical image analysis
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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/2d/filter/adaptmed.hh>
 
-
 NS_BEGIN(adaptmed_2dimage_filter)
 
 NS_MIA_USE;
diff --git a/mia/2d/filter/adaptmed.hh b/mia/2d/filter/adaptmed.hh
index 0c38630..cce72a8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3f76ed4..8e6df74 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b205561..45adad0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 261408b..03c224c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6b5e8e4..a898f20 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 fcd972d..b2e1651 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 773f80e..1fd3728 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5a7d43f..1f9dfa4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9f3103c..e2427a2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 53b0f28..fd7467e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index e6eef98..8da113a 100644
--- a/mia/2d/filter/combiner.cc
+++ b/mia/2d/filter/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/filter/combiner.hh
index ad97a6e..b5c8391 100644
--- a/mia/2d/filter/combiner.hh
+++ b/mia/2d/filter/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/2d/filter/convert.cc
index 4b3c124..4f032c7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f19a6aa..f09c239 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9cd81b0..ff0ece2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 380ac05..e3d1029 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9b0999c..bf2d28f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f4c39c8..6e8b336 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3f134d5..4d659e6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e914155..4bd9c23 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 323cf09..d697053 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/filter/downscale.hh
index 4100e8a..f9b45ec 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 088c4f2..b6d3e2d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 896246d..b70a062 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ea91354..d939ad8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b3f777b..001833e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e6ffec9..c054af8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0c67bc0..a028843 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4201691..f513779 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 50e6421..1ab2339 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 56861de..00c92a2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 eb6dedf..3e96e38 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f8d6afe..85acf50 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9b9960e..3e84cfa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0074b6c..8e720df 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9b4494c..bdb9538 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 98ccce5..f8e0e9d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/filter/labelmap.hh
index 68aca75..6ea7f04 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/labelscale.cc b/mia/2d/filter/labelscale.cc
index af51ebe..2573bb9 100644
--- a/mia/2d/filter/labelscale.cc
+++ b/mia/2d/filter/labelscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/labelscale.hh b/mia/2d/filter/labelscale.hh
index 29db0b6..c1d3c7a 100644
--- a/mia/2d/filter/labelscale.hh
+++ b/mia/2d/filter/labelscale.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ffdff9c..d6fd61d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0c0f3de..197456c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/filter/load.hh
index 661510a..55d4fa4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 751fba2..1d152a8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/filter/mask.hh
index 0165b70..028dea1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3840668..f83aba1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 @@
 #include <mia/2d/filter/mean.hh>
 #include <boost/type_traits/is_floating_point.hpp>
 
+#include <mia/core/parallel.hh>
+
 NS_BEGIN(mean_2dimage_filter)
 NS_MIA_USE;
 using namespace std;
@@ -37,12 +39,6 @@ struct __dispatch_filter {
 	static T apply(const T2DImage<T>& data, int cx, int cy, int hw) {
 		double result = 0.0; 
 		int n = 0;
-		// 
-		// Coverty complains about this: 1128688, 1128687 
-		// 
-		// hw >= 0, cy >= 0 && cy < data.get_size().y
-		// therefore n>=1 
-		// 
 		for (int y = cy - hw; y <= cy + hw; ++y) {
 			if ( y >= 0 && y < (int)data.get_size().y) 
 				for (int x = cx - hw; x <= cx + hw; ++x) {
@@ -52,6 +48,10 @@ struct __dispatch_filter {
 					}
 				}
 		}
+		
+		// hw >= 0, cy >= 0 && cy < data.get_size().y
+		// therefore n >=1, hence the override 
+		// coverity[divide_by_zero] 
 		return static_cast<T>(rint(result/n)); 
 	}
 }; 
@@ -61,9 +61,7 @@ struct __dispatch_filter<T, true> {
 	static T apply(const T2DImage<T>& data, int cx, int cy, int  hw) {
 		double result = 0.0; 
 		int n = 0; 
-		// 
-		// see above. Coverty  1128688, 1128687
-		// 
+		
 		for (int y = cy - hw; y <= cy + hw; ++y) {
 			if ( y >= 0 && y < (int)data.get_size().y) 
 				for (int x = cx - hw; x <= cx + hw; ++x) {
@@ -73,6 +71,10 @@ struct __dispatch_filter<T, true> {
 					}
 				}
 		}
+		
+		// hw >= 0, cy >= 0 && cy < data.get_size().y
+		// therefore n >=1, hence the override 
+		// coverity[divide_by_zero] 
 		return static_cast<T>(result/n); 
 	}
 }; 
@@ -87,7 +89,10 @@ struct __dispatch_filter<bool, false> {
 			if ( y >= 0 && y < (int)data.get_size().y) 
 				for (int x = cx - hw; x <= cx + hw; ++x) {
 					if ( x >= 0 && x < (int)data.get_size().x) {
-						balance += data(x,y) ? 1 : -1; 
+						if (data(x,y))
+							++balance;
+						else
+							--balance; 
 					}
 				}
 		}
@@ -106,12 +111,17 @@ C2DMean::result_type C2DMean::operator () (const T2DImage<T>& data) const
 	T2DImage<T> *tresult = new T2DImage<T>(data.get_size(), data);
 	P2DImage result(tresult);
 
-	typename T2DImage<T>::iterator i = tresult->begin();
-
-	for (size_t y = 0; y < data.get_size().y; ++y)
-		for (size_t x = 0; x < data.get_size().x; ++x, ++i)
-			*i = __dispatch_filter<T, is_floating_point>::apply(data, x, y, m_hw);
 
+	int hw = m_hw; 
+        auto run_line  = [hw, data, tresult](const C1DParallelRange& range) {
+		for (auto y = range.begin(); y !=  range.end(); ++y) {
+			typename T2DImage<T>::iterator i = tresult->begin_at(0, y);
+			for (size_t x = 0; x < data.get_size().x; ++x, ++i)
+				*i = __dispatch_filter<T, is_floating_point>::apply(data, x, y, hw);
+		}
+	};
+	pfor(C1DParallelRange(0, data.get_size().y, 1), run_line);
+	
 	return result;
 }
 
diff --git a/mia/2d/filter/mean.hh b/mia/2d/filter/mean.hh
index 1e94c7b..69c1fab 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/meanvar.cc b/mia/2d/filter/meanvar.cc
new file mode 100644
index 0000000..f2055fd
--- /dev/null
+++ b/mia/2d/filter/meanvar.cc
@@ -0,0 +1,175 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/threadedmsg.hh>
+#include <mia/core/parallel.hh>
+
+#include <mia/2d/filter/meanvar.hh>
+#include <mia/2d/imageio.hh>
+
+#include <limits>
+
+#include <gsl/gsl_cblas.h>
+
+NS_BEGIN(meanvar_2dimage_filter);
+
+NS_MIA_USE;
+using namespace std;
+
+C2DMeanVar::C2DMeanVar(unsigned hw, double thresh, const std::string& varfilename):
+	m_hw(hw),
+	m_thresh(thresh),
+	m_varfilename(varfilename)
+{
+}
+
+template <typename T>
+std::pair<double, double> evaluate_pixel(const T2DImage<T>& data, unsigned x, unsigned y, unsigned hw, double thresh)
+{
+	unsigned startx = x - hw;
+	if (startx > data.get_size().x)
+		startx = 0;
+
+	unsigned endx = x + hw + 1;
+	if (endx > data.get_size().x)
+		endx = data.get_size().x;
+
+	unsigned starty = y - hw;
+	if (starty > data.get_size().y)
+		starty = 0;
+
+	unsigned endy = y + hw + 1;
+	if (endy > data.get_size().y)
+		endy = data.get_size().y;
+
+
+	std::pair<double, double> result = {0.0f, 0.0f};
+
+	float orig_value = data(x,y);
+	
+	if (orig_value >=  thresh) {
+		double sum = 0.0f;
+		double sum2 = 0.0f;
+		unsigned n = 0; 
+		
+		for (unsigned iy = starty; iy < endy; ++iy) {
+			for (unsigned ix = startx; ix < endx; ++ix) {
+				double v = data(ix, iy);
+				if (v >= thresh) {
+					sum += v;
+					sum2 += v*v;
+					++n;
+				}
+			}
+		}
+		if (n > 1) {
+			result.first = sum / n;
+			result.second = sqrt((sum2 - sum * result.first) / (n - 1));
+		}else{
+			result.first = orig_value; 
+		}
+	}
+	return result; 
+}
+
+template <typename T>
+C2DMeanVar::result_type C2DMeanVar::operator () (const T2DImage<T>& data) const
+{
+	TRACE_FUNCTION;
+
+	cvdebug() << "Running 2D meanvar with hw=" << m_hw
+		  << ", thresh=" << m_thresh
+		  << ", and varfile=" << m_varfilename
+		  << "\n";
+
+	C2DFImage *result_mu = new C2DFImage(data.get_size(), data);
+	C2DFImage *result_sigma = new C2DFImage(data.get_size(), data);
+
+	P2DImage presult_sigma(result_sigma);
+	
+	auto evaluate_row = [&](const C1DParallelRange& range){
+		for (int y = range.begin(); y != range.end(); ++y){
+			auto omu = result_mu->begin_at(0,y);
+			auto osigma = result_sigma->begin_at(0,y);
+			for (unsigned x = 0; x < data.get_size().x; ++x, ++omu, ++osigma){
+				auto r = evaluate_pixel(data, x, y, m_hw, m_thresh);
+				*omu = r.first;
+				*osigma = r.second; 
+			}
+		}
+	};
+
+	pfor(C1DParallelRange(0, data.get_size().y, 1), evaluate_row);
+	
+	if (!m_varfilename.empty()) {
+		if (!save_image(m_varfilename, presult_sigma)) {
+			cverr() << "C2DMeanVar: Unable to save variation data to '" << m_varfilename <<"'"; 
+		}
+	
+	}
+	return P2DImage(result_mu);
+}
+
+P2DImage C2DMeanVar::do_filter(const C2DImage& image) const
+{
+	return mia::filter(*this, image);
+}
+
+C2DMeanVarImageFilterFactory::C2DMeanVarImageFilterFactory():
+	C2DFilterPlugin("meanvar"),
+	m_hw(1),
+	m_thresh(0.0)
+{
+	add_parameter("w", make_lc_param(m_hw, 1, false, "filter width parameter"));
+	add_parameter("thresh", make_lc_param(m_thresh, 0.0, false, "Intensity threshholding parameter: Pixels with intensities "
+					      "below this threshhold will be set to zero, and also not used when evaluating mean "
+					      "and variation"));
+	add_parameter("varfile", new CStringParameter(m_varfilename, CCmdOptionFlags::required_output,
+						      "name of the output file to save the variation image too.", 
+						      &C2DImageIOPluginHandler::instance()));
+}
+
+C2DFilter *C2DMeanVarImageFilterFactory::do_create()const
+{
+	return new C2DMeanVar(m_hw, m_thresh, m_varfilename);
+}
+
+const string C2DMeanVarImageFilterFactory::do_get_descr()const
+{
+	return "Filter that evaluates simultaniously the pixel wise mean and the variance of an image in a given window. "
+		"Pixel intensities below the given threshold will be ignored and at their loctions the output mean and "
+		"variation are set to zero. The mean intensity image is directly passed as float image to the pipeline, "
+		"the variation image is saved to a file given with the varfile parameter.";
+}
+
+struct FCompare {
+	bool operator () (float a, float b){
+		return ::fabs(a-b) < 0.0001;
+	}
+};
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C2DMeanVarImageFilterFactory();
+}
+
+NS_END
diff --git a/mia/2d/filter/thresh.hh b/mia/2d/filter/meanvar.hh
similarity index 66%
copy from mia/2d/filter/thresh.hh
copy to mia/2d/filter/meanvar.hh
index ea02094..6d18ca5 100644
--- a/mia/2d/filter/thresh.hh
+++ b/mia/2d/filter/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,38 +18,38 @@
  *
  */
 
-#include <limits>
 #include <mia/core/filter.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/2d/filter.hh>
-#include <mia/2d/shape.hh>
 
+#include <limits>
 
-NS_BEGIN(thresh_2dimage_filter)
+NS_BEGIN(meanvar_2dimage_filter);
 
-class C2DThreshNImageFilter: public mia::C2DFilter {
+class C2DMeanVar: public mia::C2DFilter {
 public:
-	C2DThreshNImageFilter(mia::P2DShape shape, double thresh);
+	C2DMeanVar(unsigned  hw, double thresh, const std::string& m_varfilenme);
 
 	template <typename T>
-	typename mia::C2DFilter::result_type operator () (const mia::T2DImage<T>& result)const;
-
+	C2DMeanVar::result_type operator () (const mia::T2DImage<T>& data) const;
 private:
+	virtual mia::P2DImage do_filter(const mia::C2DImage& image) const;
 
-	virtual mia::P2DImage do_filter(const mia::C2DImage& src) const;
-
-	mia::P2DShape m_shape;
+	unsigned m_hw;
 	double m_thresh;
+	std::string m_varfilename; 
 };
 
-class C2DThreshNImageFilterFactory: public mia::C2DFilterPlugin {
+
+class C2DMeanVarImageFilterFactory: public mia::C2DFilterPlugin {
 public:
-	C2DThreshNImageFilterFactory();
+	C2DMeanVarImageFilterFactory();
 private:
 	virtual mia::C2DFilter *do_create()const;
 	virtual const std::string do_get_descr() const;
-	mia::P2DShape m_shape;
+	unsigned m_hw;
 	double m_thresh;
+	std::string m_varfilename;
 };
 
 NS_END
diff --git a/mia/2d/filter/median.cc b/mia/2d/filter/median.cc
index 04e0c58..171468f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2ae8947..e47d8f3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/medianmad.cc b/mia/2d/filter/medianmad.cc
new file mode 100644
index 0000000..8ecabff
--- /dev/null
+++ b/mia/2d/filter/medianmad.cc
@@ -0,0 +1,183 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/threadedmsg.hh>
+#include <mia/core/parallel.hh>
+
+#include <mia/2d/filter/medianmad.hh>
+#include <mia/2d/imageio.hh>
+
+#include <limits>
+#include <cmath>
+
+#include <gsl/gsl_cblas.h>
+
+NS_BEGIN(medianmad_2dimage_filter);
+
+NS_MIA_USE;
+using namespace std;
+
+C2DMedianMad::C2DMedianMad(unsigned hw, double thresh, const std::string& madfilename):
+	m_hw(hw),
+	m_thresh(thresh),
+	m_madfilename(madfilename)
+{
+}
+
+template <typename T>
+std::pair<T, T> evaluate_pixel(const T2DImage<T>& data,
+					 unsigned x, unsigned y, unsigned hw, double thresh, vector<T>& buffer)
+{
+	unsigned startx = x - hw;
+	if (startx > data.get_size().x)
+		startx = 0;
+
+	unsigned endx = x + hw + 1;
+	if (endx > data.get_size().x)
+		endx = data.get_size().x;
+
+	unsigned starty = y - hw;
+	if (starty > data.get_size().y)
+		starty = 0;
+
+	unsigned endy = y + hw + 1;
+	if (endy > data.get_size().y)
+		endy = data.get_size().y;
+
+
+	std::pair<T, T> result = {0, 0};
+
+	float orig_value = data(x,y);
+
+	if (orig_value >=  thresh) {
+		int n = 0; 
+		auto i = buffer.begin(); 
+		for (unsigned iy = starty; iy < endy; ++iy) {
+			for (unsigned ix = startx; ix < endx; ++ix) {
+				double v = data(ix, iy);
+				if (v >= thresh) {
+					*i++ = v;
+					++n; 
+				}
+			}
+		}
+		if (i != buffer.begin()) {
+			sort(buffer.begin(), i);
+			if (n & 1) 
+				result.first = buffer[n / 2];
+			else
+				result.first = static_cast<T>(0.5 * (buffer[n/2] + buffer[n/2 - 1]));
+
+			transform (buffer.begin(), i, buffer.begin(),
+				   [result](T x){ return x >  result.first ? x - result.first : result.first - x;});
+			sort(buffer.begin(), i);
+			if (n & 1) 
+				result.second = buffer[n / 2];
+			else
+				result.second = static_cast<T>(0.5 * (buffer[n/2] + buffer[n/2 - 1]));
+			
+		}else{
+			result.first = orig_value; 
+		}
+	}
+	return result; 
+}
+
+template <typename T>
+C2DMedianMad::result_type C2DMedianMad::operator () (const T2DImage<T>& data) const
+{
+	TRACE_FUNCTION;
+
+	cvdebug() << "Running 2D MedianMad with hw=" << m_hw
+		  << ", thresh=" << m_thresh
+		  << ", and madfile=" << m_madfilename
+		  << "\n";
+
+	T2DImage<T> *result_mu = new T2DImage<T>(data.get_size(), data);
+	T2DImage<T> *result_sigma = new T2DImage<T>(data.get_size(), data);
+
+	P2DImage presult_sigma(result_sigma);
+	
+	auto evaluate_row = [&](const C1DParallelRange& range){
+		int size = 2 * m_hw + 1; 
+		vector<T> buffer(size * size); 
+		for (int y = range.begin(); y != range.end(); ++y){
+			auto omu = result_mu->begin_at(0,y);
+			auto osigma = result_sigma->begin_at(0,y);
+			for (unsigned x = 0; x < data.get_size().x; ++x, ++omu, ++osigma){
+				auto r = evaluate_pixel(data, x, y, m_hw, m_thresh, buffer);
+				*omu = r.first;
+				*osigma = r.second; 
+			}
+		}
+	};
+
+	pfor(C1DParallelRange(0, data.get_size().y, 1), evaluate_row);
+	
+	if (!m_madfilename.empty()) {
+		if (!save_image(m_madfilename, presult_sigma)) {
+			cverr() << "C2DMedianMad: Unable to save median absolute distance data to '" << m_madfilename <<"'"; 
+		}
+	
+	}
+	return P2DImage(result_mu);
+}
+
+P2DImage C2DMedianMad::do_filter(const C2DImage& image) const
+{
+	return mia::filter(*this, image);
+}
+
+C2DMedianMadImageFilterFactory::C2DMedianMadImageFilterFactory():
+	C2DFilterPlugin("medianmad"),
+	m_hw(1),
+	m_thresh(0.0)
+{
+	add_parameter("w", make_lc_param(m_hw, 1, false, "filter width parameter"));
+	add_parameter("thresh", make_lc_param(m_thresh, 0.0, false, "Intensity threshholding parameter: Pixels with intensities "
+					      "below this threshhold will be set to zero, and also not used when evaluating mean "
+					      "and variation"));
+	add_parameter("madfile", new CStringParameter(m_madfilename, CCmdOptionFlags::required_output,
+						      "name of the output file to save the median absolute deviation image too.", 
+						      &C2DImageIOPluginHandler::instance()));
+}
+
+C2DFilter *C2DMedianMadImageFilterFactory::do_create()const
+{
+	return new C2DMedianMad(m_hw, m_thresh, m_madfilename);
+}
+
+const string C2DMedianMadImageFilterFactory::do_get_descr()const
+{
+	return "Filter that evaluates simultaniously the pixel wise median and the median absolute deviation (MAD) of an image"
+		" in a given window. Pixel intensities below the given threshold will be ignored "
+		"and at their loctions the output median and MAD are set to zero. The median "
+		"intensity image is directly passed to the pipeline, the variation image is "
+		"saved to a file given with the varfile parameter. Both output images have the same pixel type like the input image.";
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C2DMedianMadImageFilterFactory();
+}
+
+NS_END
diff --git a/mia/2d/filter/thresh.hh b/mia/2d/filter/medianmad.hh
similarity index 65%
copy from mia/2d/filter/thresh.hh
copy to mia/2d/filter/medianmad.hh
index ea02094..762661b 100644
--- a/mia/2d/filter/thresh.hh
+++ b/mia/2d/filter/medianmad.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,38 +18,38 @@
  *
  */
 
-#include <limits>
 #include <mia/core/filter.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/2d/filter.hh>
-#include <mia/2d/shape.hh>
 
+#include <limits>
 
-NS_BEGIN(thresh_2dimage_filter)
+NS_BEGIN(medianmad_2dimage_filter);
 
-class C2DThreshNImageFilter: public mia::C2DFilter {
+class C2DMedianMad: public mia::C2DFilter {
 public:
-	C2DThreshNImageFilter(mia::P2DShape shape, double thresh);
+	C2DMedianMad(unsigned  hw, double thresh, const std::string& m_madfilenme);
 
 	template <typename T>
-	typename mia::C2DFilter::result_type operator () (const mia::T2DImage<T>& result)const;
-
+	C2DMedianMad::result_type operator () (const mia::T2DImage<T>& data) const;
 private:
+	virtual mia::P2DImage do_filter(const mia::C2DImage& image) const;
 
-	virtual mia::P2DImage do_filter(const mia::C2DImage& src) const;
-
-	mia::P2DShape m_shape;
+	unsigned m_hw;
 	double m_thresh;
+	std::string m_madfilename; 
 };
 
-class C2DThreshNImageFilterFactory: public mia::C2DFilterPlugin {
+
+class C2DMedianMadImageFilterFactory: public mia::C2DFilterPlugin {
 public:
-	C2DThreshNImageFilterFactory();
+	C2DMedianMadImageFilterFactory();
 private:
 	virtual mia::C2DFilter *do_create()const;
 	virtual const std::string do_get_descr() const;
-	mia::P2DShape m_shape;
+	unsigned m_hw;
 	double m_thresh;
+	std::string m_madfilename;
 };
 
 NS_END
diff --git a/mia/2d/filter/midpoint.cc b/mia/2d/filter/midpoint.cc
index c805577..03aa016 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b8098f0..ed70ce6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,11 +24,7 @@
 
 #include <limits>
 
-#ifdef HAVE_BLAS
-extern "C" {
-#include <cblas.h>
-}
-#endif
+#include <gsl/gsl_cblas.h>
 
 NS_BEGIN(mlv_2dimage_filter);
 
@@ -201,7 +197,6 @@ C2DMLV::result_type C2DMLV::operator () (const T2DImage<T>& data) const
 											 data.begin() + data.get_size().x * (y + 1) ,
 											 m_sqbuf.begin());
 
-#ifdef HAVE_BLAS
 			copy(data.begin_at(0,y), data.begin_at(0,y) + data.get_size().x, m_buf.begin());
 			for (size_t x = 0; x < m_kh; ++x) {
 				cblas_saxpy(data.get_size().x, 1.0f, &m_buf[0],  1, &m_mu_l1[x], 1);
@@ -212,27 +207,6 @@ C2DMLV::result_type C2DMLV::operator () (const T2DImage<T>& data) const
 				cblas_saxpy(m_mu_l1.size(), 1.0f, &m_mu_l1[0],  1, &m_mu(0,y + iy), 1);
 				cblas_saxpy(m_sigma_l1.size(), 1.0f, &m_sigma_l1[0],  1, &m_sigma(0,y + iy), 1);
 			}
-#else
-			for (size_t x = 0; x < m_kh; ++x) {
-				C2DFImage::iterator start = m_mu_l1.begin() + x;
-
-				__dispatch_trasform<typename T2DImage<T>::const_iterator>::apply_add(start,
-												     start + data.get_size().x,
-												     data.begin() + data.get_size().x * y);
-
-				start = m_sigma_l1.begin() + x;
-				transform(start, start + data.get_size().x, m_sqbuf.begin(), start, 
-					  [][float a, float b](return a+b;});
-			}
-
-			for (size_t iy= 0; iy < m_kh; ++iy) {
-				transform(m_mu_l1.begin(), m_mu_l1.end(), m_mu.begin_at(0,y + iy), 
-					  m_mu.begin_at(0,y + iy), [](float a, float b)(return a+b;});
-				transform(m_sigma_l1.begin(), m_sigma_l1.end(), m_sigma.begin_at(0,y + iy), 
-					  m_sigma.begin_at(0,y + iy), [](float a, float b)(return a+b;});
-			}
-#endif
-
 		}
 
 
diff --git a/mia/2d/filter/mlv.hh b/mia/2d/filter/mlv.hh
index 97a6079..9f714c1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 80f9e97..6928944 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ab05ad2..31a35c5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 db7cab2..f1194dd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 772f136..c3559f6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 81fb5dd..a6fe17e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8322879..e8c82e2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3b267fc..6177f55 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/filter/regiongrow.hh
index c0ffec9..37a2192 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9f7e4f3..b008eca 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 01111c1..6905a86 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ed797ab..526c237 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1e74c5f..dff8ccf 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1be0fbf..3abeaeb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f1a7792..6d9fa5e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 99f5a29..522b50a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0139a90..9529034 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@ void CSeparableConvolute::fold(vector<T>& data, const C1DFilterKernel& kernel) c
 template <class T>
 CSeparableConvolute::result_type CSeparableConvolute::operator () (const T2DImage<T>& image) const
 {
-	typedef typename T2DImage<T>::value_type value_type;
-	typedef std::vector<value_type> invec_t;
+	typedef std::vector<T> invec_t;
 
 	T2DImage<T> *data = new T2DImage<T>(image);
 	CSeparableConvolute::result_type result(data);
@@ -131,14 +130,13 @@ const string C2DGaussFilterPlugin::do_get_descr()const
 	return "isotropic 2D gauss filter";
 }
 
-const TDictMap<C2DSobelFilterPlugin::EGradientDirection>::Table C2DSobelFilterPlugin::dir_dict[] = {
-	{"x", C2DSobelFilterPlugin::gd_x, "gradient in x-direction "},
-	{"y", C2DSobelFilterPlugin::gd_y, "gradient in y-direction "},
-	{NULL, C2DSobelFilterPlugin::gd_undefined, ""}
+const TDictMap<EGradientDirection>::Table dir_dict[] = {
+	{"x", gd_x, "gradient in x-direction "},
+	{"y", gd_y, "gradient in y-direction "},
+	{NULL, gd_undefined, ""}
 };
 
-const TDictMap<C2DSobelFilterPlugin::EGradientDirection>
-C2DSobelFilterPlugin::Ddirection(C2DSobelFilterPlugin::dir_dict);
+const TDictMap<EGradientDirection> Ddirection(dir_dict);
 
 C2DSobelFilterPlugin::C2DSobelFilterPlugin():
 	C2DFilterPlugin("sobel"),
@@ -169,6 +167,35 @@ const std::string C2DSobelFilterPlugin::do_get_descr()const
 }
 
 
+C2DScharrFilterPlugin::C2DScharrFilterPlugin():
+	C2DFilterPlugin("scharr"),
+	m_direction(gd_x)
+{
+	add_parameter("dir", new CDictParameter<EGradientDirection>(m_direction, Ddirection, "Gradient direction"));
+}
+
+mia::C2DFilter *C2DScharrFilterPlugin::do_create()const
+{
+	const auto&  skp = C1DSpacialKernelPluginHandler::instance();
+	auto scharr = skp.produce("scharr");
+	auto cdiff = skp.produce("cdiff");
+	
+	switch (m_direction) {
+	case gd_x: return new CSeparableConvolute(cdiff, scharr);
+	case gd_y: return new CSeparableConvolute(scharr, cdiff);
+	default:
+		throw invalid_argument("C2DScharrFilterPlugin: unknown gradient direction specified");
+	}
+}
+
+const std::string C2DScharrFilterPlugin::do_get_descr()const
+{
+	return "The 2D Scharr filter for gradient evaluation. Note that the output pixel type "
+		"of the filtered image is the same as the input pixel type, so converting the input "
+		"beforehand to a floating point valued image is recommendable."; 
+}
+
+
 extern "C" EXPORT CPluginBase *get_plugin_interface()
 {
 	CPluginBase *gauss = new C2DGaussFilterPlugin();
diff --git a/mia/2d/filter/sepconv.hh b/mia/2d/filter/sepconv.hh
index 7e1decf..af0cf18 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@ private:
 	int m_w;
 };
 
+enum EGradientDirection {gd_x, gd_y, gd_undefined};
 
 class C2DSobelFilterPlugin: public mia::C2DFilterPlugin {
 public:
@@ -74,10 +75,15 @@ public:
 	virtual mia::C2DFilter *do_create()const;
 	virtual const std::string do_get_descr()const;
 private:
-	enum EGradientDirection {gd_x, gd_y, gd_undefined};
 
-	static const mia::TDictMap<EGradientDirection>::Table dir_dict[];
-	static const mia::TDictMap<C2DSobelFilterPlugin::EGradientDirection> Ddirection;
+	EGradientDirection m_direction; 
+};
+
+class C2DScharrFilterPlugin: public mia::C2DFilterPlugin {
+public:
+	C2DScharrFilterPlugin();
+	virtual mia::C2DFilter *do_create()const;
+	virtual const std::string do_get_descr()const;
 
 	EGradientDirection m_direction; 
 };
diff --git a/mia/2d/filter/shaped_mean.cc b/mia/2d/filter/shaped_mean.cc
index d7d3712..12546aa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1fac862..32c418c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 fd82af1..2c2651e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ec09629..83e5749 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2198155..48bd0ac 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/filter/tee.hh
index 399c484..3b9656e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5b70de0..11efcfb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 817ad44..69fdc69 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 beaf211..68fa526 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3c5f969..6eb3f18 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d0ec664..6ac1743 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index bfd197e..59f12f2 100644
--- a/mia/2d/filter/test_combiner.cc
+++ b/mia/2d/filter/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_convert.cc b/mia/2d/filter/test_convert.cc
index ea57354..494de9b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5b8aa3a..20d74fa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 249c457..6f4b38e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1d393c6..52742c0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d353f27..cd50f38 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_fft.cc b/mia/2d/filter/test_fft.cc
index 2e79662..509ba75 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3506f8b..b82648f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 cb8690a..cbed57a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a74ab86..7b35ee4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 81dc5fe..32635a1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a89e4aa..9b874df 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_labelscale.cc b/mia/2d/filter/test_labelscale.cc
index fc51a29..4c095e9 100644
--- a/mia/2d/filter/test_labelscale.cc
+++ b/mia/2d/filter/test_labelscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9ade1a8..28d3593 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_mask.cc b/mia/2d/filter/test_mask.cc
index 7c1a41d..a65ce05 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 760e5b7..90d228e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_meanvar.cc b/mia/2d/filter/test_meanvar.cc
new file mode 100644
index 0000000..bce802d
--- /dev/null
+++ b/mia/2d/filter/test_meanvar.cc
@@ -0,0 +1,134 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/meanvar.hh>
+#include <mia/2d/imageio.hh>
+
+NS_MIA_USE
+using namespace std;
+using namespace ::boost;
+using namespace ::boost::unit_test;
+using namespace meanvar_2dimage_filter;
+
+BOOST_AUTO_TEST_CASE( test_meanvar_without_thresh )
+{
+#ifndef WIN32
+	// deterministic test, aleays use the same seed 
+	srand48(0);
+#endif
+
+	for (int width = 4; width < 5; ++width) {
+		int w = width / 2;
+		cvdebug() << "test filter of width " << w << "\n";
+		ostringstream filter_descr; 
+		filter_descr << "meanvar:w=" << w << ",varfile=varfile.@";
+		cvdebug() << "Testing " << filter_descr.str() << "\n"; 
+		auto filter = BOOST_TEST_create_from_plugin<C2DMeanVarImageFilterFactory>(filter_descr.str().c_str()); 
+
+		int isize = 4 * w + 1;
+		C2DBounds size(isize, isize);
+
+		C2DFImage *src = new C2DFImage(size);
+		for (C2DFImage::iterator i = src->begin(), e = src->end(); i != e; ++i)
+#ifndef WIN32
+			*i = drand48();
+#else
+			*i = 1.0f; // windows doesnt have drand48
+#endif
+
+		// create the reference image
+		C2DFImage ref(src->get_size());
+
+		C2DFImage sigma(size);
+		C2DFImage mu(size);
+
+
+		for (int y = 0; y < isize; ++y) {
+			for (int x = 0; x < isize; ++x) {
+				float sum  = 0.0f;
+				float sum2 = 0.0f;
+				int n = 0;
+
+				int starty = max(0, y - w);
+				int startx = max(0, x - w);
+				
+				int endy = min(isize, y + w + 1);
+				int endx = min(isize, x + w + 1);
+
+				
+				for (int iy = starty; iy < endy; ++iy) 
+					for (int ix = startx; ix < endx; ++ix) {
+						float const& val = (*src)(ix,iy);
+						sum += val;
+						sum2 += val * val;
+						++n;
+					}
+				cvdebug() << "("<< x << ", " << y << ")n=" << n
+					  << " ["<< startx << "," << endx 
+					  << "]x[" << starty << "," << endy 
+					  << "]\n"; 
+				float m = n>0 ? mu(x,y) = sum / n : 0;
+				sigma(x,y) = (n > 1) ? sqrt((sum2 - sum * m) / (n - 1)) : 0.0f;
+			}
+
+		}
+		
+		P2DImage src_wrap(src);
+		P2DImage res_mu_wrap = filter->filter(*src_wrap);
+		C2DFImage * res_mu = dynamic_cast<C2DFImage *>(res_mu_wrap.get());
+		BOOST_REQUIRE(res_mu);
+
+		BOOST_CHECK_EQUAL(res_mu->get_size(), src_wrap->get_size());
+		BOOST_REQUIRE(res_mu->get_size() == src_wrap->get_size());
+
+		
+		auto ires = res_mu->begin();
+		auto iref = mu.begin();
+
+		for (int  y = 0; y < isize; ++y) {
+			for (int  x = 0; x < isize; ++x, ++ires, ++iref) {
+				if (fabs(*ires - *iref) > 1e-5
+					) {
+					cvfail() << "Error at (" << x << ", " << y << ") got " << *ires
+						 << " expect "<< *iref << "\n"; 
+				}
+			}
+		}
+		
+		for (auto ires = res_mu->begin(), iref = mu.begin();
+		     ires != res_mu->end(); ++ires, ++iref) {
+			BOOST_CHECK_CLOSE(*ires, *iref, 0.1);
+		}		
+
+		P2DImage res_sigma_wrap = load_image2d("varfile.@");
+		BOOST_REQUIRE(res_sigma_wrap); 
+		C2DFImage *res_sigma = dynamic_cast<C2DFImage *>(res_sigma_wrap.get());
+		BOOST_REQUIRE(res_sigma);
+		
+		BOOST_CHECK_EQUAL(res_sigma->get_size(), src_wrap->get_size());
+		BOOST_REQUIRE(res_sigma->get_size() == src_wrap->get_size());
+
+		for (auto ires = res_sigma->begin(), iref = sigma.begin();
+		     ires != res_sigma->end(); ++ires, ++iref) {
+			BOOST_CHECK_CLOSE(*ires, *iref, 0.1);
+		}		
+	}
+}
diff --git a/mia/2d/filter/test_median.cc b/mia/2d/filter/test_median.cc
index b55ff38..fe0b17f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_medianmad.cc b/mia/2d/filter/test_medianmad.cc
new file mode 100644
index 0000000..c9e6464
--- /dev/null
+++ b/mia/2d/filter/test_medianmad.cc
@@ -0,0 +1,130 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/medianmad.hh>
+#include <mia/2d/imageio.hh>
+
+NS_MIA_USE
+using namespace std;
+using namespace ::boost;
+using namespace ::boost::unit_test;
+using namespace medianmad_2dimage_filter;
+
+BOOST_AUTO_TEST_CASE( test_medianmad_without_thresh )
+{
+	const size_t size_x = 7;
+	const size_t size_y = 5;
+
+	const int src[size_y][size_x] =
+		{{ 0, 1, 2, 3, 2, 3, 5},
+		 { 2, 5, 2, 3, 5, 3, 2},
+		 { 1, 2, 7, 6, 4, 2, 1},
+		 { 3, 4, 4, 3, 4, 3, 2},
+		 { 1, 3, 2, 4, 5, 6, 2}};
+
+	// "hand filtered" w = 1 -> 3x3
+	const int src_ref[size_y][size_x] =
+ 		{{ 1, 2, 2, 2, 3, 3, 3},
+		 { 1, 2, 3, 3, 3, 3, 2},
+		 { 2, 3, 4, 4, 3, 3, 2},
+		 { 2, 3, 4, 4, 4, 3, 2},
+		 { 3, 3, 3, 4, 4, 3, 2}};
+
+	const int ref_mad[size_y][size_x] =
+		{{ 1, 0, 1, 0, 0, 1, 0},
+		 { 1, 1, 1, 1, 1, 1, 1},
+		 { 1, 1, 1, 1, 1, 1, 0},
+		 { 1, 1, 1, 1, 1, 1, 0},
+		 { 0, 1, 1, 0, 1, 1, 0}};
+
+	
+
+	C2DBounds size(size_x, size_y);
+
+	C2DSIImage *src_img = new C2DSIImage(size);
+	C2DSIImage ref_median_img(size);
+	C2DSIImage ref_mad_img(size);
+	
+	for (size_t y = 0; y < size_y; ++y)
+		for (size_t x = 0; x < size_x; ++x) {
+			(*src_img)(x,y) = src[y][x];
+			ref_median_img(x,y) = src_ref[y][x];
+			ref_mad_img(x,y) = ref_mad[y][x];
+		}
+
+	auto medianmad = BOOST_TEST_create_from_plugin<C2DMedianMadImageFilterFactory>("medianmad:w=1,madfile=mad.@"); 
+	P2DImage src_wrap(src_img);
+	P2DImage res_wrap = medianmad->filter(*src_wrap);
+
+	C2DSIImage * res_median = dynamic_cast<C2DSIImage *>(res_wrap.get());
+	BOOST_REQUIRE(res_median);
+	
+	BOOST_CHECK_EQUAL(res_median->get_size(), src_wrap->get_size());
+	BOOST_REQUIRE(res_median->get_size() == src_wrap->get_size());
+
+		
+	auto ires = res_median->begin();
+	auto iref = ref_median_img.begin();
+	
+	for (unsigned y = 0; y < size_y; ++y) {
+		for (unsigned x = 0; x < size_x; ++x, ++ires, ++iref) {
+			if (fabs(*ires - *iref) > 1e-5
+				) {
+				cvfail() << "Error at (" << x << ", " << y << ") got " << *ires
+					 << " expect "<< *iref << "\n"; 
+			}
+		}
+	}
+	
+	for (auto ires = res_median->begin(), iref = ref_median_img.begin();
+	     ires != res_median->end(); ++ires, ++iref) {
+		BOOST_CHECK_EQUAL(*ires, *iref);
+	}		
+
+	
+	P2DImage res_mad_wrap = load_image2d("mad.@");
+	BOOST_REQUIRE(res_mad_wrap); 
+	C2DSIImage *res_mad = dynamic_cast<C2DSIImage *>(res_mad_wrap.get());
+	BOOST_REQUIRE(res_mad);
+		
+	BOOST_CHECK_EQUAL(res_mad->get_size(), src_wrap->get_size());
+	BOOST_REQUIRE(res_mad->get_size() == src_wrap->get_size());
+
+
+	ires = res_mad->begin();
+	iref = ref_mad_img.begin();
+
+	for (unsigned y = 0; y < size_y; ++y) {
+		for (unsigned x = 0; x < size_x; ++x, ++ires, ++iref) {
+			if (fabs(*ires - *iref) > 1e-5
+				) {
+				cvfail() << "MAD: Error at (" << x << ", " << y << ") got " << *ires
+					 << " expect "<< *iref << "\n"; 
+			}
+		}
+	}
+
+	
+	for (ires = res_mad->begin(), iref = ref_mad_img.begin();
+	     ires != res_mad->end(); ++ires, ++iref) {
+		BOOST_CHECK_EQUAL(*ires, *iref);
+	}		
+}
diff --git a/mia/2d/filter/test_mlv.cc b/mia/2d/filter/test_mlv.cc
index 84d126b..1d03321 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9ea103a..bb0ce8f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ngfnorm.cc b/mia/2d/filter/test_ngfnorm.cc
index 001f8b0..ccf54fb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b0810fd..36e8bd0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_regiongrow.cc b/mia/2d/filter/test_regiongrow.cc
index 9176ec8..c5f919f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_scale.cc b/mia/2d/filter/test_scale.cc
index 5d1571d..c8323c6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_seededwatershed.cc b/mia/2d/filter/test_seededwatershed.cc
index 7eda00e..5c5c5af 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_selectbig.cc b/mia/2d/filter/test_selectbig.cc
index 01d7784..51cf153 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 7863cc9..6414e27 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +147,78 @@ BOOST_AUTO_TEST_CASE( test_sobel_y )
 }
 
 
+BOOST_AUTO_TEST_CASE( test_scharr_x )
+{
+	auto scharr_x = BOOST_TEST_create_from_plugin<C2DScharrFilterPlugin>("scharr:dir=x"); 
+
+	const float in_image[] = {
+		1, 2, 3, 4,                 
+		2, 3, 2, 5,
+		6, 7, 8, 9,
+		5, 4, 6, 3,
+		6, 7, 8, 3
+	};
+
+	
+	const float test_image[] = {
+		0, .625, 1, 0, 
+		0, .375, 1, 0, 
+		0, .71875, .71875, 0, 
+		0, .6875, -0.5, 0, 
+		0, .8125, -1.4375, 0
+	};
+
+	C2DFImage src(C2DBounds(4,5), in_image);
+
+	auto filtered = scharr_x->filter(src);
+
+	const C2DFImage& f = dynamic_cast<const C2DFImage&>(*filtered);
+
+	BOOST_CHECK_EQUAL(f.get_size(), src.get_size());
+
+	const float *t = test_image; 
+	for(auto i = f.begin(); i != f.end(); ++i, ++t) {
+		cvdebug() << *i << " " << *t << "\n"; 
+		BOOST_CHECK_CLOSE(*i, *t, 0.1);
+	}
+}
+
+BOOST_AUTO_TEST_CASE( test_scharr_y )
+{
+	auto scharr_y = BOOST_TEST_create_from_plugin<C2DScharrFilterPlugin>("scharr:dir=y"); 
+
+	const float in_image[] = {
+		1, 2, 6, 5, 6,
+		2, 3, 7, 4, 7,
+		3, 2, 8, 6, 8,
+		4, 5, 9, 3, 3
+	};
+
+	
+	const float test_image[] = {
+		0,  0,  0,  0,  0,
+		.625, 0.375, 0.71875, 0.6875, 0.8125,
+		1, 1, 0.71875, -0.5, -1.4375,
+		0,  0,  0,  0,  0
+	};
+
+	C2DFImage src(C2DBounds(5,4), in_image);
+
+	auto filtered = scharr_y->filter(src);
+
+	const C2DFImage& f = dynamic_cast<const C2DFImage&>(*filtered);
+
+	BOOST_CHECK_EQUAL(f.get_size(), src.get_size());
+
+	const float *t = test_image; 
+	for(auto i = f.begin(); i != f.end(); ++i, ++t) {
+		cvdebug() << *i << " " << *t << "\n"; 
+		BOOST_CHECK_CLOSE(*i, *t, 0.1);
+	}
+	
+}
+
+
 
 
 
diff --git a/mia/2d/filter/test_shaped_mean.cc b/mia/2d/filter/test_shaped_mean.cc
index ee01cd4..29d8c96 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_sortlabel.cc b/mia/2d/filter/test_sortlabel.cc
index d635243..6418e7b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e837804..59dc356 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 fab27ec..8d059e0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9d70347..aec33ac 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_tmean.cc
similarity index 50%
copy from mia/2d/filter/test_mean.cc
copy to mia/2d/filter/test_tmean.cc
index 760e5b7..348cd90 100644
--- a/mia/2d/filter/test_mean.cc
+++ b/mia/2d/filter/test_tmean.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,15 +19,15 @@
  */
 
 #include <mia/internal/plugintester.hh>
-#include <mia/2d/filter/mean.hh>
+#include <mia/2d/filter/tmean.hh>
 
 NS_MIA_USE
 using namespace std;
 using namespace ::boost;
 using namespace ::boost::unit_test;
-using namespace mean_2dimage_filter;
+using namespace tmean_2dimage_filter;
 
-BOOST_AUTO_TEST_CASE( test_2dfilter_mean_float )
+BOOST_AUTO_TEST_CASE( test_2dfilter_tmean_float )
 {
 	const size_t size_x = 7;
 	const size_t size_y = 5;
@@ -42,11 +42,11 @@ BOOST_AUTO_TEST_CASE( test_2dfilter_mean_float )
 	// "hand filtered" w = 1 -> 3x3 using zero boundary conditions 
         //
 	const float src_ref[size_y][size_x] =
-		{{ 2.0/1.0,  2.0/1.0, 8.0/3.0, 17.0/6.0, 19.0/6.0, 10.0/3.0, 13.0/4.0},
-		 {11.0/6.0, 22.0/9.0,31.0/9.0, 34.0/9.0, 31.0/9.0,  3.0/1.0,  8.0/3.0},
-		 {17.0/6.0, 10.0/3.0, 4.0/1.0, 38.0/9.0, 11.0/3.0, 26.0/9.0, 13.0/6.0},
-		 { 7.0/3.0,  3.0/1.0,35.0/9.0, 13.0/3.0, 37.0/9.0, 29.0/9.0,  8.0/3.0},
-		 {11.0/4.0, 17.0/6.0,10.0/3.0, 11.0/3.0, 25.0/6.0, 11.0/3.0, 13.0/4.0}}; 
+		{{ 0.0,      0.0,      3.0, 17.0/6.0, 19.0/6.0, 10.0/3.0, 13.0/4.0},
+		 { 3.0, 20.0/6.0, 30.0/8.0, 34.0/9.0, 31.0/9.0,  13.0/4.0,      3.0},
+		 { 0.0, 29.0/8.0, 4.0/1.0, 38.0/9.0, 11.0/3.0, 25.0/8.0,    0},
+		 { 3.0, 25.0/7.0,35.0/9.0, 13.0/3.0, 37.0/9.0, 28.0/8.0,  3.0},
+		 { 0.0, 16.0/5.0,10.0/3.0, 11.0/3.0, 25.0/6.0, 11.0/3.0, 13.0/4.0}}; 
 	
 	C2DBounds size(size_x, size_y);
 	
@@ -55,11 +55,11 @@ BOOST_AUTO_TEST_CASE( test_2dfilter_mean_float )
 		for (size_t x = 0; x < size_x; ++x)
 			(*src_img)(x,y) = src[y][x];
 	
-	auto mean = BOOST_TEST_create_from_plugin<C2DMeanFilterPlugin>("mean:w=1");
+	auto tmean = BOOST_TEST_create_from_plugin<C2DTmeanFilterPlugin>("tmean:w=1,t=1.5");
 
 	P2DImage src_wrap(src_img);
 
-	P2DImage res_wrap = mean->filter(*src_wrap);
+	P2DImage res_wrap = tmean->filter(*src_wrap);
 
 	C2DFImage* res_img = dynamic_cast<C2DFImage*>(res_wrap.get());
 	BOOST_REQUIRE(res_img);
@@ -67,59 +67,27 @@ BOOST_AUTO_TEST_CASE( test_2dfilter_mean_float )
 
 
 	for (size_t y = 0; y < size_y; ++y)
-		for (size_t x = 0; x < size_x; ++x)
-			BOOST_CHECK_EQUAL((*res_img)(x,y), src_ref[y][x]);
+		for (size_t x = 0; x < size_x; ++x) {
+                        if ((*res_img)(x,y)!= src_ref[y][x]) 
+                                cvdebug() << "(" << x << "," << y << ")="
+                                          << (*res_img)(x,y) << "expect" <<  src_ref[y][x] << "\n"; 
+			BOOST_CHECK_CLOSE((*res_img)(x,y), src_ref[y][x], 0.01);
+                }
 }
 
 
-BOOST_AUTO_TEST_CASE( test_2dfilter_mean_bool )
+// For binary images the filter doesn't make sense. 
+BOOST_AUTO_TEST_CASE( test_2dfilter_tmean_bool )
 {
-	const size_t size_x = 7;
-	const size_t size_y = 5;
-	
-	const bool src[size_y][size_x] =
-		{{ 1, 1, 0, 0, 0, 0, 0},
-		 { 0, 0, 1, 1, 1, 0, 0},
-		 { 0, 0, 1, 1, 1, 0, 0},
-		 { 0, 0, 0, 0, 1, 1, 0},
-		 { 1, 1, 1, 0, 1, 1, 0}};
-	
-	// "hand filtered" w = 1 -> 3x3 using zero boundary conditions 
-        //
-	const bool src_ref[size_y][size_x] =
-		{{ 1, 1, 0, 0, 0, 0, 0},
-		 { 0, 0, 1, 1, 0, 0, 0},
-		 { 0, 0, 0, 1, 1, 0, 0},
-		 { 0, 0, 0, 1, 1, 1, 0},
-		 { 1, 1, 0, 0, 1, 1, 0}};
-	
-	C2DBounds size(size_x, size_y);
-	
-	C2DBitImage *src_img = new C2DBitImage(size);
-	for (size_t y = 0; y < size_y; ++y)
-		for (size_t x = 0; x < size_x; ++x)
-			(*src_img)(x,y) = src[y][x];
-	
-	auto mean = BOOST_TEST_create_from_plugin<C2DMeanFilterPlugin>("mean:w=1");
-
-	P2DImage src_wrap(src_img);
-
-	P2DImage res_wrap = mean->filter(*src_wrap);
-
-	C2DBitImage* res_img = dynamic_cast<C2DBitImage*>(res_wrap.get());
-	BOOST_REQUIRE(res_img);
-	BOOST_REQUIRE(res_img->get_size() == src_img->get_size());
+	auto tmean = BOOST_TEST_create_from_plugin<C2DTmeanFilterPlugin>("tmean:w=1,t=1.5");
 
+	P2DImage src_wrap(new C2DBitImage(C2DBounds(7, 5)));
 
-	for (size_t y = 0; y < size_y; ++y)
-		for (size_t x = 0; x < size_x; ++x) {
-			BOOST_CHECK_EQUAL((*res_img)(x,y), src_ref[y][x]);
-			cvdebug() << x << ", " << y << (*res_img)(x,y) << " vs " << src_ref[y][x]<< "\n"; 
-		}
+        BOOST_CHECK_THROW(tmean->filter(*src_wrap), invalid_argument); 
 }
 
 
-BOOST_AUTO_TEST_CASE( test_2dfilter_mean_int )
+BOOST_AUTO_TEST_CASE( test_2dfilter_tmean_int )
 {
 	const size_t size_x = 7;
 	const size_t size_y = 5;
@@ -134,11 +102,11 @@ BOOST_AUTO_TEST_CASE( test_2dfilter_mean_int )
 	// "hand filtered" w = 1 -> 3x3 using zero boundary conditions 
         //
 	const unsigned int src_ref[size_y][size_x] =
-		{{ 2,  2, 3, 3, 3, 3, 3},
-		 { 2,  2, 3, 4, 3, 3, 3},
-		 { 3,  3, 4, 4, 4, 3, 2},
-		 { 2,  3, 4, 4, 4, 3, 3},
-		 { 3,  3, 3, 4, 4, 4, 3}}; 
+		{{ 0,  0, 3, 3, 3, 3, 3},
+		 { 3,  3, 4, 4, 3, 3, 3},
+		 { 0,  4, 4, 4, 4, 3, 0},
+		 { 3,  4, 4, 4, 4, 4, 3},
+		 { 0,  3, 3, 4, 4, 4, 3}}; 
 	
 	C2DBounds size(size_x, size_y);
 	
@@ -147,11 +115,11 @@ BOOST_AUTO_TEST_CASE( test_2dfilter_mean_int )
 		for (size_t x = 0; x < size_x; ++x)
 			(*src_img)(x,y) = src[y][x];
 	
-	auto mean = BOOST_TEST_create_from_plugin<C2DMeanFilterPlugin>("mean:w=1");
+	auto tmean = BOOST_TEST_create_from_plugin<C2DTmeanFilterPlugin>("tmean:w=1,t=1.5");
 
 	P2DImage src_wrap(src_img);
 
-	P2DImage res_wrap = mean->filter(*src_wrap);
+	P2DImage res_wrap = tmean->filter(*src_wrap);
 
 	C2DUIImage* res_img = dynamic_cast<C2DUIImage*>(res_wrap.get());
 	BOOST_REQUIRE(res_img);
@@ -160,7 +128,8 @@ BOOST_AUTO_TEST_CASE( test_2dfilter_mean_int )
 
 	for (size_t y = 0; y < size_y; ++y)
 		for (size_t x = 0; x < size_x; ++x) {
-			BOOST_CHECK_EQUAL((*res_img)(x,y), src_ref[y][x]);
-			cvdebug() << x << ", " << y << (*res_img)(x,y) << " vs " << src_ref[y][x]<< "\n"; 
+                        BOOST_CHECK_EQUAL((*res_img)(x,y), src_ref[y][x]);
+                        if ((*res_img)(x,y) != src_ref[y][x])
+                                cvdebug() << x << ", " << y << ":= "<<(*res_img)(x,y) << " vs " << src_ref[y][x]<< "\n"; 
 		}
 }
diff --git a/mia/2d/filter/test_transform.cc b/mia/2d/filter/test_transform.cc
index 23bc6d8..0f49e91 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_watershed.cc b/mia/2d/filter/test_watershed.cc
index 3890ade..9eed452 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/2d/filter/thinning.cc
index b1122bd..fc3f6ba 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 cd52d12..13b0bef 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1425b70..811c55c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ C2DThreshNImageFilterFactory::C2DThreshNImageFilterFactory():
 	m_thresh(5.0)
 {
 	add_parameter("shape", make_param(m_shape, "4n", false, "neighborhood shape to take into account")); 
-	add_parameter("thresh", make_param(m_thresh, false, "The threshhold value"));
+	add_parameter("thresh", make_param(m_thresh, false, "The threshold value"));
 }
 
 C2DFilter *C2DThreshNImageFilterFactory::do_create()const
@@ -80,8 +80,8 @@ C2DFilter *C2DThreshNImageFilterFactory::do_create()const
 
 const std::string C2DThreshNImageFilterFactory::do_get_descr() const
 {
-	return  "This filter sets all pixels of an image to zero that fall below a certain threshhold and "
-		"whose neighbours in a given neighborhood shape also fall below a this threshhold"; 
+	return  "This filter sets all pixels of an image to zero that fall below a certain threshold and "
+		"whose neighbours in a given neighborhood shape also fall below a this threshold"; 
 }
 
 extern "C" EXPORT CPluginBase *get_plugin_interface()
diff --git a/mia/2d/filter/thresh.hh b/mia/2d/filter/thresh.hh
index ea02094..08522a7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/tmean.cc b/mia/2d/filter/tmean.cc
new file mode 100644
index 0000000..8ae27ee
--- /dev/null
+++ b/mia/2d/filter/tmean.cc
@@ -0,0 +1,144 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/2d/filter/tmean.hh>
+#include <boost/type_traits/is_floating_point.hpp>
+
+#include <mia/core/parallel.hh>
+
+NS_BEGIN(tmean_2dimage_filter)
+NS_MIA_USE;
+using namespace std;
+
+C2DTmean::C2DTmean(int hw, float thresh):
+	m_hw(hw),
+        m_thresh(thresh)
+{
+}
+
+
+template <typename T, bool value> 
+struct __dispatch_filter {
+	static T apply(const T2DImage<T>& data, int cx, int cy, int hw, float thresh) {
+		double result = 0.0; 
+		int n = 0;
+		for (int y = cy - hw; y <= cy + hw; ++y) {
+			if ( y >= 0 && y < (int)data.get_size().y) 
+				for (int x = cx - hw; x <= cx + hw; ++x) {
+					if ( x >= 0 && x < (int)data.get_size().x) {
+                                                double v = data(x,y);
+                                                if (v > thresh) {
+                                                        result += v; 
+                                                        ++n;
+                                                }
+					}
+				}
+		}
+		return (n > 0) ? static_cast<T>(rint(result/n)): 0; 
+	}
+}; 
+
+template <typename T> 
+struct __dispatch_filter<T, true> {
+	static T apply(const T2DImage<T>& data, int cx, int cy, int  hw, float thresh) {
+		double result = 0.0; 
+		int n = 0; 
+		for (int y = cy - hw; y <= cy + hw; ++y) {
+			if ( y >= 0 && y < (int)data.get_size().y) 
+				for (int x = cx - hw; x <= cx + hw; ++x) {
+					if ( x >= 0 && x < (int)data.get_size().x) {
+                                                double v = data(x,y);
+                                                if (v > thresh) {
+                                                        result += v;
+                                                        ++n;
+                                                }
+					}
+				}
+		}
+		return (n > 0) ? static_cast<T>(result/n): 0; 
+	}
+}; 
+
+template <typename T> 
+C2DTmean::result_type C2DTmean::operator () (const T2DImage<T>& data) const
+{
+	TRACE_FUNCTION; 
+	assert(m_hw >=0); 
+	const bool is_floating_point = boost::is_floating_point<T>::value; 
+
+	T2DImage<T> *tresult = new T2DImage<T>(data.get_size(), data);
+	P2DImage result(tresult);
+
+
+        auto run_line  = [this, data, tresult](const C1DParallelRange& range) {
+		for (auto y = range.begin(); y !=  range.end(); ++y) {
+			auto  i = tresult->begin_at(0, y);
+			auto id = data.begin_at(0, y);
+			for (size_t x = 0; x < data.get_size().x; ++x, ++i, ++id) {
+				if (*id > m_thresh) 
+                                *i = __dispatch_filter<T, is_floating_point>::apply(data, x, y, m_hw, m_thresh);
+                        else
+                                *i = 0;
+			}
+		}
+	};
+	pfor(C1DParallelRange(0, data.get_size().y, 1), run_line);
+
+	return result;
+}
+
+C2DTmean::result_type C2DTmean::operator () (const mia::T2DImage<bool>& MIA_PARAM_UNUSED(data)) const
+{
+        throw invalid_argument("tmean: doesn't make sense for binary images, use mean or median filter"); 
+}
+
+P2DImage C2DTmean::do_filter(const C2DImage& image) const
+{
+	return mia::filter(*this, image);
+}
+
+C2DTmeanFilterPlugin::C2DTmeanFilterPlugin():
+	C2DFilterPlugin("tmean"), 
+	m_hw(1),
+        m_thresh(0.0)
+{
+	add_parameter("w", make_lc_param(m_hw, 1, false, "half filter width"));
+        add_parameter("t", make_param(m_thresh, false, "Threshold for pixels not to take into account"));
+}
+
+C2DFilter *C2DTmeanFilterPlugin::do_create()const
+{
+	return new C2DTmean(m_hw, m_thresh);
+}
+
+const string C2DTmeanFilterPlugin::do_get_descr()const
+{
+	return "2D image thresholded tmean filter: The output pixel value is zero if the input pixel "
+                "value is below the given threshhold, otherwise the pixels in the evaluation windows "
+                "are only considered if the input pixel intensity is above the threshhold.";
+}
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	return new C2DTmeanFilterPlugin();
+}
+
+NS_END
diff --git a/mia/2d/filter/mean.hh b/mia/2d/filter/tmean.hh
similarity index 69%
copy from mia/2d/filter/mean.hh
copy to mia/2d/filter/tmean.hh
index 1e94c7b..088f1e4 100644
--- a/mia/2d/filter/mean.hh
+++ b/mia/2d/filter/tmean.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,29 +20,34 @@
 
 #include <mia/2d/filter.hh>
 
-NS_BEGIN( mean_2dimage_filter)
+NS_BEGIN( tmean_2dimage_filter)
 
 
-class C2DMean : public mia::C2DFilter {
+class C2DTmean : public mia::C2DFilter {
 public:
-	C2DMean(int hw);
+	C2DTmean(int hw, float thresh);
 
 	template <class T>
-	typename C2DMean::result_type operator () (const mia::T2DImage<T>& data) const;
+	C2DTmean::result_type operator () (const mia::T2DImage<T>& data) const;
+
+	C2DTmean::result_type operator () (const mia::T2DImage<bool>& data) const;
+
 private:
 	virtual mia::P2DImage do_filter(const mia::C2DImage& image) const;
 
 	int m_hw;
+        float m_thresh; 
 };
 
 
-class C2DMeanFilterPlugin: public mia::C2DFilterPlugin {
+class C2DTmeanFilterPlugin: public mia::C2DFilterPlugin {
 public:
-	C2DMeanFilterPlugin();
+	C2DTmeanFilterPlugin();
 private:
 	virtual mia::C2DFilter *do_create()const;
 	virtual const std::string do_get_descr()const;
 	int m_hw;
+        float m_thresh; 
 };
 
 NS_END
diff --git a/mia/2d/filter/transform.cc b/mia/2d/filter/transform.cc
index 522ff83..a94a2f5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/filter/transform.hh
index 0163a29..2df2bfd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 aad2d81..de92346 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8ae4003..7cdb696 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6c5f85f..02662da 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 10d4061..583432b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 20dba5e..e5c4744 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
deleted file mode 100644
index a3ea6d4..0000000
--- a/mia/2d/filterchain.cc
+++ /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-2015 Gert Wollny
- *
- * 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/filterchain.hh>
-
-NS_MIA_BEGIN
-
-using namespace std;
-
-C2DFilterChain::C2DFilterChain()
-{
-}
-
-C2DFilterChain::C2DFilterChain(const vector<const char *>& descr)
-{
-	const C2DFilterPluginHandler::Instance& filter_plugins = C2DFilterPluginHandler::instance();
-	vector<const char *>::const_iterator i = descr.begin();
-	vector<const char *>::const_iterator e = descr.end();
-
-	for (; i != e; ++i) {
-		P2DFilter f = filter_plugins.produce(*i);
-		if (f)
-			m_chain.push_back(f);
-		else
-			throw invalid_argument(*i);
-	}
-}
-
-void C2DFilterChain::push_front(P2DFilter filter)
-{
-	assert(filter);
-	m_chain.push_front(filter);
-}
-
-void C2DFilterChain::push_back(P2DFilter filter)
-{
-	assert(filter);
-	m_chain.push_back(filter);
-}
-
-P2DImage C2DFilterChain::filter(const C2DImage& image) const
-{
-	P2DImage tmp(image.clone());
-	list<P2DFilter>::const_iterator i = m_chain.begin();
-	list<P2DFilter>::const_iterator e = m_chain.end();
-
-	while (i != e) {
-		tmp = (*i)->filter(*tmp);
-		++i;
-	}
-	return tmp;
-}
-
-bool C2DFilterChain::empty() const
-{
-	return m_chain.empty();
-}
-
-NS_MIA_END
diff --git a/mia/2d/filterchain.hh b/mia/2d/filterchain.hh
index ccf9d80..93b13da 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 @@ NS_MIA_BEGIN
    
 */
 
+typedef TFilterChain<
+
 class EXPORT_2D C2DFilterChain {
 public:
 	C2DFilterChain();
diff --git a/mia/2d/filtertest.cc b/mia/2d/filtertest.cc
index 0aabddf..c18de94 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f7665a9..04b25e3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f5d6c8d..fb32c91 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/fullcost.hh
index 28a8fc1..22912a3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/image.cc b/mia/2d/fullcost/image.cc
index 788befb..c25d482 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/image.hh b/mia/2d/fullcost/image.hh
index 1c23acd..8985b42 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/label.cc b/mia/2d/fullcost/label.cc
index e885533..b0bca34 100644
--- a/mia/2d/fullcost/label.cc
+++ b/mia/2d/fullcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +186,7 @@ void C2DLabelFullCost::prepare_distance_fields( const C2DUBImage &image )
                 if (exist) {
 			C2DFImage prep(bool_bin.get_size()); 
 			distance_transform_prepare(bool_bin.begin(), bool_bin.end(), 
-						   prep.begin());
+						   prep.begin(), true);
 			
                         m_ref_distances[i] = distance_transform(prep); 
 			transform(m_ref_distances[i].begin(), m_ref_distances[i].end(), 
diff --git a/mia/2d/fullcost/label.hh b/mia/2d/fullcost/label.hh
index 23bad6a..22eb705 100644
--- a/mia/2d/fullcost/label.hh
+++ b/mia/2d/fullcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index ff35ce1..774d90c 100644
--- a/mia/2d/fullcost/maskedimage.cc
+++ b/mia/2d/fullcost/maskedimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/fullcost/maskedimage.hh
index 491a4f2..e44dbab 100644
--- a/mia/2d/fullcost/maskedimage.hh
+++ b/mia/2d/fullcost/maskedimage.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_image.cc b/mia/2d/fullcost/test_image.cc
index 2c5ad7b..7f38bd3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_label.cc b/mia/2d/fullcost/test_label.cc
index b8daad6..bd230a2 100644
--- a/mia/2d/fullcost/test_label.cc
+++ b/mia/2d/fullcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ struct TransformInitFixture {
 }; 
 
 
-BOOST_FIXTURE_TEST_CASE ( test_labeldistance, TransformInitFixture ) 
+BOOST_FIXTURE_TEST_CASE ( test_init_gradient, TransformInitFixture )
 {
         // create two images and do the thing 
         
@@ -52,14 +52,7 @@ BOOST_FIXTURE_TEST_CASE ( test_labeldistance, TransformInitFixture )
                 5, 5, 5, 5, 2, 
 	}; 
 
-        const float distances [25] = {
-                0, 0, 1, 0,         0, 
-                0, 0, 1, 0,         0, 
-                0, 0, 1, 0,         0, 
-                1, 1, 0, 0,         0, 
-                0, 0, 1, sqrtf(2.0f), 0,
-        }; 
-        
+
 	const float gradx [25] = {
 		0, 0, 1, 0, 0, 
                 0, 0, 1, 0, 0, 
diff --git a/mia/2d/fullcost/test_maskedimage.cc b/mia/2d/fullcost/test_maskedimage.cc
index cded7a7..ec4de81 100644
--- a/mia/2d/fullcost/test_maskedimage.cc
+++ b/mia/2d/fullcost/test_maskedimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +100,103 @@ BOOST_AUTO_TEST_CASE( test_imagefullcost_src_mask)
 	cvdebug() << gradient << "\n"; 	
 }
 
+BOOST_AUTO_TEST_CASE( test_imagefullcost_src_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,  1,  1, 0,  0, 1, 1, 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
+	};
+	
+	const bool ref_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,   1,  1,  1, 1,  1, 1, 1, 1,   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 ));
+	P2DImage ref_mask(new C2DBitImage(size, ref_mask_data ));
+	
+	BOOST_REQUIRE(save_image("src.@", src)); 
+	BOOST_REQUIRE(save_image("ref.@", ref)); 
+	BOOST_REQUIRE(save_image("src-mask.@", src_mask));
+	BOOST_REQUIRE(save_image("ref-mask.@", ref_mask)); 
+
+	C2DMaskedImageFullCost cost("src.@", "ref.@","src-mask.@", "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(cost.cost_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_CHECK(cost.has(property_gradient));
+	BOOST_CHECK(!cost.has("nonexistent-property"));
+
+	C2DBounds read_size = C2DBounds::_0;
+	
+	BOOST_CHECK(cost.get_full_size(read_size));
+	BOOST_CHECK_EQUAL(read_size, size);
+
+	C2DBounds read_wrong_size(2,3); 
+	BOOST_CHECK(!cost.get_full_size(read_wrong_size));
+		
+	cost.set_size(C2DBounds(4,4));
+	
+}
+
+
 BOOST_AUTO_TEST_CASE( test_imagefullcost_ref_mask)
 {
 
diff --git a/mia/2d/fuzzyclustersolver_cg.cc b/mia/2d/fuzzyclustersolver_cg.cc
index 4b9b65a..1158c45 100644
--- a/mia/2d/fuzzyclustersolver_cg.cc
+++ b/mia/2d/fuzzyclustersolver_cg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/fuzzyclustersolver_cg.hh b/mia/2d/fuzzyclustersolver_cg.hh
index eba7ec2..ac0b0e2 100644
--- a/mia/2d/fuzzyclustersolver_cg.hh
+++ b/mia/2d/fuzzyclustersolver_cg.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/fuzzyclustersolver_sor.cc b/mia/2d/fuzzyclustersolver_sor.cc
index c589914..8506018 100644
--- a/mia/2d/fuzzyclustersolver_sor.cc
+++ b/mia/2d/fuzzyclustersolver_sor.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 <cmath> 
 #include <mia/2d/fuzzyclustersolver_sor.hh>
 #include <mia/core/msgstream.hh>
+#include <mia/core/parallel.hh>
 
 
 NS_MIA_BEGIN
@@ -43,28 +44,27 @@ void C2DFuzzyClusterSolver::solve(const C2DFImage& force, C2DFImage& gain)
 
 	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 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 run_y = [&](const C1DParallelRange& range, float norm) -> float{
+		for(auto y = range.begin(); y != range.end(); ++y) {
 			auto igain = gain.begin_at(2, y); 
 			auto iforce = force.begin_at(2, y); 
-			auto iweight = m_weight.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; 
@@ -73,6 +73,18 @@ void C2DFuzzyClusterSolver::solve(const C2DFImage& force, C2DFImage& gain)
 				
 			}
 		}
+		return norm; 
+	};
+
+
+	
+
+
+	float n0 = 0.0; 
+	for (int i = 0; i < m_max_iter; ++i) {
+		float norm = 0.0;
+		norm = preduce( C1DParallelRange(2, size.y - 2), norm, run_y, [](float x, float y){return x+y;}); 
+		
 		cvinfo() << "FuzzyComputeGain: [" << i << "] n=" << norm <<"\n"; 
 		if (i == 0) 
 			n0 = norm; 
diff --git a/mia/2d/fuzzyclustersolver_sor.hh b/mia/2d/fuzzyclustersolver_sor.hh
index d1f99d7..75a50c0 100644
--- a/mia/2d/fuzzyclustersolver_sor.hh
+++ b/mia/2d/fuzzyclustersolver_sor.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/fuzzyseg.cc b/mia/2d/fuzzyseg.cc
index b3fd88c..4b9a9f8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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/cmdlineparser.hh>
 #include <mia/core/histogram.hh>
+#include <mia/core/kmeans.hh>
+#include <mia/core/cmeans.hh>
 #include <mia/2d/fuzzyclustersolver_cg.hh>
 #include <mia/2d/fuzzyclustersolver_sor.hh>
 #include <mia/2d/fuzzyseg.hh>
@@ -40,10 +42,10 @@ using namespace std;
 
 
 /* maximum number of iterations for EM-Algorithm */
-#define _MAXIT 200 
+#define _MAXIT 400 
 
 
-typedef vector<C2DFImage*> C2DFImageVec;
+typedef vector<C2DFImage> C2DFImageVec;
 
 
 class CSegment2d : public TFilter<C2DFImageVec> {
@@ -70,110 +72,6 @@ private:
 
 using namespace std;
 
-template <class Data2D>
-vector<double> Isodata2d (const Data2D& src_image, unsigned int nClasses, unsigned int  maxPixVal)
-{
-	vector<double> clCenter(nClasses);
-
-	/** classmembership of each possible pixelvalue 0-maxPixVal */
-	vector<unsigned int> classOfGreyval( maxPixVal + 1 );
-
-	// discard all intensities below
-	unsigned int ignore = 0;
-
-	if (nClasses <= 1 || nClasses > maxPixVal) {
-		string out_of_range = ("Isodata2d: parameter --no-of-classes out of range");
-		throw invalid_argument(out_of_range);
-
-	};
-
-	// let initial cluster centers be evenly distributed between 0...maxPixelVal
-	double dCenters = (double)(maxPixVal)/(nClasses+1);  		 // get distance between clCenters
-	for (unsigned int i = 0; i < nClasses; i++)
-		clCenter[i] = (i+1) *dCenters; //save clCenters
-
-	// first pass: build a histogram
-	THistogram<THistogramFeeder<int> > histo(THistogramFeeder<int>(0, maxPixVal + 1, maxPixVal + 1));
-	histo.push_range (src_image.begin(), src_image.end ());
-
-	// now find cluster centers
-	double diff = HUGE;
-	for (unsigned int t = 0; diff > 1.0 && t < 15; t++) {
-
-		// for every grey value
-		for (unsigned int gV = ignore+1; gV < maxPixVal+1; gV++) {
-
-			double dmin = maxPixVal * maxPixVal;
-			// for each class
-			for (unsigned int nc = 0; nc < nClasses; nc++) {
-
-				//distance: shade of grey to class center
-				double dx = gV - clCenter[nc];
-				dx *= dx;
-
-				if (dx < dmin) {
-					//match nearest class
-					classOfGreyval[gV] = nc;
-					dmin = dx;
-				};
-
-			};
-
-		};
-
-		diff = 0;
-
-		for (unsigned int c = 0; c < nClasses; c++) {
-
-			//sum up #pixels belonging to class c
-			//multiply #pixel with grey value (g) & sum up
-			double nPixels = 0;
-			double sumPixelVal = 0;
-
-			for (unsigned int g = ignore+1; g < maxPixVal+1; g++) {
-				if (classOfGreyval[g] == c) {
-
-					nPixels 	+= histo[g];
-					sumPixelVal += histo[g] * g;
-				};
-			};
-
-			//if pixels in class -> get average grey value of cls
-			sumPixelVal = nPixels? sumPixelVal/nPixels : 0;
-			double dx   = sumPixelVal - clCenter[c];
-			clCenter[c] = sumPixelVal;
-			diff += dx*dx;
-
-		};
-	};
-
-	// compute classOfGreyvalue for classification
-	for (unsigned int i = 0; i < ignore+1; i++)
-		classOfGreyval[i] = 0;
-
-	for (unsigned int gV = ignore+1; gV < maxPixVal+1; gV++) {
-
-		double dmin = HUGE;
-		int newClass = 0;
-
-		for (unsigned int c = 0; c < nClasses; c++) {
-
-			// distance: grey value to current cluster center
-			double dValCtr = abs((double)gV - clCenter[c]);
-			// save class-1 with shortest distance
-			if (dValCtr < dmin) {
-				dmin = dValCtr;
-				newClass = c;
-			};
-		};
-		// set classOfGreyvalue
-		classOfGreyval[gV] = newClass + 1;
-	};
-
-	return clCenter;
-};
-
-
 
 // solves the PDE  (W + lambda1 * H1 + lambda2 * H2) = f
 void solvePDE (C2DFImage& weight_image, C2DFImage& force_image, C2DFImage& gain_image, const SFuzzySegParams& params)
@@ -183,7 +81,7 @@ void solvePDE (C2DFImage& weight_image, C2DFImage& force_image, C2DFImage& gain_
 }
 
 template <class Data2D>
-int estimateGain (C2DFImage& gain_image, const Data2D& src_image, vector<C2DFImage*>& cls_image,
+int estimateGain (C2DFImage& gain_image, const Data2D& src_image, vector<C2DFImage>& cls_image,
 		  vector<double> &clCenter, unsigned int classes, const SFuzzySegParams& params)
 {
 
@@ -201,7 +99,7 @@ int estimateGain (C2DFImage& gain_image, const Data2D& src_image, vector<C2DFIma
 			double forcePixel = 0;
 			double weightPixel = 0;
 			for (unsigned int k = 0; k < classes; k++)  {
-				double uk = (*cls_image[k])(x, y);
+				double uk = cls_image[k](x, y);
 				double vk = clCenter[k];
 				double v = uk * uk * vk;
 				forcePixel += v;
@@ -263,8 +161,6 @@ CSegment2d::result_type CSegment2d::operator () (const T2DImage<T>& data)
 	// Field to store the border
 	vector<char> border(noOfPixels);
 
-	double nom, den, dist;
-
 	// get type of iterator
 	typedef T itype;
 
@@ -296,42 +192,19 @@ CSegment2d::result_type CSegment2d::operator () (const T2DImage<T>& data)
 	fill (gain_image.begin(), gain_image.end(), 1.0);
 
 	// class probability image, compute initial class centers
-	vector<double> clCenter = Isodata2d (data, m_nClasses, (unsigned int) iMax);
+	vector<double> clCenter(m_nClasses);
+	vector<unsigned short> buffer(data.size()); 
+	
+	kmeans(data.begin(), data.end(), buffer.begin(), clCenter); 
 
-	// some verbose output
-	cvmsg()  << "intl. class centers:" ;
-	for (unsigned int k = 0; k < m_nClasses; k++)
-		cverb << " [" << k << "] " << clCenter[k];
-	cverb << endl;
+	cvmsg()  << "intl. class centers:" << clCenter << "\n"; 
 
 	// Algorithm step 1
 	// create class membership volumes
 
 	C2DFImageVec cls_image;
 	for (size_t i = 0; i < m_nClasses; ++i)  {
-		cls_image.push_back(new C2DFImage ( data.get_size(), data));
-	}
-	if (0) {
-		vector<C2DFImage::iterator> cls_it( m_nClasses ); 
-		transform(cls_image.begin(), cls_image.end(), cls_it.begin(), 
-			  [](C2DFImage *cls) { return cls->begin(); }); 
-			
-		for(auto sp = data.begin(); sp != data.end(); ++sp) {
-			double pixVal = *sp;
-			//if (pixVal == 0)
-			//	continue;
-			double sum = 0;
-			for (unsigned int k = 0; k < m_nClasses; k++)  {
-				dist = pixVal - clCenter[k];
-				u[k] = dist? 1/(dist*dist): 1e+32;
-				sum += u[k];
-			};
-				
-			for (unsigned int k = 0; k < m_nClasses; k++)  {
-				double un = u[k]/sum;
-				*cls_it[k] = un;
-			}
-		}
+		cls_image.push_back(C2DFImage ( data.get_size(), data));
 	}
 
 	for (unsigned int t = 0; t < _MAXIT; t++)  {
@@ -343,70 +216,19 @@ CSegment2d::result_type CSegment2d::operator () (const T2DImage<T>& data)
 
 		// Algorithm step 3:
 		// recompute class memberships
-		double dumax = 0;
-		auto sp  = data.begin();
 
-		// Compute each pixel of the layer
-		
-		for (unsigned int y = 0; y < ny; y++)  {
-			for (unsigned int x = 0; x < nx; x++, sp++)  {
-				// get Value
-				double pixVal = *sp;
-				//if (pixVal == 0)
-				//	continue;
-				double sum = 0;
-				// get difference from gain-field
-				double gainVal = gain_image(x, y);
-				for (unsigned int k = 0; k < m_nClasses; k++)  {
-					dist = pixVal-gainVal*clCenter[k];
-					u[k] = dist? 1/(dist*dist): HUGE;
-					sum += u[k];
-				};
-				
-				for (unsigned int k = 0; k < m_nClasses; k++)  {
-					double un = u[k]/sum;
-					double uk = (*cls_image[k])(x, y);
-					if (::fabs(un-uk) > dumax)
-						dumax = ::fabs(un-uk);
-					(*cls_image[k])(x, y) = un;
-				}
-			}
-		}
+		cmeans_evaluate_probabilities(data, gain_image, clCenter, cls_image); 
 		
 		// Algorithm step 4:
 		// recompute class clCenters
-		for (unsigned int k = 0; k < m_nClasses; k++) {
-			nom = 0;
-			den = 0;
-			typename T2DImage<T>::const_iterator sp = data.begin();
-			for (unsigned int y = 0; y < ny; y++)  {
-				for (unsigned int x = 0; x < nx; x++, sp++)  {
-					double pixVal = *sp;
-					//if (pixVal == 0)
-					//	continue;
-					double gainVal = gain_image(x, y);
-					double uj      = (*cls_image[k])(x, y);
-					nom += uj*uj*gainVal*pixVal;
-					den += uj*uj*gainVal*gainVal;
-				}
-			}
-			clCenter[k] = den ? nom/den: 0;
-			
-		}
-		
-		cvmsg() << "\r[" << t << "]" << flush;
-		cvmsg() << " class centers:";
-		
-		for (unsigned int k = 0; k < m_nClasses; k++)
-			cverb << " [" << k << "] " << clCenter[k];
+		double residuum = cmeans_update_class_centers(data, gain_image, cls_image, clCenter); 
 
-		cverb << " dumax=" << dumax << "\n"; 
-		if (dumax < 0.01)
+		cvmsg() << "I[" << t << "]: cc=" << clCenter << ", r=" << residuum << "\n"; 
+		if (residuum < 0.0001)
 			break;
 		
 	};
 	
-	
 	// compute corrected image
 	T2DImage<T> *corrected_image = new T2DImage<T> (data.get_size(), data);
 	C2DFImage::iterator gain_itr = gain_image.begin();
@@ -425,9 +247,9 @@ CSegment2d::result_type CSegment2d::operator () (const T2DImage<T>& data)
 				       PAttribute(new CVDoubleAttribute( clCenter)));
 	m_out.reset(corrected_image);
 	for (size_t i = 0; i < cls_image.size(); ++i) {
-		cls_image[i]->set_attribute("class_number",
+		cls_image[i].set_attribute("class_number",
 					    PAttribute(new CIntAttribute( i )));
-		cls_image[i]->set_attribute("class_centers",
+		cls_image[i].set_attribute("class_centers",
 					    PAttribute(new CVDoubleAttribute( clCenter)));
 	}
 	m_gain_image.reset(new C2DFImage(gain_image)); 
@@ -448,7 +270,7 @@ EXPORT_2D P2DImage fuzzy_segment_2d(const C2DImage& src, size_t noOfClasses, con
 	C2DFImageVec imagesVector = mia::accumulate (segment2D, src);
 
 	for (size_t i=0; i < noOfClasses; i++) {
-		classes.push_back( P2DImage(imagesVector[i]) );
+		classes.push_back( P2DImage(new C2DFImage(imagesVector[i])));
 	}
 	gain = segment2D.get_gain_image(); 
 	return segment2D.get_out_image();
diff --git a/mia/2d/fuzzyseg.hh b/mia/2d/fuzzyseg.hh
index 5d2d976..c410ffe 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c7f5363..3f98a3a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c675ba1..2f36804 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1b2fa2e..f4bcbf1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9d9c7df..104bf1b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f31eb3c..4863044 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8f2889c..e0db8f0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b31a228..a342ed0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +117,7 @@ T2DImage<T>::T2DImage(const C2DBounds& size, const T* init_data):
 }
 
 template <typename T>
-T2DImage<T>::T2DImage(const C2DBounds& size, const typename T2DDatafield<T>::data_array& init_data):
+T2DImage<T>::T2DImage(const C2DBounds& size, const vector<T>& init_data):
 	C2DImage(size, (EPixelType)pixel_type<T>::value),
 	m_image(size, init_data)
 {
@@ -179,6 +179,11 @@ const T2DDatafield<T>& T2DImage<T>::data() const
 	return m_image;
 }
 
+template <typename T>
+void T2DImage<T>::make_single_ref()
+{
+	m_image.make_single_ref(); 
+}
 
 template <typename T>
 void T2DImage<T>::get_data_line_x(size_t y, std::vector<T>& buffer) const
@@ -291,6 +296,13 @@ C2DFVector T2DImage<bool>::get_gradient(const C2DFVector& p) const
 }
 
 
+template <class T>
+std::pair<double, double> T2DImage<T>::get_minmax_intensity() const
+{
+	auto mm = std::minmax_element( m_image.begin(), m_image.end());
+	return std::pair<double, double>(*mm.first, *mm.second);
+}
+
 struct FGradientEvaluator: public TFilter<C2DFVectorfield> {
 	template <typename T>
 	C2DFVectorfield operator ()( const T2DImage<T>& image) const {
diff --git a/mia/2d/image.hh b/mia/2d/image.hh
index 9919d0b..da39603 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 @@ public:
         */
 	virtual C2DImage* clone() const __attribute__((warn_unused_result))  = 0;
 
+	virtual std::pair<double, double> get_minmax_intensity() const = 0; 
+
+	virtual void make_single_ref() = 0; 
+	
  protected:
          /** Constructor initializes the size and the pixel type
          */
@@ -158,7 +162,7 @@ public:
 	   \param size 
 	   \param init_data must at least be of size (size.x*size.y)
 	*/
-	T2DImage(const C2DBounds& size, const data_array& init_data);
+	T2DImage(const C2DBounds& size, const std::vector<T>& init_data);
 	/**
 	   Create a 2D image with thegiven size and attach the given meta-data list. 
 	   \param size image size 
@@ -308,6 +312,11 @@ public:
 	   \returns gradient at position p 
 	 */
 	C2DFVector get_gradient(const C2DFVector& p) const;
+
+	/// \returns a pair (minimum, maximum) pixel intensity 
+	std::pair<double, double> get_minmax_intensity() const;
+
+	void make_single_ref(); 
 private:
 	T2DDatafield<T> m_image;
 };
diff --git a/mia/2d/imageio.cc b/mia/2d/imageio.cc
index 38498c0..e387dc3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -183,6 +183,7 @@ C2DImageGroupedSeries  EXPORT_2D load_image_series(const std::vector<std::string
 	return result; 
 }
 
+template class TPlugin<io_2dimage_type, io_plugin_type>; 
 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 29c2d11..72d1f1e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 @@ typedef TIOPlugin<io_2dimage_type> C2DImageIOPlugin;
 
 /// @cond INTERNAL 
 
+extern template class EXPORT_2D TPlugin<io_2dimage_type, io_plugin_type>; 
+extern template class EXPORT_2D TIOPlugin<io_2dimage_type>; 
+
 /**
    \ingroup io 
    \brief Handler class for the image IO 
diff --git a/mia/2d/imageiotest.cc b/mia/2d/imageiotest.cc
index 887ddb6..efdb868 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5edd3d2..4add1d1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 20e1867..9b80933 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 75c2560..8f73035 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/interpolator.cc b/mia/2d/interpolator.cc
index 8d631ca..efb53e0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -91,43 +91,6 @@ const CSplineKernel* C2DInterpolatorFactory::get_kernel() const
 	return m_kernel.get();
 }
 
-C2DInterpolatorFactory *create_2dinterpolation_factory(EInterpolation type, EBoundaryConditions bc)
-{
-	string boundary; 
-	switch (bc) {
-	case bc_mirror_on_bounds: 
-		boundary = "mirror"; 
-		break; 
-		
-	case bc_repeat: 
-		boundary = "repeat"; 
-		break; 
-	case bc_zero: 
-		boundary = "zero"; 
-		break; 
-	default: 
-		throw invalid_argument("Unknown boundary consitions requested"); 
-	}
-	
-	string kernel; 
-	switch (type) {
-	case ip_nn: 
-	case ip_bspline0: kernel = "bspline:d=0"; break; 
-	case ip_linear:
-	case ip_bspline1: kernel = "bspline:d=1"; break; 
-	case ip_bspline2: kernel = "bspline:d=2"; break; 
-	case ip_bspline3: kernel = "bspline:d=3"; break; 
-	case ip_bspline4: kernel = "bspline:d=4"; break; 
-	case ip_bspline5: kernel = "bspline:d=5"; break; 
-	case ip_omoms3:   kernel = "omoms:d=3"; break;
-	default: 
-		throw invalid_argument("create_interpolator_factory:Unknown interpolator type requested"); 
-	}; 
-
-	return new C2DInterpolatorFactory(kernel, boundary); 
-}
-
-
 #ifdef __SSE__
 float add_2d_new<T2DDatafield< float >, 4>::value(const T2DDatafield< float >&  coeff, 
 							   const CSplineKernel::SCache& xc, 
diff --git a/mia/2d/interpolator.cxx b/mia/2d/interpolator.cxx
index 56271eb..be464ff 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -266,7 +266,7 @@ struct add_2d_new<T2DDatafield< T >, 1> {
 }; 
 
 
-#ifdef __SSE__
+#ifdef __SSE2__
 template <>
 struct add_2d_new<T2DDatafield< double >, 4> {
 	static double value(const T2DDatafield< double >&  coeff, 
@@ -275,7 +275,7 @@ struct add_2d_new<T2DDatafield< double >, 4> {
 }; 
 #endif
 
-#ifdef __SSE2__
+#ifdef __SSE__
 
 template <>
 struct add_2d_new<T2DDatafield< float >, 4> {
diff --git a/mia/2d/interpolator.hh b/mia/2d/interpolator.hh
index ae71670..bbbed9e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +175,8 @@ private:
 	PSplineKernel m_kernel;
 	PSplineBoundaryCondition m_x_boundary; 
 	PSplineBoundaryCondition m_y_boundary; 
-	T m_min;
-	T m_max;
+	typename T2DDatafield<T>::value_type m_min;
+	typename T2DDatafield<T>::value_type m_max;
 
 	/// This part makes the class to be not thread save 
 	mutable CSplineKernel::VIndex m_x_index; 
@@ -264,12 +264,6 @@ private:
 typedef std::shared_ptr<C2DInterpolatorFactory > P2DInterpolatorFactory;
 
 
-/**
-   create a 2D interpolation factory of a certain interpolation type 
-*/
-C2DInterpolatorFactory EXPORT_2D  *create_2dinterpolation_factory(EInterpolation type, EBoundaryConditions bc)
-	__attribute__ ((warn_unused_result));
-
 // implementation
 
 template <class T>
diff --git a/mia/2d/io/bmp.cc b/mia/2d/io/bmp.cc
index 9b739c4..f4b7ba8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@ using namespace std;
 using namespace boost;
 
 
-enum EDataType {dt_8bit, dt_16bit, dt_32bit};
 enum ECompression {c_none = 0,
 		   c_8bit_rle,
 		   c_4bit_rle,
@@ -96,7 +95,6 @@ private:
 CBMP2DImageIO::CBMP2DImageIO():
 	C2DImageIOPlugin("bmp")
 {
-	add_supported_type(it_ushort);
 	add_supported_type(it_ubyte);
 	add_supported_type(it_bit);
 	add_suffix(".bmp");
@@ -143,9 +141,77 @@ static P2DImage  read_bit_pixels(CFile& image, unsigned int width, unsigned int
         return presult;
 }
 
+static P2DImage  read_4bit_pixels_c(CFile& image, unsigned int width, unsigned int height)
+{
+	C2DUBImage *result = new C2DUBImage(C2DBounds(width, height));
+	P2DImage presult(result); 
+	cvdebug() << "read_4bit_pixels compressed\n";
+
+	
+	int y = height-1;
+	int x = 0; 
+	while (y >= 0) {
+		int inbyte_1 = fgetc(image);
+		
+		//rle encoded pixels
+		if (inbyte_1 > 0) {
+			int inbyte_2 = fgetc(image);
+			if (inbyte_2 == EOF) 
+				throw runtime_error("BPM::Load: incomplete image");
+			char hi = (inbyte_2 >> 4) & 0xF;
+			char lo = inbyte_2 & 0xF;
+			
+			while (inbyte_1--) {
+				(*result)(x,y) = hi;
+				cvdebug() << inbyte_1 << " x=" << x << ", y=" << y << " -> " << (int)hi << "\n"; 
+				swap(hi, lo);
+				++x;
+			}
+		}else{
+			int inbyte_2 = fgetc(image);
+
+			// literal pixels 
+			if ( inbyte_2 > 2){
+				vector<char> buffer( (inbyte_2 + 3) / 2);
+				if (fread(&buffer[0], 1, buffer.size(), image) != buffer.size())
+					throw runtime_error("BPM::Load: incomplete image");
+				for (auto c = buffer.begin(); c != buffer.end() && inbyte_2 > 0; ++c) {
+					(*result)(x,y) = (*c >> 4) & 0xF;
+					++x; 
+					inbyte_2--;
+					if (inbyte_2--) {
+						(*result)(x,y) = *c & 0xF;
+						++x; 
+					}
+				}
+			}else if (inbyte_2 == 0){
+				cvdebug() << "End of row\n"; 
+				--y;
+				x = 0;
+			}else if (inbyte_2 == 1){
+				cvdebug() << "End of image\n"; 
+				// end of image 
+				break;
+			}else { // if inbyte_2 == 2
+				// offset
+				int dx = fgetc(image);
+				int dy = fgetc(image);
+
+				if (dx == EOF || dy == EOF) {
+					throw runtime_error("BPM::Load: incomplete image");
+				}
+				y -= dy;
+				x += dx;
+			}
+		}
+	}
+	
+	return presult;
+}
+
 static P2DImage  read_4bit_pixels(CFile& image, unsigned int width, unsigned int height)
 {
-	C2DBitImage *result = new C2DBitImage(C2DBounds(width, height));
+	C2DUBImage *result = new C2DUBImage(C2DBounds(width, height));
 	P2DImage presult(result); 
 	cvdebug() << "read_4bit_pixels\n";
 
@@ -251,54 +317,6 @@ static P2DImage  read_8bit_pixels_c(CFile& image, unsigned int width, unsigned i
 	return presult;
 }
 
-
-static P2DImage  read_16bit_pixels(CFile& image, unsigned int width, unsigned int height)
-{
-	C2DUSImage *result = new C2DUSImage(C2DBounds(width, height));
-	P2DImage presult(result); 
-	int row_count = width % 2;
-	cvdebug() << "read_16bit_pixels\n";
-
-	for (int y = height-1; y >= 0; --y) {
-		unsigned short *p = &(*result)(0,y);
-		if (fread( p, width, 2, image) != 2)
-			throw runtime_error("BMP::Load: incomplete image");
-#ifdef WORDS_BIGENDIAN
-		for (size_t x = 0; x < width; ++x, ++p)
-			ENDIANADAPT(*p);
-#endif
-		int remain = row_count;
-		while (remain--) {
-			if (fgetc(image) == EOF) 
-				throw runtime_error("BPM::Load: incomplete image");
-			if (fgetc(image) == EOF) 
-				throw runtime_error("BPM::Load: incomplete image");
-		}
-	}
-	return presult;
-}
-
-
-
-static P2DImage  read_24bit_pixels(CFile& image, unsigned int width, unsigned int height)
-{
-	cvdebug() << "read_24bit_pixels\n";
-
-	C2DUIImage *result = new C2DUIImage(C2DBounds(width, height));
-	P2DImage presult(result); 
-
-	for (int y = height-1; y >= 0; --y) {
-		unsigned int *p = &(*result)(0,y);
-		if (fread( p, width, 4, image) != 4)
-			throw runtime_error("BMP::Load: incomplete image");
-#ifdef WORDS_BIGENDIAN
-		for (size_t x = 0; x < width; ++x, ++p)
-			ENDIANADAPT(*p);
-#endif
-	}
-	return presult;
-}
-
 #ifdef WORDS_BIGENDIAN
 void endian_adapt_header(CBMP2DImageIO::BMPHeader& header)
 {
@@ -357,23 +375,18 @@ CBMP2DImageIO::PData CBMP2DImageIO::do_load(string const& filename)const
 #ifdef WORDS_BIGENDIAN
 	endian_adapt_info_header(info_header);
 #endif
-
-
-	if (info_header.size != 40)
-		throw runtime_error("CBMP2DImageIO::load: incompatible header size");
-
-	cvdebug() << "validated infor header size\n";
-
-	if (info_header.bits <= 8) {
-		// eat the palette
-		size_t palette_size = (1 << info_header.bits);
-		cvdebug() << "Read palette of size " << palette_size << "\n";
-		vector<char> buffer(palette_size * 4);
-		if (fread(&buffer[0], palette_size, 4, f) != 4) {
-			throw runtime_error("bmp: error reading palette");
-		}
+	switch (info_header.size) {
+	case 40:cvdebug() << "BMP: Windows NT, 3.1x style bitmap\n"; 
+		break;
+	case 108: cvdebug() << "BMP: Windows NT 4.0, 95 style bitmap\n"; 
+		break;
+	case 124: cvdebug() << "BMP: Windows NT 5.0, 98 style bitmap\n";
+	default: 
+		throw create_exception<runtime_error>("CBMP2DImageIO::load: incompatible header size=", info_header.size);
 	}
 
+	cvdebug() << "validated info header size\n";
+
 	if ((info_header.width < 1) || (info_header.height < 1))
 		throw create_exception<runtime_error>("CBMP2DImageIO::load: Image has unsupported dimensions", 
 						      " width=", info_header.width, ", height=", 
@@ -388,6 +401,11 @@ CBMP2DImageIO::PData CBMP2DImageIO::do_load(string const& filename)const
 		throw create_exception<runtime_error>("CBMP2DImageIO::load: Image has too big", 
 						      " width=", info_header.width, ", height=", 
 						      info_header.height);
+	if (fseek(f, header.offset, SEEK_SET) != 0) {
+		throw create_exception<runtime_error>("CBMP2DImageIO::load: '", filename,
+						      "' ", strerror(errno)); 
+	}
+	
 	
 	PData result = PData(new C2DImageVector());
 
@@ -401,10 +419,6 @@ CBMP2DImageIO::PData CBMP2DImageIO::do_load(string const& filename)const
 			break;
 		case 8: result->push_back(read_8bit_pixels_uc(f, info_header.width, info_header.height));
 			break;
-		case 16:result->push_back(read_16bit_pixels(f, info_header.width, info_header.height));
-			break;
-		case 24:result->push_back(read_24bit_pixels(f, info_header.width, info_header.height));
-			break;
 		default: {
 			stringstream errmsg;
 			errmsg << "CBMP2DImageIO::load: unsupported pixel size: " << info_header.bits;
@@ -413,10 +427,13 @@ CBMP2DImageIO::PData CBMP2DImageIO::do_load(string const& filename)const
 		} // end switch
 	}else{
 		switch (info_header.bits) {
+		case 4: result->push_back(read_4bit_pixels_c(f, info_header.width, info_header.height));
+			break;
 		case 8: result->push_back(read_8bit_pixels_c(f, info_header.width, info_header.height));
 			break;
 		default:
-			throw runtime_error("CBMP2DImageIO::load: compressed images not (yet) supported");
+			throw create_exception<runtime_error>("CBMP2DImageIO::load: compressed images with ",
+							      info_header.bits, " bits per pixel not supported");
 		}
 	}
 	cvdebug() << "CBMP2DImageIO::load done\n";
@@ -453,23 +470,11 @@ struct TBMPIOPixelTrait<C2DBitImage> {
 };
 
 template <>
-struct TBMPIOPixelTrait<C2DUIImage> {
-	enum { pixel_size = 24 };
-	enum { supported = 1 };
-};
-
-template <>
 struct TBMPIOPixelTrait<C2DUBImage> {
 	enum { pixel_size = 8 };
 	enum { supported = 1 };
 };
 
-template <>
-struct TBMPIOPixelTrait<C2DUSImage> {
-	enum { pixel_size = 16 };
-	enum { supported = 1 };
-};
-
 template <typename Image2D, int supported>
 struct T2DBMPImageWriter
 {
@@ -645,7 +650,9 @@ bool CBMP2DImageIO::do_save(string const& filename, const C2DImageVector& data)
 
 const string  CBMP2DImageIO::do_get_descr()const
 {
-	return string("BMP 2D-image input/output support");
+	return string("BMP 2D-image input/output support. The plug-in supports reading and writing of binary images and "
+		      "8-bit gray scale images. read-only support is provided for 4-bit gray scale images. "
+		      "The color table is ignored and the pixel values are taken as literal gray scale values.");
 }
 
 
diff --git a/mia/2d/io/raw.cc b/mia/2d/io/raw.cc
index fde3fa2..497d79d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 02dc6ac..c2339d4 100644
--- a/mia/2d/io/test_xml.cc
+++ b/mia/2d/io/test_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/xml.cc b/mia/2d/io/xml.cc
index f58e5be..ffee85c 100644
--- a/mia/2d/io/xml.cc
+++ b/mia/2d/io/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/xml.hh b/mia/2d/io/xml.hh
index 8d4666e..5f60f32 100644
--- a/mia/2d/io/xml.hh
+++ b/mia/2d/io/xml.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/iterator.cxx b/mia/2d/iterator.cxx
index 674df97..2ef3b0f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/iterator.hh b/mia/2d/iterator.hh
index 5f334f5..fa0a282 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1ddad7b..2e73729 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 67f738d..15a37db 100644
--- a/mia/2d/maskedcost.cc
+++ b/mia/2d/maskedcost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/maskedcost.hh
index d5edc79..bee308c 100644
--- a/mia/2d/maskedcost.hh
+++ b/mia/2d/maskedcost.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/lncc.cc b/mia/2d/maskedcost/lncc.cc
index 506f353..a97c823 100644
--- a/mia/2d/maskedcost/lncc.cc
+++ b/mia/2d/maskedcost/lncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
 #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>
+#include <mia/core/parallel.hh>
 
 
 NS_BEGIN(NS)
@@ -65,7 +64,7 @@ public:
 	
 	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> {
+		auto evaluate_local_cost = [this, &mov, &ref](const C1DParallelRange& range, const pair<float, int>& result) -> pair<float, int> {
 			CThreadMsgStream msks; 
 			float lresult = 0.0; 
 			int count = 0; 
@@ -107,8 +106,10 @@ public:
 		};
 		
 		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);});	
+		auto r = preduce(C1DParallelRange(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; 
 	}
@@ -136,7 +137,7 @@ public:
 	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, 
+		auto evaluate_local_cost_force = [this, &mov, &ref, &ag](const C1DParallelRange& range, 
 									 const pair<float, int>& result) -> pair<float, int> {
 			
 			CThreadMsgStream msks; 		
@@ -187,10 +188,10 @@ public:
 			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);
-					 });
+		auto r = preduce(C1DParallelRange(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; 
 	}
diff --git a/mia/2d/maskedcost/lncc.hh b/mia/2d/maskedcost/lncc.hh
index 8292f83..666dd4b 100644
--- a/mia/2d/maskedcost/lncc.hh
+++ b/mia/2d/maskedcost/lncc.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/mi.cc b/mia/2d/maskedcost/mi.cc
index 63b4ed0..bab8c75 100644
--- a/mia/2d/maskedcost/mi.cc
+++ b/mia/2d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/mi.hh b/mia/2d/maskedcost/mi.hh
index 0fb7931..e48d162 100644
--- a/mia/2d/maskedcost/mi.hh
+++ b/mia/2d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ncc.cc b/mia/2d/maskedcost/ncc.cc
index 55c8a4b..55d32d9 100644
--- a/mia/2d/maskedcost/ncc.cc
+++ b/mia/2d/maskedcost/ncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +22,7 @@
 
 #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>
+#include <mia/core/parallel.hh>
 
 
 NS_BEGIN(NS)
@@ -39,7 +37,7 @@ 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; 
+	NCCSums operator ()(const C1DParallelRange& range, const NCCSums& sumacc) const; 
 private: 
 	C2DBitImage m_mask; 
 	T m_mov; 
@@ -55,7 +53,7 @@ FEvaluateNCCSum<T,S>::FEvaluateNCCSum(const C2DBitImage& mask, const T& mov, con
 }
 
 template <typename T, typename S> 
-NCCSums FEvaluateNCCSum<T,S>::operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const
+NCCSums FEvaluateNCCSum<T,S>::operator ()(const C1DParallelRange& range, const NCCSums& sumacc) const
 {
 	CThreadMsgStream msks; 
 	
@@ -89,10 +87,10 @@ public:
 
 		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;
-				      });
+		sum = preduce(C1DParallelRange(0, mov.get_size().y, 1), sum, ev, 
+			      [](const NCCSums& x, const NCCSums& y){
+				      return x + y;
+			      });
 		return sum.value(); 
 	}
 }; 
@@ -120,15 +118,15 @@ public:
 		
 		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;
-				      });
+		sum = preduce(C1DParallelRange(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) {
+		auto grad_eval = [this, &mov, &ref, &grad, &geval](const C1DParallelRange& 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); 
@@ -148,7 +146,7 @@ public:
 			}; 
 		}; 
 		
-		parallel_for(tbb::blocked_range<size_t>(0, mov.get_size().y, 1), grad_eval); 
+		pfor(C1DParallelRange(0, mov.get_size().y, 1), grad_eval); 
 
 		return geval.first; 
 	}
diff --git a/mia/2d/maskedcost/ncc.hh b/mia/2d/maskedcost/ncc.hh
index cf4d7bb..816e6e6 100644
--- a/mia/2d/maskedcost/ncc.hh
+++ b/mia/2d/maskedcost/ncc.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ssd.cc b/mia/2d/maskedcost/ssd.cc
index 78095c8..abbc2fa 100644
--- a/mia/2d/maskedcost/ssd.cc
+++ b/mia/2d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ssd.hh b/mia/2d/maskedcost/ssd.hh
index 4e4f1cb..9356f8f 100644
--- a/mia/2d/maskedcost/ssd.hh
+++ b/mia/2d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_lncc.cc b/mia/2d/maskedcost/test_lncc.cc
index f435ab2..1f89581 100644
--- a/mia/2d/maskedcost/test_lncc.cc
+++ b/mia/2d/maskedcost/test_lncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_mi.cc b/mia/2d/maskedcost/test_mi.cc
index a52b06e..f026bee 100644
--- a/mia/2d/maskedcost/test_mi.cc
+++ b/mia/2d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_ncc.cc b/mia/2d/maskedcost/test_ncc.cc
index ea4a075..4e23f46 100644
--- a/mia/2d/maskedcost/test_ncc.cc
+++ b/mia/2d/maskedcost/test_ncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_ssd.cc b/mia/2d/maskedcost/test_ssd.cc
index f637608..5a22590 100644
--- a/mia/2d/maskedcost/test_ssd.cc
+++ b/mia/2d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/matrix.hh b/mia/2d/matrix.hh
index b5ecbbd..ce467cd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 09dd693..028fa79 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 68b4ad6..788a3fa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a93cf09..a1ea7db 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 20c4e06..044cf71 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6e39eb2..7cf6d4b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a9a368a..1982087 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 71c8256..453aa6e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/model/naviera.hh
index 4d864c3..da5c29c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 35ed563..840119c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 69989c3..74a41a8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d3369e1..eeef04a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f2bb351..0e5a503 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 65e1fdc..c8cfcc7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b3ece4b..d41a5fe 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3eb33be..0a99747 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8e617fb..6c67b64 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 44452b7..4d89de5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 eaeac05..fda6c4a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 bdede88..9368332 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 50ac2bc..08634d6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 799a77a..f8a087a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 94b47df..1c77ecc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ struct C2DPerfusionAnalysisImpl {
 				 bool meanstrip); 
 	
 	vector<C2DFImage> get_references() const; 
-	bool run_ica(const vector<C2DFImage>& series);
+	bool run_ica(const vector<C2DFImage>& series, const CICAAnalysisFactory& icatool);
 	P2DFilter get_crop_filter(float scale, C2DBounds& crop_start,
 				  C2DPerfusionAnalysis::EBoxSegmentation approach, 
 				  const std::string& save_features) const; 
@@ -47,7 +47,7 @@ struct C2DPerfusionAnalysisImpl {
 						  C2DBounds& crop_start, 
 						  const string& save_features)const; 
 	
-	CICAAnalysis::IndexSet get_all_without_periodic()const; 
+    CICAAnalysis::IndexSet get_all_without_periodic()const;
 	void save_feature(const string& base, const string& feature, const C2DImage& image)const; 
 	P2DImage get_rvlv_delta_from_feature(const string& save_features)const; 
 	P2DImage get_rvlv_delta_from_peaks(const string& save_features)const; 
@@ -65,7 +65,7 @@ struct C2DPerfusionAnalysisImpl {
 	C2DBounds m_image_size; 
 	CWaveletSlopeClassifier m_cls; 
 	size_t m_length; 
-	int m_ica_approach; 
+	CICAAnalysis::EApproach m_ica_approach;
 	bool m_use_guess_model; 
 	C2DFImage m_image_attributes; 
 	float m_min_movement_frequency;  
@@ -109,7 +109,7 @@ void C2DPerfusionAnalysis::set_min_movement_frequency(float min_freq)
 
 
 
-void C2DPerfusionAnalysis::set_approach(size_t approach)
+void C2DPerfusionAnalysis::set_approach(CICAAnalysis::EApproach approach)
 {
 	assert(impl); 
 	impl->m_ica_approach = approach; 
@@ -131,10 +131,10 @@ P2DFilter C2DPerfusionAnalysis::get_crop_filter(float scale, C2DBounds& crop_sta
 	return impl->get_crop_filter(scale, crop_start, approach, save_features); 
 }
 
-bool C2DPerfusionAnalysis::run(const vector<C2DFImage>& series)
+bool C2DPerfusionAnalysis::run(const vector<C2DFImage>& series, const CICAAnalysisFactory& icatool)
 {
 	assert(impl); 
-	return impl->run_ica(series); 
+    return impl->run_ica(series, icatool);
 }
 
 vector<C2DFImage> C2DPerfusionAnalysis::get_references() const
@@ -157,7 +157,7 @@ C2DPerfusionAnalysisImpl::C2DPerfusionAnalysisImpl(size_t components,
 	m_meanstrip(meanstrip),
 	m_max_iterations(0),
 	m_length(0), 
-	m_ica_approach(FICA_APPROACH_DEFL), 
+    m_ica_approach(CICAAnalysis::appr_defl),
 	m_use_guess_model(false), 
 	m_min_movement_frequency(-1)
 {
@@ -228,7 +228,7 @@ P2DFilter C2DPerfusionAnalysisImpl::get_crop_filter(float scale, C2DBounds& crop
 vector<C2DFImage> C2DPerfusionAnalysisImpl::get_references() const
 {
 	vector<C2DFImage> result(m_length); 
-	CICAAnalysis::IndexSet component_set = get_all_without_periodic(); 
+    CICAAnalysis::IndexSet component_set = get_all_without_periodic();
 	
 	for (size_t i = 0; i < m_length; ++i) {
 		result[i] = m_ica->get_partial_mix(i, component_set); 
@@ -242,18 +242,18 @@ vector<vector<float> > C2DPerfusionAnalysisImpl::create_guess(size_t rows)
 {
 	vector<vector<float> > result(3); 
 	
-	float rv_shift = 0.25 * rows;
-	float lv_shift = 0.4 * rows;
+    float rv_shift = 0.25f * rows;
+    float lv_shift = 0.4f * rows;
 
 	vector<float> lv_slope(rows); 
 	vector<float> rv_slope(rows); 
 	vector<float> perf_slope(rows); 
 	for (size_t x = 0; x < rows; ++x) {
-		rv_slope[x] = (tanh(12 * x /rows - 0.05 * rows) +   
-			       4.0 * exp(-(x-rv_shift) * (x-rv_shift) / rows) - 1)/5.0;
-		lv_slope[x] = (tanh(12 * x /rows - 0.05 * rows) +   
-			       4.0 * exp(-(x-lv_shift) * (x-lv_shift) / rows) - 1)/5.0;
-		perf_slope[x] = tanh(6 * x /rows - 0.05 * rows) / 5.0; 
+        rv_slope[x] = (tanh(12 * x /rows - 0.05f * rows) +
+                   4.0f * exp(-(x-rv_shift) * (x-rv_shift) / rows) - 1)/5.0f;
+        lv_slope[x] = (tanh(12 * x /rows - 0.05f * rows) +
+                   4.0f * exp(-(x-lv_shift) * (x-lv_shift) / rows) - 1)/5.0f;
+        perf_slope[x] = tanh(6 * x /rows - 0.05f * rows) / 5.0f;
 	}
 	result[0] = rv_slope; 
 	result[1] = lv_slope; 
@@ -261,7 +261,7 @@ vector<vector<float> > C2DPerfusionAnalysisImpl::create_guess(size_t rows)
 	return result; 
 }
 
-bool C2DPerfusionAnalysisImpl::run_ica(const vector<C2DFImage>& series) 
+bool C2DPerfusionAnalysisImpl::run_ica(const vector<C2DFImage>& series, const CICAAnalysisFactory& icatool)
 {
 	m_series = series; 
 	m_length = series.size(); 
@@ -270,10 +270,10 @@ bool C2DPerfusionAnalysisImpl::run_ica(const vector<C2DFImage>& series)
 
 	m_image_attributes = series[0]; 
 		
-	srand(time(NULL));
+    srand(static_cast<unsigned>(time(NULL)));
 	m_image_size = series[0].get_size(); 
 	bool has_one = false; 
-	unique_ptr<C2DImageSeriesICA> ica(new C2DImageSeriesICA(series, false));
+    unique_ptr<C2DImageSeriesICA> ica(new C2DImageSeriesICA(icatool, series, false));
 
 	vector<vector<float> > guess; 
 	if (m_use_guess_model) 
@@ -283,7 +283,7 @@ bool C2DPerfusionAnalysisImpl::run_ica(const vector<C2DFImage>& series)
 		ica->set_approach(m_ica_approach); 
 			
 		if (!ica->run(m_components, m_meanstrip, m_normalize, guess) && 
-		    (m_ica_approach == FICA_APPROACH_DEFL))
+            (m_ica_approach == CICAAnalysis::appr_defl))
 			return false; 
 		m_cls = CWaveletSlopeClassifier(ica->get_mixing_curves(), false, m_min_movement_frequency);
 		if (m_cls.result() != CWaveletSlopeClassifier::wsc_fail)
@@ -292,11 +292,11 @@ bool C2DPerfusionAnalysisImpl::run_ica(const vector<C2DFImage>& series)
 
 		size_t min_components_nonzero = 100;
 		for (int i = 6; i >= 4; --i) {
-			unique_ptr<C2DImageSeriesICA> l_ica(new C2DImageSeriesICA(series, false));
+            unique_ptr<C2DImageSeriesICA> l_ica(new C2DImageSeriesICA(icatool, series, false));
 			ica->set_approach(m_ica_approach); 
 			l_ica->set_max_iterations(m_max_iterations);
 
-			if (!l_ica->run(i, m_meanstrip, m_normalize, guess) && (m_ica_approach == FICA_APPROACH_DEFL)) {
+            if (!l_ica->run(i, m_meanstrip, m_normalize, guess) && (m_ica_approach == CICAAnalysis::appr_defl)) {
 				cvwarn() << "run_ica: " << i << " components didn't return a result\n"; 
 				continue; 
 			}
@@ -340,7 +340,7 @@ bool C2DPerfusionAnalysisImpl::run_ica(const vector<C2DFImage>& series)
 	return has_one; 
 }
 
-CICAAnalysis::IndexSet C2DPerfusionAnalysisImpl::get_all_without_periodic()const 
+CICAAnalysis::IndexSet C2DPerfusionAnalysisImpl::get_all_without_periodic() const
 {
 	assert(m_ica); 
 	int movement_index = m_cls.get_movement_idx();
@@ -457,7 +457,6 @@ P2DFilter C2DPerfusionAnalysisImpl::create_LV_cropper_from_delta(P2DImage rvlv_f
 retry:
 	do {
 		do {
-			++nc;
 			stringstream kfd;
 			kfd << "kmeans:c=" << 2*nc + 1;
 			kmeans = run_filter(*pre_kmeans, kfd.str().c_str());
@@ -467,9 +466,16 @@ retry:
 			
 			RV = RV_filter_chain.run(kmeans_binarized);
 			
-			npixels = ::mia::filter(GetRegionSize(1), *RV);
+			npixels = 10 * ::mia::filter(GetRegionSize(1), *RV);
+			cvinfo() << "nc= "<< nc << ", got " << npixels << " RV pixels from size "
+				 << rvlv_feature->get_size().x * rvlv_feature->get_size().y << "\n";
+
+			if (npixels < rvlv_feature->get_size().x * rvlv_feature->get_size().y)
+				break; 
+			
+			++nc;
 			
-		} while (10 * npixels > rvlv_feature->get_size().x * rvlv_feature->get_size().y && nc < 7);
+		} while (nc < 7);
 		
 		if (!save_features.empty()) {
 			save_feature(save_features, "kmeans", *kmeans); 
@@ -487,8 +493,18 @@ retry:
 		
 		label = ::mia::filter(GetClosestRegionLabel(RV_center), *LV_candidates);
 		lv_pixels = ::mia::filter(GetRegionSize(label), *LV_candidates);
+
+		cvinfo() << "nc= "<< nc << ", got " << lv_pixels << " LV pixels from size "
+				 << rvlv_feature->get_size().x * rvlv_feature->get_size().y << "\n";
+		
+		if (10 * lv_pixels < rvlv_feature->get_size().x * rvlv_feature->get_size().y) {
+			cvinfo() << "Found LV\n"; 
+			break;
+		}else
+			++nc; 
+		
 		
-	} while (10 * lv_pixels > rvlv_feature->get_size().x * rvlv_feature->get_size().y && nc < 7);
+	} while (nc < 7);
 	
 	if (10 * lv_pixels > rvlv_feature->get_size().x * rvlv_feature->get_size().y) {
 		cvmsg() << "LV classification failed\n"; 
@@ -521,8 +537,11 @@ retry:
 	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));
+	int csy = int(LV_center.y - r);
+	
+	crop_start = C2DBounds(int(LV_center.x - r), csy < 0 ? 0 : csy);
 
+	cvinfo() << "crop_start= "<< crop_start << "\n"; 
 	// this is ugly and should be replaced
 	if (crop_start.x > LV_center.x ||crop_start.y > LV_center.y) {
 		if (nc < 7) 
@@ -667,6 +686,15 @@ int C2DPerfusionAnalysis::get_perfusion_idx() const
 	return impl->m_cls.get_perfusion_idx();
 }
 
+int C2DPerfusionAnalysis::get_movement_idx() const
+{
+	return impl->m_cls.get_movement_idx();
+}
+
+vector<float> C2DPerfusionAnalysis::get_mixing_curve(unsigned idx) const
+{
+	return impl->m_ica->get_mixing_curve(idx); 
+}
 
 template <typename T>
 int GetClosestRegionLabel::operator() (const T2DImage<T>& image) const
@@ -743,7 +771,7 @@ P2DImage C2DPerfusionAnalysis::get_feature_image(int index) const
 }
 
 
-TDictMap<C2DPerfusionAnalysis::EBoxSegmentation>::Table segmethod_table[] ={
+static TDictMap<C2DPerfusionAnalysis::EBoxSegmentation>::Table segmethod_table[] ={
 	{"delta-feature", C2DPerfusionAnalysis::bs_delta_feature, "difference of the feature images"},
 	{"delta-peak", C2DPerfusionAnalysis::bs_delta_peak, "difference of the peak enhancement images"},
 	{"features", C2DPerfusionAnalysis::bs_features, "feature images"},      
diff --git a/mia/2d/perfusion.hh b/mia/2d/perfusion.hh
index 2853d18..178a0b5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 <vector>
 #include <mia/core/dictmap.hh>
 #include <mia/core/waveletslopeclassifier.hh>
+#include <mia/core/icaanalysisbase.hh>
 #include <mia/2d/image.hh>
 #include <mia/2d/filter.hh>
 
@@ -38,7 +39,7 @@ NS_MIA_BEGIN
    designed for the analysis of free breathingly aquired myocardial perfusion images. 
 */
 
-class  EXPORT_2D C2DPerfusionAnalysis  {
+class  EXPORT_2DMYOCARD C2DPerfusionAnalysis  {
 public: 
 	/// Possible bases for LV-RV heart segmentation
 	enum EBoxSegmentation {
@@ -68,9 +69,10 @@ public:
 	/**
 	   Run the ICA analysis - keeps a copy of the image series 
 	   \param series image series should contain more images thennumber of requested components 
+       \param icatool Generator for the used ICA analyis method
 	 */
 
-	bool run(const std::vector<C2DFImage>& series); 
+	bool run(const std::vector<C2DFImage>& series, const CICAAnalysisFactory& icatool);
 
 
 	/**
@@ -107,7 +109,7 @@ public:
 	   \param approach FICA_APPROACH_SYMM or FICA_APPROACH_DEFL
 	   \todo the parameter should be an enum
 	 */
-	void set_approach(size_t approach); 
+	void set_approach(CICAAnalysis::EApproach approach);
 
 	/**
 	   \returns the RV peak enhancement IC index of -1 if it could not be identified
@@ -144,6 +146,12 @@ public:
 	*/
 	int get_perfusion_idx() const; 
 
+        /**
+	   \returns the perfusion enhancement IC index of -1 if it could not be identified
+	*/
+	int get_movement_idx() const; 
+
+	
 	/**
 	   Dictionary for segmentation method flags 
 	 */
@@ -183,6 +191,13 @@ public:
 	 */
 	int get_RV_peak_time() const; 
 
+	/**
+	   Obtain the mixing curve of a vertain component
+	   @param idx index of the requested mixing series; 
+	   @returns the mixing curve
+	 */
+	std::vector<float> get_mixing_curve(unsigned  idx) const;
+	
 private: 
 	struct C2DPerfusionAnalysisImpl *impl; 
 
diff --git a/mia/2d/polygon.cc b/mia/2d/polygon.cc
index 22055ec..3ef2b3a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 36638bf..9974b8b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c786cbf..831495f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -283,12 +283,23 @@ double C2DPPDivcurlMatrixImpl::evaluate(const T2DDatafield<C2DDVector>& coeffici
 		
 		__m128d cjpv = cj * pv; 
 		__m128d cjpv12 = cj * pv12; 
-		cjpv12 = _mm_shuffle_pd(cjpv12, cjpv12, 0x1); 
+		cjpv12 = _mm_shuffle_pd(cjpv12, cjpv12, 0x1);
+
+		// coverity is complaining about variables of type __m128d
+		// being pointers where they are indeed to interpreted as
+		// arrays of two elements 
+		
+		// coverity[array_vs_singleton]
+		result_a = result_a + ci * cjpv;
 		
-		result_a = result_a + ci * cjpv; 
-		cjpv = cjpv + cjpv; 
+		// coverity[array_vs_singleton]
+		cjpv = cjpv + cjpv;
+		
+		// coverity[array_vs_singleton]
 		g = g + cjpv12; 
-		result_b = _mm_add_sd(result_b, _mm_mul_sd(ci, cjpv12)); 
+		result_b = _mm_add_sd(result_b, _mm_mul_sd(ci, cjpv12));
+
+		// coverity[array_vs_singleton]
 		g = g + cjpv; 
 		
 		_mm_storeu_pd(&gradient[2*p->i], g); 
diff --git a/mia/2d/ppmatrix.hh b/mia/2d/ppmatrix.hh
index 6a17ab0..e676201 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,35 +55,35 @@ public:
 	~C2DPPDivcurlMatrix(); 
 
 	/**
-	   Given this matrix P and the coefficient field c evaluate the value for c^T P c 
+	   Given this matrix P and the coefficient field c evaluate the value for \f$c^T P c\f$
 	   \param coefficients B-Spline coefficient field c 
-	   \returns <c^T, P, c>
+	   \returns \f$<c^T, P, c>\f$
 	 */
 	double operator * (const C2DFVectorfield& coefficients) const; 
 
 	/**
-	   Given this matrix P and the coefficient field c evaluate the value for c^T P c 
+	   Given this matrix P and the coefficient field c evaluate the value for \f$c^T P c\f$ 
 	   \param coefficients B-Spline coefficient field c 
-	   \returns <c^T, P, c>
+	   \returns \f$<c^T, P, c>\f$
 	 */
 	double operator * (const T2DDatafield<C2DDVector>& coefficients) const; 
 
 
 	/**
-	   Given this matrix P and the coefficient field c evaluate the value for c^T P c 
+	   Given this matrix P and the coefficient field c evaluate the value for \f$c^T P c\f$ 
 	   \param coefficients B-Spline coefficient field c 
 	   \param[out] gradient gradient of the divcurl cost 
-	   \returns <c^T, P, c>
+	   \returns \f$<c^T, P, c>\f$
 	 */
 	
 	double evaluate(const C2DFVectorfield& coefficients, CDoubleVector& gradient) const; 
 
 	/**
-	   Given this matrix P and the coefficient field c evaluate the value for c^T P c 
+	   Given this matrix P and the coefficient field c evaluate the value for \f$c^T P c\f$ 
 	   Specialization for double valued vectors 
 	   \param coefficients B-Spline coefficient field c 
 	   \param[out] gradient gradient of the divcurl cost 
-	   \returns <c^T, P, c>
+	   \returns \f$<c^T, P, c>\f$
 	*/
 	double evaluate(const T2DDatafield<C2DDVector>& coefficients, CDoubleVector& gradient) const; 
 
diff --git a/mia/2d/register.cc b/mia/2d/register.cc
index 3e4dca5..2a5b98c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5518e2d..ec71cac 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,11 +55,11 @@ public:
            \param outer_epsilon a relative cost function value per 
                 multi-grid level to stop registration
 	*/
-	C2DMultiImageRegister(size_t start_size, size_t max_iter, 
-			      C2DRegModel& model, 
-			      C2DRegTimeStep& time_step, 
-			      C2DTransformCreator& trans_factory, 
-			      float outer_epsilon); 
+	C2DMultiImageNonrigidRegister(size_t start_size, size_t max_iter, 
+				      C2DRegModel& model, 
+				      C2DRegTimeStep& time_step, 
+				      C2DTransformCreator& trans_factory, 
+				      float outer_epsilon); 
 
 	/**
 	   The registration operator that does the registration
diff --git a/mia/2d/rgbimageio.cc b/mia/2d/rgbimageio.cc
index 20ee992..bf99166 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 @@
 #include <mia/core/ioplugin.cxx>
 #include <mia/core/iohandler.cxx>
 
+#include <mia/core/msgstream.hh>
+
 
 NS_MIA_BEGIN
 using namespace std; 
@@ -35,6 +37,7 @@ CRGB2DImage::CRGB2DImage(const C2DBounds& size):
         m_size(size), 
 	m_pixels(size.x * size.y * 3)
 {
+	cvdebug() << "Allocated buffer of " << size.x * size.y * 3 << " bytes\n"; 
 }
 
 const C2DBounds& CRGB2DImage::get_size() const
@@ -62,6 +65,7 @@ template <> const char *  const
 	TPluginHandler<C2DRGBImageIOPlugin>::m_help =  
        "These plug-ins implement the support for (loading?) and storing 2D RGB images to various file types.";
 
+template class TPlugin<CRGB2DImage, io_plugin_type>; 
 template class TIOPlugin<CRGB2DImage>;
 template class THandlerSingleton<TIOPluginHandler<C2DRGBImageIOPlugin> >;
 template class TIOPluginHandler<C2DRGBImageIOPlugin>;
diff --git a/mia/2d/rgbimageio.hh b/mia/2d/rgbimageio.hh
index f7701cd..3f609af 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +83,10 @@ private:
 typedef CRGB2DImage::Pointer PRGB2DImage; 
 
 /// Base type for 2D RGB image IO plugins 
-typedef mia::TIOPlugin<CRGB2DImage> C2DRGBImageIOPlugin;
-
+typedef TIOPlugin<CRGB2DImage> C2DRGBImageIOPlugin;
 
+extern template class EXPORT_2D TPlugin<CRGB2DImage, io_plugin_type>; 
+extern template class EXPORT_2D TIOPlugin<CRGB2DImage>; 
 /**
    @ingroup io 
    \brief The 2D RGB image plugin handler 
diff --git a/mia/2d/rgbio/bmp.cc b/mia/2d/rgbio/bmp.cc
index 0e2f806..6df0f85 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -121,11 +121,114 @@ void endian_adapt_info_header(CBMPRGB2DImageIO::BMPInfoHeader& header)
 
 #endif
 
+static PRGB2DImage read_8bit_pixels_uc(CFile& image, unsigned int width, unsigned int height)
+{
+	PRGB2DImage result(new CRGB2DImage(C2DBounds(width, height))); 
+
+	unsigned load_width = ((3 * width + 3) /4) * 4; 
+	vector< unsigned char> buffer(load_width); 
+	unsigned char *pixel =  result->pixel();
+
+	cvdebug() << "Loading " << load_width << "\n"; 
+	
+	for (int y = height-1; y >= 0; --y) {
+		if (fread( &buffer[0], 1, load_width, image) != load_width){
+			throw runtime_error("BPM::Load: incomplete image");
+		}
+
+		for (unsigned x = 0; x < width; ++x) {
+
+			unsigned char *p = &pixel[3*(x + y * width)];
+			p[0] = buffer[3*x+2];
+			p[1] = buffer[3*x+1];
+			p[2] = buffer[3*x+0]; 
+		}
+	}
+	
+	return result;
+}
+
 
 CBMPRGB2DImageIO::PData CBMPRGB2DImageIO::do_load(string const& MIA_PARAM_UNUSED(filename))const
 {
-	assert(0 && "loading of RGB image not yet supported");
-	return PData();
+	int read = 0;
+	CInputFile f(filename);
+	if (!f)
+		return PData();
+
+	BMPHeader header;
+	BMPInfoHeader info_header;
+
+	cvdebug() << "CBMPRGB2DImageIO::load\n";
+
+	read = fread(&header, sizeof(BMPHeader), 1, f);
+	if (header.magic[0] != 'B' || header.magic[1] != 'M' || read != 1)
+		return PData();
+
+#ifdef WORDS_BIGENDIAN
+	endian_adapt_header(header);
+#endif
+
+	cvdebug() << "read header\n";
+
+	read = fread(&info_header, sizeof(BMPInfoHeader), 1, f);
+	if (read != 1) {
+                throw create_exception<runtime_error>("CBMPRGB2DImageIO::load: unable to read info header from '", filename, "'");
+        }
+
+	cvdebug() << "read info header";
+
+#ifdef WORDS_BIGENDIAN
+	endian_adapt_info_header(info_header);
+#endif
+	switch (info_header.size) {
+	case 40:cvdebug() << "BMP: Windows NT, 3.1x style bitmap\n"; 
+		break;
+	case 108: cvdebug() << "BMP: Windows NT 4.0, 95 style bitmap\n"; 
+		break;
+	case 124: cvdebug() << "BMP: Windows NT 5.0, 98 style bitmap\n";
+	default: 
+		throw create_exception<runtime_error>("CBMP2DImageIO::load: incompatible header size=", info_header.size);
+	}
+
+	cvdebug() << "validated info header size\n";
+
+	if ((info_header.width < 1) || (info_header.height < 1))
+		throw create_exception<runtime_error>("CBMPRGB2DImageIO::load: Image has unsupported dimensions", 
+						      " width=", info_header.width, ", height=", 
+						      info_header.height);
+	
+  
+	// this is actually a non-sense test but it should silence the Coverty warning about 
+	// the tainted variables. 
+	size_t h = info_header.height; 
+	size_t w = info_header.width; 
+	if (h > numeric_limits<unsigned>::max() || w > numeric_limits<unsigned>::max()) 
+		throw create_exception<runtime_error>("CBMPRGB2DImageIO::load: '", filename,
+						      "' Image has too big - width=",
+						      info_header.width, ", height=", 
+						      info_header.height);
+	
+	if (fseek(f, header.offset, SEEK_SET) != 0) {
+		throw create_exception<runtime_error>("CBMP2DImageIO::load: '", filename,
+						      "' ", strerror(errno)); 
+	}
+
+
+	if (!info_header.compression) {
+
+		switch (info_header.bits) {
+		case 24: return read_8bit_pixels_uc(f, info_header.width, info_header.height);
+		default: {
+			stringstream errmsg;
+			errmsg << "CBMP2DImageIO::load: unsupported pixel size: " << info_header.bits;
+			throw runtime_error(errmsg.str());
+		}
+		} // end switch
+	}else{
+		throw create_exception<runtime_error>("CBMPRGB2DImageIO::load: compressed RGB images with ",
+						      info_header.bits, " bits per pixel not supported");
+	}
 }
 
 bool CBMPRGB2DImageIO::write_header(COutputFile& f, const C2DBounds& size) const
@@ -181,7 +284,9 @@ bool CBMPRGB2DImageIO::do_save(string const& filename, const CRGB2DImage& data)
 	struct BGR {
 		unsigned char b,g,r; 
 	}; 
-	vector<BGR> buffer(data.get_size().x); 	
+	vector<BGR> buffer(data.get_size().x);
+	const unsigned  fill = (data.get_size().x * 3 + 3)/4 * 4 - 3 * data.get_size().x; 
+	
 	for (int i = data.get_size().y - 1; i >= 0 && good; --i) {
 		auto p = data.pixel() +  i * dx; 
 		for (auto b = buffer.begin(); b != buffer.end(); ++b) {
@@ -190,7 +295,10 @@ bool CBMPRGB2DImageIO::do_save(string const& filename, const CRGB2DImage& data)
 			b->b = *p++; 
 		}
 
-		good = (dx == fwrite(&buffer[0], 1, dx, f));
+		good &= (dx == fwrite(&buffer[0], 1, dx, f));
+		for (unsigned i = 0; i < fill; ++i)
+			good &= (fputc(0, f) != EOF);
+		
 	}
 	
 	cvdebug() << "CBMPRGB2DImageIO::save end\n";
diff --git a/mia/2d/rigidregister.cc b/mia/2d/rigidregister.cc
index 48aea23..b587b3d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2cd5076..b276306 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index e58cc91..e960443 100644
--- a/mia/2d/segframe.cc
+++ b/mia/2d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 @@
 #include <libxml++/libxml++.h>
 #include <boost/filesystem.hpp> 
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
+#if LIBXMLPP_VERSION < 3
+#define add_child_element add_child
+#endif
 
 NS_MIA_BEGIN
 using namespace std; 
@@ -96,7 +102,7 @@ CSegFrame::CSegFrame(const Node& node, int version):
 	}
 	m_filename = attr->get_value(); 
 	
-	Node::NodeList nodes = elm.get_children(); 
+	auto nodes = elm.get_children(); 
 	
 	for (auto i = nodes.begin(); i != nodes.end(); ++i) {
 
@@ -160,9 +166,9 @@ const CSegStar& CSegFrame::get_star() const
 }
 
 
-void CSegFrame::write(Node& node, int version) const
+void CSegFrame::write(xmlpp::Element& node, int version) const
 {
-	Element* self = node.add_child("frame"); 
+	Element* self = node.add_child_element("frame"); 
 	self->set_attribute("image", m_filename); 	
 
 	if (version > 1) {
diff --git a/mia/2d/segframe.hh b/mia/2d/segframe.hh
index f46f39d..75f3445 100644
--- a/mia/2d/segframe.hh
+++ b/mia/2d/segframe.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ public:
 	   @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;
+	void write(xmlpp::Element& node, int version) const;
 
 	/**
 	   Shift the segmentation frame and change the file name to the new name 
diff --git a/mia/2d/segpoint.cc b/mia/2d/segpoint.cc
index a5094a1..6a7e836 100644
--- a/mia/2d/segpoint.cc
+++ b/mia/2d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,15 @@
 #include <mia/core/tools.hh>
 #include <libxml++/libxml++.h>
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if LIBXMLPP_VERSION < 3
+#define add_child_element add_child
+#endif
+
+
 NS_MIA_BEGIN
 
 using namespace xmlpp;
@@ -73,8 +82,8 @@ CSegPoint2D::CSegPoint2D(float x, float 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");
+	auto *ax = elm.get_attribute ("x");
+	auto *ay = elm.get_attribute ("y");
 	if (!ax || !ay)
 		throw runtime_error("SegSection:Point attribute x or y not found");
 	
@@ -87,9 +96,9 @@ CSegPoint2D::CSegPoint2D(const Node& node)
 					     ay->get_value(), "' is not a floating point value");
 }
 
-void CSegPoint2D::write(Node& node) const
+void CSegPoint2D::write(Element& node) const
 {
-	Element* point = node.add_child("point");
+	Element* point = node.add_child_element("point");
 	point->set_attribute("y", to_string<float>(y));
 	point->set_attribute("x", to_string<float>(x));
 }
diff --git a/mia/2d/segpoint.hh b/mia/2d/segpoint.hh
index 5359e6c..be543e6 100644
--- a/mia/2d/segpoint.hh
+++ b/mia/2d/segpoint.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +66,7 @@ public:
 	/** Write the point as child-node to a given XML tree
 	    \param node 
 	*/
-	void write(xmlpp::Node& node) const;
+	void write(xmlpp::Element& node) const;
 
 	/**
 	   Tranform the point according to the given tranformation 
diff --git a/mia/2d/segsection.cc b/mia/2d/segsection.cc
index ff194a4..a9aad34 100644
--- a/mia/2d/segsection.cc
+++ b/mia/2d/segsection.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 @@
 #include <mia/2d/segsection.hh>
 #include <libxml++/libxml++.h>
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if LIBXMLPP_VERSION < 3
+#define add_child_element add_child
+#endif
 
 NS_MIA_BEGIN
 using namespace std;
@@ -40,19 +47,19 @@ CSegSection::CSegSection(const string& id, const Points& points, bool is_open):
 {
 }
 
-CSegSection::CSegSection(xmlpp::Node& node, int version):
+CSegSection::CSegSection(const 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");
+	const xmlpp::Element& elm = dynamic_cast<const xmlpp::Element&>(node);
+	auto *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");
+	auto points = node.get_children("point");
 
 	for (auto i = points.begin(); i != points.end(); ++i)
 		m_points.push_back(CSegPoint2D(**i));
@@ -97,9 +104,9 @@ void CSegSection::inv_transform(const C2DTransformation& t)
 }
 
 
-void CSegSection::write(xmlpp::Node& node, int version) const
+void CSegSection::write(xmlpp::Element& node, int version) const
 {
-	xmlpp::Element* nodeChild = node.add_child("section");
+	xmlpp::Element* nodeChild = node.add_child_element("section");
 	nodeChild->set_attribute("color", m_id);
 
 	if (version > 1) {
diff --git a/mia/2d/segsection.hh b/mia/2d/segsection.hh
index d8c314b..65dfbac 100644
--- a/mia/2d/segsection.hh
+++ b/mia/2d/segsection.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,14 @@ public:
 	   @param node root of the XML sub tree 
 	   \param version segmentation set version the node stems from. 
 	*/
-	CSegSection(xmlpp::Node& node, int version);
+	CSegSection(const 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;
+	void write(xmlpp::Element& node, int version) const;
 
 	/// \returns the ID of the section 
 	const std::string& get_id() const;
diff --git a/mia/2d/segset.cc b/mia/2d/segset.cc
index e17c5db..a19e076 100644
--- a/mia/2d/segset.cc
+++ b/mia/2d/segset.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 @@
 #include <mia/core/filetools.hh>
 #include <mia/core/tools.hh>
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if LIBXMLPP_VERSION < 3
+#define add_child_element add_child
+#endif
 
 
 NS_MIA_BEGIN
@@ -114,12 +121,12 @@ xmlpp::Document *CSegSet::write() const
 		nodeRoot->set_attribute("version", to_string<int>(m_version));
 	}
 
-	Element* description = nodeRoot->add_child("description"); 
-	Element* RVPeak = description->add_child("RVpeak"); 
+	Element* description = nodeRoot->add_child_element("description"); 
+	Element* RVPeak = description->add_child_element("RVpeak"); 
 	RVPeak->set_attribute("value", to_string<int>(m_RV_peak));
-	Element* LVPeak = description->add_child("LVpeak"); 
+	Element* LVPeak = description->add_child_element("LVpeak"); 
 	LVPeak->set_attribute("value", to_string<int>(m_LV_peak));
-	Element* PreferedRef = description->add_child("PreferedRef"); 
+	Element* PreferedRef = description->add_child_element("PreferedRef"); 
 	PreferedRef->set_attribute("value", to_string<int>(m_preferred_reference));
 
 
@@ -156,7 +163,7 @@ void CSegSet::read(const xmlpp::Document& node)
 			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), 
+            throw create_exception<invalid_argument>("Segset: Error reading frame ", distance(frames.begin(), i),
 								 ":", x.what());  
 		}
 		++i;
diff --git a/mia/2d/segset.hh b/mia/2d/segset.hh
index 9fe2ecc..00e089b 100644
--- a/mia/2d/segset.hh
+++ b/mia/2d/segset.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/segsetwithimages.cc b/mia/2d/segsetwithimages.cc
index 633362e..5bd84f1 100644
--- a/mia/2d/segsetwithimages.cc
+++ b/mia/2d/segsetwithimages.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -216,6 +216,7 @@ TPluginHandler<CSegSetWithImagesIOPlugin>::m_help =
 	"Input/output of 2D image series with segmentations.";
 
 
+template class TPlugin<CSegSetWithImages, io_plugin_type>;
 template class TIOPlugin<CSegSetWithImages>;
 template class TIOPluginHandler<CSegSetWithImagesIOPlugin>;
 template class TPluginHandler<CSegSetWithImagesIOPlugin>;
diff --git a/mia/2d/segsetwithimages.hh b/mia/2d/segsetwithimages.hh
index d2142ba..65aa9c0 100644
--- a/mia/2d/segsetwithimages.hh
+++ b/mia/2d/segsetwithimages.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +101,9 @@ private:
 
 typedef CSegSetWithImages::Pointer PSegSetWithImages; 
 
+extern template class EXPORT_2DMYOCARD TPlugin<CSegSetWithImages, io_plugin_type>;
+extern template class EXPORT_2DMYOCARD TIOPlugin<CSegSetWithImages>; 
+
 typedef TIOPlugin<CSegSetWithImages> CSegSetWithImagesIOPlugin;
 typedef THandlerSingleton< TIOPluginHandler<CSegSetWithImagesIOPlugin > > CSegSetWithImagesIOPluginHandler;
 
diff --git a/mia/2d/segstar.cc b/mia/2d/segstar.cc
index 86af9ec..adf0229 100644
--- a/mia/2d/segstar.cc
+++ b/mia/2d/segstar.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,15 @@
 #include <mia/2d/segstar.hh>
 #include <libxml++/libxml++.h>
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if LIBXMLPP_VERSION < 3
+#define add_child_element add_child
+#endif
+
+
 
 NS_MIA_BEGIN
 using namespace std;
@@ -58,7 +67,7 @@ CSegStar::CSegStar(const xmlpp::Node& n)
 
 
 	m_center = CSegPoint2D(node);
-	xmlpp::Attribute *rx = node.get_attribute ("r");
+	auto rx = node.get_attribute ("r");
 	if (!rx)
 		throw runtime_error("CSegStar: attribute r not found");
 
@@ -67,16 +76,15 @@ CSegStar::CSegStar(const xmlpp::Node& n)
 
 	cvdebug() << "Got star center (" << m_center.x << ", " << m_center.y << " @ " << m_radius << ")\n";
 
-	xmlpp::Node::NodeList points = node.get_children("point");
+	auto 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);
+	for (auto i = points.begin(); i != points.end(); ++i, ++k) {
+		auto& node = dynamic_cast<const xmlpp::Element&>(**i);
 		m_directions[k] = CSegPoint2D(node);
 	}
 }
@@ -164,9 +172,9 @@ void CSegStar::inv_transform(const C2DTransformation& t)
 	recenter_rays();
 }
 
-void CSegStar::write(xmlpp::Node& node) const
+void CSegStar::write(xmlpp::Element& node) const
 {
-	xmlpp::Element* nodeChild = node.add_child("star");
+	auto nodeChild = node.add_child_element("star");
 
 	nodeChild->set_attribute("y", to_string<float>(m_center.y));
 	nodeChild->set_attribute("x", to_string<float>(m_center.x));
diff --git a/mia/2d/segstar.hh b/mia/2d/segstar.hh
index 7f39590..af09db5 100644
--- a/mia/2d/segstar.hh
+++ b/mia/2d/segstar.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ public:
 	   write the CSegStar info to a XML node 
 	   @param node root node to add the info to 
 	 */
-	void write(xmlpp::Node& node) const;
+	void write(xmlpp::Element& node) const;
 
 	/**
 	   Shift the segmentation data 
diff --git a/mia/2d/shape.cc b/mia/2d/shape.cc
index a230835..417e1c8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/shape.hh b/mia/2d/shape.hh
index 3c30055..de3679a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1eecc26..6d389a6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8d58138..64410c0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 85180ab..dcae2cf 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 41d58d8..a8e86a5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2d1d6dc..9d84ea2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 23012ca..6d4f684 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 465d421..a059e1f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4d72f84..064b30f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5afe7e6..244a6ce 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2ec8316..37bedb9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 977fdd7..b3ea7e5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8ced76d..a5f6024 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/sparse_image_solver.hh
index 903da14..9952861 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3f4ddfa..2017f7d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/splinepenalty/divcurl.hh
index 7ebd508..cedbb1a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_divcurl.cc b/mia/2d/splinepenalty/test_divcurl.cc
index 37ef99f..f530413 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/splinetransformpenalty.cc b/mia/2d/splinetransformpenalty.cc
index e4edd9f..f93a50a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/splinetransformpenalty.hh b/mia/2d/splinetransformpenalty.hh
index 5c1d29b..05ca60b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_2d.cc b/mia/2d/test_2d.cc
index 506e6be..d360e29 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 12cea1c..1f75e34 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 154fa54..2b853e3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_combiner.cc b/mia/2d/test_combiner.cc
index 8202f8b..578c40f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 426573d..e4a1c21 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e3aa77c..69e30fd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_datafield.cc b/mia/2d/test_datafield.cc
index e5e809e..58d0fb5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 22b405d..c31b859 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -103,7 +103,7 @@ BOOST_AUTO_TEST_CASE( test_distance_from_inf )
 
 	C2DFImage src_img(C2DBounds(4,4)); 
 	
-	distance_transform_prepare(&in_2d[0], &in_2d[16],src_img.begin()); 
+	distance_transform_prepare(&in_2d[0], &in_2d[16],src_img.begin(), true); 
 	
 	C2DFImage result =  distance_transform(src_img); 
 
@@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE( test_distance_from_func)
 
 	C2DFImage src_img(C2DBounds(4,4)); 
 
-	distance_transform_prepare(&in_2d[0], &in_2d[16],src_img.begin()); 
+	distance_transform_prepare(&in_2d[0], &in_2d[16],src_img.begin(), false); 
 	
 	C2DFImage result =  distance_transform(src_img); 
 
diff --git a/mia/2d/test_divcurlmatrix.cc b/mia/2d/test_divcurlmatrix.cc
index 0b32a15..99fd041 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 209fda3..d0964b0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +43,9 @@ BOOST_AUTO_TEST_CASE(test_available_filters)
 	set<string> test_data = {
 		"adaptmed", "admean", "aniso", "bandpass", "binarize", "close", "combiner", "convert", "crop", 
 		"dilate", "distance", "downscale", "erode", "gauss", "gradnorm", "invert", "kmeans", 
-		"label", "labelmap", "labelscale", "load", "mask", "mean", "median", "mlv", "ngfnorm", "noise", "open",
-		"pruning", "regiongrow", "sandp", "scale", "selectbig", "sepconv", "shmean", "sobel", "sort-label", 
-		"sws", "tee", "thinning", "thresh", "transform", "ws"};
+		"label", "labelmap", "labelscale", "load", "mask", "mean", "meanvar", "median", "medianmad", "mlv", "ngfnorm",
+		"noise", "open", "pruning", "regiongrow", "sandp", "scale", "selectbig", "sepconv", "shmean",
+		"sobel", "sort-label", "sws", "tee", "thinning", "thresh", "tmean", "transform", "ws"};
 
 #ifdef HAVE_MAXFLOW
 	test_data.insert("maxflow"); 
@@ -108,3 +108,100 @@ BOOST_AUTO_TEST_CASE(test_chain_filters)
 	}
 }
 
+
+BOOST_AUTO_TEST_CASE(test_filters_chain_push_font_and_back)
+{
+	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); 
+
+	C2DImageFilterChain chain(NULL, 0);
+
+	BOOST_CHECK(chain.empty()); 
+
+	chain.push_back("binarize:min=100,max=200");
+	chain.push_front("bandpass:min=1,max=150");
+	chain.push_back("convert:repn=ushort,map=linear,b=2,a=3");
+	
+	auto testimg = chain.run(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; 
+	}
+}
+
+BOOST_AUTO_TEST_CASE(test_filters_chain_init_from_vector)
+{
+	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); 
+
+	vector<string> filter_descr({"bandpass:min=1,max=150",
+				"binarize:min=100,max=200",
+				"convert:repn=ushort,map=linear,b=2,a=3"}); 
+
+	C2DImageFilterChain chain(filter_descr);
+	
+	auto testimg = chain.run(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; 
+	}
+}
+
+BOOST_AUTO_TEST_CASE(test_filters_chain_init_from_cstring_array)
+{
+	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); 
+	
+	const char *filter_descr[] = {"bandpass:min=1,max=150",
+				      "binarize:min=100,max=200",
+				      "convert:repn=ushort,map=linear,b=2,a=3"};
+	
+	C2DImageFilterChain chain(filter_descr, 3);
+	
+	auto testimg = chain.run(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 dfb1b37..1b76ae1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a0e0ab7..4c4af54 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_mi_spline.cc b/mia/2d/test_fullcost_mi_spline.cc
index d26324b..28b8e0a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_groundtruthproblem.cc b/mia/2d/test_groundtruthproblem.cc
index dce6643..5409753 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ica.cc b/mia/2d/test_ica.cc
index bf0524c..35770e4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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/2d/transform.hh>
 #include <mia/internal/autotest.hh>
 
+#include <mia/core/ica.hh>
 #include <mia/2d/ica.hh>
 
 using namespace mia;
@@ -43,13 +44,13 @@ protected:
 BOOST_AUTO_TEST_CASE ( test_empty_initialization )
 {
 	vector<C2DFImage> series;
-	BOOST_CHECK_THROW( C2DImageSeriesICA s(series, false), invalid_argument);
+    BOOST_CHECK_THROW( C2DImageSeriesICA s(CICAAnalysisITPPFactory(), series, false), invalid_argument);
 }
 
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean, ICASeriesFixture )
 {
-	C2DImageSeriesICA ica(image_set, false);
+    C2DImageSeriesICA ica(CICAAnalysisITPPFactory(), image_set, false);
 
 	ica.run(3, false, false);
 
@@ -66,7 +67,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean, ICASeriesFixture )
 
 BOOST_FIXTURE_TEST_CASE( test_ica_imcomplete_mix, ICASeriesFixture )
 {
-	C2DImageSeriesICA ica(image_set, false);
+    C2DImageSeriesICA ica(CICAAnalysisITPPFactory(),image_set, false);
 	C2DImageSeriesICA::IndexSet skip;
 	skip.insert(0);
 	skip.insert(1);
@@ -88,7 +89,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_imcomplete_mix, ICASeriesFixture )
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_stripped_series_mean, ICASeriesFixture )
 {
-	C2DImageSeriesICA ica(image_set, true);
+    C2DImageSeriesICA ica(CICAAnalysisITPPFactory(),image_set, true);
 
 	ica.run(3, false, false);
 
@@ -105,7 +106,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_stripped_series_mean, ICASeriesFixture )
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp, ICASeriesFixture )
 {
-	C2DImageSeriesICA ica(image_set, true);
+    C2DImageSeriesICA ica(CICAAnalysisITPPFactory(),image_set, true);
 
 	ica.run(4, false, false);
 
@@ -122,7 +123,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp, ICASeriesFixture )
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_stripped_and_normalized, ICASeriesFixture )
 {
-	C2DImageSeriesICA ica(image_set, true);
+    C2DImageSeriesICA ica(CICAAnalysisITPPFactory(),image_set, true);
 
 	ica.run(4, true, true);
 
@@ -139,7 +140,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_stripped_and_normalized,
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_normalized, ICASeriesFixture )
 {
-	C2DImageSeriesICA ica(image_set, false);
+    C2DImageSeriesICA ica(CICAAnalysisITPPFactory(),image_set, false);
 
 	ica.run(4, true, true);
 
@@ -156,7 +157,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_normalized, ICASeriesFixt
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_normalized2, ICASeriesFixture )
 {
-	C2DImageSeriesICA ica(image_set, false);
+    C2DImageSeriesICA ica(CICAAnalysisITPPFactory(),image_set, false);
 
 	ica.run(4, true, true);
 
@@ -173,7 +174,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_normalized2, ICASeriesFix
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_mix_normalized, ICASeriesFixture )
 {
-	C2DImageSeriesICA ica(image_set, false);
+    C2DImageSeriesICA ica(CICAAnalysisITPPFactory(),image_set, false);
 
 	ica.run(4,  true, false);
 
@@ -190,7 +191,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_mix_normalized, ICASeries
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_none, ICASeriesFixture )
 {
-	C2DImageSeriesICA ica(image_set, false);
+    C2DImageSeriesICA ica(CICAAnalysisITPPFactory(),image_set, false);
 
 	ica.run(4, false, false);
 	for (size_t i = 0; i < slices; ++i) {
@@ -217,7 +218,7 @@ BOOST_AUTO_TEST_CASE( test_ica_mean_substract )
 	images.push_back(C2DFImage(size, init_image1));
 	images.push_back(C2DFImage(size, init_image2));
 
-	C2DImageSeriesICA ica(images, true);
+    C2DImageSeriesICA ica(CICAAnalysisITPPFactory(),images, true);
 
 	const C2DFImage& mean = ica.get_mean_image();
 
diff --git a/mia/2d/test_image.cc b/mia/2d/test_image.cc
index c003029..698b1f2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -126,3 +126,26 @@ BOOST_AUTO_TEST_CASE( check_gradient )
 
 }
 
+BOOST_AUTO_TEST_CASE( check_comparison )
+{
+	C2DBounds size(1,2); 
+	C2DFImage fimage(size, {1.0f, 2.0f});
+	C2DUBImage ubimage(size);
+	C2DUBImage ubimage2(C2DBounds(2,2));
+	C2DFImage fimage2(fimage);
+
+	BOOST_CHECK(fimage == fimage2);
+	fimage2(0,0) = 3.0;
+	// data is still shared!!
+	BOOST_CHECK(fimage == fimage2);
+	
+	fimage2.make_single_ref(); 
+	fimage2(0,0) = 4.0;
+	BOOST_CHECK(fimage != fimage2);
+
+	BOOST_CHECK(fimage != ubimage);
+	BOOST_CHECK(ubimage != ubimage2);
+
+	
+	
+}
diff --git a/mia/2d/test_imagecostbase.cc b/mia/2d/test_imagecostbase.cc
index 1b0664e..e8ebc8f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 53b1333..15ca418 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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/attribute_names.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/2d/imageio.hh>
+#include <mia/2d/rgbimageio.hh>
 
 NS_MIA_USE
 using namespace std; 
@@ -98,3 +99,250 @@ BOOST_AUTO_TEST_CASE( test_load_series )
 	
 }
 
+
+BOOST_AUTO_TEST_CASE( test_load_bmp_8_uncompressed )
+{
+	string filename(MIA_SOURCE_ROOT"/testdata/gray2x3.bmp");
+
+	auto test_image = load_image2d(filename);
+
+	const C2DUBImage& img = dynamic_cast<const C2DUBImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img(0,0),   0u);
+	BOOST_CHECK_EQUAL(img(1,0),  63u);
+	BOOST_CHECK_EQUAL(img(0,1), 128u);
+	BOOST_CHECK_EQUAL(img(1,1), 190u);
+	BOOST_CHECK_EQUAL(img(0,2), 229u);
+	BOOST_CHECK_EQUAL(img(1,2), 255u);
+
+	save_image("test_image-8u.bmp", test_image);
+
+	auto test2_image = load_image2d("test_image-8u.bmp");
+	
+	const C2DUBImage& img2 = dynamic_cast<const C2DUBImage&>(*test2_image); 
+	BOOST_CHECK_EQUAL(img2.get_size().x, 2u);
+	BOOST_CHECK_EQUAL(img2.get_size().y, 3u);
+
+	BOOST_CHECK_EQUAL(img2(0,0),   0u);
+	BOOST_CHECK_EQUAL(img2(1,0),  63u);
+	BOOST_CHECK_EQUAL(img2(0,1), 128u);
+	BOOST_CHECK_EQUAL(img2(1,1), 190u);
+	BOOST_CHECK_EQUAL(img2(0,2), 229u);
+	BOOST_CHECK_EQUAL(img2(1,2), 255u);
+
+	unlink("test_image-8u.bmp"); 
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_load_bmp_8_compressed )
+{
+	auto test_image = load_image2d(MIA_SOURCE_ROOT"/testdata/gray100x2c.bmp");
+
+	const C2DUBImage& img = dynamic_cast<const C2DUBImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 100u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 2u);
+
+	auto p = img.begin(); 
+	
+	for (unsigned x = 0; x < 52; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 163u);
+	
+	for (unsigned x = 52; x < 100; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 139u); 
+
+	for (unsigned x = 0; x < 47; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 100u); 
+	for (unsigned x = 47; x < 100; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 211u); 
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_load_bmp_4bit_compressed )
+{
+	auto test_image = load_image2d(MIA_SOURCE_ROOT"/testdata/gray100x2c-4bit.bmp");
+
+	const C2DUBImage& img = dynamic_cast<const C2DUBImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 100u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 2u);
+
+	auto p = img.begin(); 
+	
+	for (unsigned x = 0; x < 52; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 2u);
+
+	BOOST_CHECK_EQUAL(*p++, 1u);
+	BOOST_CHECK_EQUAL(*p++, 3u);
+	BOOST_CHECK_EQUAL(*p++, 1u);
+	BOOST_CHECK_EQUAL(*p++, 0u);
+	BOOST_CHECK_EQUAL(*p++, 1u);
+	BOOST_CHECK_EQUAL(*p++, 0u);
+
+	
+	for (unsigned x = 58; x < 100; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 1u); 
+
+	for (unsigned x = 0; x < 47; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 0u);
+
+	
+	for (unsigned x = 47; x < 100; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 3u); 
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_load_bmp_4bit_uncompressed )
+{
+	auto test_image = load_image2d(MIA_SOURCE_ROOT"/testdata/gray100x2uc-4bit.bmp");
+
+	const C2DUBImage& img = dynamic_cast<const C2DUBImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 100u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 2u);
+
+	auto p = img.begin(); 
+	
+	for (unsigned x = 0; x < 52; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 2u);
+	
+	for (unsigned x = 52; x < 100; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 1u); 
+
+	for (unsigned x = 0; x < 47; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 0u); 
+	for (unsigned x = 47; x < 100; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 3u); 
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_bmp_1bit_uc )
+{
+	auto test_image = load_image2d(MIA_SOURCE_ROOT"/testdata/binary100x2uc.bmp");
+
+	const C2DBitImage& img = dynamic_cast<const C2DBitImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 100u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 2u);
+
+	auto p = img.begin(); 
+	
+	for (unsigned x = 0; x < 55; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 0u);
+
+	BOOST_CHECK_EQUAL(*p++, 1u);
+	BOOST_CHECK_EQUAL(*p++, 0u);
+	BOOST_CHECK_EQUAL(*p++, 1u);
+
+	
+	for (unsigned x = 58; x < 100; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 0u); 
+
+	for (unsigned x = 0; x < 47; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 1u);
+
+	
+	for (unsigned x = 47; x < 100; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 0u); 
+
+
+	save_image("test_image-bit.bmp", test_image);
+
+	auto test2_image = load_image2d("test_image-bit.bmp");
+
+
+	const C2DBitImage& img2 = dynamic_cast<const C2DBitImage&>(*test2_image); 
+	BOOST_CHECK_EQUAL(img2.get_size().x, 100u);
+	BOOST_CHECK_EQUAL(img2.get_size().y, 2u);
+
+	p = img2.begin(); 
+	
+	for (unsigned x = 0; x < 55; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 0u);
+
+	BOOST_CHECK_EQUAL(*p++, 1u);
+	BOOST_CHECK_EQUAL(*p++, 0u);
+	BOOST_CHECK_EQUAL(*p++, 1u);
+
+	
+	for (unsigned x = 58; x < 100; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 0u); 
+
+	for (unsigned x = 0; x < 47; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 1u);
+
+	
+	for (unsigned x = 47; x < 100; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 0u); 
+
+	unlink("test_image-bit.bmp"); 
+}
+
+BOOST_AUTO_TEST_CASE( test_load_bmp_8_compressed_with_jumps )
+{
+	// this test should check whether the jump inside a bitmap file is propperly
+	// executed, but currently the image is not encoded with such a jump. 
+	
+	auto test_image = load_image2d(MIA_SOURCE_ROOT"/testdata/gray20x20c.bmp");
+
+	const C2DUBImage& img = dynamic_cast<const C2DUBImage&>(*test_image); 
+	BOOST_CHECK_EQUAL(img.get_size().x, 20u);
+	BOOST_CHECK_EQUAL(img.get_size().y, 20u);
+
+	auto p = img.begin(); 
+	unsigned x; 
+	for (x = 0; x < 9; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 99u);
+
+	for (; x < 8*20+6; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 0u);
+
+	for (; x < 9*20; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 121u);
+	
+	for (; x < 14*20; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 0u);
+
+	for (; x < 14*20 + 10; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 138u);
+	
+	for (; x < 20*20; ++x, ++p)
+		BOOST_CHECK_EQUAL(*p, 0u); 
+
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_rgb8_bmp )
+{
+	
+        vector<unsigned char> test_data{206, 89, 97, 71, 99, 67, 192, 205, 52,
+                        28, 31, 98, 94, 27, 204, 232, 18, 214};
+        
+        const auto& io = C2DRGBImageIOPluginPluginHandler::instance(); 
+
+        auto test_image = io.load(MIA_SOURCE_ROOT"/testdata/rgb3x2-24bit.bmp");
+
+        const CRGB2DImage& img = *test_image;
+
+        BOOST_CHECK_EQUAL(img.get_size().x, 3);
+        BOOST_CHECK_EQUAL(img.get_size().y, 2);
+        
+        auto pixels = img.pixel();
+        for (int i = 0; i < 18; ++i) {
+		cvdebug() << i << ":" <<  (int)pixels[i] << " exp " << (int)test_data[i] << "\n"; 
+                BOOST_CHECK_EQUAL(pixels[i], test_data[i]); 
+        }
+
+        BOOST_REQUIRE(save_image("test_image_rgb.bmp", *test_image));
+        
+        auto test_image2 = io.load("test_image_rgb.bmp");
+
+        const CRGB2DImage& img2 = *test_image2;
+
+        BOOST_CHECK_EQUAL(img2.get_size().x, 3);
+        BOOST_CHECK_EQUAL(img2.get_size().y, 2);
+        
+        pixels = img2.pixel();
+        for (int i = 0; i < 18; ++i) {
+                BOOST_CHECK_EQUAL(pixels[i], test_data[i]); 
+        }
+
+        unlink("test_image_rgb.bmp"); 
+}
diff --git a/mia/2d/test_interpol.cc b/mia/2d/test_interpol.cc
index eae4377..cdb91ca 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -137,7 +137,7 @@ void test_deformadd()
 	C2DUSImage *fimage = new C2DUSImage(size);
 	P2DImage image(fimage);
 
-	std::shared_ptr<C2DInterpolatorFactory > ipf(create_2dinterpolation_factory(ip_linear, bc_mirror_on_bounds));
+	C2DInterpolatorFactory ipf("bspline:d=1", "mirror");
 
 	C2DFVectorfield A(size);
 	C2DFVectorfield B(size);
@@ -158,12 +158,12 @@ void test_deformadd()
 		}
 	}
 
-	P2DImage im = filter(FDeformer2D(A, *ipf), *image);
-	P2DImage result_add = filter(FDeformer2D(B, *ipf), *im);
+	P2DImage im = filter(FDeformer2D(A, ipf), *image);
+	P2DImage result_add = filter(FDeformer2D(B, ipf), *im);
 
 	A += B;
 
-	P2DImage result_direct = filter(FDeformer2D(A, *ipf), *image);
+	P2DImage result_direct = filter(FDeformer2D(A, ipf), *image);
 
 	if (!filter_equal(FCompareImages(), *result_direct, *result_add)) {
 		if (!save(image, "original.png") ||
diff --git a/mia/2d/test_iterator.cc b/mia/2d/test_iterator.cc
index e5d73f3..5191982 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_matrix.cc b/mia/2d/test_matrix.cc
index 3d2015f..7b4a2d8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 53f876b..0b63e41 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_morphshape.cc b/mia/2d/test_morphshape.cc
index c3d87d3..e1b7b7b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 33b6573..04d86a3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d01a1e6..78a555a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 73ff20e..6e87135 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_param.cc b/mia/2d/test_param.cc
index 631fadf..c624c52 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 636a12e..e51d882 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,308 @@
 
 
 #include <mia/2d/perfusion.hh>
+#include <mia/core/ica.hh>
 
 NS_MIA_USE
+using std::vector; 
 
 BOOST_AUTO_TEST_CASE( test_instance ) 
 {
 	C2DPerfusionAnalysis pa(0, true, true); 
+}
+
+extern const vector<float> LV_init;
+extern const vector<float> RV_init;
+extern const vector<float>  MOV_init;
+extern const vector<float> PERF_init;
+extern const vector<float> BG_init;
+
+extern const vector<float> LV_mix;
+extern const vector<float> RV_mix;
+extern const vector<float> MOV_mix;
+extern const vector<float> PERF_mix;
+extern const vector<float> BG_mix;
+
+const unsigned nframes = 64;
+const unsigned ncomponents = 5; 
+
+const float LV_scale = 5;
+const float RV_scale = 5;
+const float MOV_scale = 7;
+const float PERF_scale = 3;
+const float BG_scale = 1;
+
+extern const vector<float> mix[]; 
+extern const vector<float> init[]; 
+
+const float scale[5] = {
+	BG_scale, LV_scale, RV_scale, MOV_scale, PERF_scale
+}; 
+
+
+/**
+   This checks the scalar prduct to see whether the stwo series are 
+   (mostly) parallel. 
+*/
+template <typename T> 
+void check_scalar_product(const vector<float>& prototype,
+			  const T& value, float tol)
+{
+	float sump2 = 0.0f;
+	float sumv2 = 0.0f;
+	float sumpv = 0.0f;
+
+	BOOST_CHECK_EQUAL(prototype.size(), value.size());
+
+	for (unsigned i = 0; i < prototype.size(); ++i) {
+		const float p =  prototype[i];
+		const float v =  value[i];
 
+		sump2 += p*p;
+		sumv2 += v*v;
+		sumpv += p * v; 
+	}
 
+	BOOST_REQUIRE(sump2 > 0.1);
+	BOOST_REQUIRE(sumv2 > 0.1);
+
+	const float dot_normal = fabsf(sumpv) / (sump2 * sumv2); 
+	cvdebug() << "dot_normal = " << dot_normal << "\n";
+	
+	BOOST_CHECK_SMALL(dot_normal, tol);   
+	
+}
+
+void check_scalar_product_with_image(const vector<float>& prototype,
+				     const C2DImage& img, float tol)
+{
+	const C2DFImage& fimage = dynamic_cast<const C2DFImage&>(img);
+	check_scalar_product(prototype, fimage, tol); 
 }
+
+void check_pa(const C2DPerfusionAnalysis& pa)
+{
+	BOOST_CHECK(pa.has_movement()); 
+	BOOST_CHECK_EQUAL(pa.get_RV_peak_time(), 7);
+	BOOST_CHECK_EQUAL(pa.get_LV_peak_time(), 15);
+
+	BOOST_CHECK(pa.get_RV_idx() >= 0);
+	BOOST_CHECK(pa.get_LV_idx() >= 0);
+	BOOST_CHECK(pa.get_perfusion_idx() >= 0); 
+	BOOST_CHECK(pa.get_movement_idx() >= 0);
+
+	// this test checks how much the obtained mixing curve deviates from the
+	// original 0.1 means ~5 degree off 
+	check_scalar_product(LV_mix, pa.get_mixing_curve(pa.get_LV_idx()), 0.01);
+	check_scalar_product(RV_mix, pa.get_mixing_curve(pa.get_RV_idx()), 0.01);
+	check_scalar_product(PERF_mix, pa.get_mixing_curve(pa.get_perfusion_idx()), 0.01);
+	check_scalar_product(MOV_mix, pa.get_mixing_curve(pa.get_movement_idx()), 0.01); 
+
+	check_scalar_product_with_image(LV_init, *pa.get_feature_image(pa.get_LV_idx()), 0.01);
+	check_scalar_product_with_image(RV_init, *pa.get_feature_image(pa.get_RV_idx()), 0.01);
+	check_scalar_product_with_image(PERF_init, *pa.get_feature_image(pa.get_perfusion_idx()), 0.01);
+	check_scalar_product_with_image(MOV_init, *pa.get_feature_image(pa.get_movement_idx()), 0.01); 
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_series_with_movement_fixed_componenets )
+{
+	C2DBounds size(16,16);
+	C2DFImage prototype(size);
+	prototype.set_pixel_size(C2DFVector(4, 4)); 
+	std::vector<C2DFImage> series(nframes, prototype);
+
+	
+	for (unsigned i = 0; i < nframes; ++i) {
+		for (unsigned k = 0; k < ncomponents; ++k) {
+			const vector<float>& m = mix[k]; 
+			float mix_factor = m[i] * scale[k];
+			transform(init[k].begin(), init[k].end(), series[i].begin(), series[i].begin(),
+				  [mix_factor](float comp, float pixel) {
+					  return comp * mix_factor + pixel; 
+				  }); 
+		}
+	}
+	
+	CICAAnalysisITPPFactory ica_factory;
+	
+	C2DPerfusionAnalysis pa(5, true, true);
+
+	BOOST_CHECK(pa.run(series, ica_factory));
+	check_pa(pa);
+
+	C2DBounds crop_start;
+	P2DFilter crop_filter = pa.get_crop_filter(1.0, crop_start, C2DPerfusionAnalysis::bs_delta_feature); 
+	BOOST_REQUIRE(crop_filter);
+	
+#if 0 // this is a very shaky test, probably depends on the BLAS library used with it++ 
+	BOOST_CHECK_EQUAL(crop_start.x, 2);
+	BOOST_CHECK_EQUAL(crop_start.y, 0); 
+#endif 	
+	C2DPerfusionAnalysis pa0(0, true, true);
+	BOOST_CHECK(pa0.run(series, ica_factory));
+	check_pa(pa0); 
+}
+
+const vector<float>  LV_mix = {
+	-4, -4, -4, -4, -4, -4, -4, -4,
+	-4, -4, -4, -4, -1,  4, 10, 20,
+	18, 16, 14, 12, 10,  9,  8,  7,
+	 6,  6,  5,  5,  4,  4,  4,  3,
+	 3,  3,  3,  2,  2,  2,  2,  1,
+	 1,  1,  1,  0,  0,  0,  0,  0,
+	-1, -1, -1, -1, -2, -2, -2, -2,
+	-3, -3, -3, -3, -4, -4, -4, -4
+}; 
+
+const vector<float>  RV_mix = {
+	-4, -4,  -4, -4,  2,  8,  10,  25,
+	18, 16,  14, 13, 13, 12,  12,  11,
+	11, 10, 10,   9,  9,  8,   8,   7, 
+	 7,  7,  6,   6,  6,  5,   5,   5,
+	 4,  4,  4,   4,  3,  3,   2,   2,
+  	 2,  1,  1,   1,  0,  0,   0,   0,
+	-1, -1, -1,  -1, -2, -2,  -2,  -2,
+	-3, -3,	-3,  -3, -4, -4,  -4,  -4 
+}; 
+
+
+const vector<float>  MOV_mix = {
+	-4, -3,  0,  3,  4,  3,   0,  -3,
+	-4, -3,  0,  3,  4,  3,   0,  -3,
+	-4, -3,  0,  3,  4,  3,   0,  -3,
+	-4, -3,  0,  3,  4,  3,   0,  -3,
+	-4, -3,  0,  3,  4,  3,   0,  -3,
+	-4, -3,  0,  3,  4,  3,   0,  -3,
+	-4, -3,  0,  3,  4,  3,   0,  -3,
+	-4, -3,  0,  3,  4,  3,   0,  -3
+}; 
+
+const vector<float> PERF_mix = {
+	-4, -4, -4, -4, -4, -4, -4, -4,
+	-4, -4, -4, -4, -4, -4, -4, -4,
+	-4, -4, -4, -4, -4, -4, -4, -4,
+	-4, -4, -4, -4, -4, -4, -4, -3,
+	-3, -3, -3, -2, -2, -2, -1, -1,
+	-1, -1,  0,  0,  0,  1,  1,  1,
+	 2,  2,  2,  2,  3,  3,  3,  3, 
+	 3,  4,  4,  4,  4,  4,  4,  4
+}; 
+
+const vector<float>  BG_mix = {
+	-1, -1, -1,  0,  1, -1,  0,  0,
+	 1,  0,  1,  1,  0, -1,  1, -1,
+	 0,  0,  1, -1,  1,  0,  1, -1,
+	-1,  1,  1, -1,  1,  0,  0, -1,
+	-1,  0,  1,  1,  0, -1,  1,  1,
+	-1, -1,  0,  0,  0,  1,  1,  1,
+	-1,  1, -1,  0,  1,  0,  1,  0,
+	 0,  0,  1,  1, -1, -1,  1,  1
+}; 
+
+const vector<float>  LV_init = {
+
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 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, 1, 1, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 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 vector<float>  RV_init = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 1, 1, 1, 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, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 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 vector<float>  MOV_init = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0,
+	0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0,
+	0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0,
+	0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0,
+	0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0,
+	0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0,
+	0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 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 vector<float>  PERF_init = {
+
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	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, 1, 1, 1, 1, 1, 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, 1, 0, 0, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 1, 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, 1, 0, 0, 0, 0, 0, 1, 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, 1, 1, 1, 1, 1, 1, 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, 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 vector<float>  BG_init = {
+
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
+	0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+	0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+	0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+	0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+	0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
+	0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0,
+	0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0,
+	0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
+	0, 1, 1, 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, 1, 1, 1, 0,
+	0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+	0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0,
+	0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+const vector<float> mix[5] = {
+	BG_mix, LV_mix, RV_mix, MOV_mix, PERF_mix
+}; 
+
+const vector<float> init[5] = {
+	BG_init, LV_init, RV_init, MOV_init, PERF_init
+}; 
diff --git a/mia/2d/test_polygon.cc b/mia/2d/test_polygon.cc
index 5dca688..105ff0b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 77aae8a..e999aaa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,16 +25,18 @@
 
 NS_MIA_USE;
 
+using std::string;
+
 struct TransformSplineFixtureFieldBase {
 	TransformSplineFixtureFieldBase()
 	{
 
 	}
-	void init(int dsize, float range, EInterpolation type) {
-		init2d(T2DVector<int>(dsize,dsize), range, type); 
+	void init(int dsize, float range, const string& kernel) {
+		init2d(T2DVector<int>(dsize,dsize), range, kernel); 
 	}
-	void init2d(const T2DVector<int>& dsize, float range, EInterpolation type) {
-		ipf.reset(create_2dinterpolation_factory(type, bc_mirror_on_bounds));
+	void init2d(const T2DVector<int>& dsize, float range, const std::string& kernel) {
+		ipf.reset(new C2DInterpolatorFactory(kernel, "mirror"));
 		size = C2DBounds(2 * dsize.x + 1,2 * dsize.y + 1);
 		field = C2DFVectorfield(size);
 		scale.x = range / dsize.x;
@@ -73,19 +75,19 @@ private:
 
 
 struct TransformSplineFixtureConst: public TransformSplineFixtureFieldBase {
-	void prepare(int dsize, float range, EInterpolation type, float fx, float fy); 
+	void prepare(int dsize, float range, const std::string& kernel, float fx, float fy); 
 	virtual float fx(float x, float y);
 	virtual float fy(float x, float y);
 private: 
 	C2DFVector m_f; 
 };
 
-void TransformSplineFixtureConst::prepare(int dsize, float range, EInterpolation type, float fx, float fy)
+void TransformSplineFixtureConst::prepare(int dsize, float range, const std::string& kernel, float fx, float fy)
 {
 	m_f.x = fx; 
 	m_f.y = fy; 
 
-	init(dsize, range, type); 
+	init(dsize, range, kernel); 
 }
 
 float TransformSplineFixtureConst::fx(float , float )
@@ -139,20 +141,20 @@ struct TransformSplineFixtureCurlOnly: public TransformSplineFixtureFieldBase {
 
 
 struct TransformSplineFixtureexpm2Field_44: public TransformSplineFixtureexpm2Field {
-	void run(int dsize, float range, EInterpolation type, double corr=1.0); 
+	void run(int dsize, float range, const string& type, double corr=1.0); 
 }; 
 
 struct TransformSplineFixtureexpm2testInterp : public TransformSplineFixtureexpm2Field {
-	void run(int dsize, float range, EInterpolation type); 
+	void run(int dsize, float range, const string& type); 
 }; 
 
 
 BOOST_FIXTURE_TEST_CASE( test_nocurl_bspline3, TransformSplineFixtureDivOnly )
 {
-	init(16, 4, ip_bspline4);
+	init(16, 4, "bspline:d=4");
 
 	const T2DConvoluteInterpolator<C2DFVector>& interp = 
-		dynamic_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
+		static_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double testvalue = 6.0 * M_PI;
@@ -169,10 +171,10 @@ BOOST_FIXTURE_TEST_CASE( test_nocurl_bspline3, TransformSplineFixtureDivOnly )
 
 BOOST_FIXTURE_TEST_CASE( test_nocurl_bspline3_noniso, TransformSplineFixtureDivOnly )
 {
-	init2d(T2DVector<int>(32, 14), 4, ip_bspline4);
+	init2d(T2DVector<int>(32, 14), 4, "bspline:d=4");
 
 	const T2DConvoluteInterpolator<C2DFVector>& interp = 
-		dynamic_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
+		static_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double testvalue = 6.0 * M_PI;
@@ -190,10 +192,10 @@ BOOST_FIXTURE_TEST_CASE( test_nocurl_bspline3_noniso, TransformSplineFixtureDivO
 
 BOOST_FIXTURE_TEST_CASE( test_nocurl_bspline3_8_4, TransformSplineFixtureDivOnly )
 {
-	init(8, 4, ip_bspline4);
+	init(8, 4, "bspline:d=4");
 
 	const T2DConvoluteInterpolator<C2DFVector>& interp = 
-		dynamic_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
+		static_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double testvalue = 6.0 * M_PI;
@@ -210,10 +212,10 @@ BOOST_FIXTURE_TEST_CASE( test_nocurl_bspline3_8_4, TransformSplineFixtureDivOnly
 
 BOOST_FIXTURE_TEST_CASE( test_nodiv_bspline3, TransformSplineFixtureCurlOnly )
 {
-	init(16, 4, ip_bspline4);
+	init(16, 4, "bspline:d=4");
 
 	const T2DConvoluteInterpolator<C2DFVector>& interp = 
-		dynamic_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
+		static_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double testvalue = 6.0 * M_PI;
@@ -232,27 +234,27 @@ BOOST_FIXTURE_TEST_CASE( test_nodiv_bspline3, TransformSplineFixtureCurlOnly )
 // test whether the interpolation is "good enough" 
 BOOST_FIXTURE_TEST_CASE( test_interpolation_16_2_bspline3, TransformSplineFixtureexpm2testInterp ) 
 {
-	run( 8, 2.0, ip_bspline3);
+	run( 8, 2.0, "bspline:d=3");
 }
 
 BOOST_FIXTURE_TEST_CASE( test_divergence_expm2_bspline3_16_8, TransformSplineFixtureexpm2Field_44 )
 {
-	run(16, 4, ip_bspline3, 1.0);
+	run(16, 4, "bspline:d=3", 1.0);
 
 }
 
 BOOST_FIXTURE_TEST_CASE( test_divergence_expm2_bspline3_8_8, TransformSplineFixtureexpm2Field_44 )
 {
-	run(8, 4, ip_bspline3, 1.0);
+	run(8, 4, "bspline:d=3", 1.0);
 
 }
 
 BOOST_FIXTURE_TEST_CASE( test_divergence_expm2_bspline3_grad, TransformSplineFixtureexpm2Field_44 )
 {
-	init(8, 4, ip_bspline4);
+	init(8, 4, "bspline:d=4");
 
 	const T2DConvoluteInterpolator<C2DFVector>& interp = 
-		dynamic_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
+		static_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	C2DPPDivcurlMatrix div(field.get_size(), field_range, *ipf->get_kernel(), 1.0, 0.0);
@@ -291,10 +293,10 @@ BOOST_FIXTURE_TEST_CASE( test_divergence_expm2_bspline3_grad, TransformSplineFix
 
 BOOST_FIXTURE_TEST_CASE( test_rotation_expm2_bspline3_grad, TransformSplineFixtureexpm2Field_44 )
 {
-	init(8, 4, ip_bspline4);
+	init(8, 4, "bspline:d=4");
 
 	const T2DConvoluteInterpolator<C2DFVector>& interp = 
-		dynamic_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
+		static_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	C2DPPDivcurlMatrix rot(field.get_size(), field_range, *ipf->get_kernel(), 0.0, 1.0);
@@ -333,10 +335,10 @@ BOOST_FIXTURE_TEST_CASE( test_rotation_expm2_bspline3_grad, TransformSplineFixtu
 
 BOOST_FIXTURE_TEST_CASE( test_divergence_expm2_bspline3_grad_noiso, TransformSplineFixtureexpm2Field_44 )
 {
-	init2d(T2DVector<int>(12, 9), 4, ip_bspline4);
+	init2d(T2DVector<int>(12, 9), 4, "bspline:d=4");
 
 	const T2DConvoluteInterpolator<C2DFVector>& interp = 
-		dynamic_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
+		static_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	C2DPPDivcurlMatrix div(field.get_size(), field_range, *ipf->get_kernel(), 1.0, 0.0);
@@ -375,10 +377,10 @@ BOOST_FIXTURE_TEST_CASE( test_divergence_expm2_bspline3_grad_noiso, TransformSpl
 
 BOOST_FIXTURE_TEST_CASE( test_rotation_expm2_bspline3_grad_noiso, TransformSplineFixtureexpm2Field_44 )
 {
-	init2d(T2DVector<int>(12, 9), 4, ip_bspline4);
+	init2d(T2DVector<int>(12, 9), 4, "bspline:d=4");
 
 	const T2DConvoluteInterpolator<C2DFVector>& interp = 
-		dynamic_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
+		static_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	C2DPPDivcurlMatrix rot(field.get_size(), field_range, *ipf->get_kernel(), 0.0, 1.0);
@@ -418,24 +420,24 @@ BOOST_FIXTURE_TEST_CASE( test_rotation_expm2_bspline3_grad_noiso, TransformSplin
 
 BOOST_FIXTURE_TEST_CASE( test_divergence_expm2_bspline4, TransformSplineFixtureexpm2Field_44 )
 {
-	run(16, 4, ip_bspline4, 1.0);
+	run(16, 4, "bspline:d=4", 1.0);
 
 }
 
 BOOST_FIXTURE_TEST_CASE( test_divergence_expm2_bspline4_8_4, TransformSplineFixtureexpm2Field_44 )
 {
-	run(8, 4, ip_bspline4, 1.0);
+	run(8, 4, "bspline:d=4", 1.0);
 
 }
 
 BOOST_FIXTURE_TEST_CASE( test_divergence_zero_x, TransformSplineFixtureConst )
 {
-	prepare(16, 16, ip_bspline4, 0, .01);
+	prepare(16, 16, "bspline:d=4", 0, .01);
 
 	const double testvalue = 0.0;
 
 	const T2DConvoluteInterpolator<C2DFVector>& interp = 
-		dynamic_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
+		static_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 
@@ -604,9 +606,9 @@ float TransformSplineFixtureexpm2Field::integrate_div(float x1, float x2,
 
 
 
-void TransformSplineFixtureexpm2testInterp::run(int size, float range, EInterpolation type)
+void TransformSplineFixtureexpm2testInterp::run(int size, float range, const string& kernel)
 {
-	init( size, range, type);
+	init( size, range, kernel);
 	
 	for (float y = -range; y < range; y += range/5.0)
 		for (float x = -range; x < range; x += range/5.0) {
@@ -618,7 +620,7 @@ void TransformSplineFixtureexpm2testInterp::run(int size, float range, EInterpol
 	
 }
 
-void TransformSplineFixtureexpm2Field_44::run(int dsize, float range, EInterpolation type, double corr)
+void TransformSplineFixtureexpm2Field_44::run(int dsize, float range, const string& type, double corr)
 {
 	init(dsize, range, type);
 
@@ -626,7 +628,7 @@ void TransformSplineFixtureexpm2Field_44::run(int dsize, float range, EInterpola
 	const double testvalue = 4.0 * M_PI;
 
 	const T2DConvoluteInterpolator<C2DFVector>& interp = 
-		dynamic_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
+		static_cast<const T2DConvoluteInterpolator<C2DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 
diff --git a/mia/2d/test_register.cc b/mia/2d/test_register.cc
index 3b37f9d..ca68758 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +22,8 @@
 #include <mia/internal/autotest.hh>
 #include <mia/2d/register.hh>
 
-struct AffineRegistrationFixture {
-
+struct SimpleRegistrationFixture {
+	
 	AffineRegistrationFixture(); 
 
 	
@@ -34,9 +34,19 @@ struct AffineRegistrationFixture {
 	size_t max_iter; 
 }; 
 
+const float *src_init = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0	
+}; 
 
 // How to test registration creation 
-BOOST_AUTO_TEST_CASE( test_affine_registration )  
+BOOST_AUTO_TEST_CASE( test_simple_registration )  
 {
 	C2DMultiImageRegister registration(start_size, max_iter,
 					   C2DRegModel& model, 
@@ -44,6 +54,15 @@ BOOST_AUTO_TEST_CASE( test_affine_registration )
 					   P2DTransformationFactory& trans_factory, 
 					   float outer_epsilon); 
 	
+	C2DBounds size(32, 32);
+
+	
+
+	C2DFImage src(size);
+	C2DFImage ref(size);
+	
+	
+	
 
 }
 
diff --git a/mia/2d/test_regplugins.cc b/mia/2d/test_regplugins.cc
index c0fa9e0..8cd36e7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5e8b7a5..76c7fb3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@ void RigidRegisterFixture::run(C2DTransformation& t, const string& minimizer_des
 
 	auto minimizer = CMinimizerPluginHandler::instance().produce(minimizer_descr); 
 	P2DImageCost cost = C2DImageCostPluginHandler::instance().produce("ssd");
-	unique_ptr<C2DInterpolatorFactory>   ipfactory(create_2dinterpolation_factory(ip_bspline3, bc_mirror_on_bounds));
+	C2DInterpolatorFactory  ipfactory(C2DInterpolatorFactory("bspline:d=3", "mirror"));
 	auto tr_creator = C2DTransformCreatorHandler::instance().produce(t.get_creator_string());
 
 	C2DRigidRegister rr(cost, minimizer, tr_creator, 1);
@@ -155,7 +155,7 @@ BOOST_AUTO_TEST_CASE( test_rigidreg_affine_cost_gradient ) //, RigidRegisterFixt
 	auto transformation = tr_creator->create(size); 
 
 	P2DImageCost cost = C2DImageCostPluginHandler::instance().produce("ssd");
-	unique_ptr<C2DInterpolatorFactory>   ipfactory(create_2dinterpolation_factory(ip_bspline3));
+	C2DInterpolatorFactory   ipfactory("bspline:d=3", "mirror"));
 
 	float src_image_init[10 * 10] = {
 		0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -197,12 +197,12 @@ BOOST_AUTO_TEST_CASE( test_rigidreg_affine_cost_gradient ) //, RigidRegisterFixt
 	for (size_t i = 0; i < transformation->degrees_of_freedom(); ++i) {
 		params[i] -= 0.01;  
 		transformation->set_parameters(params); 
-		P2DImage tmp = (*transformation)(*src, *ipfactory); 
+		P2DImage tmp = (*transformation)(*src, ipfactory); 
 		double cm = cost->value(*tmp, *ref); 
 		
 		params[i] += 0.02; 
 		transformation->set_parameters(params); 
-		tmp = (*transformation)(*src, *ipfactory); 
+		tmp = (*transformation)(*src, ipfactory); 
 		double cp = cost->value(*tmp, *ref); 
 		
 		params[i] -= 0.01;
diff --git a/mia/2d/test_segframe.cc b/mia/2d/test_segframe.cc
index d1beb0f..dd602a1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@ void FrameTestRead::init(const char *init_str)
 	parser.parse_memory(init_str);
 	const xmlpp::Document *document = parser.get_document();
 	const xmlpp::Element *root = document->get_root_node ();
-	const xmlpp::Node::NodeList nodes = root->get_children();
+	auto nodes = root->get_children();
 	BOOST_CHECK_EQUAL(nodes.size(),1u);
 
 	frame = CSegFrame (**nodes.begin(), 1);
diff --git a/mia/2d/test_segmentation.cc b/mia/2d/test_segmentation.cc
index 763388a..89d21a6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,11 +46,10 @@ BOOST_AUTO_TEST_CASE(segpoint_read)
 
 	const Document *document = parser.get_document();
 	const Element *root = document->get_root_node ();
-	const Node::NodeList nodes = root->get_children("point");
+	auto nodes = root->get_children("point");
 	BOOST_CHECK_EQUAL(nodes.size(),1u);
 
-	for (Node::NodeList::const_iterator i = nodes.begin();
-	     i != nodes.end(); ++i) {
+	for (auto i = nodes.begin(); i != nodes.end(); ++i) {
 		CSegPoint2D p(**i);
 		BOOST_CHECK_EQUAL(p.x, 10);
 		BOOST_CHECK_EQUAL(p.y, 20);
@@ -109,7 +108,7 @@ void SegStarFixture::init(const char *init_str)
 	parser.parse_memory(init_str);
 	const Document *document = parser.get_document();
 	const Element *root = document->get_root_node ();
-	const Node::NodeList nodes = root->get_children("star");
+	auto nodes = root->get_children("star");
 	BOOST_CHECK_EQUAL(nodes.size(),1u);
 
 	star = CSegStar(**nodes.begin());
@@ -391,7 +390,7 @@ BOOST_AUTO_TEST_CASE(test_segstart_error_attribute)
 	parser.parse_memory(sestsection_error_r);
 	const xmlpp::Document *document = parser.get_document();
 	const xmlpp::Element *root = document->get_root_node ();
-	const xmlpp::Node::NodeList nodes = root->get_children();
+	auto nodes = root->get_children();
 	BOOST_CHECK_EQUAL(nodes.size(),1u);
 	BOOST_CHECK_THROW(CSegStar(**nodes.begin()), runtime_error); 
 }
@@ -411,7 +410,7 @@ BOOST_AUTO_TEST_CASE( test_segset_write_version1 )
 	segset.add_frame(CSegFrame("image.png", star1, CSegFrame::Sections()));
 	segset.add_frame(CSegFrame("image2.png", star2, CSegFrame::Sections()));
 
-	auto_ptr<xmlpp::Document> document(segset.write());
+	unique_ptr<xmlpp::Document> document(segset.write());
 
 	const string xmldoc = document->write_to_string("UTF-8");
 	const string testdoc(testset_init2);
@@ -603,7 +602,7 @@ void SectionTestRead::init(const char *init_str)
 	parser.parse_memory(init_str);
 	const xmlpp::Document *document = parser.get_document();
 	const xmlpp::Element *root = document->get_root_node ();
-	const xmlpp::Node::NodeList nodes = root->get_children();
+	auto nodes = root->get_children();
 	BOOST_CHECK_EQUAL(nodes.size(),1u);
 	section = CSegSection(**nodes.begin(), 1);
 
diff --git a/mia/2d/test_segpoint.cc b/mia/2d/test_segpoint.cc
index 591581a..6c64423 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_shape.cc b/mia/2d/test_shape.cc
index f9479a8..2d6ac9d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_similarity_profile.cc b/mia/2d/test_similarity_profile.cc
index fbd62c1..e146021 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +46,23 @@ BOOST_FIXTURE_TEST_CASE (test_C2DSimilarityProfile_ref10, SimityProfileFixture)
 	
 }
 
+BOOST_FIXTURE_TEST_CASE (test_C2DSimilarityProfile_ref10_profile, SimityProfileFixture) 
+{
+	
+	C2DSimilarityProfile sp(cost, series, 10, 0); 
+
+	auto subset = sp.get_periodic_subset();
+
+	size_t test_subset[] = {0, 3, 10, 13, 20, 23, 30, 33, 39}; 
+	BOOST_CHECK_EQUAL(subset.size(), 9);
+	cvdebug()<< "got subset: " << subset<< "\n";
+	
+	for (int i = 0; i< 9; ++i) {
+		BOOST_CHECK_EQUAL(subset[i], test_subset[i]); 
+	}
+}
+
+
 
 
 SimityProfileFixture::SimityProfileFixture()
@@ -55,10 +72,10 @@ SimityProfileFixture::SimityProfileFixture()
 
 	C2DBounds size(1,1); 
 	float values[40] = {
-		-2, -3, -4, -1, 1, 4, 2, -1, -3, -2, 
-		-2, -3, -4, -1, 1, 4, 2, -1, -3, -2, 
-		-2, -3, -4, -1, 1, 4, 2, -1, -3, -2, 
-		-2, -3, -4, -1, 1, 4, 2, -1, -3, -2 }; 
+		-2, -3, -4, -1, 1, 4, 2, -1, -3, -2.1, 
+		-2, -3, -4, -1, 1, 4, 2, -1, -3, -2.1, 
+		-2, -3, -4, -1, 1, 4, 2, -1, -3, -2.1, 
+		-2, -3, -4, -1, 1, 4, 2, -1, -3, -2.1 }; 
  
 	for(size_t i = 0; i < 40; ++i) {
 		C2DFImage *img = new C2DFImage(size); 
diff --git a/mia/2d/test_sparse_image_solver.cc b/mia/2d/test_sparse_image_solver.cc
index f4f9a9e..d8be825 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 69e0a9a..b2e3abe 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_trackpoint.cc b/mia/2d/test_trackpoint.cc
index b2e2b60..4a20505 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_transform.cc b/mia/2d/test_transform.cc
index 5af6c0d..d49e7fa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_transformfactory.cc b/mia/2d/test_transformfactory.cc
index 4c7f307..82c4b8a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_transio.cc b/mia/2d/test_transio.cc
index 32cc316..d852eaa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_vector.cc b/mia/2d/test_vector.cc
index 2d3e6c8..8ccfd7e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_vectorfield_interpolator.cc b/mia/2d/test_vectorfield_interpolator.cc
index aaece6b..378879c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_vfio.cc b/mia/2d/test_vfio.cc
index 9712b13..ea2027a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 282049f..bb4774e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9cae355..dd2b0e5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1af3044..0124a8f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1461fbd..78dadd5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e331221..caf7b2c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d1c3108..9615275 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d79b72b..fe80e81 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_fluid.cc b/mia/2d/timestep/test_fluid.cc
index 6394a1e..b133487 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/2d/trackpoint.cc
index 6baf5db..2b9c855 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6248e95..fae6d4f 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-2015 Gert Wollny, David Pastor
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny, David Pastor
  *
  * MIA is free software; 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 c1194eb..9e302a0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e795c2f..f01f035 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/2d/transform.hh
index c1d2577..988a7c1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -84,7 +84,7 @@ protected:
 		   Constructor to initialize the iterator at a certain point 
 		   @param pos current position of the iterator 
 		   @param size defines the grid of the domain of the iterator as 
-		      \f$[0,size.x-1] \times  [0,size.y-1]\f$
+		      \f$[pos.x, size.x-1] \times  [pos.y, size.y-1]\f$
 		   
 		 */
 		iterator_impl(const C2DBounds& pos, const C2DBounds& size); 
diff --git a/mia/2d/transform/affine.cc b/mia/2d/transform/affine.cc
index 4143959..af3e0ea 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/affine.hh b/mia/2d/transform/affine.hh
index f7f73de..0ae2b1c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/rigid.cc b/mia/2d/transform/rigid.cc
index 2f08b7f..5064173 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/rigid.hh b/mia/2d/transform/rigid.hh
index 650f0f3..6de9f20 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/rotation.cc b/mia/2d/transform/rotation.cc
index 020fbb3..29d4fce 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/rotation.hh b/mia/2d/transform/rotation.hh
index 03e93d6..2a45013 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/spline.cc b/mia/2d/transform/spline.cc
index 3105fbf..f48fa84 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/spline.hh b/mia/2d/transform/spline.hh
index fd7746e..91f1b48 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_affine.cc b/mia/2d/transform/test_affine.cc
index 5851646..e650719 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_nonlinear.cc b/mia/2d/transform/test_nonlinear.cc
index cca9755..f75d7ba 100644
--- a/mia/2d/transform/test_nonlinear.cc
+++ b/mia/2d/transform/test_nonlinear.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_rigid.cc b/mia/2d/transform/test_rigid.cc
index db65564..f5a3287 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_rotation.cc b/mia/2d/transform/test_rotation.cc
index 8a4f28d..c57f0ee 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_spline.cc b/mia/2d/transform/test_spline.cc
index 28fd7a2..6b8564a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -731,9 +731,9 @@ public:
 BOOST_AUTO_TEST_CASE (test_spline_set_parameter) 
 {
 	C2DBounds size(20,30); 
-	P2DInterpolatorFactory ipf(create_2dinterpolation_factory(ip_bspline3, bc_mirror_on_bounds)); 
+	C2DInterpolatorFactory ipf("bspline:d=3", "mirror"); 
 	PSplineKernel kernel(CSplineKernelPluginHandler::instance().produce("bspline:d=3")); 
-	C2DSplineTransformation t(size, kernel, C2DFVector(5.0,5.0), *ipf, P2DSplineTransformPenalty());
+	C2DSplineTransformation t(size, kernel, C2DFVector(5.0,5.0), ipf, P2DSplineTransformPenalty());
 	auto params = t.get_parameters();
 	
 	params[0] = 1.0; 
@@ -752,8 +752,8 @@ BOOST_AUTO_TEST_CASE (test_spline_set_parameter)
 
 BOOST_FIXTURE_TEST_CASE (test_spline_Gradient, TransformGradientFixture) 
 {
-	P2DInterpolatorFactory ipf(create_2dinterpolation_factory(ip_bspline3, bc_mirror_on_bounds)); 
-	C2DSplineTransformation t(size, kernel, C2DFVector(5.0,5.0), *ipf, P2DSplineTransformPenalty());
+	C2DInterpolatorFactory ipf("bspline:d=3", "mirror"); 
+	C2DSplineTransformation t(size, kernel, C2DFVector(5.0,5.0), ipf, P2DSplineTransformPenalty());
 	
 
 	auto params = t.get_parameters();
diff --git a/mia/2d/transform/test_translate.cc b/mia/2d/transform/test_translate.cc
index bb75301..6a54cfe 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_vectorfield.cc b/mia/2d/transform/test_vectorfield.cc
index e83ebe5..d90b8f8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/translate.cc b/mia/2d/transform/translate.cc
index dd6a463..2d3332d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/translate.hh b/mia/2d/transform/translate.hh
index 41a149c..49e8e7c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vectorfield.cc b/mia/2d/transform/vectorfield.cc
index 897eacb..f44e314 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vectorfield.hh b/mia/2d/transform/vectorfield.hh
index 6e35fac..ce292d2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/2d/transformfactory.cc
index 986414a..2a3f772 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0430579..aa130c1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 747f3b8..bca4e52 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 @@ 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 TPlugin<C2DTransformation, io_plugin_type>; 
 template class TIOPlugin<C2DTransformation>;
 template class THandlerSingleton<C2DTransformIOPluginHandlerImpl>;
 template class TIOPluginHandler<C2DTransformationIO>;
diff --git a/mia/2d/transformio.hh b/mia/2d/transformio.hh
index 1bbd722..59a14ef 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +37,9 @@ NS_MIA_BEGIN
 */ 
 typedef TIOPlugin<C2DTransformation> C2DTransformationIO; 
 
+extern template class EXPORT_2D TPlugin<C2DTransformation, io_plugin_type>; 
+extern template class EXPORT_2D TIOPlugin<C2DTransformation>; 
+
 
 /**
    \ingroup io
diff --git a/mia/2d/transformmock.cc b/mia/2d/transformmock.cc
index 6c4d458..2ea2343 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 bedb5ab..7a236df 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 146fd72..518ebf0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d9bac6b..40fc862 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d3d491c..3a50b97 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/xml.cc b/mia/2d/transio/xml.cc
index b454306..f7c3ddb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6f61af1..21579b3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vectorfield.cc b/mia/2d/vectorfield.cc
index 98931bb..6a24d84 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vectorfield.hh b/mia/2d/vectorfield.hh
index 8f363b5..47f4570 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vfio.cc b/mia/2d/vfio.cc
index 9833273..3eee635 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vfio.hh b/mia/2d/vfio.hh
index 9f03f80..8d91f1d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vfiotest.cc b/mia/2d/vfiotest.cc
index 2f32037..ec058f8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 99d8738..084e83f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/2dimagefifofilter.cc
index 1d43d72..2754a8c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0c6ab99..7cb3563 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -140,6 +140,21 @@ protected:
 */
 typedef TFifoFilter<P2DImage>::Pointer P2DImageFifoFilter;
 
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#ifndef __clang__
+#pragma GCC diagnostic ignored "-Wattributes"
+#endif
+#endif
+
+extern template class EXPORT_3D TFifoFilter<P2DImage>; 
+extern template class EXPORT_3D TFifoFilterSink<P2DImage>;
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
 /**
    \ingroup filtering
    \brief Plugin handler for the FIFO filters 
diff --git a/mia/3d/CMakeLists.txt b/mia/3d/CMakeLists.txt
index c8a2b3e..d06a487 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-2015 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
 #
 # 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,7 +57,7 @@ SET(MIA3D_SRC
   orientation.cc
   ppmatrix.cc 
   quaternion.cc
-  register.cc
+#  register.cc
   rigidregister.cc
   rot.cc
   shape.cc
@@ -115,7 +115,7 @@ SET(MIA3D_HEADERS
   orientation.hh
   ppmatrix.hh
   quaternion.hh
-  register.hh
+#  register.hh
   rigidregister.hh
   rot.hh
   shape.hh 
@@ -196,6 +196,7 @@ ELSE (WIN32)
 ENDIF(WIN32)
 
 TEST_3D(affine_matrix affine_matrix)
+TEST_3D(critical_points)
 TEST_3D(2dimagefifofilter imagefifofilter)
 TEST_3D(nfg nfg)
 TEST_3D(vectorfield vectorfield)
@@ -224,6 +225,8 @@ TEST_3D(imagecollect imagecollect)
 TEST_3D(imagedraw imagedraw)
 TEST_3D(rot rot)
 TEST_3D(splinetransformpenalty splinetransformpenalty)
+
+TEST_3D(imageio imageio)
 #
 # installation 
 #
diff --git a/mia/3d/affine_matrix.cc b/mia/3d/affine_matrix.cc
index bc10d72..e3aee8b 100644
--- a/mia/3d/affine_matrix.cc
+++ b/mia/3d/affine_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 <cmath>
 #include <mia/3d/affine_matrix.hh>
+#include <mia/core/utils.hh>
 
 NS_MIA_BEGIN
 
diff --git a/mia/3d/affine_matrix.hh b/mia/3d/affine_matrix.hh
index 889769f..b00e0b9 100644
--- a/mia/3d/affine_matrix.hh
+++ b/mia/3d/affine_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/camera.cc
index a5833ea..f64400c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3ee42a9..154d5e8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/combiner/labelxmap.cc
index 7352ff8..7420b61 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6f97e4e..e18748a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 68390a4..df90dbe 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/combiner/ops.hh
index 419bb0b..0a77847 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/plugin.hh b/mia/3d/combiner/plugin.hh
index e355109..de81110 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 54b2cbd..8a3e2af 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d568571..f4c07d2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/cost.cc
index d9a8764..955b7e9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/cost.hh
index 89b60b2..aa26cca 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/lncc.cc b/mia/3d/cost/lncc.cc
index ff4dd1f..8d812cf 100644
--- a/mia/3d/cost/lncc.cc
+++ b/mia/3d/cost/lncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +22,7 @@
 
 #include <mia/core/threadedmsg.hh>
 #include <mia/core/nccsum.hh>
-#include <tbb/parallel_reduce.h>
-#include <tbb/blocked_range.h>
-
+#include <mia/core/parallel.hh>
 
 NS_BEGIN(NS)
 
@@ -69,7 +67,7 @@ public:
 	
 	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> {
+		auto evaluate_local_cost = [this, &mov, &ref](const C1DParallelRange& range, const pair<float, int>& result) -> pair<float, int> {
 			CThreadMsgStream msks; 
 			float lresult = 0.0; 
 			int count = 0; 
@@ -104,10 +102,10 @@ public:
 		};
 		
 		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);
-					 });	
+		auto r = preduce(C1DParallelRange(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; 
 	}
 }; 
@@ -132,7 +130,7 @@ public:
 	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, 
+		auto evaluate_local_cost_force = [this, &mov, &ref, &ag](const C1DParallelRange& range, 
 									 const pair<float, int>& result) -> pair<float, int> {
 			
 			CThreadMsgStream msks; 		
@@ -175,10 +173,10 @@ public:
 			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);
-					 });
+		auto r = preduce(C1DParallelRange(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; 
 	}
diff --git a/mia/3d/cost/lncc.hh b/mia/3d/cost/lncc.hh
index 8dae95a..1fa879c 100644
--- a/mia/3d/cost/lncc.hh
+++ b/mia/3d/cost/lncc.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/cost/mi.cc
index 8a29086..cf0ae19 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9f0b358..9f440fb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index c439bff..e1db830 100644
--- a/mia/3d/cost/ncc.cc
+++ b/mia/3d/cost/ncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +22,7 @@
 
 #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>
+#include <mia/core/parallel.hh>
 
 
 NS_BEGIN(NS)
@@ -39,7 +37,7 @@ 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; 
+	NCCSums operator ()(const C1DParallelRange& range, const NCCSums& sumacc) const; 
 private: 
 	T m_mov; 
 	S m_ref; 
@@ -54,7 +52,7 @@ FEvaluateNCCSum<T,S>::FEvaluateNCCSum(const T& mov, const S& ref):
 }
 
 template <typename T, typename S> 
-NCCSums FEvaluateNCCSum<T,S>::operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const
+NCCSums FEvaluateNCCSum<T,S>::operator ()(const C1DParallelRange& range, const NCCSums& sumacc) const
 {
 	CThreadMsgStream msks; 
 	
@@ -80,10 +78,10 @@ public:
 
 		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;
-				      });
+		sum = preduce(C1DParallelRange(0, mov.get_size().z, 1), sum, ev, 
+			      [](const NCCSums& x, const NCCSums& y){
+				      return x + y;
+			      });
 		return sum.value(); 
 	}
 }; 
@@ -109,15 +107,15 @@ public:
 		
 		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;
-				      });
+		sum = preduce(C1DParallelRange(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) {
+		auto grad_eval = [this, &mov, &ref, &grad, &geval](const C1DParallelRange& 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); 
@@ -134,7 +132,7 @@ public:
 			}; 
 		}; 
 		
-		parallel_for(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), grad_eval); 
+		pfor(C1DParallelRange(0, mov.get_size().z, 1), grad_eval); 
 
 		return geval.first; 
 	}
diff --git a/mia/3d/cost/ncc.hh b/mia/3d/cost/ncc.hh
index 45ed562..78a6175 100644
--- a/mia/3d/cost/ncc.hh
+++ b/mia/3d/cost/ncc.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ngf.cc b/mia/3d/cost/ngf.cc
index 8002166..b7c48a1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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/3d/cost/ngf.hh>
 #include <mia/3d/nfg.hh>
 
+#include <numeric> 
 
 NS_BEGIN(ngf_3dimage_cost)
 
diff --git a/mia/3d/cost/ngf.hh b/mia/3d/cost/ngf.hh
index caeea7c..8287b17 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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-automask.cc b/mia/3d/cost/ssd-automask.cc
index cfd1281..97a4bce 100644
--- a/mia/3d/cost/ssd-automask.cc
+++ b/mia/3d/cost/ssd-automask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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-automask.hh b/mia/3d/cost/ssd-automask.hh
index 1ac57d7..1bbc387 100644
--- a/mia/3d/cost/ssd-automask.hh
+++ b/mia/3d/cost/ssd-automask.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/cost/ssd.cc
index 6d2859c..7581f67 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b586b52..f1bd40c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 1fcb8fb..749b9d6 100644
--- a/mia/3d/cost/test_lncc.cc
+++ b/mia/3d/cost/test_lncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_mi.cc b/mia/3d/cost/test_mi.cc
index 460e5d8..c79ebe3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ncc.cc b/mia/3d/cost/test_ncc.cc
index c6759bb..da188be 100644
--- a/mia/3d/cost/test_ncc.cc
+++ b/mia/3d/cost/test_ncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ngf.cc b/mia/3d/cost/test_ngf.cc
index 66a30ec..8d3de51 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ssd-automask.cc b/mia/3d/cost/test_ssd-automask.cc
index 3382cca..a3a3f52 100644
--- a/mia/3d/cost/test_ssd-automask.cc
+++ b/mia/3d/cost/test_ssd-automask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ssd.cc b/mia/3d/cost/test_ssd.cc
index d22f647..d3c9a87 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ssdautomask.cc b/mia/3d/cost/test_ssdautomask.cc
index 2098c0e..1d78e27 100644
--- a/mia/3d/cost/test_ssdautomask.cc
+++ b/mia/3d/cost/test_ssdautomask.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/creator.cc
index 759dbce..f249b9f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e148860..9a39463 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 aa9468f..94f4ff2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 48effdd..76e1207 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ffbc18c..761c832 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 255e754..e9f81ff 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 49d0460..4c80eb6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_sphere.cc b/mia/3d/creator/test_sphere.cc
index fca532d..086cabb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1ebde24..0922d66 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ C3DCriticalPoint&  C3DCriticalPoint::operator = (const C3DCriticalPoint& org)
 
 C3DFVector C3DCriticalPoint::at(const C3DFVector& x)const
 {
-	C3DFVector delta = x-x0;
+	C3DFVector delta = x - x0;
 	float tmp = delta.norm2(); 
 	if (tmp > .0001) {
 		return (gamma / tmp) * (A * delta);
@@ -138,9 +138,9 @@ bool C3DCriticalPointEigen::estimate()
 			cerr << "ERROR: 3 distinct eigenvalues but rank not 3!" << endl; 
 			return false; 
 		}
-		evec1 = portrait.get_eigenvector(0); 
-		evec2 = portrait.get_eigenvector(1); 
-		evec3 = portrait.get_eigenvector(2); 
+		evec1 = portrait.get_complex_eigenvector(0); 
+		evec2 = portrait.get_complex_eigenvector(1); 
+		evec3 = portrait.get_complex_eigenvector(2); 
 		type = ev_real; 
 		return true; 
 		
@@ -150,21 +150,29 @@ bool C3DCriticalPointEigen::estimate()
 				cerr << "ERROR: 3 distinct eigenvalues but rank not 3!" << endl; 
 				return false; 
 			}
-			evec1 = portrait.get_eigenvector(0); 
-			evec2 = portrait.get_eigenvector(1); 
-			evec2 = portrait.get_eigenvector(2); 
+			evec1 = portrait.get_complex_eigenvector(0); 
+			evec2 = portrait.get_complex_eigenvector(1); 
+			evec3 = portrait.get_complex_eigenvector(2); 
 			
 			type = ev_complex; 
 			return true; 
 		}
 	case 2:// three ev's but at least two are equal
-		evec1 = portrait.get_eigenvector(0); 
-		evec2 = portrait.get_eigenvector(1); 
-		evec3 = portrait.get_eigenvector(2); 
+		evec1 = portrait.get_complex_eigenvector(0); 
+		evec2 = portrait.get_complex_eigenvector(1); 
+		evec3 = portrait.get_complex_eigenvector(2); 
 		type = ev_real_two_equal;
 		return true;
+	case 4:// three real ev's all are equal
+		evec1 = portrait.get_complex_eigenvector(0); 
+		evec2 = portrait.get_complex_eigenvector(1); 
+		evec3 = portrait.get_complex_eigenvector(2); 
+		type = ev_real_three_equal;
+		return true;
+
+		
 	default: 
-		evec1 = portrait.get_eigenvector(0); 
+		evec1 = portrait.get_complex_eigenvector(0); 
 		return false;
 		
 	}
diff --git a/mia/3d/critical_point.hh b/mia/3d/critical_point.hh
index 0a614a6..3013483 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +41,7 @@ NS_MIA_BEGIN
 */
 
 
-class C3DCriticalPoint {
+class EXPORT_3D C3DCriticalPoint {
 public:
 
 	/// A list of critical points 
@@ -56,7 +56,7 @@ public:
 
 	/** 
 	    Construct a critical point at a certain location. 
-	    Magnitude and pahse portrait are set to zero. 
+	    Magnitude and phase portrait are set to zero. 
 	    \param x0_ location of the new critical point
 	*/
 
@@ -92,11 +92,12 @@ public:
 	/** \retval the magnitude of the critical point */
 	float get_gamma()const;
 
-	/** \retval the location of the critical point \a writable */
-	C3DFVector& get_point();
+	/** \retval the location of the critical point */
+	void set_point(const C3DFVector&);
 	
-	/** \retval the phase portrait of the critical point \a writable */
-	C3DFMatrix& get_a();
+	/** \retval the phase portrait of the critical point */
+	void  set_a(const C3DFMatrix&);
+
 	
 	/** set the magnitude if the critical point 
 	    \param gamma_ the new magnitude of the critical point
@@ -110,7 +111,13 @@ public:
 	    \retval value of vector field created by this crtitical point at \a x
 	*/
 	C3DFVector at(const C3DFVector& x) const;
-	
+
+	/** return the magniture of the critical point at location \a x according to 
+	    \f[ \frac {A \dot (x - x0)}{ | \| \mathbf{x} - \mathbf{x_0} \|_2 - gamma |}  \f]
+	    \param x location weher to evaluate the vector field 
+	    \retval value of vector field created by this crtitical point at \a x
+	*/
+
 	C3DFVector at_alt(const C3DFVector& x) const;
 
 	/** compare two critical points 
@@ -132,9 +139,6 @@ private:
 typedef C3DCriticalPoint::List C3DCriticalPointList;
 
 
-typedef std::complex<float> fcomplex; 
-typedef T3DVector<fcomplex> C3DCVector; 
-
 /** 
     \ingroup basic 
     \brief A class to hold a criticalpoint with eigenvalues and eigenvectors.
@@ -142,8 +146,10 @@ typedef T3DVector<fcomplex> C3DCVector;
     @remark untested 
 */
 
-class C3DCriticalPointEigen {
-	/// where is the critical point 
+class EXPORT_3D C3DCriticalPointEigen {
+	
+	
+        /// where is the critical point 
 	C3DFVector location; 
 
 
@@ -158,13 +164,13 @@ class C3DCriticalPointEigen {
 	float eval3;
 	
 	/// first eigenvector (always real)
-	C3DFVector evec1;
+	T3DCVector<float> evec1;
 	
 	/// second real eigenvector, or real part of a the conjugated complex eigenvectors
-	C3DFVector evec2; 
+	T3DCVector<float> evec2; 
 	
 	/// third real eigenvector, or imaginary part of a the conjugated complex eigenvectors
-	C3DFVector evec3;
+	T3DCVector<float> evec3;
 	
 public:	
 	/// types of critical points
@@ -229,12 +235,12 @@ public:
 	/** \retval get second eigenvalue as complex
 	    \remark asserts whether eigenvalue is really complex
 	*/	
-	fcomplex get_complex_eval2()const; 
+	std::complex<float> get_complex_eval2()const; 
 	
 	/** \retval get third eigenvalue as complex
 	    \remark asserts whether eigenvalue is really complex
 	*/	
-	fcomplex get_complex_eval3()const;
+	std::complex<float> get_complex_eval3()const;
 	
 	/** \retval a copy of the phase portrait
 	 */
@@ -251,17 +257,11 @@ public:
 	/** \retval a copy of the second eigenvector as real
 	    \remark use only for loading and storing
 	 */
-	const C3DFVector get_evect2()const; 
-	/** \retval a copy of the third eigenvector as real
-	    \remark use only for loading and storing
-	 */
-	const C3DFVector get_evect3()const; 
 
-	
 	const C3DFVector get_real_evect2()const; 
 	const C3DFVector get_real_evect3()const; 
-	const C3DCVector get_complex_evect2()const; 
-	const C3DCVector get_complex_evect3()const; 
+	const T3DCVector<float> get_complex_evect2()const; 
+	const T3DCVector<float> get_complex_evect3()const; 
 	
 
 private:
@@ -298,52 +298,40 @@ inline float C3DCriticalPointEigen::get_real_eval3()const
 	assert(type != ev_complex);
 	return eval3; 
 }     
-inline fcomplex C3DCriticalPointEigen::get_complex_eval2()const
+inline std::complex<float> C3DCriticalPointEigen::get_complex_eval2()const
 {
 	assert(type == ev_complex);
-	return fcomplex(eval2,eval3); 
+	return std::complex<float>(eval2,eval3); 
 }
-inline fcomplex C3DCriticalPointEigen::get_complex_eval3()const
+inline std::complex<float> C3DCriticalPointEigen::get_complex_eval3()const
 {
 	assert(type == ev_complex);
-	return fcomplex(eval2,-eval3); 
+	return std::complex<float>(eval2,eval3); 
 }
 
 inline const C3DFVector C3DCriticalPointEigen::get_evect1()const
 {
-	return evec1; 
-}
-inline const C3DFVector C3DCriticalPointEigen::get_evect2()const
-{
-	return evec2; 
-}
-inline const C3DFVector C3DCriticalPointEigen::get_evect3()const
-{
-	return evec3; 
+	return C3DFVector(evec1.x.real(), evec1.y.real(), evec1.z.real()); 
 }
 inline const C3DFVector C3DCriticalPointEigen::get_real_evect2()const
 {
 	assert(type != ev_complex);	
-	return evec2; 
+	return C3DFVector(evec2.x.real(), evec2.y.real(), evec2.z.real()); 
 }
 inline const C3DFVector C3DCriticalPointEigen::get_real_evect3()const
 {
 	assert(type != ev_complex);
-	return evec3; 
+	return C3DFVector(evec3.x.real(), evec3.y.real(), evec3.z.real()); ; 
 }
-inline const C3DCVector C3DCriticalPointEigen::get_complex_evect2()const
+inline const T3DCVector<float> C3DCriticalPointEigen::get_complex_evect2()const
 {
 	assert(type == ev_complex);
-	return C3DCVector(fcomplex(evec2.x,evec3.x),
-			  fcomplex(evec2.y,evec3.y),
-			  fcomplex(evec2.z,evec3.z));
+	return evec2;
 }
-inline const C3DCVector C3DCriticalPointEigen::get_complex_evect3()const
+inline const T3DCVector<float> C3DCriticalPointEigen::get_complex_evect3()const
 {
 	assert(type == ev_complex);
-	return C3DCVector(fcomplex(evec2.x,-evec3.x),
-			  fcomplex(evec2.y,-evec3.y),
-			  fcomplex(evec2.z,-evec3.z));
+	return evec3;
 }
 
 inline const C3DFVector C3DCriticalPointEigen::get_location()const
@@ -371,16 +359,18 @@ inline const C3DFMatrix  C3DCriticalPoint::get_a()const
 	return A;
 }
 
-inline C3DFVector& C3DCriticalPoint::get_point()
+
+inline void C3DCriticalPoint::set_point(const C3DFVector& x) 
 {
-	return x0;
+	x0 = x;
 }
 
-inline C3DFMatrix& C3DCriticalPoint::get_a()
+inline void C3DCriticalPoint::set_a(const C3DFMatrix& a) 
 {
-	return A;
+	A = a;
 }
 
+
 inline  float C3DCriticalPoint::get_gamma()const
 {
 	return gamma;
diff --git a/mia/3d/datafield.cc b/mia/3d/datafield.cc
index beef397..9ae3839 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,14 +95,15 @@ INSTANCIATE(short);
 INSTANCIATE(unsigned short);
 INSTANCIATE(unsigned char );
 INSTANCIATE(signed char);
-INSTANCIATE(bool);
+template class  T3DDatafield<bool>;
 
 DEFINE_TYPE_DESCR2(C3DBounds, "3dbounds"); 
 DEFINE_TYPE_DESCR2(C3DFVector, "3dfvector"); 
 
-template class EXPORT_3D  CTParameter<C3DBounds>;
-template class EXPORT_3D  CTParameter<C3DFVector>;
-template class EXPORT_3D  TTranslator<C3DFVector>; 
+template class CTParameter<C3DBounds>;
+template class CTParameter<C3DFVector>;
+template class TTranslator<C3DFVector>; 
+template class TAttribute<C3DFVector>; 
 
 NS_MIA_END
 
diff --git a/mia/3d/datafield.cxx b/mia/3d/datafield.cxx
index 63722d9..eb31b2f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ template <typename T>
 T3DDatafield<T>::T3DDatafield():
 	m_size(C3DBounds(0,0,0)), 
 	m_xy(0), 
-	m_data(new std::vector<T>(0))
+	m_data(new data_array(0))
 {
 }
 
@@ -54,7 +54,7 @@ template <typename T>
 T3DDatafield<T>::T3DDatafield(const C3DBounds& size ):
 	m_size(size),
 	m_xy(static_cast<size_t>(size.x) * static_cast<size_t>(size.y)), 
-	m_data(new std::vector<T>(m_xy * static_cast<size_t>(size.z)))
+	m_data(new data_array(m_xy * static_cast<size_t>(size.z)))
 {
 }
 
@@ -62,7 +62,7 @@ template <typename T>
 T3DDatafield<T>::T3DDatafield(const C3DBounds& size, const T *data):
 	m_size(size), 
 	m_xy(static_cast<size_t>(size.x) * static_cast<size_t>(size.y)), 
-	m_data(new std::vector<T>(m_xy * static_cast<size_t>(size.z)))
+	m_data(new data_array(m_xy * static_cast<size_t>(size.z)))
 {
 	std::copy(data, data + m_data->size(), m_data->begin()); 
 }
@@ -84,7 +84,7 @@ template <typename T>
 void T3DDatafield<T>::make_single_ref()
 {
 	if (!m_data.unique())
-		m_data = ref_data_type( new std::vector<T>(*m_data) );
+		m_data = ref_data_type( new data_array(*m_data) );
 }
 
 template <typename T>
@@ -195,18 +195,19 @@ struct __copy_dispatch<bool> {
 
 };
 
-template <typename T, bool trivial_copy> 
-struct __mia_copy_dispatch_1 {
-	static void apply_read(std::vector<T>& dest, const std::vector<T>& src, size_t start, size_t n) {
+template <typename O, typename I> 
+struct __mia_copy_dispatch {
+	static void apply_read(std::vector<O>& dest, const std::vector<I>& src, size_t start, size_t n) {
 		std::copy(src.begin() + start, src.begin() + start + n, dest.begin()); 
 	}
-	static void apply_write(std::vector<T>& dest, const std::vector<T>& src, size_t start, size_t n) {
+	static void apply_write(std::vector<O>& dest, const std::vector<I>& src, size_t start, size_t n) {
 		std::copy(src.begin(), src.begin() + n, dest.begin() + start); 
 	}
 }; 
 
-template <typename T> 
-struct __mia_copy_dispatch_1<T, true> {
+
+template <typename T, bool trivial_copy> 
+struct __mia_copy_dispatch_1{
 	static void apply_read(std::vector<T>& dest, const std::vector<T>& src, size_t start, size_t n) {
 		memcpy(&dest[0], &src[start], n * sizeof(T)); 
 	}
@@ -216,36 +217,31 @@ struct __mia_copy_dispatch_1<T, true> {
 }; 
 
 template <typename T> 
-struct __mia_copy_dispatch {
+struct __mia_copy_dispatch_1<T, false> {
 	static void apply_read(std::vector<T>& dest, const std::vector<T>& src, size_t start, size_t n) {
-		__mia_copy_dispatch_1<T, __has_trivial_copy(T)>::apply_read(dest, src, start, n); 
+		std::copy(src.begin() + start, src.begin() + start + n, dest.begin()); 
 	}
 	static void apply_write(std::vector<T>& dest, const std::vector<T>& src, size_t start, size_t n) {
-		__mia_copy_dispatch_1<T, __has_trivial_copy(T)>::apply_write(dest, src, start, n);
+		std::copy(src.begin(), src.begin() + n, dest.begin() + start); 
 	}
 }; 
 
-
-template <> 
-struct __mia_copy_dispatch<bool> {
-	static void apply_read(std::vector<bool>& dest, const std::vector<bool>& src, size_t start, size_t n) {
-		std::copy(src.begin() + start, 
-			  src.begin() + start + n, dest.begin()); 
+template <typename T> 
+struct __mia_copy_dispatch<T, T> {
+	static void apply_read(std::vector<T>& dest, const std::vector<T>& src, size_t start, size_t n) {
+		__mia_copy_dispatch_1<T, __has_trivial_copy(T)>::apply_read(dest, src, start, n); 		
 	}
-	static void apply_write(std::vector<bool>& dest, const std::vector<bool>& src, size_t start, size_t n) {
-		std::copy(src.begin(), src.begin() + n, dest.begin() + start); 
+	static void apply_write(std::vector<T>& dest, const std::vector<T>& src, size_t start, size_t n) {
+		__mia_copy_dispatch_1<T, __has_trivial_copy(T)>::apply_write(dest, src, start, n); 		
 	}
 }; 
 
-
-
-
 template <typename T>
 void T3DDatafield<T>::get_data_line_x(int y, int z, std::vector<T>& result)const
 {
         result.resize(m_size.x);
 	const size_t start = m_xy * z + static_cast<size_t>(m_size.x) * y; 
-	__mia_copy_dispatch<T>::apply_read(result, *m_data, start, m_size.x); 
+	__mia_copy_dispatch<T, value_type>::apply_read(result, *m_data, start, m_size.x); 
 }
 
 template <typename T>
@@ -265,8 +261,8 @@ void T3DDatafield<T>::get_data_line_z(int x, int y, std::vector<T>& result)const
 	size_t start = static_cast<size_t>(x) + static_cast<size_t>(m_size.x) * y;
 
 
-	typename std::vector<T>::const_iterator i = m_data->begin() + start;
-	typename std::vector<T>::iterator k = result.begin(); 
+	auto  i = m_data->begin() + start;
+	auto  k = result.begin(); 
 	
 	if (m_size.z > 8) {
 		const size_t xy = m_xy; 
@@ -296,8 +292,8 @@ void T3DDatafield<T>::put_data_line_x(int y, int z, const std::vector<T>& input)
 {
         assert(input.size() == m_size.x);
 	make_single_ref();
-	size_t start = m_size.x * (y + z * m_size.y); 
-	__mia_copy_dispatch<T>::apply_write(*m_data, input, start, m_size.x); 		
+	size_t start = m_size.x * (y + z * m_size.y);
+	__mia_copy_dispatch<value_type, T>::apply_write(*m_data, input, start, m_size.x);
 }
 
 template <typename T>
@@ -308,9 +304,9 @@ void T3DDatafield<T>::put_data_line_y(int x, int z, const std::vector<T>& input)
 	make_single_ref();
 	size_t start= x + m_size.x * m_size.y * z;
 	
-	typename std::vector<T>::iterator k = m_data->begin() + start; 
+	auto k = m_data->begin() + start; 
 
-	for (typename std::vector<T>::const_iterator i = input.begin(); 
+	for (auto i = input.begin(); 
 	     i != input.end(); ++i, k += m_size.x)
 		*k = *i; 
 }
@@ -323,9 +319,9 @@ void T3DDatafield<T>::put_data_line_z(int x, int y, const std::vector<T>& input)
 	make_single_ref();
 	size_t start= x + m_size.x * y;
 	
-	typename std::vector<T>::iterator k = m_data->begin() + start; 
+	auto k = m_data->begin() + start; 
 
-	for (typename std::vector<T>::const_iterator i = input.begin(); 
+	for (auto i = input.begin(); 
 	     i != input.end(); ++i, k += m_xy)
 		 *k = *i; 
 }
@@ -369,7 +365,7 @@ void T3DDatafield<T>::read_zslice_flat(size_t z, std::vector<atomic_type>& buffe
 {
 	assert(z < get_size().z); 
 	assert(m_xy * m_elements <= buffer.size()); 
-	__copy_dispatch<T>::apply_read(buffer, 0, *m_data, z * m_xy, m_xy); 
+	__copy_dispatch<value_type>::apply_read(buffer, 0, *m_data, z * m_xy, m_xy); 
 }
 
 
@@ -378,7 +374,7 @@ void T3DDatafield<T>::write_zslice_flat(size_t z, const std::vector<atomic_type>
 {
 	assert(z < get_size().z); 
 	assert(m_xy * m_elements <= buffer.size()); 
-	__copy_dispatch<T>::apply_write(*m_data, z * m_xy, buffer, 0, m_xy); 
+	__copy_dispatch<value_type>::apply_write(*m_data, z * m_xy, buffer, 0, m_xy); 
 }
 
 
@@ -390,8 +386,8 @@ void T3DDatafield<T>::read_yslice_flat(size_t y, std::vector<atomic_type>& buffe
 	
 	const size_t offset = y * get_size().x; 
 	for (size_t z = 0; z < get_size().z; ++z) {
-		__copy_dispatch<T>::apply_read(buffer, z * get_size().x  * m_elements, 
-					       *m_data, offset + z * m_xy, get_size().x); 
+		__copy_dispatch<value_type>::apply_read(buffer, z * get_size().x  * m_elements, 
+							*m_data, offset + z * m_xy, get_size().x); 
 	}
 }
 
@@ -403,9 +399,9 @@ void T3DDatafield<T>::write_yslice_flat(size_t y, const std::vector<atomic_type>
 	
 	const size_t offset = y * get_size().x; 
 	for (size_t z = 0; z < get_size().z; ++z) {
-		__copy_dispatch<T>::apply_write(*m_data, offset + z * m_xy,
-						buffer, z * get_size().x * m_elements, 
-					        get_size().x); 
+		__copy_dispatch<value_type>::apply_write(*m_data, offset + z * m_xy,
+							 buffer, z * get_size().x * m_elements, 
+							 get_size().x); 
 	}
 }
 
@@ -419,8 +415,8 @@ void T3DDatafield<T>::read_xslice_flat(size_t x, std::vector<atomic_type>& buffe
 	size_t offset = x; 
 	size_t doffs =  get_size().x; 
 	for (size_t i = 0; i < slice_size; ++i, offset += doffs) {
-		__copy_dispatch<T>::apply_read(buffer, m_elements * i, 
-					       *m_data, offset, 1); 
+		__copy_dispatch<value_type>::apply_read(buffer, m_elements * i, 
+							*m_data, offset, 1); 
 	}
 }
 
@@ -434,8 +430,8 @@ void T3DDatafield<T>::write_xslice_flat(size_t x, const std::vector<atomic_type>
 	size_t offset = x; 
 	size_t doffs =  get_size().x; 
 	for (size_t i = 0; i < slice_size; ++i, offset += doffs) {
-		__copy_dispatch<T>::apply_write(*m_data, offset, 
-						buffer, m_elements * i, 1);
+		__copy_dispatch<value_type>::apply_write(*m_data, offset, 
+							 buffer, m_elements * i, 1);
 	}
 }
 
@@ -564,7 +560,7 @@ void T3DDatafield<T>::clear()
 }
 
 template <typename T>
-const T T3DDatafield<T>::Zero = T();
+const typename T3DDatafield<T>::value_type T3DDatafield<T>::Zero = T();
 
 template <typename T>
 typename T3DDatafield<T>::value_type
diff --git a/mia/3d/datafield.hh b/mia/3d/datafield.hh
index da1ecdf..4ab9b16 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 @@ NS_MIA_BEGIN
 	extern template class  EXPORT_3D range2d_iterator<std::vector<TYPE>::const_iterator>;
 
 
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#ifndef __clang__
+#pragma GCC diagnostic ignored "-Wattributes"
+#endif
+#endif
+
 DECLARE_EXTERN_ITERATORS(double);
 DECLARE_EXTERN_ITERATORS(float);
 DECLARE_EXTERN_ITERATORS(unsigned int);
@@ -65,6 +72,9 @@ DECLARE_EXTERN_ITERATORS(unsigned long);
 DECLARE_EXTERN_ITERATORS(C3DFVector)
 DECLARE_EXTERN_ITERATORS(C3DDVector)
 
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif 
 
 /**
    @ingroup basic 
@@ -73,24 +83,10 @@ DECLARE_EXTERN_ITERATORS(C3DDVector)
 template <class T>
 class  EXPORT_3D T3DDatafield {
 
-	typedef  ::std::vector<T> data_array;
+	typedef  ::std::vector<typename __holder_type_dispatch<T>::type> data_array;
 
         typedef std::shared_ptr<data_array>  ref_data_type;
 
-        /** Size of the field */
-        C3DBounds  m_size;
-
-        /** helper: product of Size.x * Size.y */
-        size_t  m_xy;
-
-        /** Pointer to the Field of Data hold by this class */
-        ref_data_type m_data;
-
-        /** helper: represents the zero-value */
-        static const T Zero;
-	
-	static const size_t m_elements; 
-
 public:
 	
 
@@ -110,16 +106,16 @@ public:
 	/// a shortcut data type
 
 	/// \cond SELFEXPLAINING 
-        typedef typename std::vector<T>::iterator iterator;
-        typedef typename std::vector<T>::const_iterator const_iterator;
-        typedef typename std::vector<T>::const_reference const_reference;
-        typedef typename std::vector<T>::reference reference;
-        typedef typename std::vector<T>::const_pointer const_pointer;
-        typedef typename std::vector<T>::pointer pointer;
-        typedef typename std::vector<T>::value_type value_type;
-        typedef typename std::vector<T>::size_type size_type;
-        typedef typename std::vector<T>::difference_type difference_type;
-	typedef typename atomic_data<T>::type atomic_type; 
+        typedef typename data_array::iterator iterator;
+        typedef typename data_array::const_iterator const_iterator;
+        typedef typename data_array::const_reference const_reference;
+        typedef typename data_array::reference reference;
+        typedef typename data_array::const_pointer const_pointer;
+        typedef typename data_array::pointer pointer;
+        typedef typename data_array::value_type value_type;
+        typedef typename data_array::size_type size_type;
+        typedef typename data_array::difference_type difference_type;
+	typedef typename atomic_data<value_type>::type atomic_type; 
 	typedef range3d_iterator<iterator> range_iterator; 
 	typedef range3d_iterator<const_iterator> const_range_iterator; 
 
@@ -272,7 +268,7 @@ public:
 	{
         	// Look if we are inside, and give reference, else give the zero
 	        if (x < m_size.x && y < m_size.y && z < m_size.z) {
-	                const std::vector<T>& data = *m_data;
+	                const data_array& data = *m_data;
 	                return data[x+ m_size.x * (y  + m_size.y * z)];
 	        }
 		return Zero;
@@ -540,6 +536,20 @@ public:
         };
 
 private:
+	/** Size of the field */
+        C3DBounds  m_size;
+
+        /** helper: product of Size.x * Size.y */
+        size_t  m_xy;
+
+        /** Pointer to the Field of Data hold by this class */
+        ref_data_type m_data;
+
+        /** helper: represents the zero-value */
+        static const value_type Zero;
+	
+	static const size_t m_elements; 
+
 };
 
 /// a data field of float values
@@ -574,7 +584,9 @@ typedef  TTranslator<C3DFVector> C3DFVectorTranslator;
 
 /// @cond NEVER 
 DECLARE_TYPE_DESCR(C3DBounds); 
-DECLARE_TYPE_DESCR(C3DFVector); 
+DECLARE_TYPE_DESCR(C3DFVector);
+
+extern template class EXPORT_3D TAttribute<C3DFVector>; 
 /// @endcond 
 
 // some implementations
@@ -743,6 +755,12 @@ DECLARE_EXTERN(unsigned long);
 DECLARE_EXTERN(C3DFVector);
 DECLARE_EXTERN(C3DDVector);
 
+extern template class EXPORT_3D CTParameter<C3DBounds>;
+extern template class EXPORT_3D CTParameter<C3DFVector>;
+extern template class EXPORT_3D TTranslator<C3DFVector>; 
+extern template class EXPORT_3D TAttribute<C3DFVector>; 
+
+
 #undef DECLARE_EXTERN
 
 #ifdef __GNUC__
diff --git a/mia/3d/defines3d.hh b/mia/3d/defines3d.hh
index 1d8d507..bab111a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/deformer.hh b/mia/3d/deformer.hh
index b8f7a35..aaf7b5e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +22,7 @@
 #define reg3d_deformer_hh
 
 #include <memory>
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
 
 
 #include <mia/3d/image.hh>
@@ -60,9 +59,9 @@ struct FDeformer3D: public TFilter<P3DImage> {
 		std::unique_ptr<T3DConvoluteInterpolator<T> > interp(m_ipfac.create(image.data())); 
 		const auto& rinterp = *interp; 
 
-		auto callback = [this, &rinterp, &result](const tbb::blocked_range<size_t>& range){
+		auto callback = [this, &rinterp, &result](const C1DParallelRange& range){
 			CThreadMsgStream thread_stream;
-			CWeightCache cache = rinterp.create_cache(); 
+			auto cache = rinterp.create_cache(); 
 			for (auto z = range.begin(); z != range.end();++z) {
 				auto r = result.begin_at(0,0,z); 
 				auto v = m_vf.begin_at(0,0,z); 
@@ -71,7 +70,7 @@ struct FDeformer3D: public TFilter<P3DImage> {
 						*r = rinterp(C3DFVector(x - v->x, y - v->y, z - v->z), cache);
 			}
 		}; 
-		tbb::parallel_for(tbb::blocked_range<size_t>(0, result.get_size().z, 1), callback); 
+		pfor(C1DParallelRange(0, result.get_size().z, 1), callback); 
 		return P3DImage(); 
 	}
 	
diff --git a/mia/3d/distance.cc b/mia/3d/distance.cc
index 6f920b6..902b686 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 62d7971..d26cbfe 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 683fb3c..cb6e2ca 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 366c8f5..6e9e2ec 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d4790b3..eefd927 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 50a049e..be363c0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +59,8 @@ private:
 	mia::P2DFilter m_gauss2d;
 	mia::C2DBounds m_slice_size;
 	mia::P1DSpacialKernel m_1dfilter;
-	std::auto_ptr<mia::C3DFImage> m_buffer;
-	std::auto_ptr<mia::C3DImage> m_dummy;
+	std::unique_ptr<mia::C3DFImage> m_buffer;
+	std::unique_ptr<mia::C3DImage> m_dummy;
 };
 
 NS_END
diff --git a/mia/3d/fifof/label.cc b/mia/3d/fifof/label.cc
index 244b83d..3742674 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/fifof/label.hh
index 9a52bcd..85a51f2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2485c52..4042c69 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +25,7 @@
 #include <iomanip>
 #include <limits>
 #include <mia/3d/fifof/median.hh>
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-using namespace tbb;
+#include <mia/core/parallel.hh>
 
 NS_BEGIN(median_2dstack_filter)
 
@@ -57,7 +55,7 @@ struct __dispatch_median_3dfilter {
 		int idx = distance(target_vector.begin(), tend); 
 
 		if (idx & 1) {
-			typename vector<T>::iterator mid = target_vector.begin() + idx/2;
+			auto mid = target_vector.begin() + idx/2;
 			nth_element(target_vector.begin(), mid, tend);
 			return *mid;
 		} else {
@@ -107,7 +105,7 @@ struct MedianRowThread {
 		hwidth(hw)
 		{
 		}
-	void operator()( const blocked_range<int>& range ) const {
+	void operator()( const C1DParallelRange& range ) const {
 		for( int y=range.begin(); y!=range.end(); ++y ) {
 		auto i = return_image->begin_at(0, y);
 		
@@ -131,7 +129,7 @@ C2DImage *C2DMedianFifoFilter::operator()(const T3DImage<T>& buffer) const {
 	T2DImage<T> *retval = new T2DImage<T>(m_slice_size);
 
 	MedianRowThread<T> row_thread(retval, buffer, m_slice_size.x, get_start(), get_end(), m_hw); 
-	parallel_for(blocked_range<int>( 0, m_slice_size.y), row_thread);
+	pfor(C1DParallelRange( 0, m_slice_size.y), row_thread);
 
 	return retval;
 }
diff --git a/mia/3d/fifof/median.hh b/mia/3d/fifof/median.hh
index e8c3439..fb716cb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@ private:
 	void do_shift();
 	void shift_buffer();
 	mia::C2DBounds m_slice_size;
-	std::auto_ptr<mia::C3DImage> m_buffer;
+	std::unique_ptr<mia::C3DImage> m_buffer;
 	size_t m_hw;
 
 	C2DImageFifoFilter::CShiftSlices m_ss;
diff --git a/mia/3d/fifof/mlv.cc b/mia/3d/fifof/mlv.cc
index ae210e3..ea80a5e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 +22,7 @@
 #include <config.h>
 #endif
 
-extern "C" {
-#include <cblas.h>
-}
-
+#include <gsl/gsl_cblas.h>
 #include <iomanip>
 #include <limits>
 
diff --git a/mia/3d/fifof/mlv.hh b/mia/3d/fifof/mlv.hh
index f8e7e11..c71dac6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +60,7 @@ private:
 
 	std::vector<float> m_buf1;
 	std::vector<float> m_buf2;
-	std::auto_ptr<mia::C3DImage> m_prototype;
+	std::unique_ptr<mia::C3DImage> m_prototype;
 
 	mia::C2DFImage m_n_template;
 
diff --git a/mia/3d/fifof/morphological.cc b/mia/3d/fifof/morphological.cc
index 86fa3d7..d3432ad 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 09f19fb..2a93060 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ class PRIVATE C2DMorphFifoFilter : public mia::C2DImageFifoFilter {
 	void shift_buffer();
 
 	mia::P3DShape m_shape;
-	std::auto_ptr<mia::C3DImage> m_buffer;
+	std::unique_ptr<mia::C3DImage> m_buffer;
 
 	mia::C2DBounds m_slice_size;
 	CShiftSlices m_shifter;
diff --git a/mia/3d/fifof/regiongrow.cc b/mia/3d/fifof/regiongrow.cc
index 60d2025..a7587cc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/fifof/regiongrow.hh
index c2325d5..ad1e6fa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1c435f1..c97eeee 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/rgg2pass.cc b/mia/3d/fifof/rgg2pass.cc
index f794a26..6ef7efa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 71a476f..fc5694b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_gauss.cc b/mia/3d/fifof/test_gauss.cc
index 9933f3f..9734003 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_label.cc b/mia/3d/fifof/test_label.cc
index beb28e9..122346d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_median.cc b/mia/3d/fifof/test_median.cc
index a81e65f..0e5b09d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 76c4dd3..bc64fd1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_morphological.cc b/mia/3d/fifof/test_morphological.cc
index 66f8bc1..53ed3fb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9f34c0e..c09a2a4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a595398..a5978f1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 aee89af..ea30b34 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1466897..4a875ae 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/filter.hh
index 59e96da..22fdd8e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/aniso.cc b/mia/3d/filter/aniso.cc
index 3fef19a..cfffcd5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f202393..0be819a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8b6e77e..12e574c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 493b262..8739b8c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 85948f2..85b59a2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index aecbad1..eccd467 100644
--- a/mia/3d/filter/combiner.cc
+++ b/mia/3d/filter/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/filter/combiner.hh
index 42ea40c..582e4d5 100644
--- a/mia/3d/filter/combiner.hh
+++ b/mia/3d/filter/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/filter/convert.cc
index bdef436..b803f88 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 7484573..b3c09a9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 088af7b..ba11d75 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a1eb2a6..65748e2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 3f7804c..823ebb7 100644
--- a/mia/3d/filter/distance.cc
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,38 +23,37 @@
 #include <mia/core/distance.hh>
 
 #include <mia/core/threadedmsg.hh>
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-
+#include <mia/core/parallel.hh>
 
 namespace distance_3d_filter {
 
 using namespace mia; 
 
 using std::vector; 
-using std::string; 
+using std::string;
 
 template <typename T> 
 P3DImage C3DDistanceFilter::operator () ( const T3DImage<T>& image) const
 {
 	C3DFImage *result = new C3DFImage(image.get_size(), image);
 
-	auto transform_x = [result, &image](const tbb::blocked_range<size_t>& range) {
+	auto transform_x = [result, &image](const C1DParallelRange& range) {
 		vector<float> buffer(image.get_size().x); 
 		vector<T> in_buffer(image.get_size().x); 
-		for (size_t z = range.begin(); z != range.end(); ++z) {
+		for (auto z = range.begin(); z != range.end(); ++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_prepare(in_buffer.begin(), in_buffer.end(), buffer.begin(),
+							   __is_mask_pixel<T>::value); 
 				distance_transform_inplace(buffer); 
 				result->put_data_line_x(y, z, buffer);
 			}
 		}
 	}; 
 	
-	auto transform_y = [result](const tbb::blocked_range<size_t>& range) {
+	auto transform_y = [result](const C1DParallelRange& range) {
 		vector<float> buffer(result->get_size().y); 
-		for (size_t z = range.begin(); z != range.end(); ++z) {
+		for (auto z = range.begin(); z != range.end(); ++z) {
 			for (size_t x = 0; x < result->get_size().x; ++x) {
 				result->get_data_line_y(x, z, buffer);
 				distance_transform_inplace(buffer); 
@@ -63,9 +62,9 @@ P3DImage C3DDistanceFilter::operator () ( const T3DImage<T>& image) const
 		}
 	}; 
 
-	auto transform_z = [result](const tbb::blocked_range<size_t>& range) {
+	auto transform_z = [result](const C1DParallelRange& range) {
 		vector<float> buffer(result->get_size().z);
-		for (size_t y = range.begin(); y != range.end(); ++y) {
+		for (auto y = range.begin(); y != range.end(); ++y) {
 			for (size_t x = 0; x < result->get_size().x; ++x) {
 				result->get_data_line_z(x, y, buffer);
 				distance_transform_inplace(buffer); 
@@ -76,9 +75,9 @@ P3DImage C3DDistanceFilter::operator () ( const T3DImage<T>& image) const
 		}
 	}; 
 	
-	parallel_for(tbb::blocked_range<size_t>(0, image.get_size().z, 1), transform_x); 
-	parallel_for(tbb::blocked_range<size_t>(0, image.get_size().z, 1), transform_y); 
-	parallel_for(tbb::blocked_range<size_t>(0, image.get_size().y, 1), transform_z); 
+	pfor(C1DParallelRange(0, image.get_size().z, 1), transform_x); 
+	pfor(C1DParallelRange(0, image.get_size().z, 1), transform_y); 
+	pfor(C1DParallelRange(0, image.get_size().y, 1), transform_z); 
 	
 	return P3DImage(result); 
 }
diff --git a/mia/3d/filter/distance.hh b/mia/3d/filter/distance.hh
index 6d3d7de..016e841 100644
--- a/mia/3d/filter/distance.hh
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/downscale.cc b/mia/3d/filter/downscale.cc
index 8628e07..b534984 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/downscale.hh b/mia/3d/filter/downscale.hh
index b49b7c1..d0208a7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c4c970a..27d84ad 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/filter/gradnorm.hh
index 5a0829f..7fcff5a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 add81c2..185aeae 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -183,15 +183,15 @@ C3DDoGrowmask::result_type C3DDoGrowmask::operator () (const T3DImage<T>& data)
 	P3DImage result(r);
 
 	// first initialize the seed queue
-	C3DBitImage::iterator ir = r->begin();
-	typename T3DImage<T>::const_iterator d = data.begin();
+	auto ir = r->begin();
+	auto d = data.begin();
 
 	C3DBounds pos;
 	for (pos.z = 0; pos.z < data.get_size().z; ++pos.z)
 		for (pos.y = 0; pos.y < data.get_size().y; ++pos.y)
 			for (pos.x = 0; pos.x < data.get_size().x; ++pos.x, ++ir, ++d) {
 				if (*ir)
-					add_neigborhood(pos, data, *r, *d, pool);
+					add_neigborhood(pos, data, *r, static_cast<T>(*d), pool);
 			}
 
 	// then grow
diff --git a/mia/3d/filter/growmask.hh b/mia/3d/filter/growmask.hh
index 2e54744..1bc9976 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c624769..12ab250 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 374bb87..6289c32 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0e17ea6..0445750 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ff51166..973e5de 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9682924..03c930c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 178efdb..9f500f5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/labelmap.cc b/mia/3d/filter/labelmap.cc
index 1a385b6..2779a16 100644
--- a/mia/3d/filter/labelmap.cc
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/labelmap.hh b/mia/3d/filter/labelmap.hh
index 0235833..c64f9ef 100644
--- a/mia/3d/filter/labelmap.hh
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/labelscale.cc b/mia/3d/filter/labelscale.cc
index 4ac9c6f..eb87d89 100644
--- a/mia/3d/filter/labelscale.cc
+++ b/mia/3d/filter/labelscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/labelscale.hh b/mia/3d/filter/labelscale.hh
index ac03844..0cc8569 100644
--- a/mia/3d/filter/labelscale.hh
+++ b/mia/3d/filter/labelscale.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1a2f61d..4dfd0d4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/filter/load.hh
index 0221ae6..9b63cc3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 1ec6d26..6a6aac2 100644
--- a/mia/3d/filter/lvdownscale.cc
+++ b/mia/3d/filter/lvdownscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/filter/lvdownscale.hh
index 7663c4d..175c86f 100644
--- a/mia/3d/filter/lvdownscale.hh
+++ b/mia/3d/filter/lvdownscale.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/mask.cc b/mia/3d/filter/mask.cc
index 67aae52..7b871eb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/mask.hh b/mia/3d/filter/mask.hh
index 9b1b392..0fce15d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 99c143d..e27777b 100644
--- a/mia/3d/filter/mean.cc
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
 #include <mia/core/threadedmsg.hh>
 
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
 
 
 NS_BEGIN(mean_3dimage_filter)
@@ -65,12 +64,6 @@ 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); 
@@ -80,6 +73,10 @@ struct __dispatch_filter {
 			++rb;
 			++n; 
 		}
+		
+		// hw >= 0, cy >= 0 && cy < data.get_size().y
+		// therefore n >=1, hence the override 
+		// coverity[divide_by_zero] 
 		return mia_round_clamped<T>(rint(result/n)); 
 	}
 }; 
@@ -101,6 +98,10 @@ struct __dispatch_filter<T, true> {
 			++rb; 
 			++n; 
 		}
+	 
+		// hw >= 0, cy >= 0 && cy < data.get_size().y
+		// therefore n >=1, hence the override 
+		// coverity[divide_by_zero] 
 		return static_cast<T>(result/n); 
 	}
 }; 
@@ -133,7 +134,7 @@ mia::T3DImage<T> *C3DMeanFilter::apply(const mia::T3DImage<T>& data) const
         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) {
+        auto run_slice  = [hw, data, result](const C1DParallelRange& 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)
@@ -142,7 +143,7 @@ mia::T3DImage<T> *C3DMeanFilter::apply(const mia::T3DImage<T>& data) const
                                 }
                 }
         }; 
-        parallel_for(tbb::blocked_range<size_t>(0, data.get_size().z, 1), run_slice);
+        pfor(C1DParallelRange(0, data.get_size().z, 1), run_slice);
         return result;
 }
 
@@ -198,7 +199,7 @@ P3DImage C3DVarianceFilter::operator () (const mia::T3DImage<T>& data) const
         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) {
+        auto run_slice  = [hw, &mean, result](const C1DParallelRange& 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)
@@ -208,7 +209,7 @@ P3DImage C3DVarianceFilter::operator () (const mia::T3DImage<T>& data) const
                                 }
                 }
         }; 
-        parallel_for(tbb::blocked_range<size_t>(0, data.get_size().z, 1), run_slice);
+        pfor(C1DParallelRange(0, data.get_size().z, 1), run_slice);
         return P3DImage(result);
  }
 
diff --git a/mia/3d/filter/mean.hh b/mia/3d/filter/mean.hh
index 5834ffd..afd28a0 100644
--- a/mia/3d/filter/mean.hh
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/filter/median.cc
index d3fce8a..332e3bb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 cbab1ba..a859e22 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c5471de..fed98bd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5e28e24..3ef8a92 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ebd0560..9add2b0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +24,7 @@
 #include <mia/3d/filter/morphological.hh>
 
 #include <mia/core/threadedmsg.hh>
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-
+#include <mia/core/parallel.hh>
 
 NS_BEGIN(morph_3dimage_filter)
 
@@ -51,7 +49,7 @@ struct __dispatch_dilate {
 		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) {
+		auto run_slice = [&size, &image, &shape, &result](const C1DParallelRange& 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);
@@ -73,7 +71,7 @@ struct __dispatch_dilate {
 					}
 			}
 		};
-		tbb::parallel_for(tbb::blocked_range<size_t>(0, image.get_size().z, 1), run_slice); 
+		pfor(C1DParallelRange(0, image.get_size().z, 1), run_slice); 
 		return result;
 	}
 };
@@ -199,7 +197,7 @@ struct __dispatch_erode {
 		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) {
+		auto run_slice = [&size, &image, &shape, &result](const C1DParallelRange& 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);
@@ -220,7 +218,7 @@ struct __dispatch_erode {
 					}
 			}
 		}; 
-		tbb::parallel_for(tbb::blocked_range<size_t>(0, image.get_size().z, 1), run_slice); 
+		pfor(C1DParallelRange(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 609260a..8027155 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 28961ac..e6f3597 100644
--- a/mia/3d/filter/msnormalizer.cc
+++ b/mia/3d/filter/msnormalizer.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,15 +18,11 @@
  *
  */
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-
+#include <mia/core/parallel.hh>
 #include <mia/3d/filter/msnormalizer.hh>
 #include <mia/core/threadedmsg.hh>
 
-extern "C" {
-#include <cblas.h>
-}
+#include <gsl/gsl_cblas.h>
 
 
 NS_BEGIN(msnormalizer_3dimage_filter)
@@ -64,7 +60,7 @@ void  C3DMSNormalizerFilter::add(C3DFImage& mean, C3DFImage& variance, const mia
 
         int x_length = ei.x - bi.x; 
 	
-	auto sum_slice = [&data, &mean, &variance, bi, bo, ei, x_length](const tbb::blocked_range<int>& range) {
+	auto sum_slice = [&data, &mean, &variance, bi, bo, ei, x_length](const C1DParallelRange& 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) {
@@ -80,8 +76,8 @@ void  C3DMSNormalizerFilter::add(C3DFImage& mean, C3DFImage& variance, const mia
 			}
 		}
 	}; 
-
-	parallel_for(tbb::blocked_range<int>(0, ei.z - bi.z, 1), sum_slice);
+	
+	pfor(C1DParallelRange(0, ei.z - bi.z, 1), sum_slice);
 
 
 }
@@ -115,7 +111,7 @@ mia::P3DImage C3DMSNormalizerFilter::operator () (const mia::T3DImage<T>& data)
         }
 
 	
-	auto evaluate_result = [data, this, &mean, &variance](const tbb::blocked_range<unsigned>& range) {
+	auto evaluate_result = [data, this, &mean, &variance](const C1DParallelRange& range) {
 		CThreadMsgStream thread_stream;
 		for (auto z = range.begin(); z != range.end(); ++z) {
 			cvmsg() << "Evaluate slice " << z << "\n"; 
@@ -137,7 +133,7 @@ mia::P3DImage C3DMSNormalizerFilter::operator () (const mia::T3DImage<T>& data)
 		}
 	}; 
 	
-	parallel_for(tbb::blocked_range<unsigned>(0, data.get_size().z, 1), evaluate_result);
+	pfor(C1DParallelRange(0, data.get_size().z, 1), evaluate_result);
 	
         return P3DImage(mean); 
 }
diff --git a/mia/3d/filter/msnormalizer.hh b/mia/3d/filter/msnormalizer.hh
index 023bdd3..d20e9e0 100644
--- a/mia/3d/filter/msnormalizer.hh
+++ b/mia/3d/filter/msnormalizer.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/filter/reorient.cc
index 190e682..fdf956b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2b4d0f0..a15c3e2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3f1f243..603a0b6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 da10d88..0069c4f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4d19565..c95a518 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 +26,7 @@
 #include <mia/3d/filter/scale.hh>
 
 #include <mia/core/threadedmsg.hh>
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-
-
+#include <mia/core/parallel.hh>
 
 NS_BEGIN(scale_3dimage_filter)
 
@@ -52,7 +49,7 @@ C3DScale::result_type do_scale(const T3DImage<T>& src, const C3DBounds& target_s
 // run x-scaling 
 	T3DImage<double> tmp(C3DBounds(target_size.x, src.get_size().y, src.get_size().z)); 
 
-	auto filter_x = [&src, &tmp, &scaler_x](const tbb::blocked_range<size_t>& range) {
+	auto filter_x = [&src, &tmp, &scaler_x](const C1DParallelRange& range) {
 		vector<double> in_buffer(src.get_size().x); 
 		vector<double> out_buffer(tmp.get_size().x);
 		for (auto z = range.begin(); z != range.end(); ++z)
@@ -64,12 +61,12 @@ C3DScale::result_type do_scale(const T3DImage<T>& src, const C3DBounds& target_s
 		
 	};
 	
-	parallel_for(tbb::blocked_range<size_t>(0, src.get_size().z, 1), filter_x); 
+	pfor(C1DParallelRange(0, src.get_size().z, 1), filter_x); 
 
 	// run y-scaling 
 	T3DImage<double> tmp2(C3DBounds(target_size.x, target_size.y, src.get_size().z)); 
 
-	auto filter_y = [&tmp, &tmp2, &scaler_y](const tbb::blocked_range<size_t>& range) {
+	auto filter_y = [&tmp, &tmp2, &scaler_y](const C1DParallelRange& range) {
 		vector<double> in_buffer(tmp.get_size().y); 
 		vector<double> out_buffer(tmp2.get_size().y);
 		for (auto z = range.begin(); z != range.end(); ++z)
@@ -80,9 +77,9 @@ C3DScale::result_type do_scale(const T3DImage<T>& src, const C3DBounds& target_s
 			}
 		
 	};
-	parallel_for(tbb::blocked_range<size_t>(0, tmp.get_size().z, 1), filter_y); 
+	pfor(C1DParallelRange(0, tmp.get_size().z, 1), filter_y); 
 
-	auto filter_z = [&tmp2, result, &scaler_z](const tbb::blocked_range<size_t>& range) {
+	auto filter_z = [&tmp2, result, &scaler_z](const C1DParallelRange& range) {
 		vector<double> in_buffer(tmp2.get_size().z); 
 		vector<double> out_buffer(result->get_size().z);
 		vector<T> out_buffer_T(result->get_size().z);
@@ -97,7 +94,7 @@ C3DScale::result_type do_scale(const T3DImage<T>& src, const C3DBounds& target_s
 		
 	};
 
-	parallel_for(tbb::blocked_range<size_t>(0, tmp2.get_size().y, 1), filter_z); 
+	pfor(C1DParallelRange(0, tmp2.get_size().y, 1), filter_z); 
 
 	return C3DScale::result_type(result);	
 }
diff --git a/mia/3d/filter/scale.hh b/mia/3d/filter/scale.hh
index 7241592..ba8a029 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c6a7941..9da6a8d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0dcbb7a..30270dd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0aebd93..2566ea5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5b8eead..ccf8992 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5fbcb62..a357df7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
  */
 
 #include <mia/core/threadedmsg.hh>
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
 
 #include <mia/core/filter.hh>
 #include <mia/core/msgstream.hh>
@@ -77,7 +76,7 @@ CSeparableConvolute::result_type CSeparableConvolute::operator () (const T3DImag
 	int cachYSize = data->get_size().y;
 	int cachZSize = data->get_size().z;
 
-	auto filter_x = [cachXSize, cachYSize, data, this](const tbb::blocked_range<size_t>& range) {
+	auto filter_x = [cachXSize, cachYSize, data, this](const C1DParallelRange& range) {
 		invec_t buffer(cachXSize);
 		for (auto z = range.begin(); z != range.end();++z) {
 			for (int y = 0; y < cachYSize; y++) {
@@ -88,7 +87,7 @@ CSeparableConvolute::result_type CSeparableConvolute::operator () (const T3DImag
 		}
 	}; 
 
-	auto filter_y = [cachXSize, cachYSize, data, this](const tbb::blocked_range<size_t>& range) {
+	auto filter_y = [cachXSize, cachYSize, data, this](const C1DParallelRange& range) {
 		invec_t buffer(cachYSize);
 		for (auto z = range.begin(); z != range.end();++z) {
 			for (int x = 0; x < cachXSize; x++) {
@@ -99,7 +98,7 @@ CSeparableConvolute::result_type CSeparableConvolute::operator () (const T3DImag
 		}
 	}; 
 
-	auto filter_z = [cachXSize, cachZSize, data, this](const tbb::blocked_range<size_t>& range) {
+	auto filter_z = [cachXSize, cachZSize, data, this](const C1DParallelRange& range) {
 		invec_t buffer(cachZSize);
 		for (auto y = range.begin(); y != range.end();++y) {
 			for (int x = 0; x < cachXSize; x++) {
@@ -111,16 +110,16 @@ CSeparableConvolute::result_type CSeparableConvolute::operator () (const T3DImag
 	}; 
 
 	if (m_kx.get()) {
-		tbb::parallel_for(tbb::blocked_range<size_t>(0, cachZSize, 1), filter_x); 
+		pfor(C1DParallelRange(0, cachZSize, 1), filter_x); 
 	}
 
 
 	if (m_ky.get()) {
-		tbb::parallel_for(tbb::blocked_range<size_t>(0, cachZSize, 1), filter_y); 
+		pfor(C1DParallelRange(0, cachZSize, 1), filter_y); 
 	}
 
 	if (m_kz.get()) {
-		tbb::parallel_for(tbb::blocked_range<size_t>(0, cachYSize, 1), filter_z); 	
+		pfor(C1DParallelRange(0, cachYSize, 1), filter_z); 	
 	}
 	return result;
 }
diff --git a/mia/3d/filter/sepconv.hh b/mia/3d/filter/sepconv.hh
index 5daf52c..0504abc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5956774..3100ac5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/filter/tee.hh
index 9d00fd2..4064f34 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f39b94b..884d23f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 deab7e2..9b17c32 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 2d2869b..35f7d63 100644
--- a/mia/3d/filter/test_combiner.cc
+++ b/mia/3d/filter/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_convert.cc b/mia/3d/filter/test_convert.cc
index 7467b80..1e566a3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ffb5ae0..b424dbf 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_distance.cc b/mia/3d/filter/test_distance.cc
index 34652a4..37c835f 100644
--- a/mia/3d/filter/test_distance.cc
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_downscale.cc b/mia/3d/filter/test_downscale.cc
index a73436d..e907f73 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_gradnorm.cc b/mia/3d/filter/test_gradnorm.cc
index 3bda0a6..e65c98b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f2a64a9..08b2d45 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_invert.cc b/mia/3d/filter/test_invert.cc
index cf93410..a552de0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0fedc76..892ab61 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f28d438..a5218b8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_labelmap.cc b/mia/3d/filter/test_labelmap.cc
index 246c7c2..9bc8672 100644
--- a/mia/3d/filter/test_labelmap.cc
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_labelscale.cc b/mia/3d/filter/test_labelscale.cc
index b43facd..08d9314 100644
--- a/mia/3d/filter/test_labelscale.cc
+++ b/mia/3d/filter/test_labelscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_load.cc b/mia/3d/filter/test_load.cc
index cdff622..dd7d7da 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 04ea099..1115152 100644
--- a/mia/3d/filter/test_lvdownscale.cc
+++ b/mia/3d/filter/test_lvdownscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_mask.cc b/mia/3d/filter/test_mask.cc
index fbbb2ef..2cdfc8e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index bf0cd3f..b8574c1 100644
--- a/mia/3d/filter/test_mean.cc
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_median.cc b/mia/3d/filter/test_median.cc
index 6cbcb57..a93409f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5c64d10..71cc18e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8bfb849..91a0a08 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 117a1f1..873b03c 100644
--- a/mia/3d/filter/test_msnormalizer.cc
+++ b/mia/3d/filter/test_msnormalizer.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_reorient.cc b/mia/3d/filter/test_reorient.cc
index a07c0d7..5c20c74 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b63bb62..3ba602c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4c9c110..5aa87f4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_seededwatershed.cc b/mia/3d/filter/test_seededwatershed.cc
index 06277d3..940e97d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_selectbig.cc b/mia/3d/filter/test_selectbig.cc
index a7b5006..678e756 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 207d470..58f4dcc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_tee.cc b/mia/3d/filter/test_tee.cc
index 0aed629..636a16a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8866368..a52162c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d6f661d..98ad73f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_watershed.cc b/mia/3d/filter/test_watershed.cc
index 94854d7..c98c726 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/filter/thinning.cc
index d32378a..c6b00e2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b43e27f..1bf8af4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0a88f78..1130f5c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/filter/transform.hh
index 39f4771..3f3c806 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/filter/watershed.cc
index cdecd94..5a582f0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 162a06a..e8690ff 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 bfb987d..ae20d92 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 66f415e..5767297 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/image.cc b/mia/3d/fullcost/image.cc
index 11f08de..7bc6eb9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/image.hh b/mia/3d/fullcost/image.hh
index e381ab0..7bfba06 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/label.cc b/mia/3d/fullcost/label.cc
index d94c845..339a719 100644
--- a/mia/3d/fullcost/label.cc
+++ b/mia/3d/fullcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -169,7 +169,7 @@ void C3DLabelFullCost::prepare_distance_fields( const C3DUBImage &image )
                 if (exist) {
 			C3DFImage prep(bool_bin.get_size()); 
 			distance_transform_prepare(bool_bin.begin(), bool_bin.end(), 
-						   prep.begin());
+						   prep.begin(), true);
 			
                         m_ref_distances[i] = distance_transform(prep); 
 			transform(m_ref_distances[i].begin(), m_ref_distances[i].end(), 
diff --git a/mia/3d/fullcost/label.hh b/mia/3d/fullcost/label.hh
index 7debac2..c47d299 100644
--- a/mia/3d/fullcost/label.hh
+++ b/mia/3d/fullcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/maskedimage.cc b/mia/3d/fullcost/maskedimage.cc
index 6b09a5a..04d00c1 100644
--- a/mia/3d/fullcost/maskedimage.cc
+++ b/mia/3d/fullcost/maskedimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -211,7 +211,7 @@ void C3DMaskedImageFullCost::do_reinit()
 			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 [", 
+                        throw create_exception<invalid_argument>("C3DMaskedImageFullCost: moving image has size [", 
                                                               m_src->get_size(), "], but corresponding mask is of size [", 
                                                               m_src_mask->get_size(), "]"); 
                 }
@@ -235,9 +235,9 @@ void C3DMaskedImageFullCost::do_reinit()
 			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(), "]"); 
+                        throw create_exception<invalid_argument>("C3DMaskedImageFullCost: reference image has size [", 
+                                                              m_ref->get_size(), "], but corresponding mask is of size [",
+                                                              m_ref_mask->get_size(), "]"); 
                 }
 
 
diff --git a/mia/3d/fullcost/maskedimage.hh b/mia/3d/fullcost/maskedimage.hh
index 750751b..8dc27a5 100644
--- a/mia/3d/fullcost/maskedimage.hh
+++ b/mia/3d/fullcost/maskedimage.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/taggedssd.cc b/mia/3d/fullcost/taggedssd.cc
index fbcc1f7..b27c39b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/taggedssd.hh b/mia/3d/fullcost/taggedssd.hh
index a29628a..1544eb6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_image.cc b/mia/3d/fullcost/test_image.cc
index 473d947..13cbf6e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_label.cc b/mia/3d/fullcost/test_label.cc
index 8f1c2a7..baf8fdd 100644
--- a/mia/3d/fullcost/test_label.cc
+++ b/mia/3d/fullcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_maskedimage.cc b/mia/3d/fullcost/test_maskedimage.cc
index 7e197c6..918fb61 100644
--- a/mia/3d/fullcost/test_maskedimage.cc
+++ b/mia/3d/fullcost/test_maskedimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +28,8 @@
 
 NS_MIA_USE
 namespace bfs=::boost::filesystem;
+using std::invalid_argument;
+using std::runtime_error; 
 
 BOOST_AUTO_TEST_CASE( test_imagefullcost_src_mask)
 {
@@ -219,3 +221,228 @@ BOOST_AUTO_TEST_CASE( test_imagefullcost_ref_mask)
 	BOOST_CHECK_CLOSE(gradient[113], 255 *255/128.0 , 0.1);
 	
 }
+
+
+BOOST_AUTO_TEST_CASE( test_imagefullcost_src_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, 1, 1, 0,
+		0, 1, 1, 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
+
+	};
+
+	const bool ref_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,
+		1, 1, 1, 1,
+		1, 1, 1, 1,
+		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 ));
+	P3DImage ref_mask(new C3DBitImage(size, ref_mask_data ));
+	
+	BOOST_REQUIRE(save_image("src.@", src)); 
+	BOOST_REQUIRE(save_image("ref.@", ref));
+	BOOST_REQUIRE(save_image("src-mask.@", ref_mask)); 
+	BOOST_REQUIRE(save_image("ref-mask.@", src_mask)); 
+
+        assert("at least one mask must be provided"); 
+	C3DMaskedImageFullCost cost("src.@", "ref.@", "src-mask.@", "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);
+
+	value = cost.cost_value();
+	BOOST_CHECK_CLOSE(value, 0.5 * 255 * 255.0/16.0  , 0.1);
+
+
+	C3DBounds read_size = C3DBounds::_0;
+
+	BOOST_CHECK(cost.get_full_size(read_size));
+	BOOST_CHECK_EQUAL(read_size, size);
+
+	C3DBounds read_wrong_size(2,3,4); 
+	BOOST_CHECK(!cost.get_full_size(read_wrong_size));
+	
+	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_CHECK(cost.has(property_gradient));
+
+	BOOST_CHECK(!cost.has("nonexistent-property"));
+
+	cost.set_size(C3DBounds(2,2,2));
+}
+
+BOOST_AUTO_TEST_CASE( test_some_expected_failures)
+{
+	P3DImage src_234(new C3DUBImage(C3DBounds(2,3,4)));
+	P3DImage src_345(new C3DUBImage(C3DBounds(3,4,5)));
+
+	P3DImage mask_234(new C3DBitImage(C3DBounds(2,3,4)));
+	P3DImage mask_345(new C3DBitImage(C3DBounds(3,4,5)));
+
+	BOOST_REQUIRE(save_image("234.@", src_234)); 
+	BOOST_REQUIRE(save_image("345.@", src_345));
+	BOOST_REQUIRE(save_image("mask_234.@", mask_234)); 
+	BOOST_REQUIRE(save_image("mask_345.@", mask_345)); 
+
+	{
+		// at least one mask should be given
+		BOOST_CHECK_THROW(C3DMaskedImageFullCost cost("234.@", "234.@", "", "", nullptr, nullptr, 
+			      C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0), invalid_argument);
+	}
+
+	{
+		C3DMaskedImageFullCost cost("234.@", "234.@", "234.@", "", nullptr, nullptr, 
+					    C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0); 
+
+		// mask should be binary 
+		BOOST_CHECK_THROW(cost.reinit(), invalid_argument);  
+	}
+
+	{
+		C3DMaskedImageFullCost cost("234.@", "234.@", "", "234.@",  nullptr, nullptr, 
+					    C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0); 
+
+		// mask should be binary 
+		BOOST_CHECK_THROW(cost.reinit(), invalid_argument);  
+	}
+
+	{
+		C3DMaskedImageFullCost cost("234.@", "345.@", "", "mask_234.@",  nullptr, nullptr, 
+					    C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0); 
+
+		// images must be of same size 
+		BOOST_CHECK_THROW(cost.reinit(), invalid_argument);  
+	}
+
+	{
+		C3DMaskedImageFullCost cost("234.@", "234.@", "", "mask_345.@",  nullptr, nullptr, 
+					    C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0); 
+		
+		// mask and image must be of same size 
+		BOOST_CHECK_THROW(cost.reinit(), invalid_argument);  
+	}
+	{
+		C3DMaskedImageFullCost cost("234.@", "234.@", "mask_345.@", "", nullptr, nullptr, 
+					    C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0); 
+		
+		// mask and image must be of same size 
+		BOOST_CHECK_THROW(cost.reinit(), invalid_argument);  
+	}
+	
+	{
+		// reference must be given 
+		BOOST_CHECK_THROW(C3DMaskedImageFullCost cost("234.@", "", "", "mask_234.@",  nullptr, nullptr, 
+				   C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0), runtime_error);
+	}
+
+	{
+		// source must be given 
+		BOOST_CHECK_THROW(C3DMaskedImageFullCost cost("", "234.@", "", "mask_234.@",  nullptr, nullptr, 
+				      C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0), runtime_error); 
+	}
+
+	{
+		// reference must exists at reinit()
+		C3DMaskedImageFullCost cost("234.@", "nonex.@", "", "mask_234.@",  nullptr, nullptr, 
+					    C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0);
+		BOOST_CHECK_THROW(cost.reinit(), invalid_argument); 
+	}
+
+	{
+		// source must exist at reinit()
+		C3DMaskedImageFullCost cost("nonex.@", "234.@", "", "mask_234.@",  nullptr, nullptr, 
+					    C3DMaskedImageCostPluginHandler::instance().produce("ssd"), 1.0);
+		BOOST_CHECK_THROW(cost.reinit(), invalid_argument); 
+	}
+
+	
+}
diff --git a/mia/3d/fullcost/test_taggedssd.cc b/mia/3d/fullcost/test_taggedssd.cc
index 57ffaa9..2250a2d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/fuzzyclustersolver_cg.cc b/mia/3d/fuzzyclustersolver_cg.cc
index bac10ef..0d0eb8e 100644
--- a/mia/3d/fuzzyclustersolver_cg.cc
+++ b/mia/3d/fuzzyclustersolver_cg.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/fuzzyclustersolver_cg.hh b/mia/3d/fuzzyclustersolver_cg.hh
index 2e895f5..a165e07 100644
--- a/mia/3d/fuzzyclustersolver_cg.hh
+++ b/mia/3d/fuzzyclustersolver_cg.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/fuzzyseg.cc b/mia/3d/fuzzyseg.cc
index 82caf4c..caaa50d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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/cmdlineparser.hh>
 #include <mia/core/histogram.hh>
+#include <mia/core/kmeans.hh>
+#include <mia/core/cmeans.hh>
 #include <mia/3d/fuzzyclustersolver_cg.hh>
 #include <mia/3d/fuzzyseg.hh>
 
@@ -42,7 +44,7 @@ using namespace std;
 #define _MAXIT 5
 
 
-typedef vector<C3DFImage*> C3DFImageVec;
+typedef vector<C3DFImage> C3DFImageVec;
 
 
 class CSegment3d : public TFilter<C3DFImageVec> {
@@ -70,110 +72,6 @@ private:
 
 using namespace std;
 
-template <class Data3D>
-vector<double> Isodata3d (const Data3D& src_image, unsigned int nClasses, unsigned int  maxPixVal)
-{
-	vector<double> clCenter(nClasses);
-
-	/** classmembership of each possible pixelvalue 0-maxPixVal */
-	vector<unsigned int> classOfGreyval( maxPixVal + 1 );
-
-	// discard all intensities below
-	unsigned int ignore = 0;
-
-	if (nClasses <= 1 || nClasses > maxPixVal) {
-		string out_of_range = ("Isodata3d: parameter --no-of-classes out of range");
-		throw invalid_argument(out_of_range);
-
-	};
-
-	// let initial cluster centers be evenly distributed between 0...maxPixelVal
-	double dCenters = (double)(maxPixVal)/(nClasses+1);  		 // get distance between clCenters
-	for (unsigned int i = 0; i < nClasses; i++)
-		clCenter[i] = (i+1) *dCenters; //save clCenters
-
-	// first pass: build a histogram
-	THistogram<THistogramFeeder<int> > histo(THistogramFeeder<int>(0, maxPixVal + 1, maxPixVal + 1));
-	histo.push_range (src_image.begin(), src_image.end ());
-
-	// now find cluster centers
-	double diff = HUGE;
-	for (unsigned int t = 0; diff > 1.0 && t < 15; t++) {
-
-		// for every grey value
-		for (unsigned int gV = ignore+1; gV < maxPixVal+1; gV++) {
-
-			double dmin = maxPixVal * maxPixVal;
-			// for each class
-			for (unsigned int nc = 0; nc < nClasses; nc++) {
-
-				//distance: shade of grey to class center
-				double dx = gV - clCenter[nc];
-				dx *= dx;
-
-				if (dx < dmin) {
-					//match nearest class
-					classOfGreyval[gV] = nc;
-					dmin = dx;
-				};
-
-			};
-
-		};
-
-		diff = 0;
-
-		for (unsigned int c = 0; c < nClasses; c++) {
-
-			//sum up #pixels belonging to class c
-			//multiply #pixel with grey value (g) & sum up
-			double nPixels = 0;
-			double sumPixelVal = 0;
-
-			for (unsigned int g = ignore+1; g < maxPixVal+1; g++) {
-				if (classOfGreyval[g] == c) {
-
-					nPixels 	+= histo[g];
-					sumPixelVal += histo[g] * g;
-				};
-			};
-
-			//if pixels in class -> get average grey value of cls
-			sumPixelVal = nPixels? sumPixelVal/nPixels : 0;
-			double dx   = sumPixelVal - clCenter[c];
-			clCenter[c] = sumPixelVal;
-			diff += dx*dx;
-
-		};
-	};
-
-	// compute classOfGreyvalue for classification
-	for (unsigned int i = 0; i < ignore+1; i++)
-		classOfGreyval[i] = 0;
-
-	for (unsigned int gV = ignore+1; gV < maxPixVal+1; gV++) {
-
-		double dmin = HUGE;
-		int newClass = 0;
-
-		for (unsigned int c = 0; c < nClasses; c++) {
-
-			// distance: grey value to current cluster center
-			double dValCtr = abs((double)gV - clCenter[c]);
-			// save class-1 with shortest distance
-			if (dValCtr < dmin) {
-				dmin = dValCtr;
-				newClass = c;
-			};
-		};
-		// set classOfGreyvalue
-		classOfGreyval[gV] = newClass + 1;
-	};
-
-	return clCenter;
-};
-
-
 
 // solves the PDE  (W + lambda1 * H1 + lambda2 * H2) = f
 void solvePDE (C3DFImage& weight_image, C3DFImage& force_image, C3DFImage& gain_image, double lambda1, double lambda2, double *firstnormr0, double relres, double min_res)
@@ -189,7 +87,7 @@ void solvePDE (C3DFImage& weight_image, C3DFImage& force_image, C3DFImage& gain_
 }
 
 template <class Data3D>
-int estimateGain (C3DFImage& gain_image, const Data3D& src_image, vector<C3DFImage*>& cls_image,
+int estimateGain (C3DFImage& gain_image, const Data3D& src_image, vector<C3DFImage>& cls_image,
 		  vector<double> &clCenter, unsigned int classes, double * firstnormr0, float relres, const vector<char>& border)
 {
 
@@ -209,7 +107,7 @@ int estimateGain (C3DFImage& gain_image, const Data3D& src_image, vector<C3DFIma
 				double forcePixel = 0;
 				double weightPixel = 0;
 				for (unsigned int k = 0; k < classes; k++)  {
-					double uk = (*cls_image[k])(x, y, z);
+					double uk = cls_image[k](x, y, z);
 					double vk = clCenter[k];
 					double v = uk * uk * vk;
 					forcePixel += v;
@@ -299,19 +197,6 @@ CSegment3d::result_type CSegment3d::operator () (const T3DImage<T>& data)
 	vector<char> border(noOfPixels);
 
 	double firstnormr0 = 1.0;
-	double dumax, sum, nom, den, dist;
-
-	// get type of iterator
-	typedef T itype;
-
-	// maximum pixel value in image
-	typename T3DImage<T>::const_iterator maximum =
-		max_element(data.begin(), data.end());
-	assert(maximum == data.end() || *maximum >= 1);
-	itype iMax = *maximum;
-
-	// increment maximum Pixel Value by one to take 0 into account
-	cvmsg()  << " The Maximum pixel value is " << (double) iMax << endl;
 
 	unsigned long k = 0;
 	typename T3DImage<T>::const_iterator data_itr = data.begin();
@@ -334,20 +219,20 @@ CSegment3d::result_type CSegment3d::operator () (const T3DImage<T>& data)
 	fill (gainBegin, gainEnd, 1.0);
 
 	// class probability image, compute initial class centers
-	vector<double> clCenter = Isodata3d (data, m_nClasses, (unsigned int) iMax);
+	vector<double> clCenter(m_nClasses);
+	vector<unsigned short> buffer(data.size()); 
+	kmeans(data.begin(), data.end(), buffer.begin(), clCenter); 
+
 
 	// some verbose output
-	cvmsg()  << "intl. class centers:" ;
-	for (unsigned int k = 0; k < m_nClasses; k++)
-		cverb << " [" << k << "] " << clCenter[k];
-	cverb << endl;
+	cvmsg()  << "intl. class centers:"  << clCenter << "\n"; 
 
 	// Algorithm step 1
 	// create class membership volumes
 
 	C3DFImageVec cls_image;
 	for (size_t i = 0; i < m_nClasses; ++i)  {
-		cls_image.push_back(new C3DFImage ( data.get_size(), data));
+		cls_image.push_back(C3DFImage ( data.get_size(), data));
 	}
 
 	for (unsigned int t = 0; t < _MAXIT; t++)  {
@@ -362,67 +247,13 @@ CSegment3d::result_type CSegment3d::operator () (const T3DImage<T>& data)
 
 		// Algorithm step 3:
 		// recompute class memberships
-		dumax = 0;
-		typename T3DImage<T>::const_iterator sp  = data.begin();
-
-		// Compute each pixel of the layer
-		for (unsigned int z = 0; z < nz; z++)  {
-			for (unsigned int y = 0; y < ny; y++)  {
-				for (unsigned int x = 0; x < nx; x++, sp++)  {
-					// get Value
-					double pixVal = *sp;
-					if (pixVal == 0)
-						continue;
-					sum = 0;
-					// get difference from gain-field
-					double gainVal = gain_image(x, y, z);
-					for (unsigned int k = 0; k < m_nClasses; k++)  {
-						dist = pixVal-gainVal*clCenter[k];
-						u[k] = dist? 1/(dist*dist): HUGE;
-						sum += u[k];
-					};
-
-					for (unsigned int k = 0; k < m_nClasses; k++)  {
-						double un = u[k]/sum;
-						double uk = (*cls_image[k])(x, y, z);
-						if (::fabs(un-uk) > dumax)
-							dumax = ::fabs(un-uk);
-						(*cls_image[k])(x, y, z) = un;
-					}
-				}
-			}
-		}
-
-		// Algorithm step 4:
-		// recompute class clCenters
-		for (unsigned int k = 0; k < m_nClasses; k++) {
-			nom = 0;
-			den = 0;
-			typename T3DImage<T>::const_iterator sp = data.begin();
-			for (unsigned int z = 0; z < nz; z++)  {
-				for (unsigned int y = 0; y < ny; y++)  {
-					for (unsigned int x = 0; x < nx; x++, sp++)  {
-						double pixVal = *sp;
-						if (pixVal == 0)
-							continue;
-						double gainVal = gain_image(x, y, z);
-						double uj      = (*cls_image[k])(x, y, z);
-						nom += uj*uj*gainVal*pixVal;
-						den += uj*uj*gainVal*gainVal;
-					}
-				}
-			}
-			clCenter[k] = den ? nom/den: 0;
-
-		}
-
-		cvmsg() << "\r[" << t << "/4]" << flush;
-		cvmsg() << " class centers:";
-
-		for (unsigned int k = 0; k < m_nClasses; k++)
-			cverb << " [" << k << "] " << clCenter[k];
-		cverb << endl;
-		if (dumax < 0.01)
+		cmeans_evaluate_probabilities(data, gain_image, clCenter, cls_image); 
+
+		double residuum = cmeans_update_class_centers(data, gain_image, cls_image, clCenter); 
+
+		
+		cvmsg() << "\r[" << t << "/4]" << " class centers:" << clCenter << ", r= " << residuum << "\n"; 
+		if (residuum < 0.0001)
 			break;
 
 	};
@@ -446,9 +277,9 @@ CSegment3d::result_type CSegment3d::operator () (const T3DImage<T>& data)
 				       PAttribute(new CVDoubleAttribute( clCenter)));
 	m_out.reset(corrected_image);
 	for (size_t i = 0; i < cls_image.size(); ++i) {
-		cls_image[i]->set_attribute("class_number",
+		cls_image[i].set_attribute("class_number",
 					    PAttribute(new CIntAttribute( i )));
-		cls_image[i]->set_attribute("class_centers",
+		cls_image[i].set_attribute("class_centers",
 					    PAttribute(new CVDoubleAttribute( clCenter)));
 	}
 	return cls_image;
@@ -468,7 +299,7 @@ EXPORT_3D P3DImage fuzzy_segment_3d(const C3DImage& src, size_t noOfClasses, flo
 	C3DFImageVec imagesVector = mia::accumulate (segment3D, src);
 
 	for (size_t i=0; i < noOfClasses; i++) {
-		classes.push_back( P3DImage(imagesVector[i]) );
+		classes.push_back( P3DImage(imagesVector[i].clone()) );
 	}
 	return segment3D.get_out_image();
 }
diff --git a/mia/3d/fuzzyseg.hh b/mia/3d/fuzzyseg.hh
index 8f62361..42751b9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3b6e70d..adcc31c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 90431ce..532a930 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c5bdc44..a354860 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -286,6 +286,13 @@ const C3DBounds& T3DImage<T>::get_size() const
 	return m_image.get_size();
 }
 
+template <class T>
+std::pair<double, double> T3DImage<T>::get_minmax_intensity() const
+{
+	auto mm = std::minmax_element( m_image.begin(), m_image.end());
+	return std::pair<double, double>(*mm.first, *mm.second);
+}
+
 
 struct FGetGradient3D: public TFilter< C3DFVectorfield> {
 	template <typename T>
diff --git a/mia/3d/image.hh b/mia/3d/image.hh
index 0a8a7c7..7112a3b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -121,6 +121,9 @@ public:
 	    @remark orientation is currently not really used
 	*/
 	void set_orientation(E3DImageOrientation orient);
+
+	/// \returns a pair (minimum, maximum) pixel intensity 
+	virtual std::pair<double, double> get_minmax_intensity() const = 0; 
 private:
 	EPixelType m_pixel_type;
 };
@@ -366,6 +369,8 @@ public:
 	/// \returns the 3D size of the image
 	virtual const C3DBounds& get_size() const;
 
+	/// \returns minimum and mximum pixel intensity of the image
+	std::pair<double, double> get_minmax_intensity() const; 
 private:
 	T3DDatafield<T> m_image;
 };
diff --git a/mia/3d/imagecollect.cc b/mia/3d/imagecollect.cc
index 6dec2fc..088646b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f2d6cd3..7ab3bba 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/imagedraw.cc b/mia/3d/imagedraw.cc
index 7a921f4..22a4279 100644
--- a/mia/3d/imagedraw.cc
+++ b/mia/3d/imagedraw.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/imagedraw.cxx b/mia/3d/imagedraw.cxx
index 2367a70..8d820e4 100644
--- a/mia/3d/imagedraw.cxx
+++ b/mia/3d/imagedraw.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/imagedraw.hh b/mia/3d/imagedraw.hh
index 3a2b03c..a954d45 100644
--- a/mia/3d/imagedraw.hh
+++ b/mia/3d/imagedraw.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 42eb9a0..af6f7c3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +74,7 @@ bool  EXPORT_3D save_image(const std::string& filename, C3DImage& image)
       return save_image(filename, P3DImage(&image, void_destructor<C3DImage>())); 
 }
 
+template class TPlugin<io_3dimage_data, io_plugin_type>;
 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 a0c9dbe..c271116 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 @@ struct EXPORT_3D io_3dimage_data {
 */
 typedef TIOPlugin<io_3dimage_data> C3DImageIOPlugin;
 
+extern template class EXPORT_3D TPlugin<io_3dimage_data, io_plugin_type>;
+extern template class EXPORT_3D TIOPlugin<io_3dimage_data>; 
+
 /**
    @ingroup io
    @brief Handler for the plug-ins that store and load 3D images. 
diff --git a/mia/3d/imageiotest.cc b/mia/3d/imageiotest.cc
index eef35b8..760b8a4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a1d6b3b..0075a5e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 364547e..3e368e5 100644
--- a/mia/3d/imagetest.cc
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/imagetest.hh
index b190061..a1f60b4 100644
--- a/mia/3d/imagetest.hh
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/interpolator.cc b/mia/3d/interpolator.cc
index d8c616c..784663f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ NS_MIA_BEGIN
 
 using namespace std;
 
-CWeightCache::CWeightCache(int kernel_size, 
-			   const CSplineBoundaryCondition& xbc, 
-			   const CSplineBoundaryCondition& ybc, 
-			   const CSplineBoundaryCondition& zbc):
+C3DWeightCache::C3DWeightCache(int kernel_size, 
+			       const CSplineBoundaryCondition& xbc, 
+			       const CSplineBoundaryCondition& ybc, 
+			       const CSplineBoundaryCondition& zbc):
 	x(kernel_size, xbc, kernel_size < 3), 
 	y(kernel_size, ybc, true), 
 	z(kernel_size, zbc, true)
@@ -113,42 +113,6 @@ PSplineKernel C3DInterpolatorFactory::get_kernel() const
 	return m_kernel; 
 }
 
-C3DInterpolatorFactory *create_3dinterpolation_factory(EInterpolation type, EBoundaryConditions bc)
-{
-	string boundary; 
-	switch (bc) {
-	case bc_mirror_on_bounds: 
-		boundary = "mirror"; 
-		break; 
-		
-	case bc_repeat: 
-		boundary = "repeat"; 
-		break; 
-	case bc_zero: 
-		boundary = "zero"; 
-		break; 
-	default: 
-		throw invalid_argument("Unknown boundary consitions requested"); 
-	}
-	
-	string kernel; 
-	switch (type) {
-	case ip_nn: 
-	case ip_bspline0: kernel = "bspline:d=0"; break; 
-	case ip_linear:
-	case ip_bspline1: kernel = "bspline:d=1"; break; 
-	case ip_bspline2: kernel = "bspline:d=2"; break; 
-	case ip_bspline3: kernel = "bspline:d=3"; break; 
-	case ip_bspline4: kernel = "bspline:d=4"; break; 
-	case ip_bspline5: kernel = "bspline:d=5"; break; 
-	case ip_omoms3:   kernel = "omoms:d=3"; break;
-	default: 
-		throw invalid_argument("create_interpolator_factory:Unknown interpolator type requested"); 
-	}; 
-
-	return new C3DInterpolatorFactory(kernel, boundary); 
-}
-
 
 #ifdef __SSE2__
 typedef double v2df __attribute__ ((vector_size (16)));
@@ -189,10 +153,8 @@ inline void my_daxpy_4(double weight, v2df *in, v2df *out)
   if B-spline 1 is used 
 */
 
-double add_3d<T3DDatafield< double >, 2>::value(const T3DDatafield< double >&  coeff, 
-					       const CSplineKernel::SCache& xc, 
-					       const CSplineKernel::SCache& yc,
-					       const CSplineKernel::SCache& zc)
+double add_3d<T3DDatafield< double >, 2>::value(const T3DDatafield< double >&  coeff,
+						const C3DWeightCache& cache)
 {
 	const int dx = coeff.get_size().x;
 	const int dxy = coeff.get_size().x *coeff.get_size().y;
@@ -200,29 +162,29 @@ double add_3d<T3DDatafield< double >, 2>::value(const T3DDatafield< double >&  c
 	
 	double __attribute__((aligned(16))) c[8];
 	
-	v2df xweights = _mm_loadu_pd(&xc.weights[0]);
-	v2df yweight0 = _mm_load1_pd(&yc.weights[0]);
-	v2df yweight1 = _mm_load1_pd(&yc.weights[1]);
-	v2df zweight0 = _mm_load1_pd(&zc.weights[0]);
-	v2df zweight1 = _mm_load1_pd(&zc.weights[1]);
+	v2df xweights = _mm_loadu_pd(&cache.x.weights[0]);
+	v2df yweight0 = _mm_load1_pd(&cache.y.weights[0]);
+	v2df yweight1 = _mm_load1_pd(&cache.y.weights[1]);
+	v2df zweight0 = _mm_load1_pd(&cache.z.weights[0]);
+	v2df zweight1 = _mm_load1_pd(&cache.z.weights[1]);
 	
-	if (xc.is_flat) {
+	if (cache.x.is_flat) {
 		
 		for (size_t z = 0; z < 2; ++z) {
-			const double *slice = &coeff[zc.index[z] * dxy]; 
+			const double *slice = &coeff[cache.z.index[z] * dxy]; 
 			for (size_t y = 0; y < 2; ++y, idx +=2 ) {
-				const double *p = &slice[yc.index[y] * dx];
-				c[idx    ] = p[xc.start_idx];
-				c[idx + 1] = p[xc.start_idx + 1];
+				const double *p = &slice[cache.y.index[y] * dx];
+				c[idx    ] = p[cache.x.start_idx];
+				c[idx + 1] = p[cache.x.start_idx + 1];
 			}
 		}
 	}else{
 		for (size_t z = 0; z < 2; ++z) {
-			const double *slice = &coeff[zc.index[z] * dxy]; 
+			const double *slice = &coeff[cache.z.index[z] * dxy]; 
 			for (size_t y = 0; y < 2; ++y, idx += 2) {
-				const double *p = &slice[yc.index[y] * dx];
-				c[idx    ] = p[xc.index[0]]; 
-				c[idx + 1] = p[xc.index[1]]; 
+				const double *p = &slice[cache.y.index[y] * dx];
+				c[idx    ] = p[cache.x.index[0]]; 
+				c[idx + 1] = p[cache.x.index[1]]; 
 			}
 		}
 	}
@@ -252,10 +214,8 @@ double add_3d<T3DDatafield< double >, 2>::value(const T3DDatafield< double >&  c
 /*
   In this function the registration algorithm spends approx 30% of the time 
 */
-double add_3d<T3DDatafield< double >, 4>::value(const T3DDatafield< double >&  coeff, 
-		    const CSplineKernel::SCache& xc, 
-		    const CSplineKernel::SCache& yc,
-		    const CSplineKernel::SCache& zc) 
+double add_3d<T3DDatafield< double >, 4>::value(const T3DDatafield< double >&  coeff,
+						const C3DWeightCache& wicache) 
 {
 	const int dx = coeff.get_size().x; 
 	const int dxy = coeff.get_size().x *coeff.get_size().y; 
@@ -266,25 +226,25 @@ double add_3d<T3DDatafield< double >, 4>::value(const T3DDatafield< double >&  c
 
 	// if the boundaries are not mirrored, then we can load without looking at each index 
 	// this should happen more often 
-	if (xc.is_flat) {
+	if (wicache.x.is_flat) {
 		for (int z = 0; z < 4; ++z) {
-			const double *slice = &coeff[zc.index[z] * dxy]; 
+			const double *slice = &coeff[wicache.z.index[z] * dxy]; 
 			for (int y = 0; y < 4; ++y, idx+=2) {
-				const double *p = &slice[yc.index[y] * dx];
-				cache[idx  ] = _mm_loadu_pd(&p[xc.start_idx]);
-				cache[idx+1] = _mm_loadu_pd(&p[xc.start_idx+2]);
+				const double *p = &slice[wicache.y.index[y] * dx];
+				cache[idx  ] = _mm_loadu_pd(&p[wicache.x.start_idx]);
+				cache[idx+1] = _mm_loadu_pd(&p[wicache.x.start_idx+2]);
 			}
 		}
 	}else{
 		double __attribute__((aligned(16))) c[4]; 
 		for (int z = 0; z < 4; ++z) {
-			const double *slice = &coeff[zc.index[z] * dxy]; 
+			const double *slice = &coeff[wicache.z.index[z] * dxy]; 
 			for (int y = 0; y < 4; ++y, idx+=2) {
-				const double *p = &slice[yc.index[y] * dx];
-				c[0] = p[xc.index[0]]; 
-				c[1] = p[xc.index[1]]; 
-				c[2] = p[xc.index[2]]; 
-				c[3] = p[xc.index[3]]; 
+				const double *p = &slice[wicache.y.index[y] * dx];
+				c[0] = p[wicache.x.index[0]]; 
+				c[1] = p[wicache.x.index[1]]; 
+				c[2] = p[wicache.x.index[2]]; 
+				c[3] = p[wicache.x.index[3]]; 
 
 				cache[idx  ] = 	_mm_load_pd(&c[0]); 
 				cache[idx+1] = 	_mm_load_pd(&c[2]); 
@@ -293,20 +253,20 @@ double add_3d<T3DDatafield< double >, 4>::value(const T3DDatafield< double >&  c
 	}
 	v2df  target1[8]; 
 	// apply splines 
-	my_daxpy_16_zero(zc.weights[0], &cache[ 0], target1);
-	my_daxpy_16(zc.weights[1], &cache[8], target1);
-	my_daxpy_16(zc.weights[2], &cache[16], target1);
-	my_daxpy_16(zc.weights[3], &cache[24], target1);
+	my_daxpy_16_zero(wicache.z.weights[0], &cache[ 0], target1);
+	my_daxpy_16(wicache.z.weights[1], &cache[8], target1);
+	my_daxpy_16(wicache.z.weights[2], &cache[16], target1);
+	my_daxpy_16(wicache.z.weights[3], &cache[24], target1);
 
 	v2df target2[2];
-	my_daxpy_4_zero(yc.weights[0], &target1[ 0], target2);
-	my_daxpy_4(yc.weights[1], &target1[ 2], target2);
-	my_daxpy_4(yc.weights[2], &target1[ 4], target2);
-	my_daxpy_4(yc.weights[3], &target1[6], target2);
+	my_daxpy_4_zero(wicache.y.weights[0], &target1[ 0], target2);
+	my_daxpy_4(wicache.y.weights[1], &target1[ 2], target2);
+	my_daxpy_4(wicache.y.weights[2], &target1[ 4], target2);
+	my_daxpy_4(wicache.y.weights[3], &target1[6], target2);
 
 	v2df wx[2]; 
-	wx[0] = _mm_loadu_pd(&xc.weights[0]); 
-	wx[1] = _mm_loadu_pd(&xc.weights[2]);
+	wx[0] = _mm_loadu_pd(&wicache.x.weights[0]); 
+	wx[1] = _mm_loadu_pd(&wicache.x.weights[2]);
 	
 	target2[0] *= wx[0]; 
 	target2[1] *= wx[1]; 
@@ -361,37 +321,34 @@ inline void my_daxpy_4(float weight, v4df* in, v4df *out)
   if B-spline 1 is used 
 */
 
-float add_3d<T3DDatafield< float >, 2>::value(const T3DDatafield< float >&  coeff, 
-					      const CSplineKernel::SCache& xc, 
-					      const CSplineKernel::SCache& yc,
-					      const CSplineKernel::SCache& zc)
+float add_3d<T3DDatafield< float >, 2>::value(const T3DDatafield< float >&  coeff, const C3DWeightCache& cache)
 {
 	const int dx = coeff.get_size().x; 
 	const int dxy = coeff.get_size().x *coeff.get_size().y; 
 	int idx = 0; 
 
-	assert(!xc.is_flat); 
+	assert(!cache.x.is_flat); 
 
 	float __attribute__((aligned(16))) c[8];
 	float __attribute__((aligned(16))) w[4];
 	
-	w[0] = xc.weights[0]; 
-	w[1] = xc.weights[1]; 
-	w[2] = yc.weights[0]; 
-	w[3] = yc.weights[1]; 
+	w[0] = cache.x.weights[0]; 
+	w[1] = cache.x.weights[1]; 
+	w[2] = cache.y.weights[0]; 
+	w[3] = cache.y.weights[1]; 
 
 	for (int z = 0; z < 2; ++z) {
-		const float *slice = &coeff[zc.index[z] * dxy]; 
+		const float *slice = &coeff[cache.z.index[z] * dxy]; 
 		for (int y = 0; y < 2; ++y, idx += 2) {
-			const float *p = &slice[yc.index[y] * dx];
-			c[idx    ] = p[xc.index[0]]; 
-			c[idx + 1] = p[xc.index[1]]; 
+			const float *p = &slice[cache.y.index[y] * dx];
+			c[idx    ] = p[cache.x.index[0]]; 
+			c[idx + 1] = p[cache.x.index[1]]; 
 		}
 	}
 
 	v4df weights = _mm_load_ps(w); 
-	v4df wz0 = _mm_set1_ps(zc.weights[0]); 
-	v4df wz1 = _mm_set1_ps(zc.weights[1]);
+	v4df wz0 = _mm_set1_ps(cache.z.weights[0]); 
+	v4df wz1 = _mm_set1_ps(cache.z.weights[1]);
 	v4df whx = _mm_shuffle_ps(weights, weights, _MM_SHUFFLE(1,0,1,0)); 
 	v4df why = _mm_shuffle_ps(weights, weights, _MM_SHUFFLE(3,3,2,2)); 
 	v4df z0  = _mm_load_ps(&c[0]); 
@@ -420,10 +377,7 @@ float add_3d<T3DDatafield< float >, 2>::value(const T3DDatafield< float >&  coef
   In this function the registration algorithm spends approx 30% of the time 
   if B-spline 3 is used 
 */
-float add_3d<T3DDatafield< float >, 4>::value(const T3DDatafield< float >&  coeff, 
-		    const CSplineKernel::SCache& xc, 
-		    const CSplineKernel::SCache& yc,
-		    const CSplineKernel::SCache& zc) 
+float add_3d<T3DDatafield< float >, 4>::value(const T3DDatafield< float >&  coeff, const C3DWeightCache& wicache) 
 {
 	const int dx = coeff.get_size().x; 
 	const int dxy = coeff.get_size().x *coeff.get_size().y; 
@@ -434,48 +388,48 @@ float add_3d<T3DDatafield< float >, 4>::value(const T3DDatafield< float >&  coef
 
 	// if the boundaries are not mirrored, then we can load without looking at each index 
 	// this should happen more often 
-	if (xc.is_flat) {
+	if (wicache.x.is_flat) {
 		for (int z = 0; z < 4; ++z) {
-			const float *slice = &coeff[zc.index[z] * dxy]; 
+			const float *slice = &coeff[wicache.z.index[z] * dxy]; 
 			for (int y = 0; y < 4; ++y, ++idx) {
-				const float *p = &slice[yc.index[y] * dx];
-				cache[idx] = _mm_loadu_ps(&p[xc.start_idx]);
+				const float *p = &slice[wicache.y.index[y] * dx];
+				cache[idx] = _mm_loadu_ps(&p[wicache.x.start_idx]);
 			}
 		}
 	}else{
 		float __attribute__((aligned(16))) c[4]; 
 		for (int z = 0; z < 4; ++z) {
-			const float *slice = &coeff[zc.index[z] * dxy]; 
+			const float *slice = &coeff[wicache.z.index[z] * dxy]; 
 			for (int y = 0; y < 4; ++y, ++idx) {
-				const float *p = &slice[yc.index[y] * dx];
-				c[0] = p[xc.index[0]]; 
-				c[1] = p[xc.index[1]]; 
-				c[2] = p[xc.index[2]]; 
-				c[3] = p[xc.index[3]]; 
+				const float *p = &slice[wicache.y.index[y] * dx];
+				c[0] = p[wicache.x.index[0]]; 
+				c[1] = p[wicache.x.index[1]]; 
+				c[2] = p[wicache.x.index[2]]; 
+				c[3] = p[wicache.x.index[3]]; 
 				cache[idx] = _mm_load_ps(c);
 			}
 		}
 	}
-	float wy = yc.weights[0]; 
+	float wy = wicache.y.weights[0]; 
 	v4df  target1[4]; 
 	// apply splines 
-	my_daxpy_16_zero(zc.weights[0], &cache[ 0], target1);
-	my_daxpy_16(zc.weights[1],      &cache[ 4], target1);
-	my_daxpy_16(zc.weights[2],      &cache[ 8], target1);
-	my_daxpy_16(zc.weights[3],      &cache[12], target1);
+	my_daxpy_16_zero(wicache.z.weights[0], &cache[ 0], target1);
+	my_daxpy_16(wicache.z.weights[1],      &cache[ 4], target1);
+	my_daxpy_16(wicache.z.weights[2],      &cache[ 8], target1);
+	my_daxpy_16(wicache.z.weights[3],      &cache[12], target1);
 
 	;
 
 	v4df w=_mm_set1_ps(wy); 
 	v4df target2 = w * target1[0]; 
 	
-//	my_daxpy_4_zero(yc.weights[0], &target1[0], &target2);
-	my_daxpy_4(yc.weights[1],      &target1[1], &target2);
-	my_daxpy_4(yc.weights[2],      &target1[2], &target2);
-	my_daxpy_4(yc.weights[3],      &target1[3], &target2);
+//	my_daxpy_4_zero(wicache.y.weights[0], &target1[0], &target2);
+	my_daxpy_4(wicache.y.weights[1],      &target1[1], &target2);
+	my_daxpy_4(wicache.y.weights[2],      &target1[2], &target2);
+	my_daxpy_4(wicache.y.weights[3],      &target1[3], &target2);
 	
 	float __attribute__((aligned(16)))  wxa[4]; 
-	copy(xc.weights.begin(), xc.weights.end(), wxa); 
+	copy(wicache.x.weights.begin(), wicache.x.weights.end(), wxa); 
 	v4df wx = _mm_load_ps(wxa); 
 	target2 *= wx; 
 #ifdef __SSE3__	
diff --git a/mia/3d/interpolator.cxx b/mia/3d/interpolator.cxx
index 7087c55..aaf75af 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,22 +21,23 @@
 #include <cmath>
 
 #include <mia/core/threadedmsg.hh>
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
 
 NS_MIA_BEGIN
 
 template <class T>
 struct min_max_3d {
-	static void get( const T3DDatafield<T>& data, T* min, T*max)
+	static void get( const T3DDatafield<T>& data,
+			 typename T3DDatafield<T>::value_type& min,
+			 typename T3DDatafield<T>::value_type& max)
 	{
-		typename T3DDatafield<T>::const_iterator i = data.begin(); 
-		typename T3DDatafield<T>::const_iterator e = data.end(); 
-		*min = *max = *i++; 
+		auto i = data.begin(); 
+		auto e = data.end(); 
+		min = max = *i++; 
 		
 		while (i != e) {
-			if (*i > *max) *max = *i; 
-			if (*i < *min) *min = *i; 
+			if (*i > max) max = *i; 
+			if (*i < min) min = *i; 
 			++i; 
 		}
 	}
@@ -44,19 +45,19 @@ struct min_max_3d {
 
 template <class  T>
 struct min_max_3d<T3DVector<T> > {
-	static void get( const T3DDatafield<T3DVector<T> >& data, T3DVector<T>* min, T3DVector<T>*max)
+	static void get( const T3DDatafield<T3DVector<T> >& data, T3DVector<T>& min, T3DVector<T>& max)
 	{
-		typename T3DDatafield<T3DVector<T> >::const_iterator i = data.begin(); 
-		typename T3DDatafield<T3DVector<T> >::const_iterator e = data.end(); 
-		*min = *max = *i++; 
+		auto i = data.begin(); 
+		auto e = data.end(); 
+		min = max = *i++; 
 		
 		while (i != e) {
-			if (i->x > max->x) max->x = i->x; 
-			if (i->y > max->y) max->y = i->y; 
-			if (i->z > max->z) max->z = i->z; 
-			if (i->x < min->x) min->x = i->x; 
-			if (i->y < min->y) min->y = i->y; 
-			if (i->z < min->z) min->z = i->z; 
+			if (i->x > max.x) max.x = i->x; 
+			if (i->y > max.y) max.y = i->y; 
+			if (i->z > max.z) max.z = i->z; 
+			if (i->x < min.x) min.x = i->x; 
+			if (i->y < min.y) min.y = i->y; 
+			if (i->z < min.z) min.z = i->z; 
 			++i; 
 		}
 	}
@@ -71,9 +72,7 @@ T3DConvoluteInterpolator<T>::T3DConvoluteInterpolator(const T3DDatafield<T>& ima
 	m_xbc(produce_spline_boundary_condition("mirror")), 
 	m_ybc(produce_spline_boundary_condition("mirror")),
 	m_zbc(produce_spline_boundary_condition("mirror")),
-	m_x_cache(kernel->size(), *m_xbc, m_kernel->size() < 3), 
-	m_y_cache(kernel->size(), *m_ybc, true), 
-	m_z_cache(kernel->size(), *m_zbc, true)
+	m_cache(kernel->size(), *m_xbc, *m_ybc, *m_zbc)
 {
 
 	prefilter(image); 
@@ -90,9 +89,7 @@ T3DConvoluteInterpolator<T>::T3DConvoluteInterpolator(const T3DDatafield<T>& ima
 	m_xbc(xbc.clone()), 
 	m_ybc(ybc.clone()),
 	m_zbc(zbc.clone()),
-	m_x_cache(kernel->size(), *m_xbc, m_kernel->size() < 3), 
-	m_y_cache(kernel->size(), *m_ybc, true), 
-	m_z_cache(kernel->size(), *m_zbc, true)
+	m_cache(kernel->size(), *m_xbc, *m_ybc, *m_zbc)
 {
 	prefilter(image); 
 }
@@ -103,13 +100,13 @@ void T3DConvoluteInterpolator<T>::prefilter(const T3DDatafield<T>& image)
 {
 
 	m_xbc->set_width(image.get_size().x); 
-	m_x_cache.reset(); 
+	m_cache.x.reset(); 
 	m_ybc->set_width(image.get_size().y); 
-	m_y_cache.reset(); 
+	m_cache.y.reset(); 
 	m_zbc->set_width(image.get_size().z);
-	m_z_cache.reset(); 
+	m_cache.z.reset(); 
 
-	min_max_3d<T>::get(image, &m_min, &m_max);
+	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(); 
@@ -126,7 +123,7 @@ void T3DConvoluteInterpolator<T>::prefilter(const T3DDatafield<T>& image)
 	int cachZSize = image.get_size().z;
 	
 
-	auto filter_x = [this, cachXSize, cachYSize, poles](const tbb::blocked_range<size_t>& range_z) {
+	auto filter_x = [this, cachXSize, cachYSize, poles](const C1DParallelRange& range_z) {
 		coeff_vector buffer(cachXSize);
 		for (auto z = range_z.begin(); z != range_z.end() ; ++z){
 			for (int y = 0; y < cachYSize; y++) {
@@ -136,10 +133,10 @@ void T3DConvoluteInterpolator<T>::prefilter(const T3DDatafield<T>& image)
 			}
 		}
 	};
-	parallel_for(tbb::blocked_range<size_t>(0, cachZSize, 1), filter_x); 
+	pfor(C1DParallelRange(0, cachZSize, 1), filter_x); 
 	
 	
-	auto filter_y = [this, cachXSize, cachYSize, poles](const tbb::blocked_range<size_t>& range_z) {
+	auto filter_y = [this, cachXSize, cachYSize, poles](const C1DParallelRange& range_z) {
 		coeff_vector buffer(cachYSize);
 		for (auto z = range_z.begin(); z  != range_z.end() ; ++z){
 			for (int x = 0; x < cachXSize; x++) {
@@ -149,10 +146,10 @@ void T3DConvoluteInterpolator<T>::prefilter(const T3DDatafield<T>& image)
 			}
 		}
 	};
-	parallel_for(tbb::blocked_range<size_t>(0, cachZSize, 1), filter_y); 
+	pfor(C1DParallelRange(0, cachZSize, 1), filter_y); 
 	
 
-	auto filter_z = [this, cachXSize, cachZSize, poles](const tbb::blocked_range<size_t>& range_y) {
+	auto filter_z = [this, cachXSize, cachZSize, poles](const C1DParallelRange& range_y) {
 		coeff_vector buffer(cachZSize);
 		for (auto y = range_y.begin(); y  != range_y.end() ; ++y){
 			for (int x = 0; x < cachXSize; x++) {
@@ -162,14 +159,14 @@ void T3DConvoluteInterpolator<T>::prefilter(const T3DDatafield<T>& image)
 			}
 		}
 	};
-	parallel_for(tbb::blocked_range<size_t>(0, cachYSize, 1), filter_z); 
+	pfor(C1DParallelRange(0, cachYSize, 1), filter_z); 
 
 }
 
 template <typename T>
-CWeightCache T3DConvoluteInterpolator<T>::create_cache() const
+C3DWeightCache T3DConvoluteInterpolator<T>::create_cache() const
 {
-	return CWeightCache(m_kernel->size(), *m_xbc, *m_ybc, *m_zbc); 
+	return C3DWeightCache(m_kernel->size(), *m_xbc, *m_ybc, *m_zbc); 
 }
 
 template <typename T>
@@ -191,9 +188,7 @@ template <class C, int size>
 struct add_3d {
 	typedef typename C::value_type U; 
 	
-	static typename C::value_type value(const C&  coeff, const CSplineKernel::SCache& xc, 
-					    const CSplineKernel::SCache& yc,
-					    const CSplineKernel::SCache& zc) 
+	static typename C::value_type value(const C&  coeff, const C3DWeightCache& cache) 
 	{
 		U result = U();
 		
@@ -201,14 +196,14 @@ struct add_3d {
 			U ry = U();
 			for (size_t y = 0; y < size; ++y) {
 				U rx = U();
-				const U *p = &coeff(0, yc.index[y], zc.index[z]);
+				const U *p = &coeff(0, cache.y.index[y], cache.z.index[z]);
 				for (size_t x = 0; x < size; ++x) {
-					int xinx = xc.is_flat ? xc.start_idx +x : xc.index[x]; 
-					rx += xc.weights[x] * p[xinx];
+					int xinx = cache.x.is_flat ? cache.x.start_idx + x : cache.x.index[x]; 
+					rx += cache.x.weights[x] * p[xinx];
 				}
-				ry += yc.weights[y] * rx; 
+				ry += cache.y.weights[y] * rx; 
 			}
-			result += zc.weights[z] * ry; 
+			result += cache.z.weights[z] * ry; 
 		}
 		return result; 
 	}
@@ -216,13 +211,10 @@ struct add_3d {
 
 template <typename T>
 struct add_3d<T3DDatafield< T >, 1> {
-	static T value(const T3DDatafield< T >&  coeff, 
-		       const CSplineKernel::SCache& xc, 
-		       const CSplineKernel::SCache& yc,
-		       const CSplineKernel::SCache& zc) 
+	static T value(const T3DDatafield< T >&  coeff, const C3DWeightCache& cache) 
 		{
-			return xc.weights[0] *  yc.weights[0] * zc.weights[0] * 
-				coeff(xc.index[0], yc.index[0], zc.index[0] ) ; 
+			return cache.x.weights[0] *  cache.y.weights[0] * cache.z.weights[0] * 
+				coeff(cache.x.index[0], cache.y.index[0], cache.z.index[0] ) ; 
 		}
 };
 
@@ -230,19 +222,13 @@ struct add_3d<T3DDatafield< T >, 1> {
 #ifdef __SSE2__
 template <>
 struct add_3d<T3DDatafield< double >, 2> {
-	static double value(const T3DDatafield< double >&  coeff, 
-			    const CSplineKernel::SCache& xc, 
-			    const CSplineKernel::SCache& yc,
-			    const CSplineKernel::SCache& zc); 
+	static double value(const T3DDatafield< double >&  coeff, const C3DWeightCache& cache); 
 	
 };
 
 template <>
 struct add_3d<T3DDatafield< double >, 4> {
-	static double value(const T3DDatafield< double >&  coeff, 
-			    const CSplineKernel::SCache& xc, 
-			    const CSplineKernel::SCache& yc,
-			    const CSplineKernel::SCache& zc); 
+	static double value(const T3DDatafield< double >&  coeff, const C3DWeightCache& cache); 
 	
 };
 #endif
@@ -250,25 +236,19 @@ struct add_3d<T3DDatafield< double >, 4> {
 #ifdef __SSE__
 template <>
 struct add_3d<T3DDatafield< float >, 4> {
-	static float value(const T3DDatafield< float >&  coeff, 
-			    const CSplineKernel::SCache& xc, 
-			    const CSplineKernel::SCache& yc,
-			    const CSplineKernel::SCache& zc); 
+	static float value(const T3DDatafield< float >&  coeff, const C3DWeightCache& cache); 
 	
 };
 template <>
 struct add_3d<T3DDatafield< float >, 2> {
-	static float value(const T3DDatafield< float >&  coeff, 
-			    const CSplineKernel::SCache& xc, 
-			    const CSplineKernel::SCache& yc,
-			    const CSplineKernel::SCache& zc); 
+	static float value(const T3DDatafield< float >&  coeff, const C3DWeightCache& cache); 
 	
 };
 
 #endif
 
 template <typename T>
-T  T3DConvoluteInterpolator<T>::operator () (const C3DFVector& x, CWeightCache& cache) const
+T  T3DConvoluteInterpolator<T>::operator () (const C3DFVector& x, C3DWeightCache& cache) const
 {
 	typedef typename TCoeff3D::value_type U; 
 	
@@ -290,12 +270,12 @@ T  T3DConvoluteInterpolator<T>::operator () (const C3DFVector& x, CWeightCache&
 	// With SSE and SSE2 available kernel sizes 2 and 4 and the use of float and double 
 	// scalar fields are optimized.
 	switch (m_kernel->size()) {
-	case 1: result = add_3d<TCoeff3D,1>::value(m_coeff, cache.x, cache.y, cache.z); break; 
-	case 2: result = add_3d<TCoeff3D,2>::value(m_coeff, cache.x, cache.y, cache.z); break; 
-	case 3: result = add_3d<TCoeff3D,3>::value(m_coeff, cache.x, cache.y, cache.z); break; 
-	case 4: result = add_3d<TCoeff3D,4>::value(m_coeff, cache.x, cache.y, cache.z); break; 
-	case 5: result = add_3d<TCoeff3D,5>::value(m_coeff, cache.x, cache.y, cache.z); break; 
-	case 6: result = add_3d<TCoeff3D,6>::value(m_coeff, cache.x, cache.y, cache.z); break; 
+	case 1: result = add_3d<TCoeff3D,1>::value(m_coeff, cache); break; 
+	case 2: result = add_3d<TCoeff3D,2>::value(m_coeff, cache); break; 
+	case 3: result = add_3d<TCoeff3D,3>::value(m_coeff, cache); break; 
+	case 4: result = add_3d<TCoeff3D,4>::value(m_coeff, cache); break; 
+	case 5: result = add_3d<TCoeff3D,5>::value(m_coeff, cache); break; 
+	case 6: result = add_3d<TCoeff3D,6>::value(m_coeff, cache); break; 
 	default: {
 		assert(0 && "kernel sizes above 5 are not implemented"); 
 	}
@@ -314,15 +294,15 @@ T  T3DConvoluteInterpolator<T>::operator () (const C3DFVector& x) const
 	
 	// x will usually be the fastest changing index, therefore, it is of no use to use the cache 
 	// at the same time it's access may be handled "flat" 
-	m_kernel->get_uncached(x.x, m_x_cache);
+	m_kernel->get_uncached(x.x, m_cache.x);
 
 	// the other two coordinates are changing slowly and caching makes sense 
 	// however, the index set will always be fully evaluated 
-	if (x.y != m_y_cache.x) 
-		m_kernel->get_cached(x.y, m_y_cache);
+	if (x.y != m_cache.y.x) 
+		m_kernel->get_cached(x.y, m_cache.y);
 	
-	if (x.z != m_z_cache.x) 
-		m_kernel->get_cached(x.z, m_z_cache);	
+	if (x.z != m_cache.z.x) 
+		m_kernel->get_cached(x.z, m_cache.z);	
 	
 	U result = U();
 	// now we give the compiler a chance to optimize based on kernel size and data type.  
@@ -330,12 +310,12 @@ T  T3DConvoluteInterpolator<T>::operator () (const C3DFVector& x) const
 	// With SSE and SSE2 available kernel sizes 2 and 4 and the use of float and double 
 	// scalar fields are optimized.
 	switch (m_kernel->size()) {
-	case 1: result = add_3d<TCoeff3D,1>::value(m_coeff, m_x_cache, m_y_cache, m_z_cache); break; 
-	case 2: result = add_3d<TCoeff3D,2>::value(m_coeff, m_x_cache, m_y_cache, m_z_cache); break; 
-	case 3: result = add_3d<TCoeff3D,3>::value(m_coeff, m_x_cache, m_y_cache, m_z_cache); break; 
-	case 4: result = add_3d<TCoeff3D,4>::value(m_coeff, m_x_cache, m_y_cache, m_z_cache); break; 
-	case 5: result = add_3d<TCoeff3D,5>::value(m_coeff, m_x_cache, m_y_cache, m_z_cache); break; 
-	case 6: result = add_3d<TCoeff3D,6>::value(m_coeff, m_x_cache, m_y_cache, m_z_cache); break; 
+	case 1: result = add_3d<TCoeff3D,1>::value(m_coeff, m_cache); break; 
+	case 2: result = add_3d<TCoeff3D,2>::value(m_coeff, m_cache); break; 
+	case 3: result = add_3d<TCoeff3D,3>::value(m_coeff, m_cache); break; 
+	case 4: result = add_3d<TCoeff3D,4>::value(m_coeff, m_cache); break; 
+	case 5: result = add_3d<TCoeff3D,5>::value(m_coeff, m_cache); break; 
+	case 6: result = add_3d<TCoeff3D,6>::value(m_coeff, m_cache); break; 
 	default: {
 		assert(0 && "kernel sizes above 5 are not implemented"); 
 	}
diff --git a/mia/3d/interpolator.hh b/mia/3d/interpolator.hh
index 85ad6ae..eca41fd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@
 #include <mia/core/splinekernel.hh>
 #include <mia/core/boundary_conditions.hh>
 #include <mia/3d/image.hh>
-#include <tbb/mutex.h>
+#include <mia/core/parallel.hh>
 
 NS_MIA_BEGIN
 
@@ -60,15 +60,15 @@ struct coeff_map<T3DVector<U> > {
 	typedef C3DDVector   coeff_type;
 };
 
-struct CWeightCache {
+struct C3DWeightCache {
 	CSplineKernel::SCache x; 
 	CSplineKernel::SCache y; 
 	CSplineKernel::SCache z; 
 	
-	CWeightCache(int kernel_size, 
-		    const CSplineBoundaryCondition& xbc, 
-		    const CSplineBoundaryCondition& ybc, 
-		    const CSplineBoundaryCondition& zbc); 
+	C3DWeightCache(int kernel_size, 
+		       const CSplineBoundaryCondition& xbc, 
+		       const CSplineBoundaryCondition& ybc, 
+		       const CSplineBoundaryCondition& zbc); 
 }; 
 /// @endcond 
 
@@ -113,7 +113,7 @@ public:
 	   environment. This function must be called in each thread once. 
 	   \returns the cache structure 
 	*/
-	CWeightCache create_cache() const; 
+	C3DWeightCache create_cache() const; 
 
 	/**
 	   get the interpolated value at a given location \a x
@@ -122,7 +122,7 @@ public:
 	   \returns the interpolated value
 	   \remark This method is thread save if the cache structure is thread local 
 	*/
-	T  operator () (const C3DFVector& x, CWeightCache& cache) const;
+	T  operator () (const C3DFVector& x, C3DWeightCache& cache) const;
 
 	/**
 	   get the interpolated value at a given location \a x
@@ -152,13 +152,11 @@ private:
 	PSplineBoundaryCondition m_ybc; 
 	PSplineBoundaryCondition m_zbc; 
 
-	T m_min;
-	T m_max;
+	typename T3DDatafield<T>::value_type m_min;
+	typename T3DDatafield<T>::value_type m_max;
 	
-	mutable tbb::mutex m_cache_lock; 
- 	mutable CSplineKernel::SCache m_x_cache; 
-	mutable CSplineKernel::SCache m_y_cache; 
-	mutable CSplineKernel::SCache m_z_cache; 
+	mutable CMutex m_cache_lock; 
+ 	mutable C3DWeightCache m_cache; 
 };
 
 
@@ -236,10 +234,6 @@ private:
 	PSplineBoundaryCondition m_zbc; 
 };
 
-
-EXPORT_3D C3DInterpolatorFactory *create_3dinterpolation_factory(EInterpolation type, EBoundaryConditions bc)
-	__attribute__ ((warn_unused_result));
-
 // implementation
 
 template <class T>
diff --git a/mia/3d/io/analyze.cc b/mia/3d/io/analyze.cc
index da13782..7a02d62 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/io/analyze.hh
index 17a665b..3e4c41d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/inria.cc b/mia/3d/io/inria.cc
index 3841609..bf59e8f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vff.cc b/mia/3d/io/vff.cc
index 9508461..06cab90 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0a75083..9b58c9e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/iterator.hh
index 51a06fe..7d1b97d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/landmark.cc
index c91843f..99ed82b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4e16f8a..7d6c9c0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 7380434..7a797d3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 7a889cc..4b86db5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9900715..e747c3f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ template <> const char *  const
 TPluginHandler<C3DLandmarklistIOPlugin>::m_help =  
 	"Loading and storing of 3D landmark list.";
 
+template class TPlugin<C3DLandmarklist, io_plugin_type>;
 EXPLICITE_INSTANCEIATE_IO_HANDLER(C3DLandmarklist); 
 
 NS_MIA_END
diff --git a/mia/3d/landmarklistio.hh b/mia/3d/landmarklistio.hh
index b9c4594..0f9a599 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +33,20 @@ NS_MIA_BEGIN
 */
 typedef TIOPlugin<C3DLandmarklist> C3DLandmarklistIOPlugin;
 
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#ifndef __clang__
+#pragma GCC diagnostic ignored "-Wattributes"
+#endif
+#endif
+
+extern template class EXPORT_3D TIOPlugin<C3DLandmarklist>;
+extern template class EXPORT_3D TPlugin<C3DLandmarklist, io_plugin_type>;
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
+
 /**
    @ingroup io 
    @brief 3D Landmark list IO plugin handler 
diff --git a/mia/3d/linear_transform.cc b/mia/3d/linear_transform.cc
index a37ab50..7395e17 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 825df96..3f50de2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ca7f4f6..df0a5e2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,17 @@
 #include <boost/filesystem.hpp>
 
 
-namespace
- bfs=boost::filesystem; 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if LIBXMLPP_VERSION < 3
+#define get_first_child_text get_child_text
+#define set_first_child_text set_child_text
+#define add_child_element add_child
+#endif
+
+namespace  bfs=boost::filesystem;
 using namespace xmlpp;
 
 NS_MIA_USE
@@ -111,13 +120,13 @@ bool get_single_xml_value(const Node& node, const string& tag, Expect& result)
 			 << "' specified more then once. Only reading first."; 
 	}
 
-	auto  content = dynamic_cast<Element*>(*children.begin());
+	auto  content = dynamic_cast<const Element*>(*children.begin());
 	if (!content) {
 		cvdebug() << "  got empty node\n"; 
 		return false; 
 	}
 	
-	auto text = content->get_child_text(); 
+	auto text = content->get_first_child_text(); 
 	if (!text) {
 		cvdebug() << "  no text in node\n"; 
 		return false; 
@@ -237,15 +246,15 @@ void add_node(Element& parent, const string& name, const T& value)
 {
 	ostringstream s;
 	s << value; 
-	auto node = parent.add_child(name);
-	node->set_child_text(s.str());
+	auto node = parent.add_child_element(name);
+	node->set_first_child_text(s.str());
 }
 
 template <>
 void add_node(Element& parent, const string& name, const string& value) 
 {
-	auto node = parent.add_child(name);
-	node->set_child_text(value);
+	auto node = parent.add_child_element(name);
+	node->set_first_child_text(value);
 }
 
 template <typename T>
@@ -254,8 +263,8 @@ void add_node(Element& parent, const string& name, const T3DVector<T>& value)
 	ostringstream s;
 	s << value.x << " " << value.y << " " << value.z;
 
-	auto node = parent.add_child(name);
-	node->set_child_text(s.str());
+	auto node = parent.add_child_element(name);
+	node->set_first_child_text(s.str());
 }
 
 template <>
@@ -263,14 +272,14 @@ void add_node(Element& parent, const string& name, const Quaternion& value)
 {
 	ostringstream s;
 	s << value.x() << " " << value.y() << " " << value.z() << " " << value.w() ;
-	auto node = parent.add_child(name);
-	node->set_child_text(s.str());
+	auto node = parent.add_child_element(name);
+	node->set_first_child_text(s.str());
 }
 
 template <>
 void add_node(Element& parent, const string& name, const C3DCamera& value) 
 {
-	auto node = parent.add_child(name);
+	auto node = parent.add_child_element(name);
 	add_node(*node, "location", value.get_location()); 
 	add_node(*node, "rotation", value.get_rotation()); 
 	add_node(*node, "zoom", value.get_zoom()); 
@@ -294,7 +303,7 @@ bool C3DLMXLandmarklistIOPlugin::do_save(string const&  filename, const C3DLandm
 	add_node(*list, "name", data.get_name()); 
 	
 	for(auto i = data.begin(); i != data.end(); ++i) {
-		auto lmnode = list->add_child("landmark"); 
+		auto lmnode = list->add_child_element("landmark"); 
 		add_landmark(lmnode, *i->second);
 	}
 	
diff --git a/mia/3d/maskedcost.cc b/mia/3d/maskedcost.cc
index 2fea381..c8160ce 100644
--- a/mia/3d/maskedcost.cc
+++ b/mia/3d/maskedcost.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/maskedcost.hh
index 92d98a8..85e9564 100644
--- a/mia/3d/maskedcost.hh
+++ b/mia/3d/maskedcost.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/lncc.cc b/mia/3d/maskedcost/lncc.cc
index 0c12b5f..80e5d20 100644
--- a/mia/3d/maskedcost/lncc.cc
+++ b/mia/3d/maskedcost/lncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +22,7 @@
 
 #include <mia/core/threadedmsg.hh>
 #include <mia/core/nccsum.hh> 
-#include <tbb/parallel_reduce.h>
-#include <tbb/blocked_range.h>
-
+#include <mia/core/parallel.hh>
 
 NS_BEGIN(NS)
 
@@ -74,7 +72,7 @@ public:
 	
 	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> {
+		auto evaluate_local_cost = [this, &mov, &ref](const C1DParallelRange& range, const pair<float, int>& result) -> pair<float, int> {
 			CThreadMsgStream msks; 
 			float lresult = 0.0; 
 			int count = 0; 
@@ -120,8 +118,10 @@ public:
 		};
 		
 		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);});	
+		auto r = preduce(C1DParallelRange(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; 
 	}
@@ -149,7 +149,7 @@ public:
 	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, 
+		auto evaluate_local_cost_force = [this, &mov, &ref, &ag](const C1DParallelRange& range, 
 									 const pair<float, int>& result) -> pair<float, int> {
 			
 			CThreadMsgStream msks; 		
@@ -202,10 +202,10 @@ public:
 			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);
-					 });
+		auto r = preduce(C1DParallelRange(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; 
 	}
diff --git a/mia/3d/maskedcost/lncc.hh b/mia/3d/maskedcost/lncc.hh
index 77494c9..7589f0c 100644
--- a/mia/3d/maskedcost/lncc.hh
+++ b/mia/3d/maskedcost/lncc.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/mi.cc b/mia/3d/maskedcost/mi.cc
index a14eed8..efbb8ef 100644
--- a/mia/3d/maskedcost/mi.cc
+++ b/mia/3d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/mi.hh b/mia/3d/maskedcost/mi.hh
index 355087c..c18389e 100644
--- a/mia/3d/maskedcost/mi.hh
+++ b/mia/3d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ncc.cc b/mia/3d/maskedcost/ncc.cc
index 00e4cca..0bf7fd1 100644
--- a/mia/3d/maskedcost/ncc.cc
+++ b/mia/3d/maskedcost/ncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 +22,7 @@
 
 #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>
-
+#include <mia/core/parallel.hh>
 
 NS_BEGIN(NS)
 
@@ -39,7 +36,7 @@ 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; 
+	NCCSums operator ()(const C1DParallelRange& range, const NCCSums& sumacc) const; 
 private: 
 	C3DBitImage m_mask; 
 	T m_mov; 
@@ -55,7 +52,7 @@ FEvaluateNCCSum<T,S>::FEvaluateNCCSum(const C3DBitImage& mask, const T& mov, con
 }
 
 template <typename T, typename S> 
-NCCSums FEvaluateNCCSum<T,S>::operator ()(const tbb::blocked_range<size_t>& range, const NCCSums& sumacc) const
+NCCSums FEvaluateNCCSum<T,S>::operator ()(const C1DParallelRange& range, const NCCSums& sumacc) const
 {
 	CThreadMsgStream msks; 
 	
@@ -89,10 +86,10 @@ public:
 
 		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;
-				      });
+		sum = preduce(C1DParallelRange(0, mov.get_size().z, 1), sum, ev, 
+			      [](const NCCSums& x, const NCCSums& y){
+				      return x + y;
+			      });
 		return sum.value(); 
 	}
 }; 
@@ -120,15 +117,15 @@ public:
 		
 		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;
-				      });
+		sum = preduce(C1DParallelRange(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) {
+		auto grad_eval = [this, &mov, &ref, &grad, &geval](const C1DParallelRange& 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); 
@@ -148,7 +145,7 @@ public:
 			}; 
 		}; 
 		
-		parallel_for(tbb::blocked_range<size_t>(0, mov.get_size().z, 1), grad_eval); 
+		pfor(C1DParallelRange(0, mov.get_size().z, 1), grad_eval); 
 
 		return geval.first; 
 	}
diff --git a/mia/3d/maskedcost/ncc.hh b/mia/3d/maskedcost/ncc.hh
index 5e352d1..847e9e9 100644
--- a/mia/3d/maskedcost/ncc.hh
+++ b/mia/3d/maskedcost/ncc.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ssd.cc b/mia/3d/maskedcost/ssd.cc
index 04ca519..79e2420 100644
--- a/mia/3d/maskedcost/ssd.cc
+++ b/mia/3d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ssd.hh b/mia/3d/maskedcost/ssd.hh
index 0ecce45..3155abe 100644
--- a/mia/3d/maskedcost/ssd.hh
+++ b/mia/3d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_lncc.cc b/mia/3d/maskedcost/test_lncc.cc
index 40dec83..bd4d980 100644
--- a/mia/3d/maskedcost/test_lncc.cc
+++ b/mia/3d/maskedcost/test_lncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_mi.cc b/mia/3d/maskedcost/test_mi.cc
index f995dfa..7bb8e87 100644
--- a/mia/3d/maskedcost/test_mi.cc
+++ b/mia/3d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_ncc.cc b/mia/3d/maskedcost/test_ncc.cc
index 9eeb7f9..429c62a 100644
--- a/mia/3d/maskedcost/test_ncc.cc
+++ b/mia/3d/maskedcost/test_ncc.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_ssd.cc b/mia/3d/maskedcost/test_ssd.cc
index eb415a5..656d50c 100644
--- a/mia/3d/maskedcost/test_ssd.cc
+++ b/mia/3d/maskedcost/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/matrix.cc b/mia/3d/matrix.cc
index 98e06b8..ab4dab5 100644
--- a/mia/3d/matrix.cc
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 @@
 #pragma GCC diagnostic push
 #ifndef __clang__ 
 #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 #else
 #pragma clang diagnostic ignored "-Wdeprecated-register"
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
 #endif 
 #endif 
 
@@ -43,7 +45,7 @@ NS_MIA_BEGIN
 template <typename T> 
 T3DMatrix<T>::T3DMatrix():
         m_ev_type(0),
-	m_evectors(3),
+	m_complex_evectors(3),
 	m_ev_order(3)
 {
 }
@@ -69,7 +71,7 @@ template <typename T>
 T3DMatrix<T>::T3DMatrix(const T3DVector< T3DVector<T> >& other):
 	T3DVector<T3DVector<T> >(other.x, other.y, other.z),
 	m_ev_type(0),
-	m_evectors(3),
+	m_complex_evectors(3),
 	m_ev_order(3)
 {
 }
@@ -78,7 +80,7 @@ template <typename T>
 T3DMatrix<T>::T3DMatrix(const T3DVector< T >& x, const T3DVector< T >& y, const T3DVector< T >& z ):
 	T3DVector<T3DVector<T> >(x, y, z),
 	m_ev_type(0),
-	m_evectors(3),
+	m_complex_evectors(3),
 	m_ev_order(3)
 {
 }
@@ -139,7 +141,6 @@ void T3DMatrix<T>::evaluate_ev() const
 			evnorms[i] = std::norm(eval(i)); 
 		
 		
-		
 		if (evnorms[0] < evnorms[1]) {
 			if (evnorms[0] < evnorms[2]) {
 				m_ev_order[2] = 0; 
@@ -191,15 +192,21 @@ void T3DMatrix<T>::evaluate_ev() const
 		m_evalues.y = eval[m_ev_order[1]].real(); 
 		m_evalues.z = eval[m_ev_order[2]].real();
 		
-		if (m_evalues.x == m_evalues.y || m_evalues.y == m_evalues.z) 
-			m_ev_type = 2;
-		else 
-			m_ev_type = 3; 
+		if (m_evalues.x == m_evalues.y || m_evalues.y == m_evalues.z) {
+			if (m_evalues.x == m_evalues.y && m_evalues.y == m_evalues.z)
+				m_ev_type = 4;
+			else
+				m_ev_type = 2;
+		}else {
+			m_ev_type = 3;
+		}
 	}
 	assert(m_ev_type);
 	for (int i = 0; i < 3; ++i) {
 		const auto evec = esolver.eigenvectors().col(m_ev_order[i]);
-		m_evectors[i] = C3DFVector(evec(0).real(), evec(1).real(), evec(2).real());
+		cvdebug() << "i: eval= " << eval[m_ev_order[i]]
+			  << "evec= " << evec(0) << ", " << evec(1) << "," << evec(2) << "\n"; 
+		m_complex_evectors[i] = T3DCVector<T>(evec(0), evec(1), evec(2));
 	}
 }
 
@@ -237,7 +244,7 @@ T T3DMatrix<T>::get_det()  const
 
 
 template <typename T> 
-int T3DMatrix<T>::get_eigenvalues(C3DFVector& result)const
+int T3DMatrix<T>::get_eigenvalues(T3DVector<T>& result)const
 {
 	if (m_ev_type == 0) 
 		evaluate_ev(); 
@@ -247,14 +254,25 @@ int T3DMatrix<T>::get_eigenvalues(C3DFVector& result)const
 }
 
 template <typename T> 
-C3DFVector T3DMatrix<T>::get_eigenvector(int i)const
+T3DCVector<T> T3DMatrix<T>::get_complex_eigenvector(int i)const
 {
 	if (m_ev_type == 0) 
 		evaluate_ev(); 
 	
-	return m_evectors[i];
+	return m_complex_evectors[i];
+}
+
+template <typename T> 
+T3DVector<T> T3DMatrix<T>::get_real_eigenvector(int i)const
+{
+	if (m_ev_type == 0) 
+		evaluate_ev(); 
+
+	auto evec = m_complex_evectors[i]; 
+	return T3DVector<T>(evec.x.real(), evec.y.real(), evec.z.real()); 
 }
 
+
 template class T3DMatrix<float>; 
 template class T3DMatrix<double>; 
 
diff --git a/mia/3d/matrix.hh b/mia/3d/matrix.hh
index cd9b5e1..16b4845 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +28,8 @@
 
 NS_MIA_BEGIN
 
+template <typename T>
+using T3DCVector=T3DVector<std::complex<T>>; 
 
 /**
    @ingroup basic 
@@ -43,7 +45,8 @@ template <typename T>
 class T3DMatrix: public T3DVector< T3DVector<T> > {
 
 
-public:  
+public:
+
 	
 	T3DMatrix(); 
 	
@@ -127,16 +130,23 @@ public:
 	    \returns 1 one real, two complex eigenvalues, real part = result->y, imaginary part = result->z
 	             2 three real eigenvalues, at least two are equal
 		     3 three distinct real eigenvalues
+		     4 three real eigenvalues, all equal 
 	*/	     
 
-	int get_eigenvalues(C3DFVector& v)const; 
+	int get_eigenvalues(T3DVector<T>& v)const; 
+
+	/** Calculate the eigenvector to a given eigenvalues. 
+	    This function doesn't work for complex valued eigenvectors 
+	    \param i number of eigenvector 
+	    \returns the requested eigenvector
+	 */
+	T3DVector<T> get_real_eigenvector(int i)const;
 
-	/** 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
+	/** Calculate the complex eigenvector to a given eigenvalues. 
 	    \param i number of eigenvector 
 	    \returns the requested eigenvector
 	 */
-	C3DFVector get_eigenvector(int i)const; 
+	T3DCVector<T> get_complex_eigenvector(int i)const; 
 
 
 	/// The unity matrix 
@@ -150,8 +160,8 @@ private:
 
 		
 	mutable int m_ev_type; // 0 = not valid 
-	mutable C3DFVector m_evalues;
-	mutable std::vector<C3DFVector> m_evectors; 
+	mutable T3DVector<T> m_evalues;
+	mutable std::vector<T3DCVector<T>> m_complex_evectors; 
 	mutable std::vector<int> m_ev_order; 
 }; 
 
diff --git a/mia/3d/model.cc b/mia/3d/model.cc
index d686332..58ac517 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2dddf0c..1dc0451 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/multicost.cc
index cfd0992..fe084b9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d3db3c6..9ed84a8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ed1ed97..4531bd5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 55168dc..619cf07 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6605634..8b78a48 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 533ac3d..56d2d35 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ff5a527..20c61b7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4a28fe5..5e8932a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d5b7b5e..a68c08e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -314,6 +314,10 @@ EXPORT_3D  std::istream& operator >> (std::istream& is, C3DOrientationAndPositio
 	return is; 
 }
 
+template class EXPORT_3D TAttribute<E3DImageOrientation>;
+template class EXPORT_3D TAttribute<E3DPatientPositioning>;
+template class EXPORT_3D TAttribute<C3DOrientationAndPosition>; 
+
 template class  EXPORT_3D TTranslator<E3DImageOrientation>;
 template class  EXPORT_3D TTranslator<E3DPatientPositioning>;
 template class  EXPORT_3D TTranslator<C3DOrientationAndPosition>; 
diff --git a/mia/3d/orientation.hh b/mia/3d/orientation.hh
index 3bfa25d..dfbbbbc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -240,22 +240,29 @@ EXPORT_3D  std::istream& operator >> (std::istream& is, E3DPatientPositioning& p
    @brief attribute for 3D image orientation 
 */
 typedef TAttribute<E3DImageOrientation> C3DImageOrientation;
+extern template class EXPORT_3D TAttribute<E3DImageOrientation>; 
 
 /**
    @ingroup basic 
    @brief translator for 3D image orientations to and from strings 
 */ 
 typedef TTranslator<E3DImageOrientation> COrientationTranslator;
+extern template class EXPORT_3D TTranslator<E3DImageOrientation>; 
+
 
 /**
    @ingroup basic 
    @brief attribute for the patient position 
 */
 typedef TAttribute<E3DPatientPositioning> CPatientPositionAttribute;
-
+extern template class EXPORT_3D TAttribute<E3DPatientPositioning>; 
 
 typedef TAttribute<C3DOrientationAndPosition> C3DImageOrientationPositionAttribute;
 typedef TTranslator<C3DOrientationAndPosition> COrientationPositionTranslator;
+
+extern template class EXPORT_3D TAttribute<C3DOrientationAndPosition>; 
+extern template class EXPORT_3D TTranslator<C3DOrientationAndPosition>; 
+
 /**
    @ingroup basic 
    @brief translator for the patient position 
diff --git a/mia/3d/ppmatrix.cc b/mia/3d/ppmatrix.cc
index bda3d76..7ecac88 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,14 @@
 #include <mia/3d/datafield.cxx>
 #include <mia/core/threadedmsg.hh>
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
+#include <numeric> 
+
 
 #ifdef __SSE2__
 #include <emmintrin.h>
 #endif
 
-using namespace tbb;
 using namespace std; 
 
 NS_MIA_BEGIN
@@ -405,7 +405,7 @@ struct EvaluateGradientAndValue {
 		{
 		}
 	
-	void operator()( const blocked_range<int>& range ) const {
+	void operator()( const C1DParallelRange& range ) const {
 		CThreadMsgStream thread_stream;
 		TRACE_FUNCTION; 
 		int nx = size.x; 
@@ -549,7 +549,7 @@ struct EvaluateGradientAndValue {
 		{
 		}
 	
-	void operator()( const blocked_range<int>& range ) const {
+	void operator()( const C1DParallelRange& range ) const {
 		CThreadMsgStream thread_stream;
 		TRACE_FUNCTION; 
 		int nx = size.x; 
@@ -624,7 +624,7 @@ double C3DPPDivcurlMatrixImpl::evaluate(const T3DDatafield<C3DFVector>& coeffici
 	vector<double> values(m_size.z); 
 	EvaluateGradientAndValue<C3DFVector> eval(coefficients, gradient, values,m_P, m_size, m_ksize); 
 	
-	parallel_for(blocked_range<int>( 0, m_size.z), eval);
+	pfor(C1DParallelRange( 0, m_size.z), eval);
 	return accumulate(values.begin(), values.end(), 0.0); 
 
 }
@@ -639,7 +639,7 @@ double C3DPPDivcurlMatrixImpl::evaluate(const T3DDatafield<C3DDVector>& coeffici
 	vector<double> values(m_size.z); 
 	EvaluateGradientAndValue<C3DDVector> eval(coefficients, gradient, values,m_P, m_size, m_ksize); 
 	
-	parallel_for(blocked_range<int>( 0, m_size.z), eval);
+	pfor(C1DParallelRange( 0, m_size.z), eval);
 	return accumulate(values.begin(), values.end(), 0.0); 
 }
 
diff --git a/mia/3d/ppmatrix.hh b/mia/3d/ppmatrix.hh
index 1135e36..90f9b20 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 cc25570..8463a54 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -282,7 +282,5 @@ Quaternion& Quaternion::operator *= (const Quaternion& o)
 	return *this; 
 }
 
-
-
 NS_MIA_END
 
diff --git a/mia/3d/quaternion.hh b/mia/3d/quaternion.hh
index f0ef409..d52afe2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 +21,16 @@
 #ifndef mia_3d_quaternion_hh
 #define mia_3d_quaternion_hh
 
-#include <ostream>
 #include <mia/3d/defines3d.hh>
 #include <mia/3d/matrix.hh>
 #include <mia/3d/vector.hh>
 
+#include <ostream>
+#include <cmath>
+
 NS_MIA_BEGIN 
 
+
 /**
    \ingroup misc 
    \brief a class to implement a quaternion
@@ -153,8 +156,6 @@ bool EXPORT_3D operator == (const Quaternion& a, const Quaternion& b);
 bool EXPORT_3D operator != (const Quaternion& a, const Quaternion& b); 
 
 
-
-
 inline double Quaternion::w() const
 {
 	return m_w; 
diff --git a/mia/3d/reg3d/direct.cc b/mia/3d/reg3d/direct.cc
index befdcaf..9c38ba6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 34f17c9..aed9031 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9c12a4a..d84a7bd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/naviera.cc b/mia/3d/reg3d/naviera.cc
index e405b69..7cf8485 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/navierasse.cc b/mia/3d/reg3d/navierasse.cc
index d53b514..11ceb23 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/navierpsse.cc b/mia/3d/reg3d/navierpsse.cc
index b1cdb5a..7c63795 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/register.cc
index c6c626a..e9137cd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d7b48a1..3005916 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 99166e0..f7956e7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 01d1fef..c8797db 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index d6f0d5b..1572e18 100644
--- a/mia/3d/rot.cc
+++ b/mia/3d/rot.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/rot.hh
index ee3de24..1ac5bd1 100644
--- a/mia/3d/rot.hh
+++ b/mia/3d/rot.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/shape.cc b/mia/3d/shape.cc
index 55f396e..2ce5b69 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/shape.hh b/mia/3d/shape.hh
index 5254832..31f7b6a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/CMakeLists.txt b/mia/3d/shapes/CMakeLists.txt
index 7f92d43..60d1034 100644
--- a/mia/3d/shapes/CMakeLists.txt
+++ b/mia/3d/shapes/CMakeLists.txt
@@ -21,7 +21,16 @@ SET(shape3d
 )
 
 
-ADD_LIBRARY(3d-shapes MODULE basic_shapes.cc sphere.cc)
+SET(SHAPES_SRC basic_shapes.cc sphere.cc)
+add_library(3d-shapes-common OBJECT ${SHAPES_SRC})
+IF(NOT WIN32)
+  set_source_files_properties(${SHAPES_SRC}  PROPERTIES COMPILE_FLAGS "-fPIC")
+  set_target_properties(3d-shapes-common  PROPERTIES COMPILE_FLAGS -DVSTREAM_DOMAIN='"${plugname}"') 
+ENDIF(NOT WIN32)
+
+
+add_library(3d-shapes MODULE $<TARGET_OBJECTS:3d-shapes-common>)
+
 TARGET_LINK_LIBRARIES(3d-shapes ${MIA3DLIBS})
 SET_TARGET_PROPERTIES(3d-shapes PROPERTIES PREFIX "" SUFFIX ${PLUGSUFFIX})
 INSTALL(TARGETS 3d-shapes LIBRARY DESTINATION "${PLUGIN_INSTALL_PATH}/3dimage/shape")
@@ -32,3 +41,18 @@ ADD_CUSTOM_TARGET(3d-shapes_test_link
 
 ADD_DEPENDENCIES(plugin_test_links 3d-shapes_test_link)
 
+add_executable(test-3d-shapes test_shapes.cc $<TARGET_OBJECTS:3d-shapes-common>)
+IF(NOT WIN32)
+  set_target_properties(test-3d-shapes PROPERTIES 
+    COMPILE_FLAGS -DVSTREAM_DOMAIN='"3d-shapes"' 
+    COMPILE_FLAGS -DBOOST_TEST_DYN_LINK)
+ELSE(NOT WIN32)
+  set_target_properties(test-3d-shapes PROPERTIES
+    COMPILE_FLAGS -DBOOST_TEST_DYN_LINK)
+ENDIF(NOT WIN32)
+#  target_link_libraries(test-${plugname} ${plugname}-common)
+target_link_libraries(test-3d-shapes ${MIA3DLIBS} ${BOOST_UNITTEST})
+add_test(3d-shapes test-3d-shapes)
+
+
+
diff --git a/mia/3d/shapes/basic_shapes.cc b/mia/3d/shapes/basic_shapes.cc
index d4ac09e..aa8adc4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,20 +24,13 @@
 
 
 #include <limits>
-#include <mia/3d/shape.hh>
-#include "sphere.hh"
-
+#include <mia/3d/shapes/sphere.hh>
+#include <mia/3d/shapes/basic_shapes.hh>
 
 NS_BEGIN(basic_3dshape_creator)
 NS_MIA_USE;
 using namespace std;
 
-
-class C6n3DShape: public C3DShape {
-public:
-	C6n3DShape();
-};
-
 C6n3DShape::C6n3DShape()
 {
 	insert(C3DShape::Flat::value_type( 0, 0, 0));
@@ -49,15 +42,6 @@ C6n3DShape::C6n3DShape()
 	insert(C3DShape::Flat::value_type( 0, 0,-1));
 }
 
-class C6n3DShapeFactory: public C3DShapePlugin {
-public:
-	C6n3DShapeFactory();
-private:
-	virtual const string do_get_descr() const;
-	virtual C3DShape *do_create()const;
-	virtual bool do_test() const;
-};
-
 C6n3DShapeFactory::C6n3DShapeFactory():
 	C3DShapePlugin("6n")
 {
@@ -74,36 +58,6 @@ const string C6n3DShapeFactory::do_get_descr()const
 	return string("6n neighborhood 3D shape creator");
 }
 
-bool C6n3DShapeFactory::do_test()const
-{
-	C6n3DShape shape;
-	C6n3DShape::Mask mask = shape.get_mask();
-
-	if (mask.get_size() != C3DBounds(3,3,3)) {
-		cvfail() << get_name() << ": wrong mask size\n";
-		assert("size failture");
-	}
-
-	if (! ( mask(1,1,1) && mask(1,1,0) && mask(0,1,1) && mask(1,0,1) &&
-		mask(1,2,1) && mask(2,1,1) && mask(1,1,2) ) ||
-	    mask(0,0,0) || mask(1,0,0) || mask(2,0,0) ||
-	    mask(0,1,0) ||                mask(2,1,0) ||
-	    mask(0,2,0) || mask(1,2,0) || mask(2,2,0) ||
-	    mask(0,0,1) ||                mask(2,0,1) ||
-	    mask(0,2,1) ||                mask(2,2,1) ||
-	    mask(0,0,2) || mask(1,0,2) || mask(2,0,2) ||
-	    mask(0,1,2) ||                mask(2,1,2) ||
-	    mask(0,2,2) || mask(1,2,2) || mask(2,2,2)) {
-		return false;
-	}
-	return true;
-}
-
-
-class C18n3DShape: public C6n3DShape {
-public:
-	C18n3DShape();
-};
 
 C18n3DShape::C18n3DShape()
 {
@@ -123,15 +77,6 @@ C18n3DShape::C18n3DShape()
 	insert(C3DShape::Flat::value_type( 1, 0, 1));
 }
 
-class C18n3DShapeFactory: public C3DShapePlugin {
-public:
-	C18n3DShapeFactory();
-private:
-	virtual const string do_get_descr() const;
-	virtual C3DShape *do_create()const;
-	virtual bool  do_test() const;
-};
-
 C18n3DShapeFactory::C18n3DShapeFactory():
 	C3DShapePlugin("18n")
 {
@@ -148,35 +93,6 @@ const string C18n3DShapeFactory::do_get_descr()const
 	return string("18n neighborhood 3D shape creator");
 }
 
-bool C18n3DShapeFactory::do_test()const
-{
-	C18n3DShape shape;
-	C18n3DShape::Mask mask = shape.get_mask();
-
-	if (mask.get_size() != C3DBounds(3,3,3)) {
-		cvfail() << get_name() << ": wrong mask size\n";
-		assert(0);
-	}
-
-	if (mask(0,0,0) || !mask(1,0,0) || mask(2,0,0) ||
-	   !mask(0,1,0) || !mask(1,1,0) ||!mask(2,1,0) ||
-	    mask(0,2,0) || !mask(1,2,0) || mask(2,2,0) ||
-	   !mask(0,0,1) || !mask(1,0,1) ||!mask(2,0,1) ||
-	   !mask(0,1,1) || !mask(1,1,1) ||!mask(2,1,1) ||
-	   !mask(0,2,1) || !mask(1,2,1) ||!mask(2,2,1) ||
-	    mask(0,0,2) || !mask(1,0,2) || mask(2,0,2) ||
-	   !mask(0,1,2) || !mask(1,1,2) ||!mask(2,1,2) ||
-	    mask(0,2,2) || !mask(1,2,2) || mask(2,2,2)) {
-		return false;
-	}
-	return true;
-}
-
-
-class C26n3DShape: public C18n3DShape {
-public:
-	C26n3DShape();
-};
 
 C26n3DShape::C26n3DShape()
 {
@@ -190,15 +106,6 @@ C26n3DShape::C26n3DShape()
 	insert(C3DShape::Flat::value_type( 1, 1, 1));
 }
 
-class C26n3DShapeFactory: public C3DShapePlugin {
-public:
-	C26n3DShapeFactory();
-private:
-	virtual const string do_get_descr() const;
-	virtual C3DShape *do_create()const;
-	virtual bool do_test() const;
-};
-
 C26n3DShapeFactory::C26n3DShapeFactory():
 	C3DShapePlugin("26n")
 {
@@ -215,22 +122,6 @@ const string C26n3DShapeFactory::do_get_descr()const
 	return string("26n neighborhood 3D shape creator");
 }
 
-bool C26n3DShapeFactory::do_test()const
-{
-	C26n3DShape shape;
-	C26n3DShape::Mask mask = shape.get_mask();
-
-	assert(mask.get_size() == C3DBounds(3,3,3));
-
-	for (C26n3DShape::Mask::const_iterator i = mask.begin(), e = mask.end();
-	     i != e; ++i)
-		if (!*i) {
-			return false;
-		}
-	return true;
-}
-
-
 extern "C" {
 	EXPORT CPluginBase *get_plugin_interface()
 	{
diff --git a/mia/core/testplug/dummy1.cc b/mia/3d/shapes/basic_shapes.hh
similarity index 51%
copy from mia/core/testplug/dummy1.cc
copy to mia/3d/shapes/basic_shapes.hh
index a96b414..dcf2d88 100644
--- a/mia/core/testplug/dummy1.cc
+++ b/mia/3d/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,41 +18,57 @@
  *
  */
 
-#include <mia/core/testplugin.hh>
 
-NS_MIA_USE
+#include <mia/3d/shape.hh>
+
+NS_BEGIN(basic_3dshape_creator)
+NS_MIA_USE;
 using namespace std;
 
-class EXPORT CDummy1 :public CTestPlugin {
+
+
+class C6n3DShape: public C3DShape {
+public:
+	C6n3DShape();
+};
+
+class C6n3DShapeFactory: public C3DShapePlugin {
 public:
-	CDummy1();
+	C6n3DShapeFactory();
 private:
 	virtual const string do_get_descr() const;
+	virtual C3DShape *do_create()const;
 };
 
-CDummy1::CDummy1():
-  CTestPlugin("dummy1")
-{
-}
-
-const std::string test_dummy_symbol()
-{
-	return "test_dummy_symbol from dummy1"; 
-}
 
-const string CDummy1::do_get_descr() const
-{
-	return test_dummy_symbol();;
-}
+class C18n3DShape: public C6n3DShape {
+public:
+	C18n3DShape();
+};
 
+class C18n3DShapeFactory: public C3DShapePlugin {
+public:
+	C18n3DShapeFactory();
+private:
+	virtual const string do_get_descr() const;
+	virtual C3DShape *do_create()const;
+};
 
+class C26n3DShape: public C18n3DShape {
+public:
+	C26n3DShape();
+};
 
-extern "C" EXPORT  CPluginBase *get_plugin_interface()
-{
-	return new CDummy1();
-}
 
+class C26n3DShapeFactory: public C3DShapePlugin {
+public:
+	C26n3DShapeFactory();
+private:
+	virtual const string do_get_descr() const;
+	virtual C3DShape *do_create()const;
+};
 
 
 
 
+NS_END
diff --git a/mia/3d/shapes/sphere.cc b/mia/3d/shapes/sphere.cc
index 589d38a..05d1c60 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 293bce0..1ac27c2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_shapes.cc b/mia/3d/shapes/test_shapes.cc
new file mode 100644
index 0000000..b202c46
--- /dev/null
+++ b/mia/3d/shapes/test_shapes.cc
@@ -0,0 +1,100 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/shapes/basic_shapes.hh>
+#include <mia/3d/shapes/sphere.hh>
+using namespace mia; 
+using namespace basic_3dshape_creator; 
+
+struct CShapeTestFixture {
+        void check(const C3DShape& shape, const C3DBounds& size, const bool *mask); 
+        
+}; 
+
+void CShapeTestFixture::check(const C3DShape& shape, const C3DBounds& size, const bool *test_mask)
+{
+        auto mask = shape.get_mask();
+        BOOST_CHECK_EQUAL(mask.get_size(), size);
+
+        auto im = mask.begin();
+        auto em = mask.end();
+
+        const bool *tm = test_mask;
+	int i = 0; 
+        while (im != em) {
+                BOOST_CHECK_EQUAL(*im, *tm);
+		++im;
+		++tm;
+		++i; 
+        }
+        
+}
+
+BOOST_FIXTURE_TEST_CASE( test_6n_shape, CShapeTestFixture )
+{
+        auto shape = BOOST_TEST_create_from_plugin<C6n3DShapeFactory>("6n");
+
+        const bool test_mask [] = {0,0,0, /**/  0,1,0, /**/ 0,0,0,
+                                   0,1,0, /**/  1,1,1, /**/ 0,1,0,
+                                   0,0,0, /**/  0,1,0, /**/ 0,0,0}; 
+        
+	check(*shape, C3DBounds(3,3,3), test_mask); 
+       
+}
+
+BOOST_FIXTURE_TEST_CASE( test_18n_shape, CShapeTestFixture )
+{
+        auto shape = BOOST_TEST_create_from_plugin<C18n3DShapeFactory>("18n");
+
+        const bool test_mask [] = {0,1,0, /**/  1,1,1, /**/ 0,1,0,
+                                   1,1,1, /**/  1,1,1, /**/ 1,1,1,
+                                   0,1,0, /**/  1,1,1, /**/ 0,1,0}; 
+        
+	check(*shape, C3DBounds(3,3,3), test_mask); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_27n_shape, CShapeTestFixture )
+{
+        auto shape = BOOST_TEST_create_from_plugin<C26n3DShapeFactory>("26n");
+
+        const bool test_mask [] = {1,1,1, /**/  1,1,1, /**/ 1,1,1,
+                                   1,1,1, /**/  1,1,1, /**/ 1,1,1,
+                                   1,1,1, /**/  1,1,1, /**/ 1,1,1}; 
+        
+	check(*shape, C3DBounds(3,3,3), test_mask); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_sphere_2_shape, CShapeTestFixture )
+{
+        auto shape = BOOST_TEST_create_from_plugin<CSphere3DShapeFactory>("sphere:r=2");
+
+        const bool test_mask [] = {0,0,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,1,1,1,0, /**/ 0,1,1,1,0, /**/ 0,1,1,1,0, /**/ 0,0,0,0,0,
+				   0,0,1,0,0, /**/  0,1,1,1,0, /**/ 1,1,1,1,1, /**/ 0,1,1,1,0, /**/ 0,0,1,0,0,
+				   0,0,0,0,0, /**/  0,1,1,1,0, /**/ 0,1,1,1,0, /**/ 0,1,1,1,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,0,0}; 
+        
+	check(*shape, C3DBounds(5,5,5), test_mask); 
+}
+
+
+
+
diff --git a/mia/3d/similarity_profile.cc b/mia/3d/similarity_profile.cc
index 6b26cbd..6b1b109 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 bbfa730..a622507 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2818b5f..1041db2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/splinepenalty/divcurl.hh
index 7db08f9..e51cb18 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_divcurl.cc b/mia/3d/splinepenalty/test_divcurl.cc
index 814d3cb..23a16a4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/splinetransformpenalty.cc b/mia/3d/splinetransformpenalty.cc
index d0f07bf..4357393 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/splinetransformpenalty.hh b/mia/3d/splinetransformpenalty.hh
index bc2df2d..0244635 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/stackdisttrans.cc
index 5e7906c..d4ad20c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6d4a5b0..354bfc2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 eafe7d0..0419e76 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 956cc57..1ef9042 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_affine_matrix.cc b/mia/3d/test_affine_matrix.cc
index 89901cf..caae249 100644
--- a/mia/3d/test_affine_matrix.cc
+++ b/mia/3d/test_affine_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_combiner.cc b/mia/3d/test_combiner.cc
index 8e10fb7..558d1e6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ef73808..c4eff23 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_critical_points.cc b/mia/3d/test_critical_points.cc
new file mode 100644
index 0000000..ce1320a
--- /dev/null
+++ b/mia/3d/test_critical_points.cc
@@ -0,0 +1,177 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 <climits>
+
+#define VSTREAM_DOMAIN "test-critical-points"
+#include <mia/internal/autotest.hh>
+
+
+#include <mia/3d/critical_point.hh>
+
+using namespace mia; 
+
+BOOST_AUTO_TEST_CASE( test_critical_point_simple )
+{
+        C3DCriticalPoint cp_0;
+
+        BOOST_CHECK_EQUAL(cp_0.get_point(), C3DFVector::_0);
+        BOOST_CHECK_EQUAL(cp_0.get_a(), C3DFMatrix::_0);
+        BOOST_CHECK_EQUAL(cp_0.get_gamma(), 0.0f); 
+
+
+        C3DFVector x(1,2,3); 
+        C3DCriticalPoint cp_1(x);
+        BOOST_CHECK_EQUAL(cp_1.get_point(), x);
+
+        cp_1.set_a(C3DFMatrix::diagonal(C3DFVector(3.0f,2.0f,0.5f)));
+        cp_1.set_gamma(0.1f);
+        
+        BOOST_CHECK_EQUAL(cp_1.get_gamma(), 0.1f);
+
+        // check center 
+        BOOST_CHECK_EQUAL(cp_1.at(x), C3DFVector::_0); 
+
+        C3DFVector val_2_1_1 = cp_1.at(C3DFVector(2,1,1)); // delta = 1, -1, -2
+        // C3DFVector test_2_1_1(0.1 * 3 / 6, 0.1f/3.0f,  -2 * 0.5 / 6 ); 
+
+        BOOST_CHECK_CLOSE(val_2_1_1.x, 0.05f, 0.1);
+        BOOST_CHECK_CLOSE(val_2_1_1.y, -0.1f/3.0f, 0.1);
+        BOOST_CHECK_CLOSE(val_2_1_1.z, -0.1f/6.0f, 0.1);
+
+	C3DFVector val_2_1_1_alt = cp_1.at_alt(C3DFVector(2,0,1)); //delta = 1, -2, -2
+        // 3.9 
+        // C3DFVector test_2_1_1(3 / 3.9    -4/ 3.9  -1/ 3.9  ); 
+
+        BOOST_CHECK_CLOSE(val_2_1_1_alt.x,  3.0f / 3.9f, 0.1);
+        BOOST_CHECK_CLOSE(val_2_1_1_alt.y, -4.0f / 3.9f, 0.1);
+        BOOST_CHECK_CLOSE(val_2_1_1_alt.z, -1.0f / 3.9f, 0.1);
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_critical_point_eigen_zero )
+{
+        C3DCriticalPointEigen cp(C3DFVector::_1, C3DFMatrix::_0);
+
+        BOOST_CHECK_EQUAL(cp.get_type(), C3DCriticalPointEigen::ev_zero); 
+}
+
+BOOST_AUTO_TEST_CASE( test_critical_point_eigen_real )
+{
+        C3DCriticalPointEigen cp(C3DFVector::_1,
+                                 C3DFMatrix::diagonal(C3DFVector(1,2,3)));
+
+        BOOST_CHECK_EQUAL(cp.get_type(), C3DCriticalPointEigen::ev_real);
+
+        BOOST_CHECK_EQUAL(cp.get_eval1(), 3.0f);
+        BOOST_CHECK_EQUAL(cp.get_real_eval2(), 2.0f);
+        BOOST_CHECK_EQUAL(cp.get_real_eval3(), 1.0f);
+        BOOST_CHECK_EQUAL(cp.get_eval2(), 2.0f);
+        BOOST_CHECK_EQUAL(cp.get_eval3(), 1.0f); 
+
+        BOOST_CHECK_EQUAL(cp.get_location(), C3DFVector::_1); 
+
+        BOOST_CHECK_EQUAL(cp.get_evect1(), C3DFVector(0,0,1));
+        BOOST_CHECK_EQUAL(cp.get_real_evect2(), C3DFVector(0,1,0));
+        BOOST_CHECK_EQUAL(cp.get_real_evect3(), C3DFVector(1,0,0)); 
+
+}
+
+BOOST_AUTO_TEST_CASE( test_critical_point_eigen_real_two )
+{
+        C3DCriticalPointEigen cp(C3DFVector::_1,
+                                 C3DFMatrix::diagonal(C3DFVector(2,2,3)));
+
+        BOOST_CHECK_EQUAL(cp.get_type(), C3DCriticalPointEigen::ev_real_two_equal);
+
+        BOOST_CHECK_EQUAL(cp.get_eval1(), 3.0f);
+        BOOST_CHECK_EQUAL(cp.get_real_eval2(), 2.0f);
+        BOOST_CHECK_EQUAL(cp.get_real_eval3(), 2.0f);
+        BOOST_CHECK_EQUAL(cp.get_eval2(), 2.0f);
+        BOOST_CHECK_EQUAL(cp.get_eval3(), 2.0f);
+        
+        BOOST_CHECK_EQUAL(cp.get_evect1(), C3DFVector(0,0,1));
+        BOOST_CHECK_EQUAL(cp.get_real_evect2(), C3DFVector(1,0,0));
+        BOOST_CHECK_EQUAL(cp.get_real_evect3(), C3DFVector(0,1,0)); 
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_critical_point_eigen_real_three )
+{
+        C3DCriticalPointEigen cp(C3DFVector::_1,
+                                 C3DFMatrix::diagonal(C3DFVector(2,2,2)));
+
+        BOOST_CHECK_EQUAL(cp.get_type(), C3DCriticalPointEigen::ev_real_three_equal);
+
+        BOOST_CHECK_EQUAL(cp.get_eval1(), 2.0f);
+        BOOST_CHECK_EQUAL(cp.get_real_eval2(), 2.0f);
+        BOOST_CHECK_EQUAL(cp.get_real_eval3(), 2.0f);
+        BOOST_CHECK_EQUAL(cp.get_eval2(), 2.0f);
+        BOOST_CHECK_EQUAL(cp.get_eval3(), 2.0f);
+        
+        BOOST_CHECK_EQUAL(cp.get_evect1(), C3DFVector(0,0,1));
+        BOOST_CHECK_EQUAL(cp.get_real_evect2(), C3DFVector(1,0,0));
+        BOOST_CHECK_EQUAL(cp.get_real_evect3(), C3DFVector(0,1,0)); 
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_critical_point_eigen_two_complex )
+{
+        C3DCriticalPointEigen cp(C3DFVector::_1,
+                                 C3DFMatrix(C3DFVector(1,0,0),
+                                            C3DFVector(0,cos(M_PI/3),sin(M_PI/3)),
+                                            C3DFVector(0,-sin(M_PI/3),cos(M_PI/3))));
+
+        BOOST_CHECK_EQUAL(cp.get_type(), C3DCriticalPointEigen::ev_complex);
+
+        BOOST_CHECK_EQUAL(cp.get_eval1(), 1.0f);
+        auto cev2 = cp.get_complex_eval2(); 
+        BOOST_CHECK_CLOSE(cev2.real(), 0.5f, 0.1);
+        BOOST_CHECK_CLOSE(cev2.imag(), sqrt(3.0f)/2.0f, 0.1);
+
+        auto cev3 = cp.get_complex_eval3(); 
+        BOOST_CHECK_CLOSE(cev3.real(), 0.5f, 0.1);
+        BOOST_CHECK_CLOSE(cev3.imag(), sqrt(3.0f)/2.0f, 0.1);
+
+        // use directly what comes from the library eigen3
+        
+        BOOST_CHECK_EQUAL(cp.get_evect1(), C3DFVector(1,0,0));
+
+        auto evect2 = cp.get_complex_evect2();
+        BOOST_CHECK_SMALL(evect2.x.real(), 1e-5f);
+        BOOST_CHECK_SMALL(evect2.x.imag(), 1e-5f);
+        BOOST_CHECK_CLOSE(evect2.y.real(), 1.0f/sqrt(2.0f), 0.1);
+        BOOST_CHECK_SMALL(evect2.y.imag(), 1e-5f);
+        BOOST_CHECK_SMALL(evect2.z.real(), 1e-5f);
+        BOOST_CHECK_CLOSE(evect2.z.imag(), 1.0f/sqrt(2.0f), 0.1);
+
+
+        auto evect3 = cp.get_complex_evect3();
+        BOOST_CHECK_SMALL(evect3.x.real(), 1e-5f);
+        BOOST_CHECK_SMALL(evect3.x.imag(), 1e-5f);
+        BOOST_CHECK_CLOSE(evect3.y.real(), 1.0f/sqrt(2.0f), 1e-5f);
+        BOOST_CHECK_SMALL(evect3.y.imag(), 1e-5f);
+        BOOST_CHECK_SMALL(evect3.z.real(), 1e-5f);
+        BOOST_CHECK_CLOSE(evect3.z.imag(), 1.0f/sqrt(2.0f), 1e-5f);
+
+        
+        
+}
+                
diff --git a/mia/3d/test_datafield.cc b/mia/3d/test_datafield.cc
index 79be924..9dd3d71 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_deform.cc b/mia/3d/test_deform.cc
index 97c424e..d75ae36 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ using namespace std;
 
 struct DeformFixture {
 	DeformFixture();
-	void check(EInterpolation ip);
+	void check(const string& ip);
 
 	C3DFVector voxel;
 	C3DBounds size;
@@ -51,10 +51,10 @@ DeformFixture::DeformFixture():
 	image.set_voxel_size(voxel);
 }
 
-void DeformFixture::check(EInterpolation ip)
+void DeformFixture::check(const string& ip)
 {
-	unique_ptr<C3DInterpolatorFactory> ipf(create_3dinterpolation_factory(ip,bc_mirror_on_bounds));
-	FDeformer3D d(transform, *ipf);
+	C3DInterpolatorFactory ipf(ip,"mirror");
+	FDeformer3D d(transform, ipf);
 	C3DImage& img = image;
 	P3DImage result = mia::filter(d, img);
 	const C3DFImage& r = dynamic_cast<const C3DFImage&>(*result);
@@ -68,11 +68,11 @@ void DeformFixture::check(EInterpolation ip)
 
 BOOST_FIXTURE_TEST_CASE( test_deform_nn, DeformFixture )
 {
-	check(ip_nn);
+	check("bspline:d=0");
 }
 
 
 BOOST_FIXTURE_TEST_CASE( test_deform_bspline3, DeformFixture )
 {
-	check(ip_bspline3);
+	check("bspline:d=3");
 }
diff --git a/mia/3d/test_distance.cc b/mia/3d/test_distance.cc
index 8687070..050c3a5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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_FIXTURE_TEST_CASE( test_distance_full3d_inf, Distance3DInfFixture )
 {
 	C3DFImage src_img(C3DBounds(4,4,4)); 
 	
-	distance_transform_prepare(&src_init[0], &src_init[64], src_img.begin()); 
+	distance_transform_prepare(&src_init[0], &src_init[64], src_img.begin(), true); 
 	
 	C3DFImage result =  distance_transform(src_img); 
 
@@ -61,7 +61,7 @@ BOOST_FIXTURE_TEST_CASE( test_distance_per_slice3d_inf, Distance3DInfFixture )
 	C2DFImage slice(C2DBounds(4,4)); 
 	
 	for (int i = 0; i < 4; ++i) {
-		distance_transform_prepare(&src_init[16 * i], &src_init[16 * (i+1)], slice.begin());
+		distance_transform_prepare(&src_init[16 * i], &src_init[16 * (i+1)], slice.begin(), true);
 		slice_based_distance.push_slice(i, slice); 
 	}
 
@@ -83,7 +83,7 @@ BOOST_FIXTURE_TEST_CASE( test_distance_per_slice3d_direct, Distance3DInfFixture
 	C2DFImage slice(C2DBounds(4,4)); 
 	
 	for (int i = 0; i < 4; ++i) {
-		distance_transform_prepare(&src_init[16 * i], &src_init[16 * (i+1)], slice.begin());
+		distance_transform_prepare(&src_init[16 * i], &src_init[16 * (i+1)], slice.begin(), true);
 		slice_based_distance.push_slice(i, slice); 
 	}
 
@@ -110,7 +110,7 @@ BOOST_FIXTURE_TEST_CASE( test_distance_per_slice3d_direct_3_3_3, Distance3DInfFi
 	C2DFImage slice(C2DBounds(4,4)); 
 	
 	for (int i = 0; i < 4; ++i) {
-		distance_transform_prepare(&src_init[16 * i], &src_init[16 * (i+1)], slice.begin());
+		distance_transform_prepare(&src_init[16 * i], &src_init[16 * (i+1)], slice.begin(), true);
 		slice_based_distance.push_slice(i, slice); 
 	}
 
@@ -126,7 +126,7 @@ BOOST_FIXTURE_TEST_CASE( test_distance_full3d_func,  Distance3DFuncFixture )
 {
 	C3DFImage src_img(C3DBounds(4,4,4)); 
 	
-	distance_transform_prepare(&src_init[0], &src_init[64], src_img.begin()); 
+	distance_transform_prepare(&src_init[0], &src_init[64], src_img.begin(), false); 
 	
 	C3DFImage result =  distance_transform(src_img); 
 
@@ -144,7 +144,7 @@ BOOST_FIXTURE_TEST_CASE( test_distance_per_slice3d_func, Distance3DFuncFixture )
 	C2DFImage slice(C2DBounds(4,4)); 
 	
 	for (int i = 0; i < 4; ++i) {
-		distance_transform_prepare(&src_init[16 * i], &src_init[16 * (i+1)], slice.begin());
+		distance_transform_prepare(&src_init[16 * i], &src_init[16 * (i+1)], slice.begin(), false);
 		slice_based_distance.push_slice(i, slice); 
 	}
 
diff --git a/mia/3d/test_fullcost.cc b/mia/3d/test_fullcost.cc
index 261bff5..b0000d9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_ica.cc b/mia/3d/test_ica.cc
index 975d6e2..0c3aec0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 @@
 
 #include <mia/internal/autotest.hh>
 
+
+#include <mia/core/ica.hh>
 #include <mia/3d/ica.hh>
 
 using namespace mia;
@@ -46,13 +48,13 @@ protected:
 BOOST_AUTO_TEST_CASE ( test_empty_initialization )
 {
 	vector<C3DFImage> series;
-	BOOST_CHECK_THROW( C3DImageSeriesICA s(series, false), invalid_argument);
+    BOOST_CHECK_THROW( C3DImageSeriesICA s(CICAAnalysisITPPFactory(),  series, false), invalid_argument);
 }
 
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean, ICA3DSeriesFixture )
 {
-	C3DImageSeriesICA ica(image_set, false);
+    C3DImageSeriesICA ica(CICAAnalysisITPPFactory(), image_set, false);
 
 	ica.run(3,false,false);
 
@@ -62,7 +64,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean, ICA3DSeriesFixture )
 
 BOOST_FIXTURE_TEST_CASE( test_ica_imcomplete_mix, ICA3DSeriesFixture )
 {
-	C3DImageSeriesICA ica(image_set, false);
+    C3DImageSeriesICA ica(CICAAnalysisITPPFactory(), image_set, false);
 	C3DImageSeriesICA::IndexSet skip;
 	skip.insert(0);
 	skip.insert(1);
@@ -81,7 +83,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_imcomplete_mix, ICA3DSeriesFixture )
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_stripped_series_mean, ICA3DSeriesFixture )
 {
-	C3DImageSeriesICA ica(image_set, true);
+    C3DImageSeriesICA ica(CICAAnalysisITPPFactory(), image_set, true);
 
 	ica.run(3,false,false);
 
@@ -91,7 +93,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_stripped_series_mean, ICA3DSeriesFixture
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp, ICA3DSeriesFixture )
 {
-	C3DImageSeriesICA ica(image_set, true);
+    C3DImageSeriesICA ica(CICAAnalysisITPPFactory(), image_set, true);
 
 	ica.run(4, false, false);
 
@@ -101,7 +103,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp, ICA3DSeriesFixture )
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_stripped_and_normalized, ICA3DSeriesFixture )
 {
-	C3DImageSeriesICA ica(image_set, true);
+    C3DImageSeriesICA ica(CICAAnalysisITPPFactory(), image_set, true);
 
 	ica.run(4, true, true);
 
@@ -111,7 +113,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_stripped_and_normalized,
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_normalized, ICA3DSeriesFixture )
 {
-	C3DImageSeriesICA ica(image_set, false);
+    C3DImageSeriesICA ica(CICAAnalysisITPPFactory(), image_set, false);
 
 	ica.run(4, true, true);
 
@@ -121,7 +123,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_normalized, ICA3DSeriesFi
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_normalized2, ICA3DSeriesFixture )
 {
-	C3DImageSeriesICA ica(image_set, false);
+    C3DImageSeriesICA ica(CICAAnalysisITPPFactory(), image_set, false);
 
 	ica.run(4, true, true);
 
@@ -131,7 +133,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_normalized2, ICA3DSeriesF
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_mix_normalized, ICA3DSeriesFixture )
 {
-	C3DImageSeriesICA ica(image_set, false);
+    C3DImageSeriesICA ica(CICAAnalysisITPPFactory(), image_set, false);
 
 	ica.run(4, true, false);
 
@@ -141,7 +143,7 @@ BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_mix_normalized, ICA3DSeri
 
 BOOST_FIXTURE_TEST_CASE( test_ica_with_some_mean_4comp_none, ICA3DSeriesFixture )
 {
-	C3DImageSeriesICA ica(image_set, false);
+    C3DImageSeriesICA ica(CICAAnalysisITPPFactory(), image_set, false);
 
 	ica.run(4, false, false);
 	for (size_t i = 0; i < slices; ++i)
@@ -161,7 +163,7 @@ BOOST_AUTO_TEST_CASE( test_ica_mean_substract )
 	images.push_back(C3DFImage(size, init_image1));
 	images.push_back(C3DFImage(size, init_image2));
 
-	C3DImageSeriesICA ica(images, true);
+    C3DImageSeriesICA ica(CICAAnalysisITPPFactory(), images, true);
 
 	const C3DFImage& mean = ica.get_mean_image();
 
diff --git a/mia/3d/test_image.cc b/mia/3d/test_image.cc
index 9cdee4e..2fdf187 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_imagecollect.cc b/mia/3d/test_imagecollect.cc
index 2c32e38..a11c83c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_imagedraw.cc b/mia/3d/test_imagedraw.cc
index a5e695a..b26856b 100644
--- a/mia/3d/test_imagedraw.cc
+++ b/mia/3d/test_imagedraw.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
new file mode 100644
index 0000000..bafa3c4
--- /dev/null
+++ b/mia/3d/test_imageio.cc
@@ -0,0 +1,126 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 <boost/mpl/vector.hpp>
+#include <boost/test/test_case_template.hpp>
+#include <boost/mpl/insert_range.hpp>
+
+#include <mia/core/attribute_names.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/3d/imageio.hh>
+
+using namespace std;
+using namespace mia;
+namespace bmpl=boost::mpl;
+
+template <typename Pixel>
+void store_and_load(const char *suffix)
+{
+        vector<unsigned char> values{
+                11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+                31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42};
+        
+        C3DBounds size(2,3,4); 
+
+        const C3DFVector voxel_size(2,3,4); 
+        T3DImage<Pixel> image(size);
+        image.set_voxel_size(voxel_size); 
+        
+        copy(values.begin(), values.end(), image.begin());
+
+        stringstream filenamestr;
+        filenamestr << "test3dio-" << __type_descr<Pixel>::value << "." << suffix;
+
+        auto filename = filenamestr.str(); 
+        BOOST_REQUIRE(save_image(filename, image));
+
+        auto test_image = load_image3d(filename);
+
+        const T3DImage<Pixel>& loaded = dynamic_cast<const T3DImage<Pixel>&>(*test_image);
+
+        BOOST_CHECK_EQUAL(loaded.get_size(), size);
+
+        BOOST_CHECK_EQUAL(loaded.get_voxel_size(), voxel_size);
+
+        auto p= loaded.begin();
+        auto tv = values.begin();
+        auto tve = values.end();
+
+        while (tv != tve) {
+                BOOST_CHECK_EQUAL(*p, *tv);
+                ++p; ++tv; 
+        }
+        unlink(filename.c_str());
+        
+        if (strcmp(suffix, "hdr") == 0) {
+                stringstream rawfilenamestr;
+                rawfilenamestr << "test3dio-" << __type_descr<Pixel>::value << ".img";
+                unlink(rawfilenamestr.str().c_str());
+        }
+                
+}
+
+struct InriaPixelTypes {
+	typedef bmpl::vector<signed char,
+			     unsigned char,
+			     signed short,
+			     unsigned short,
+			     signed int,
+			     unsigned int,
+			     float,
+			     double
+			     > type;
+};
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_volume_io_inria, T, InriaPixelTypes::type )
+{
+        store_and_load<T>("inr"); 
+}
+
+
+struct VffPixelTypes {
+	typedef bmpl::vector<unsigned char,
+			     signed short
+			     > type;
+};
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_volume_io_vff, T, VffPixelTypes::type )
+{
+        store_and_load<T>("vff"); 
+}
+
+
+struct AnalyzePixelTypes {
+	typedef bmpl::vector<unsigned char,
+			     signed short,
+			     signed int,
+			     float,
+			     double
+			     > type;
+};
+
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(test_volume_io_analyze, T, AnalyzePixelTypes::type )
+{
+        store_and_load<T>("hdr"); 
+}
diff --git a/mia/3d/test_interpol.cc b/mia/3d/test_interpol.cc
index 5c345ec..dfbe3cf 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +20,7 @@
 
 #include <climits>
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
 
 #include <boost/test/unit_test.hpp>
 #include <mia/3d/interpolator.hh>
@@ -142,30 +141,38 @@ extern const char bspline4[] = "bspline:d=4";
 extern const char bspline5[] = "bspline:d=5"; 
 extern const char omomsspl3[] = "omoms:d=3"; 
 
+const vector<const char*> interpolator_kernels = {
+	bspline0, bspline1, bspline2,
+	bspline3, bspline4, bspline5, omomsspl3 
+}; 
+
 
 BOOST_AUTO_TEST_CASE(test_external_cache_interpolator) 
 {
 	T3DDatafield<float> data(C3DBounds(10, 12, 11));
-	auto kernel = produce_spline_kernel(bspline3); 
-	
+
 	auto i = data.begin();
 	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 + y + z + 1;
 
-	T3DConvoluteInterpolator<float>  src(data, kernel);
+	for (auto k: interpolator_kernels) {
+		auto kernel = produce_spline_kernel(k); 
+		
+		T3DConvoluteInterpolator<float>  src(data, kernel);
 	
-	auto cache = src.create_cache(); 
-	i = data.begin();
-
-	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) {
-				C3DFVector loc(x,y,z);
-				auto v = src(loc, cache);
-				BOOST_CHECK_CLOSE(v, *i, 0.01); 
-			}
+		auto cache = src.create_cache(); 
+		i = data.begin();
+		
+		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) {
+					C3DFVector loc(x,y,z);
+					auto v = src(loc, cache);
+					BOOST_CHECK_CLOSE(v, *i, 0.01); 
+				}
+	}
 }
 
 
@@ -180,7 +187,7 @@ struct FParallelInterpolator {
 		{
 		}
 
-	void operator()( const tbb::blocked_range<int>& range ) const {
+	void operator()( const C1DParallelRange& range ) const {
 		
 		auto cache = src.create_cache(); 
 		for (auto z = range.begin(); z != range.end(); ++z)
@@ -213,7 +220,7 @@ struct FParallelInterpolator2 {
 		{
 		}
 
-	void operator()( const tbb::blocked_range<int>& range ) const {
+	void operator()( const C1DParallelRange& range ) const {
 		CThreadMsgStream thread_stream;
 		auto cache = src.create_cache(); 
 		for (auto z = range.begin(); z != range.end(); ++z)
@@ -249,7 +256,7 @@ BOOST_AUTO_TEST_CASE(test_parallel_interpolator)
 	T3DDatafield<float> output(data.get_size());
 	FParallelInterpolator worker(output, src); 
 	
-	tbb::parallel_for(tbb::blocked_range<int>( 0, data.get_size().z), worker);
+	pfor(C1DParallelRange( 0, data.get_size().z), worker);
 	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)
@@ -281,7 +288,7 @@ BOOST_AUTO_TEST_CASE(test_parallel_interpolator_zerofill_shifted)
 	T3DDatafield<float> output(data.get_size());
 	FParallelInterpolator2 worker(output, src, shift, test_data); 
 	
-	tbb::parallel_for(tbb::blocked_range<int>( 0, data.get_size().z), worker);
+	pfor(C1DParallelRange( 0, data.get_size().z), worker);
 	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) {
@@ -345,4 +352,3 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_types, T , types )
 	test_type<T, bspline0>();
 	test_type<T, omomsspl3>();
 }
-
diff --git a/mia/3d/test_iterator.cc b/mia/3d/test_iterator.cc
index 3e62476..7aef97c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_landmark.cc b/mia/3d/test_landmark.cc
index 346241e..e7adf6f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8717e77..3bba025 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_matrix.cc b/mia/3d/test_matrix.cc
index 4883b50..8638dd7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,19 +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 =  m.get_eigenvector(0); 
+	C3DFVector vec =  m.get_real_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); 
 
-	vec =  m.get_eigenvector(1); 
+	vec =  m.get_real_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); 
 
-	vec =  m.get_eigenvector(2); 
+	vec =  m.get_real_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 8251774..1836d82 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9037020..974164b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ namespace bfs=boost::filesystem;
 
 BOOST_AUTO_TEST_CASE ( test_nothing ) 
 {
-	BOOST_MESSAGE("This is a placeholder"); 
+	BOOST_TEST_MESSAGE("This is a placeholder"); 
 }
 
 #if 0
diff --git a/mia/3d/test_orientation.cc b/mia/3d/test_orientation.cc
index b04655d..70e7d1c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ BOOST_AUTO_TEST_CASE( test_orientation_attribute )
 {
 	COrientationTranslator::register_for("orientation");
 	PAttribute attr = CStringAttrTranslatorMap::instance().to_attr("orientation", "axial");
-	C3DImageOrientation *io = dynamic_cast<C3DImageOrientation *>(attr.get());
+	const C3DImageOrientation *io = dynamic_cast<const C3DImageOrientation *>(attr.get());
 	BOOST_REQUIRE(io);
 
 	E3DImageOrientation orient = *io;
diff --git a/mia/3d/test_ppmatrix.cc b/mia/3d/test_ppmatrix.cc
index 5fbd588..37a4102 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 @@ struct TransformSplineFixtureFieldBase {
 		{
 		}
 	
-	void init(int dsize, double r, EInterpolation type) {
-		ipf.reset(create_3dinterpolation_factory(type, bc_mirror_on_bounds));
+	void init(int dsize, double r, const std::string& kernel) {
+		ipf.reset(new C3DInterpolatorFactory(kernel, "mirror"));
 		size = C3DBounds(2 * dsize + 1,2 * dsize + 1,2 * dsize + 1);
 		field = C3DFVectorfield(size);
 		range = r; 
@@ -102,10 +102,10 @@ struct TransformSplineFixtureMixed2: public TransformSplineFixtureFieldBase {
 
 BOOST_FIXTURE_TEST_CASE( test_bspline3_8_4_mix2,  TransformSplineFixtureMixed2 )
 {
-	init(8, 4, ip_bspline4);
+	init(8, 4, "bspline:d=4");
 
 	const T3DConvoluteInterpolator<C3DFVector>& interp = 
-		dynamic_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
+		static_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double h = 21.0 * pow(M_PI, 1.5) / (sqrt(2.0) * 2.0);
@@ -125,10 +125,10 @@ BOOST_FIXTURE_TEST_CASE( test_bspline3_8_4_mix2,  TransformSplineFixtureMixed2 )
 
 BOOST_FIXTURE_TEST_CASE( test_bspline3_8_4, TransformSplineFixtureDivOnly )
 {
-	init(8, 4, ip_bspline4);
+	init(8, 4, "bspline:d=4");
 
 	const T3DConvoluteInterpolator<C3DFVector>& interp = 
-		dynamic_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
+		static_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double testvalue = 105.0 * pow(M_PI, 1.5) / (sqrt(2.0) * 8.0); 
@@ -146,10 +146,10 @@ BOOST_FIXTURE_TEST_CASE( test_bspline3_8_4, TransformSplineFixtureDivOnly )
 
 BOOST_FIXTURE_TEST_CASE( test_nocurl_bspline3_7_4, TransformSplineFixtureDivOnly )
 {
-	init(9, 4, ip_bspline3);
+	init(9, 4, "bspline:d=3");
 
 	const T3DConvoluteInterpolator<C3DFVector>& interp = 
-		dynamic_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
+		static_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double testvalue = 105.0 * pow(M_PI, 1.5) / (sqrt(2.0) * 8.0); 
@@ -231,10 +231,10 @@ double TransformSplineFixtureMixed::graddiv2(double , double , double )const
 
 BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_10_4, TransformSplineFixtureMixed )
 {
-	init(10, 4, ip_bspline4);
+	init(10, 4, "bspline:d=4");
 
 	const T3DConvoluteInterpolator<C3DFVector>& interp = 
-		dynamic_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
+		static_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double testdiv = 7.0 * pow(M_PI, 1.5) / sqrt(2.0); 
@@ -261,10 +261,10 @@ BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_10_4, TransformSplineFixtureMixed )
 
 BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_20_4, TransformSplineFixtureMixed )
 {
-	init(20, 4, ip_bspline4);
+	init(20, 4, "bspline:d=4");
 
 	const T3DConvoluteInterpolator<C3DFVector>& interp = 
-		dynamic_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
+		static_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double testdiv = 7.0 * pow(M_PI, 1.5) / sqrt(2.0); 
@@ -290,10 +290,10 @@ BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_20_4, TransformSplineFixtureMixed )
 
 BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_20_7, TransformSplineFixtureMixed )
 {
-	init(20, 7, ip_bspline4);
+	init(20, 7, "bspline:d=4");
 
 	const T3DConvoluteInterpolator<C3DFVector>& interp = 
-		dynamic_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
+		static_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double testdiv = 7.0 * pow(M_PI, 1.5) / sqrt(2.0); 
@@ -319,10 +319,10 @@ BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_20_7, TransformSplineFixtureMixed )
 
 BOOST_FIXTURE_TEST_CASE( test_mix_bspline4_10_4_grad, TransformSplineFixtureMixed )
 {
-	init(4, 2, ip_bspline3);
+	init(4, 2, "bspline:d=3");
 
 	const T3DConvoluteInterpolator<C3DFVector>& interp = 
-		dynamic_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
+		static_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	C3DPPDivcurlMatrix divcurl(field.get_size(), field_range, *ipf->get_kernel(), 1.0, 1.0);
@@ -386,8 +386,8 @@ struct TransformSplineFixtureFieldNonuniform {
 	{
 
 	}
-	void init(const C3DBounds& dsize, double r, EInterpolation type) {
-		ipf.reset(create_3dinterpolation_factory(type, bc_mirror_on_bounds));
+	void init(const C3DBounds& dsize, double r, const std::string& kernel) {
+		ipf.reset(new C3DInterpolatorFactory(kernel, "mirror"));
 		size = C3DBounds(2*dsize.x + 1, 2*dsize.y + 1, 2*dsize.z + 1); 
 		field = C3DFVectorfield(size);
 		range = r; 
@@ -497,10 +497,10 @@ double TransformSplineFixtureMixed2::graddiv2(double x, double y, double z)const
 BOOST_FIXTURE_TEST_CASE( test_bspline3_nonuniform, TransformSplineFixtureMixedNonuniform )
 {
 	C3DBounds size(8,9,7); 
-	init(size, 4, ip_bspline4);
+	init(size, 4, "bspline:d=4");
 
 	const T3DConvoluteInterpolator<C3DFVector>& interp = 
-		dynamic_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
+		static_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double h = 21.0 * pow(M_PI, 1.5) / (sqrt(2.0) * 2.0);
@@ -527,10 +527,10 @@ BOOST_FIXTURE_TEST_CASE( test_bspline3_nonuniform, TransformSplineFixtureMixedNo
 BOOST_FIXTURE_TEST_CASE( test_bspline3_uniform, TransformSplineFixtureMixedNonuniform )
 {
 	C3DBounds size(8,8,8); 
-	init(size, 4, ip_bspline4);
+	init(size, 4, "bspline:d=4");
 
 	const T3DConvoluteInterpolator<C3DFVector>& interp = 
-		dynamic_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
+		static_cast<const T3DConvoluteInterpolator<C3DFVector>&>(*source); 
 	
 	auto coeffs = interp.get_coefficients(); 
 	const double h = 21.0 * pow(M_PI, 1.5) / (sqrt(2.0) * 2.0);
diff --git a/mia/3d/test_quaternion.cc b/mia/3d/test_quaternion.cc
index 2a6dc6a..0fd06bf 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 <mia/internal/autotest.hh>
 
 #include <mia/3d/quaternion.hh>
+#include <mia/core/utils.hh>
 
 NS_MIA_USE; 
 
diff --git a/mia/3d/test_regplugins.cc b/mia/3d/test_regplugins.cc
index 3e5d631..759ca32 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3fd20fc..fac917f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_rot.cc b/mia/3d/test_rot.cc
index 510431e..975073a 100644
--- a/mia/3d/test_rot.cc
+++ b/mia/3d/test_rot.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_shape.cc b/mia/3d/test_shape.cc
index 814a9a3..998f70b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6837578..3fefcca 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_splinetransformpenalty.cc b/mia/3d/test_splinetransformpenalty.cc
index 86f3111..6fedc79 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_stackdisttrans.cc b/mia/3d/test_stackdisttrans.cc
index 34d4ca8..5632d41 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 fa02029..909347b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_transform.cc b/mia/3d/test_transform.cc
index 344b0cb..5247d3a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_transformfactory.cc b/mia/3d/test_transformfactory.cc
index eab8218..6e098d1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_transio.cc b/mia/3d/test_transio.cc
index a8e9231..e274c72 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_vector.cc b/mia/3d/test_vector.cc
index 43505a8..47ed811 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -105,22 +105,12 @@ BOOST_AUTO_TEST_CASE( test_float_vector_option)
 
 	PCmdOption popt(make_opt(v,  "3dvector", 'f', "a float 3d vector option"));
 	const char *str_value = "1.2,3.4,8.2";
-	try {
-		popt->set_value(str_value);
-		BOOST_CHECK(v.x == 1.2f && v.y == 3.4f && v.z == 8.2f);
-	}
-	catch (invalid_argument& x) {
-		BOOST_FAIL(x.what());
-	}
+	popt->set_value(str_value);
+	BOOST_CHECK(v.x == 1.2f && v.y == 3.4f && v.z == 8.2f);
 
+	// don't accept extra characters 
 	const char *str_value_err = "1.2,3.4,8.2x";
-	try {
-		popt->set_value(str_value_err);
-		BOOST_FAIL("error value not detected");
-	}
-	catch (invalid_argument& x) {
-		BOOST_MESSAGE(string("Caught:") + string(x.what()));
-	}
+	BOOST_CHECK_THROW(popt->set_value(str_value_err), invalid_argument); 
 }
 
 BOOST_AUTO_TEST_CASE( test_size_vector_option)
@@ -129,23 +119,15 @@ BOOST_AUTO_TEST_CASE( test_size_vector_option)
 
 	PCmdOption popt(make_opt(v,  "3dbounds", 'f', "a 3d size option"));
 	const char *str_value = "12,34,256";
-	try {
-		cvdebug() << "initialising from '" << str_value<< "'\n";
-		popt->set_value(str_value);
-		BOOST_CHECK(v.x == 12 && v.y == 34 && v.z == 256);
-	}
-	catch (invalid_argument& x) {
-		BOOST_FAIL(x.what());
-	}
+	cvdebug() << "initialising from '" << str_value<< "'\n";
+	popt->set_value(str_value); 
+	
+	BOOST_CHECK(v.x == 12 && v.y == 34 && v.z == 256);
 
+	// don't accept floating point values 
 	const char *str_value_err = "1.2,3.4,8.2";
-	try {
-		popt->set_value(str_value_err);
-		BOOST_FAIL("error value not detected");
-	}
-	catch (invalid_argument& x) {
-		BOOST_MESSAGE(string("Caught:") + string(x.what()));
-	}
+	BOOST_CHECK_THROW(popt->set_value(str_value_err), invalid_argument);
+	
 }
 
 BOOST_AUTO_TEST_CASE( test_swizzle )
diff --git a/mia/3d/test_vectorfield.cc b/mia/3d/test_vectorfield.cc
index b429900..fd27d65 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 032deb9..7a615b9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 bbc981f..73c74ed 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/3d/timestep.hh
index e8b0cf7..352e994 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b7bac90..1586a51 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 dcca7e8..48d6861 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d0939ee..04e7cd1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5e00dca..122b928 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,7 @@
  *
  */
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
 
 #define VSTREAM_DOMAIN "3dtransform"
 #include <mia/3d/transform.hh>
@@ -262,7 +261,7 @@ struct F3DTransformer {
 		       const T3DConvoluteInterpolator<T>& _interp, 
 		       T3DImage<T>& _result); 
 
-	void operator() ( const tbb::blocked_range<int>& range ) const; 
+	void operator() ( const C1DParallelRange& range ) const; 
 
 	const C3DTransformation& trans; 
 	T3DImage<T>& result; 
@@ -297,7 +296,7 @@ struct F3DTransform : public TFilter<P3DImage> {
 		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);
+		pfor(C1DParallelRange( 0, timage->get_size().z), worker);
 
 		// if the transformation provides a forced output pixel spacing, 
 		// set it here 
@@ -329,7 +328,7 @@ F3DTransformer<T>::F3DTransformer(const C3DTransformation& _trans,
 }
 
 template <typename T> 
-void F3DTransformer<T>::operator() ( const tbb::blocked_range<int>& range ) const
+void F3DTransformer<T>::operator() ( const C1DParallelRange& range ) const
 {
 	CThreadMsgStream thread_stream;
 	auto cache = interp.create_cache(); 
diff --git a/mia/3d/transform.hh b/mia/3d/transform.hh
index 8ffd9e1..d8f719e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/affine.cc b/mia/3d/transform/affine.cc
index ec0a998..689cd6e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/affine.hh b/mia/3d/transform/affine.hh
index efa937b..21f9625 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/axisrot.cc b/mia/3d/transform/axisrot.cc
index 93944c1..296f061 100644
--- a/mia/3d/transform/axisrot.cc
+++ b/mia/3d/transform/axisrot.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/axisrot.hh b/mia/3d/transform/axisrot.hh
index 9da63c9..75c0d70 100644
--- a/mia/3d/transform/axisrot.hh
+++ b/mia/3d/transform/axisrot.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/raffine.cc b/mia/3d/transform/raffine.cc
index d3240ee..9c5adbe 100644
--- a/mia/3d/transform/raffine.cc
+++ b/mia/3d/transform/raffine.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/raffine.hh b/mia/3d/transform/raffine.hh
index 82920b8..4de15e9 100644
--- a/mia/3d/transform/raffine.hh
+++ b/mia/3d/transform/raffine.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/rigid.cc b/mia/3d/transform/rigid.cc
index a48d2a2..7c7f8d4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +20,7 @@
 
 #include <fstream>
 
-#include <tbb/parallel_reduce.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
 
 #include <mia/core/msgstream.hh>
 #include <mia/core/utils.hh>
@@ -301,12 +300,12 @@ void C3DRigidTransformation::translate(const C3DFVectorfield& gradient, CDoubleV
 	typedef vector<double> dvect; 
 	assert(gradient.get_size() == m_size);
 	assert(params.size() == degrees_of_freedom());
-
+	assert(params.size() == 6);  
 	auto sumslice = [&gradient, this] 
-		(const tbb::blocked_range<unsigned int>& range, dvect ls)->dvect{
-		
+		(const C1DParallelRange& range, dvect ls)->dvect{
+		assert(ls.size() == 6);  
 		double fz = range.begin() - m_rot_center.z; 
-		for (unsigned int z = range.begin(); z != range.end();++z, fz += 1.0) {
+		for (auto z = range.begin(); z != range.end();++z, fz += 1.0) {
 			auto g = gradient.begin_at(0,0,z);
 			double fy =  - m_rot_center.y; 
 			for (size_t y = 0; y < m_size.y; ++y, fy += 1.0) {
@@ -332,7 +331,7 @@ void C3DRigidTransformation::translate(const C3DFVectorfield& gradient, CDoubleV
 	}; 
 	
 	dvect init(params.size(), 0.0); 
-	auto sparams = tbb::parallel_reduce( tbb::blocked_range<unsigned int>(0, m_size.z, 1), init, sumslice, sum_parts); 
+	auto sparams = preduce( C1DParallelRange(0, m_size.z, 1), init, sumslice, sum_parts); 
 	std::copy(sparams.begin(), sparams.end(), params.begin()); 
 }
 
diff --git a/mia/3d/transform/rigid.hh b/mia/3d/transform/rigid.hh
index be8dce8..8bea1ea 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/rotation.cc b/mia/3d/transform/rotation.cc
index 55d230d..6bb6391 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/rotation.hh b/mia/3d/transform/rotation.hh
index fc73ac7..df2eb15 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/rotbend.cc b/mia/3d/transform/rotbend.cc
index dc3abe4..811c9ca 100644
--- a/mia/3d/transform/rotbend.cc
+++ b/mia/3d/transform/rotbend.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/rotbend.hh b/mia/3d/transform/rotbend.hh
index d46dccf..ac72e05 100644
--- a/mia/3d/transform/rotbend.hh
+++ b/mia/3d/transform/rotbend.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/spline.cc b/mia/3d/transform/spline.cc
index 9f1de51..4ebcf5f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,11 +31,7 @@
 #include <mia/3d/imageio.hh>
 #include <mia/core/index.hh>
 
-#ifdef HAVE_BLAS
-extern "C" {
-#include <cblas.h>
-}
-#endif
+#include <gsl/gsl_cblas.h>
 
 NS_MIA_BEGIN
 using namespace std;
@@ -538,7 +534,7 @@ float C3DSplineTransformation::get_max_transform() const
 
 }
 
-#ifdef HAVE_BLAS
+
 /*
   This versions of the INIT-GRID function evaluate a 3D vector field comprising the deformations 
   at each grid point. Other then interpolating at each grid point on  request, this version 
@@ -655,95 +651,6 @@ void C3DSplineTransformation::init_grid()const
 	m_grid_valid = true; 
 }
 
-#else 
-/*
-  This versions of the INIT-GRID function evaluate a 3D vector field comprising the deformations 
-  at each grid point. The filtering is done per row/column/pillar. The number of operations should 
-  be the same, but the BLAS version works the data in larger batches and should, therefore, take 
-  more advantage of caching effects. 
-*/
-void C3DSplineTransformation::init_grid()const
-{
-	reinit();
-	if (m_grid_valid) 
-		return; 
-
-	TRACE_FUNCTION; 
-	CScopedLock lock(m_mutex); 
-	if (!m_grid_valid) {
-		cvdebug() << "initialize grid\n"; 
-		if (!m_current_grid || (m_current_grid->get_size() != m_range)) {
-			cvdebug() << "initialize grid field\n"; 
-			m_current_grid.reset(new C3DFVectorfield(m_range)); 
-		}
-		cvdebug() << "Current gris has size " << m_current_grid->get_size() << "\n"; 
-		// now filter 
-		C3DFVectorfield tmp(C3DBounds(m_coefficients.get_size().x, 
-					      m_coefficients.get_size().y, 
-					      m_range.z));
-		
-		vector<C3DFVector> out_buffer(m_range.z); 
-		vector<C3DFVector> in_buffer(m_coefficients.get_size().z);
-		
-		for (size_t iy = 0; iy < m_coefficients.get_size().y; ++iy) {
-			for (size_t ix = 0; ix < m_coefficients.get_size().x; ++ix) {
-				m_coefficients.get_data_line_z(ix, iy, in_buffer);
-				for(size_t z = 0; z < m_range.z; ++z) {
-					int start_z = m_z_indices[z];
-					auto w = m_z_weights[z]; 
-					
-					out_buffer[z] = inner_product(w.begin(), w.end(), 
-								      in_buffer.begin() + start_z, C3DFVector());
-				}
-				tmp.put_data_line_z(ix, iy, out_buffer);
-			}
-		}
-		
-		C3DFVectorfield tmp2(C3DBounds(m_coefficients.get_size().x, 
-					      m_range.y, 
-					      m_range.z));
-
-		out_buffer.resize(m_range.y); 
-		in_buffer.resize(m_coefficients.get_size().y);
-
-		for (size_t iz = 0; iz < tmp.get_size().z; ++iz) {
-			for (size_t ix = 0; ix < tmp.get_size().x; ++ix) {
-				tmp.get_data_line_y(ix, iz, in_buffer);
-				for(size_t y = 0; y < m_range.y; ++y) {
-					int start = m_y_indices[y];
-					auto w = m_y_weights[y]; 
-					
-					out_buffer[y] = inner_product(w.begin(), w.end(), 
-								      in_buffer.begin() + start, C3DFVector());
-				}
-				tmp2.put_data_line_y(ix, iz, out_buffer);
-			}
-		}
-
-		in_buffer.resize(m_coefficients.get_size().x);
-		out_buffer.resize(m_range.x); 
-
-		for (size_t iz = 0; iz < tmp2.get_size().z; ++iz) {
-			for (size_t iy = 0; iy < tmp2.get_size().y; ++iy) {
-				tmp2.get_data_line_x(iy, iz, in_buffer);
-				for(size_t x = 0; x < m_range.x; ++x) {
-					int start = m_x_indices[x];
-					auto w = m_x_weights[x]; 
-					
-					out_buffer[x] = C3DFVector(x,iy,iz) - 
-						inner_product(w.begin(), w.end(), 
-							      in_buffer.begin() + start, C3DFVector());
-				}
-				m_current_grid->put_data_line_x(iy, iz, out_buffer);
-			}
-		}
-		m_grid_valid = true; 
-	}
-}
-#endif 
-
-
-
 C3DTransformation::const_iterator C3DSplineTransformation::begin() const
 {
 	TRACE_FUNCTION;
diff --git a/mia/3d/transform/spline.hh b/mia/3d/transform/spline.hh
index cc20a3d..1080fe6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_affine.cc b/mia/3d/transform/test_affine.cc
index 67e7e6c..ffa5a5e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_axisrot.cc b/mia/3d/transform/test_axisrot.cc
index 76b7992..2394f8c 100644
--- a/mia/3d/transform/test_axisrot.cc
+++ b/mia/3d/transform/test_axisrot.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_nonlinear.cc b/mia/3d/transform/test_nonlinear.cc
index cca9755..f75d7ba 100644
--- a/mia/3d/transform/test_nonlinear.cc
+++ b/mia/3d/transform/test_nonlinear.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_raffine.cc b/mia/3d/transform/test_raffine.cc
index 8312705..ed0e075 100644
--- a/mia/3d/transform/test_raffine.cc
+++ b/mia/3d/transform/test_raffine.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_rigid.cc b/mia/3d/transform/test_rigid.cc
index 7103d61..0edd6dc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_rotation.cc b/mia/3d/transform/test_rotation.cc
index b5a13ed..02e99e6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_rotbend.cc b/mia/3d/transform/test_rotbend.cc
index 6c318a5..acea2dc 100644
--- a/mia/3d/transform/test_rotbend.cc
+++ b/mia/3d/transform/test_rotbend.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_spline.cc b/mia/3d/transform/test_spline.cc
index fa541af..67be069 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -356,7 +356,7 @@ BOOST_FIXTURE_TEST_CASE( test_splines_deform, TransformSplineFixture )
 	
 	C3DFImage test_image(range);
 	
-	auto_ptr<T3DInterpolator<float> > src(ipf.create(image.data()));
+	unique_ptr<T3DInterpolator<float> > src(ipf.create(image.data()));
 
 	C3DFImage::iterator t = test_image.begin();
 
diff --git a/mia/3d/transform/test_translate.cc b/mia/3d/transform/test_translate.cc
index 63980d0..6852b00 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/test_vectorfield.cc b/mia/3d/transform/test_vectorfield.cc
index ac5f304..2200193 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/translate.cc b/mia/3d/transform/translate.cc
index 04de8f6..95f12a9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/translate.hh b/mia/3d/transform/translate.hh
index 94d6f44..1f0574b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vectorfield.cc b/mia/3d/transform/vectorfield.cc
index 9c979fb..0c9300f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vectorfield.hh b/mia/3d/transform/vectorfield.hh
index 1d3d89d..f45b93b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/transformfactory.cc b/mia/3d/transformfactory.cc
index 5c78b6e..270d5fe 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/transformfactory.hh b/mia/3d/transformfactory.hh
index a617ca5..612f2fd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/transformio.cc b/mia/3d/transformio.cc
index 309ca9b..3bd5f25 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +40,7 @@ template <> const char *  const
        "These plug-ins implement support for loading and saving 3D transformations to various file types.";
 
 
+template class TPlugin<C3DTransformation, io_plugin_type>;
 template class TIOPlugin<C3DTransformation>;
 template class THandlerSingleton<C3DTransformIOPluginHandlerImpl>;
 template class TIOPluginHandler<C3DTransformationIO>;
diff --git a/mia/3d/transformio.hh b/mia/3d/transformio.hh
index 10dbe53..2880468 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +33,9 @@ NS_MIA_BEGIN
 */
 typedef TIOPlugin<C3DTransformation> C3DTransformationIO; 
 
+extern template class EXPORT_3D TPlugin<C3DTransformation, io_plugin_type>;
+extern template class EXPORT_3D TIOPlugin<C3DTransformation>;
+
 /**
    \ingroup io
    \brief The non-singleton plug-in handler for 3D transformations 
diff --git a/mia/3d/transformmock.cc b/mia/3d/transformmock.cc
index f2305b1..3178955 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8775a2d..2376e63 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ff427f5..f00be39 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5ee87c2..0541300 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/xml.cc b/mia/3d/transio/xml.cc
index 8e9a548..9ddb082 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index d0c1f88..7ffd4d7 100644
--- a/mia/3d/valueattributetranslator.hh
+++ b/mia/3d/valueattributetranslator.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vector.hh b/mia/3d/vector.hh
index ab3e8e3..2a06c3c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vectorfield.cc b/mia/3d/vectorfield.cc
index 269d3e0..aec99d5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
  *
  */
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-
+#include <mia/core/parallel.hh>
 
 #include <mia/3d/vectorfield.hh>
 
@@ -39,7 +37,7 @@ EXPORT_3D C3DFVectorfield& operator += (C3DFVectorfield& a, const C3DFVectorfiel
 	C3DFVectorfield help(a.get_size());
 	std::copy(a.begin(), a.end(), help.begin());
 
-	auto callback = [&a, &b, &help](const tbb::blocked_range<size_t>& range) {
+	auto callback = [&a, &b, &help](const C1DParallelRange& range) {
 		
 		for (auto z = range.begin(); z != range.end();  ++z)  {
 			C3DFVectorfield::iterator i = a.begin_at(0,0,z);
@@ -52,7 +50,7 @@ EXPORT_3D C3DFVectorfield& operator += (C3DFVectorfield& a, const C3DFVectorfiel
 			}
 		}
 	}; 
-	tbb::parallel_for( tbb::blocked_range<size_t>(0, a.get_size().z, 1), callback); 
+	pfor( C1DParallelRange(0, a.get_size().z, 1), callback); 
 	return a;
 }
 
diff --git a/mia/3d/vectorfield.hh b/mia/3d/vectorfield.hh
index 906e76c..b33aad4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vfio.cc b/mia/3d/vfio.cc
index 5a6af72..72d6552 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vfio.hh b/mia/3d/vfio.hh
index b717b91..02a8895 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/3d/vfiotest.cc
index 16d9cff..f60f0cb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8b31c62..0619573 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/vfregularizer/test_sor.cc b/mia/3d/vfregularizer/test_sor.cc
index e23dcc8..6c57cd5 100644
--- a/mia/3d/vfregularizer/test_sor.cc
+++ b/mia/3d/vfregularizer/test_sor.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 65cc614..d3c217f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/CMakeLists.txt b/mia/core/CMakeLists.txt
index 6e754f3..afc60d7 100644
--- a/mia/core/CMakeLists.txt
+++ b/mia/core/CMakeLists.txt
@@ -16,7 +16,27 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 
-SET(MIACORE_SRC_BASE 
+SET(GSLPP_SOURCE 
+  gsl_matrix.cc
+  gsl_matrix_vector_ops.cc
+  gsl_multimin.cc
+  gsl_pca.cc 
+  gsl_vector.cc
+  gsl_wavelet.cc
+  )
+
+SET(GSLPP_HEADERS 
+  gsl_matrix.hh
+  gsl_matrix_vector_ops.hh
+  gsl_multimin.hh
+  gsl_pca.hh
+  gsl_vector.hh
+  gsl_wavelet.hh
+  gsl_defines.hh
+  )
+
+SET(MIACORE_SRC_BASE
+  ${GSLPP_SOURCE} 
   attributes.cc 
   attribute_names.cc 
   boundary_conditions.cc
@@ -33,6 +53,8 @@ SET(MIACORE_SRC_BASE
   distance.cc
   dlloader.cc
   dummyhandler.cc
+  fastica.cc
+  fastica_nonlinearity.cc
   file.cc 
   filetools.cc 
   filter.cc
@@ -43,12 +65,13 @@ SET(MIACORE_SRC_BASE
   fullstats.cc
   handlerbase.cc
   history.cc
+  icaanalysisbase.cc
   index.cc
   info.cc
-  splinekernel.cc
   interpolator1d.cc
   iodata.cc
   ioplugin.cc
+  kmeans.cc
   labelmap.cc
   mitestimages.cc
   module.cc
@@ -57,7 +80,7 @@ SET(MIACORE_SRC_BASE
   nccsum.cc 
   noisegen.cc 
   optionparser.cc 
-  optparam.cc 
+  optparam.cc
   paramoption.cc  
   parameter.cc  
   paramtranslator.cc  
@@ -76,7 +99,9 @@ SET(MIACORE_SRC_BASE
   shape.cc 
   slopestatistics.cc
   slopeclassifier.cc
-  spacial_kernel.cc 
+  spacial_kernel.cc
+  sparse_histogram.cc
+  splinekernel.cc
   splineparzenmi.cc
   sqmin.cc
   streamredir.cc
@@ -90,6 +115,7 @@ SET(MIACORE_SRC_BASE
   )
 
 SET(MIACORE_HEADER_BASE
+  ${GSLPP_HEADERS}
   attributes.hh
   attribute_names.hh 
   attributetype.hh
@@ -98,6 +124,7 @@ SET(MIACORE_HEADER_BASE
   cmdbooloption.hh
   cmdlineparser.hh
   cmdoption.hh
+  cmdparamoption.hh
   cmdoptionflags.hh
   cmdstringoption.hh
   cmeans.hh
@@ -118,6 +145,8 @@ SET(MIACORE_HEADER_BASE
   export_handler.hh
   factory.hh
   factory_trait.hh
+  fastica.hh
+  fastica_nonlinearity.hh
   fft1d_r2c.hh
   fftslopeclassifier.hh
   fifofilter.hh
@@ -132,6 +161,7 @@ SET(MIACORE_HEADER_BASE
   handler.cxx handler.hh
   history.hh
   histogram.hh
+  icaanalysisbase.hh
   index.hh
   import_handler.hh
   iodata.hh
@@ -148,6 +178,8 @@ SET(MIACORE_HEADER_BASE
   nccsum.hh
   optionparser.hh
   optparam.hh
+  parallel.hh
+  parallelcxx11.hh
   parameter.cxx parameter.hh
   paramoption.hh
   paramtranslator.hh
@@ -171,6 +203,7 @@ SET(MIACORE_HEADER_BASE
   splinekernel.hh
   splineparzenmi.hh
   spacial_kernel.hh
+  sparse_histogram.hh
   sparse_solver.hh
   sqmin.hh
   statistics.hh
@@ -191,20 +224,7 @@ SET(MIACORE_HEADER_BASE
   )
 
 SET(MIACORETEST_SRC 
-  test_core.cc
-  test_cost.cc
-  test_filter.cc
-  test_kernels.cc
-  test_optparam.cc
-  test_optionparser.cc
-  test_parameter.cc
-  test_pixeltype.cc
-  test_register.cc
-  test_sqmin.cc
-  test_streamredir.cc
-  test_dictmap.cc
-  test_fifofilter.cc
-  test_probmap.cc
+  test_core_combined.cc
 )
 
 IF(ITPP_FOUND)
@@ -217,6 +237,13 @@ IF(ITPP_FOUND)
     )
 ENDIF(ITPP_FOUND)
 
+IF(NOT TBB_FOUND)
+  SET(MIACORE_SRC_PARALLELCXX11 
+    parallelcxx11.cc
+    )
+  NEW_TEST(parallelcxx11 miacore)
+ENDIF(NOT TBB_FOUND)
+  
 IF(PWPDF_FOUND) 
   SET(PWPDF_SRC 
     pwh.cc
@@ -244,10 +271,10 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/revision.hh.cmake ${CMAKE_CURRENT_BIN
 #
 # the library target 
 #
-SET(MIACORE_SRC ${MIACORE_SRC_BASE} ${ITPP_SRC} ${FFTWF_SRC} ${PWPDF_SRC})
+SET(MIACORE_SRC ${MIACORE_SRC_BASE} ${ITPP_SRC} ${FFTWF_SRC} ${PWPDF_SRC} ${MIACORE_SRC_PARALLELCXX11})
 SET(MIACORE_HEADER ${MIACORE_HEADER_BASE} ${ITPP_HEADER} ${FFTWF_HEADER} ${PWPDF_HEADER})
 
-SET(miacore_deps miagsl ${BASELIBS} ${TBB_LIBRARIES} ${FFTWF_LIBRARIES} ${XMLPP_LIBRARIES})
+SET(miacore_deps ${BASELIBS} ${TBB_LIBRARIES} ${FFTWF_LIBRARIES} ${XMLPP_LIBRARIES})
 MIA_ADD_LIBRARY(miacore "${MIACORE_SRC}" "${miacore_deps}")
 
 IF(PWPDF_FOUND AND FFTWD_FOUND)
@@ -284,25 +311,34 @@ ENDIF(WIN32)
 #ENDIF (NOT WIN32)
 #CORE_TEST(noisegen)
 
+ADD_SUBDIRECTORY(fastica       )
 ADD_SUBDIRECTORY(cmeansinit    )
+ADD_SUBDIRECTORY(minimizer     )
+ADD_SUBDIRECTORY(noise         )
 ADD_SUBDIRECTORY(spacialkernel )
-ADD_SUBDIRECTORY(noise         ) 
-ADD_SUBDIRECTORY(minimizer     ) 
 ADD_SUBDIRECTORY(splinekernel  ) 
 ADD_SUBDIRECTORY(splinebc  ) 
 ADD_SUBDIRECTORY(testplug      )
 
+#tests that fork themselfs 
+SET(cmdxmlhelp_params  -r 1 --other o)
+NEW_TEST_WITH_PARAM(cmdxmlhelp miacore "${cmdxmlhelp_params}")
+
+
 NEW_TEST(Vector miacore)
 NEW_TEST(attributes miacore)
 NEW_TEST(boundary_conditions  miacore)
 NEW_TEST(callback miacore)
 NEW_TEST(cmdoptionflags miacore)
+NEW_TEST(cmdparamoption miacore)
 NEW_TEST(cmdlineparser miacore)
+NEW_TEST(cmdlineparseroutput miacore)
 NEW_TEST(cmeans miacore)
 NEW_TEST(datapool miacore)
 NEW_TEST(delayedparameter miacore)
 NEW_TEST(distance miacore)
 NEW_TEST(factoryoption miacore)
+NEW_TEST(fastica miacore)
 NEW_TEST(fftslopeclassifier miacore)
 NEW_TEST(filetools miacore)
 NEW_TEST(fixedwidthoutput miacore)
@@ -327,6 +363,7 @@ NEW_TEST(simpson miacore)
 NEW_TEST(slopeclassifier miacore)
 NEW_TEST(slopestatistics miacore)
 NEW_TEST(sparse_solver miacore)
+NEW_TEST(sparse_histogram miacore)
 NEW_TEST(splinekernel miacore)
 NEW_TEST(splineparzenmi miacore)
 NEW_TEST(streamvector miacore)
@@ -338,6 +375,13 @@ NEW_TEST(utils miacore)
 NEW_TEST(waveletslopeclassifier miacore)
 NEW_TEST(xmlinterface miacore)
 
+NEW_TEST(gsl_matrix miacore)
+NEW_TEST(gsl_matrix_vector_ops miacore)
+NEW_TEST(gsl_multimin miacore)
+NEW_TEST(gsl_pca miacore)
+NEW_TEST(gsl_vector miacore)
+
+
 IF(ITPP_FOUND)
   NEW_TEST(ica miacore)
 ENDIF(ITPP_FOUND)
diff --git a/mia/core/attribute_names.cc b/mia/core/attribute_names.cc
index 0a3d8d3..6002564 100644
--- a/mia/core/attribute_names.cc
+++ b/mia/core/attribute_names.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +58,12 @@ EXPORT_CORE const char * IDPixelIntensityRelationship = "PixelIntensityRelations
 
 EXPORT_CORE const char * IDPositionerPrimaryAngleIncrement = "PositionerPrimaryAngleIncrement"; 
 EXPORT_CORE const char * IDPositionerSecondaryAngleIncrement = "PositionerSecondaryAngleIncrement"; 
-EXPORT_CORE const char * IDSliceThickness = "SliceThickness"; 
+EXPORT_CORE const char * IDSliceThickness = "SliceThickness";
+EXPORT_CORE const char * IDSpacingBetweenSlices = "SpacingBetweenSlices"; 
 EXPORT_CORE const char * IDPhotometricInterpretation = "PhotometricInterpretation";
 
 EXPORT_CORE const char * IDAttrPixelSizeIsImager = "PixelSizeIsImagerSize"; 
+EXPORT_CORE const char * IDRescaleIntercept = "RescaleIntercept"; 
+EXPORT_CORE const char * IDRescaleSlope = "RescaleSlope"; 
 
 NS_MIA_END
diff --git a/mia/core/attribute_names.hh b/mia/core/attribute_names.hh
index d7eb623..93322d1 100644
--- a/mia/core/attribute_names.hh
+++ b/mia/core/attribute_names.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,11 +60,18 @@ 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 * IDSliceThickness;
+extern EXPORT_CORE const char * IDSpacingBetweenSlices; 
 extern EXPORT_CORE const char * IDPhotometricInterpretation; 
 
+
+
+
 extern EXPORT_CORE const char * IDAttrPixelSizeIsImager; 
-/// @endcond 
+extern EXPORT_CORE const char * IDRescaleIntercept; 
+extern EXPORT_CORE const char * IDRescaleSlope; 
+
+// \endcond DICOM_TAGS
 
 NS_MIA_END
 
diff --git a/mia/core/attributes.cc b/mia/core/attributes.cc
index c22ddcb..021406b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +234,11 @@ bool EXPORT_CORE operator == (const CAttributedData& a, const CAttributedData& b
 	return  *a.m_attr == *b.m_attr;
 }
 
+template class EXPORT_CORE TAttribute<unsigned char>;
+template class EXPORT_CORE TAttribute<signed char>; 
+
+template class EXPORT_CORE TAttribute<std::vector<unsigned char>>;
+template class EXPORT_CORE TAttribute<std::vector<signed char>>; 
 
 template class EXPORT_CORE  TTranslator<double>;
 template class EXPORT_CORE  TTranslator<std::vector<double> >;
diff --git a/mia/core/attributes.cxx b/mia/core/attributes.cxx
index 3ada79f..6c19f77 100644
--- a/mia/core/attributes.cxx
+++ b/mia/core/attributes.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/attributes.hh b/mia/core/attributes.hh
index b333881..ba71bd0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 <iostream>
 #include <sstream>
 #include <stdexcept>
+#include <type_traits>
+#include <iomanip>
 #include <boost/any.hpp>
 #include <boost/ref.hpp>
 #include <boost/lexical_cast.hpp>
@@ -561,14 +563,29 @@ int TAttribute<T>::type_id() const
    \remark this should replace the parameter translation methods 
 */
 
+template <typename T, bool is_floating>
+struct __convert_to_string
+{
+	static std::string apply(const typename ::boost::reference_wrapper<T>::type value) {
+		return boost::lexical_cast<std::string>(value);
+	}
+}; 
 
 template <typename T>
-struct dispatch_attr_string {
-	static std::string val2string(const typename ::boost::reference_wrapper<T>::type value) {
+struct __convert_to_string<T, true> {
+	static std::string apply(const typename ::boost::reference_wrapper<T>::type value) {
 		std::stringstream sval;
-		sval << boost::lexical_cast<std::string>(value);
+		sval << std::setprecision(10) << value; 
 		return sval.str();
 	}
+}; 
+
+
+template <typename T>
+struct dispatch_attr_string {
+	static std::string val2string(const typename ::boost::reference_wrapper<T>::type value) {
+		return __convert_to_string<T, std::is_floating_point<T>::value>::apply(value);
+	}
 	static T string2val(const std::string& str) {
 		T v;
 		std::istringstream svalue(str);
@@ -584,8 +601,9 @@ struct dispatch_attr_string<std::vector<T> > {
 		std::stringstream sval;
 		sval << value.size();
 		for (size_t i = 0; i < value.size(); ++i)
-			sval << " " << boost::lexical_cast<std::string>(value[i]);
-		return sval.str();
+			sval << " "
+			     <<  __convert_to_string<T, std::is_floating_point<T>::value>::apply(value[i]); 
+	        return sval.str();
 	}
 	static std::vector<T> string2val(const std::string& str) {
 		size_t s;
@@ -622,6 +640,15 @@ struct dispatch_attr_string<std::vector<bool> > {
 		std::istringstream svalue(str);
 		svalue >> s;
 		std::vector<bool> v(s);
+
+		// Added override for coverity
+		// 
+		// Since s is used as the size for the new vector, a large
+		// value will result in a std::bad_alloc exception. This
+		// is not worse than bailing out because s is larger than
+		// an abitrary set boundary that youle be cheked here.
+		// 
+		// coverity[tainted_scalar] 
 		for (size_t i = 0; i < s; ++i) {
 			bool value;
 			svalue >> value;
@@ -748,6 +775,12 @@ const T CAttributedData::get_attribute_as(const std::string& key, T default_valu
 	return *attr; 
 }
 
+extern template class EXPORT_CORE TAttribute<unsigned char>;
+extern template class EXPORT_CORE TAttribute<signed char>; 
+
+extern template class EXPORT_CORE TAttribute<std::vector<unsigned char>>;
+extern template class EXPORT_CORE TAttribute<std::vector<signed char>>; 
+
 
 typedef TTranslator<double> CDoubleTranslator;
 typedef TTranslator<std::vector<double> > CVDoubleTranslator;
diff --git a/mia/core/attributetype.hh b/mia/core/attributetype.hh
index 334efb0..b5fb0cd 100644
--- a/mia/core/attributetype.hh
+++ b/mia/core/attributetype.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 22e006b..bd6b873 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/core/boundary_conditions.hh
index e9c39d5..8701d73 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +72,11 @@ public:
 
 
 	/**
-	   Default copy constructor 
+	   Delete copy operations 
 	 */
-	CSplineBoundaryCondition(const CSplineBoundaryCondition& /*other*/) = default; 
+	CSplineBoundaryCondition(const CSplineBoundaryCondition& /*other*/) = delete;
+
+	CSplineBoundaryCondition& operator = (const CSplineBoundaryCondition& /*other*/) = delete; 
 
 	/**
 	   Constructor for the boundary conditions. 
diff --git a/mia/core/callback.cc b/mia/core/callback.cc
index 7f56386..5ca6ab1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 cf328ef..d065885 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 20d0349..94181a3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b184600..ed13701 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ce39a49..b820b07 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 <config.h>
-//#include <miaconfig.h>
+#include <miaconfig.h>
 #include <cstdlib>
 #include <cstring>
 #include <iostream>
@@ -32,7 +32,15 @@
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #endif
+
+#ifdef HAVE_TBB 
 #include <tbb/task_scheduler_init.h>
+#if defined(__PPC__) && ( TBB_INTERFACE_VERSION  < 6101 )
+#define TBB_PREFERE_ONE_THREAD 1
+#endif 
+#else
+#include <mia/core/parallelcxx11.hh>
+#endif
 
 #include <mia/core/xmlinterface.hh>
 #include <mia/core/tools.hh>
@@ -42,15 +50,9 @@
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/fixedwidthoutput.hh>
 
-#if defined(__PPC__) && ( TBB_INTERFACE_VERSION  < 6101 )
-#define TBB_PREFERE_ONE_THREAD 1
-#endif 
-
 extern void print_full_copyright(const char *name, const char *author);
 
-
 NS_MIA_BEGIN
-extern char const *get_revision(); 
 
 using std::ostream;
 using std::ofstream;
@@ -61,7 +63,7 @@ using std::logic_error;
 using std::vector; 
 using std::map; 
 using std::unique_ptr; 
-
+using std::setiosflags;
 
 #define ENTRY(X) {X, #X }
 const std::map<EProgramDescriptionEntry, const char *> g_DescriptionEntryNames = {
@@ -193,7 +195,7 @@ 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-2015 Leipzig, Germany and Madrid, Spain. "
+const char *g_basic_copyright2 = " 1999-2016 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"; 
@@ -203,12 +205,16 @@ CCmdOptionListData::CCmdOptionListData(const SProgramDescription& description):
 	usage(false),
 	version(false), 
 	copyright(false),
-	verbose(vstream::ml_warning), 
+	verbose(vstream::ml_warning),
+#if HAVE_TBB 
 #if TBB_PREFERE_ONE_THREAD
 	max_threads(1), 
-#else 
+#else
 	max_threads(tbb::task_scheduler_init::automatic), 
-#endif 
+#endif
+#else
+	max_threads(-1),
+#endif 	
 	m_selftest_run(false), 
 	m_stdout_is_result(false), 
 	m_log(&std::cout)
@@ -384,10 +390,13 @@ void CCmdOptionListData::print_help_xml(const char *name_help, const CPluginHand
 	auto cr = nodeRoot->add_child("Author");
 	cr->set_child_text(m_author); 
 
-	ofstream xmlfile(help_xml.c_str());  
-	
-	xmlfile << doc->write_to_string_formatted();
-	xmlfile << "\n"; 
+	if (help_xml != "-") {
+		ofstream xmlfile(help_xml.c_str());  
+		xmlfile << doc->write_to_string_formatted();
+		xmlfile << std::endl;
+	}else{
+		std::cout << doc->write_to_string_formatted();
+	}
 }
 
 /**
@@ -682,6 +691,8 @@ void CCmdOptionList::set_stdout_is_result()
 	m_impl->m_stdout_is_result = true; 
 }
 
+#ifdef HAVE_TBB 
+
 struct TBBTaskScheduler {
 	static const tbb::task_scheduler_init& initialize(int max_threads);
 }; 
@@ -699,6 +710,7 @@ const tbb::task_scheduler_init& TBBTaskScheduler::initialize(int max_threads)
 	return init; 
 }
 
+#endif 
 
 CCmdOptionList::EHelpRequested
 CCmdOptionList::do_parse(size_t argc, const char *args[], bool has_additional, 
@@ -767,6 +779,7 @@ CCmdOptionList::do_parse(size_t argc, const char *args[], bool has_additional,
 		m_impl->print_help(name_help, has_additional);
 		return hr_help;
 	}else if (!m_impl->help_xml.empty()) {
+		cvdebug() << "Write XML help\n";
 		m_impl->print_help_xml(name_help, additional_help);
 		return hr_help_xml;
 	} else if (m_impl->usage) {
@@ -808,10 +821,14 @@ CCmdOptionList::do_parse(size_t argc, const char *args[], bool has_additional,
 		throw invalid_argument(msg.str());
 	}
 	
+#ifdef HAVE_TBB 
 	// the return value and info output is mostly used to make sure the compiler 
 	// doesn't optimize anything away. 
 	const auto& ts  = TBBTaskScheduler::initialize(m_impl->max_threads); 
-	cvinfo() << "Task scheduler set to " << (ts.is_active() ? "active":"inactive") << "\n"; 
+	cvinfo() << "Task scheduler set to " << (ts.is_active() ? "active":"inactive") << "\n";
+#else
+	CMaxTasks::set_max_tasks(m_impl->max_threads); 
+#endif 	
 	return hr_no; 
 }
 
diff --git a/mia/core/cmdlineparser.hh b/mia/core/cmdlineparser.hh
index f8a8d87..cbe9365 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
 #include <iostream>
 #include <string>
 #include <iterator>
-#include <mia/core/cmdoption.hh>
-#include <mia/core/typedescr.hh>
-#include <mia/core/paramoption.hh>
+#include <mia/core/cmdparamoption.hh>
 #include <mia/core/dictmap.hh>
 #include <mia/core/flagstring.hh>
 #include <mia/core/handlerbase.hh>
@@ -84,46 +82,6 @@ typedef std::map<EProgramDescriptionEntry, const char *>  SProgramDescription;
 
 
 
-/** 
-    \ingroup cmdline
-    \brief Templated version based on CCmdOptionValue for values that can be converted to 
-    and from strings by stream operators 
-
-    Templated implementation of a command line option to hold a value of type T.
-    \tparam T value parameter, the type T has to support the operators
-    "std::ostream& operator << (std::ostream& os, T x)" and
-    "std::istream& operator >> (std::istream& os, T x)"
-    must be defined.
-    f the string passed to the option for translation can not be translation to a 
-    value of type T,
-    the \a set_value method will throw a \a std::invalid_argument exception
-    If T is of type template < typename R > std::vector < R >,  
-    the list of N values needs to be  given like value1,value2,...,valueN.
-*/
-template <typename T>
-class TCmdOption: public  CCmdOption{
-
-public:
-        /** Constructor of the command option
-	    \param[in,out] val variable to hold the parsed option value - pass in the default value -
-            exception: \a bool values always default to \a false
-	    \param short_opt short option name (or 0)
-	    \param long_opt long option name (must not be NULL)
-	    \param long_help long help string (must not be NULL)
-	    \param short_help short help string
-	    \param flags support options like required 
-        */
-	TCmdOption(T& val, char short_opt, const char *long_opt, const char *long_help,
-                   const char *short_help, CCmdOptionFlags flags = CCmdOptionFlags::none);
-
-private:
-	virtual void do_get_long_help_xml(std::ostream& os, CXMLElement& parent, HandlerHelpMap& handler_map) const; 
-	virtual bool do_set_value(const char *str_value);
-	virtual size_t do_get_needed_args() const;
-	virtual void do_write_value(std::ostream& os) const;
-	virtual const std::string do_get_value_as_string() const;
-	T& m_value;
-};
 
 /** 
     \ingroup cmdline
@@ -292,243 +250,6 @@ private:
 
 // implementation of template classes and functions
 
-/**
-   @cond INTERNAL 
-   @ingroup traits 
-   @brief Dispatcher to handle the translation of strings to values 
-   
-   Dispatch the translation between a string and value. The standard case assumes that 
-   we have exactly one value to translate and that the type T supports the stream in-and 
-   output operators << and >> 
-   \tparam the type to be translated 
-   \remark most of this is now obsolete since for most types the TParamater class and its 
-   derivatives/instanciantions are used 
-*/
-template <typename T>
-struct __dispatch_opt {
-	/**
-	   Handle the standard initialization, normally do nothing
-	*/
-        static void init(T& /*value*/){
-        }
-
-	/**
-	   Translate a string to a value by using the >> operator
-	   \param[in] svalue the value as string 
-	   \param[out] value 
-	*/
-        static bool  apply(const char *svalue, T& value) {
-                std::istringstream sval(svalue);
-
-                sval >> value;
-                while (isspace(sval.peek())) {
-                        char c;
-                        sval >> c;
-                }
-                return sval.eof();
-        }
-	/// \returns the number of string elements are expected, in the standard case that is one 
-	static size_t size(const T /*value*/) {
-                return 1;
-        }
-	
-	/**
-	   Translate the value to a string for the help output by using the operator << and adding "=" at the beginning 
-	   \param os the output stream 
-	   \param value the value 
-	 */
-        static void apply(std::ostream& os, const T& value, bool /*required*/) {
-                os << "=" << value << " ";
-        }
-
-	/**
-	   translate the value to a string by using the operator >>
-	   \param value the value 
-	   \returns the string representation of the value 
-	*/
-        static const std::string get_as_string(const T& value) {
-                std::ostringstream os;
-                os << value;
-                return os.str();
-        }
-};
-
-/**
-   @ingroup traits 
-   @brief Dispatcher to handle the translation of vectors of to and from a string 
-   \remark this specialization is still used, since no vector patameter type is defined with TParameter
-*/
-template <typename T>
-struct __dispatch_opt< std::vector<T> > {
-        static void init(std::vector<T>& /*value*/){
-
-        }
-        static bool  apply(const char *svalue, std::vector<T>& value) {
-		std::string h(svalue);
-		unsigned int n = 1; 
-		for(std::string::iterator 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 '", 
-									      svalue, "' provides ", n);
-			}
-		}else{
-			value.resize(n); 
-		}
-		
-                std::istringstream sval(h);
-		auto i =  value.begin(); 
-		while (!sval.eof()) {
-			sval >> *i;
-			++i; 
-		}
-                return sval.eof();
-        }
-
-        static size_t size(const std::vector<T>& /*value*/) {
-                return 1;
-        }
-
-        static void apply(std::ostream& os, const std::vector<T>& value, bool required) {
-
-                os << "=";
-		if (value.empty() && required)
-			os << "[required] "; 
-		else {
-			for (auto i = value.begin(); i != value.end(); ++i) {
-				if (i != value.begin())
-					os << ",";
-				os << *i;
-			}
-			os << " ";
-		}
-        }
-
-        static const std::string get_as_string(const std::vector<T>& value) {
-                std::ostringstream os;
-		for (auto i = value.begin(); i != value.end(); ++i) {
-			if (i != value.begin())
-				os << ",";
-			os << *i;
-		}
-                return os.str();
-        }
-};
-
-/**
-   @ingroup traits 
-   @brief Dispatcher to handle the translation for boolen values 
-   
-   \todo This dispatcher is not really translating anything, since boolean values are flags. 
-   which means, that now, since most other types are handled by TParameter, boolean command line parameters (flags) 
-   should be implemented as a differently. 
-*/
-template <>
-struct __dispatch_opt<bool> {
-        static void init(bool& value) {
-                value = false;
-        }
-        static bool apply(const char */*svalue*/, bool& value) {
-                value = true;
-                return true;
-        }
-        static size_t size(bool /*value*/) {
-                return 0;
-        }
-        static void apply(std::ostream& /*os*/, bool /*value*/, bool /*required*/) {
-        }
-        static const std::string get_as_string(const bool& value) {
-                return value ? "true" : "false";
-        }
-};
-
-
-/**
-   @ingroup traits 
-   @brief Dispatcher to handle the translation for string values 
-   
-   \todo This dispatcher is not really translating anything, since strings are just copied
-   which means, that now, since most other types are handled by TParameter, string command line parameters 
-   should be implemented a differently.
-*/
-template <>
-struct __dispatch_opt<std::string> {
-	static void init(std::string& /*value*/) {
-        }
-        static bool apply(const char *svalue, std::string& value) {
-                value = std::string(svalue);
-                return true;
-        }
-        static size_t size(std::string /*value*/) {
-                return 1;
-        }
-        static void apply(std::ostream& os, const std::string& value, bool required) {
-		if (value.empty()) 
-			if (required)
-				os << "[required] "; 
-			else
-				os << "=NULL ";
-		else 
-			os << "=" << value;
-        }
-        static const std::string get_as_string(const std::string& value) {
-                return value;
-        }
-};
-/// @endcond 
-
-
-//
-// Implementation of the standard option that holds a value
-//
-template <typename T>
-TCmdOption<T>::TCmdOption(T& val, char short_opt, const char *long_opt, 
-			  const char *long_help, const char *short_help, 
-			  CCmdOptionFlags flags):
-        CCmdOption(short_opt, long_opt, long_help, short_help, flags),
-        m_value(val)
-{
-        __dispatch_opt<T>::init(m_value);
-}
-
-template <typename T>
-bool TCmdOption<T>::do_set_value(const char *svalue)
-{
-        return __dispatch_opt<T>::apply(svalue, m_value);
-}
-
-template <typename T>
-size_t TCmdOption<T>::do_get_needed_args() const
-{
-        return __dispatch_opt<T>::size(m_value);
-}
-
-template <typename T>
-void TCmdOption<T>::do_write_value(std::ostream& os) const
-{
-        __dispatch_opt<T>::apply( os, m_value, is_required());
-}
-
-template <typename T>
-void TCmdOption<T>::do_get_long_help_xml(std::ostream& os, CXMLElement& parent, 
-					 HandlerHelpMap& /*handler_map*/) const
-{
-	do_get_long_help(os);
-	parent.set_attribute("type", __type_descr<T>::value);
-}
-
-template <typename T>
-const std::string TCmdOption<T>::do_get_value_as_string() const
-{
-        return __dispatch_opt<T>::get_as_string(m_value);
-}
 
 /**
    \ingroup cmdline
@@ -581,31 +302,6 @@ PCmdOption make_opt(T& value, EParameterBounds bflags, const std::vector<T>& bou
 
 /**
    \ingroup cmdline
-   \brief Create an option to set a vector of values, 
-   
-   The parameters on the command line will be separated by ',' and without spaces (or protected from the shell by usinh "". 
-   If the vetcor comes with a pre-allocated size, then the numer of given values must correspond to this size, 
-   Otherwise the size of the vector is deducted from the given command line parameter,. 
-   \tparam T type of the value hold by the vector
-   \param[in,out] value at input: if not empty, number of expected values and their defaults, at output: the values given on the command line
-   \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 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, CCmdOptionFlags flags = CCmdOptionFlags::none)
-{
-	return PCmdOption(new TCmdOption<std::vector<T> >(value, short_opt, long_opt, help, 
-							  long_opt, flags ));
-}
-
-/**
-   \ingroup cmdline
    \brief Create an option that represents a flag. 
    
    It is always assumed to be not set  if the according option is not given at the command line 
diff --git a/mia/core/cmdoption.cc b/mia/core/cmdoption.cc
index b827de5..ef2a7f1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cmdoption.hh b/mia/core/cmdoption.hh
index 18711ce..4c22823 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cmdoptionflags.hh b/mia/core/cmdoptionflags.hh
index 7d8c771..0cd98b2 100644
--- a/mia/core/cmdoptionflags.hh
+++ b/mia/core/cmdoptionflags.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cmdparamoption.hh b/mia/core/cmdparamoption.hh
new file mode 100644
index 0000000..5950a6b
--- /dev/null
+++ b/mia/core/cmdparamoption.hh
@@ -0,0 +1,463 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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_cmdparamlineparser_hh
+#define mia_core_cmdparamlineparser_hh
+
+#include <mia/core/cmdoption.hh>
+#include <mia/core/typedescr.hh>
+#include <mia/core/paramoption.hh>
+#include <mia/core/handlerbase.hh>
+
+NS_MIA_BEGIN
+
+
+/** 
+    \ingroup cmdline
+    \brief Templated version based on CCmdOptionValue for values that can be converted to 
+    and from strings by stream operators 
+
+    Templated implementation of a command line option to hold a value of type T.
+    \tparam T value parameter, the type T has to support the operators
+    "std::ostream& operator << (std::ostream& os, T x)" and
+    "std::istream& operator >> (std::istream& os, T x)"
+    must be defined.
+    f the string passed to the option for translation can not be translation to a 
+    value of type T,
+    the \a set_value method will throw a \a std::invalid_argument exception
+    If T is of type template < typename R > std::vector < R >,  
+    the list of N values needs to be  given like value1,value2,...,valueN.
+*/
+template <typename T>
+class TCmdOption: public  CCmdOption{
+
+public:
+        /** Constructor of the command option
+	    \param[in,out] val variable to hold the parsed option value - pass in the default value -
+            exception: \a bool values always default to \a false
+	    \param short_opt short option name (or 0)
+	    \param long_opt long option name (must not be NULL)
+	    \param long_help long help string (must not be NULL)
+	    \param short_help short help string
+	    \param flags support options like required 
+        */
+	TCmdOption(T& val, char short_opt, const char *long_opt, const char *long_help,
+                   const char *short_help, CCmdOptionFlags flags = CCmdOptionFlags::none);
+
+private:
+	virtual void do_get_long_help_xml(std::ostream& os, CXMLElement& parent, HandlerHelpMap& handler_map) const; 
+	virtual bool do_set_value(const char *str_value);
+	virtual size_t do_get_needed_args() const;
+	virtual void do_write_value(std::ostream& os) const;
+	virtual const std::string do_get_value_as_string() const;
+	T& m_value;
+};
+
+
+
+/** 
+    \ingroup cmdline
+    \brief Templated version based on CCmdOptionValue for values that can be converted to 
+    and from strings by stream operators 
+
+    Templated implementation of a command line option to hold a value of type T.
+    \tparam T value parameter, the type T has to support the operators
+    "std::ostream& operator << (std::ostream& os, T x)" and
+    "std::istream& operator >> (std::istream& os, T x)"
+    must be defined.
+    f the string passed to the option for translation can not be translation to a 
+    value of type T,
+    the \a set_value method will throw a \a std::invalid_argument exception
+    If this option is repeated on the command line then the values are accumulated 
+    in the value vector. 
+
+*/
+template <typename T>
+class TRepeatableCmdOption: public  CCmdOption{
+
+public:
+        /** Constructor of the command option
+	    \param[in,out] val variable to hold the parsed option value - pass in the default value -
+            exception: \a bool values always default to \a false
+	    \param short_opt short option name (or 0)
+	    \param long_opt long option name (must not be NULL)
+	    \param long_help long help string (must not be NULL)
+	    \param short_help short help string
+	    \param flags support options like required 
+        */
+	TRepeatableCmdOption(std::vector<T>& val, char short_opt, const char *long_opt, const char *long_help,
+                   const char *short_help, CCmdOptionFlags flags = CCmdOptionFlags::none);
+
+private:
+	virtual void do_get_long_help_xml(std::ostream& os, CXMLElement& parent, HandlerHelpMap& handler_map) const; 
+	virtual bool do_set_value(const char *str_value);
+	virtual size_t do_get_needed_args() const;
+	virtual void do_write_value(std::ostream& os) const;
+	virtual const std::string do_get_value_as_string() const;
+	std::vector<T>& m_value;
+};
+
+
+
+
+/**
+   @cond INTERNAL 
+   @ingroup traits 
+   @brief Dispatcher to handle the translation of strings to values 
+   
+   Dispatch the translation between a string and value. The standard case assumes that 
+   we have exactly one value to translate and that the type T supports the stream in-and 
+   output operators << and >> 
+   \tparam the type to be translated 
+   \remark most of this is now obsolete since for most types the TParamater class and its 
+   derivatives/instanciantions are used 
+*/
+template <typename T>
+struct __dispatch_opt {
+	/**
+	   Handle the standard initialization, normally do nothing
+	*/
+        static void init(T& /*value*/){
+        }
+
+	/**
+	   Translate a string to a value by using the >> operator
+	   \param[in] svalue the value as string 
+	   \param[out] value 
+	*/
+        static bool  apply(const char *svalue, T& value) {
+                std::istringstream sval(svalue);
+
+                sval >> value;
+                while (isspace(sval.peek())) {
+                        char c;
+                        sval >> c;
+                }
+                return sval.eof();
+        }
+	/// \returns the number of string elements are expected, in the standard case that is one 
+	static size_t size(const T /*value*/) {
+                return 1;
+        }
+	
+	/**
+	   Translate the value to a string for the help output by using the operator << and adding "=" at the beginning 
+	   \param os the output stream 
+	   \param value the value 
+	 */
+        static void apply(std::ostream& os, const T& value, bool /*required*/) {
+                os << "=" << value << " ";
+        }
+
+	/**
+	   translate the value to a string by using the operator >>
+	   \param value the value 
+	   \returns the string representation of the value 
+	*/
+        static const std::string get_as_string(const T& value) {
+                std::ostringstream os;
+                os << value;
+                return os.str();
+        }
+};
+
+/**
+   @ingroup traits 
+   @brief Dispatcher to handle the translation of vectors of to and from a string 
+   \remark this specialization is still used, since no vector patameter type is defined with TParameter
+*/
+template <typename T>
+struct __dispatch_opt< std::vector<T> > {
+        static void init(std::vector<T>& /*value*/){
+
+        }
+        static bool  apply(const char *svalue, std::vector<T>& value) {
+		std::string h(svalue);
+		unsigned int n = 1; 
+		for(std::string::iterator 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 '", 
+									      svalue, "' provides ", n);
+			}
+		}else{
+			value.resize(n); 
+		}
+		
+                std::istringstream sval(h);
+		auto i =  value.begin(); 
+		while (!sval.eof()) {
+			sval >> *i;
+			++i; 
+		}
+                return sval.eof();
+        }
+
+        static size_t size(const std::vector<T>& /*value*/) {
+                return 1;
+        }
+
+        static void apply(std::ostream& os, const std::vector<T>& value, bool required) {
+
+                os << "=";
+		if (value.empty() && required)
+			os << "[required] "; 
+		else {
+			for (auto i = value.begin(); i != value.end(); ++i) {
+				if (i != value.begin())
+					os << ",";
+				os << *i;
+			}
+			os << " ";
+		}
+        }
+
+        static const std::string get_as_string(const std::vector<T>& value) {
+                std::ostringstream os;
+		for (auto i = value.begin(); i != value.end(); ++i) {
+			if (i != value.begin())
+				os << ",";
+			os << *i;
+		}
+                return os.str();
+        }
+};
+
+/**
+   @ingroup traits 
+   @brief Dispatcher to handle the translation for boolen values 
+   
+   \todo This dispatcher is not really translating anything, since boolean values are flags. 
+   which means, that now, since most other types are handled by TParameter, boolean command line parameters (flags) 
+   should be implemented as a differently. 
+*/
+template <>
+struct __dispatch_opt<bool> {
+        static void init(bool& value) {
+                value = false;
+        }
+        static bool apply(const char */*svalue*/, bool& value) {
+                value = true;
+                return true;
+        }
+        static size_t size(bool /*value*/) {
+                return 0;
+        }
+        static void apply(std::ostream& /*os*/, bool /*value*/, bool /*required*/) {
+        }
+        static const std::string get_as_string(const bool& value) {
+                return value ? "true" : "false";
+        }
+};
+
+
+/**
+   @ingroup traits 
+   @brief Dispatcher to handle the translation for string values 
+   
+   \todo This dispatcher is not really translating anything, since strings are just copied
+   which means, that now, since most other types are handled by TParameter, string command line parameters 
+   should be implemented a differently.
+*/
+template <>
+struct __dispatch_opt<std::string> {
+	static void init(std::string& /*value*/) {
+        }
+        static bool apply(const char *svalue, std::string& value) {
+                value = std::string(svalue);
+                return true;
+        }
+        static size_t size(std::string /*value*/) {
+                return 1;
+        }
+        static void apply(std::ostream& os, const std::string& value, bool required) {
+		if (value.empty()) 
+			if (required)
+				os << "[required] "; 
+			else
+				os << "=NULL ";
+		else 
+			os << "=" << value;
+        }
+        static const std::string get_as_string(const std::string& value) {
+                return value;
+        }
+};
+/// @endcond 
+
+
+//
+// Implementation of the standard option that holds a value
+//
+template <typename T>
+TCmdOption<T>::TCmdOption(T& val, char short_opt, const char *long_opt, 
+			  const char *long_help, const char *short_help, 
+			  CCmdOptionFlags flags):
+        CCmdOption(short_opt, long_opt, long_help, short_help, flags),
+        m_value(val)
+{
+        __dispatch_opt<T>::init(m_value);
+}
+
+template <typename T>
+bool TCmdOption<T>::do_set_value(const char *svalue)
+{
+        return __dispatch_opt<T>::apply(svalue, m_value);
+}
+
+template <typename T>
+size_t TCmdOption<T>::do_get_needed_args() const
+{
+        return __dispatch_opt<T>::size(m_value);
+}
+
+template <typename T>
+void TCmdOption<T>::do_write_value(std::ostream& os) const
+{
+        __dispatch_opt<T>::apply( os, m_value, is_required());
+}
+
+template <typename T>
+void TCmdOption<T>::do_get_long_help_xml(std::ostream& os, CXMLElement& parent, 
+					 HandlerHelpMap& /*handler_map*/) const
+{
+	do_get_long_help(os);
+	parent.set_attribute("type", __type_descr<T>::value);
+}
+
+template <typename T>
+const std::string TCmdOption<T>::do_get_value_as_string() const
+{
+        return __dispatch_opt<T>::get_as_string(m_value);
+}
+
+
+template <typename T>
+TRepeatableCmdOption<T>::TRepeatableCmdOption(std::vector<T>& val, char short_opt, const char *long_opt,
+                                              const char *long_help,
+                                              const char *short_help,
+                                              CCmdOptionFlags flags):
+        CCmdOption(short_opt, long_opt, long_help, short_help, flags),
+        m_value(val)
+{
+        __dispatch_opt<std::vector<T>>::init(m_value);
+}
+
+template <typename T>
+void TRepeatableCmdOption<T>::do_get_long_help_xml(std::ostream& os, CXMLElement& parent,
+                                                   HandlerHelpMap& MIA_PARAM_UNUSED(handler_map)) const
+{
+	do_get_long_help(os);
+	parent.set_attribute("type", __type_descr<T>::value);
+        parent.set_attribute("repeatable", "1");
+}
+
+template <typename T>
+bool TRepeatableCmdOption<T>::do_set_value(const char *str_value)
+{
+        T value; 
+        bool good = __dispatch_opt<T>::apply(str_value, value);
+	if (good) {
+		m_value.push_back(value);
+	}
+	return good; 
+	
+
+}
+
+template <typename T>
+size_t TRepeatableCmdOption<T>::do_get_needed_args() const
+{
+        return 1;
+}
+
+template <typename T>
+void TRepeatableCmdOption<T>::do_write_value(std::ostream& os) const
+{
+        __dispatch_opt<std::vector<T>>::apply( os, m_value, is_required());
+}
+
+template <typename T>
+const std::string TRepeatableCmdOption<T>::do_get_value_as_string() const
+{
+        return __dispatch_opt<std::vector<T>>::get_as_string(m_value);
+}
+
+
+/**
+   \ingroup cmdline
+   \brief Create an option to set a vector of values, 
+   
+   The parameters on the command line will be separated by ',' and without spaces (or protected from the shell by usinh "". 
+   If the vetcor comes with a pre-allocated size, then the numer of given values must correspond to this size, 
+   Otherwise the size of the vector is deducted from the given command line parameter,. 
+   \tparam T type of the value hold by the vector
+   \param[in,out] value at input: if not empty, number of expected values and their defaults, at output: the values given on the command line
+   \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 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, CCmdOptionFlags flags = CCmdOptionFlags::none)
+{
+	return PCmdOption(new TCmdOption<std::vector<T> >(value, short_opt, long_opt, help, 
+							  long_opt, flags ));
+}
+
+
+/**
+   \ingroup cmdline
+   \brief Create a repeatable option to set a vector of values
+   
+   The option can be given more than one time. 
+   The values are accumulated in the parameter vector. 
+   \tparam T type of the value hold by the vector
+   \param[in,out] value at input: if not empty, number of expected values and their defaults, at output: the values given on the command line
+   \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 flags option flags indicating whether the option is required 
+   \remark be aware that localization of the decimal separator of floating point values is not used, 
+   it is always the full stop ".". 
+*/
+
+template <typename T>
+PCmdOption make_repeatable_opt(std::vector<T>& value, const char *long_opt, char short_opt, 
+			       const char *help, CCmdOptionFlags flags = CCmdOptionFlags::none)
+ {
+	return PCmdOption(new TRepeatableCmdOption<T>(value, short_opt, long_opt, help, 
+								    long_opt, flags ));
+}
+
+NS_MIA_END
+
+#endif 
diff --git a/mia/core/cmdstringoption.cc b/mia/core/cmdstringoption.cc
index ce2dc30..e4d2727 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cmdstringoption.hh b/mia/core/cmdstringoption.hh
index 2cdb9ab..d284322 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cmdtranslateroption.cc b/mia/core/cmdtranslateroption.cc
index c2a6a02..32994f6 100644
--- a/mia/core/cmdtranslateroption.cc
+++ b/mia/core/cmdtranslateroption.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cmdtranslateroption.hh b/mia/core/cmdtranslateroption.hh
index 562fd10..93ad62d 100644
--- a/mia/core/cmdtranslateroption.hh
+++ b/mia/core/cmdtranslateroption.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cmeans.cc b/mia/core/cmeans.cc
index e486157..fc7d9d9 100644
--- a/mia/core/cmeans.cc
+++ b/mia/core/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,28 +35,23 @@ using namespace std;
 
 struct CMeansImpl {
 
-	CMeansImpl(double k, double epsilon);
+	typedef vector<pair<double, CMeans::DVector>> Probmap; 
+	
+	CMeansImpl(double epsilon);
 
-	CMeans::SparseProbmap run(const CMeans::NormalizedHistogram& nh, CMeans::DVector& class_centers) const; 
+	Probmap run(const CMeans::NormalizedHistogram& nh, CMeans::DVector& class_centers) const; 
 
 private: 
-	void evaluate_probabilities(const CMeans::DVector& classes, CMeans::SparseProbmap& pv, double k) const; 
+	void evaluate_probabilities(const CMeans::DVector& classes, Probmap& pv) const; 
 	double update_class_centers(CMeans::DVector& class_center,
 				    const CMeans::NormalizedHistogram& nh, 
-				    const CMeans::SparseProbmap& pv) const; 
-	
-	double adjust_k(const CMeans::DVector& class_center,
-			const CMeans::NormalizedHistogram& nh, 
-			const CMeans::SparseProbmap& pv) const; 
-		
+				    const Probmap& pv) const; 
 	
-	double m_k;
 	double m_epsilon;
 }; 
 
 
-CMeansImpl::CMeansImpl(double k, double epsilon):
-	m_k(k), 
+CMeansImpl::CMeansImpl(double epsilon):
 	m_epsilon(epsilon)
 {
 }
@@ -65,10 +60,10 @@ const char *CMeans::Initializer::data_descr = "1d";
 const char *CMeans::Initializer::type_descr = "cmeans"; 
 
 
-CMeans::CMeans(double k, double epsilon, PInitializer class_center_initializer):
+CMeans::CMeans(double epsilon, PInitializer class_center_initializer):
 	m_cci(class_center_initializer)
 {
-	impl = new CMeansImpl(k, epsilon);
+	impl = new CMeansImpl(epsilon);
 }
 
 CMeans::~CMeans()
@@ -79,13 +74,22 @@ CMeans::~CMeans()
 
 CMeans::SparseProbmap CMeans::run(const SparseHistogram& histogram,  DVector& class_centers) const
 {
+	return run(histogram, class_centers, true);
+}
+
+CMeans::SparseProbmap CMeans::run(const SparseHistogram& histogram,  DVector& class_centers, bool de_normalize_results) const
+{
+	FUNCTION_NOT_TESTED; 
+		
 	// prepare input data 
 	NormalizedHistogram nhist(histogram.size());
-	
-	const double bin_shift = histogram[0].first;
+
+	const double bin_shift = histogram[0].first < 0 ? histogram[0].first : 0;
 	const double bin_scale = 1.0 / double(histogram[histogram.size() - 1].first - bin_shift);
 	const double inv_bin_scale = double(histogram[histogram.size() - 1].first - bin_shift);
 
+	cvinfo() << "Histogram conversion: shift = " <<  bin_shift << ", scale = " << bin_scale << "\n"; 
+	
 	size_t n = 0;
 	for(auto h: histogram)
 		n += h.second;
@@ -100,26 +104,37 @@ CMeans::SparseProbmap CMeans::run(const SparseHistogram& histogram,  DVector& cl
 		  [bin_shift, bin_scale, normalizer](const SparseHistogram::value_type& x) -> NormalizedHistogram::value_type {
 			  return make_pair((x.first - bin_shift) * bin_scale, x.second * normalizer);  
 		  });
-	
+
+	cvinfo() << "CMeans: normalized histogram range:[" <<  nhist[0].first
+		 << ", " << nhist[nhist.size()-1].first << "]\n"; 
 
 	class_centers = m_cci->run(nhist);
 	cvmsg() << "Initial class centers =" << class_centers << "\n"; 
-	SparseProbmap result = impl->run(nhist, class_centers);
+	auto internal_result = impl->run(nhist, class_centers);
 	cvmsg() << "Finale class centers =" << class_centers << "\n"; 
+
+	SparseProbmap result(internal_result.size()); 
 	
-	transform(result.begin(), result.end(), histogram.begin(), result.begin(),
-		  [](const SparseProbmap::value_type& p, const SparseHistogram::value_type& h) -> SparseProbmap::value_type {
+	transform(internal_result.begin(), internal_result.end(), histogram.begin(), result.begin(),
+		  [](const pair<double, CMeans::DVector>& p, const SparseHistogram::value_type& h) ->
+		  SparseProbmap::value_type {
 			  return make_pair(h.first, p.second); 
 		  }); 
-	
-	transform(class_centers.begin(), class_centers.end(), class_centers.begin(),
-		  [inv_bin_scale, bin_shift](double x) {
-			  return inv_bin_scale * x +  bin_shift; 
-		  });
+
+	// scale class centers to actual intensity range (if requested)
+	if (de_normalize_results) {
+		transform(class_centers.begin(), class_centers.end(), class_centers.begin(),
+			  [inv_bin_scale, bin_shift](double x) {
+				  return inv_bin_scale * x +  bin_shift; 
+			  });
+		cvmsg() << "Finale class rescaled =" << class_centers << "\n"; 
+	}
 	
 	return result; 
 }
 
+
+
 template<>  const char * const 
 TPluginHandler<TFactory<CMeans::Initializer>>::m_help = 
 	"These plug-ins provide methods to initialize the cmeans classification.";
@@ -128,33 +143,46 @@ TPluginHandler<TFactory<CMeans::Initializer>>::m_help =
 template class TPlugin<CMeans::Initializer, CMeans::Initializer>;
 template class TFactory<CMeans::Initializer>;
 template class TFactoryPluginHandler<CMeansInitializerPlugin>;
-template class EXPORT_CORE TPluginHandler<TFactory<CMeans::Initializer>>;
+template class TPluginHandler<TFactory<CMeans::Initializer>>;
 template class THandlerSingleton<TFactoryPluginHandler<CMeansInitializerPlugin>>;
 
-void CMeansImpl::evaluate_probabilities(const CMeans::DVector& classes, CMeans::SparseProbmap& pv, double k) const
+void CMeansImpl::evaluate_probabilities(const CMeans::DVector& classes,
+					Probmap& pv) const
 {
         for (auto p = pv.begin(); p != pv.end(); ++p) {
-                double x = p->first;
-                double sum = 0.0;
-
-                for (size_t j = 0; j < classes.size(); ++j) {
-                        double  val =  x - classes[j]; 
-                        val = exp(- (val * val) / k);
-                        p->second[j] = val; 
-			sum += val;
-                }
-                
-                assert(sum != 0.0);
-                for (size_t j = 0; j < classes.size(); ++j)
-			p->second[j] /= sum;
-
-		cvdebug() << "Probs " << x << ":" << p->second << "\n"; 
-        }
+                double x = p->first; 
+		fill(p->second.begin(), p->second.end(), 0.0); 
+		
+		if ( x < classes[0]) {
+			p->second[0] = 1.0;
+		} else {
+			unsigned j = 1;
+			bool value_set = false; 
+			while (!value_set && (j < classes.size()) ) {
+				// between two centers
+				if (x < classes[j]) {
+					double p0 = x - classes[j-1];
+					double p1 = x - classes[j];
+					double p02 = p0 * p0;
+					double p12 = p1 * p1;
+					double normalizer = 1.0/(p02 + p12); 
+					
+					p->second[j] = p02  * normalizer;
+					p->second[j - 1] = p12  * normalizer;
+					value_set = true;
+				}
+				++j; 
+			}
+			if (!value_set)
+				p->second[classes.size() - 1] = 1.0; 
+		}
+
+	}
 }
 
 double CMeansImpl::update_class_centers(CMeans::DVector& class_center,
 				     const CMeans::NormalizedHistogram& nh, 
-				     const CMeans::SparseProbmap& pv)const
+				     const Probmap& pv)const
 {
 	double residuum = 0.0; 
 
@@ -180,50 +208,36 @@ double CMeansImpl::update_class_centers(CMeans::DVector& class_center,
 				sum_prob << ":" <<sum_weight <<"\n"; 
 			
 		}
-		double delta = cc - class_center[i]; 
+		double delta = (cc - class_center[i]) * 0.5; 
 		residuum += delta * delta; 
-		class_center[i] =  cc; 
+		class_center[i] +=  delta; 
 		
 	}// end update class centers
 	return sqrt(residuum); 
 }
 
-double CMeansImpl::adjust_k(const CMeans::DVector& class_center,
-			     const CMeans::NormalizedHistogram& nh, 
-			     const CMeans::SparseProbmap& pv)const
-{
-	cvwarn() << "CMeans: auto 'k' not implemented\n"; 
-	return m_k; 
-}
 
-
-CMeans::SparseProbmap CMeansImpl::run(const CMeans::NormalizedHistogram& nh, CMeans::DVector& class_centers) const
+CMeansImpl::Probmap
+CMeansImpl::run(const CMeans::NormalizedHistogram& nh, CMeans::DVector& class_centers) const
 {
 	int csize = class_centers.size(); 
-	CMeans::SparseProbmap pv(nh.size()); 
+	Probmap pv(nh.size()); 
 
 	transform(nh.begin(), nh.end(), pv.begin(), [csize](const CMeans::NormalizedHistogram::value_type& x) {
 			return make_pair(x.first, CMeans::DVector(csize));
 		}); 
         
-	double k = m_k; 
 	bool cont = true;
 
-	// for now no k adjustment
-	const bool auto_k = false; 
-	
 	while (cont) {
-		evaluate_probabilities(class_centers, pv, k);
+		evaluate_probabilities(class_centers, pv);
 		double residuum = update_class_centers(class_centers, nh, pv);
-		if (auto_k) {
-			k = adjust_k(class_centers, nh, pv); 
-		}
 		cvmsg() << "Class centers: " << class_centers
 			<<  ", res=" << residuum
-			<<  ", k=" << k 
 			<< "\n";
 		cont = residuum > m_epsilon; 
 	};
+	
 	return pv; 
 }
 
@@ -377,7 +391,6 @@ CMeans::DVector CMeans::SparseProbmap::get_fuzzy(double x) const
 		  });
 	
 	return result; 
-		
 }
 
 		
diff --git a/mia/core/cmeans.hh b/mia/core/cmeans.hh
index 01b7bd2..a668837 100644
--- a/mia/core/cmeans.hh
+++ b/mia/core/cmeans.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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/probmap.hh>
+#include <mia/core/sparse_histogram.hh>
 #include <mia/core/factory.hh>
 
 NS_MIA_BEGIN
@@ -29,13 +30,13 @@ NS_MIA_BEGIN
 class EXPORT_CORE CMeans {
 public:
 	typedef std::vector<double> DVector;
-	typedef std::vector<std::pair<int, unsigned long>> SparseHistogram;
+	typedef CSparseHistogram::Compressed SparseHistogram;
 	typedef std::vector<std::pair<double, double>> NormalizedHistogram;
 
 	class EXPORT_CORE SparseProbmap { 
 	public: 
-		typedef std::pair<double, DVector> value_type;  
-		typedef std::vector<std::pair<double, DVector>> Map;
+		typedef std::pair<unsigned short, DVector> value_type;  
+		typedef std::vector<value_type> Map;
 
 		SparseProbmap() = delete; 
 		SparseProbmap (size_t size);
@@ -87,11 +88,13 @@ public:
 	}; 
 	typedef std::shared_ptr<Initializer> PInitializer; 
 	
-	CMeans(double k, double epsilon, PInitializer class_center_initializer);
+	CMeans(double epsilon, PInitializer class_center_initializer);
 
 	~CMeans();
 	
 	SparseProbmap run(const SparseHistogram& histogram,  DVector& class_centers) const;
+
+	SparseProbmap run(const SparseHistogram& histogram,  DVector& class_centers, bool de_normalize_results) const;
 	
 private:
 	PInitializer m_cci; 
@@ -99,6 +102,158 @@ private:
 	
 };
 
+/**
+   \brief evaluate the probabilities for a c-means classification with gain field 
+   
+   This function evaluates the per-pixel class probabilities for a c-means 
+   classification with gain field correction. 
+
+   With n classes the evalaution is done aoocrding to 
+
+   \f[
+   p_{k,i} := \left\{\begin{array}{lcl}
+   I_k < c_0 & & p_{k,0} = 1, p_{k,i} = 0 \: \forall \: i \in [1, n-1]\\
+   c_j < I_k < c_{j+1} & & 
+        p_{k,l} = \frac{(I_k - g_k * c_{m})^2}{(I_k - g_k * c_{m})^2 + (I_k - g_k * c_{l})^2} 
+       \: \forall \: (l,m) \in \{(j, j+1), (j+1, j)\}\\
+	I_k > c_{n-1} & & p_{k,n} = 1,  p_{k,i} = 0 \: \forall \: i \in [0, n-2]
+   \end{array} \right. 
+   \f]
+
+   \tparam T input pixel type of the data to be classified 
+   \tparam Field template of the data field type 
+   \param[in] image image the classification is applied to 
+   \param[in] gain multiplicative gain field 
+   \param[in] class_centers 
+   \param[out] pv probability fields containing the evaluated probabilities 
+   
+*/
+
+
+template <typename T, template <class > class  Field> 
+void cmeans_evaluate_probabilities(const Field<T>& image, const Field<float>& gain,
+				   const std::vector<double>& class_centers,
+				   std::vector<Field<float>>& pv)
+{
+	assert(image.size() == gain.size());
+	assert(class_centers.size() == pv.size());
+#ifndef NDEBUG
+	for (auto i: pv)
+		assert(image.size() == i.size());
+#endif 	
+	
+	auto ii = image.begin();
+	auto ie = image.end();
+	auto ig = gain.begin();
+	typedef typename Field<float>::iterator prob_iterator; 
+
+	std::vector<prob_iterator> ipv(pv.size());
+	transform(pv.begin(), pv.end(), ipv.begin(), [](Field<float>& p){return p.begin();});
+
+	std::vector<double> gain_class_centers(class_centers.size());
+	
+	while (ii != ie) {
+		double x = *ii; 
+		for(auto iipv: ipv)
+			*iipv = 0.0;
+
+		const double  vgain = *ig; 
+		transform(class_centers.begin(), class_centers.end(), gain_class_centers.begin(),
+			  [vgain](double x){return vgain * x;}); 
+		
+		if ( x < gain_class_centers[0]) {
+			*ipv[0] = 1.0; 
+		} else {
+			unsigned j = 1;
+			bool value_set = false; 
+			while (!value_set && (j < class_centers.size()) ) {
+				// between two centers
+				if (x < gain_class_centers[j]) {
+
+					double p0 = x - gain_class_centers[j-1];
+					double p1 = x - gain_class_centers[j];
+					double p02 = p0 * p0;
+					double p12 = p1 * p1;
+					double normalizer = 1.0/(p02 + p12); 
+					*ipv[j] = p02  * normalizer;
+					*ipv[j - 1] = p12  * normalizer;
+					value_set = true;
+				}
+				++j; 
+			}
+			if (!value_set)
+				*ipv[class_centers.size() - 1] = 1.0; 
+		}
+		++ii; ++ig;
+		for (unsigned i = 0; i < class_centers.size(); ++i)
+			++ipv[i];
+	}
+}
+
+/**
+   Evaluate the new clas centers from 
+   \f[
+   \sum_{k,i} (p_{i,k} I_k - g_k c_i)^2 \rightarrow \min
+   \f]
+   In order to avoid a ping-pong effect, the actual class center update is evaluated 
+   according to 
+   \f[
+   c_i^{(t+1)} = \frac{1}{2} \left( \sum_{k} \frac{p_{i,k}^2 g_k I_k}{ p_{i,k}^2 g_k^2 } - c_i^{(t)} \right)
+   \f]
+   
+   \tparam T input pixel type of the data to be classified 
+   \tparam Field template of the data field type 
+   \param[in] image image the classification is applied to 
+   \param[in] gain multiplicative gain field 
+   \param[in] pv probability fields 
+   \param[in,out] class_centers 
+   \returns sum of absolute change applied to the class centers 
+
+*/
+
+template <typename T, template <class> class Field> 
+double cmeans_update_class_centers(const Field<T>& image, const Field<float>& gain,
+				 const std::vector<Field<float>>& pv, 
+				 std::vector<double>& class_centers)
+{
+	double residuum = 0.0; 
+
+	for (size_t i = 0; i < class_centers.size(); ++i) {
+		double cc = class_centers[i]; 
+		double sum_prob = 0.0; 
+		double sum_weight = 0.0; 
+
+		auto ie = image.end();
+		auto ii = image.begin();
+		auto ig = gain.begin();
+		auto ip = pv[i].begin();
+
+		while (ii != ie)  {
+			if (*ip > 0.0) {
+				auto v = *ip * *ip * *ig;
+				sum_prob += v * *ig; 
+				sum_weight += v * *ii;
+			}
+			++ii;
+			++ig;
+			++ip;
+		}
+			
+		
+		if (sum_prob  != 0.0) // move slowly in the direction of new center
+			cc = sum_weight / sum_prob; 
+		else {
+			cvwarn() << "class[" << i << "] has no probable members, keeping old value:" << 
+				sum_prob << ":" <<sum_weight <<"\n"; 
+			
+		}
+		double delta = (cc - class_centers[i]) * 0.5; 
+		residuum += delta * delta; 
+		class_centers[i] +=  delta;
+		
+	}// end update class centers
+	return sqrt(residuum); 
+}
 
 
 typedef TFactory<CMeans::Initializer> CMeansInitializerPlugin;
@@ -114,16 +269,21 @@ private:
        
 }; 
 
+/// @cond NEVER
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wattributes"
+#endif 
 extern template class EXPORT_CORE TPlugin<CMeans::Initializer, CMeans::Initializer>; 
 extern template class EXPORT_CORE TFactory<CMeans::Initializer>;
-
-template <>  const char * const TPluginHandler<TFactory<CMeans::Initializer>>::m_help;
-
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif 
 extern template class EXPORT_CORE TFactoryPluginHandler<TFactory<CMeans::Initializer>>;
-
 extern template class EXPORT_CORE THandlerSingleton<TFactoryPluginHandler<TFactory<CMeans::Initializer>> >;
+/// @endcond
 
-
+template <>  const char * const TPluginHandler<TFactory<CMeans::Initializer>>::m_help;
 
 
 typedef THandlerSingleton<TFactoryPluginHandler<CMeansInitializerPlugin> >CMeansInitializerPluginHandler;
diff --git a/mia/core/cmeansinit/kmeans.cc b/mia/core/cmeansinit/kmeans.cc
index e913a9d..a52ec3b 100644
--- a/mia/core/cmeansinit/kmeans.cc
+++ b/mia/core/cmeansinit/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 +122,15 @@ CMeans::DVector CKMeansInitializer::run(const CMeans::NormalizedHistogram& nh) c
 	
 	double sum = 0.0;
 	for(auto h : nh) {
-		sum += h.first * h.second; 
+		sum += h.first * h.second;
 	}; 
 
 	
 	// simple initialization splitting at the mean 
 	classes[0] = sum / 1.99;  
-	classes[1] = sum / 2.01; 
+	classes[1] = sum / 2.01;
+
+	cvinfo() << "kmeans: initial classes: " << classes << "\n"; 
 	
 	// first run calles directly 
 	int biggest_class = 0; 
diff --git a/mia/core/cmeansinit/kmeans.hh b/mia/core/cmeansinit/kmeans.hh
index 515bbcd..5e56ecc 100644
--- a/mia/core/cmeansinit/kmeans.hh
+++ b/mia/core/cmeansinit/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cmeansinit/static.cc b/mia/core/cmeansinit/static.cc
index b1d3816..1ac9b0c 100644
--- a/mia/core/cmeansinit/static.cc
+++ b/mia/core/cmeansinit/static.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cmeansinit/static.hh b/mia/core/cmeansinit/static.hh
index c1e2161..91ae85e 100644
--- a/mia/core/cmeansinit/static.hh
+++ b/mia/core/cmeansinit/static.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cmeansinit/test_kmeans.cc b/mia/core/cmeansinit/test_kmeans.cc
index c9bdd42..07d7ca9 100644
--- a/mia/core/cmeansinit/test_kmeans.cc
+++ b/mia/core/cmeansinit/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cmeansinit/test_static.cc b/mia/core/cmeansinit/test_static.cc
index a2de711..21e07b1 100644
--- a/mia/core/cmeansinit/test_static.cc
+++ b/mia/core/cmeansinit/test_static.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/core/combiner.cc
index a139a5a..4d40e65 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f399bae..19ccb3a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f707630..1042f61 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cxx b/mia/core/cost.cxx
index 2e1b66b..d28ffae 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 337ea50..a892f8a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/core/creator.cc
index d92d99d..a955b12 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 24f56d5..8c05bda 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6319f68..4be8a8c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4327b95..a36002d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 +23,10 @@
 #include <mia/core/datapool.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/core/errormacro.hh>
+#include <mia/core/parallel.hh>
 
 NS_MIA_BEGIN
 
-typedef tbb::recursive_mutex::scoped_lock CRecursiveScopedLock; 
 using namespace std;
 CDatapool::CDatapool()
 {
@@ -58,7 +58,7 @@ void CDatapool::add(const std::string& key, boost::any value)
 	m_map[key] = value;
 }
 
-tbb::recursive_mutex CDatapool::m_mutex; 
+CRecursiveMutex CDatapool::m_mutex; 
 
 CDatapool& CDatapool::instance()
 {
diff --git a/mia/core/datapool.hh b/mia/core/datapool.hh
index 5b9f4c8..cf69543 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +24,7 @@
 #include <map>
 #include <boost/any.hpp>
 
-#include <mia/core/defines.hh>
-#include <tbb/recursive_mutex.h>
-
+#include <mia/core/parallel.hh>
 
 NS_MIA_BEGIN
 
@@ -99,7 +97,7 @@ private:
 	Anymap m_map;
 	typedef std::map<std::string,bool> Usagemap;
 	mutable Usagemap m_usage;
-	static tbb::recursive_mutex m_mutex; 
+	static CRecursiveMutex m_mutex; 
 };
 
 NS_MIA_END
diff --git a/mia/core/defines.hh b/mia/core/defines.hh
index b4a43b0..816d40c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,23 +21,13 @@
 /**
    @file core/defines.hh 
    This file provides some defines to make life easier 
- */
+*/
 
 
 #ifndef mia_core_defines_hh
 #define mia_core_defines_hh
 
-#include <gsl++/gsldefines.hh>
-#include <tbb/mutex.h>
-
-
-/// The mutex renamed to MIA style
-typedef tbb::mutex CMutex; 
-
-
-/// The scoped lock renamed to MIA style
-typedef tbb::mutex::scoped_lock CScopedLock; 
-
+#include <mia/core/gsl_defines.hh>
 
 /// conveniance define to start the mia namespace 
 #define NS_MIA_BEGIN namespace mia {
@@ -67,6 +57,7 @@ typedef tbb::mutex::scoped_lock CScopedLock;
 */
 NS_MIA_BEGIN
 
+
 /// some constants for interpoation types
 enum EInterpolation {
 	ip_nn,       /**< nearest neighbor interpolation */
@@ -137,5 +128,11 @@ NS_MIA_END
 #  define VSTREAM "MIA-CORE"
 #endif
 
+NS_MIA_BEGIN
+
+EXPORT_CORE extern char const *get_revision(); 
+
+NS_MIA_END
+
 #endif
 
diff --git a/mia/core/delayedparameter.hh b/mia/core/delayedparameter.hh
index 82d7676..9a26e5d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/dictmap.hh b/mia/core/dictmap.hh
index 1366e12..88751a4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2ac9365..3d0e775 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1bf0e58..99f7168 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,23 +41,6 @@ NS_MIA_BEGIN
 
 void EXPORT_CORE distance_transform_inplace(std::vector<float>& r); 
 
-
-template <typename InputIterator, typename OutputIterator, typename T> 
-struct __distance_transform_prepare {
-	static void apply(InputIterator in_begin, InputIterator in_end, OutputIterator out_begin){
-		std::transform(in_begin, in_end, out_begin, [](float x){ return x*x;});
-	}
-}; 
-
-template <typename InputIterator, typename OutputIterator> 
-struct __distance_transform_prepare<InputIterator, OutputIterator, bool> {
-	static void apply(InputIterator in_begin, InputIterator in_end, OutputIterator out_begin){
-		std::transform(in_begin, in_end, out_begin, 
-			       [](bool x){ return x ? 0.0f : std::numeric_limits<float>::max();});
-	}
-}; 
-
-
 /**
    This function evaluates prepares data for the use in a distance transform. 
    The input values are interpreted differently depending on the input data type: 
@@ -72,14 +55,21 @@ struct __distance_transform_prepare<InputIterator, OutputIterator, bool> {
    \param in_end end of the input data range 
    \param out_begin begin of the output data container, note that the output container must at least hold as 
    many values as the input data range provides. This is not tested. 
+   \param to_mask set to true if the input data is a mask, to false if the input data is a height field
 */
 
 template <typename InputIterator, typename OutputIterator>
 void  distance_transform_prepare(InputIterator in_begin, InputIterator in_end, 
-					    OutputIterator out_begin) 
+				 OutputIterator out_begin, bool to_mask) 
 {
-	typedef typename std::iterator_traits<InputIterator>::value_type in_value_type; 
-	__distance_transform_prepare<InputIterator, OutputIterator, in_value_type>::apply( in_begin, in_end, out_begin); 
+	if (to_mask) {
+		std::transform(in_begin, in_end, out_begin, 
+			       [](bool x){ return x ? 0.0f : std::numeric_limits<float>::max();});
+	}else{
+		std::transform(in_begin, in_end, out_begin, [](float x){ return x*x;});
+	}
+		
+	
 }
 
 NS_MIA_END
diff --git a/mia/core/dlloader.cc b/mia/core/dlloader.cc
index 3d1a3f8..006d55d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c7e3d43..6093c5d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 77cfdb8..4366a94 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,11 +48,16 @@ template<> const char * const
 TPluginHandler<CTestIOPlugin>::m_help = "These are some dummy plug-ins for IO handler testing."; 
 
 
+void CDummyIOPluginHandler::check_file_exists(const std::string& MIA_PARAM_UNUSED(fname)) const
+{
+}
+
+
 template class TPlugin<test_io_data,io_plugin_type>; 
 template class TPluginHandler<CTestIOPlugin>;
 template class TIOPlugin<test_io_data>; 
 template class TIOPluginHandler<CTestIOPlugin>;
-template class THandlerSingleton<TIOPluginHandler<CTestIOPlugin> >;
+template class THandlerSingleton<CDummyIOPluginHandler>;
 
 
 NS_MIA_END
diff --git a/mia/core/dummyhandler.hh b/mia/core/dummyhandler.hh
index 27f7f33..e47e91d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +51,15 @@ public:
 };
 
 
+
+class EXPORT_CORE CDummyIOPluginHandler: public TIOPluginHandler<CTestIOPlugin> {
+	void check_file_exists(const std::string& fname) const; 
+}; 
+
+extern template class EXPORT_CORE TIOPluginHandler<CTestIOPlugin>;
+extern template class EXPORT_CORE THandlerSingleton<TIOPluginHandler<CTestIOPlugin> >;
 /// Test IO plugin handler, don't use this in real code  
-typedef THandlerSingleton<TIOPluginHandler<CTestIOPlugin> > CTestIOPluginHandler;
+typedef THandlerSingleton<CDummyIOPluginHandler> CTestIOPluginHandler;
 
 
 NS_MIA_END
diff --git a/mia/core/errormacro.hh b/mia/core/errormacro.hh
index b117c56..4ea6271 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 be53390..fa4a662 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 591534b..4d420c4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_trait.hh b/mia/core/factory_trait.hh
index efa6cab..7cd6be3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/fastica.cc b/mia/core/fastica.cc
new file mode 100644
index 0000000..42896ae
--- /dev/null
+++ b/mia/core/fastica.cc
@@ -0,0 +1,567 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/gsl_matrix_vector_ops.hh>
+#include <mia/core/gsl_pca.hh>
+#include <mia/core/fastica.hh>
+#include <algorithm>
+#include <random>
+#include <cmath>
+#include <stdexcept>
+#include <gsl/gsl_blas.h>
+#include <mia/core/fastica_nonlinearity.hh>
+
+NS_MIA_BEGIN 
+
+using gsl::Vector; 
+using gsl::Matrix; 
+using gsl::CSymmvEvalEvec; 
+
+using std::sort; 
+using std::transform; 
+using std::vector; 
+
+FastICA::FastICA(int num_ic):
+        m_approach(appr_defl), 
+        m_numOfIC(num_ic), 
+        m_finetune(true), 
+        m_mu(1.0), 
+        m_epsilon(1e-10), 
+        m_sampleSize(1.0), 
+        m_stabilization(true), 
+        m_maxNumIterations(1000), 
+        m_maxFineTune(200),
+	m_firstEig(-1), 
+	m_lastEig(-1),
+        m_PCAonly(false), 
+	m_component_energy_limit(0.9), 
+	m_with_initial_guess(false), 
+	m_do_saddle_check(false), 
+	m_saddle_postiter(100), 
+	m_separating_matrix(1,1,false)
+{
+        m_nonlinearity = produce_fastica_nonlinearity("pow3");  
+}
+
+struct CCenteredSignal  {
+	CCenteredSignal(const Matrix& mixedSig); 
+	
+	Matrix signal; 
+	Vector mean; 
+}; 
+
+
+CCenteredSignal::CCenteredSignal(const Matrix& mixedSig):
+	signal(mixedSig.rows(), mixedSig.cols(), false), 
+	mean(mixedSig.rows(), true)
+{
+	for (size_t r = 0; r < mixedSig.rows(); ++r) {
+		for (size_t c = 0; c < mixedSig.cols(); ++c)
+			mean[r] += mixedSig(r,c); 
+		mean[r] /= mixedSig.cols(); 
+		for (size_t c = 0; c < mixedSig.cols(); ++c)
+			signal.set(r,c, mixedSig(r,c) - mean[r]); 
+	}
+}
+
+void FastICA::evaluate_whiten_matrix(const Matrix& evec, const Vector& eval)
+{
+	m_whitening_matrix.reset(evec.cols(), evec.rows(), false); 
+	m_dewhitening_matrix.reset(evec.rows(), evec.cols(), false);
+	
+	for (unsigned  i = 0; i < eval.size(); i++) {
+		double iwscale = sqrt(eval[i]);
+		double wscale = 1.0 / iwscale;
+		
+		auto wmr = m_whitening_matrix.get_row(i); 
+		auto inv = evec.get_column(i);
+		auto dwmc = m_dewhitening_matrix.get_column(i); 
+		
+		transform(inv.begin(), inv.end(), wmr.begin(), 
+			  [wscale](double x) {return wscale * x;}); 
+		
+		transform(inv.begin(), inv.end(), dwmc.begin(), 
+			  [iwscale](double x) {return iwscale * x;}); 
+	}
+	
+	cvdebug() << "Whitening: = " << m_whitening_matrix << "\n"; 
+	cvdebug() << "DeWhitening: = " << m_dewhitening_matrix << "\n"; 
+
+}
+
+bool FastICA::separate(const gsl::Matrix&  mix)
+{
+	CCenteredSignal centered(mix);
+	cvdebug() << "separate signal of size " << centered.signal.rows() << "x" << centered.signal.cols() << "\n"; 
+
+	// currently not used 
+	Matrix guess;
+	if (m_initGuess)
+		guess = m_initGuess;
+
+
+	// run PCA to prepare the whitening 
+	// also select the limit of useful compinents based on maximal 
+	// energy 
+	gsl::PCA pca(m_numOfIC, m_component_energy_limit);
+	auto pca_result = pca.analyze(centered.signal); 
+	
+	if (pca_result.eval.size() < 1) {
+		m_independent_components = mix;
+		return false;
+	}
+
+	// update the number of components 
+	m_numOfIC = pca_result.eval.size(); 
+
+	cvdebug() << "Considering " << m_numOfIC << " independend components\n"; 
+	cvdebug() << "PCA: eval= " << pca_result.eval << "\n"; 
+	cvdebug() << "PCA: evec= " << pca_result.evec << "\n"; 
+
+	evaluate_whiten_matrix(pca_result.evec, pca_result.eval);
+
+	// if only PCA, stop here and save the dewithening as independend components 
+	// where is the mixing matrix? 
+	if (m_PCAonly) {
+		m_mixing_matrix.reset(mix.rows(), m_dewhitening_matrix.cols(), 1.0);
+		m_independent_components = m_dewhitening_matrix; 
+		return true; 
+	}
+
+	// run the actual ICA 
+	
+	auto whitened_signal = m_whitening_matrix * centered.signal; 
+
+	bool result = false; 
+	Matrix B( whitened_signal.rows(), m_numOfIC,  true); 	
+	
+	switch (m_approach) {
+	case appr_defl: result = fpica_defl(whitened_signal, B);break; 
+	case appr_symm: result = fpica_symm(whitened_signal, B); break; 
+	default: 
+		throw std::invalid_argument("FastICA::separate: unknown apporach given"); 
+		
+	}
+
+	// evaluate the results if the ICA 
+	m_mixing_matrix = m_dewhitening_matrix * B; 
+		
+	cvdebug() << "Mixing matrix= " << m_mixing_matrix << "\n"; 
+
+	multiply_mT_m(m_separating_matrix, B, m_whitening_matrix); 
+	
+	m_independent_components = m_separating_matrix * mix; 
+
+	cvdebug() << "ICs= " << m_independent_components << "\n"; 
+
+	return result; 
+}
+
+bool FastICA::fpica_defl_round(int component, Vector& w, Matrix& B)
+{
+	Vector w_old(w);
+	Vector w_old2(w);
+
+	double mu = m_mu;
+	double delta = m_epsilon + 1.0;
+
+	bool is_finetuning = false;  
+	bool converged = false; 
+	bool loong = false; 
+
+	double stroke = 0.0; 
+
+	int iter = 0;
+	int maxiter = m_maxNumIterations; 
+	
+	while (!converged && iter < maxiter) {
+			
+		cvdebug() << "Defl: c=" << component
+			  << ", iter= " << iter 
+			  << ", delta= " << delta
+			  << "\n"; 
+		
+		m_nonlinearity->set_mu(mu); 
+		m_nonlinearity->apply(w); 
+		
+		Vector w_save(w); 
+		for (int j = 0; j < component; ++j) {
+			const double wdot = B.dot_column(j, w_save); 
+                        auto wj = B.get_column(j);
+			cblas_daxpy(wj->size, -wdot, wj->data, wj->stride, w->data, w->stride);
+		}
+		
+		double norm = sqrt(dot(w, w));
+		if (norm > 0.0) 
+			gsl_vector_scale(w, 1.0/norm); 
+
+		Vector w_help = w_old; 
+		gsl_vector_sub(w_help, w); 
+		
+		cvdebug() << "w-help=" << w_help << "\n"; 
+		delta = sqrt(dot(w_help, w_help));
+
+		cvmsg() << "DEFL["<<iter<<"]: delta = " << delta << "\n"; 
+
+		if (delta < m_epsilon) {
+			if (m_finetune && !is_finetuning) {
+				cvinfo() << "DEFL: start fine tuning\n"; 
+				is_finetuning = true; 
+				maxiter += m_maxFineTune; 
+				mu = 0.01 * m_mu; 
+			}else{
+				converged = true; 
+			}
+		} else if (m_stabilization) {
+			gsl_vector_sub(w_old2, w);
+			double delta2 = sqrt(dot(w_old2, w_old2));
+			if ( (stroke == 0.0) && (delta2 < m_epsilon)) {
+				stroke = mu; 
+				mu *= 0.5; 
+			}else if (stroke != 0.0) {
+				mu = stroke; 
+				stroke = 0.0; 
+			}else if (! loong && 2*iter >  m_maxNumIterations ) {
+				loong = true; 
+				mu *= 0.5; 
+			}
+		}
+		w_old2 = w_old; 
+		w_old = w; 
+		
+		cvdebug() << "w_old=" << w_old << " norm=" << norm << "\n"; 
+		
+		iter++; 
+	}
+	
+	return delta < m_epsilon; 
+}
+
+bool FastICA::fpica_defl(const Matrix& X, Matrix& B)
+{ 
+	// not yet supported 
+	assert(!m_with_initial_guess); 
+		
+	std::random_device rd;
+	std::mt19937 gen(rd());
+	std::uniform_real_distribution<> random_source( -0.5, 0.5 ); 
+
+	Vector w( X.rows(), false); 
+
+	m_nonlinearity->set_signal(&X);
+	
+	bool global_converged = true; 
+	
+	for (int i = 0; i < m_numOfIC; ++i) {
+		
+		// initalize vector (should also go into extra class 
+		for (unsigned i = 0; i < w.size(); ++i) 
+			w[i] = random_source(gen);
+		
+		bool converged = fpica_defl_round(i, w, B); 
+		cvmsg() << "Round(" << i << ")" << (converged ? "converged" : "did not converge") << "\n"; 
+
+		global_converged &= converged; 
+		B.set_column(i, w);
+	}
+
+	return global_converged; 
+}
+
+
+static double min_abs_diag(const Matrix& m)
+{
+	unsigned N = m.rows() > m.cols() ? m.rows() : m.cols(); 
+	double min_val = fabs(m(0,0)); 
+	for (unsigned i = 1; i < N; ++i) {
+		double v = fabs(m(i,i)); 
+		if ( min_val > v) 
+			min_val = v; 
+	}
+	return min_val; 
+}
+
+double FastICA::fpica_symm_step(Matrix& B, Matrix& B_old,double mu, Matrix& workspace)
+{
+	m_nonlinearity->set_mu(mu); 
+	m_nonlinearity->apply(B);
+	matrix_inv_sqrt(B);
+	multiply_mT_m(workspace, B, B_old); 
+	return min_abs_diag(workspace); 
+}
+
+bool FastICA::fpica_symm(const Matrix& X, Matrix& B)
+{
+	// not yet supported 
+	assert(!m_with_initial_guess); 
+
+	std::random_device rd;
+	std::mt19937 gen(rd());
+	std::uniform_real_distribution<> random_source( -0.5, 0.5 ); 
+
+	Matrix B_old2(B);
+	Matrix B_restart(B);
+	
+	// random and orthogonalize 
+	for(auto ib = B.begin(); ib != B.end(); ++ib) 
+		*ib = random_source(gen); 
+
+	matrix_orthogonalize(B); 
+	Matrix B_old(B);
+
+	m_nonlinearity->set_signal(&X);
+	
+	bool is_fine_tuning = false; 
+	double mu = m_mu;
+
+	Matrix BTB(B.cols(), B.rows(), false); 
+
+	bool converged = false; 
+	int iter = 0; 
+	double stroke = 0.0; 
+	bool loong = false; 
+
+	int maxiter = m_maxNumIterations; 
+
+	bool do_saddle_check = m_do_saddle_check; 
+	bool finished = !do_saddle_check; 
+
+	do {
+		while (!converged  && iter < maxiter) {
+
+			double minAbsCos = fpica_symm_step(B, B_old, mu, BTB); 
+			
+			cvdebug() << "B= "  << B << "\n"; 
+
+			cvmsg() << "FastICA: "<<  iter << ":" << 1.0 - minAbsCos << "\n"; 
+			
+			if ( 1.0 - minAbsCos < m_epsilon) {
+				// run one more time with lower step-width
+				if (m_finetune && !is_fine_tuning) {
+					mu *= 0.01;
+					is_fine_tuning = true; 
+					maxiter += m_maxFineTune;
+				} else {
+					converged = true; 
+				}
+			} else if (m_stabilization) {
+				multiply_mT_m(BTB, B, B_old2); 
+				double minAbsCos2 = min_abs_diag(BTB); 
+				
+				// Avoid ping-pong 
+				if (!stroke && (1 - minAbsCos2 < m_epsilon)) {
+					stroke = mu; 
+					mu /= 2.0; 
+				} else if (stroke) { // back to normal 
+					mu = stroke; 
+					stroke = 0; 
+				} else if ( !loong && 2 * iter > m_maxNumIterations) {
+					// already running some time and 
+					// no convergence, try half step width 
+					// once
+					loong = true; 
+					mu *= 0.5; 
+				}
+			}
+			
+			B_old2 = B_old; 
+			B_old = B;
+			
+			++iter; 
+		}
+		if (do_saddle_check) {
+			do_saddle_check = run_saddlecheck(B, X); 
+			m_saddle_postiter = maxiter; 
+			iter = 0; 
+		} else 
+			finished = true;
+		
+	} while (!finished); 
+	
+	return converged; 	
+}
+
+
+/*
+  This is the saddle check as described in 
+ 
+  Petr Tichavský, Zbynek Koldovský, and Erkki Oja
+  "Performance Analysis of the FastICA Algorithm and Cramér–Rao "
+  "Bounds for Linear Independent Component Analysis"
+  IEEE Tran Signal Processing, 54(4), 2006, 1189-1203  
+  
+  Returns true if at least one check resulted in an update of the
+  components.
+  
+*/ 
+bool FastICA::run_saddlecheck(Matrix &B, const Matrix& X)
+{
+	bool result = false; 
+	vector<bool> rotated(B.cols(), false); 
+	Matrix U(B.cols(), X.cols(), false); 
+	multiply_mT_m(U, B, X); 
+	auto table = m_nonlinearity->get_saddle_test_table(U);
+	
+	for (unsigned i = 0; i < U.rows(); ++i) {
+		for (unsigned j = i+1; j < U.rows() && !rotated[i]; ++j) {
+			if (rotated[j]) 
+				continue; 
+			auto ui = U.get_row(i);
+			auto uj = U.get_row(j);
+			const double isqrt2 = 1.0 / sqrt(2.0); 
+			auto ui_new = (ui + uj) * isqrt2; 
+			auto uj_new = (ui - uj) * isqrt2; 
+			
+			auto ui_sir = m_nonlinearity->get_saddle_test_value(ui_new);
+			auto uj_sir = m_nonlinearity->get_saddle_test_value(uj_new);
+			
+			if (fmax(ui_sir, uj_sir) > fmax(table[i], table[j])) {
+				result = rotated[i] = rotated[j] = true;
+				auto bi_new = (B.get_row(i) + B.get_row(j)) * isqrt2; 
+				auto bj_new = (B.get_row(i) - B.get_row(j)) * isqrt2; 
+				B.set_row(i, bi_new); 
+				B.set_row(j, bj_new);
+				cvdebug() << "Rotating components " << i << " and " << j << "\n"; 
+			}
+		}
+	}
+	return result; 
+}; 
+
+void FastICA::set_approach(EApproach apr)
+{
+        m_approach = apr; 
+}
+
+void FastICA::set_nr_of_independent_components (int nrIC)
+{
+        m_numOfIC = nrIC; 
+}
+
+
+void FastICA::set_nonlinearity (PFastICADeflNonlinearity g)
+{
+        assert(g); 
+        m_nonlinearity = g; 
+}
+
+
+void FastICA::set_finetune (bool finetune)
+{
+        m_finetune = finetune; 
+}
+
+void FastICA::set_mu (double mu)
+{
+        m_mu = mu; 
+}
+
+void FastICA::set_epsilon (double epsilon)
+{
+        m_epsilon = epsilon; 
+}
+
+void FastICA::set_sample_size (double sampleSize)
+{
+        m_sampleSize = sampleSize; 
+}
+
+void FastICA::set_component_energy_limit(double limit)
+{
+	m_component_energy_limit = limit; 
+}
+
+void FastICA::set_stabilization (bool stabilization)
+{
+        m_stabilization = stabilization; 
+}
+
+void FastICA::set_max_num_iterations (int maxNumIterations)
+{
+        m_maxNumIterations = maxNumIterations; 
+}
+
+void FastICA::set_max_fine_tune (int maxFineTune)
+{
+        m_maxFineTune = maxFineTune; 
+}
+
+void FastICA::set_pca_only (bool PCAonly)
+{
+        m_PCAonly = PCAonly; 
+}
+
+void FastICA::set_init_guess (const Matrix&  initGuess)
+{
+        m_initGuess = initGuess;
+}
+
+void FastICA::set_saddle_check(bool saddle_check)
+{
+	m_do_saddle_check = saddle_check; 
+}
+
+void FastICA::set_saddle_check_postiterations(int saddle_postiter)
+{
+	m_saddle_postiter = saddle_postiter; 
+}
+	
+int FastICA::get_nr_of_independent_components () const
+{
+        return m_numOfIC; 
+}
+
+const Matrix& FastICA::get_mixing_matrix () const
+{
+        return m_mixing_matrix; 
+}
+
+const Matrix& FastICA::get_separating_matrix () const
+{
+        return m_separating_matrix; 
+}
+
+const Matrix& FastICA::get_independent_components () const
+{
+        return m_independent_components; 
+}
+
+
+const Matrix& FastICA::get_principal_eigenvectors () const
+{
+        return m_principal_eigenvectors; 
+}
+
+const Matrix& FastICA::get_whitening_matrix () const
+{
+        return m_whitening_matrix; 
+}
+
+const Matrix& FastICA::get_dewhitening_matrix () const
+{
+        return m_dewhitening_matrix; 
+}
+
+const Matrix& FastICA::get_white_signal () const
+{
+        return m_white_sig; 
+}
+
+NS_END  
diff --git a/mia/core/fastica.hh b/mia/core/fastica.hh
new file mode 100644
index 0000000..bccf0bc
--- /dev/null
+++ b/mia/core/fastica.hh
@@ -0,0 +1,231 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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_fastica_hh
+#define mia_core_fastica_hh
+
+#include <memory>
+#include <mia/core/gsl_matrix.hh>
+#include <mia/core/fastica_nonlinearity.hh>
+
+namespace mia {
+
+/**
+   This class implements the FastICA blind source separation
+
+   As additional feature the saddle-check [1] can be run to
+   improve the obtained results.
+   
+   [1] Petr Tichavský, Zbynek Koldovský, and Erkki Oja
+   "Performance Analysis of the FastICA Algorithm and Cramér–Rao "
+   "Bounds for Linear Independent Component Analysis"
+   IEEE Tran Signal Processing, 54(4), 2006, 1189-1203  
+
+ */
+
+class EXPORT_CORE FastICA {
+public: 
+
+	/**
+	   Separation approach to be used.  
+	 */
+	enum EApproach {
+		appr_defl, /**< Deflation approach - each component is extimated separately */ 
+		appr_symm  /**< Symmetric approach thet estimates all components at the same time */
+	}; 
+
+
+	/**
+	   Construct the FastICA algorithms with the number of expected components. 
+	   \param num_ic will seperate in at most this number of components 
+	*/
+	FastICA(int num_ic);
+
+	/**
+	   Separate the given signal 
+	   \param mix the mixed signal, each row contains a time step 
+	   \returns true if the method converged 
+	*/
+	bool separate(const gsl::Matrix&  mix); 
+
+	/**
+	   Set the separation approach to be used. 
+	   \param apr appr_delf|appr_symm 
+	*/
+	void set_approach(EApproach apr); 
+	
+	/**
+	   Set the limit of the energy sum used to estimate the number of 
+	   components that make sense based on the PCA 
+	   \param limit energy limit, set >= 1.0 if you want to enforce the number 
+	*/
+	void set_component_energy_limit(double limit); 
+	
+	/**
+	   Set the number of components to be estimated 
+	   \param nrIC (maximum) number of components to be estimated 
+	   
+	 */
+	void set_nr_of_independent_components (int nrIC); 
+	
+	/**
+	   Set the non-linearity to be used for separation 
+	 */
+	void set_nonlinearity (PFastICADeflNonlinearity in_g); 
+	
+	/**
+	   Set if fine tuning is to be applied 
+	 */ 
+	void set_finetune (bool in_finetune); 
+		
+	/**
+	   Set parameter \a mu to run the iteration 
+	 */ 
+ 	void set_mu (double mu); 
+	
+	/**
+	   Iteration breaking condition, i.e. maximum change in mixing vector 
+	*/ 
+ 	void set_epsilon (double epsilon); 
+
+	/**
+	   Sample size to be used (not yet implemented) 
+	 */
+ 	void set_sample_size (double sampleSize);
+
+	/**
+	   Set if stablilization is to be used. 
+	*/
+ 	void set_stabilization (bool in_stabilization);
+
+	/**
+	   Set maximum number of iteration to run
+	 */
+ 	void set_max_num_iterations (int maxNumIterations);
+
+	/**
+	   Set number of additional fine-tune iterations that might be run 
+	*/ 
+ 	void set_max_fine_tune (int maxFineTune);
+
+	/**
+	   Run only PCA (Why is this here, PCA is a aseparate class?) 
+	 */
+	void set_pca_only (bool in_PCAonly);
+ 
+	/**
+	   Set an initial guess (not yet used) 
+	 */
+	void set_init_guess (const gsl::Matrix&  ma_initGuess);
+	
+	/**
+	   Use the saddle check in the symetric method
+	*/
+	void set_saddle_check(bool saddle_check); 
+
+	/**
+	   Number of iterations after a sucessful saddle check 
+	*/
+	void set_saddle_check_postiterations(int saddle_postiter); 
+
+	/// \returns number of estimated independedn components 
+	int  get_nr_of_independent_components () const;
+	
+	
+	const gsl::Matrix& 	get_mixing_matrix () const;
+
+	const gsl::Matrix& 	get_separating_matrix () const;
+
+	const gsl::Matrix&	get_independent_components () const;
+
+
+
+	const gsl::Matrix&	get_whitening_matrix () const;
+
+	const gsl::Matrix&	get_dewhitening_matrix () const;
+	
+	const gsl::Matrix&	get_principal_eigenvectors () const; 
+	
+	const gsl::Matrix&	get_white_signal () const;
+	
+private:
+	// evaluate the whitening and de-whitening matrices 
+	void evaluate_whiten_matrix(const gsl::Matrix& evec, const gsl::Vector& eval); 
+    bool fpica_defl_round(int component, gsl::Vector& w, gsl::Matrix& B);
+	bool fpica_defl(const gsl::Matrix& X, gsl::Matrix& B); 
+	double fpica_symm_step(gsl::Matrix& B, gsl::Matrix& B_old, double mu, gsl::Matrix& Workspace); 
+	bool fpica_symm(const gsl::Matrix& X, gsl::Matrix& B); 
+	bool run_saddlecheck(gsl::Matrix &B, const gsl::Matrix& X); 
+
+	EApproach m_approach; 
+	
+	int m_numOfIC; 
+	
+	PFastICADeflNonlinearity m_nonlinearity; 
+	
+	bool m_finetune; 
+	
+	double m_mu; 
+	
+ 	double m_epsilon; 
+	
+ 	double m_sampleSize;
+	
+ 	bool m_stabilization;
+	
+ 	int m_maxNumIterations;
+	
+ 	int m_maxFineTune;
+	
+ 	int m_firstEig;
+	
+	int m_lastEig;
+	
+	bool m_PCAonly;
+
+	double m_component_energy_limit; 
+	
+	bool m_with_initial_guess; 
+
+	bool m_do_saddle_check; 
+
+	int m_saddle_postiter; 
+		
+	gsl::Matrix m_initGuess;
+	
+	gsl::Matrix m_mixing_matrix;
+	
+	gsl::Matrix m_separating_matrix;
+	
+	gsl::Matrix	m_independent_components;
+	
+	gsl::Matrix	m_whitening_matrix;
+	
+	gsl::Matrix	m_dewhitening_matrix;
+
+    gsl::Matrix	m_principal_eigenvectors;
+
+    gsl::Matrix	m_white_sig;
+	
+};
+
+}
+
+#endif 
diff --git a/mia/mesh/io/CMakeLists.txt b/mia/core/fastica/CMakeLists.txt
similarity index 80%
copy from mia/mesh/io/CMakeLists.txt
copy to mia/core/fastica/CMakeLists.txt
index da7b8f7..3d63350 100644
--- a/mia/mesh/io/CMakeLists.txt
+++ b/mia/core/fastica/CMakeLists.txt
@@ -1,6 +1,6 @@
 #
 # This file is part of MIA - a toolbox for medical image analysis 
-# Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+# Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 #
 # 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,15 +16,6 @@
 # along with this program; if not, see <http://www.gnu.org/licenses/>.
 #
 
+SET(NAMES deflationnonlinearity) 
 
-SET(iomesh
-  off
-  ply
-  stl
-)
-
-PLUGINGROUP_WITH_PREFIX2(
-  "mesh" "io" 
-  "${iomesh}" 
-  "${MIAMESHLIBS}" 
-)
+PLUGINGROUP_WITH_TEST_AND_PREFIX2("fastica" "deflation" "${NAMES}" "${MIACORE}")
diff --git a/mia/core/fastica/deflationnonlinearity.cc b/mia/core/fastica/deflationnonlinearity.cc
new file mode 100644
index 0000000..dac828c
--- /dev/null
+++ b/mia/core/fastica/deflationnonlinearity.cc
@@ -0,0 +1,210 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/fastica/deflationnonlinearity.hh>
+#include <gsl/gsl_blas.h>
+#include <mia/core/gsl_matrix_vector_ops.hh>
+#include <algorithm> 
+
+NS_BEGIN(fastica_deflnonlin)
+
+using namespace std; 
+using namespace mia; 
+
+double CFastICADeflPow3::get_correction_and_scale(gsl::Vector& XTw, gsl::Vector& correction)
+{
+        const double inv_m = get_sample_scale(); 
+	transform(XTw.begin(), XTw.end(), XTw.begin(), [inv_m](double x) -> double {
+			return x*x*x;
+		}); 
+	
+	multiply_m_v(correction, get_signal(), XTw);
+	return 3.0 / inv_m; 
+}
+
+double CFastICADeflPow3::do_get_saddle_test_value(const gsl::Vector& ic) const
+{
+	double result = 0.0; 
+	for (auto v = ic.begin(); v != ic.end(); ++v) {
+		double vv = *v * *v; 
+		result += vv * vv; 
+	}
+	result = result / ic.size() - 3.0; 
+	return result * result; 
+}
+	
+
+CFastICADeflTanh::CFastICADeflTanh(double a):m_a(a)
+{
+}
+
+double CFastICADeflTanh::get_correction_and_scale(gsl::Vector& XTw, gsl::Vector& correction)
+{
+	transform(XTw.begin(), XTw.end(), XTw.begin(), 
+		  [this](double x) { return tanh(m_a * x);}); 
+	
+	multiply_m_v(correction, get_signal(), XTw);
+
+	double scale = 0.0; 
+	for_each(XTw.begin(), XTw.end(), [this, &scale](double x) {
+			scale += 1 - x*x;
+		}); 
+	
+	return m_a * scale; 
+}
+
+double CFastICADeflTanh::do_get_saddle_test_value(const gsl::Vector& ic) const
+{
+	// note that this is only valid for a = 1
+	double result = 0.0; 
+	for (auto v = ic.begin(); v != ic.end(); ++v) {
+		result += log(cosh(*v));
+	}
+	result = result / ic.size() - 0.37457; // = Integral (log(cos(x)) * N(0,1)(x)) 
+	return result * result; 
+}
+
+
+CFastICADeflGauss::CFastICADeflGauss(double a):m_a(a)
+{
+}
+
+double CFastICADeflGauss::get_correction_and_scale(gsl::Vector& XTw, gsl::Vector& correction)
+{
+	transform(XTw.begin(), XTw.end(), m_usquared.begin(), 
+		  [](double x) {return x * x; }); 
+
+	transform(m_usquared.begin(), m_usquared.end(), m_ex.begin(),
+		  [this](double x) { return exp(- m_a * x / 2.0);}); 
+	
+        transform(XTw.begin(), XTw.end(), m_ex.begin(), XTw.begin(),
+			  [](double u, double expu2) {return u * expu2;}); 
+	
+	multiply_m_v(correction, get_signal(), XTw);
+	
+	
+	transform(m_usquared.begin(), m_usquared.end(), m_ex.begin(), m_ex.begin(),
+		  [this](double u2, double expu2) { return (1 - m_a * u2 ) * expu2;});
+	
+	double scale = 0.0; 
+	for_each(m_ex.begin(), m_ex.end(), [this, &scale](double x) {
+			scale += x;
+		}); 
+	return scale; 
+}
+
+double CFastICADeflGauss::do_get_saddle_test_value(const gsl::Vector& ic) const
+{
+	// note that this is only valid for a = 1
+	double result = 0.0; 
+	for (auto v = ic.begin(); v != ic.end(); ++v) {
+		result += exp( - *v * *v / 2.0 );
+	}
+	result = result / ic.size() - 1.0 / sqrt(2.0);
+	return result * result; 
+}
+	
+
+void CFastICADeflGauss::post_set_signal()
+{
+        m_usquared = gsl::Vector(get_signal().cols(), false); 
+	m_ex = gsl::Vector(get_signal().cols(), false); 
+	CFastICADeflNonlinearity::post_set_signal();
+}
+
+
+
+CFastICADeflPow3Plugin::CFastICADeflPow3Plugin():
+	CFastICADeflNonlinearityPlugin("pow3")
+{
+}
+
+CFastICADeflNonlinearity *CFastICADeflPow3Plugin::do_create() const
+{
+       return new CFastICADeflPow3(); 
+}
+
+const std::string CFastICADeflPow3Plugin::do_get_descr()const
+{
+	return "Implementation of the simple pow3 non-linearity for the deflation "
+		"based FastICA algorithm. It's use is justified on statistical grounds "
+		"only for estimating sub-Gaussian independent components without outliers."; 
+}
+
+CFastICADeflTanhPlugin::CFastICADeflTanhPlugin():
+	CFastICADeflNonlinearityPlugin("tanh"), 
+	m_a(1.0)
+{
+	this->add_parameter("a", 
+                new CDBoundedParameter(m_a, EParameterBounds::bf_closed_interval, { 1, 2},
+						 false, "Tuning parameter")); 
+	
+}
+
+CFastICADeflNonlinearity *CFastICADeflTanhPlugin::do_create() const
+{
+	return new CFastICADeflTanh(m_a); 
+}
+
+const std::string CFastICADeflTanhPlugin::do_get_descr()const
+{
+	return "Implementation of the 'log cosh' non-linearity "
+		"for the deflation based FastICA algorithm. This is a good general "
+		"purpouse contrast function.";
+}
+
+
+
+CFastICADeflGaussPlugin::CFastICADeflGaussPlugin():
+	CFastICADeflNonlinearityPlugin("gauss"), 
+	m_a(1.0)
+{
+	this->add_parameter("a", 
+                new CDBoundedParameter(m_a, EParameterBounds::bf_min_open, {0},
+						 false, 
+						 "Tuning parameter: a in (0,2) for super-Gaussian"
+						 "density, a > 2 for sub-Gaussian density. "
+						 "a~1 is usually a good choice.")); 
+}
+
+CFastICADeflNonlinearity *CFastICADeflGaussPlugin::do_create() const
+{
+	return new CFastICADeflGauss(m_a); 
+}
+
+const std::string CFastICADeflGaussPlugin::do_get_descr()const
+{
+	return "Implementation of the Gauss non-linearity for the deflation based "
+		"FastICA algorithm. Use it when the independend components are highly "
+		"super-Gaussian or robustness is very important."; 
+}
+
+
+extern "C" EXPORT CPluginBase *get_plugin_interface()
+{
+	auto result = new CFastICADeflGaussPlugin(); 
+	result->append_interface(new CFastICADeflTanhPlugin()); 
+	result->append_interface(new CFastICADeflPow3Plugin()); 
+	return result;
+}
+
+
+NS_END
diff --git a/mia/core/fastica/deflationnonlinearity.hh b/mia/core/fastica/deflationnonlinearity.hh
new file mode 100644
index 0000000..0a64023
--- /dev/null
+++ b/mia/core/fastica/deflationnonlinearity.hh
@@ -0,0 +1,92 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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_fastica_deflationnonlinearity_hh
+#define mia_core_fastica_deflationnonlinearity_hh
+
+#include <mia/core/fastica_nonlinearity.hh>
+
+NS_BEGIN(fastica_deflnonlin)
+
+class CFastICADeflPow3 : public mia::CFastICADeflNonlinearity {
+	virtual double get_correction_and_scale(gsl::Vector& XTw, gsl::Vector& correction); 
+	virtual double do_get_saddle_test_value(const gsl::Vector& ic) const; 
+}; 
+
+class CFastICADeflTanh : public mia::CFastICADeflNonlinearity {
+public: 
+        CFastICADeflTanh(double a); 
+private: 
+	virtual double get_correction_and_scale(gsl::Vector& XTw, gsl::Vector& correction); 
+	virtual double do_get_saddle_test_value(const gsl::Vector& ic) const;
+        double m_a; 
+}; 
+
+class CFastICADeflGauss : public mia::CFastICADeflNonlinearity {
+public: 
+        CFastICADeflGauss(double a); 
+private: 
+
+	virtual void post_set_signal();
+	virtual double get_correction_and_scale(gsl::Vector& XTw, gsl::Vector& correction); 
+	virtual double do_get_saddle_test_value(const gsl::Vector& ic) const;
+        gsl::Vector m_usquared;
+	gsl::Vector m_ex; 
+        double m_a; 
+}; 
+
+class CFastICADeflPow3Plugin: public mia::CFastICADeflNonlinearityPlugin {
+public: 
+        CFastICADeflPow3Plugin(); 
+        
+        virtual mia::CFastICADeflNonlinearity *do_create() const;
+        
+	virtual const std::string do_get_descr()const;
+
+}; 
+
+
+class CFastICADeflTanhPlugin: public mia::CFastICADeflNonlinearityPlugin {
+public: 
+        CFastICADeflTanhPlugin(); 
+private: 
+        virtual mia::CFastICADeflNonlinearity *do_create() const;
+        
+	virtual const std::string do_get_descr()const;
+        double m_a; 
+
+}; 
+
+class CFastICADeflGaussPlugin: public mia::CFastICADeflNonlinearityPlugin {
+public: 
+        CFastICADeflGaussPlugin(); 
+private:         
+        virtual mia::CFastICADeflNonlinearity *do_create() const;
+        
+	virtual const std::string do_get_descr()const;
+        double m_a; 
+
+}; 
+
+NS_END
+
+#endif 
+
+
diff --git a/mia/core/fastica/test_deflationnonlinearity.cc b/mia/core/fastica/test_deflationnonlinearity.cc
new file mode 100644
index 0000000..944d285
--- /dev/null
+++ b/mia/core/fastica/test_deflationnonlinearity.cc
@@ -0,0 +1,284 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/fastica/deflationnonlinearity.hh>
+
+using namespace fastica_deflnonlin; 
+using namespace mia; 
+using namespace gsl; 
+using namespace std; 
+
+struct DeflationNonlinearityFixture {
+
+	DeflationNonlinearityFixture(); 
+	Matrix signal;
+	Vector w;
+
+}; 
+
+struct NonlinearitySaddlevalueFixture {
+
+	NonlinearitySaddlevalueFixture(); 
+	Vector u;
+}; 
+
+struct NonlinearitySaddleMatrixFixture {
+
+	NonlinearitySaddleMatrixFixture(); 
+	Matrix U;
+}; 
+
+
+BOOST_FIXTURE_TEST_CASE( test_pow3_nonlinearity, DeflationNonlinearityFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflPow3Plugin>("pow3");
+	
+	plugin->set_signal(&signal);
+	plugin->apply(w); 
+	
+	BOOST_CHECK_CLOSE(w[0],  0.67748, 0.01); 
+	BOOST_CHECK_CLOSE(w[1], -0.48505, 0.01); 
+	BOOST_CHECK_CLOSE(w[2], -1.35082, 0.01); 
+	BOOST_CHECK_CLOSE(w[3], -0.35110, 0.01); 
+	
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_pow3_SIR,  NonlinearitySaddlevalueFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflPow3Plugin>("pow3");
+	BOOST_CHECK_CLOSE(plugin->get_saddle_test_value(u), 8.9148, 0.1); 
+	
+}
+
+BOOST_FIXTURE_TEST_CASE( test_pow3_SIR_Matrix,  NonlinearitySaddleMatrixFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflPow3Plugin>("pow3");
+	auto values = plugin->get_saddle_test_table(U); 
+	BOOST_CHECK_CLOSE(values[0], 8.9148, 0.1); 
+	BOOST_CHECK_CLOSE(values[1], 8.1902, 0.1); 
+	
+}
+
+
+
+BOOST_FIXTURE_TEST_CASE( test_pow3_nonlinearity_stabelized, DeflationNonlinearityFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflPow3Plugin>("pow3");
+	
+	plugin->set_signal(&signal);
+	plugin->set_mu(0.1); 
+	plugin->apply(w); 
+	 
+	BOOST_CHECK_CLOSE(w[0], -0.22633, 0.01); 
+	BOOST_CHECK_CLOSE(w[1], 0.16169, 0.01); 
+	BOOST_CHECK_CLOSE(w[2], 0.45097, 0.01); 
+	BOOST_CHECK_CLOSE(w[3], 0.11686, 0.01); 
+	
+}
+
+BOOST_FIXTURE_TEST_CASE( test_tanh_nonlinearity, DeflationNonlinearityFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflTanhPlugin>("tanh:a=1.5");
+		
+	plugin->set_signal(&signal);
+	plugin->apply(w); 
+	 
+	BOOST_CHECK_CLOSE(w[0],  0.26363, 0.01); 
+	BOOST_CHECK_CLOSE(w[1], -0.22528, 0.01); 
+	BOOST_CHECK_CLOSE(w[2], -0.57095, 0.01); 
+	BOOST_CHECK_CLOSE(w[3], -0.17719, 0.01); 
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_tanh_1_SIR,  NonlinearitySaddlevalueFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflTanhPlugin>("tanh");
+	BOOST_CHECK_CLOSE(plugin->get_saddle_test_value(u), 0.11077, 0.1); 
+}
+
+BOOST_FIXTURE_TEST_CASE( test_tanh_SIR_Matrix,  NonlinearitySaddleMatrixFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflTanhPlugin>("tanh");
+	auto values = plugin->get_saddle_test_table(U); 
+	BOOST_CHECK_CLOSE(values[0], 0.11077, 0.1); 
+	BOOST_CHECK_CLOSE(values[1], 0.070633, 0.1); 
+	
+}
+
+
+
+BOOST_FIXTURE_TEST_CASE( test_tanh_nonlinearity_stabelized, DeflationNonlinearityFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflTanhPlugin>("tanh:a=1.5");
+		
+	plugin->set_signal(&signal);
+	plugin->set_mu(0.1); 
+	plugin->apply(w); 
+
+	BOOST_CHECK_CLOSE(w[0], -0.22299, 0.01); 
+	BOOST_CHECK_CLOSE(w[1], 0.16196, 0.01); 
+	BOOST_CHECK_CLOSE(w[2], 0.44761, 0.01); 
+	BOOST_CHECK_CLOSE(w[3], 0.11809, 0.01); 
+	
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_gauss_nonlinearity, DeflationNonlinearityFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflGaussPlugin>("gauss:a=1.1");
+	
+	plugin->set_signal(&signal);
+	plugin->apply(w); 
+	   
+	BOOST_CHECK_CLOSE(w[0],  0.17860, 0.01); 
+	BOOST_CHECK_CLOSE(w[1], -0.15242, 0.01); 
+	BOOST_CHECK_CLOSE(w[2], -0.38649, 0.01); 
+	BOOST_CHECK_CLOSE(w[3], -0.11984, 0.01); 
+	
+}
+
+BOOST_FIXTURE_TEST_CASE( test_gauss_SIR_matrix,  NonlinearitySaddleMatrixFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflGaussPlugin>("gauss");
+
+	auto values = plugin->get_saddle_test_table(U); 
+	BOOST_CHECK_CLOSE(values[0], 0.063381, 0.1); 
+	BOOST_CHECK_CLOSE(values[1], 0.036016, 0.1); 
+	
+}
+
+BOOST_FIXTURE_TEST_CASE( test_gauss_SIR,  NonlinearitySaddlevalueFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflGaussPlugin>("gauss");
+	BOOST_CHECK_CLOSE(plugin->get_saddle_test_value(u), 0.063381, 0.1); 
+	
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_gauss_nonlinearity_stabilized, DeflationNonlinearityFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflGaussPlugin>("gauss:a=1.1");
+	
+	plugin->set_signal(&signal);
+	plugin->set_mu(0.1); 
+	plugin->apply(w); 
+	 
+	BOOST_CHECK_CLOSE(w[0],  -0.22302, 0.01); 
+	BOOST_CHECK_CLOSE(w[1],  0.16196, 0.01); 
+	BOOST_CHECK_CLOSE(w[2],  0.44763, 0.01); 
+	BOOST_CHECK_CLOSE(w[3],  0.11809, 0.01); 
+
+}
+
+const double init_signal[] = {
+	-0.150788,  0.185673,  0.253528, -0.192714,  0.309594,  0.384079,  0.117799,  0.200267, -0.212151, -0.257026,
+	0.221388, -0.166861,  0.128731, -0.207766, -0.041186, -0.089463, -0.151564,  0.249002, -0.060958,  0.223747,
+	0.170328, -0.071203, -0.435380,  0.093816, -0.206290, -0.408690, -0.212328, -0.211139,  0.499941, -0.015164,
+	-0.240928,  0.052391,  0.053121,  0.306664, -0.062118,  0.114074,  0.246093, -0.238130, -0.226832,  0.048444
+};
+
+DeflationNonlinearityFixture::DeflationNonlinearityFixture()
+{
+	double init_w[] = { -0.22638, 0.16168, 0.45102, 0.11684}; 
+
+	signal = Matrix(4, 10, init_signal); 
+	w = Vector(4, false); 
+	std::copy(init_w, init_w + 4, w.begin()); 
+
+
+}
+
+struct SymmetryNonlinearityFixture {
+
+	SymmetryNonlinearityFixture(); 
+	Matrix signal;
+	Matrix W;
+
+}; 
+
+
+BOOST_FIXTURE_TEST_CASE( test_pow_nonlinearity_stabilized_Symm, SymmetryNonlinearityFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflPow3Plugin>("pow3");
+	
+	plugin->set_signal(&signal);
+	plugin->apply(W); 
+	 
+	BOOST_CHECK_CLOSE(W(0,0), 1.24114, 0.01); 
+	BOOST_CHECK_CLOSE(W(0,1), -2.34633, 0.01); 
+	BOOST_CHECK_CLOSE(W(1,0), -0.89385, 0.01); 
+	BOOST_CHECK_CLOSE(W(1,1), -1.22523, 0.01); 
+	BOOST_CHECK_CLOSE(W(2,0), -2.47949, 0.01); 
+	BOOST_CHECK_CLOSE(W(2,1), -0.39022, 0.01); 
+	BOOST_CHECK_CLOSE(W(3,0), -0.64952, 0.01); 
+	BOOST_CHECK_CLOSE(W(3,1), -1.35443, 0.01); 
+
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_tanh_nonlinearity_Symm, SymmetryNonlinearityFixture ) 
+{
+	auto plugin = BOOST_TEST_create_from_plugin<CFastICADeflTanhPlugin>("tanh:a=1.5");
+	
+	plugin->set_signal(&signal);
+	plugin->apply(W); 
+	    
+	BOOST_CHECK_CLOSE(W(0,0), 0.42007, 0.01); 
+	BOOST_CHECK_CLOSE(W(0,1), -1.05476, 0.01); 
+	BOOST_CHECK_CLOSE(W(1,0),  -0.36337, 0.01); 
+	BOOST_CHECK_CLOSE(W(1,1), -0.58123, 0.01); 
+	BOOST_CHECK_CLOSE(W(2,0), -0.91679, 0.01); 
+	BOOST_CHECK_CLOSE(W(2,1), -0.24641, 0.01); 
+	BOOST_CHECK_CLOSE(W(3,0),  -0.28688, 0.01); 
+	BOOST_CHECK_CLOSE(W(3,1), -0.62782, 0.01); 
+
+}
+
+
+
+SymmetryNonlinearityFixture::SymmetryNonlinearityFixture()
+{
+	double init_W[] = { -0.41718, 0.78261, 
+			     0.29795, 0.40841,    
+			     0.83116, 0.12941,   
+			     0.21532, 0.45165}; 
+
+	signal = Matrix(4, 10, init_signal); 
+	W = Matrix(4, 2, init_W);
+}
+
+NonlinearitySaddlevalueFixture::NonlinearitySaddlevalueFixture():
+	u(7,false)
+{
+	double init_u[] = { .1, .2, .3, .4, .5, .1, .2 }; 
+	copy(init_u, init_u +7, u.begin()); 
+
+}
+
+
+NonlinearitySaddleMatrixFixture::NonlinearitySaddleMatrixFixture()
+{
+	double init_U[] = { .1, .2, .3, .4, .5, .1, .2, 
+			    .3, .1, .5, .7, .1, .9, .0
+	}; 
+	U = Matrix(2, 7, init_U); 
+}
diff --git a/mia/core/fastica_nonlinearity.cc b/mia/core/fastica_nonlinearity.cc
new file mode 100644
index 0000000..ad195b4
--- /dev/null
+++ b/mia/core/fastica_nonlinearity.cc
@@ -0,0 +1,150 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/fastica_nonlinearity.hh>
+#include <mia/core/gsl_matrix_vector_ops.hh>
+#include <mia/core/export_handler.hh>
+#include <mia/core/plugin_base.cxx>
+#include <mia/core/handler.cxx>
+#include <algorithm>
+
+namespace mia {
+
+using std::transform; 
+using std::vector; 
+using namespace gsl; 
+using std::ostream_iterator; 
+
+CFastICANonlinearityBase::CFastICANonlinearityBase():
+	m_mu(1.0),
+	m_sample_scale(1.0), 
+        m_signal(nullptr)
+{
+}
+
+void CFastICANonlinearityBase::set_signal(const Matrix *signal)
+{
+	m_signal = signal; 
+	assert(m_signal); 
+	m_sample_scale = 1.0 / m_signal->cols(); 
+	
+	post_set_signal(); 
+}
+
+void CFastICANonlinearityBase::set_mu(double mu)
+{
+	m_mu = mu; 
+}
+
+
+
+const Matrix& CFastICANonlinearityBase::get_signal() const
+{
+	assert(m_signal); 
+	return *m_signal; 
+}
+
+void CFastICADeflNonlinearity::post_set_signal()
+{
+	m_workspace = Vector(get_signal().rows(), false); 
+	m_XTw = Vector(get_signal().cols(), false); 
+}
+
+const char *CFastICANonlinearityBase::data_descr = "fastica"; 
+const char *CFastICADeflNonlinearity::type_descr = "deflation"; 
+
+
+void CFastICADeflNonlinearity::apply(gsl::Vector& w)
+{
+	multiply_v_m(m_XTw, w, get_signal());
+	const double scale = get_correction_and_scale(m_XTw, m_workspace); 
+
+	if (get_mu() >= 1.0) 
+		sum_final(w, scale);  
+	else 
+		sum_final_stabelized(w, scale); 
+}
+
+void CFastICADeflNonlinearity::apply(gsl::Matrix& W)
+{
+	for (unsigned c = 0; c < W.cols(); ++c) {
+		auto wc = gsl_matrix_column(W, c); 
+		gsl::Vector w(&wc.vector); 
+		
+		multiply_v_m(m_XTw, w, get_signal());
+		const double scale = get_correction_and_scale(m_XTw, m_workspace); 
+
+		if (get_mu() >= 1.0) 
+			sum_final(w, scale);  
+		else 
+			sum_final_stabelized(w, scale); 
+	}
+}
+
+vector<double> CFastICADeflNonlinearity::get_saddle_test_table(const gsl::Matrix& ics) const
+{
+	vector<double> result(ics.rows()); 
+	for (unsigned i = 0; i < ics.rows(); ++i) {
+		auto row = ics.get_row(i); 
+		result[i] = do_get_saddle_test_value(row);
+	}
+	return result; 
+}
+
+double CFastICADeflNonlinearity::get_saddle_test_value(const gsl::Vector& ic) const
+{
+	return do_get_saddle_test_value(ic); 
+}
+
+
+void CFastICADeflNonlinearity::sum_final(gsl::Vector& w, double scale)
+{
+	const double inv_m = get_sample_scale(); 
+
+	transform(m_workspace.begin(), m_workspace.end(), w.begin(), w.begin(), 
+		  [scale, inv_m](double x, double y) { return (x - scale * y) * inv_m;}); 
+
+}
+
+void CFastICADeflNonlinearity::sum_final_stabelized(gsl::Vector& w, double scale)
+{
+	const double beta = dot(w, m_workspace); 
+	const double a2 = get_mu() / (scale - beta); 
+	const double a1 = 1 + beta * a2; 
+
+	transform(m_workspace.begin(), m_workspace.end(), w.begin(), w.begin(), 
+		  [a1, a2](double x, double y){return a1 * y - a2 * x;}); 
+
+}
+
+template<>  const char * const 
+TPluginHandler<TFactory<CFastICADeflNonlinearity>>::m_help = 
+	"These plug-ins provide various non-linearity models for the FastICA algorithm "
+        "that uses deflation.";
+
+EXPORT_CORE PFastICADeflNonlinearity produce_fastica_nonlinearity(const std::string& descr)
+{
+	return CFastICADeflNonlinearityPluginHandler::instance().produce(descr);
+}
+
+EXPLICIT_INSTANCE_HANDLER(CFastICADeflNonlinearity); 
+
+
+}// end namespace 
diff --git a/mia/core/fastica_nonlinearity.hh b/mia/core/fastica_nonlinearity.hh
new file mode 100644
index 0000000..4c332df
--- /dev/null
+++ b/mia/core/fastica_nonlinearity.hh
@@ -0,0 +1,125 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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_fastica_nonlinearity_hh
+#define mia_core_fastica_nonlinearity_hh
+
+#include <mia/core/gsl_vector.hh>
+#include <mia/core/gsl_matrix.hh>
+
+#include <mia/core/factory.hh>
+namespace mia {
+
+
+class EXPORT_CORE CFastICANonlinearityBase : public CProductBase {
+public: 
+
+	/// helper typedef for plugin handling 
+	typedef CFastICANonlinearityBase plugin_data; 
+
+	static const char *data_descr; 
+
+	CFastICANonlinearityBase(); 
+
+        void set_signal(const gsl::Matrix *signal); 
+        void set_mu(double m); 
+
+protected: 
+        double get_sample_scale() const {return m_sample_scale;}
+	double get_mu() const { return m_mu;}; 
+        const gsl::Matrix& get_signal() const; 
+
+private: 
+        virtual void post_set_signal() = 0;
+	double m_mu;
+	double m_sample_scale;
+        const gsl::Matrix *m_signal; 
+}; 
+
+/**
+   \brief This is the base clase for non-linearities used in deflation based ICA
+   
+   This class defines the interface of the nonlinearity g for deflation based FastICA. In order to 
+   implement the a real non-linearity the method get_correction_and_scale must be overwritten. 
+   
+   If the factor \f$\mu\f$ defined in the parent class is \f$\ge 1.0\f$, than the normal implementation 
+   will be used, if the value is positive but \f$\le 1.0\f$ then the stabelized variant of the algorithm 
+   is used. 
+   
+*/
+
+class EXPORT_CORE CFastICADeflNonlinearity : public CFastICANonlinearityBase {
+public: 
+
+	/// helper typedef for plugin handling 
+	typedef CFastICADeflNonlinearity plugin_type; 
+
+	static const char *type_descr; 
+
+
+        void apply(gsl::Vector& w); 
+	void apply(gsl::Matrix& W);
+
+	std::vector<double> get_saddle_test_table(const gsl::Matrix& ics) const;  
+	double get_saddle_test_value(const gsl::Vector& ic) const;
+
+protected: 
+	virtual void post_set_signal();
+private: 
+	/**
+	   Key worker function of the class that needs to be overwritten. Given the signal X and the 
+	   input vector \a w passed to \a apply the parameters are to interpreted as follows: 
+	   \param XTw the vector resulting from the multiplication of $X^T w$. This vector will be overwritten. 
+	   \param correction [in,out] a vector of the same size like \a w. On output it must contain the 
+	   correction $X g(X^T w)$
+	 */
+
+	virtual double get_correction_and_scale(gsl::Vector& XTw, gsl::Vector& correction) = 0; 
+	
+	/**
+	   This function evaluates the SIR quantity needed for the saddle test
+	   \param ic independet component to evaluate the SIR from 
+	 */
+	virtual double do_get_saddle_test_value(const gsl::Vector& ic) const = 0;
+	void sum_final(gsl::Vector& w, double scale); 
+	void sum_final_stabelized(gsl::Vector& w, double scale); 
+
+        gsl::Vector m_XTw;
+        gsl::Vector m_workspace; 
+}; 
+
+
+typedef std::shared_ptr<CFastICADeflNonlinearity> PFastICADeflNonlinearity; 
+
+
+EXPORT_CORE PFastICADeflNonlinearity produce_fastica_nonlinearity(const std::string& descr); 
+
+
+typedef TFactory<CFastICADeflNonlinearity> CFastICADeflNonlinearityPlugin; 
+
+/**
+   \ingroup interpol 
+   Plugin handler for the creation of deflation FastICA nonlinearities 
+*/
+typedef THandlerSingleton<TFactoryPluginHandler<CFastICADeflNonlinearityPlugin> > CFastICADeflNonlinearityPluginHandler;
+
+}
+
+#endif 
diff --git a/mia/core/fft1d_r2c.cc b/mia/core/fft1d_r2c.cc
index 685f6c5..1a72c45 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 00570ec..4538d6e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3fceb40..84a19e7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b169e05..f7f0085 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 207a2a4..3b9e24f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 155ee41..9aa21e3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8cab476..1b5af86 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/core/file.hh
index 046d674..969c02f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 17d8b84..aae1e3b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,70 +47,9 @@ namespace bfs = ::boost::filesystem;
 #define MAX_PATH 4096
 #endif
 
-
-CPathNameArray find_files(const CPathNameArray& searchpath, const std::string& pattern)
-{
-	boost::regex pat_expr(pattern);
-	CPathNameArray result; 
-
-	// search through all the path to find the plugins
-	for (auto dir = searchpath.begin(); dir != searchpath.end(); ++dir){
-
-		cvdebug() << "Looking for " << dir->string() << "\n"; 
-
-		if (bfs::exists(*dir) && bfs::is_directory(*dir)) {
-			// if we cant save the old directory something is terribly wrong
-			bfs::directory_iterator di(*dir); 
-			bfs::directory_iterator dend;
-			
-			cvdebug() << "TPluginHandler<I>::initialise: scan '"<<dir->string() <<"'\n"; 
-
-			while (di != dend) {
-				cvdebug() << "    candidate:'" << di->path().string() << "'"; 
-				if (boost::regex_match(di->path().string(), pat_expr)) {
-					result.push_back(*di); 
-					cverb << " add\n";
-				}else
-					cverb << " discard\n";
-				++di; 
-			}
-		}
-	}
-	return result; 
-}
-
-EXPORT_CORE vector<string> get_consecutive_numbered_files_from_pattern(string const& in_filename, int start, int end)
-{
-	char buffer[MAX_PATH];
-	int num = start;
-	vector<string> result;
-
-	snprintf(buffer, MAX_PATH, in_filename.c_str(), num);
-	string first_filename(buffer);
-
-	while (!bfs::exists(buffer) && num < end) {
-		++num;
-		snprintf(buffer, MAX_PATH, in_filename.c_str(), num);
-		// no file found
-		if (first_filename == string(buffer))
-			return result;
-	}
-
-
-
-	while (bfs::exists(buffer) && num < end) {
-		result.push_back(string(buffer));
-		++num;
-		snprintf(buffer, MAX_PATH, in_filename.c_str(), num);
-
-		// run through all possible file names
-		if (first_filename == string(buffer))
-			break;
-	}
-	return result;
-}
-
-EXPORT_CORE const std::string get_filename_pattern_and_range(std::string const& in_filename, size_t& start_filenum, size_t& end_filenum, size_t& format_width)
+EXPORT_CORE const std::string get_filename_pattern_and_range(std::string const& in_filename,
+							     size_t& start_filenum,
+							     size_t& end_filenum, size_t& format_width)
 {
 	string base_name;
 	size_t nwidth = format_width = fname_to_cformat(in_filename.c_str(), base_name, false);
@@ -232,22 +171,6 @@ EXPORT_CORE size_t fname_to_cformat(const char *fname, string& base, bool wildca
 	return nwidth;
 }
 
-EXPORT_CORE void split_dir_fname(const char *in_name, std::string& dir, std::string& fname)
-{
-	char *help = strdup(in_name);
-	char *filename = strrchr(help, '/');
-
-	if (filename) {
-		*filename = 0;
-		++filename;
-		dir.assign(help);
-		fname.assign(filename);
-	}else {
-		dir.assign("./");
-		fname.assign(help);
-	}
-	free(help);
-}
 
 // ugly
 EXPORT_CORE string create_filename(const char *cformat, size_t num)
diff --git a/mia/core/filetools.hh b/mia/core/filetools.hh
index baf6a0b..ff209f8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,11 +34,6 @@ class path;
 
 NS_MIA_BEGIN
 
-
-typedef std::vector<boost::filesystem::path> CPathNameArray; 
-
-CPathNameArray find_files(const CPathNameArray& searchpath, const std::string& pattern); 
-
 /**
    \ingroup misc
 
@@ -68,18 +63,6 @@ EXPORT_CORE const std::string get_filename_pattern_and_range(std::string const&
 /**
    \ingroup misc
 
-   Based on an input pattern obtain a vector of file names that follow the same numbering pattern and
-   are all numberd consecutive and are within the given range.
-   \param in_filename a file name pattern, e.g. file0000.png
-   \param start minimum file number
-   \param end maximum file number
-   \returns a vector of filenames that follow above pattern
-*/
-EXPORT_CORE std::vector<std::string> get_consecutive_numbered_files_from_pattern(std::string const& in_filename, int start, int end);
-
-/**
-   \ingroup misc
-
    split a filename with a number part into a c-format string or a wildcard string
    \param fname input file name
    \param[out] base the resulting format string
@@ -89,15 +72,6 @@ EXPORT_CORE std::vector<std::string> get_consecutive_numbered_files_from_pattern
 */
 EXPORT_CORE size_t fname_to_cformat(const char *fname, std::string& base, bool wildcard);
 
-/**
-   \ingroup misc
-
-   split a file name into directory and file
-   \remark obsolate - use BOOST functions
-*/
-
-EXPORT_CORE void split_dir_fname(const char *in_name, std::string& dir, std::string& sname);
-
 
 /**
    \ingroup misc
diff --git a/mia/core/filter.cc b/mia/core/filter.cc
index ea5115a..60920e4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,5 +25,4 @@ NS_MIA_BEGIN
 const char *combiner_type::type_descr = "combiner";
 const char *filter_type::type_descr = "filter";
 
-
 NS_MIA_END
diff --git a/mia/core/filter.hh b/mia/core/filter.hh
index 58fa01d..4708107 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +110,18 @@ public:
 	 */ 
 	result_type filter(std::shared_ptr<D> pimage) const;
 
+
+	/**
+	   proved a pixel type conversion prediction based on the given input pixel type set. 
+	   \param in_types the pixel types that are fed into the pipeline 
+	   \returns the possible pixel types after running the pipeline
+	 */
+	std::set<EPixelType> test_pixeltype_conversion(const std::set<EPixelType>& in_types) const; 
 private:
 	virtual result_type do_filter(const Image& image) const = 0;
 	virtual result_type do_filter(std::shared_ptr<D> image) const;
+	
+	virtual std::set<EPixelType> do_test_pixeltype_conversion(const std::set<EPixelType>& in_type) const; 
 
 };
 
@@ -125,6 +134,7 @@ public:
 	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); 
@@ -137,6 +147,16 @@ private:
 		}
 		return result; 
 	}
+
+	std::set<EPixelType> do_test_pixeltype_conversion(const std::set<EPixelType>& in_type) const
+	{
+		std::set<EPixelType> result = in_type;
+		for(auto f: m_chain) {
+			result = f->test_pixeltype_conversion(result); 
+		}
+		return result; 
+	}
+	
 	std::vector<Pointer> m_chain; 
 }; 
 
@@ -641,6 +661,22 @@ TDataFilter<D>::do_filter(std::shared_ptr<D> pimage) const
 	return do_filter(*pimage); 
 }
 
+
+template <class D>
+std::set<EPixelType>
+TDataFilter<D>::test_pixeltype_conversion(const std::set<EPixelType>& in_types) const
+{
+	return do_test_pixeltype_conversion(in_types); 
+}
+
+template <class D>
+std::set<EPixelType>
+TDataFilter<D>::do_test_pixeltype_conversion(const std::set<EPixelType>& in_types) const
+{
+	return in_types; 
+}
+
+
 NS_MIA_END
 
 #endif
diff --git a/mia/core/fixedwidthoutput.cc b/mia/core/fixedwidthoutput.cc
index d6a3a7b..e8c152a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8137262..375931d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/flags.hh b/mia/core/flags.hh
index 0e283f8..89e203d 100644
--- a/mia/core/flags.hh
+++ b/mia/core/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@
 
 NS_MIA_BEGIN 
 
+
 /**
    This macro implements operations on a strongly typed enum 
    that is used as a flag. We use a macro since we don't want to 
diff --git a/mia/core/flagstring.cc b/mia/core/flagstring.cc
index 34923d6..0446903 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e261e50..1d2c46a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 82d7913..be1b74c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c9ccc56..3fd872c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/mia/core/gsl_defines.hh
similarity index 95%
rename from gsl++/gsldefines.hh
rename to mia/core/gsl_defines.hh
index 03f7c51..a392126 100644
--- a/gsl++/gsldefines.hh
+++ b/mia/core/gsl_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/gsl_iterator.hh b/mia/core/gsl_iterator.hh
new file mode 100644
index 0000000..cf013e8
--- /dev/null
+++ b/mia/core/gsl_iterator.hh
@@ -0,0 +1,312 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 gslpp_iterator_hh
+#define gslpp_iterator_hh
+
+#include <cassert>
+#include <iterator>
+#include <iostream>
+
+namespace gsl {
+
+class vector_iterator {
+public:  
+	typedef double value_type; 
+	typedef double* pointer;
+	typedef double& reference; 
+	typedef size_t difference_type; 
+
+	vector_iterator(double *base, int stride): m_current(base), m_stride(stride){}
+	
+	vector_iterator(const vector_iterator& other) = default;  
+	
+	vector_iterator():m_current(nullptr), m_stride(0){}
+	
+	double& operator *() {
+		return *m_current;
+	}; 
+	
+	double* operator ->() {
+		return  m_current;
+	}; 
+
+	vector_iterator& operator ++() {
+		m_current += m_stride;
+		return *this; 
+	}; 
+	
+	vector_iterator operator ++(int){
+		vector_iterator result(*this); 
+		++(*this);
+		return result; 
+	}
+
+
+	vector_iterator& operator --() {
+		m_current -= m_stride;
+		return *this; 
+	}; 
+	
+	vector_iterator operator --(int){
+		vector_iterator result(*this); 
+		--(*this); 
+		return result; 
+	}
+	
+	vector_iterator& operator += (int dist) {
+		m_current += dist * m_stride; 
+		return *this; 
+	}
+
+	vector_iterator& operator -= (int dist) {
+		m_current -= dist * m_stride; 
+		return *this; 
+	}
+
+	double& operator[] (int idx) {
+		return m_current[idx * m_stride]; 
+	}
+	
+	difference_type operator - (const vector_iterator& other) {
+		assert(m_stride == other.m_stride); 
+		return (m_current - other.m_current) / m_stride;  
+	}
+	
+	bool operator == (const vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current == other.m_current; 
+	}
+
+	bool operator != (const vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current != other.m_current; 
+	}
+
+	bool operator < (const vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current < other.m_current; 
+	}
+
+	bool operator <= (const vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current <= other.m_current; 
+	}
+
+	bool operator > (const vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current > other.m_current; 
+	}
+	
+	bool operator >= (const vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current >= other.m_current; 
+	}
+
+private: 
+	friend class const_vector_iterator; 
+	double* m_current;
+	int m_stride;
+}; 
+
+
+inline vector_iterator operator + (const vector_iterator& it, int dist) 
+{
+	vector_iterator result(it); 
+	result += dist; 
+	return result; 
+}
+
+inline vector_iterator operator - (const vector_iterator& it, int dist) 
+{
+	vector_iterator result(it); 
+	result -= dist; 
+	return result; 
+}
+
+inline vector_iterator operator + (int dist, const vector_iterator& it) 
+{
+	vector_iterator result(it); 
+	result += dist; 
+	return result; 
+}
+
+
+class const_vector_iterator {
+public:  
+	typedef const double value_type; 
+	typedef const double* pointer;
+	typedef const double& reference; 
+	typedef size_t difference_type; 
+	
+
+	const_vector_iterator(const double *base, int stride): 
+		m_current(base), m_stride(stride)
+	{
+	}
+	
+	const_vector_iterator(const const_vector_iterator& other) = default;  
+	
+	const_vector_iterator(const vector_iterator& other): 
+		m_current(other.m_current),
+		m_stride(other.m_stride)
+	{
+	}
+	
+	const_vector_iterator():
+		m_current(nullptr), 
+		m_stride(0)
+	{
+	}
+	
+	const double& operator *() const {
+		return *m_current;
+	}; 
+	
+	const double* operator ->() const {
+		return  m_current;
+	}; 
+
+	const_vector_iterator& operator ++() {
+		m_current += m_stride;
+		return *this; 
+	}; 
+	
+	const_vector_iterator operator ++(int){
+		const_vector_iterator result(*this); 
+		++(*this); 
+		return result; 
+	}
+
+	const_vector_iterator& operator --() {
+		m_current -= m_stride;
+		return *this; 
+	}; 
+	
+	const_vector_iterator operator --(int){
+		const_vector_iterator result(*this); 
+		--(*this); 
+		return result; 
+	}
+
+	const_vector_iterator& operator += (int dist) {
+		m_current += dist * m_stride; 
+		return *this; 
+	}
+
+	const_vector_iterator& operator -= (int dist) {
+		m_current -= dist * m_stride; 
+		return *this; 
+	}
+
+	difference_type operator - (const const_vector_iterator& other) {
+		assert(m_stride == other.m_stride); 
+		return (m_current - other.m_current) / m_stride;  
+	}
+
+	const double& operator[] (int idx) const {
+		return m_current[idx * m_stride]; 
+	}
+	
+	bool operator == (const const_vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current == other.m_current; 
+	}
+
+	bool operator != (const const_vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current != other.m_current; 
+	}
+
+	bool operator < (const const_vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current < other.m_current; 
+	}
+
+	bool operator <= (const const_vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current <= other.m_current; 
+	}
+
+	bool operator > (const const_vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current > other.m_current; 
+	}
+	
+	bool operator >= (const const_vector_iterator& other) const {
+		assert(m_stride == other.m_stride); 
+		return m_current >= other.m_current; 
+	}
+
+
+private: 
+	const double* m_current;
+	int m_stride;
+}; 
+
+
+inline const_vector_iterator operator + (const const_vector_iterator& it, int dist) 
+{
+	const_vector_iterator result(it); 
+	result += dist; 
+	return result; 
+}
+
+inline const_vector_iterator operator - (const const_vector_iterator& it, int dist) 
+{
+	const_vector_iterator result(it); 
+	result -= dist; 
+	return result; 
+}
+
+inline const_vector_iterator operator + (int dist, const const_vector_iterator& it) 
+{
+	const_vector_iterator result(it); 
+	result += dist; 
+	return result; 
+}
+
+}
+
+namespace std {
+
+template <>
+class iterator_traits< gsl::const_vector_iterator >  {
+public: 
+	typedef size_t   difference_type; 
+	typedef double	 value_type; 
+	typedef const double* pointer; 
+	typedef const double&	reference; 
+	typedef random_access_iterator_tag	iterator_category; 
+}; 
+
+template <>
+class iterator_traits< gsl::vector_iterator > {
+public: 
+	typedef size_t   difference_type; 
+	typedef double	 value_type; 
+	typedef double* pointer; 
+	typedef double&	reference; 
+	typedef random_access_iterator_tag	iterator_category; 
+}; 
+
+}
+
+#endif 
diff --git a/mia/core/gsl_matrix.cc b/mia/core/gsl_matrix.cc
new file mode 100644
index 0000000..4f24d08
--- /dev/null
+++ b/mia/core/gsl_matrix.cc
@@ -0,0 +1,420 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 <cassert>
+#include <cstring>
+#include <iostream>
+#include <gsl/gsl_statistics.h>
+#include <gsl/gsl_eigen.h>
+#include <gsl/gsl_blas.h>
+
+#include <mia/core/gsl_matrix.hh>
+#include <mia/core/gsl_matrix_vector_ops.hh>
+#include <algorithm>
+
+namespace gsl {
+
+using std::swap; 
+using std::fill; 
+using std::ostream_iterator; 
+using std::sqrt; 
+  
+Matrix::Matrix():m_matrix(nullptr), m_const_matrix(nullptr), m_owner(false)
+{
+}
+
+Matrix::Matrix(size_t rows, size_t columns, bool clean):
+	m_matrix(NULL), m_owner(true)
+{
+	m_matrix = clean ? 
+		gsl_matrix_calloc(rows, columns):
+		gsl_matrix_alloc(rows, columns); 
+	m_const_matrix = m_matrix; 
+}
+
+Matrix::Matrix(size_t rows, size_t columns, double init):
+	m_matrix(NULL), m_owner(true)
+{
+	m_matrix = gsl_matrix_alloc(rows, columns); 
+	auto p = gsl_matrix_ptr (m_matrix, 0, 0);
+	fill(p, p + rows * columns, init); 
+	m_const_matrix = m_matrix; 
+}
+
+Matrix::Matrix(size_t rows, size_t columns, const double *init):
+	m_matrix(NULL), m_owner(true)
+{
+	assert(init); 
+	m_matrix = gsl_matrix_alloc(rows, columns); 
+	memcpy(gsl_matrix_ptr (m_matrix, 0, 0), init, rows * columns * sizeof(double)); 
+	m_const_matrix = m_matrix; 
+}
+
+Matrix::Matrix(const Matrix& other):
+	m_owner(true)
+{
+	m_matrix = gsl_matrix_alloc(other.rows(), other.cols()); 
+	gsl_matrix_memcpy (m_matrix, other.m_matrix);
+	m_const_matrix = m_matrix; 
+}
+
+Matrix::Matrix(gsl_matrix* m):
+	m_matrix(m), 
+	m_const_matrix(m), 
+	m_owner(false)
+{
+}
+
+Matrix::Matrix(const gsl_matrix* m):
+	m_matrix(nullptr), 
+	m_const_matrix(m), 
+	m_owner(false)
+{
+}
+
+Matrix& Matrix::operator =(const Matrix& other)
+{
+	if (this == &other) 
+		return *this; 
+
+	if (m_matrix && rows() == other.rows() && cols() == other.cols()) {
+		gsl_matrix_memcpy (m_matrix, other.m_const_matrix);
+		return *this; 
+	}
+	gsl_matrix *help = gsl_matrix_alloc(other.rows(), other.cols()); 
+	gsl_matrix_memcpy (help, other.m_matrix); 
+	swap(m_matrix, help); 
+	if (help && m_owner) 
+		gsl_matrix_free(help);
+	
+	m_const_matrix = m_matrix; 
+	m_owner = true; 
+	return *this; 
+}
+
+void Matrix::reset(size_t rows, size_t columns, bool clean) 
+{
+	gsl_matrix *help = clean ? 
+		gsl_matrix_calloc(rows, columns):
+		gsl_matrix_alloc(rows, columns); 
+	swap(help, m_matrix); 
+	if (help && m_owner) 
+		gsl_matrix_free(help);
+	m_const_matrix = m_matrix; 
+}
+
+void Matrix::reset(size_t rows, size_t columns, double init) 
+{
+	gsl_matrix *help = gsl_matrix_alloc(rows, columns); 
+	auto p = gsl_matrix_ptr (help, 0, 0);
+	fill(p, p + rows * columns, init); 
+	
+	swap(help, m_matrix); 
+	if (help && m_owner) 
+		gsl_matrix_free(help);
+	m_const_matrix = m_matrix; 
+}
+
+Matrix::~Matrix()
+{
+	if (m_matrix && m_owner) 
+		gsl_matrix_free(m_matrix);
+}
+
+size_t Matrix::rows()const
+{
+	assert(m_const_matrix); 
+	return m_const_matrix->size1; 
+}
+
+size_t Matrix::cols()const
+{
+	assert(m_const_matrix); 
+	return m_const_matrix->size2; 
+}
+
+void Matrix::set_row(int r, const Vector& row)
+{
+	assert(row.size() == cols()); 
+	auto mrow = gsl_matrix_row(m_matrix, r); 
+	gsl_vector_memcpy(&mrow.vector, row); 
+}
+
+VectorView Matrix::get_row(int r)
+{
+	return VectorView(gsl_matrix_row(m_matrix, r)); 
+}
+
+ConstVectorView Matrix::get_row(int r) const 
+{
+	return ConstVectorView(gsl_matrix_const_row(m_const_matrix, r)); 
+}
+
+void Matrix::set_column(int c, const Vector& col)
+{
+	assert(col.size() == rows()); 
+	auto mcol = gsl_matrix_column(m_matrix, c); 
+	gsl_vector_memcpy(&mcol.vector, col); 
+}
+
+VectorView Matrix::get_column(int c)
+{
+	return VectorView(gsl_matrix_column(m_matrix, c)); 
+}
+
+ConstVectorView Matrix::get_column(int c) const
+{
+	return ConstVectorView(gsl_matrix_const_column(m_const_matrix, c)); 
+}
+
+
+
+double Matrix::dot_row(int r, const Vector& row) const 
+{
+	auto mrow = gsl_matrix_const_row(m_const_matrix, r); 
+	return dot(row, &mrow.vector); 
+}
+
+double Matrix::dot_column(int c, const Vector& col) const 
+{
+	auto mcol = gsl_matrix_const_column(m_const_matrix, c); 
+	return dot(col, &mcol.vector); 
+}
+
+void Matrix::print(std::ostream& os) const
+{
+	os << "["; 
+	if (!m_matrix) {
+		if (!m_const_matrix) {
+			os << "(null)]"; 
+			return; 
+		}
+			
+		os << "(const)"; 
+	}
+	os << "\n"; 
+	
+	for (unsigned r = 0; r < rows(); ++r) {
+		auto mrow = get_row(r); 
+		os << "  "; 
+		copy(mrow.begin(), mrow.end(), ostream_iterator<double>(os, ", ")); 
+		os << "\n"; 
+	}
+	os << "]";
+
+	
+}
+
+void Matrix::set(size_t i, size_t j, double x)
+{
+	assert(m_matrix); 
+	gsl_matrix_set(m_matrix, i,j,x); 
+}
+
+double Matrix::operator ()(size_t i, size_t j) const
+{
+	return gsl_matrix_get(m_const_matrix, i,j);
+}
+
+Matrix::operator gsl_matrix * ()
+{
+	return m_matrix; 
+}
+
+Matrix::operator const gsl_matrix *() const
+{
+	return m_const_matrix; 
+}
+
+
+matrix_iterator Matrix::begin()
+{
+	assert(m_matrix); 
+	return matrix_iterator(m_matrix, true); 
+}
+
+matrix_iterator Matrix::end()
+{
+	assert(m_matrix); 
+	return matrix_iterator(m_matrix, false);
+}
+
+
+const_matrix_iterator Matrix::begin() const
+{
+	assert(m_const_matrix); 
+	return const_matrix_iterator(m_const_matrix, true); 
+}
+
+const_matrix_iterator Matrix::end() const
+{
+	assert(m_const_matrix); 
+	return const_matrix_iterator(m_const_matrix, false); 
+}
+
+Matrix Matrix::transposed() const
+{
+	assert(m_matrix); 
+	Matrix result(cols(), rows(), false); 
+	gsl_matrix_transpose_memcpy (result.m_matrix, m_matrix); 
+	return result; 
+}
+
+Matrix Matrix::row_covariance() const 
+{
+	int d = rows(); 
+	int n = cols(); 
+	Matrix cov(d,d, true); 
+	
+	Matrix help(d, n, false); 
+
+	// remove mean 
+	for (int r = 0; r < d; ++r)  {
+		auto tmp = gsl_matrix_const_row (m_const_matrix, r);
+		auto mean = gsl_stats_mean (tmp.vector.data, tmp.vector.stride, n); 
+		for (int c = 0; c < n; ++c)  {
+			help.set(r, c, gsl_matrix_get(m_const_matrix, r, c) - mean); 
+		}
+	}
+
+	for (int i = 0; i < d; i++) {
+		for (int j = 0; j <= i; j++) {
+			
+			auto a = gsl_matrix_row (help, i);
+			auto b = gsl_matrix_row (help, j);
+			double c = gsl_stats_covariance(a.vector.data, a.vector.stride,
+							b.vector.data, b.vector.stride, n);
+			cov.set(j, i, c); 
+			cov.set(i, j, c); 
+		}
+	}
+	return cov; 
+}
+
+Matrix Matrix::column_covariance() const
+{
+	int n = rows(); 
+	int d = cols(); 
+	Matrix cov(d,d, true); 
+	
+	Matrix help(n, d, false); 
+
+	// remove mean 
+	for (int i = 0; i < d; ++i)  {
+		auto tmp = gsl_matrix_const_column (m_const_matrix, i);
+		auto mean = gsl_stats_mean (tmp.vector.data, tmp.vector.stride, n); 
+		for (int r = 0; r < n; ++r)  {
+			help.set(r,i, gsl_matrix_get(m_const_matrix, r, i) - mean); 
+		}
+	}
+
+	for (int i = 0; i < d; i++) {
+		for (int j = 0; j <= i; j++) {
+			
+			auto a = gsl_matrix_column (help, i);
+			auto b = gsl_matrix_column (help, j);
+			double c = gsl_stats_covariance(a.vector.data, a.vector.stride,
+							b.vector.data, b.vector.stride, n);
+			cov.set(j, i, c); 
+			cov.set(i, j, c); 
+		}
+	}
+	return cov; 
+	
+}
+
+
+Matrix operator - (const Matrix& lhs, const Matrix& rhs)
+{
+	Matrix result(lhs); 
+	result -= rhs; 
+	return result; 
+}
+
+Matrix operator + (const Matrix& lhs, const Matrix& rhs)
+{
+	Matrix result(lhs); 
+	result += rhs; 
+	return result; 
+}
+
+Matrix operator * (const Matrix& lhs, const Matrix& rhs)
+{
+	Matrix result(lhs.rows(), rhs.cols(), false); 
+	multiply_m_m(result, lhs, rhs);
+	return result; 
+}
+
+CSymmvEvalEvec::CSymmvEvalEvec(Matrix m):
+	evec(m.rows(), m.cols(), false), 
+	eval(m.rows(), false)
+{
+	assert(m.cols() == m.rows()); 
+	
+	gsl_eigen_symmv_workspace *ws = gsl_eigen_symmv_alloc (m.rows()); 
+	gsl_eigen_symmv (m, eval, evec, ws); 
+	gsl_eigen_symmv_free (ws); 
+}
+
+void matrix_inv_sqrt(Matrix& m )
+{
+	Matrix mTm(m.cols(), m.cols(), false); 
+	multiply_mT_m(mTm, m, m); 
+
+	CSymmvEvalEvec see(mTm);
+	
+	for (unsigned r = 0; r < see.evec.cols(); ++r) {
+		auto wmr = see.evec.get_column(r); 
+		const double f = see.eval[r] > 0 ? 1.0/ sqrt(sqrt(see.eval[r])) : 0.0; 
+		std::transform(wmr.begin(), wmr.end(), wmr.begin(), [f](double x) {return f*x;}); 
+	}
+	multiply_m_mT(mTm, see.evec, see.evec); 
+	m = m * mTm; 
+
+}
+
+
+bool operator == (const matrix_iterator& lhs, const matrix_iterator& rhs)
+{
+	assert(lhs.m_matrix == rhs.m_matrix); 
+	return lhs.m_current == rhs.m_current; 
+}
+
+bool operator != (const matrix_iterator& lhs, const matrix_iterator& rhs)
+{
+	assert(lhs.m_matrix == rhs.m_matrix); 
+	return lhs.m_current != rhs.m_current; 
+}
+
+bool operator == (const const_matrix_iterator& lhs, const const_matrix_iterator& rhs)
+{
+	assert(lhs.m_matrix == rhs.m_matrix); 
+	return lhs.m_current == rhs.m_current; 
+}
+
+bool operator != (const const_matrix_iterator& lhs, const const_matrix_iterator& rhs)
+{
+	assert(lhs.m_matrix == rhs.m_matrix); 
+	return lhs.m_current != rhs.m_current; 
+}
+
+
+}
diff --git a/mia/core/gsl_matrix.hh b/mia/core/gsl_matrix.hh
new file mode 100644
index 0000000..6071c37
--- /dev/null
+++ b/mia/core/gsl_matrix.hh
@@ -0,0 +1,475 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 GSLPP_MATRIX_HH
+#define GSLPP_MATRIX_HH
+
+#include <cassert>
+#include <iterator>
+#include <gsl/gsl_matrix.h>
+#include <mia/core/gsl_vector.hh>
+
+namespace gsl {
+
+class EXPORT_GSL matrix_iterator {
+        friend class const_matrix_iterator; 
+public: 
+	matrix_iterator(gsl_matrix *m, bool begin):
+		m_matrix(m), 
+		m_current(begin ? m->data : m->data +  m->size1 * m->tda), 
+		m_current_column(0), 
+		m_row_jump(m->tda - m->size2)
+		{
+		}
+		
+	matrix_iterator():
+		m_matrix(nullptr), 
+		m_current(nullptr), 
+		m_current_column(0)
+		{
+		}
+		
+		
+	matrix_iterator(const matrix_iterator& other) = default; 
+
+	double& operator *(){
+		assert(m_current); 
+		return *m_current; 
+	}
+	
+	matrix_iterator& operator ++() {
+		assert(m_current); 
+		++m_current; 
+		++m_current_column; 
+		if(m_current_column == m_matrix->size2) {
+			m_current += m_row_jump; 
+			m_current_column = 0; 
+		}
+		return *this; 
+	}
+	
+	
+	matrix_iterator operator ++(int) {
+		matrix_iterator result(*this); 
+		++(*this); 
+		return result; 
+	}
+	
+	friend bool operator == (const matrix_iterator& lhs, const matrix_iterator& rhs); 
+	friend bool operator != (const matrix_iterator& lhs, const matrix_iterator& rhs); 
+private: 
+	gsl_matrix *m_matrix; 
+	double *m_current; 
+	size_t m_current_column; 
+	size_t m_row_jump; 
+}; 
+
+bool EXPORT_GSL operator == (const matrix_iterator& lhs, const matrix_iterator& rhs); 
+bool EXPORT_GSL operator != (const matrix_iterator& lhs, const matrix_iterator& rhs); 
+
+
+class EXPORT_GSL const_matrix_iterator {
+public: 
+	const_matrix_iterator(const gsl_matrix *m, bool begin):
+		m_matrix(m), 
+		m_current(begin ? m->data : m->data +  m->size1 * m->tda), 
+		m_current_column(0), 
+		m_row_jump(m->tda - m->size2)
+		{
+		}
+
+	const_matrix_iterator(const matrix_iterator& other):
+		m_matrix(other.m_matrix), 
+		m_current(other.m_current), 
+		m_current_column(other.m_current_column), 
+		m_row_jump(other.m_row_jump)
+		{
+		}
+		
+	const_matrix_iterator():
+		m_matrix(nullptr), 
+		m_current(nullptr), 
+		m_current_column(0)
+		{
+		}
+		
+		
+	const_matrix_iterator(const const_matrix_iterator& other) = default; 
+
+	double operator *() const{
+		assert(m_current); 
+		return *m_current; 
+	}
+	
+	const_matrix_iterator& operator ++() {
+		assert(m_current); 
+		++m_current; 
+		++m_current_column; 
+		if(m_current_column == m_matrix->size2) {
+			m_current += m_row_jump; 
+			m_current_column = 0; 
+		}
+		return *this; 
+	}
+			
+	const_matrix_iterator operator ++(int) {
+		const_matrix_iterator result(*this); 
+		++(*this); 
+		return result; 
+	}
+
+	friend bool operator == (const const_matrix_iterator& lhs, const const_matrix_iterator& rhs); 
+	friend bool operator != (const const_matrix_iterator& lhs, const const_matrix_iterator& rhs); 
+private: 
+	const gsl_matrix *m_matrix; 
+	const double *m_current; 
+	size_t m_current_column; 
+	size_t m_row_jump; 
+}; 
+
+bool EXPORT_GSL operator == (const const_matrix_iterator& lhs, const const_matrix_iterator& rhs); 
+bool EXPORT_GSL operator != (const const_matrix_iterator& lhs, const const_matrix_iterator& rhs); 
+
+
+
+
+
+/**
+   This is a wrapper class around the GSL matrix type. It provides 
+   a compatibility to avoid handling de-alloction manually.
+*/
+class EXPORT_GSL Matrix {
+public: 
+	typedef matrix_iterator iterator; 
+	typedef const_matrix_iterator const_iterator; 
+
+	Matrix(); 
+
+	/**
+	   Create a matrix of size rows \f$\times\f$ columns, 
+	   \param rows
+	   \param columns 
+	   \param clean allocate zeroing out all elements 
+	 */
+	Matrix(size_t rows, size_t columns, bool clean); 
+
+	/**
+	   Create a matrix of size rows \f$\times\f$ columns, 
+	   \param rows
+	   \param columns 
+	   \param init set the matrix elements to this value 
+	 */
+	Matrix(size_t rows, size_t columns, double init); 
+
+	/**
+	   Create a matrix of size rows \f$\times\f$ columns and initialize it 
+	   with the given data 
+	   \param rows
+	   \param columns 
+	   \param init the input data in row major format 
+	*/
+	Matrix(size_t rows, size_t columns, const double *init);
+	
+	/**
+	   Copy constructor that executes a deep copy 
+	 */
+	Matrix(const Matrix& other); 
+	
+	/**
+	   Wrap an existing GSL matrix 
+	   \param m the GSL matrix 
+	 */
+	Matrix(gsl_matrix* m); 
+
+	/**
+	   Wrap an existing GSL constant matrix 
+	   \param m the GSL matrix 
+	 */
+	Matrix(const gsl_matrix* m); 
+
+	/**
+	   Acquire the transposed matrix. 
+	   \returns  transposed matrix as newly created object
+	*/
+	Matrix transposed() const; 
+
+
+	/**
+	   Copy operator that executes a deep copy 
+	 */
+	Matrix& operator =(const Matrix& other); 
+
+	/**
+	   Reset the matrix with the new dimensions. 
+	   \param rows 
+	   \param columns 
+	   \param clean - set all values to zero 
+	 */
+	void reset(size_t rows, size_t columns, bool clean); 
+
+	/**
+	   Reset the matrix with the new dimensions. 
+	   \param rows 
+	   \param columns 
+	   \param init - set all values to \a init 
+	 */
+	void reset(size_t rows, size_t columns, double init); 
+
+	~Matrix(); 
+
+
+	/**
+	   \returns the number of rows in the matrix 
+	 */
+	size_t rows()const; 
+
+	/**
+	   \returns the number of columns in the matrix 
+	*/
+	size_t cols()const; 
+	
+	/**
+	   Set a value of the matrix 
+	   \param i row 
+	   \param j column 
+	   \param x value
+	 */
+	void set(size_t i, size_t j, double x); 
+
+	/**
+	   Get a value of the matrix 
+	   \param i row 
+	   \param j column 
+	   \returns the value 
+	 */
+
+	double operator ()(size_t i, size_t j) const; 
+	
+	/**
+	   operator to get the underlying gsl_matrix pointer 
+	 */
+	operator gsl_matrix *(); 
+
+	/**
+	   operator to get the underlying const gsl_matrix pointer 
+	 */
+	operator const gsl_matrix *() const; 
+
+	/**
+	   Evaluate the covariance matrix between the columns of this matrix 
+	   \returns the covariance matrix 
+	 */
+	Matrix column_covariance() const; 
+
+	/**
+	   Evaluate the covariance matrix between the rows of this matrix 
+	   \returns the covariance matrix 
+	 */
+	Matrix row_covariance() const; 
+
+	/**
+	   Iterator over the matrix elements of the matrix, column indices are the 
+	   fastest changing indices. 
+	   \returns the begin of the range 
+	 */ 
+	matrix_iterator begin(); 
+
+	/**
+	   Iterator over the matrix elements of the matrix, column indices are the 
+	   fastest changing indices. 
+	   \returns the end of the range 
+	 */ 
+	matrix_iterator end(); 
+
+	/**
+	   Read only iterator over the matrix elements of the matrix, column indices are the 
+	   fastest changing indices. 
+	   \returns the begin of the range 
+	 */ 
+	const_matrix_iterator begin() const; 
+
+	/**
+	   Read only iterator over the matrix elements of the matrix, column indices are the 
+	   fastest changing indices. 
+	   \returns the end of the range 
+	 */ 
+	const_matrix_iterator end() const; 
+
+	/**
+	   Set a matrix row 
+	   \param r index of row to be set, must be in [0, this->rows()-1]
+	   \param row vector containing the new values. It's size must be equal 
+	   to the number of columns of the matrix 
+	 */ 
+	void set_row(int r, const Vector& row); 
+
+	/**
+	   Get a read-write view of a matrix row
+	   \param r index of the matrix row 
+	   \returns view 
+	*/
+	VectorView get_row(int r); 
+
+	/**
+	   Get a read-only view of a matrix row
+	   \param r index of the matrix row 
+	   \returns constant view 
+	*/
+	ConstVectorView get_row(int r) const; 
+
+	/**
+	   Set a matrix column 
+	   \param c index of column to be set,  must be in [0, this->cols()-1]
+	   \param col vector containing the new values. It's size must be equal 
+	   to the number of rows of the matrix 
+	 */ 
+	void set_column(int c, const Vector& col); 
+
+	/**
+	   Get a read-write view of a matrix column
+	   \param c index of the matrix column 
+	   \returns view 
+	*/
+	VectorView get_column(int c); 
+
+	/**
+	   Get a read-only view of a matrix column
+	   \param c index of the matrix column 
+	   \returns view 
+	*/
+	ConstVectorView get_column(int c) const; 
+
+	/**
+	   Evaluate the dot product between a row of the matrix and a given vector 
+	   \param r index of row, must be in [0, this->rows()-1] 
+	   \param v vector to evaluate the dot product with. The vector's size must be equal to the 
+	   number of matrix columns. 
+	   \returns the dot product of the row vector and the input vector 
+	 */ 
+	double dot_row(int r, const Vector& v) const; 
+
+	/**
+	   Evaluate the dot product between a column  of the matrix and a given vector 
+	   \param c index of column,  must be in [0, this->cols()-1]
+       \param col vector to evaluate the dot product with. The vector's size must be equal to the
+	   number of matrix rows.  
+	   \returns the dot product of the row vector and the input vector 
+	 */ 
+
+	double dot_column(int c, const Vector& col) const; 
+
+	/**
+	   Print matrix to a ostream 
+	   \param os output stream to write to 
+	 */
+	void print(std::ostream& os) const; 
+
+	/**
+	   Element wise matrix subtraction 
+	   \param rhs matrix to subtract 
+	   \returns reference of this matrix
+	*/
+	Matrix& operator -=(const Matrix& rhs) {
+		gsl_matrix_sub(*this, rhs); 
+		return *this; 
+	}
+
+	/**
+	   Element wise matrix addition  
+	   \param rhs matrix to add 
+	   \returns reference of this matrix
+	*/
+	Matrix& operator +=(const Matrix& rhs) {
+		gsl_matrix_add(*this, rhs); 
+		return *this; 
+	}
+
+	/**
+	   Scale elements with a factor   
+	   \param rhs scaling factor  
+	   \returns reference of this matrix
+	*/
+	Matrix& operator *=(double rhs) {
+		gsl_matrix_scale(*this, rhs); 
+		return *this; 
+	}
+	
+private: 
+	gsl_matrix *m_matrix; 
+	const gsl_matrix *m_const_matrix; 
+	bool m_owner; 
+}; 
+
+
+Matrix EXPORT_GSL operator * (const Matrix& lhs, const Matrix& rhs); 
+Matrix EXPORT_GSL operator + (const Matrix& lhs, const Matrix& rhs); 
+Matrix EXPORT_GSL operator - (const Matrix& lhs, const Matrix& rhs); 
+
+inline std::ostream& operator << (std::ostream& os, const Matrix& m)
+{
+	m.print(os); 
+	return os; 
+}
+
+/**
+   Evaluate the eigenvalues and eigenvectors of the input matrix
+*/
+struct EXPORT_GSL CSymmvEvalEvec {
+	CSymmvEvalEvec(Matrix m); 
+	
+	Matrix evec; 
+	Vector eval; 
+}; 
+	
+/**
+   Evaluate in place: pow(m, -0.5); 
+
+*/
+void EXPORT_GSL matrix_inv_sqrt(Matrix& m); 
+
+
+} // end namespace 
+
+namespace std {
+
+template <>
+class iterator_traits< gsl::const_matrix_iterator >  {
+public: 
+	typedef size_t   difference_type; 
+	typedef double	 value_type; 
+	typedef const double* pointer; 
+	typedef const double&	reference; 
+	typedef forward_iterator_tag	iterator_category; 
+}; 
+
+template <>
+class iterator_traits< gsl::matrix_iterator > {
+public: 
+	typedef size_t   difference_type; 
+	typedef double	 value_type; 
+	typedef double* pointer; 
+	typedef double&	reference; 
+	typedef forward_iterator_tag	iterator_category; 
+}; 
+
+}
+
+
+#endif
diff --git a/mia/core/gsl_matrix_vector_ops.cc b/mia/core/gsl_matrix_vector_ops.cc
new file mode 100644
index 0000000..e3af56e
--- /dev/null
+++ b/mia/core/gsl_matrix_vector_ops.cc
@@ -0,0 +1,187 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/gsl_matrix_vector_ops.hh>
+
+#include <gsl/gsl_blas.h>
+#include <gsl/gsl_linalg.h>
+#include <cassert>
+#include <mia/core/parallel.hh>
+
+namespace gsl {
+using mia::C1DParallelRange;
+using mia::pfor;
+
+struct MultVectMatrix {
+	typedef   Vector::vector_pointer_type pvector; 
+	MultVectMatrix(gsl_vector& result, const gsl_vector& lhs, const Matrix& rhs); 
+        
+        void operator () (const C1DParallelRange& range) const;
+private:
+        gsl_vector& m_result; 
+        const gsl_vector& m_lhs; 
+        const Matrix& m_rhs; 
+}; 
+
+MultVectMatrix::MultVectMatrix(gsl_vector& result, const gsl_vector& lhs, const Matrix& rhs):
+        m_result(result), 
+        m_lhs(lhs), 
+        m_rhs(rhs)
+{
+}
+
+void MultVectMatrix::operator () (const C1DParallelRange& range) const
+{
+	double val = 0.0; 
+        for (int c = range.begin(); c != range.end(); ++c) {
+                auto rhs_column = m_rhs.get_column(c); 
+                gsl_blas_ddot(&m_lhs, rhs_column, &val); 
+                gsl_vector_set(&m_result, c, val); 
+        }
+}
+
+
+struct MultVectMatrixT {
+        typedef   Vector::vector_pointer_type pvector; 
+        MultVectMatrixT(gsl_vector& result, const gsl_vector& lhs, const Matrix& rhs); 
+        
+        void operator () (const C1DParallelRange& range) const;
+private:
+        gsl_vector& m_result; 
+        const gsl_vector& m_lhs; 
+        const Matrix& m_rhs; 
+}; 
+
+MultVectMatrixT::MultVectMatrixT(gsl_vector& result, const gsl_vector& lhs, const Matrix& rhs):
+        m_result(result), 
+        m_lhs(lhs), 
+        m_rhs(rhs)
+{
+}
+
+void MultVectMatrixT::operator () (const C1DParallelRange& range) const
+{
+        for (int c = range.begin(); c != range.end(); ++c) {
+                auto rhs_row = gsl_matrix_const_row(m_rhs, c); 
+                const double val = cblas_ddot (m_rhs.cols(), m_lhs.data, m_lhs.stride, 
+                                         rhs_row.vector.data, rhs_row.vector.stride); 
+                gsl_vector_set(&m_result, c, val); 
+        }
+}
+
+void multiply_m_m(Matrix& result, const Matrix& lhs, const Matrix& rhs)
+{
+        assert(result.rows() == lhs.rows()); 
+        assert(result.cols() == rhs.cols()); 
+        assert(lhs.cols() == rhs.rows());
+
+        for (unsigned r = 0; r < result.rows(); ++r) {
+                gsl_vector_view out_row = gsl_matrix_row(result, r); 
+                gsl_vector_const_view lhs_row = gsl_matrix_const_row(lhs, r); 
+                MultVectMatrix op(out_row.vector, lhs_row.vector, rhs); 
+                pfor(C1DParallelRange( 0, result.cols()), op);
+        }
+}
+
+void multiply_mT_m(Matrix& result, const Matrix& lhs, const Matrix& rhs)
+{
+        assert(lhs.rows() == rhs.rows());
+	if (result.rows() != lhs.cols() || 
+	    result.cols() != rhs.cols()) 
+		result.reset(lhs.cols(), rhs.cols(), false); 
+
+        for (unsigned r = 0; r < result.rows(); ++r) {
+                gsl_vector_view out_row = gsl_matrix_row(result, r); 
+                gsl_vector_const_view lhs_col = gsl_matrix_const_column(lhs, r); 
+                MultVectMatrix op(out_row.vector, lhs_col.vector, rhs);
+                pfor(C1DParallelRange( 0, result.cols()), op);
+        }
+
+}
+
+void multiply_m_mT(Matrix& result, const Matrix& lhs, const Matrix& rhs)
+{
+        assert(lhs.cols() == rhs.cols());
+
+	if (result.rows() != lhs.rows() || 
+	    result.cols() != rhs.rows()) 
+		result.reset(lhs.rows(), rhs.rows(), false); 
+
+
+	for (unsigned r = 0; r < result.rows(); ++r) {
+                gsl_vector_view out_row = gsl_matrix_row(result, r); 
+                gsl_vector_const_view lhs_row = gsl_matrix_const_row(lhs, r); 
+                MultVectMatrixT op(out_row.vector, lhs_row.vector, rhs);
+                pfor(C1DParallelRange( 0, result.cols()), op);
+        }
+}
+
+
+void multiply_v_m(Vector& result, const Vector& lhs, const Matrix& rhs)
+{
+        assert(result.size() == rhs.cols()); 
+        assert(lhs.size() == rhs.rows());
+
+        MultVectMatrix op(*result, *lhs, rhs);
+        pfor(C1DParallelRange( 0, result.size()), op);
+}
+
+void multiply_m_v(Vector& result, const Matrix& lhs, const Vector& rhs)
+{
+        assert(result.size() == lhs.rows()); 
+        assert(rhs.size() == lhs.cols());
+        
+        auto mult = [&result, &lhs, &rhs](const C1DParallelRange& range) -> void {
+                for (int r = range.begin(); r != range.end(); ++r) {
+                        auto lhs_row = gsl_matrix_const_row(lhs, r); 
+                        const double val = cblas_ddot (lhs_row.vector.size, lhs_row.vector.data, lhs_row.vector.stride, 
+                                                       rhs->data, rhs->stride);
+                        result[r] = val; 
+                }
+        }; 
+        pfor(C1DParallelRange( 0, result.size()), mult);
+        
+}
+
+double dot(const gsl_vector *lhs, const gsl_vector *rhs)
+{
+        assert(rhs); 
+        assert(lhs); 
+        assert(rhs->size == lhs->size);
+        
+        return cblas_ddot (rhs->size, lhs->data, lhs->stride, 
+                           rhs->data, rhs->stride);
+
+}
+
+void matrix_orthogonalize(Matrix& M)
+{
+	Matrix U(M); 
+	Matrix V(M.cols(), M.cols(), true); 
+	Vector D(M.cols(), true); 
+	Vector work_vector(M.cols(), false); 
+	
+	gsl_linalg_SV_decomp (U, V, D, work_vector); 
+	
+	multiply_m_mT(M, U, V); 
+}
+
+}
diff --git a/gsl++/vector.hh b/mia/core/gsl_matrix_vector_ops.hh
similarity index 50%
rename from gsl++/vector.hh
rename to mia/core/gsl_matrix_vector_ops.hh
index 47dc6aa..ff78161 100644
--- a/gsl++/vector.hh
+++ b/mia/core/gsl_matrix_vector_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,28 @@
  *
  */
 
-#ifndef GSLPP_VECTOR_HH
-#define GSLPP_VECTOR_HH
 
-#include <gsl++/vector_template.hh>
+#ifndef gslpp_matrix_vector_ops_hh
+#define gslpp_matrix_vector_ops_hh
+
+#include <mia/core/gsl_matrix.hh>
+#include <mia/core/gsl_vector.hh>
 
 namespace gsl {
 
-typedef TVector<double>  DoubleVector; 
-typedef TVector<float>   FloatVector; 
+void EXPORT_GSL multiply_m_m(Matrix& result, const Matrix& lhs, const Matrix& rhs);
+void EXPORT_GSL multiply_mT_m(Matrix& result, const Matrix& lhs, const Matrix& rhs);
+void EXPORT_GSL multiply_m_mT(Matrix& result, const Matrix& lhs, const Matrix& rhs);
 
-typedef TVector<long>    LongVector; 
-typedef TVector<int>     IntVector; 
-typedef TVector<short>   ShortVector; 
-typedef TVector<char>    CharVector; 
+void EXPORT_GSL multiply_v_m(Vector& result, const Vector& lhs, const Matrix& rhs); 
+void EXPORT_GSL multiply_m_v(Vector& result, const Matrix& rhs, const Vector& lhs);
 
-typedef TVector<ulong>   ULongVector; 
-typedef TVector<uint>    UIntVector; 
-typedef TVector<ushort>  UShortVector; 
-typedef TVector<uchar>   UCharVector; 
+double EXPORT_GSL dot(const gsl_vector *lhs, const gsl_vector *rhs); 
 
-}
+void EXPORT_GSL matrix_orthogonalize(Matrix& M); 
 
-#endif
+
+}
 
 
+#endif 
diff --git a/gsl++/multimin.cc b/mia/core/gsl_multimin.cc
similarity index 89%
rename from gsl++/multimin.cc
rename to mia/core/gsl_multimin.cc
index 71de56b..b0a5382 100644
--- a/gsl++/multimin.cc
+++ b/mia/core/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@
  *
  */
 
-#include <gsl++/multimin.hh>
+#include <mia/core/gsl_multimin.hh>
 
 #include <stdexcept>
 #include <algorithm>
@@ -32,7 +32,7 @@ struct CFDFMinimizerImpl {
 	CFDFMinimizerImpl(CFDFMinimizer::PProblem problem, const gsl_multimin_fdfminimizer_type *ot); 
 	~CFDFMinimizerImpl(); 
 	
-	int run(DoubleVector& x); 
+	int run(Vector& x); 
 
 	CFDFMinimizer::PProblem m_problem; 
 	const gsl_multimin_fdfminimizer_type *m_optimizer_type; 
@@ -48,7 +48,7 @@ CFDFMinimizer::CFDFMinimizer(PProblem problem, const gsl_multimin_fdfminimizer_t
 {
 }
 
-int CFDFMinimizer::run(DoubleVector& x) 
+int CFDFMinimizer::run(Vector& x) 
 {
 	return impl->run(x); 
 }
@@ -70,22 +70,22 @@ CFDFMinimizer::Problem::Problem(size_t n)
 double CFDFMinimizer::Problem::f(const gsl_vector * x, void * params)
 {
 	Problem *p = (Problem *)params; 
-	return p->do_f(DoubleVector(x)); 
+	return p->do_f(Vector(x)); 
 }
 
 void CFDFMinimizer::Problem::df(const gsl_vector * x, void * params, gsl_vector * g)
 {
 	Problem *p = (Problem *)params; 
-	const DoubleVector vx(x); 
-	DoubleVector gx(g); 
+	const Vector vx(x); 
+	Vector gx(g); 
 	p->do_df(vx,gx); 
 }
 
 void CFDFMinimizer::Problem::fdf(const gsl_vector * x, void * params, double * f, gsl_vector * g)
 {
 	Problem *p = (Problem *)params; 
-	const DoubleVector vx(x); 
-	DoubleVector gx(g); 
+	const Vector vx(x); 
+	Vector gx(g); 
 	*f = p->do_fdf(vx,gx); 
 }
 
@@ -127,7 +127,7 @@ void CFDFMinimizer::set_stop_eps(double tol)
 }
 
 
-int CFDFMinimizerImpl::run(DoubleVector& x)
+int CFDFMinimizerImpl::run(Vector& x)
 {
 	int iter = 0; 
 	int status = GSL_CONTINUE; 
@@ -142,8 +142,8 @@ int CFDFMinimizerImpl::run(DoubleVector& x)
 	} while (status == GSL_CONTINUE && iter < 100); 
 	
 	// copy best solution 
-	gsl_vector * help = gsl_multimin_fdfminimizer_x (m_s); 
-	std::copy(help->data, help->data + m_problem->size(), x.begin()); 
+	Vector help(gsl_multimin_fdfminimizer_x (m_s)); 
+	std::copy(help.begin(), help.end(), x.begin()); 
 
 	return status; 
 }
@@ -158,7 +158,7 @@ CFMinimizer::Problem::Problem(size_t n)
 double CFMinimizer::Problem::f(const gsl_vector * x, void * params)
 {
 	Problem *p = (Problem *)params; 
-	return p->do_f(DoubleVector(x)); 
+	return p->do_f(Vector(x)); 
 }
 
 size_t CFMinimizer::Problem::size() const
@@ -171,7 +171,7 @@ struct CFMinimizerImpl {
 	CFMinimizerImpl(CFMinimizer::PProblem problem, const gsl_multimin_fminimizer_type *ot); 
 	~CFMinimizerImpl(); 
 	
-	int run(DoubleVector& x); 
+	int run(Vector& x); 
 
 	CFMinimizer::PProblem m_problem; 
 	const gsl_multimin_fminimizer_type *m_optimizer_type; 
@@ -196,7 +196,7 @@ CFMinimizer::~CFMinimizer()
 	delete impl; 
 }
 	
-int CFMinimizer::run(DoubleVector& x)
+int CFMinimizer::run(Vector& x)
 {
 	return impl->run(x); 
 }
@@ -219,7 +219,7 @@ CFMinimizerImpl::~CFMinimizerImpl()
 	gsl_vector_free(m_step_size); 
 }
 
-int CFMinimizerImpl::run(DoubleVector& x)
+int CFMinimizerImpl::run(Vector& x)
 {
 	int iter = 0; 
 	int status;  
diff --git a/gsl++/multimin.hh b/mia/core/gsl_multimin.hh
similarity index 91%
rename from gsl++/multimin.hh
rename to mia/core/gsl_multimin.hh
index 772b1c6..5d0602a 100644
--- a/gsl++/multimin.hh
+++ b/mia/core/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +22,9 @@
 #define GSLPP_MULTIMIN_HH
 
 #include <memory>
-#include <gsl++/vector.hh>
+#include <mia/core/gsl_vector.hh>
 #include <gsl/gsl_multimin.h>
-#include <gsl++/gsldefines.hh>
+#include <mia/core/gsl_defines.hh>
 
 namespace gsl {
 
@@ -69,9 +69,9 @@ public:
 
 		size_t size() const; 
 	private: 
-		virtual double  do_f(const DoubleVector& x) = 0; 
-		virtual void    do_df(const DoubleVector& x, DoubleVector&  g) = 0; 
-		virtual double  do_fdf(const DoubleVector& x, DoubleVector&  g) = 0; 
+		virtual double  do_f(const Vector& x) = 0; 
+		virtual void    do_df(const Vector& x, Vector&  g) = 0; 
+		virtual double  do_fdf(const Vector& x, Vector&  g) = 0; 
 		gsl_multimin_function_fdf m_func; 
 	}; 
 	typedef std::shared_ptr<Problem> PProblem; 
@@ -101,7 +101,7 @@ public:
 	   \param[in,out] x at entry contains the start point of the optimization at exit the optimized value 
 	   \returns returns a status whether the optimization succeeded or why it stopped 
 	 */
-	int run(DoubleVector& x); 
+	int run(Vector& x); 
 	
 private: 
 	struct CFDFMinimizerImpl *impl; 
@@ -137,7 +137,7 @@ public:
 
 		size_t size() const; 
 	private: 
-		virtual double  do_f(const DoubleVector& x) = 0; 
+		virtual double  do_f(const Vector& x) = 0; 
 		gsl_multimin_function m_func; 
 	}; 
 	typedef std::shared_ptr<Problem> PProblem; 
@@ -156,7 +156,7 @@ public:
 	   \param[in,out] x at entry contains the start point of the optimization at exit the optimized value 
 	   \returns returns a status whether the optimization succeeded or why it stopped 
 	 */
-	int run(DoubleVector& x); 
+	int run(Vector& x); 
 private: 
 	struct CFMinimizerImpl *impl; 
 }; 
diff --git a/mia/core/gsl_pca.cc b/mia/core/gsl_pca.cc
new file mode 100644
index 0000000..7d4ca4c
--- /dev/null
+++ b/mia/core/gsl_pca.cc
@@ -0,0 +1,101 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/gsl_pca.hh>
+#include <algorithm>
+#include <cassert>
+#include <vector>
+
+#include <gsl/gsl_eigen.h>
+
+namespace gsl {
+
+using std::pair; 
+using std::sort; 
+using std::vector; 
+
+PCA::PCA(unsigned max_pc, double energy_thresh_ratio):
+        m_max_pc(max_pc), 
+        m_energy_thresh_ratio(energy_thresh_ratio), 
+        m_eval_min(1e-9)
+{
+        assert(max_pc > 0  || 
+               (m_energy_thresh_ratio >= 0.0 || m_energy_thresh_ratio <= 1.0)); 
+}
+
+void PCA::set_eigenvalue_minimum(double min)
+{
+        assert(m_eval_min >= 0); 
+        m_eval_min = min; 
+}
+
+PCA::Result PCA::analyze(const Matrix& signal) const
+{
+        auto  covariance_matrix = signal.row_covariance();
+
+        // evaluate eigen-decomposition of covariance matrix 
+
+	CSymmvEvalEvec see(covariance_matrix); 
+	 
+
+	double ev_energy = 0.0; 
+	for (unsigned i = 0; i < see.eval.size(); ++i) {
+		ev_energy += see.eval[i];
+	}
+	
+	gsl_eigen_symmv_sort (see.eval, see.evec, GSL_EIGEN_SORT_ABS_DESC);
+             
+        unsigned max_useful_eigen = 0; 
+        if (m_max_pc < 1) {
+                // automatic number based on culmulative energy threshold 
+		double ev_part_energy = 0.0;
+		double ev_part_thresh = m_energy_thresh_ratio * ev_energy;
+		
+		while ((ev_part_energy < ev_part_thresh) && 
+		       (max_useful_eigen < see.eval.size())) {
+			ev_part_energy += see.eval[max_useful_eigen]; 
+			++max_useful_eigen;
+		}
+	} else { 
+                // fixed number of PC/IC
+		while ((see.eval[max_useful_eigen] > m_eval_min) && 
+		       (max_useful_eigen < see.eval.size()) && 
+		       (max_useful_eigen < m_max_pc))
+			++max_useful_eigen; 
+	}
+        
+        PCA::Result result;
+        if (max_useful_eigen >= 1) {
+                // copy the useful eigenvalues and eigenvectors over 
+                result.eval = Vector(max_useful_eigen, false); 
+                result.evec.reset(covariance_matrix.rows(), max_useful_eigen, false); 
+                
+                for (unsigned i = 0; i < max_useful_eigen; ++i) {
+                        result.eval[i] = see.eval[i]; 
+                        auto in_col = gsl_matrix_column (see.evec, i);
+                        auto out_col = gsl_matrix_column (result.evec, i); 
+                        gsl_vector_memcpy (&out_col.vector, &in_col.vector); 
+                }
+        }
+        return result; 
+}
+
+}
diff --git a/mia/core/gsl_pca.hh b/mia/core/gsl_pca.hh
new file mode 100644
index 0000000..0c2d271
--- /dev/null
+++ b/mia/core/gsl_pca.hh
@@ -0,0 +1,90 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 gslpp_pca_hh
+#define gslpp_pca_hh
+
+#include <mia/core/gsl_matrix.hh>
+#include <mia/core/gsl_vector.hh>
+
+namespace gsl {
+
+
+/**
+   \brief This class implements Principal Component Analysis. 
+   
+   This class implements Principal Component Analysis by using the covariance matrix. 
+   The number of principal components 
+   to be evaluated can be defined in two ways: Either a hard number is given 
+   in the constructor, or the energy ratio is defined. In both cases PC are 
+   added starting from the component with the eigenvalue with the largest 
+   absolute value of the covariance matrix. In the first case the requested 
+   number of components is returned, unless smaller eigenvalues have a lower 
+   value than a given threshold value (default 1e-9). In the energy-ratio 
+   based case values are added as long as the ratio of the sum of the added 
+   eigenvalues with respect to the sum of all eigenvalues is below the 
+   user-defined ratio. 
+*/
+
+class EXPORT_GSL PCA {
+public: 
+        typedef struct {
+                Vector eval; 
+                Matrix evec; 
+        } Result;
+
+        /**
+           Construct the PCA analysis 
+           \param max_pc maximum number of principal components to be returned. 
+           if this parameter is set to zero, then the number is estimated based on 
+           the energy ration given in the secons parameter 
+           \param energy_thresh_ratio - if the number of principal components is to 
+           be evaluated automatically, then this value defines the condition when to 
+           stop adding components. The value must be in the range (0,1). 
+         */
+        PCA(unsigned max_pc, double energy_thresh_ratio); 
+        
+        /** 
+            Set an alternative threshold for eigenvalues to be ignored. 
+
+            \param min new minimum for acceptable eigenvalue values. 
+         */
+        void set_eigenvalue_minimum(double min); 
+
+
+        /**
+           Run the PCA on a given input data set. 
+           \param signal the input data the signals to be separated
+           are stored in the columns
+         */
+        Result analyze(const Matrix& signal) const; 
+        
+private: 
+        unsigned m_max_pc; 
+        double m_energy_thresh_ratio; 
+        double m_eval_min; 
+
+};
+
+}
+
+
+#endif 
diff --git a/mia/core/gsl_vector.cc b/mia/core/gsl_vector.cc
new file mode 100644
index 0000000..4a104fe
--- /dev/null
+++ b/mia/core/gsl_vector.cc
@@ -0,0 +1,203 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/gsl_vector.hh>
+#include <mia/core/errormacro.hh>
+
+#include <cstring>
+
+namespace gsl {
+
+
+Vector::Vector():
+	data(NULL), 
+	cdata(NULL), 
+	owner(false)
+{
+}
+
+Vector::Vector(size_type n, bool clear):
+	owner(true)
+{
+	cdata = data = (vector_type*) (clear ? gsl_vector_calloc (n) : gsl_vector_alloc (n));  
+}
+
+Vector::Vector(size_type size, const double *init):
+	owner(true)
+{
+	cdata = data = (vector_type*) (gsl_vector_alloc (size));  
+	memcpy(gsl_vector_ptr (data,0), init, size * sizeof(double)); 
+}
+
+Vector::Vector(const Vector& other):
+	owner(true)
+{
+	assert(other.cdata); 
+	
+	cdata = data = gsl_vector_alloc (other.cdata->size);
+	gsl_vector_memcpy(data, other.cdata); 
+}
+
+Vector& Vector::operator = (const Vector& other)
+{
+	if (&other != this) {
+		vector_type *d =  gsl_vector_alloc(other.data->size); 
+		gsl_vector_memcpy(d, other.cdata); 
+		if (owner)  
+			gsl_vector_free(data); 
+		cdata = data = d; 
+		owner = true; 
+	}
+	return *this; 
+}
+
+Vector::Vector(vector_type *holder):
+	data(holder), 
+	cdata(holder),
+	owner(false)
+{
+}
+
+Vector::Vector(const vector_type *holder):
+	data(NULL), 
+	cdata(holder),
+	owner(false)
+{
+}
+
+Vector::~Vector()
+{
+	if (owner) 
+		gsl_vector_free(data);
+}
+
+const Vector::vector_type * Vector::operator  ->() const
+{
+	return cdata; 
+}
+
+Vector::vector_type * Vector::operator  ->()
+{
+	return data; 
+}
+
+void Vector::print(std::ostream& os) const
+{
+	os << "["; 
+	std::copy(begin(), end(), std::ostream_iterator<double>(os, ", ")); 
+	os << "]"; 
+}
+
+Vector::operator Vector::vector_pointer_type ()
+{
+	return data; 
+}
+
+Vector::operator Vector::vector_const_pointer_type () const
+{
+	return cdata; 
+}
+
+Vector::iterator Vector::begin()
+{
+	assert(data); 
+	return vector_iterator(data->data, data->stride); 
+}
+
+Vector::iterator Vector::end()
+{
+	assert(data); 
+	return vector_iterator(data->data + data->size * data->stride, data->stride);
+}
+
+
+Vector::const_iterator Vector::begin()const
+{
+	assert(cdata); 
+	return const_vector_iterator(cdata->data, cdata->stride); 
+}
+
+
+Vector::const_iterator Vector::end()const
+{
+	assert(cdata); 
+	return const_vector_iterator(cdata->data + cdata->size * cdata->stride, cdata->stride); 
+}
+
+
+Vector::size_type Vector::size() const
+{
+	return this->cdata->size; 
+}
+
+extern "C" void gsl_error_handler (const char * reason, 
+				   const char * file, 
+				   int line, 
+				   int gsl_errno)
+{
+	switch (gsl_errno) {
+	case GSL_EBADLEN: 
+		throw mia::create_exception<std::logic_error>("GSL Error: '", reason,
+							      "' ", file, ":", line, ", Errno:");
+	default:
+		throw mia::create_exception<std::runtime_error>("GSL Error: '", reason,
+								"' ", file, ":", line, ", (Errno:", gsl_errno, ")");
+	}
+}
+
+class CSetGSLErrorHandler {
+public: 
+	CSetGSLErrorHandler();
+
+	~CSetGSLErrorHandler();
+private: 
+	gsl_error_handler_t *m_old_hander; 
+	
+}; 
+
+CSetGSLErrorHandler::CSetGSLErrorHandler()
+{
+	m_old_hander = gsl_set_error_handler(gsl_error_handler); 
+}
+
+CSetGSLErrorHandler::~CSetGSLErrorHandler()
+{
+	gsl_set_error_handler(m_old_hander);
+}
+
+
+#ifdef NDEBUG 
+	class CTurnOffErrorHandler {
+	public: 
+		CTurnOffErrorHandler(); 
+	}; 
+
+
+	CTurnOffErrorHandler::CTurnOffErrorHandler() 
+	{
+		gsl_set_error_handler_off (); 
+	}
+		
+	const CTurnOffErrorHandler gsl_turn_off_error_handler;
+#else
+CSetGSLErrorHandler replace_error_handler; 
+#endif 
+
+}
diff --git a/mia/core/gsl_vector.hh b/mia/core/gsl_vector.hh
new file mode 100644
index 0000000..5976f3b
--- /dev/null
+++ b/mia/core/gsl_vector.hh
@@ -0,0 +1,272 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 GSLPP_VECTOR_HH
+#define GSLPP_VECTOR_HH
+
+
+#include <iostream>
+#include <mia/core/gsl_defines.hh>
+#include <mia/core/gsl_iterator.hh>
+#include <gsl/gsl_vector.h>
+
+namespace gsl {
+
+/**
+    This is a wrapper class around the GSL vector type. It provides 
+    a compatibility layer to make it possible to use STL algorithms and constructs.
+    
+*/
+class  EXPORT_GSL Vector {
+
+public: 
+	typedef vector_iterator iterator; 
+	typedef const_vector_iterator const_iterator; 
+	typedef size_t size_type; 
+	typedef double value_type; 
+	typedef double& reference;
+	typedef const double& const_reference; 
+	typedef gsl_vector vector_type; 
+	typedef gsl_vector *vector_pointer_type; 
+	typedef const gsl_vector *vector_const_pointer_type; 
+	
+	/**
+	   Construct an empty vector without allocating the GSL data structures
+	 */
+	Vector();
+
+	/**
+	   Construct a vector of given size
+	   \param size 
+	   \param clear if set to \a true set all values to zero at allocation 
+	 */
+	Vector(size_type size, bool clear);
+
+
+	/**
+	   Construct a vector of given size and initialize it with the given data 
+	   \param size 
+	   \param init double array that must be at least of size \a size 
+	 */
+	Vector(size_type size, const double *init);
+
+	/**
+	   Wrap a pre-constructed GSL vector. The passed GSL-vector will not be destroyed 
+	   when the destructor is called. 
+	   The values of the GSL vector can be changed 
+	   \param holder the already allocated GSL vector 
+	   
+	*/
+	Vector(gsl_vector *holder); 
+	/**
+	   Wrap a pre-constructed GSL vector. The passed GSL-vector will not be destroyed 
+	   when the destructor is called. 
+	   The values of the GSL vector can \a not be changed 
+	   \param holder the already allocated GSL vector 
+	*/
+	Vector(const gsl_vector *holder); 
+
+	/**
+	   Copy constructor, does a deep copy of the internal data structures. 
+	 */
+	Vector(const Vector& other); 
+
+	/**
+	   Copy operator, does a deep copy of the internal data structures. 
+	 */
+	Vector& operator = (const Vector& other); 
+	
+	/// Destructor 
+	~Vector(); 
+	
+	/** \returns an STL compatible read-write iterator to the vector data 
+	    pointing to the beginning 
+	 */
+	iterator begin(); 
+
+	/** \returns an STL compatible read-write iterator to the vector data 
+	    pointing to the past end 
+	 */
+	iterator end(); 
+
+	/** \returns an STL compatible read-only iterator to the vector data 
+	    pointing to the beginning 
+	 */
+	const_iterator begin()const; 
+
+	/** \returns an STL compatible read-only iterator to the vector data 
+	    pointing to the past end 
+	 */
+	const_iterator end()const; 
+
+	/**
+	   \returns number of elements in the vector 
+	 */ 
+	size_type size() const; 
+
+	/**
+	   Element read only access operator 
+	   \param i 
+	   \returns value 
+	 */
+	value_type operator[](size_t i) const {
+	        assert(cdata); 
+		return cdata->data[i * cdata->stride]; 
+        }; 
+
+	/**
+	   Element read only access operator 
+	   \param i 
+	   \returns reference to value 
+	 */
+	reference operator[](size_t i) {
+		assert(data); 
+		return data->data[i * data->stride]; 
+	}
+
+	/// \returns transparent read-only access to underlying gsl_vector structure
+	const gsl_vector * operator  ->() const; 
+	
+	/// \returns transparent read-write access to underlying gsl_vector structure
+	gsl_vector * operator  ->(); 
+	
+        /// vector const pointer type operator  to enable transparent calls to the GSL APL
+	operator Vector::vector_const_pointer_type () const; 
+
+	/// vector pointer type operator  to enable transparent calls to the GSL APL
+	operator Vector::vector_pointer_type (); 
+	
+	/**
+	   Write the vector to a stream 
+	   \param os the output stream 
+	*/
+	void print(std::ostream& os) const;  
+
+protected:
+	
+	void reset_holder(gsl_vector *holder){
+		cdata = data = holder; 
+		owner = false; 
+	}
+	
+	void reset_holder(const gsl_vector *holder){
+		cdata = holder;
+		owner = false;  
+	}
+
+private: 
+	gsl_vector *data; 
+	const gsl_vector *cdata; 
+	bool owner; 
+}; 
+
+
+inline Vector operator + (const Vector& lhs, const Vector& rhs) 
+{
+	Vector result(lhs); 
+	gsl_vector_add(result, rhs); 
+	return result; 
+}
+
+inline Vector operator - (const Vector& lhs, const Vector& rhs) 
+{
+	Vector result(lhs); 
+	gsl_vector_sub(result, rhs); 
+	return result; 
+}
+
+inline Vector operator * (const Vector& lhs, double f) 
+{
+	Vector result(lhs); 
+	gsl_vector_scale(result, f); 
+	return result; 
+}
+
+/**
+   Wrapper for the gsl_vector_view providing transparent access 
+   to the underlying vector. 
+*/
+class EXPORT_GSL VectorView :public Vector {
+public: 
+	VectorView(gsl_vector_view vv): m_view(vv) 
+	{
+		reset_holder(&m_view.vector); 
+	}; 
+private: 
+	gsl_vector_view m_view; 
+}; 
+
+
+/**
+   Wrapper for the gsl_vector_const_view providing transparent access 
+   to the underlying vector. 
+*/
+class EXPORT_GSL ConstVectorView {
+public: 
+	ConstVectorView(gsl_vector_const_view vv):m_view(vv), 
+		m_holder(&m_view.vector)
+	{
+		
+	}; 
+	
+	Vector::const_iterator begin()const{
+		return m_holder.begin(); 
+	}
+		
+	Vector::const_iterator end()const{
+		return m_holder.end(); 
+	}
+	
+	Vector::size_type size() const {
+		return m_holder.size(); 
+	}
+	
+	double operator[](size_t i)const {
+		
+		return m_holder[i]; 
+	}; 
+
+	operator const Vector&(){
+		return m_holder; 
+	}
+		
+	const gsl_vector * operator  ->() const{
+		return m_holder.operator ->(); 
+	}
+	
+	operator Vector::vector_const_pointer_type () const {
+		return m_holder.operator Vector::vector_const_pointer_type(); 
+	}
+
+private: 
+	gsl_vector_const_view m_view; 
+	const Vector m_holder; 
+}; 
+
+inline std::ostream& operator << (std::ostream& os, const Vector& v) {
+	v.print(os); 
+	return os; 
+} 
+
+}
+
+#endif
+
+
diff --git a/gsl++/vector_dispatch.hh b/mia/core/gsl_vector_dispatch.hh
similarity index 96%
rename from gsl++/vector_dispatch.hh
rename to mia/core/gsl_vector_dispatch.hh
index be774db..788cf84 100644
--- a/gsl++/vector_dispatch.hh
+++ b/mia/core/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/mia/core/gsl_wavelet.cc
similarity index 96%
rename from gsl++/wavelet.cc
rename to mia/core/gsl_wavelet.cc
index 49b2873..e1345c9 100644
--- a/gsl++/wavelet.cc
+++ b/mia/core/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +20,9 @@
 
 #include <stdexcept>
 #include <iostream>
-#include <gsl++/wavelet.hh>
+#include <mia/core/gsl_wavelet.hh>
 #include <gsl/gsl_wavelet.h>
+#include <vector>
 
 using std::invalid_argument; 
 using std::vector; 
@@ -58,7 +59,7 @@ C1DWavelet::~C1DWavelet()
 
 std::vector<double> C1DWavelet::backward(const std::vector<double>& x) const
 {
-	return impl->forward(x); 
+	return impl->backward(x); 
 }
 
 std::vector<double> C1DWavelet::forward(const std::vector<double>& x) const
diff --git a/gsl++/wavelet.hh b/mia/core/gsl_wavelet.hh
similarity index 93%
rename from gsl++/wavelet.hh
rename to mia/core/gsl_wavelet.hh
index 6943a31..abb99d4 100644
--- a/gsl++/wavelet.hh
+++ b/mia/core/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
 #ifndef gslpp_wavelet_hh
 #define gslpp_wavelet_hh
 
-#include <gsl++/gsldefines.hh>
+#include <mia/core/gsl_defines.hh>
 #include <cstdlib>
 #include <vector>
 
diff --git a/mia/core/handler.cxx b/mia/core/handler.cxx
index 135fcb3..6ca3fc4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -310,19 +310,21 @@ T& THandlerSingleton<T>::do_instance(bool require_initialization)
 {
 	TRACE_FUNCTION; 
 	CScopedLock lock(m_creation_mutex); 
-	static THandlerSingleton<T> me; 
-	cvdebug() << "m_is_initialized = " << m_is_initialized << "\n"; 
-
-	if (!m_is_initialized && require_initialization) {
-		TRACE("Unitialized state"); 
-		CScopedLock lock_init(m_initialization_mutex);
+	static THandlerSingleton<T> me;
+	cvdebug() << "m_is_initialized = " << m_is_initialized << "\n";
+	
+	if (require_initialization) {
 		if (!m_is_initialized) {
-			TRACE("Enter locked unitialized state"); 
-			lock.release(); 
-			cvdebug() << "not yet initialized: second check passed\n"; 
-			me.initialise(m_searchpath);
-			m_is_initialized = true; 
-
+			TRACE("Unitialized state"); 
+			CScopedLock lock_init(m_initialization_mutex);
+			if (!m_is_initialized) {
+				TRACE("Enter locked unitialized state"); 
+				lock.release(); 
+				cvdebug() << "not yet initialized: second check passed\n"; 
+				me.initialise(m_searchpath);
+				m_is_initialized = true; 
+				
+			}
 		}
 	}
 	return me; 
@@ -345,10 +347,6 @@ void THandlerSingleton<T>::set_search_path(const CPluginSearchpath& searchpath)
 			 << ">::set_search_path: handler was already created\n"; 
 		
 	}
-#if 0 // work around the appearent icc bug, where the static member 
-      //variable is not initialised
-	::new (&m_searchpath) CPathNameArray; 
-#endif
 //	cvdebug() << "searchpath=" << searchpath << "\n"; 
 	m_searchpath = searchpath; 
 
@@ -362,7 +360,7 @@ template <typename T>
 bool THandlerSingleton<T>::m_is_created = false; 
 
 template <typename T>
-bool THandlerSingleton<T>::m_is_initialized = false; 
+std::atomic<bool> THandlerSingleton<T>::m_is_initialized(false); 
 
 template <typename T>
 CMutex THandlerSingleton<T>::m_creation_mutex; 
diff --git a/mia/core/handler.hh b/mia/core/handler.hh
index ae9cf20..4788ec0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,12 +26,14 @@
 #include <set>
 #include <vector>
 #include <ostream>
+#include <atomic>
 #include <boost/any.hpp>
 
 #include <mia/core/utils.hh>
 #include <mia/core/filetools.hh>
 
 #include <mia/core/defines.hh>
+#include <mia/core/parallel.hh>
 #include <mia/core/module.hh>
 #include <mia/core/plugin_base.hh>
 #include <mia/core/handlerbase.hh>
@@ -199,7 +201,7 @@ private:
 	static CPluginSearchpath m_searchpath; 
 	static bool m_is_created; 
 	static CMutex m_initialization_mutex;
-	static bool m_is_initialized; 
+	static std::atomic<bool> m_is_initialized; 
 	
 }; 
 
diff --git a/mia/core/handlerbase.cc b/mia/core/handlerbase.cc
index c2d6374..f689563 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/core/handlerbase.hh
index 9745633..b38a836 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/histogram.hh b/mia/core/histogram.hh
index d9c12ee..c13f8b4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -210,6 +210,12 @@ public:
 	/// \returns deviation of the histogram 
 	double deviation() const; 
 
+	/// \returns the excess kurtosis value of the histogram 
+	double excess_kurtosis() const; 
+
+	/// \returns the skewness value of the histogram 
+	double skewness() const; 
+
 	/**
 	   return the histogram range that cuts off the \a remove percent of pixels 
 	   from the lower ane upper end of the histogram 
@@ -404,6 +410,50 @@ double THistogram<Feeder>::average() const
 }
 
 template <typename Feeder> 
+double THistogram<Feeder>::excess_kurtosis() const
+{
+	double mu = average(); 
+	double sum1 = 0.0; 
+	double sum2 = 0.0; 
+	double sum3 = 0.0; 
+	
+	for (size_t i = 0; i < size(); ++i) {
+		const auto value = at(i); 
+		sum1 += value.first * value.second;
+		sum2 += value.first * value.first * value.second;
+		double h = (value.first - mu); 
+		h *= h; 
+		h *= h; 
+		sum3 +=  h * value.second;
+	}
+	
+	double sigma2 = (sum2 - sum1 * sum1 / m_n) / m_n; 
+	double mu4 = sum3 / m_n; 
+	return mu4 / (sigma2 * sigma2) - 3;
+}
+
+template <typename Feeder> 
+double THistogram<Feeder>::skewness() const
+{
+	double mu = average(); 
+	double sum1 = 0.0; 
+	double sum2 = 0.0; 
+	double sum3 = 0.0; 
+	
+	for (size_t i = 0; i < size(); ++i) {
+		const auto value = at(i); 
+		sum1 += value.first * value.second;
+		sum2 += value.first * value.first * value.second;
+		double h = (value.first - mu); 
+		sum3 +=  h * h * h * value.second;
+	}
+	
+	double sigma2 = (sum2 - sum1 * sum1 / m_n) / m_n; 
+	double mu4 = sum3 / m_n; 
+	return mu4 / (sigma2 * sqrt(sigma2)); 
+}
+
+template <typename Feeder> 
 double THistogram<Feeder>::deviation() const
 {
 	if (m_n < 2) 
diff --git a/mia/core/history.cc b/mia/core/history.cc
index e8ca6b1..e67a72b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1e4665a..9687593 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e45f2f7..20c8e76 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,64 +32,86 @@ NS_MIA_BEGIN
 
 using namespace std;
 
-struct CICAAnalysisImpl {
+struct CICAAnalysisITPPImpl {
 
-	CICAAnalysisImpl(size_t rows, size_t length);
-	CICAAnalysisImpl(const itpp::mat& ic, const itpp::mat& mix, const std::vector<float>& mean);
+	CICAAnalysisITPPImpl(unsigned int rows, unsigned int length);
+	CICAAnalysisITPPImpl(const itpp::mat& ic, const itpp::mat& mix, const std::vector<double>& mean);
 	void normalize_ICs();
-	void get_mixing_curve(size_t c, vector<float>& curve) const;
-	void set_mixing_series(size_t index, const std::vector<float>& series);
-	void check_set(const CICAAnalysis::IndexSet& s) const;
+	void get_mixing_curve(unsigned int c, vector<float>& curve) const;
+	void set_mixing_series(unsigned int index, const std::vector<float>& series);
+	void check_set(const CICAAnalysisITPP::IndexSet& s) const;
 	std::vector<float> normalize_Mix();
-	float max_selfcorrelation(int& row1, int &row2) const;
 
 	itpp::mat  m_Signal;
 	itpp::mat  m_ICs;
 	itpp::mat  m_Mix;
-	vector<float> m_mean;
+	vector<double> m_mean;
 
-	size_t m_ncomponents;
-	size_t m_nlength;
-	size_t m_rows;
+	unsigned int m_ncomponents;
+	unsigned int m_nlength;
+	unsigned int m_rows;
 
 	int m_max_iterations;
 	int m_approach; 
 };
 
 
-CICAAnalysis::CICAAnalysis(size_t rows, size_t length):
-	impl(new CICAAnalysisImpl(rows, length))
+CICAAnalysisITPP::CICAAnalysisITPP(const itpp::mat& ic, const itpp::mat& mix, const std::vector<double>& mean):
+	impl(new CICAAnalysisITPPImpl(ic, mix, mean))
 {
+
+}
+
+CICAAnalysisITPP::CICAAnalysisITPP():impl(nullptr)
+{
+
 }
 
-CICAAnalysis::CICAAnalysis(const itpp::mat& ic, const itpp::mat& mix, const std::vector<float>& mean):
-	impl(new CICAAnalysisImpl(ic, mix, mean))
+
+void CICAAnalysisITPP::initialize(unsigned int series_length, unsigned int slice_size)
 {
+	auto new_impl = new CICAAnalysisITPPImpl(series_length, slice_size);
+	swap(new_impl, impl);
 
+	if (new_impl)
+		delete new_impl;
 }
 
-CICAAnalysis::~CICAAnalysis()
+CICAAnalysisITPP::~CICAAnalysisITPP()
 {
 	delete impl;
 }
 
-void CICAAnalysis::set_row(int row, const itppvector&  buffer, double mean)
+void CICAAnalysisITPP::set_row_internal(unsigned row, const std::vector<double>&  buffer, double mean)
 {
 	TRACE_FUNCTION;
 	assert(impl);
-	assert(row < impl->m_Signal.rows());
-	assert(buffer.size() == impl->m_Signal.cols());
-	impl->m_Signal.set_row(row, buffer);
+	assert(row < static_cast<unsigned>(impl->m_Signal.rows()));
+	assert(buffer.size() == static_cast<unsigned>(impl->m_Signal.cols()));
+
+	itppvector buf(static_cast<signed>(buffer.size()));
+	for (auto i= 0; static_cast<unsigned>(i) < buffer.size(); ++i)
+		buf[i] = buffer[static_cast<unsigned>(i)];
+
+	impl->m_Signal.set_row(static_cast<signed>(row), buf);
 	impl->m_mean[row] = mean;
 	cvdebug() << "add row " << row << ", mean=" << mean << "\n";
 }
 
-void CICAAnalysis::set_approach(int approach)
+void CICAAnalysisITPP::set_approach(EApproach approach)
 {
-	impl->m_approach = approach;
+	switch (approach) {
+	case appr_defl: impl->m_approach = FICA_APPROACH_DEFL;
+		break;
+	case appr_symm: impl->m_approach = FICA_APPROACH_SYMM;
+		break;
+	default:
+		throw invalid_argument("CICAAnalysisITPP:set_approach: Unknown approach given");
+	}
+
 }
 
-bool CICAAnalysis::run(size_t nica, vector<vector<float> > guess)
+bool CICAAnalysisITPP::run(unsigned int nica, vector<vector<float> > guess)
 {
 	TRACE_FUNCTION;
 	assert(impl);
@@ -111,9 +133,9 @@ bool CICAAnalysis::run(size_t nica, vector<vector<float> > guess)
 		fastICA.set_max_num_iterations(impl->m_max_iterations);
 
 	if (!guess.empty()) {
-		itpp::mat mguess(impl->m_Signal.rows(), guess.size()); 
-		for (size_t c = 0; c < guess.size(); ++c) 
-			for (size_t r = 0; r < guess.size(); ++r) 
+		itpp::mat mguess(impl->m_Signal.rows(), static_cast<int>(guess.size()));
+		for (unsigned int c = 0; c < guess.size(); ++c)
+			for (unsigned int r = 0; r < guess.size(); ++r)
 				mguess(r,c) = guess[c][r]; 
 		fastICA.set_init_guess(mguess); 
 	}
@@ -135,92 +157,26 @@ bool CICAAnalysis::run(size_t nica, vector<vector<float> > guess)
 	return result; 
 }
 
-void CICAAnalysis::run_auto(int nica, int min_ica, float corr_thresh)
-{
-	TRACE_FUNCTION;
-	assert(impl);
-
-	std::unique_ptr<itpp::Fast_ICA > fastICA( new itpp::Fast_ICA(impl->m_Signal));
-
-	float corr = 1.0;
-	do {
-
-		cvinfo() << __func__ << ": run with " << nica << "\n";
-		fastICA->set_nrof_independent_components(nica);
-		fastICA->set_non_linearity(  FICA_NONLIN_TANH  );
-		fastICA->set_approach( FICA_APPROACH_DEFL );
-		fastICA->separate();
-
-		impl->m_ICs = fastICA->get_independent_components();
-		impl->m_Mix = fastICA->get_mixing_matrix();
-
-		impl->m_ncomponents = impl->m_Mix.cols();
-		impl->m_nlength     = impl->m_ICs.cols();
-		impl->m_rows        = impl->m_Mix.rows();
-
-		normalize_Mix();
-		normalize_ICs();
-
-		int row1 = -1;
-		int row2 = -1;
-
-		corr = 	impl->max_selfcorrelation(row1, row2);
-		cvinfo() << __func__ << ": R² = " << corr << ", n=" << nica << " @ " << impl->m_Mix.cols() << "\n";
-
-		if (fabs(corr) < corr_thresh)
-			break;
-
-		// copy old ICs to new guess if they don'z correspond to the most correlated mixes
-		itpp::mat guess;
-		size_t guess_rows = 0;
-		for (int i = 0; i < nica; ++i)
-			if (i != row1 && i != row2)
-				guess.ins_row(guess_rows++, impl->m_ICs.get_row(i));
-			else
-				cvinfo() << __func__ << ": skip row " << i << "\n";
-
-
-		// now combine the most correlated mixes
-		itppvector buffer(impl->m_ICs.cols());
-
-		if (corr < 0)
-			for (int i = 0; i < impl->m_ICs.cols(); ++i)
-				buffer[i] = (impl->m_ICs(row1, i) - impl->m_ICs(row2, i)) / 2.0;
-		else
-			for (int i = 0; i < impl->m_ICs.cols(); ++i)
-				buffer[i] = (impl->m_ICs(row1, i) + impl->m_ICs(row2, i)) / 2.0;
-		--nica;
-		guess.ins_row(guess_rows, buffer);
-		cvinfo() << "guess.rows()=" << guess.rows() << "\n";
-		assert(guess.rows() == nica);
-
-		fastICA.reset( new itpp::Fast_ICA(impl->m_Signal));
-		fastICA->set_init_guess(guess);
-
-	} while (nica > min_ica);
-
-}
-
-size_t CICAAnalysis::get_ncomponents() const
+unsigned int CICAAnalysisITPP::get_ncomponents() const
 {
 	return impl->m_ncomponents;
 }
 
-vector<float> CICAAnalysis::get_feature_row(size_t row) const
+vector<float> CICAAnalysisITPP::get_feature_row(unsigned int row) const
 {
 	TRACE_FUNCTION;
 	if (row < impl->m_ncomponents) {
 		vector<float> result(impl->m_nlength);
-		for (size_t i = 0; i < impl->m_nlength; ++i)
-			result[i] = impl->m_ICs(row, i);
+		for (unsigned int i = 0; i < impl->m_nlength; ++i)
+			result[i] = static_cast<float>(impl->m_ICs(row, i));
 		return result;
 	}
 
-	throw create_exception<invalid_argument>("CICAAnalysis::get_feature_row: requested row ", row, " out of range");
+	throw create_exception<invalid_argument>("CICAAnalysisITPP::get_feature_row: requested row ", row, " out of range");
 
 }
 
-std::vector<float> CICAAnalysis::get_mix_series(size_t colm)const
+std::vector<float> CICAAnalysisITPP::get_mix_series(unsigned int colm)const
 {
 	TRACE_FUNCTION;
 	if (colm < impl->m_ncomponents) {
@@ -228,16 +184,16 @@ std::vector<float> CICAAnalysis::get_mix_series(size_t colm)const
 		impl->get_mixing_curve(colm, result);
 		return result;
 	}
-	throw create_exception<invalid_argument>("CICAAnalysis::get_mix_series: requested series ", colm, " out of range");
+	throw create_exception<invalid_argument>("CICAAnalysisITPP::get_mix_series: requested series ", colm, " out of range");
 }
 
-void CICAAnalysis::set_mixing_series(size_t index, const std::vector<float>& filtered_series)
+void CICAAnalysisITPP::set_mixing_series(unsigned int index, const std::vector<float>& filtered_series)
 {
 	impl->set_mixing_series(index, filtered_series);
 }
 
 
-float correlation(const CICAAnalysis::itppvector& a, const CICAAnalysis::itppvector& b)
+float correlation(const CICAAnalysisITPP::itppvector& a, const CICAAnalysisITPP::itppvector& b)
 {
 	assert(a.size() > 0);
 	assert(a.size() == b.size());
@@ -258,76 +214,59 @@ float correlation(const CICAAnalysis::itppvector& a, const CICAAnalysis::itppvec
 	const float ssxy = sxy - sx * sy / a.size();
 	const float ssxx = sxx - sx * sx / a.size();
 	const float ssyy = syy - sy * sy / a.size();
-	if (sxx == 0 && syy == 0)
+	if (sxx < 1e-10 && syy < 1e-10 )
 		return 1.0;
 
-	if (sxx == 0 || syy == 0)
+	if (sxx < 1e-10 || syy < 1e-10 )
 		return 0.0;
 
 	return (ssxy * ssxy) /  (ssxx * ssyy);
 }
 
-float CICAAnalysisImpl::max_selfcorrelation(int& row1, int &row2) const
-{
-	float max_corr = 0.0;
-	for (int i = 0; i < m_Mix.cols(); ++i)
-		for (int j = i+1; j < m_Mix.cols(); ++j) {
-			const float corr = correlation(m_Mix.get_col(i), m_Mix.get_col(j));
-			if (fabs(max_corr) < fabs(corr)) {
-				row1 = i;
-				row2 = j;
-				max_corr = corr;
-				cvdebug() << "Corr=" << max_corr << " @ " << i << "," << j << "\n";
-			}
-		}
-	return max_corr;
-
-}
-
-void CICAAnalysisImpl::set_mixing_series(size_t index, const std::vector<float>& series)
+void CICAAnalysisITPPImpl::set_mixing_series(unsigned int index, const std::vector<float>& series)
 {
 	TRACE_FUNCTION;
 	assert(m_rows == series.size());
 	assert(index < m_nlength);
-	for (size_t i = 0; i < m_rows; ++i)
+	for (unsigned int i = 0; i < m_rows; ++i)
 		m_Mix(i, index) = series[i];
 
 }
 
 
-CSlopeColumns CICAAnalysis::get_mixing_curves() const
+CSlopeColumns CICAAnalysisITPP::get_mixing_curves() const
 {
 	TRACE_FUNCTION;
 	CSlopeColumns result(impl->m_ncomponents);
-	for (size_t c = 0; c < impl->m_ncomponents; ++c)
+	for (unsigned int c = 0; c < impl->m_ncomponents; ++c)
 		impl->get_mixing_curve(c, result[c]);
 	return result;
 }
 
-void CICAAnalysisImpl::get_mixing_curve(size_t c, vector<float>& curve) const
+void CICAAnalysisITPPImpl::get_mixing_curve(unsigned int c, vector<float>& curve) const
 {
 	TRACE_FUNCTION;
 	curve.resize(m_rows);
-	for (size_t i = 0; i < m_rows; ++i)
-		curve[i] = m_Mix(i, c);
+	for (unsigned int i = 0; i < m_rows; ++i)
+		curve[i] = static_cast<float>(m_Mix(i, c));
 }
 
-std::vector<float> CICAAnalysis::get_mix(size_t idx)const
+std::vector<float> CICAAnalysisITPP::get_mix(unsigned int idx)const
 {
 	TRACE_FUNCTION;
 	if (idx < impl->m_rows) {
-		vector<float> result(impl->m_nlength, impl->m_mean[idx]);
-		for (size_t i = 0; i < impl->m_nlength; ++i) {
-			for (size_t c = 0; c < impl->m_ncomponents; ++c)
+		vector<float> result(impl->m_nlength, static_cast<float>(impl->m_mean[idx]));
+		for (unsigned int i = 0; i < impl->m_nlength; ++i) {
+			for (unsigned int c = 0; c < impl->m_ncomponents; ++c)
 				result[i] += impl->m_ICs(c, i) *  impl->m_Mix(idx, c);
 		}
 		return result;
 	}
 
-	throw create_exception<invalid_argument>("CICAAnalysis::get_mix: requested idx ", idx, " out of range: ", impl->m_rows);
+	throw create_exception<invalid_argument>("CICAAnalysisITPP::get_mix: requested idx ", idx, " out of range: ", impl->m_rows);
 }
 
-std::vector<float> CICAAnalysis::get_delta_feature(const IndexSet& plus, const IndexSet& minus)const
+std::vector<float> CICAAnalysisITPP::get_delta_feature(const IndexSet& plus, const IndexSet& minus)const
 {
 	TRACE_FUNCTION;
 
@@ -335,7 +274,7 @@ std::vector<float> CICAAnalysis::get_delta_feature(const IndexSet& plus, const I
 	impl->check_set(plus);
 	impl->check_set(minus);
 
-	for (size_t i = 0; i < impl->m_nlength; ++i) {
+	for (unsigned int i = 0; i < impl->m_nlength; ++i) {
 		for (IndexSet::const_iterator c = plus.begin(); c != plus.end(); ++c)
 			result[i] += impl->m_ICs(*c, i);
 
@@ -346,17 +285,17 @@ std::vector<float> CICAAnalysis::get_delta_feature(const IndexSet& plus, const I
 	return result;
 }
 
-std::vector<float> CICAAnalysis::get_partial_mix(size_t idx, const IndexSet& cps)const
+std::vector<float> CICAAnalysisITPP::get_partial_mix(unsigned int idx, const IndexSet& cps)const
 {
 	TRACE_FUNCTION;
 	if (idx >=  impl->m_rows) {
-		throw create_exception<invalid_argument>("CICAAnalysis::get_mix: requested idx ", idx, 
-					       " out of range: ", impl->m_rows);
+		throw create_exception<invalid_argument>("CICAAnalysisITPP::get_mix: requested idx ", idx,
+							 " out of range: ", impl->m_rows);
 
 	} else {
 		impl->check_set(cps);
-		vector<float> result(impl->m_nlength, impl->m_mean[idx]);
-		for (size_t i = 0; i < impl->m_nlength; ++i) {
+		vector<float> result(impl->m_nlength, static_cast<float>(impl->m_mean[idx]));
+		for (unsigned int i = 0; i < impl->m_nlength; ++i) {
 			for (IndexSet::const_iterator c = cps.begin(); c != cps.end(); ++c)
 				result[i] += impl->m_ICs(*c, i) *  impl->m_Mix(idx, *c);
 		}
@@ -364,29 +303,29 @@ std::vector<float> CICAAnalysis::get_partial_mix(size_t idx, const IndexSet& cps
 	}
 }
 
-std::vector<float> CICAAnalysis::get_incomplete_mix(size_t idx, const std::set<size_t>& skip)const
+std::vector<float> CICAAnalysisITPP::get_incomplete_mix(unsigned int idx, const std::set<unsigned int>& skip)const
 {
 	TRACE_FUNCTION;
 	if (idx < impl->m_rows) {
-		vector<float> result(impl->m_nlength, impl->m_mean[idx]);
-		for (size_t i = 0; i < impl->m_nlength; ++i) {
-			for (size_t c = 0; c < impl->m_ncomponents; ++c)
+		vector<float> result(impl->m_nlength, static_cast<float>(impl->m_mean[idx]));
+		for (unsigned int i = 0; i < impl->m_nlength; ++i) {
+			for (unsigned int c = 0; c < impl->m_ncomponents; ++c)
 				if (skip.find(c) == skip.end())
 					result[i] += impl->m_ICs(c, i) *  impl->m_Mix(idx, c);
 		}
 		return result;
 	}
 
-	throw create_exception<invalid_argument>("CICAAnalysis::get_mix: requested idx ", idx, 
-				       " out of range: ", impl->m_rows);
+	throw create_exception<invalid_argument>("CICAAnalysisITPP::get_mix: requested idx ", idx,
+						 " out of range: ", impl->m_rows);
 }
 
-std::vector<float> CICAAnalysis::normalize_Mix()
+std::vector<float> CICAAnalysisITPP::normalize_Mix()
 {
 	return impl->normalize_Mix();
 }
 
-CICAAnalysisImpl::CICAAnalysisImpl(size_t rows, size_t length):
+CICAAnalysisITPPImpl::CICAAnalysisITPPImpl(unsigned int rows, unsigned int length):
 	m_Signal(rows, length),
 	m_mean(rows),
 	m_ncomponents(0),
@@ -398,10 +337,11 @@ CICAAnalysisImpl::CICAAnalysisImpl(size_t rows, size_t length):
 	cvdebug() << "Analyis of signal with " << rows << " data rows of " << length << " entries\n";
 }
 
-CICAAnalysisImpl::CICAAnalysisImpl(const itpp::mat& ic, const itpp::mat& mix, const std::vector<float>& mean):
+CICAAnalysisITPPImpl::CICAAnalysisITPPImpl(const itpp::mat& ic, const itpp::mat& mix, const std::vector<double>& mean):
 	// Coverty may complain here, but the order is correct
 	// the signal is a matrix of the number of columns of the mixing matrix = time points 
 	// by rows of the independent components - each row constitutes th epixel ogf a feature image
+	// coverity[swapped_arguments]
 	m_Signal(mix.cols(), ic.rows()),
 	m_ICs(ic),
 	m_Mix(mix),
@@ -415,38 +355,38 @@ CICAAnalysisImpl::CICAAnalysisImpl(const itpp::mat& ic, const itpp::mat& mix, co
 	TRACE_FUNCTION;
 }
 
-void CICAAnalysis::normalize_ICs()
+void CICAAnalysisITPP::normalize_ICs()
 {
 	TRACE_FUNCTION;
 	impl->normalize_ICs();
 }
 
-void CICAAnalysisImpl::check_set(const CICAAnalysis::IndexSet& s) const
+void CICAAnalysisITPPImpl::check_set(const CICAAnalysisITPP::IndexSet& s) const
 {
-	for (CICAAnalysis::IndexSet::const_iterator is = s.begin();
+	for (CICAAnalysisITPP::IndexSet::const_iterator is = s.begin();
 	     is != s.end(); ++is) {
 		if (*is >= m_ncomponents) {
-			throw create_exception<invalid_argument>("CICAAnalysis: request component index ",  *is , 
-						       " but only up to index ", m_ncomponents - 1, 
-						       " available\n");
+			throw create_exception<invalid_argument>("CICAAnalysisITPP: request component index ",  *is ,
+								 " but only up to index ", m_ncomponents - 1, 
+								 " available\n");
 		}
 	}
 }
 
-void CICAAnalysisImpl::normalize_ICs()
+void CICAAnalysisITPPImpl::normalize_ICs()
 {
 #if 1
 	if (m_nlength < 2) 
 		throw invalid_argument("ICAAnalysis: input should have at least two pixels"); 
 
 	// scale all ICs to have a variance of 1.0 
-	for (size_t c = 0; c < m_ncomponents; ++c) {
+	for (unsigned int c = 0; c < m_ncomponents; ++c) {
 		// evaluate range of IC
 		double v = m_ICs(c, 0);
 	
 		double sum = v; 
 		double sum2 = v * v;
-		for (size_t k = 1; k < m_nlength; ++k) {
+		for (unsigned int k = 1; k < m_nlength; ++k) {
 			const double v = m_ICs(c, k);
 			sum += v;
 			sum2 += v * v;
@@ -466,10 +406,10 @@ void CICAAnalysisImpl::normalize_ICs()
 			const double ic_factor = invert * 2.0 / sigma;
 			const double mix_factor = 1.0 / ic_factor;
 			
-			for (size_t k = 0; k < m_nlength; ++k)
+			for (unsigned int k = 0; k < m_nlength; ++k)
 				m_ICs(c, k) = (m_ICs(c, k) - ic_shift) * ic_factor;
 			
-			for (size_t r = 0; r < m_rows; ++r) {
+			for (unsigned int r = 0; r < m_rows; ++r) {
 				m_mean[r] += m_Mix(r, c) * ic_shift;
 				m_Mix(r, c) *= mix_factor;
 			}
@@ -478,13 +418,13 @@ void CICAAnalysisImpl::normalize_ICs()
 	
 #else 
 	// scale all ICs to have a range of 2.0 and are shifted to the mean
-	for (size_t c = 0; c < m_ncomponents; ++c) {
+	for (unsigned int c = 0; c < m_ncomponents; ++c) {
 		// evaluate range of IC
 		double min_val = m_ICs(c, 0);
 		double max_val = m_ICs(c, 0);
 
 		double sum = m_ICs(c, 0);
-		for (size_t k = 0; k < m_nlength; ++k) {
+		for (unsigned int k = 0; k < m_nlength; ++k) {
 			const double v = m_ICs(c, k);
 			if (min_val > v)
 				min_val = v;
@@ -509,10 +449,10 @@ void CICAAnalysisImpl::normalize_ICs()
 
 		const double ic_shift = sum / m_nlength;
 
-		for (size_t k = 0; k < m_nlength; ++k)
+		for (unsigned int k = 0; k < m_nlength; ++k)
 			m_ICs(c, k) = (m_ICs(c, k) - ic_shift) * ic_factor;
 
-		for (size_t r = 0; r < m_rows; ++r) {
+		for (unsigned int r = 0; r < m_rows; ++r) {
 			m_mean[r] += m_Mix(r, c) * ic_shift;
 			m_Mix(r, c) *= mix_factor;
 		}
@@ -520,27 +460,27 @@ void CICAAnalysisImpl::normalize_ICs()
 #endif 
 }
 
-std::vector<float> CICAAnalysisImpl::normalize_Mix()
+std::vector<float> CICAAnalysisITPPImpl::normalize_Mix()
 {
 	std::vector<float> result(m_nlength,0.0f);
 
-	for (size_t c = 0; c < m_ncomponents; ++c) {
+	for (unsigned int c = 0; c < m_ncomponents; ++c) {
 		float mean = 0.0f;
-		for (size_t r = 0; r < m_rows; ++r)
+		for (unsigned int r = 0; r < m_rows; ++r)
 			mean += m_Mix(r, c);
 		mean /= m_rows;
-		for (size_t r = 0; r < m_rows; ++r)
+		for (unsigned int r = 0; r < m_rows; ++r)
 			m_Mix(r, c) -= mean;
 
-		for (size_t k = 0; k < m_nlength; ++k)
+		for (unsigned int k = 0; k < m_nlength; ++k)
 			result[k] += mean * m_ICs(c, k);
 	}
-	for (size_t c = 0; c < m_ncomponents; ++c) {
+	for (unsigned int c = 0; c < m_ncomponents; ++c) {
 		// invert sign so that all mixing curves start with a value < 0 
 		if (m_Mix(0, c) > 0) {
-			for (size_t r = 0; r < m_rows; ++r)
+			for (unsigned int r = 0; r < m_rows; ++r)
 				m_Mix(r, c) *= -1;
-			for (size_t k = 0; k < m_nlength; ++k)
+			for (unsigned int k = 0; k < m_nlength; ++k)
 				m_ICs(c, k) *= -1; 
 		}
 	}
@@ -549,9 +489,14 @@ std::vector<float> CICAAnalysisImpl::normalize_Mix()
 }
 
 
-void CICAAnalysis::set_max_iterations(int n)
+void CICAAnalysisITPP::set_max_iterations(int n)
 {
 	impl->m_max_iterations = n;
 }
 
+PICAAnalysis CICAAnalysisITPPFactory::create() const
+{
+	return PICAAnalysis(new CICAAnalysisITPP);
+}
+
 NS_MIA_END
diff --git a/mia/core/ica.hh b/mia/core/ica.hh
index 16e25b8..fa089b9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +23,12 @@
 
 #include <set>
 #include <vector>
+#include <itpp/signal/fastica.h>
+
 #include <mia/core/defines.hh>
 #include <mia/core/slopevector.hh>
-#include <itpp/signal/fastica.h>
+#include <mia/core/icaanalysisbase.hh>
+
 #include <boost/concept/requires.hpp>
 #include <boost/concept_check.hpp>
 
@@ -38,77 +41,58 @@ NS_MIA_BEGIN
    This class implements basic operations for of ICA. It makes use of the ITPP implementation of FastICA.
 */
 
-class  EXPORT_CORE CICAAnalysis {
+class  EXPORT_CORE CICAAnalysisITPP : public CICAAnalysis {
 public:
+	typedef CICAAnalysis::IndexSet IndexSet; 
+	
 
-	/// The type of a vector as used by IT++
+        /// The type of a vector as used by IT++
 	typedef itpp::Vec<itpp::mat::value_type> itppvector;
 	/**
-	   Initialize an ICA based of predefined data - this is unly used for test cases.
-	 */
-	CICAAnalysis(const itpp::mat& ic, const itpp::mat& mix, const std::vector<float>& mean );
-
+	   Initialize an ICA based of predefined data - this is only used for test cases.
+	*/
+	CICAAnalysisITPP(const itpp::mat& ic, const itpp::mat& mix, const std::vector<double>& mean );
+	
+
+	CICAAnalysisITPP();
+	
+	
+	~CICAAnalysisITPP();
+	
 	/**
-	   Main constructor of the ICA, i.e. you want to use this.
+	   Initialize the ICA
 	   \param series_length number of data sets that will be provided
 	   \param slice_size number of elements each set containes
-	 */
-	CICAAnalysis(size_t series_length, size_t slice_size);
-
-
-	~CICAAnalysis();
-
-
-	/// defines a set of indices used for mixing
-	typedef std::set<size_t> IndexSet;
-
-	/**
-	   Set on row of input data
-	   \tparam Iterator input data iterator, must follow the model of a forward iterator
-	   \param row index of the input slice
-	   \param begin start iterator of input data
-	   \param end end iterator of input data
-	 */
-	template <class Iterator>
-	BOOST_CONCEPT_REQUIRES(((::boost::ForwardIterator<Iterator>)),
-			       (void))
-		set_row(size_t row, Iterator begin, Iterator end);
-
-
+	*/
+	
+	void initialize(unsigned int series_length, unsigned int slice_size);
+	
+	
 	/**
 	   Run the independed component analysis using the given numbers of components
 	   \param nica number of indentepended components
 	   \param guess initial guess for the ICA, pass an empty vector of you 
 	   don't want to use this feature  
-	 */
-	bool run(size_t nica, std::vector<std::vector<float> > guess); 
-
-        /**
-	   Run the independed component analysis with an estimation of the optimal number
-	   of components. (experimental) 
-	   \param max_ica maximum number of independend components
-	   \param min_ica minimum number of independend components
-	   \param corr_thresh minimum absolute correation of the mixing signals to joins two components
 	*/
-	void run_auto(int max_ica, int min_ica, float corr_thresh=0.9);
-
+	bool run(unsigned int nica, std::vector<std::vector<float> > guess);
+	
 
 	/// \returns the feature vector of \a row
-	std::vector<float> get_feature_row(size_t row)const;
-
+	std::vector<float> get_feature_row(unsigned int row)const;
+	
 	/// \returns the mixing signal curve of the feature \a row
-	std::vector<float> get_mix_series(size_t row)const;
-
+	std::vector<float> get_mix_series(unsigned int row)const;
+	
 	/// \returns the complete mixed signal at series index \a idx
-	std::vector<float> get_mix(size_t idx)const;
-
+	std::vector<float> get_mix(unsigned int idx)const;
+	
 	/** Evaluate an incomplete mixed signal. Here the features are given that are \a not to be used.
 	    \sa get_partial_mix
 	    \param idx series index
 	    \param skip a set of feature indices that will be skipped when evaluating the mix
 	    \returns the mixed signal
 	*/
-	std::vector<float> get_incomplete_mix(size_t idx, const IndexSet& skip)const;
+	std::vector<float> get_incomplete_mix(unsigned int idx, const IndexSet& skip)const;
 
 	/** Evaluate an incomplete mixed signal. Here the features are given that are \a used to create the mix.
 	    \sa get_incomplete_mix
@@ -116,25 +100,25 @@ public:
 	    \param use the set of feature indices that will be used to evaluate the mix
 	    \returns an incolmplete mixed signal.
 	*/
-	std::vector<float> get_partial_mix(size_t idx, const IndexSet& use)const;
-
+	std::vector<float> get_partial_mix(unsigned int idx, const IndexSet& use)const;
+	
 	/** Evaluate a mix of the feature signals by adding and subtractig individual features.
 	    \param plus features o be added
 	    \param minus features to be subtracted
 	    \returns the feature mix
-	 */
+	*/
 	std::vector<float> get_delta_feature(const IndexSet& plus, const IndexSet& minus)const;
-
+	
 	/**
 	   Replace a mixing signal curve
 	   \param index of the curve to be replaced
 	   \param series new data for mixing curve
 	 */
-	void set_mixing_series(size_t index, const std::vector<float>& series);
-
+	void set_mixing_series(unsigned int index, const std::vector<float>& series);
+	
 	/// \returns a vector containing all mixing curves
 	CSlopeColumns   get_mixing_curves() const;
-
+	
 	/**
 	   Normalize the ICs in the following manner:
 	   * Scale and shift the range of the ICs to  [-1, 1]
@@ -152,45 +136,33 @@ public:
 
 
 	/// \returns the number of actual ICs
-	size_t get_ncomponents() const;
-
+	unsigned int get_ncomponents() const;
+	
 	/**
 	   sets the number of iterations in the ICA
 	   \param n
 	 */
 	void set_max_iterations(int n);
-
+	
 	/**
 	   Set the ICA approach to either FICA_APPROACH_DEFL(default) or FICA_APPROACH_SYMM. 
 	   \param approach
-	 */
-	void set_approach(int approach); 
+	*/
+	void set_approach(EApproach approach);
 private:
-	void set_row(int row, const itppvector&  buffer, double mean);
+	void set_row_internal(unsigned row, const std::vector<double>&  buffer, double mean);
+	
+	struct CICAAnalysisITPPImpl *impl;
+	
+};
 
-	struct CICAAnalysisImpl *impl;
 
+class EXPORT_CORE CICAAnalysisITPPFactory: public CICAAnalysisFactory {
+public:
+	PICAAnalysis create() const;
 };
 
-/// \cond DOXYGEN_DOESNT_UNDERSTAND_BOOST_CONCEPT_REQUIRES
-template <class Iterator>
-BOOST_CONCEPT_REQUIRES(((::boost::ForwardIterator<Iterator>)),
-		       (void))
-CICAAnalysis::set_row(size_t row, Iterator begin, Iterator end)
-{
-	const size_t length = std::distance(begin, end);
-	itppvector buffer(length);
-	size_t idx = 0;
-	double mean = 0.0;
-
-	while (begin != end)
-		mean += (buffer[idx++] = *begin++);
-	mean /= length;
-	for(size_t i = 0; i < length; ++i)
-		buffer[i] -= mean;
-	set_row(row, buffer, mean);
-}
-/// \endcond 
+typedef std::shared_ptr<CICAAnalysisITPPFactory> PICAAnalysisITPPFactory;
 
 NS_MIA_END
 
diff --git a/mia/core/ica_template.cxx b/mia/core/ica_template.cxx
index ef9d9fb..fa3a942 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,42 +27,50 @@
 #include <limits>
 #include <numeric>
 #include <mia/core/ica_template.hh>
+#include <mia/core/msgstream.hh>
 
 NS_MIA_BEGIN
 
-template <class Data> 
-TDataSeriesICA<Data>::TDataSeriesICA(const std::vector<Data>& initializer, bool strip_mean):
-	m_analysis(initializer.size(), initializer.empty() ? 0 : initializer[0].size())
+template <class Data>
+TDataSeriesICA<Data>::TDataSeriesICA(const CICAAnalysisFactory& icatool, const std::vector<Data>& initializer,
+                                     bool strip_mean):
+        m_analysis(icatool.create())
 {
-	TRACE_FUNCTION; 
-	if (initializer.empty())
-		throw std::invalid_argument("TDataSeriesICA: empty series not supported");
-
-	m_size = initializer[0].get_size(); 
-	m_mean = Data(m_size); 
-
-	if (strip_mean) {
-		for(size_t i = 0; i < initializer.size(); ++i) {
-			std::transform(initializer[i].begin(), initializer[i].end(),
-				       m_mean.begin(), m_mean.begin(), 
-				       [](float x, float y){return x+y;});
-		}
-		float scale = 1.0f / initializer.size();
-		std::transform(m_mean.begin(), m_mean.end(), m_mean.begin(),
-			       [&scale](float x){return x * scale;});
-
-		std::vector<float> help(initializer[0].size());
-		for(size_t i = 0; i < initializer.size(); ++i) {
-			std::transform(initializer[i].begin(), initializer[i].end(),
-				       m_mean.begin(), help.begin(), 
-				       [](float x, float y){return  x - y;});
-			m_analysis.set_row(i, help.begin(), help.end());
-		}
-	}else
-		for(size_t i = 0; i < initializer.size(); ++i)
-			m_analysis.set_row(i, initializer[i].begin(), initializer[i].end());
+        TRACE_FUNCTION;
+
+        if (initializer.empty())
+                throw std::invalid_argument("TDataSeriesICA: empty series not supported");
+
+        m_size =initializer[0].get_size();
+
+        m_analysis->initialize(initializer.size(), initializer[0].size());
+
+        m_mean = Data(m_size);
+
+        if (strip_mean) {
+                for(size_t i = 0; i < initializer.size(); ++i) {
+                        std::transform(initializer[i].begin(), initializer[i].end(),
+                                       m_mean.begin(), m_mean.begin(),
+                                       [](float x, float y){return x+y;});
+                }
+                float scale = 1.0f / initializer.size();
+                std::transform(m_mean.begin(), m_mean.end(), m_mean.begin(),
+                               [&scale](float x){return x * scale;});
+
+                std::vector<double> help(initializer[0].size());
+                for(size_t i = 0; i < initializer.size(); ++i) {
+                        std::transform(initializer[i].begin(), initializer[i].end(),
+                                       m_mean.begin(), help.begin(),
+                                       [](float x, float y){return  x - y;});
+                        m_analysis->set_row(i, help.begin(), help.end());
+                }
+        }else
+                for(size_t i = 0; i < initializer.size(); ++i)
+                        m_analysis->set_row(i, initializer[i].begin(), initializer[i].end());
+
 }
 
+
 template <class Data> 
 TDataSeriesICA<Data>::~TDataSeriesICA()
 {
@@ -73,7 +81,7 @@ bool TDataSeriesICA<Data>::run(size_t ncomponents, bool strip_mean, bool ica_nor
 			       std::vector<std::vector<float> >  guess )
 {
 	TRACE_FUNCTION; 
-	bool result = m_analysis.run(ncomponents, guess);
+        bool result = m_analysis->run(ncomponents, guess);
 	if (result) {
 		if (strip_mean)
 			this->normalize_Mix();
@@ -93,7 +101,7 @@ template <class Data>
 Data TDataSeriesICA<Data>::get_mix(size_t idx) const
 {
 	TRACE_FUNCTION; 
-	std::vector<float> mix = m_analysis.get_mix(idx);
+        std::vector<float> mix = m_analysis->get_mix(idx);
 	Data result(m_size);
 	assert( result.size() == mix.size());
 	std::transform(mix.begin(), mix.end(), m_mean.begin(), result.begin(), 
@@ -105,7 +113,7 @@ template <class Data>
 Data TDataSeriesICA<Data>::get_incomplete_mix(size_t idx, const IndexSet& skip) const
 {
 	TRACE_FUNCTION; 
-	std::vector<float> mix = m_analysis.get_incomplete_mix(idx, skip);
+        std::vector<float> mix = m_analysis->get_incomplete_mix(idx, skip);
 	Data result(m_size);
 	assert( result.size() == mix.size());
 	std::transform(mix.begin(), mix.end(), m_mean.begin(), result.begin(), 
@@ -117,7 +125,7 @@ template <class Data>
 Data TDataSeriesICA<Data>::get_partial_mix(size_t idx, const IndexSet& comps) const
 {
 	TRACE_FUNCTION; 
-	std::vector<float> mix = m_analysis.get_partial_mix(idx, comps);
+        std::vector<float> mix = m_analysis->get_partial_mix(idx, comps);
 	Data result(m_size);
 	assert( result.size() == mix.size());
 	std::transform(mix.begin(), mix.end(), m_mean.begin(), result.begin(), 
@@ -129,15 +137,23 @@ template <class Data>
 CSlopeColumns TDataSeriesICA<Data>::get_mixing_curves() const
 {
 	TRACE_FUNCTION; 
-	return m_analysis.get_mixing_curves();
+        return m_analysis->get_mixing_curves();
 }
 
+template <class Data>
+std::vector<float> TDataSeriesICA<Data>::get_mixing_curve(unsigned idx) const
+{
+	TRACE_FUNCTION; 
+        return m_analysis->get_mix_series(idx);
+}
+	
+
 template <class Data> 
 typename TDataSeriesICA<Data>::PData TDataSeriesICA<Data>::get_feature_image(size_t idx) const 
 {
 	Data *result = new Data(m_size); 
 	PData presult(result); 
-	const std::vector<float> feature = m_analysis.get_feature_row(idx); 
+        const std::vector<float> feature = m_analysis->get_feature_row(idx);
 	std::copy(feature.begin(), feature.end(), result->begin()); 
 	return presult; 
 }
@@ -147,7 +163,7 @@ typename TDataSeriesICA<Data>::PData TDataSeriesICA<Data>::get_delta_feature(con
 {
 	Data *result = new Data(m_size); 
 	PData presult(result); 
-	const std::vector<float> feature = m_analysis.get_delta_feature(plus, minus); 
+        const std::vector<float> feature = m_analysis->get_delta_feature(plus, minus);
 	std::copy(feature.begin(), feature.end(), result->begin()); 
 	return presult; 
 }
@@ -155,41 +171,33 @@ typename TDataSeriesICA<Data>::PData TDataSeriesICA<Data>::get_delta_feature(con
 template <class Data> 
 void TDataSeriesICA<Data>::set_mixing_series(size_t index, const std::vector<float>& filtered_series)
 {
-	m_analysis.set_mixing_series(index, filtered_series); 
+        m_analysis->set_mixing_series(index, filtered_series);
 }
 
 template <class Data> 
 void TDataSeriesICA<Data>::normalize()
 {
-	m_analysis.normalize_ICs(); 
+        m_analysis->normalize_ICs();
 }
 
 template <class Data> 
 void  TDataSeriesICA<Data>::normalize_Mix()
 {
-	std::vector<float> mean = m_analysis.normalize_Mix(); 
+        std::vector<float> mean = m_analysis->normalize_Mix();
 	transform(m_mean.begin(), m_mean.end(), mean.begin(), m_mean.begin(), 
 		  [](float x, float y){return x+y;}); 
 }
 
 template <class Data> 
-size_t TDataSeriesICA<Data>::run_auto(int nica, int min_ica, float corr_thresh)
-{
-	m_analysis.run_auto(nica, min_ica, corr_thresh); 
-	return m_analysis.get_ncomponents(); 
-}
-
-
-template <class Data> 
 void TDataSeriesICA<Data>::set_max_iterations(int n)
 {
-	m_analysis.set_max_iterations(n); 
+        m_analysis->set_max_iterations(n);
 }
 
 template <class Data> 
-void TDataSeriesICA<Data>::set_approach(int approach)
+void TDataSeriesICA<Data>::set_approach(CICAAnalysis::EApproach approach)
 {
-	m_analysis.set_approach(approach); 
+        m_analysis->set_approach(approach);
 }
 
 NS_MIA_END
diff --git a/mia/core/ica_template.hh b/mia/core/ica_template.hh
index 5c82724..6f40b04 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +21,10 @@
 #ifndef mia_core_ica_template_hh
 #define mia_core_ica_template_hh
 
-#include <mia/core/ica.hh>
+#include <mia/core/icaanalysisbase.hh>
 #include <vector>
 
+
 #ifndef EXPORT_TDataSeriesICA
 #ifdef WIN32
 #  define EXPORT_TDataSeriesICA __declspec(dllimport)
@@ -61,7 +62,7 @@ class  EXPORT_TDataSeriesICA TDataSeriesICA {
 public:
 	/** a set of indices used for addressing a subset of the independend componsts 
 	 */
-	typedef CICAAnalysis::IndexSet IndexSet;
+        typedef CICAAnalysis::IndexSet IndexSet;
 
 	/** a (shared) pointer to itself */
 	typedef typename Data::Pointer PData; 
@@ -70,10 +71,13 @@ public:
 	   \brief ICA initialization 
 	   
 	   The contructor for an ICA
+           \param icatool tool used for the ICA analysis
 	   \param initializer data set containing all the time steps of input data 
 	   \param strip_mean strip the mean from the series before processing 
 	 */
-	TDataSeriesICA(const std::vector<Data>& initializer, bool strip_mean);
+
+
+        TDataSeriesICA(const CICAAnalysisFactory&  icatool, const std::vector<Data>& initializer, bool strip_mean);
 	
 	/**  Runs the ICA 
 	     \param ncomponents retained components 
@@ -85,15 +89,6 @@ public:
 		 std::vector<std::vector<float> >  guess = std::vector<std::vector<float> >());
 
 
-        /**
-	   Run the independed component analysis with an estimation of the optimal number
-	   of components based on mixing curve correlation (experimental) 
-	   \param max_ica maximum number of independend components
-	   \param min_ica minimum number of independend components
-	   \param corr_thresh minimum absolute correation of the mixing signals to joins two components
-	   \returns number of obtained independend components
-	*/
-	size_t run_auto(int max_ica, int min_ica, float corr_thresh); 
 	
 	/** Normalizes the ICs to the range of [-1,1] and correct the mixing matrix accordingly. 
 	    This operation does not change the output of a mix. 
@@ -131,6 +126,14 @@ public:
 	/// \returns the mixing curves as vector of vectors
 	CSlopeColumns get_mixing_curves() const;
 
+	/**
+	   Obtain a specific mixing curve
+	   \param idx: index of requested curve, throws invalid_argument if index is out of bounds 
+	   \returns a mixing curve
+	   
+	*/
+	std::vector<float> get_mixing_curve(unsigned idx) const;
+
 	/// \returns the feature data relating to component \a idx
 	PData get_feature_image(size_t idx) const; 
 
@@ -160,12 +163,12 @@ public:
 	   Set the ICA approach to either FICA_APPROACH_DEFL(default) or FICA_APPROACH_SYMM. 
 	   \param approach
 	 */
-	void set_approach(int approach); 
+        void set_approach(CICAAnalysis::EApproach approach);
 	
 
 	~TDataSeriesICA();
 private:
-	CICAAnalysis m_analysis;
+        PICAAnalysis m_analysis;
 	typedef typename Data::dimsize_type dimsize_type; 
 	dimsize_type m_size;
 	Data m_mean;
diff --git a/mia/core/shape.cc b/mia/core/icaanalysisbase.cc
similarity index 78%
copy from mia/core/shape.cc
copy to mia/core/icaanalysisbase.cc
index 9e3e639..4392080 100644
--- a/mia/core/shape.cc
+++ b/mia/core/icaanalysisbase.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
- * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * This file is part of MIA - a toolbox for medical image analysis
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,19 @@
  *
  */
 
-#include <mia/core/shape.hh>
 
-NS_MIA_BEGIN
+#include <mia/core/icaanalysisbase.hh>
 
-const char * shape_type::type_descr = "shape";
+namespace  mia {
 
-NS_MIA_END
+CICAAnalysis::~CICAAnalysis()
+{
 
+}
 
+CICAAnalysisFactory::~CICAAnalysisFactory()
+{
 
+}
 
+}
diff --git a/mia/core/icaanalysisbase.hh b/mia/core/icaanalysisbase.hh
new file mode 100644
index 0000000..20cac95
--- /dev/null
+++ b/mia/core/icaanalysisbase.hh
@@ -0,0 +1,189 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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_ICAANALYSISBASE_HH
+#define mia_core_ICAANALYSISBASE_HH
+
+#include <memory>
+#include <set>
+#include <boost/concept/requires.hpp>
+#include <boost/concept_check.hpp>
+
+#include <mia/core/defines.hh>
+#include <mia/core/slopevector.hh>
+
+
+namespace mia {
+
+class EXPORT_CORE CICAAnalysis
+{
+public:
+
+    /**
+       Separation approach to be used.
+     */
+    enum EApproach {
+        appr_defl, /**< Deflation approach - each component is extimated separately */
+        appr_symm,  /**< Symmetric approach thet estimates all components at the same time */
+        appr_unknown
+    };
+
+    typedef std::unique_ptr<CICAAnalysis> Pointer;
+
+    /// defines a set of indices used for mixing
+    typedef std::set<unsigned int> IndexSet;
+
+    virtual ~CICAAnalysis();
+
+    /**
+       Set on row of input data
+       \tparam Iterator input data iterator, must follow the model of a forward iterator
+       \param row index of the input slice
+       \param begin start iterator of input data
+       \param end end iterator of input data
+     */
+    template <class Iterator>
+    BOOST_CONCEPT_REQUIRES(((::boost::ForwardIterator<Iterator>)),
+                           (void))
+    set_row(unsigned row, Iterator begin, Iterator end);
+
+
+    virtual void initialize(unsigned int series_length, unsigned int slice_size) = 0;
+    /**
+       Run the independed component analysis using the given numbers of components
+       \param nica number of indentepended components
+       \param guess initial guess for the ICA, pass an empty vector of you
+       don't want to use this feature
+     */
+    virtual bool run(unsigned int nica, std::vector<std::vector<float> > guess) = 0;
+
+    /// \returns the feature vector of \a row
+    virtual std::vector<float> get_feature_row(unsigned int row)const = 0;
+
+    /// \returns the mixing signal curve of the feature \a row
+    virtual std::vector<float> get_mix_series(unsigned int row)const = 0;
+
+    /// \returns the complete mixed signal at series index \a idx
+    virtual std::vector<float> get_mix(unsigned int idx)const = 0;
+
+    /** Evaluate an incomplete mixed signal. Here the features are given that are \a not to be used.
+        \sa get_partial_mix
+        \param idx series index
+        \param skip a set of feature indices that will be skipped when evaluating the mix
+        \returns the mixed signal
+    */
+    virtual std::vector<float> get_incomplete_mix(unsigned int idx, const IndexSet& skip)const = 0;
+
+    /** Evaluate an incomplete mixed signal. Here the features are given that are \a used to create the mix.
+        \sa get_incomplete_mix
+        \param idx series index
+        \param use the set of feature indices that will be used to evaluate the mix
+        \returns an incolmplete mixed signal.
+    */
+    virtual std::vector<float> get_partial_mix(unsigned int idx, const IndexSet& use)const = 0;
+
+    /** Evaluate a mix of the feature signals by adding and subtractig individual features.
+        \param plus features o be added
+        \param minus features to be subtracted
+        \returns the feature mix
+     */
+    virtual std::vector<float> get_delta_feature(const IndexSet& plus, const IndexSet& minus)const = 0;
+
+    /**
+       Replace a mixing signal curve
+       \param index of the curve to be replaced
+       \param series new data for mixing curve
+     */
+    virtual void set_mixing_series(unsigned int index, const std::vector<float>& series) = 0;
+
+    /// \returns a vector containing all mixing curves
+    virtual CSlopeColumns   get_mixing_curves() const = 0;
+
+    /**
+       Normalize the ICs in the following manner:
+       * Scale and shift the range of the ICs to  [-1, 1]
+       * Scale the mixing curved to compensate for the required scaling
+       * move the means of the time points to compensate for the shifting.
+     */
+    virtual void normalize_ICs() = 0;
+
+    /**
+       Normalize the mixing curves to have a zero mean. As a result a mean image is created that
+       containes the sum of the ICs weighted by the required mean shift.
+
+     */
+    virtual std::vector<float> normalize_Mix() = 0;
+
+
+    /// \returns the number of actual ICs
+    virtual unsigned int get_ncomponents() const = 0;
+
+    /**
+       sets the number of iterations in the ICA
+       \param n
+     */
+    virtual void set_max_iterations(int n) = 0;
+
+    /**
+       Set the ICA approach to either FICA_APPROACH_DEFL(default) or FICA_APPROACH_SYMM.
+       \param approach
+     */
+    virtual void set_approach(EApproach approach) = 0;
+private:
+    virtual void set_row_internal(unsigned row, const std::vector<double>&  buffer, double mean) = 0;
+
+};
+
+typedef CICAAnalysis::Pointer PICAAnalysis;
+
+
+class EXPORT_CORE CICAAnalysisFactory {
+public:
+    virtual ~CICAAnalysisFactory();
+    virtual PICAAnalysis create() const = 0;
+};
+
+
+typedef std::shared_ptr<CICAAnalysisFactory> PICAAnalysisFactory;
+
+/// \cond DOXYGEN_DOESNT_UNDERSTAND_BOOST_CONCEPT_REQUIRES
+template <class Iterator>
+BOOST_CONCEPT_REQUIRES(((::boost::ForwardIterator<Iterator>)),
+                       (void))
+CICAAnalysis::set_row(unsigned row, Iterator begin, Iterator end)
+{
+    const unsigned int length = std::distance(begin, end);
+    std::vector<double> buffer(length);
+    unsigned int idx = 0;
+        double mean = 0.0;
+
+        while (begin != end)
+                mean += (buffer[idx++] = *begin++);
+        mean /= length;
+    for(unsigned int i = 0; i < length; ++i)
+                buffer[i] -= mean;
+        set_row_internal(row, buffer, mean);
+}
+/// \endcond
+
+}
+
+#endif // CICAANALYSISBASE_HH
diff --git a/mia/core/import_handler.hh b/mia/core/import_handler.hh
index b1b4b5a..b831f4e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e89f6be..e57ca1b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9e874eb..97af55f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 987795b..54a6c7b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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-2015 Leipzig, Germany and Madrid, Spain \n"
+	"    (c) 1999-2016 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 dccdcc9..2e04344 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +40,13 @@ C1DInterpolatorFactory::C1DInterpolatorFactory(PSplineKernel kernel, const CSpli
 	assert(m_bc); 
 }
 
+C1DInterpolatorFactory::C1DInterpolatorFactory(const std::string& kernel_descr, const std::string& boundary_descr):
+	m_kernel(produce_spline_kernel(kernel_descr)),
+	m_bc(produce_spline_boundary_condition(boundary_descr))
+{
+}
+
+
 C1DInterpolatorFactory::C1DInterpolatorFactory(const C1DInterpolatorFactory& o):
 	m_kernel(o.m_kernel), 
 	m_bc(o.m_bc->clone())
@@ -63,37 +70,6 @@ C1DInterpolatorFactory::~C1DInterpolatorFactory()
 {
 }
 
-C1DInterpolatorFactory *create_1dinterpolation_factory(EInterpolation type, EBoundaryConditions bc)
-{
-	PSplineKernel kernel; 
-	switch (type) {
-	case ip_nn: 
-	case ip_bspline0: kernel = produce_spline_kernel("bspline:d=0"); break; 
-	case ip_linear:
-	case ip_bspline1: kernel = produce_spline_kernel("bspline:d=1"); break; 
-	case ip_bspline2: kernel = produce_spline_kernel("bspline:d=2"); break; 
-	case ip_bspline3: kernel = produce_spline_kernel("bspline:d=3"); break; 
-	case ip_bspline4: kernel = produce_spline_kernel("bspline:d=4"); break; 
-	case ip_bspline5: kernel = produce_spline_kernel("bspline:d=5"); break; 
-	case ip_omoms3:   kernel = produce_spline_kernel("omoms:d=3"); break;
-	default: 
-		throw invalid_argument("create_interpolator_factory:Unknown interpolator type requested"); 
-	}; 
-	PSplineBoundaryCondition pbc; 
-	switch (bc) {
-	case bc_mirror_on_bounds: pbc = produce_spline_boundary_condition("mirror"); break; 
-	case bc_repeat:           pbc = produce_spline_boundary_condition("repeat"); break; 
-	case bc_zero:             pbc = produce_spline_boundary_condition("zero"); break;   
-	default: 
-		throw invalid_argument("create_interpolator_factory:Unknown boundary condition requested"); 
-		
-	}
-	
-	return new C1DInterpolatorFactory(kernel, *pbc); 
-
-}
-
-
 #define INSTANCIATE_INTERPOLATORS(TYPE)			\
 	template class T1DInterpolator<TYPE>;		\
 	template class T1DConvoluteInterpolator<TYPE>
diff --git a/mia/core/interpolator1d.cxx b/mia/core/interpolator1d.cxx
index 0942c16..8cbd131 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +61,7 @@ T1DConvoluteInterpolator<T>::T1DConvoluteInterpolator(const std::vector<T>& data
 	m_boundary_conditions->set_width(data.size()); 
 
 	min_max<typename std::vector<T>::const_iterator>::get(data.begin(), data.end(), m_min, m_max);
+
 	
 	// copy the data
 	__dispatch_copy<std::vector<T>, TCoeff1D >::apply(data, m_coeff); 
@@ -107,7 +108,13 @@ template <class T, class U>
 struct bounded {
 	static void apply(T& r, const U& min, const U& max)
 	{
-		r = (r >= min) ? ( (r <= max) ? r : max) : min;
+		if (r > min) {
+			if (r < max)
+				return;
+			else
+				r = max;
+		}else
+			r = min; 
 	}
 };
 
@@ -133,12 +140,9 @@ T  T1DConvoluteInterpolator<T>::operator () (const double& x) const
 {
 	typedef typename TCoeff1D::value_type U; 
 	
-	// cut at boundary
-	if (x < 0.0 || x >= m_coeff.size())
-		return T();
-	
+
 	(*m_kernel)(x, m_x_weight, m_x_index);
-	m_boundary_conditions->apply(m_x_index, m_x_weight); 
+	m_boundary_conditions->apply(m_x_index, m_x_weight);
 
 	U result = U();
 	
@@ -151,11 +155,8 @@ T  T1DConvoluteInterpolator<T>::operator () (const double& x) const
 	case 6: result = add_1d<TCoeff1D,6>::value(m_coeff, m_x_weight, m_x_index); break; 
 	default: {
 		/* perform interpolation */
-		
-		U result = U();
-		
-		for (size_t x = 0; x < m_kernel->size(); ++x) {
-			result += m_x_weight[x] * m_coeff[m_x_index[x]];
+		for (size_t i = 0; i < m_kernel->size(); ++i) {
+			result += m_x_weight[i] * m_coeff[m_x_index[i]];
 		}
 		
 	}
@@ -190,8 +191,6 @@ T1DConvoluteInterpolator<T>::derivative_at (const double& x) const
 	default: {
 		/* perform interpolation */
 		
-		U result = U();
-		
 		for (size_t x = 0; x < m_kernel->size(); ++x) {
 			result += m_x_weight[x] * m_coeff[m_x_index[x]];
 		}
diff --git a/mia/core/interpolator1d.hh b/mia/core/interpolator1d.hh
index b3031a2..04a6c7e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -166,6 +166,8 @@ public:
 	 */
 	C1DInterpolatorFactory(PSplineKernel kernel, const CSplineBoundaryCondition& bc);
 
+	C1DInterpolatorFactory(const std::string& kernel_descr, const std::string& boundary_descr);
+
 	/// Copy constructor 
 	C1DInterpolatorFactory(const C1DInterpolatorFactory& o);
 
@@ -205,9 +207,6 @@ typedef std::shared_ptr<const C1DInterpolatorFactory > P1DInterpolatorFactory;
    @todo this should become the work of a plug-in handler 
  */
 
-C1DInterpolatorFactory EXPORT_CORE  *create_1dinterpolation_factory(EInterpolation type, EBoundaryConditions bc) 
-	__attribute__ ((warn_unused_result));
-
 // implementation
 template <class T>
 T1DInterpolator<T> *C1DInterpolatorFactory::create(const std::vector<T>& src) const
diff --git a/mia/core/iodata.cc b/mia/core/iodata.cc
index 6bd85fb..2a18dd3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 cf9c56e..0f5dae2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e167ebf..764b272 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -167,11 +167,33 @@ const std::string TIOPluginHandler<I>::get_supported_suffixes() const
 	return result.str(); 
 }
 
+
+template <class I> 
+void TIOPluginHandler<I>::check_file_exists(const std::string& fname) const
+{
+	if (fname != "-") { 
+		// first check whether file actually exists
+		bfs::path p(fname);
+		
+		if (p.extension() != ".@") {
+			
+			if (!bfs::exists(p)) {
+				throw create_exception<std::runtime_error>("Can't open file '", fname,
+									   "' for reading: it doesn't exist"); 
+			}
+		}
+	}
+}
+
 template <class I> 
 typename TIOPluginHandler<I>::PData
 TIOPluginHandler<I>::load(const std::string& fname) const
 {
-	TRACE_FUNCTION; 
+	TRACE_FUNCTION;
+
+	this->check_file_exists(fname); 
+	
+	
 	const Interface *pp = preferred_plugin_ptr(fname); 
 	if (pp) {
 		PData retval = pp->load(fname); 
diff --git a/mia/core/iohandler.hh b/mia/core/iohandler.hh
index d4efc36..4c3511d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -148,6 +148,8 @@ private:
 	std::string do_get_handler_type_string() const; 
         bool do_validate_parameter_string(const std::string& s) const;
 
+	virtual void check_file_exists(const std::string& fname) const; 
+	
 	/**
 	   Private plugin to handle the virtual data pool IO  
 	 */
diff --git a/mia/core/ioplugin.cc b/mia/core/ioplugin.cc
index 092e7c9..182e7d4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ioplugin.cxx b/mia/core/ioplugin.cxx
index c1f9186..6fe4239 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ioplugin.hh b/mia/core/ioplugin.hh
index fbbf556..2c87481 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/core/kmeans.cc
index 91f1375..253531b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,25 @@
  *
  */
 
-template <typename InputIterator, typename OutputIterator> 
-void kmeans(InputIterator ibegin, InputIterator iend, OutputIterator obegin, 
-	    std::vector<float> classes)
+
+#include <cmath>
+#include <limits>
+#include <mia/core/kmeans.hh>
+
+NS_MIA_BEGIN
+
+int EXPORT_CORE kmeans_get_closest_clustercenter(const std::vector<double>& classes, size_t l, double val)
 {
-	
+	double dmin = std::numeric_limits<double>::max();
+	int c = 0;
+	for (size_t i = 0; i <= l; i++) {
+		double d = std::fabs (val - classes[i]);
+		if (d < dmin) {
+			dmin = d;
+			c = i;
+		};
+	};
+	return c; 
 }
+
+NS_MIA_END
diff --git a/mia/core/kmeans.hh b/mia/core/kmeans.hh
index f99d5d8..073fe55 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,15 @@
 #include <limits>
 #include <mia/core/defines.hh>
 #include <mia/core/errormacro.hh>
+#include <mia/core/msgstream.hh>
 #include <boost/concept/requires.hpp>
 #include <boost/concept_check.hpp>
 
 NS_MIA_BEGIN
-/// helper function called by kmeans - don't call it directly 
+
+int EXPORT_CORE kmeans_get_closest_clustercenter(const std::vector<double>& classes, size_t l, double value); 
+
+
 template <typename InputIterator, typename OutputIterator> 
 bool kmeans_step(InputIterator ibegin, InputIterator iend, OutputIterator obegin, 
 		 std::vector<double>& classes, size_t l, int& biggest_class ) 
@@ -57,26 +61,82 @@ bool kmeans_step(InputIterator ibegin, InputIterator iend, OutputIterator obegin
 		// assign closest cluster center
 		OutputIterator ob = obegin; 
 		for (InputIterator b = ibegin; b != iend; ++b, ++ob) {
-			const double val = *b;
-			double dmin = std::numeric_limits<double>::max();
-			int c = 0;
-			for (size_t i = 0; i <= l; i++) {
-				double d = fabs (val - classes[i]);
-				if (d < dmin) {
-					dmin = d;
-					c = i;
-				};
-			};
-			*ob = c; 
-			
-			++count[c];
-			sums[c] += val;
+			*ob = kmeans_get_closest_clustercenter(classes,l, *b); 
+			++count[*ob];
+			sums[*ob] += *b;
+		};
+		
+		// recompute cluster centers
+		conv = true;
+		size_t max_count = 0; 
+		for (size_t i = 0; i <= l; i++) {
+			if (count[i]) {
+				double a = sums[i] / count[i];
+				if (a  && fabs ((a - classes[i]) / a) > convLimit)
+					conv = false;
+				classes[i] = a;
+				
+				if (max_count < count[i]) {
+					max_count  = count[i]; 
+					biggest_class = i; 
+				}
+			} else { // if a class is empty move it closer to neighbour 
+				if (i == 0)
+					classes[i] = (classes[i] + classes[i + 1]) / 2.0; 
+				else
+					classes[i] = (classes[i] + classes[i - 1])  / 2.0; 
+				conv = false;
+			}
+			sums[i] = 0;
+			count[i] = 0;
+		};
+	};
+
+	cvinfo()<<  "kmeans: " << l + 1 << " classes, " << 50 - iter << "  iterations";
+	for (size_t i = 0; i <= l; ++i )
+		cverb << std::setw(8) << classes[i]<< " ";  
+	cverb << "\n"; 
+	
+	return conv; 
+}
+
+
+template <typename InputIterator, typename OutputIterator> 
+bool kmeans_step_with_fixed_centers(InputIterator ibegin, InputIterator iend, OutputIterator obegin, 
+				    std::vector<double>& classes, const std::vector<bool>& fixed_center,
+				    size_t l, int& biggest_class ) 
+{
+	cvdebug()<<  "kmeans enter: ";
+	for (size_t i = 0; i <= l; ++i )
+		cverb << std::setw(8) << classes[i]<< " ";  
+	cverb << "\n"; 
+	
+	biggest_class = -1; 
+	const double convLimit = 0.005;	// currently fixed
+	std::vector<double> sums(classes.size()); 
+	std::vector<size_t> count(classes.size()); 
+	
+	bool conv = false;
+	int iter = 50; 
+	
+	while( iter-- && !conv) {
+
+		sort(classes.begin(), classes.end()); 
+		
+		// assign closest cluster center
+		OutputIterator ob = obegin; 
+		for (InputIterator b = ibegin; b != iend; ++b, ++ob) {
+			*ob = kmeans_get_closest_clustercenter(classes,l, *b); 
+			++count[*ob];
+			sums[*ob] += *b;
 		};
 		
 		// recompute cluster centers
 		conv = true;
 		size_t max_count = 0; 
 		for (size_t i = 0; i <= l; i++) {
+			if (fixed_center[i])
+				continue; 
 			if (count[i]) {
 				double a = sums[i] / count[i];
 				if (a  && fabs ((a - classes[i]) / a) > convLimit)
@@ -99,7 +159,7 @@ bool kmeans_step(InputIterator ibegin, InputIterator iend, OutputIterator obegin
 		};
 	};
 
-	cvinfo()<<  "kmeans: " << l + 1 << " classes " << 50 - iter << "  iterations";
+	cvinfo()<<  "kmeans: " << l + 1 << " classes, " << 50 - iter << "  iterations";
 	for (size_t i = 0; i <= l; ++i )
 		cverb << std::setw(8) << classes[i]<< " ";  
 	cverb << "\n"; 
@@ -149,7 +209,12 @@ BOOST_CONCEPT_REQUIRES( ((::boost::ForwardIterator<InputIterator>))
 	classes[1] = sum / (size + 1);
 	
 	// first run calles directly 
-	int biggest_class = 0; 
+	int biggest_class = 0;
+
+	// coverity is completely off here, the 1UL is actually a class index
+	// and has nothing to do with the size of the type pointed to by ibegin
+	// 
+	// coverity[sizeof_mismatch]
 	kmeans_step(ibegin, iend, obegin, classes, 1, biggest_class); 
 	
 	// further clustering always splits biggest class 
diff --git a/mia/core/labelmap.cc b/mia/core/labelmap.cc
index 64f7fef..94f1090 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f66873f..0797212 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4ba1fda..6ddd203 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b4ad675..67c65af 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 914de69..6d23239 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/gdas.cc b/mia/core/minimizer/gdas.cc
index ba0c111..3d35c52 100644
--- a/mia/core/minimizer/gdas.cc
+++ b/mia/core/minimizer/gdas.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +20,9 @@
 
 #include <mia/core/minimizer/gdas.hh>
 #include <mia/core/errormacro.hh>
-extern "C" {
-#include <cblas.h>
-}
+
+#include <gsl/gsl_cblas.h>
+
 
 NS_BEGIN(gdas)
 using namespace mia; 
diff --git a/mia/core/minimizer/gdas.hh b/mia/core/minimizer/gdas.hh
index 5095416..a46ebb0 100644
--- a/mia/core/minimizer/gdas.hh
+++ b/mia/core/minimizer/gdas.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/core/minimizer/gdsq.cc
index 92981b3..04c2c5e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +19,8 @@
  */
 
 #include <mia/core/minimizer/gdsq.hh>
-extern "C" {
-#include <cblas.h>
-}
+#include <gsl/gsl_cblas.h>
+
 
 NS_BEGIN(minimizer_gdsq)
 using namespace mia; 
diff --git a/mia/core/minimizer/gdsq.hh b/mia/core/minimizer/gdsq.hh
index 200a81e..de8c7f4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9576b42..ce03afa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 67c2e0e..56a15b1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 4b1b12d..bb33db3 100644
--- a/mia/core/minimizer/test_gdas.cc
+++ b/mia/core/minimizer/test_gdas.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_gdsq.cc b/mia/core/minimizer/test_gdsq.cc
index 647aaa0..c530b29 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2aedd22..e047bf9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b88074c..d250298 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1f09769..63cb1ff 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2796d7e..d0e8a4f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9043685..a2a2c9a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 653f0d0..37ebb79 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/core/msgstream.hh
index e71de21..3ebb4be 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +111,7 @@ public:
 
 	/** general output routine; output is only given, if the data verbosity level is
 	    set higher or equal to the stream verbosity level.
-	    \param text the text to be written to the stream
+x1	    \param text the text to be written to the stream
 	    \returns a reference to this object
 	*/
 	template <class T>
@@ -330,19 +330,6 @@ inline vstream& cvmsg()
 */
 #define cverb ::mia::vstream::instance()
 
-/**
-   \ingroup logging
-   \brief implements the direct streaming of std::vectors. 
-*/
-template <typename T> 
-vstream& operator << (vstream& os, const std::vector<T>& v) {
-	os << "["; 
-	for (auto i =v.begin(); i != v.end(); ++i) 
-		os << *i << ", "; 
-	os << "]"; 
-	return os; 
-}
-
 NS_MIA_END
 
 #endif /* !CVERB_HH */
diff --git a/mia/core/nccsum.cc b/mia/core/nccsum.cc
index 95e9728..eabeacd 100644
--- a/mia/core/nccsum.cc
+++ b/mia/core/nccsum.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/nccsum.hh b/mia/core/nccsum.hh
index 91bc562..d43814a 100644
--- a/mia/core/nccsum.hh
+++ b/mia/core/nccsum.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5fa4676..2f33894 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 737a910..9aeb746 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 423cbbc..3344518 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a17bfab..8f4da4b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 25b0981..3146468 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1abf532..dd21eb8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0356dbf..2ed8596 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/core/noisegen.hh
index bb2456d..1b5d205 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/optionparser.cc b/mia/core/optionparser.cc
index 3a858ee..2214844 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/optionparser.hh b/mia/core/optionparser.hh
index f3ff7e8..a3e334f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/core/optparam.cc
index 95510cc..d7870ea 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8738801..10d07fc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/parallel.hh b/mia/core/parallel.hh
new file mode 100644
index 0000000..66b4763
--- /dev/null
+++ b/mia/core/parallel.hh
@@ -0,0 +1,72 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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_parallel_hh
+#define mia_core_parallel_hh
+
+
+#include <miaconfig.h>
+
+#include <mia/core/defines.hh>
+
+#ifdef HAVE_TBB
+
+#include <tbb/task_scheduler_init.h>
+#include <tbb/recursive_mutex.h>
+#include <tbb/mutex.h>
+#include <tbb/parallel_for.h>
+#include <tbb/parallel_reduce.h>
+#include <tbb/blocked_range.h>
+#include <tbb/recursive_mutex.h>
+#include <tbb/spin_mutex.h>
+
+NS_MIA_BEGIN
+
+typedef tbb::blocked_range<int> C1DParallelRange;
+typedef tbb::mutex CMutex; 
+typedef tbb::mutex::scoped_lock CScopedLock;
+
+typedef tbb::recursive_mutex CRecursiveMutex; 
+typedef tbb::recursive_mutex::scoped_lock CRecursiveScopedLock; 
+
+#define ATOMIC tbb::atomic
+
+template <typename Range, typename Func>
+void pfor(const Range& range, Func body) {
+	tbb::parallel_for(range, body); 
+}
+
+template<typename Range, typename Value, 
+         typename Func, typename Reduction>
+Value preduce( const Range& range, const Value& identity,
+	       const Func& func, const Reduction& reduction) {
+	return tbb::parallel_reduce(range, identity, func, reduction); 
+}; 
+
+NS_MIA_END
+
+#else  // no TBB: use C++ 11 thread
+
+#include <mia/core/parallelcxx11.hh>
+
+#endif
+
+
+#endif 
diff --git a/mia/core/combiner.cc b/mia/core/parallelcxx11.cc
similarity index 68%
copy from mia/core/combiner.cc
copy to mia/core/parallelcxx11.cc
index a139a5a..8b36fb2 100644
--- a/mia/core/combiner.cc
+++ b/mia/core/parallelcxx11.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,23 +18,24 @@
  *
  */
 
-#include <mia/core/combiner.hh>
+#include <mia/core/parallelcxx11.hh>
 
 NS_MIA_BEGIN
 
-CCombinerResult::~CCombinerResult()
+int CMaxTasks::get_max_tasks()
 {
-
+        if (max_tasks < 0) {
+                max_tasks = std::thread::hardware_concurrency(); 
+        }
+        return max_tasks; 
 }
 
-void CCombinerResult::save(const std::string& fname)const
+void CMaxTasks::set_max_tasks(int mt)
 {
-	do_save(fname);
+        max_tasks = mt; 
 }
 
-boost::any CCombinerResult::get() const
-{
-	return do_get(); 
-}
+int CMaxTasks::max_tasks = -1;
+
 
 NS_MIA_END
diff --git a/mia/core/parallelcxx11.hh b/mia/core/parallelcxx11.hh
new file mode 100644
index 0000000..c5354a3
--- /dev/null
+++ b/mia/core/parallelcxx11.hh
@@ -0,0 +1,214 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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_parallelcxx11_hh
+#define mia_core_parallelcxx11_hh
+
+#include <mia/core/defines.hh>
+
+#include <thread>
+#include <atomic>
+#include <mutex>
+#include <cassert>
+#include <vector>
+
+NS_MIA_BEGIN
+
+typedef std::mutex CMutex;
+typedef std::recursive_mutex CRecursiveMutex; 
+
+
+class EXPORT_CORE CMaxTasks {
+public:
+	static int get_max_tasks(); 
+	static void set_max_tasks(int mt); 
+private:
+	static int max_tasks; 
+}; 
+
+#define ATOMIC std::atomic
+
+template <typename Mutex>
+class TScopedLock {
+public:
+	TScopedLock(Mutex& m): m_mutex(m){
+		m_mutex.lock();
+		own_lock = true; 
+	};
+	~TScopedLock(){
+		if (own_lock) 
+			m_mutex.unlock();
+	};
+
+	void release() {
+		if (own_lock) {
+			own_lock = false; 
+			m_mutex.unlock();
+		}
+	}
+private:
+	Mutex& m_mutex;
+	bool own_lock;
+};
+
+typedef TScopedLock<CMutex> CScopedLock;
+typedef TScopedLock<CRecursiveMutex> CRecursiveScopedLock;
+
+class EXPORT_CORE C1DParallelRange {
+public: 
+	C1DParallelRange(int begin, int end, int block = 1):
+		m_begin(begin),
+		m_end(end),
+		m_block(block), 
+		m_current_wp(0)
+		{
+			assert(begin <= end); 
+		}
+
+	C1DParallelRange(const C1DParallelRange& orig):
+		m_begin(orig.m_begin),
+		m_end(orig.m_end),
+		m_block(orig.m_block)
+		{
+			m_current_wp = orig.m_current_wp.load();
+		}
+	
+	C1DParallelRange get_next_workpackage()	{
+		int wp = m_current_wp++;
+		int begin = m_begin + wp * m_block;
+		int end = begin + m_block;
+		if (begin > m_end) {
+			return C1DParallelRange(m_end,m_end,0);
+		}
+		if (end > m_end) {
+			return C1DParallelRange(begin, m_end, 1);
+		}
+		return C1DParallelRange(begin, end, 1);
+	}
+
+	bool empty() const {
+		return m_begin >= m_end; 
+	}
+
+	int begin() const {
+		return m_begin; 
+	}
+
+	int end() const {
+		return m_end; 
+	}
+
+private:
+	int m_begin;
+	int m_end;
+	int m_block;
+	std::atomic<int> m_current_wp;
+}; 
+
+template <typename Range, typename Func>
+void pfor_callback(Range& range, Func f)
+{
+	while (true)  {
+		Range wp = range.get_next_workpackage();
+		if (!wp.empty()) 
+			f(wp);
+		else
+			break;
+	}
+}
+
+template <typename Range, typename Func>
+void pfor(Range range, Func f) {
+	
+	int max_treads = CMaxTasks::get_max_tasks(); 
+	
+	std::thread::hardware_concurrency();
+
+	std::vector<std::thread> threads;
+	for (int i = 0; i < max_treads; ++i) {
+		threads.push_back(std::thread(pfor_callback<Range, Func>, std::ref(range), f)); 
+	}
+	
+	for (int i = 0; i < max_treads; ++i) {
+		threads[i].join(); 
+	}
+}; 
+
+template <typename V>
+class ReduceValue {
+public:
+	typedef V Value; 
+	ReduceValue(const Value& i):identity(i), value(i) {
+	}
+	
+	template <typename Reduce> 
+	void reduce(const Value& v, Reduce r)
+	{
+		CScopedLock sl(mutex);
+		value = r(v, value); 
+	}
+	const Value& get_identity() const {
+		return identity;
+	}
+	const Value& get_reduced() const {
+		return value; 
+	}
+private: 
+	mutable CMutex mutex;
+	Value identity; 
+	Value value; 
+}; 
+
+template <typename Range, typename Value, typename Func, typename Reduce>
+void preduce_callback(Range& range, ReduceValue<Value>& v, Func f, Reduce r)
+{
+	Value value = v.get_identity(); 
+	while (true)  {
+		Range wp = range.get_next_workpackage();
+		if (!wp.empty()) 
+			value = f(wp, value);
+		else
+			break;
+	}
+	v.reduce(value, r);
+}
+
+template <typename Range, typename Value, typename Func, typename Reduce>
+Value preduce(Range range, Value identity, Func f, Reduce r)
+{
+	int max_treads = CMaxTasks::get_max_tasks();
+
+	ReduceValue<Value> value(identity); 
+		
+	std::vector<std::thread> threads;
+	for (int i = 0; i < max_treads; ++i) {
+		threads.push_back(std::thread(preduce_callback<Range, Value, Func, Reduce>,
+					      std::ref(range), std::ref(value), f, r)); 
+	}
+	
+	for (int i = 0; i < max_treads; ++i) {
+		threads[i].join(); 
+	}
+	return value.get_reduced(); 
+}; 
+
+NS_MIA_END 
+
+#endif
diff --git a/mia/core/parameter.cc b/mia/core/parameter.cc
index 37728be..902a26e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cxx b/mia/core/parameter.cxx
index aff4b43..a25fc96 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/core/parameter.hh
index 4a71bf5..0bb48e0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Pub
diff --git a/mia/core/paramoption.cc b/mia/core/paramoption.cc
index 08e65f3..ae394b3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/paramoption.hh b/mia/core/paramoption.hh
index 62d6605..a62536e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/paramtranslator.cc b/mia/core/paramtranslator.cc
index 74cfc4a..d0f5741 100644
--- a/mia/core/paramtranslator.cc
+++ b/mia/core/paramtranslator.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/paramtranslator.hh b/mia/core/paramtranslator.hh
index 41245ef..ada94e4 100644
--- a/mia/core/paramtranslator.hh
+++ b/mia/core/paramtranslator.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b92f325..cda80cd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 95bf233..f3e8c83 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 47b2572..f0f52b3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cxx b/mia/core/plugin_base.cxx
index b4a2e77..43dbc85 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c3bb16f..5bfb922 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_test.cc b/mia/core/plugin_test.cc
index fa9486f..c122502 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 afb122e..d8a7d3a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +101,11 @@ void CProbabilityVector::do_load(istream& is)
 	}
 
 
+	/* hsize is first used to allocate a vector. If it is too big
+	   a std.:bad_alloc exception will be thrown. This is not worse 
+	   than a check for size that would restrict hsize to an abitrary 
+	   value */
+	// coverity[tainted_scalar]
 	for (size_t i = 0; i < hsize; ++i) {
 		for (size_t k = 0; k < size(); ++k) {
 			is >> (*this)[k][i];
@@ -183,6 +188,11 @@ void CLabelMap::do_load(istream& is)
 
 	size_t src, trgt;
 
+	/* hsize is first used to allocate a vector. If it is too big
+	   a std.:bad_alloc exception will be thrown. This is not worse 
+	   than a check for size that would restrict hsize to an abitrary 
+	   value */
+	// coverity[tainted_scalar]
 	for (size_t i = 0; i < hsize; ++i) {
 		is >> src >> trgt;
 		(*this)[src] = trgt;
diff --git a/mia/core/probmap.hh b/mia/core/probmap.hh
index a7535db..b1efd87 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 71c20dd..d4d01ff 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e4fe14f..f18db04 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a25b286..c42fcb4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 +31,13 @@ CProductCache::CProductCache(const std::string& name):m_enabled(false)
 
 void CProductCache::enable_write(bool enable)
 {
-	tbb::spin_mutex::scoped_lock lock(m_enable_mutex);
+	CScopedLock lock(m_enable_mutex);
 	m_enabled = enable; 
 }
 
 bool CProductCache::is_enabled() const
 {
-	tbb::spin_mutex::scoped_lock lock(m_enable_mutex);
+	CScopedLock lock(m_enable_mutex);
 	return m_enabled; 
 }
 
diff --git a/mia/core/productcache.hh b/mia/core/productcache.hh
index 736024e..55329e5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 +23,9 @@
 
 #include <map>
 #include <string>
-#include <mia/core/defines.hh>
-#include <tbb/recursive_mutex.h>
-#include <tbb/spin_mutex.h>
+#include <mia/core/parallel.hh>
 
 NS_MIA_BEGIN
-typedef tbb::recursive_mutex::scoped_lock CRecursiveScopedLock; 
-
 /** 
     \ingroup plugin
 
@@ -68,7 +64,7 @@ protected:
 private: 
 	virtual void do_clear() = 0; 
 	bool m_enabled; 
-	mutable tbb::spin_mutex m_enable_mutex; 
+	mutable CMutex m_enable_mutex; 
 }; 
 
 
@@ -109,7 +105,7 @@ private:
 
 	typedef std::map<std::string, ProductPtr> CMap; 
 	CMap m_cache; 
-	mutable tbb::recursive_mutex m_cache_mutex; 
+	mutable CRecursiveMutex m_cache_mutex; 
 }; 
 
 
diff --git a/mia/core/property_flags.cc b/mia/core/property_flags.cc
index b060663..b471141 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8af9937..9e44509 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4e3b0bb..7da7fa0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c06a7e9..2634df0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8e49805..42640fa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/core/regmodel.cc
index dc4bcb5..e3e38c8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f8d41f9..0f5b0a0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 62ff26b..a7c2042 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 <mia/core/revision.hh>
 
 NS_MIA_BEGIN
-char const *get_revision()
+char const * EXPORT_CORE get_revision()
 {
 
 	return LIBMIA_REVISION;
diff --git a/mia/core/scaler1d.cc b/mia/core/scaler1d.cc
index 48c732d..ea9a1cb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 7f3fc97..4a07f19 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/searchpath.cc b/mia/core/searchpath.cc
index 256325e..9ddb14f 100644
--- a/mia/core/searchpath.cc
+++ b/mia/core/searchpath.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/searchpath.hh b/mia/core/searchpath.hh
index 097d540..89ff26f 100644
--- a/mia/core/searchpath.hh
+++ b/mia/core/searchpath.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/selftestcmdoption.cc b/mia/core/selftestcmdoption.cc
index 7388c73..e18fffc 100644
--- a/mia/core/selftestcmdoption.cc
+++ b/mia/core/selftestcmdoption.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/selftestcmdoption.hh b/mia/core/selftestcmdoption.hh
index 9c596d5..382f9c8 100644
--- a/mia/core/selftestcmdoption.hh
+++ b/mia/core/selftestcmdoption.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 345922d..a36946f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e52f916..2df8a31 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9e3e639..4fe1964 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 210b929..c070fd9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e135c8e..72737f6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/silence_cmake_missing_source_file_warning.c b/mia/core/silence_cmake_missing_source_file_warning.c
deleted file mode 100644
index 5f1f3b5..0000000
--- a/mia/core/silence_cmake_missing_source_file_warning.c
+++ /dev/null
@@ -1,2 +0,0 @@
-int silence_cmake_warning_about_missing_source_file; 
-
diff --git a/mia/core/simpson.hh b/mia/core/simpson.hh
index caaa2d9..b8c77e0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 0e218bd..6068a98 100644
--- a/mia/core/singular_refobj.hh
+++ b/mia/core/singular_refobj.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/core/slopeclassifier.cc
index 49b794c..b09d0d4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3b38eec..023e4cd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 dda5721..6d7c3ff 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@
  *
  */
 
-#include <gsl++/wavelet.hh>
+#include <mia/core/gsl_wavelet.hh>
 
 #include <mia/core/spacial_kernel.hh>
 #include <mia/core/slopestatistics.hh>
diff --git a/mia/core/slopestatistics.hh b/mia/core/slopestatistics.hh
index 3c550b6..47e7354 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/slopevector.hh b/mia/core/slopevector.hh
index 56964c2..1c02129 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 12619d6..e88cae7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/core/spacial_kernel.hh
index 4d10c39..16e77d0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/cdiff.cc b/mia/core/spacialkernel/cdiff.cc
index 823bec9..d15f8d1 100644
--- a/mia/core/spacialkernel/cdiff.cc
+++ b/mia/core/spacialkernel/cdiff.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +57,48 @@ const string C1DSpacialCDiffKernelPlugin::do_get_descr()const
 	return "Central difference filter kernel, mirror boundary conditions are used.";
 }
 
+
+C1DScharrFilterKernel::C1DScharrFilterKernel():
+	C1DFoldingKernel(1)
+{
+	(*this)[0] = 3.0 / 16.0;
+	(*this)[1] = 10.0/ 16.0;
+	(*this)[2] = 3.0 / 16.0; 
+	
+}
+
+std::vector<double> C1DScharrFilterKernel::do_apply(const std::vector<double>& data) const
+{
+	std::vector<double> result(data.size());
+
+	result[0] = 2 * data[1] * 0.1875 + data[0] * 0.625;
+	result[result.size()-1] = 2 * data[result.size()-2] * 0.1875  + data[result.size()-1] * 0.625;
+
+	for (unsigned i = 1; i < result.size() -1; ++i)
+		result[i] += (data[i-1] + data[i+1]) * 0.1875 + 0.625 * data[i]; 
+	return result; 
+}
+
+
+C1DScharrKernelPlugin::C1DScharrKernelPlugin():
+	C1DSpacialKernelPlugin("scharr")
+{
+}
+
+mia::C1DFoldingKernel *C1DScharrKernelPlugin::do_create() const
+{
+	return new C1DScharrFilterKernel(); 
+}
+
+const std::string C1DScharrKernelPlugin::do_get_descr()const
+{
+	return "This plugin provides the 1D folding kernel for the Scharr gradient filter"; 
+}
+
 extern "C" EXPORT CPluginBase  *get_plugin_interface()
 {
-	return new C1DSpacialCDiffKernelPlugin();
+	CPluginBase *plugin = new C1DScharrKernelPlugin();
+	plugin->append_interface(new C1DSpacialCDiffKernelPlugin());
+	return plugin; 
 }
 
diff --git a/mia/core/spacialkernel/cdiff.hh b/mia/core/spacialkernel/cdiff.hh
index 3714ad9..e92257c 100644
--- a/mia/core/spacialkernel/cdiff.hh
+++ b/mia/core/spacialkernel/cdiff.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,4 +41,22 @@ public:
 	virtual const std::string do_get_descr()const;
 };
 
+/**  Class for a one-dimensional Scharr filter part. */
+class C1DScharrFilterKernel: public mia::C1DFoldingKernel {
+
+public:
+	/** contructor creates the kernel, is always -1, 0, 1 */
+	C1DScharrFilterKernel();
+private:
+	virtual std::vector<double> do_apply(const std::vector<double>& data) const;
+};
+
+class C1DScharrKernelPlugin: public mia::C1DSpacialKernelPlugin {
+public:
+	C1DScharrKernelPlugin();
+	virtual mia::C1DFoldingKernel *do_create() const;
+	virtual const std::string do_get_descr()const;
+};
+
+
 NS_END 
diff --git a/mia/core/spacialkernel/gauss.cc b/mia/core/spacialkernel/gauss.cc
index 264c601..646dbcc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 db35f13..4da004c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_cdiff.cc b/mia/core/spacialkernel/test_cdiff.cc
index a737e07..16bd452 100644
--- a/mia/core/spacialkernel/test_cdiff.cc
+++ b/mia/core/spacialkernel/test_cdiff.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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/internal/plugintester.hh>
 #include <mia/core/spacialkernel/cdiff.hh>
 
 NS_MIA_USE
@@ -29,16 +29,16 @@ using namespace cdiff_1d_folding_kernel;
 
 BOOST_AUTO_TEST_CASE( test_cdiff )
 {
-        C1DCDiffFilterKernel kernel; 
-	BOOST_CHECK_EQUAL(kernel.size(), 3u); 
-	BOOST_CHECK_EQUAL(kernel[0], -1);
-        BOOST_CHECK_EQUAL(kernel[1],  0);
-        BOOST_CHECK_EQUAL(kernel[2],  1);
+        auto kernel = BOOST_TEST_create_from_plugin<C1DSpacialCDiffKernelPlugin>("cdiff"); 
+	BOOST_CHECK_EQUAL(kernel->size(), 3u); 
+	BOOST_CHECK_EQUAL((*kernel)[0], -1);
+        BOOST_CHECK_EQUAL((*kernel)[1],  0);
+        BOOST_CHECK_EQUAL((*kernel)[2],  1);
 
 
         vector<double> input = {0,1,2,-1,0 }; 
         
-        kernel.apply_inplace(input);
+        kernel->apply_inplace(input);
 
         BOOST_CHECK_SMALL(input[0], 1e-10);
         BOOST_CHECK_CLOSE(input[1], 1, 0.1);
@@ -48,3 +48,38 @@ BOOST_AUTO_TEST_CASE( test_cdiff )
 
 }
 
+BOOST_AUTO_TEST_CASE( test_scharr )
+{
+	auto kernel = BOOST_TEST_create_from_plugin<C1DScharrKernelPlugin>("scharr"); 
+	BOOST_CHECK_EQUAL(kernel->size(), 3u); 
+	BOOST_CHECK_EQUAL((*kernel)[0], 3.0 / 16.0);
+        BOOST_CHECK_EQUAL((*kernel)[1], 10.0 / 16.0);
+        BOOST_CHECK_EQUAL((*kernel)[2], 3.0 / 16.0);
+
+
+        vector<double> input1 = {1,1,1,1,1}; 
+        
+        kernel->apply_inplace(input1);
+
+        BOOST_CHECK_CLOSE(input1[0], 1.0, 0.001);
+        BOOST_CHECK_CLOSE(input1[1], 1.0, 0.001);
+        BOOST_CHECK_CLOSE(input1[2], 1.0, 0.001);
+	BOOST_CHECK_CLOSE(input1[3], 1.0, 0.001);
+        BOOST_CHECK_CLOSE(input1[4], 1.0, 0.001); 
+
+	
+        vector<double> input = {0,1,2,-1,0 }; 
+        
+        kernel->apply_inplace(input);
+
+        BOOST_CHECK_CLOSE(input[0], 3.0 / 8.0, 0.001);
+        BOOST_CHECK_CLOSE(input[1], 1.0 , 0.001);
+        BOOST_CHECK_CLOSE(input[2], 20.0/16.0 , 0.001);
+	BOOST_CHECK_CLOSE(input[3], -1.0/4.0 , 0.001);
+        BOOST_CHECK_CLOSE(input[4], -3.0 / 8.0, 0.001); 
+
+
+	
+}
+
+
diff --git a/mia/core/spacialkernel/test_gauss.cc b/mia/core/spacialkernel/test_gauss.cc
index 951cf7d..6195f1c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_histogram.cc b/mia/core/sparse_histogram.cc
new file mode 100644
index 0000000..e950e90
--- /dev/null
+++ b/mia/core/sparse_histogram.cc
@@ -0,0 +1,59 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/sparse_histogram.hh>
+
+NS_MIA_BEGIN
+
+using std::vector;
+using std::pair;
+using std::make_pair;
+
+CSparseHistogram::CSparseHistogram():
+        m_shift(0), 
+        m_pixeltype(it_none)
+{
+}
+
+CSparseHistogram::Compressed CSparseHistogram::get_compressed_histogram()const
+{
+        int nonzero_bins = 0;
+        for (auto b: m_histogram) {
+                if (b > 0)
+                        ++nonzero_bins; 
+        }
+
+        Compressed result;
+        result.reserve(nonzero_bins);
+        for (unsigned i = 0; i < m_histogram.size(); ++i) {
+                if (m_histogram[i] != 0)
+                        result.push_back(make_pair(i - m_shift, m_histogram[i])); 
+        }
+        return result; 
+}
+
+EXPORT_CORE  std::ostream& operator << (std::ostream& os, const std::pair<short, unsigned long>& pair)
+{
+	os << "[" << pair.first << ": " << pair.second << "]";
+	return os; 
+}
+
+
+NS_MIA_END
diff --git a/mia/core/sparse_histogram.hh b/mia/core/sparse_histogram.hh
new file mode 100644
index 0000000..5236922
--- /dev/null
+++ b/mia/core/sparse_histogram.hh
@@ -0,0 +1,150 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 <vector> 
+#include <type_traits>
+#include <limits> 
+
+NS_MIA_BEGIN
+
+/**
+   \ingroup utils 
+    
+   \brief A sparse histogram 
+
+   This class implements a sparse histogram. As input only 
+   8 and 16 bit (un)signed data is allowed. 
+*/
+
+class EXPORT_CORE CSparseHistogram : public TFilter<size_t> {
+        
+public: 
+	typedef std::vector<std::pair<int, unsigned long>> Compressed; 
+
+	CSparseHistogram();
+
+        /**
+           Fees pixels to the histogram
+           \tparam InIterator input iterator, must be a forward iterator 
+           \param begin start of range 
+           \param end end of range 
+           \returns number of added pixels
+        */
+        template <typename InIterator>
+        size_t operator ()(InIterator begin, InIterator end); 
+
+	template <typename Image>
+	size_t operator ()(const Image& image) {
+		return (*this)(image.begin(), image.end()); 
+	}
+	
+        /**
+           \returns the histogram as a vector of <value, count> pairs 
+         */
+        Compressed get_compressed_histogram()const; 
+ private: 
+        std::vector<unsigned long> m_histogram; 
+        int m_shift; 
+        EPixelType m_pixeltype; 
+}; 
+
+EXPORT_CORE std::ostream& operator << (std::ostream& os, const std::pair<short, unsigned long>& pair); 
+
+//   Implementation
+
+///  @cond INTERNAL
+
+template <typename InIterator, bool sig> 
+struct dispatch_by_pixeltype {
+        static size_t  apply(InIterator MIA_PARAM_UNUSED(begin), InIterator MIA_PARAM_UNUSED(end),
+                             std::vector<unsigned long>& MIA_PARAM_UNUSED(histogram)){
+                throw std::invalid_argument("Input pixel type not supported"); 
+        }
+}; 
+
+template <typename InIterator> 
+struct dispatch_by_pixeltype<InIterator, false> {
+        static size_t apply(InIterator begin, InIterator end, std::vector<unsigned long>& histogram){
+                size_t n = 0; 
+                while ( begin != end) {
+                        ++histogram[*begin];
+                        ++begin;
+                        ++n; 
+                }
+                return n; 
+        }
+}; 
+
+template <typename InIterator> 
+struct dispatch_by_pixeltype<InIterator, true> {
+        static size_t apply(InIterator begin, InIterator end, std::vector<unsigned long>& histogram){
+                typedef typename InIterator::value_type in_pixels;
+		int shift = -std::numeric_limits<in_pixels>::min();
+                size_t n = 0; 
+                while ( begin != end) {
+                        ++histogram[*begin + shift];
+                        ++begin;
+                        ++n; 
+                }
+                return n; 
+        }
+}; 
+
+
+template <typename InIterator>
+size_t CSparseHistogram::operator ()(InIterator begin, InIterator end)
+{
+        typedef typename InIterator::value_type in_pixeltype; 
+        if (m_pixeltype ==it_none) {
+                m_pixeltype = pixel_type<in_pixeltype>::value;
+		m_shift = -std::numeric_limits<in_pixeltype>::min(); 
+                switch (m_pixeltype) {
+                case it_sbyte:
+                case it_ubyte:
+                        m_histogram.resize(256);
+                        break; 
+                case it_sshort:
+                case it_ushort:
+                        m_histogram.resize(65536);
+                        break; 
+                default:
+                        throw create_exception<std::invalid_argument>("Input pixel type '",
+                                                                 CPixelTypeDict.get_name(m_pixeltype),
+                                                                 "' not supported."); 
+                }
+                
+        } else if (m_pixeltype != pixel_type<in_pixeltype>::value){
+                throw create_exception<std::invalid_argument>("Input pixels not of consisted type, started with ",
+                                                         CPixelTypeDict.get_name(m_pixeltype), ", but got now ",
+                                                         CPixelTypeDict.get_name(pixel_type<in_pixeltype>::value)); 
+        }
+
+        const bool is_signed = std::is_signed<in_pixeltype>::value; 
+
+        size_t n = 0; 
+        n += dispatch_by_pixeltype<InIterator, is_signed>::apply(begin, end, m_histogram);
+        return n; 
+}
+
+/// @endcond
+
+NS_MIA_END
diff --git a/mia/core/sparse_solver.hh b/mia/core/sparse_solver.hh
index 0baca75..ca951f2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2109d07..10fee6d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ CMirrorOnBoundary::CMirrorOnBoundary(int width):
 
 CSplineBoundaryCondition *CMirrorOnBoundary::clone () const
 {
-	return new CMirrorOnBoundary(*this); 
+	return new CMirrorOnBoundary(get_width()); 
 }
 
 void CMirrorOnBoundary::do_set_width(int width)
@@ -97,7 +97,7 @@ CZeroBoundary::CZeroBoundary(int width):
 
 CSplineBoundaryCondition *CZeroBoundary::clone ()const
 {
-	return new CZeroBoundary(*this); 
+	return new CZeroBoundary(get_width()); 
 }
 
 void CZeroBoundary::test_supported(int npoles) const
@@ -156,7 +156,7 @@ CRepeatBoundary::CRepeatBoundary():
 
 CSplineBoundaryCondition *CRepeatBoundary::clone ()const
 {
-	return new CRepeatBoundary(*this); 
+	return new CRepeatBoundary(get_width()); 
 }
 
 CRepeatBoundary::CRepeatBoundary(int width):
diff --git a/mia/core/splinebc/bc.hh b/mia/core/splinebc/bc.hh
index 418f08f..aabe602 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2d3a2bd..7feb9e1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@
 #include <iomanip>
 #include <mia/core/splinekernel.hh>
 #include <gsl/gsl_linalg.h>
-#include <gsl++/vector.hh>
-#include <gsl++/matrix.hh>
+#include <mia/core/gsl_vector.hh>
+#include <mia/core/gsl_matrix.hh>
 
 NS_MIA_USE
 using std::vector; 
@@ -116,7 +116,7 @@ vector<double> BoundaryFixture::run(std::vector<double> f, const CSplineBoundary
 	CSplineKernel::VWeight orig(f); 
 
 	auto m_A = gsl::Matrix(f.size(), f.size(),  true);
-	auto m_tau = gsl::DoubleVector(f.size(), false ); 
+	auto m_tau = gsl::Vector(f.size(), false ); 
 
 	for(size_t i = 0; i < f.size(); ++i) {
 		(*kernel)(i, weights, indices);
@@ -131,9 +131,9 @@ vector<double> BoundaryFixture::run(std::vector<double> f, const CSplineBoundary
 	gsl_linalg_QR_decomp(m_A, m_tau); 
 	
 
-	gsl::DoubleVector coefs(f.size(), false); 
-	gsl::DoubleVector residual(f.size(), false); 
-	gsl::DoubleVector input(f.size(), false); 
+	gsl::Vector coefs(f.size(), false); 
+	gsl::Vector residual(f.size(), false); 
+	gsl::Vector input(f.size(), false); 
 	copy(f.begin(), f.end(), input.begin()); 
 
 	gsl_linalg_QR_lssolve (m_A, m_tau, input, coefs, residual); 
diff --git a/mia/core/splinekernel.cc b/mia/core/splinekernel.cc
index 3d41366..d00de6f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/core/splinekernel.hh
index cff7325..91cc8ec 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 04ddccb..f05019b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -247,6 +247,10 @@ void CBSplineKernel3::get_weights(double x, VWeight&  weight)const
 	v2df W30 = W03; 
 	W30 = _mm_shuffle_pd(W30, W30, 0x1); 
 
+	// coverity is complaining about variables of type __m128d
+	// being pointers where they are indeed to interpreted as
+	// arrays of two elements 
+	// coverity[array_vs_singleton]
 	const v2df W12 = X - W03 - W03 + W30; 
 	
 	_mm_storel_pd(&weight[0], W03); 
diff --git a/mia/core/splinekernel/bspline.hh b/mia/core/splinekernel/bspline.hh
index ed04eae..df0978c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2507d1c..ba03197 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/core/splineparzenmi.cc
index bfc7716..7f81d1b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 fe9b472..6757d88 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cc b/mia/core/sqmin.cc
index b3aef5a..277e67b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 55ed915..6154ff8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 7669a78..b9984dd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c699794..7aec459 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a3798a9..35d7f97 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index c9e1636..131e840 100644
--- a/mia/core/svector.hh
+++ b/mia/core/svector.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,19 @@
 
 NS_MIA_BEGIN
 
+/**
+   \ingroup logging
+   \brief implements the direct streaming of std::vectors. 
+*/
 template <typename T> 
-std::ostream&  operator << (std::ostream& os, const std::vector<T>& v) 
-{
-	for(auto x: v)
-		os << x << ","; 
+std::ostream& operator << (std::ostream& os, const std::vector<T>& v) {
+	auto i = v.begin();
+	auto e = v.end(); 
+
+	if (i != e)
+		os << *i++;
+	while (i != e)
+		os << "," << *i++;
 	return os; 
 }
 
@@ -46,6 +54,8 @@ struct __dispatch_translate {
 		char c; 
 		std::istringstream s(str); 
 		s >> v;
+		if (s.fail())
+			return false; 
 		while (!s.eof() && s.peek() == ' ') 
 			s >> c; 
 		return s.eof(); 
diff --git a/mia/core/test_Vector.cc b/mia/core/test_Vector.cc
index bc2000b..715e6af 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1e70aca..50c3524 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -375,7 +375,7 @@ BOOST_AUTO_TEST_CASE( test_attribute_data )
 	BOOST_CHECK_EQUAL(data.get_attribute_as_string("some"), "1.5");
 
 	CFloatTranslator::register_for("floatfromstring");
-	data.set_attribute( "floatfromstring", "2.5f");
+	data.set_attribute( "floatfromstring", "2.5");
 
 	PAttribute floatfromstring = data.get_attribute("floatfromstring");
 
diff --git a/mia/core/test_boundary_conditions.cc b/mia/core/test_boundary_conditions.cc
index ab8e05d..c13d74a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_callback.cc b/mia/core/test_callback.cc
index 9707717..6786ead 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 86a0d6a..463f366 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,18 @@
 #include <stdexcept>
 #include <climits>
 
+#include <config.h>
+#include <miaconfig.h>
+
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/internal/autotest.hh>
 
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
 NS_MIA_USE
 using namespace std;
 using namespace boost::unit_test;
@@ -77,7 +85,7 @@ BOOST_FIXTURE_TEST_CASE( test_set_option, CmdlineParserFixture )
 		BOOST_FAIL("error value not detected");
 	}
 	catch (invalid_argument& x) {
-		BOOST_MESSAGE(string("Caught:") + string(x.what()));
+		BOOST_TEST_MESSAGE(string("Caught:") + string(x.what()));
 	}
 }
 
@@ -161,7 +169,7 @@ BOOST_FIXTURE_TEST_CASE( test_float_option, CmdlineParserFixture )
 		BOOST_FAIL("error value not detected");
 	}
 	catch (invalid_argument& x) {
-		BOOST_MESSAGE(string("Caught:") + string(x.what()));
+		BOOST_TEST_MESSAGE(string("Caught:") + string(x.what()));
 	}
 }
 
@@ -187,7 +195,7 @@ BOOST_FIXTURE_TEST_CASE( test_int_option, CmdlineParserFixture )
 		BOOST_FAIL("error value not detected");
 	}
 	catch (invalid_argument& x) {
-		BOOST_MESSAGE(string("Caught:") + string(x.what()));
+		BOOST_TEST_MESSAGE(string("Caught:") + string(x.what()));
 	}
 }
 
@@ -295,7 +303,7 @@ BOOST_FIXTURE_TEST_CASE( test_parser, CmdlineParserFixture )
 	BOOST_CHECK_EQUAL(olist.parse(options.size(), (const char**)&options[0], "remaining"),  CCmdOptionList::hr_no);
 
 	for(auto i = olist.get_remaining().begin(); i != olist.get_remaining().end(); ++i)
-		BOOST_MESSAGE(*i);
+		BOOST_TEST_MESSAGE(*i);
 
 	BOOST_CHECK_EQUAL(int_value1,12);
 	BOOST_CHECK_EQUAL(int_value2,13);
@@ -422,7 +430,7 @@ BOOST_FIXTURE_TEST_CASE( test_parser_help_output, CmdlineParserFixture )
 			  "  -? --usage            print a short help\n"
 			  "     --version          print the version number and exit\n\n"
 			  "Processing               \n"
-#if defined(__PPC__) && ( TBB_INTERFACE_VERSION  < 6101 )
+#if defined(HAVE_TBB ) && defined(__PPC__) && ( TBB_INTERFACE_VERSION  < 6101 )
 			  "     --threads=1 (int)  Maxiumum number of threads to use for \n"
 #else
 			  "     --threads=-1 (int) \n"
@@ -436,7 +444,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-2015 Leipzig, \n"
+			  "  This software is Copyright (c) Gert Wollny 1999-2016 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"
@@ -463,3 +471,96 @@ BOOST_FIXTURE_TEST_CASE( test_parser_help_output, CmdlineParserFixture )
 	}
 }
 
+#ifdef HAVE_SYS_IOCTL_H
+
+class CmdLineWidthFixture: public CmdlineParserFixture
+{
+public: 
+	CmdLineWidthFixture();
+	~CmdLineWidthFixture();
+private:
+	struct winsize m_old_ws;
+}; 
+
+CmdLineWidthFixture::CmdLineWidthFixture()
+{
+	ioctl(0,TIOCGWINSZ,&m_old_ws); 
+}
+
+CmdLineWidthFixture::~CmdLineWidthFixture()
+{
+	ioctl(0,TIOCSWINSZ,&m_old_ws); 
+}
+
+
+BOOST_FIXTURE_TEST_CASE( test_parser_help_output_termfixedsize_small, CmdLineWidthFixture )
+{
+	int test; 
+	struct winsize ws;
+	ws.ws_col = 50;
+	ws.ws_row = 50;
+	
+	if (ioctl(0,TIOCSWINSZ,&ws)==0) {
+		CCmdOptionList olist(general_help_test);
+
+		vector<const char *> options;
+		options.push_back("self");
+		options.push_back("-h");
+
+		olist.add(make_opt(test, "lala", 'i', "a int option"));
+		BOOST_CHECK_EQUAL(olist.parse(options.size(), &options[0]), CCmdOptionList::hr_help);
+
+		
+	}
+}
+
+BOOST_FIXTURE_TEST_CASE( test_parser_help_output_termfixedsize_wide, CmdLineWidthFixture )
+{
+	int test; 
+	struct winsize ws;
+	ws.ws_col = 150;
+	ws.ws_row = 50;
+	
+	if (ioctl(0,TIOCSWINSZ,&ws)==0) {
+		CCmdOptionList olist(general_help_test);
+
+		vector<const char *> options;
+		options.push_back("self");
+		options.push_back("-h");
+
+		olist.add(make_opt(test, "lala", 'i', "a string option"));
+		BOOST_CHECK_EQUAL(olist.parse(options.size(), &options[0]), CCmdOptionList::hr_help);
+	}
+}
+
+#endif 
+
+BOOST_FIXTURE_TEST_CASE( test_repeat_option, CmdlineParserFixture )
+{
+
+	CCmdOptionList olist(general_help);
+
+	vector<int> value; 
+
+	olist.add(make_repeatable_opt(value, "int", 'i', "an intager repeatable option"));
+	vector<const char *> options;
+
+	options.push_back("self");
+	options.push_back("-i");
+	options.push_back("1");
+	options.push_back("-i");
+	options.push_back("2");
+	
+	BOOST_CHECK_EQUAL(olist.parse(options.size(), &options[0]), CCmdOptionList::hr_no); 
+
+	BOOST_CHECK_EQUAL( olist.get_remaining().size(), 0);
+	
+	BOOST_CHECK_EQUAL(value.size(), 2u);
+	BOOST_REQUIRE(value.size() == 2u);
+	
+	BOOST_CHECK_EQUAL(value[0], 1);
+	BOOST_CHECK_EQUAL(value[1], 2);
+}
+
+
+
diff --git a/mia/core/test_cmdlineparseroutput.cc b/mia/core/test_cmdlineparseroutput.cc
new file mode 100644
index 0000000..ed14343
--- /dev/null
+++ b/mia/core/test_cmdlineparseroutput.cc
@@ -0,0 +1,209 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 <climits>
+
+#include <mia/core/cmdlineparser.hh>
+#include <mia/core/msgstream.hh>
+
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#include <fcntl.h> 
+#endif
+
+#include<signal.h>
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+
+NS_MIA_USE
+using namespace std;
+
+struct CmdlineParserFixture {
+	CmdlineParserFixture():m_level(cverb.get_level()) {
+	}
+	~CmdlineParserFixture() {
+		cverb.set_verbosity(m_level);
+	}
+private:
+	vstream::Level m_level;
+
+};
+
+
+bool wait_for_child = true;
+
+void sig_usr(int signo)
+{
+	if (signo == SIGINT)
+		wait_for_child = false; 
+}
+
+
+bool fork_and_run_check(const char *me, const char *console_width, string& child_output)
+{
+        int aStdoutPipe[2];
+        
+	struct sigaction sig;
+	sigemptyset(&sig.sa_mask);          
+	sig.sa_flags = 0;
+	sig.sa_handler = sig_usr;
+	
+	wait_for_child = true;
+	
+	if (pipe2(aStdoutPipe, O_NONBLOCK) < 0) {
+                perror ("Allocatin stdout pipe");
+                return false; 
+        }
+        
+        cvdebug() << "Parent: About to fork" << endl; 
+	pid_t pid = fork();
+	if (!pid) { // child process
+
+                if (dup2(aStdoutPipe[1], STDOUT_FILENO) == -1) {
+                        perror("redirecting stdout");
+                        return false;
+                }
+                
+		execlp(me, me,
+		       "-w", console_width,
+		       "--internal",
+		       NULL);
+		cvfail() << "unable to start myself" << endl;
+		return false;
+	}else {
+		sigaction(SIGINT,&sig,NULL); 
+                cvdebug() << "Parent: Start reading" << endl; 
+                child_output.clear(); 
+                char c;
+
+                while (wait_for_child) {
+                        while(read(aStdoutPipe[0], &c, 1) == 1) {
+                                child_output.push_back(c);
+                        }
+                }
+                return true;
+	}
+}
+
+const SProgramDescription general_help {
+	{pdi_group, "Test"}, 
+	{pdi_short, "program tests"}, 
+	{pdi_description, "This program tests the command line parser output."}, 
+	{pdi_example_descr, "Example text"}, 
+	{pdi_example_code, "Example command"}
+};
+
+#ifdef MIA_COVERAGE
+extern "C" void __gcov_dump(void );
+#endif 
+
+int main(int argc, const char **args)
+{
+        int console_width = 60;
+        bool internal = false;
+        
+        CCmdOptionList options(general_help);
+        options.add(make_opt(console_width, "width", 'w', "set console width"));
+        options.add(make_opt(internal, "internal", 'i', "was forked" ));
+        
+        if (options.parse(argc, args) != CCmdOptionList::hr_no)
+                return -1;
+        
+        if (internal) {
+
+		int retvalue = 0; 
+                struct winsize ws;
+                int old_width = 100; 
+                if (ioctl(0,TIOCGWINSZ,&ws)==0) {
+                        old_width = ws.ws_col;
+			ws.ws_col = console_width;
+			
+			if (ioctl(0,TIOCSWINSZ,&ws)==0) {
+				CCmdOptionList olist(general_help);
+				int test = 0; 
+				vector<const char *> options;
+				options.push_back("self");
+				options.push_back("-h");
+				
+				olist.add(make_opt(test, "lala", 'i', "a string option"));
+				if (olist.parse(options.size(), &options[0]) == CCmdOptionList::hr_no) {
+					ws.ws_col = old_width;
+					if (ioctl(0,TIOCSWINSZ,&ws) !=0) {
+						cverr() << "Resetting console width failed\n"; 
+						retvalue = -1;
+					}
+				}else
+					retvalue = -1;
+			}else
+				retvalue = -1;
+                }else
+			retvalue = -1;
+
+		ws.ws_col = old_width;
+		ioctl(0,TIOCSWINSZ,&ws);
+
+		cverr() << "Send signal\n";
+		sleep(1); 
+		kill(getppid(), SIGINT);
+		sleep(1);
+
+		
+		return retvalue;
+		
+        } else {
+		
+                int retval = 0; 
+                // fork the tests
+                string child_output_100; 
+                if (fork_and_run_check(args[0], "100", child_output_100)) {
+                        if (child_output_100.size() != 1796) {
+                                cvfail() << "Output 100: expected 1796 bytes, got "
+                                         << child_output_100.size() <<"\n"; 
+                                retval = -3;
+                        }
+                }else 
+                        retval = -2;
+		
+		
+                string child_output_50; 
+                if (fork_and_run_check(args[0], "50", child_output_50)) {
+                        if (child_output_50.size() != 2241) {
+                                cvfail() << "Output 50: expected 2241 bytes, got "
+                                         << child_output_50.size() <<"\n"; 
+                                retval = -3;
+                        }
+                }else 
+                        retval = -2;
+
+
+                return retval; 
+        }
+}; 
+
diff --git a/mia/core/test_cmdoptionflags.cc b/mia/core/test_cmdoptionflags.cc
index 6aee087..f66ef24 100644
--- a/mia/core/test_cmdoptionflags.cc
+++ b/mia/core/test_cmdoptionflags.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_cmdparamoption.cc b/mia/core/test_cmdparamoption.cc
new file mode 100644
index 0000000..036097d
--- /dev/null
+++ b/mia/core/test_cmdparamoption.cc
@@ -0,0 +1,72 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 <climits>
+
+
+#include <mia/internal/autotest.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/core/cmdparamoption.hh>
+
+using namespace mia;
+using namespace std;
+
+const SProgramDescription general_help {
+	{pdi_group, "Test"}, 
+	{pdi_short, "program tests"}, 
+	{pdi_description, "This program tests the command line parser."}, 
+	{pdi_example_descr, "Example text"}, 
+	{pdi_example_code, "Example command"}
+};
+
+struct CmdlineParserFixture {
+	CmdlineParserFixture():m_level(cverb.get_level()) {
+	}
+	~CmdlineParserFixture() {
+		cverb.set_verbosity(m_level);
+	}
+private:
+	vstream::Level m_level;
+
+};
+
+BOOST_FIXTURE_TEST_CASE( test_string_repeatable_option, CmdlineParserFixture )
+{
+        const char *v1 = "string";
+        const char *v2 = "list"; 
+        
+        vector<string> value;
+	PCmdOption popt(make_repeatable_opt(value, "string", 's', "a string option"));
+
+        popt->set_value(v1);
+        
+        BOOST_CHECK_EQUAL(value.size(), 1u);
+        BOOST_REQUIRE(value.size() == 1);
+        BOOST_CHECK_EQUAL(value[0], v1);
+        
+        popt->set_value(v2);
+        BOOST_CHECK_EQUAL(value.size(), 2u);
+        BOOST_REQUIRE(value.size() == 2);
+        BOOST_CHECK_EQUAL(value[0], v1);
+        BOOST_CHECK_EQUAL(value[1], v2);
+        
+        //BOOST_CHECK_EQUAL(popt->get_value_as_string(), string(str_value));
+	
+}
diff --git a/mia/core/test_cmdtranslatoroption.cc b/mia/core/test_cmdtranslatoroption.cc
index 14d9fa9..4bea9e1 100644
--- a/mia/core/test_cmdtranslatoroption.cc
+++ b/mia/core/test_cmdtranslatoroption.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_cmdxmlhelp.cc b/mia/core/test_cmdxmlhelp.cc
new file mode 100644
index 0000000..41fa047
--- /dev/null
+++ b/mia/core/test_cmdxmlhelp.cc
@@ -0,0 +1,213 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 <climits>
+
+#include <mia/core/cmdlineparser.hh>
+#include <mia/core/msgstream.hh>
+#include <mia/core/testplugin.hh>
+
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#include <fcntl.h> 
+#endif
+
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
+
+/*
+  Wenn we ron coverage, then the child process sends a signal to the parent 
+  process to let the parent program terminate before the child that actually 
+  runs the interesting code is terminated. 
+*/
+#ifdef MIA_COVERAGE	
+#include<signal.h>
+#endif 
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+NS_MIA_USE
+using namespace std;
+
+#ifdef MIA_COVERAGE	
+bool wait_for_child = true;
+void sig_usr(int signo)
+{
+	if (signo == SIGINT)
+		wait_for_child = false; 
+}
+#endif 	
+
+bool fork_and_run_check(const char *me, vector<const char*  >& options, const string& expect)
+{
+        int aStdoutPipe[2];
+
+#ifdef MIA_COVERAGE	
+	struct sigaction sig;
+	sigemptyset(&sig.sa_mask);          
+	sig.sa_flags = 0;
+	sig.sa_handler = sig_usr;
+	wait_for_child = true;
+#endif 	
+        if (pipe2(aStdoutPipe, O_NONBLOCK) < 0) {
+                perror ("Allocatin stdout pipe");
+                return false; 
+        }
+        
+        cvdebug() << "Parent: About to fork" << endl; 
+	pid_t pid = fork();
+	if (!pid) { // child process
+
+                if (dup2(aStdoutPipe[1], STDOUT_FILENO) == -1) {
+                        perror("redirecting stdout");
+                        return false;
+                }
+                
+		execvp(me, (char* const* )&options[0]);
+		cvfail() << "unable to start myself" << endl;
+		return false;
+	}else {
+                cvdebug() << "Parent: Start reading" << endl; 
+
+                string child_output; 
+                char c;
+#ifdef MIA_COVERAGE
+		sigaction(SIGINT,&sig,NULL); 
+		while (wait_for_child) 
+#else 		
+		int result = -1;
+		while (!waitpid(pid, &result, WNOHANG)) 
+#endif
+		{
+                        while(read(aStdoutPipe[0], &c, 1) == 1) {
+                                child_output.push_back(c);
+                        }
+                }
+		bool test_result = child_output == expect;
+		if (!test_result) {
+			cvfail() << "Option '"<< options[1] << "' failed:\n";
+			cvfail() << "got "<< child_output.size() << " '"<< child_output << "'\n";
+			cvfail() << "expected "<< expect.size() << " '" << expect << "'\n\n";
+
+			for (unsigned i = 0; i < min(  expect.size(), child_output.size()); ++i){
+				if (child_output[i] != expect[i]) {
+					cvfail() << "First character error: " << i << " "
+						 << "got '" << child_output.substr(i)  << "', expect '" << expect.substr(i) << "'\n";
+					break; 
+				}
+			}
+		}
+		return test_result;
+	}
+}
+
+const SProgramDescription general_help {
+	{pdi_group, "Test"}, 
+	{pdi_short, "program tests"}, 
+	{pdi_description, "This program tests the command line parser output."}, 
+	{pdi_example_descr, "Example text"}, 
+	{pdi_example_code, "Example command"}
+};
+
+extern string expect_xml_help_start; 
+extern string expect_xml_help_end;
+
+int do_main(int argc, char **args)
+{
+	string required_option;
+	string other_required_option;  
+        CCmdOptionList options(general_help);
+        options.add("A", make_opt(required_option, "required", 'r',
+				   "some required option",
+				   CCmdOptionFlags::required_input));
+        options.add("A", make_opt(required_option, "other", 0,
+			     "other required option",
+			     CCmdOptionFlags::required_output));
+
+	options.set_stdout_is_result(); 
+	options.set_group("empty"); 
+
+	CPluginSearchpath sp(true);
+	sp.add("testplug"); 
+	CTestPluginHandler::set_search_path(sp);
+	
+        if (options.parse(argc, args, "plugin",
+			  &CTestPluginHandler::instance()) != CCmdOptionList::hr_no) {
+#ifdef MIA_COVERAGE
+		// strange, the output to std::cerr makes sure that the signal is received, 
+		// sleep(n) doesn't.
+		sleep(1); 
+		std::cerr << "\n"; 
+		kill(getppid(), SIGINT);
+#endif 
+		return 0;
+	}
+
+	string expect_xml_help = expect_xml_help_start + string(get_revision()) + expect_xml_help_end;
+	vector<const char*> arg{args[0],"--help-xml", "-", NULL};
+	
+
+	bool failed = false; 
+	if (!fork_and_run_check(args[0], arg, expect_xml_help)) {
+		failed = true; 
+	}
+
+	return failed ? EXIT_FAILURE : EXIT_SUCCESS; 
+}; 
+
+#include <mia/internal/main.hh>
+MIA_MAIN(do_main); 
+
+string expect_xml_help_start = "<?xml version=\"1.0\"?>\n"
+	"<program>\n"
+	"  <name>test-cmdxmlhelp</name>\n"
+	"  <version>"; 
+
+string expect_xml_help_end="</version>\n"
+	"  <section>Test</section>\n"
+"  <description>This program tests the command line parser output.</description>\n"
+"  <basic_usage> test-cmdxmlhelp -r <required> --other <value> [options] <PLUGINS:none/test></basic_usage>\n"
+"  <whatis>program tests</whatis>\n"
+"  <group name=\"A\">\n"
+"    <option short=\"r\" long=\"required\" default=\"\" type=\"string\"><flags>input required </flags>some required option</option>\n"
+"    <option short=\"\" long=\"other\" default=\"\" type=\"string\"><flags>output required </flags>other required option</option>\n"
+"  </group>\n"
+"  <group name=\"Help & Info\">\n"
+"    <option short=\"V\" long=\"verbose\" default=\"warning\" type=\"dict\">verbosity of output, print messages of given level and higher priorities. Supported priorities starting at lowest level are:<dict><value name=\"trace\">Function call trace</value><value name=\"debug\">Debug output</value><value name=\"info\">Low level messages</value><value name=\"message\">Normal messages</value><value name=\"warning\">Warnings</value><value name=\"fail\">Report test failures</value><value name= [...]
+"    <option short=\"\" long=\"copyright\" default=\"false\" type=\"bool\"><flags>nonipype </flags>print copyright information</option>\n"
+"    <option short=\"h\" long=\"help\" default=\"false\" type=\"bool\"><flags>nonipype </flags>print this help</option>\n"
+"    <option short=\"?\" long=\"usage\" default=\"false\" type=\"bool\"><flags>nonipype </flags>print a short help</option>\n"
+"    <option short=\"\" long=\"version\" default=\"false\" type=\"bool\"><flags>nonipype </flags>print the version number and exit</option>\n"
+"  </group>\n"
+"  <group name=\"Processing\">\n"
+"    <option short=\"\" long=\"threads\" default=\"-1\" type=\"int\">Maxiumum number of threads to use for processing,This number should be lower or equal to the number of logical processor cores in the machine. (-1: automatic estimation).Maxiumum number of threads to use for processing,This number should be lower or equal to the number of logical processor cores in the machine. (-1: automatic estimation).</option>\n"
+"  </group>\n"
+"  <freeparams name=\"none/test\" type=\"factory\"/>\n"
+"  <stdout-is-result/>\n"
+"  <handler name=\"none/test\">This is a handler for the test plug-ins<plugin name=\"dummy1\">test_dummy_symbol from dummy1</plugin><plugin name=\"dummy2\">test module with no data (2)</plugin><plugin name=\"dummy3\">test_dummy_symbol from dummy3</plugin></handler>\n"
+"  <Example>Example text<Code>Example command</Code></Example>\n"
+"  <Author>Gert Wollny</Author>\n"
+"</program>\n"; 
diff --git a/mia/core/test_cmeans.cc b/mia/core/test_cmeans.cc
index 384c76f..45fa899 100644
--- a/mia/core/test_cmeans.cc
+++ b/mia/core/test_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
 #include <mia/internal/autotest.hh>
 
 #include <cmath>
+#include <cstdint>
 #include <mia/core/cmeans.hh>
 
 
@@ -51,7 +52,7 @@ CTestFixedInitializer::CTestFixedInitializer(const CMeans::DVector& init):
 {
 }
 
-CMeans::DVector CTestFixedInitializer::run(const CMeans::NormalizedHistogram& nh) const
+CMeans::DVector CTestFixedInitializer::run(const CMeans::NormalizedHistogram& MIA_PARAM_UNUSED(nh)) const
 {
 	return m_init; 
 }
@@ -98,7 +99,11 @@ BOOST_AUTO_TEST_CASE( test_even_initialized )
 	vector<double> centers{30, 120, 220, 300, 390};
 	vector<double> weights{2.0, 0.9, 1.3, 1.1, 0.9};
 
-	vector<double> expect{34.34, 105.31, 214.627, 278.295, 383.15};
+	vector<double> expect{34.438498496123287,
+			118.45642796465776,
+			215.64776588197637,
+			290.79720889114071,
+			385.55101288097893}; 
 
 	double k = 20;
 	for (int i = 0; i < 250; ++i) {
@@ -111,7 +116,7 @@ BOOST_AUTO_TEST_CASE( test_even_initialized )
 	}
 
 	CMeans::PInitializer cci(new CTestFixedInitializer({0, 0.25, 0.5, 0.75, 1}));
-	CMeans cm(0.01, 0.0001, cci);
+	CMeans cm(0.0001, cci);
 
 
 	CMeans::DVector result_cci(5); 
@@ -210,5 +215,81 @@ BOOST_AUTO_TEST_CASE( test_get_fuzzy )
 	BOOST_CHECK_CLOSE(fuzzy0[0], 6, 0.01);
 	BOOST_CHECK_CLOSE(fuzzy0[1], 9, 0.01);
 	BOOST_CHECK_CLOSE(fuzzy0[2], 9, 0.01);	
+}
+
+// Helper class neede to get a container with only one template parameter
+// that is needed by the cmeans templates 
+// template alias doesn't cut it. 
+
+template <typename T>
+class Vec: public std::vector<T> {
+public:
+	using vector<T>::vector; 
+}; 
+
+
+BOOST_AUTO_TEST_CASE( test_cmeans_evaluate_probabilities_IF )
+{
+	Vec<uint16_t> image = {1,     2,   3,   4,   5};
+	Vec<float>    gain =  {1.0, 2.0, 1.0, 2.0, 0.5};
+	vector<double>   class_centers = {1.5, 3.5};
+
+	Vec<Vec<float>> pv(2, Vec<float>(5));
+
+	cmeans_evaluate_probabilities(image, gain, class_centers, pv);
+
+	BOOST_CHECK_EQUAL(pv[0][0], 1.0);
+	BOOST_CHECK_EQUAL(pv[1][0], 0.0); 
+
+	BOOST_CHECK_EQUAL(pv[0][1], 1.0);
+	BOOST_CHECK_EQUAL(pv[1][1], 0.0); 
+
+	BOOST_CHECK_EQUAL(pv[0][2], 0.25f / 2.5f); // 1.5 - 3 - 3.5    (2.25   0.25)  / 2.5 
+	BOOST_CHECK_EQUAL(pv[1][2], 2.25f / 2.5f); 
+
+	BOOST_CHECK_EQUAL(pv[0][3], .9f); 
+	BOOST_CHECK_EQUAL(pv[1][3], .1f); 
+
+	BOOST_CHECK_EQUAL(pv[0][4], 0.0);
+	BOOST_CHECK_EQUAL(pv[1][4], 1.0); 
+	
 	
+		
+}
+
+BOOST_AUTO_TEST_CASE( test_cmeans_update_class_centers )
+{
+	Vec<uint16_t> image = {1,    2,   3,   4,   5};
+	Vec<float>    gain =  {1.0, 2.0, 1.0, 2.0, 0.5};
+	vector<double>   class_centers = {1.0, 3.0};
+
+	Vec<Vec<float>> pv(2, Vec<float>(5));
+
+	pv[0][0]= 1.0;
+	pv[0][1]= 1.0;
+	pv[0][2]= 0.25f / 2.5f; // 1.5 - 3 - 3.5    (2.25   0.25)  / 2.5
+	pv[0][3]= .9f;
+	pv[0][4]= 0.0;
+	
+	pv[1][0]= 0.0; 
+	pv[1][1]= 0.0; 
+	pv[1][2]= 2.25f / 2.5f; 
+	pv[1][3]= .1f; 
+	pv[1][4]= 1.0; 
+	
+	//double test_class_center1_w = 1 + 4  + 0.25 * 0.25 / 2.5 / 2.5 * 3 + 0.9 * 0.9 * 8;
+	//double test_class_center1_n = 1 + 4  + 0.25 * 0.25 / 2.5 / 2.5 * 1 + 0.9 * 0.9 * 4;
+
+         //double test_class_center2_w = 2.25 * 2.25 / 2.5 / 2.5 * 3 + 0.1 * 0.1 * 8 + 2,5;
+	//double test_class_center2_n = 2.25 * 2.25 / 2.5 / 2.5 * 1 + 0.1 * 0.1 * 4 + 0.25;
+
+
+	
+	double r =  cmeans_update_class_centers(image, gain,pv, class_centers); 
+		
+	BOOST_CHECK_CLOSE(class_centers[0], 1.197575757, 0.001);
+	BOOST_CHECK_CLOSE(class_centers[1], 3.777272727, 0.001);
+
+	BOOST_CHECK_CLOSE(r, sqrt(.197575757  * .197575757 + .777272727 * .777272727), 0.001); 
+
 }
diff --git a/mia/core/test_core.cc b/mia/core/test_core.cc
index 68124a9..a837aea 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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/cmdlineparser.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/core/file.hh>
+#include <mia/core/utils.hh>
 
 
 NS_MIA_USE
@@ -36,6 +37,26 @@ using namespace std;
 using namespace boost::unit_test;
 namespace bfs = ::boost::filesystem;
 
+BOOST_AUTO_TEST_CASE( test_cwdsaver )
+{
+
+	char old_cwd[PATH_MAX +1]; 
+	BOOST_CHECK_EQUAL(getcwd(old_cwd, PATH_MAX), old_cwd); 
+
+	{
+		CCWDSaver wd;
+		BOOST_CHECK(!chdir(".."));
+		char test_cwd[PATH_MAX +1];
+		BOOST_CHECK_EQUAL(getcwd(test_cwd, PATH_MAX), test_cwd);
+		// test that we are no longer in the same directory
+		BOOST_CHECK(strcmp(test_cwd, old_cwd));  
+	}
+	char test_cwd2[PATH_MAX +1];
+	BOOST_CHECK_EQUAL(getcwd(test_cwd2, PATH_MAX), test_cwd2);
+	BOOST_CHECK(!strcmp(test_cwd2, old_cwd));
+}
+
+
 
 BOOST_AUTO_TEST_CASE( test_file)
 {
@@ -64,7 +85,7 @@ BOOST_AUTO_TEST_CASE( test_file)
 		BOOST_FAIL("'this-file-should-not-exist.11111' was opened for reading");
 	}
 	catch (runtime_error& x) {
-		BOOST_MESSAGE(string("caught an expected exception:") + x.what());
+		cvdebug() << "test_file: caught an expected exception:" <<  x.what() <<"\n";
 	}
 
 	try {
@@ -73,7 +94,7 @@ BOOST_AUTO_TEST_CASE( test_file)
 	}
 
 	catch (runtime_error& x) {
-		BOOST_MESSAGE(string("caught an expected exception:") + x.what());
+		cvdebug() << "test_file: caught an expected exception:" << x.what() << "\n";
 	}
 }
 
diff --git a/mia/core/test_core_combined.cc b/mia/core/test_core_combined.cc
new file mode 100644
index 0000000..24c4161
--- /dev/null
+++ b/mia/core/test_core_combined.cc
@@ -0,0 +1,16 @@
+
+
+#include <mia/core/test_core.cc>
+#include <mia/core/test_cost.cc>
+#include <mia/core/test_filter.cc>
+#include <mia/core/test_kernels.cc>
+#include <mia/core/test_optparam.cc>
+#include <mia/core/test_optionparser.cc>
+#include <mia/core/test_parameter.cc>
+#include <mia/core/test_pixeltype.cc>
+#include <mia/core/test_register.cc>
+#include <mia/core/test_sqmin.cc>
+#include <mia/core/test_streamredir.cc>
+#include <mia/core/test_dictmap.cc>
+#include <mia/core/test_fifofilter.cc>
+#include <mia/core/test_probmap.cc>
diff --git a/mia/core/test_cost.cc b/mia/core/test_cost.cc
index e4ecc71..f4d6f23 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 968253b..14b43f7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6f853a3..44d8beb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 @@
 #include <mia/core/msgstream.hh>
 
 #include <mia/core/datapool.hh>
+#include <mia/core/parallel.hh>
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-#include <tbb/atomic.h>
-using namespace tbb;
 
 
 NS_MIA_USE
@@ -97,17 +94,17 @@ BOOST_AUTO_TEST_CASE( test_pool_clear )
 }
 
 struct PoolAccessTest {
-	tbb::atomic<int> *n_errors; 
-	PoolAccessTest(tbb::atomic<int> *_nerr); 
-	void operator()( const blocked_range<int>& range ) const; 
+	ATOMIC<int> *n_errors; 
+	PoolAccessTest(ATOMIC<int> *_nerr); 
+	void operator()( const C1DParallelRange& range ) const; 
 }; 
 
-PoolAccessTest::PoolAccessTest(tbb::atomic<int> *_nerr):
+PoolAccessTest::PoolAccessTest(ATOMIC<int> *_nerr):
 	n_errors(_nerr)
 { 
 }
 
-void PoolAccessTest::operator() ( const blocked_range<int>& range ) const
+void PoolAccessTest::operator() ( const C1DParallelRange& range ) const
 {
 	try {	
 		for(auto i=range.begin(); i!=range.end(); ++i ) {
@@ -127,27 +124,27 @@ void PoolAccessTest::operator() ( const blocked_range<int>& range ) const
 
 BOOST_AUTO_TEST_CASE( test_pool_parallel_access )
 {
-	tbb::atomic<int> n_errors;
+	ATOMIC<int> n_errors;
 	n_errors = 0; 
 	PoolAccessTest ptest(&n_errors); 
 	
-	blocked_range<int> range( 0, 1000, 1 ); 
-	parallel_for(range, ptest); 
+	C1DParallelRange range( 0, 1000, 1 ); 
+	pfor(range, ptest); 
 	BOOST_CHECK_EQUAL(n_errors, 0); 
 }
 
 struct PoolWriteLaterReadTest {
-	tbb::atomic<int> *n_errors; 
-	PoolWriteLaterReadTest(tbb::atomic<int> *_nerr); 
-	void operator()( const blocked_range<int>& range ) const; 
+	ATOMIC<int> *n_errors; 
+	PoolWriteLaterReadTest(ATOMIC<int> *_nerr); 
+	void operator()( const C1DParallelRange& range ) const; 
 }; 
 
-PoolWriteLaterReadTest::PoolWriteLaterReadTest(tbb::atomic<int> *_nerr):
+PoolWriteLaterReadTest::PoolWriteLaterReadTest(ATOMIC<int> *_nerr):
 	n_errors(_nerr)
 { 
 }
 
-void PoolWriteLaterReadTest::operator() ( const blocked_range<int>& range ) const
+void PoolWriteLaterReadTest::operator() ( const C1DParallelRange& range ) const
 {
 	try {	
 		for( int i=range.begin(); i!=range.end(); ++i ) {
@@ -171,11 +168,11 @@ void PoolWriteLaterReadTest::operator() ( const blocked_range<int>& range ) cons
 
 BOOST_AUTO_TEST_CASE( test_pool_parallel_access_2 )
 {
-	tbb::atomic<int> n_errors; 
+	ATOMIC<int> n_errors; 
 	n_errors = 0; 
 	PoolWriteLaterReadTest ptest(&n_errors); 
 	
-	blocked_range<int> range( 0, 1000, 5 ); 
-	parallel_for(range, ptest); 
+	C1DParallelRange range( 0, 1000, 5 ); 
+	pfor(range, ptest); 
 	BOOST_CHECK_EQUAL(n_errors, 0); 
 }
diff --git a/mia/core/test_delayedparameter.cc b/mia/core/test_delayedparameter.cc
index 83c0c08..e8d2249 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b007646..b7650dd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8398dc3..51812b5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ BOOST_AUTO_TEST_CASE( test_distance_from_inifinity )
 			     4, 9, 16, 25 };
 	
 	vector<float> src(16); 
-	distance_transform_prepare(in_1d.begin(), in_1d.end(),src.begin()); 	
+	distance_transform_prepare(in_1d.begin(), in_1d.end(),src.begin(), true); 	
 	distance_transform_inplace(src);
 	
 	for (size_t i = 0; i < 16; ++i) {
@@ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE( test_distance_from_function )
 	float out_1d[16] = {  5, 4,  1, 0, 1, 4,  9,  9,  4,   1, 0,  1,   4,  8,  13,  20};
 	
 	vector<float> src(16); 
-	distance_transform_prepare(&in_1d[0], &in_1d[16],src.begin()); 
+	distance_transform_prepare(&in_1d[0], &in_1d[16],src.begin(), false); 
 	distance_transform_inplace(src);
 	
 	for (size_t i = 0; i < 16; ++i) {
diff --git a/mia/core/test_factoryoption.cc b/mia/core/test_factoryoption.cc
index aedf540..4beba21 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_fastica.cc b/mia/core/test_fastica.cc
new file mode 100644
index 0000000..ac8e892
--- /dev/null
+++ b/mia/core/test_fastica.cc
@@ -0,0 +1,184 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/core/fastica.hh>
+#include <mia/core/cmdlineparser.hh>
+
+#include <mia/core/gsl_matrix_vector_ops.hh>
+
+#include <gsl/gsl_blas.h>
+
+using gsl::Matrix; 
+using namespace mia; 
+
+BOOST_AUTO_TEST_CASE ( test_fastica_symm ) 
+{
+	// create the components and the mixing matrix 
+
+	const double c[] = {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,  
+			    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 
+			    0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1};
+
+	Matrix in_ics(3, 13, c); 
+	const int steps = 101; 
+
+	Matrix in_mixing_matrix(steps, 3, false);
+
+	auto c0 = in_mixing_matrix.get_column(0);
+	auto c1 = in_mixing_matrix.get_column(1);
+	auto c2 = in_mixing_matrix.get_column(2);
+
+	// sin(x) ; cos(x); sin(2x)
+	for ( int i = 0; i < steps; ++i) {
+		cvdebug() << "init row " << i << "\n"; 
+		double x = (M_PI * (i - (steps- 1)/2)) / steps;
+		c0[i] = sin(x); 
+		c1[i] = cos(x); 
+		c2[i] = sin(2 * x);
+	}
+	
+	Matrix mix = in_mixing_matrix * in_ics; 
+	
+
+	FastICA ica(3);
+
+	ica.set_approach(FastICA::appr_symm); 
+ 	ica.set_epsilon (1e-10); 
+	ica.set_finetune(true); 
+	ica.set_nonlinearity(produce_fastica_nonlinearity("pow3")); 
+	BOOST_CHECK(ica.separate(mix)); 
+	
+	
+	const gsl::Matrix& out_mixing_matrix = ica.get_mixing_matrix();
+	const gsl::Matrix& out_ics = ica.get_independent_components();
+
+	// the mixes should be close to orthogonal 
+	
+	for (unsigned int c = 1; c < out_mixing_matrix.cols(); ++c) {
+		auto col_a = out_mixing_matrix.get_column(c); 
+		double na = 0.0; 
+		gsl_blas_ddot(col_a, col_a, &na); 
+		for (unsigned int c1 = 0; c1 < c; ++c1) {
+			auto col_b = out_mixing_matrix.get_column(c1); 
+			auto dot = 1.0; 
+			double nb = 0.0; 
+			gsl_blas_ddot(col_b, col_b, &nb); 
+			gsl_blas_ddot(col_a, col_b, & dot); 
+			BOOST_CHECK_SMALL(dot, 0.1 * na * nb); 
+		}
+	}
+
+
+	BOOST_CHECK_EQUAL(out_mixing_matrix.rows(), in_mixing_matrix.rows()); 
+	BOOST_CHECK_EQUAL(out_mixing_matrix.cols(), in_mixing_matrix.cols()); 
+	BOOST_CHECK_EQUAL(out_ics.rows(), in_ics.rows()); 
+	BOOST_CHECK_EQUAL(out_ics.cols(), in_ics.cols()); 
+	
+	// create the remix and test it against the input mix
+	
+
+	Matrix remix = out_mixing_matrix * out_ics;
+	Matrix delta = remix - mix; 
+	
+	for(auto id = delta.begin(); id != delta.end(); ++id) {
+		BOOST_CHECK_SMALL(*id, 1e-10); 
+	}
+	
+}
+
+
+
+BOOST_AUTO_TEST_CASE ( test_fastica_defl ) 
+{
+	// create the components and the mixing matrix 
+
+	const double c[] = {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,  
+			    0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 
+			    0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1};
+
+	Matrix in_ics(3, 13, c); 
+	const int steps = 101; 
+
+	Matrix in_mixing_matrix(steps, 3, false);
+
+	auto c0 = in_mixing_matrix.get_column(0);
+	auto c1 = in_mixing_matrix.get_column(1);
+	auto c2 = in_mixing_matrix.get_column(2);
+
+	// sin(x) ; cos(x); sin(2x)
+	for ( int i = 0; i < steps; ++i) {
+		cvdebug() << "init row " << i << "\n"; 
+		double x = (M_PI * (i - (steps- 1)/2)) / steps;
+		c0[i] = sin(x); 
+		c1[i] = cos(x); 
+		c2[i] = sin(2 * x);
+	}
+	
+	Matrix mix = in_mixing_matrix * in_ics; 
+	
+
+	FastICA ica(3);
+
+	ica.set_approach(FastICA::appr_defl); 
+ 	ica.set_epsilon (1e-10); 
+	ica.set_finetune(true); 
+	ica.set_stabilization(true); 
+	ica.set_nonlinearity(produce_fastica_nonlinearity("pow3")); 
+	BOOST_CHECK(ica.separate(mix)); 
+	
+	
+	const gsl::Matrix& out_mixing_matrix = ica.get_mixing_matrix();
+	const gsl::Matrix& out_ics = ica.get_independent_components();
+
+	// the mixes should be close to orthogonal 
+	
+	for (unsigned int c = 1; c < out_mixing_matrix.cols(); ++c) {
+		auto col_a = out_mixing_matrix.get_column(c); 
+		double na = 0.0; 
+		gsl_blas_ddot(col_a, col_a, &na); 
+		for (unsigned int c1 = 0; c1 < c; ++c1) {
+			auto col_b = out_mixing_matrix.get_column(c1); 
+			auto dot = 1.0; 
+			double nb = 0.0; 
+			gsl_blas_ddot(col_b, col_b, &nb); 
+			gsl_blas_ddot(col_a, col_b, & dot); 
+			BOOST_CHECK_SMALL(dot, 0.1 * na * nb); 
+		}
+	}
+
+
+	BOOST_CHECK_EQUAL(out_mixing_matrix.rows(), in_mixing_matrix.rows()); 
+	BOOST_CHECK_EQUAL(out_mixing_matrix.cols(), in_mixing_matrix.cols()); 
+	
+
+	BOOST_CHECK_EQUAL(out_ics.rows(), in_ics.rows()); 
+	BOOST_CHECK_EQUAL(out_ics.cols(), in_ics.cols()); 
+
+	Matrix remix = out_mixing_matrix * out_ics;
+	Matrix delta = remix - mix; 
+	
+	for(auto id = delta.begin(); id != delta.end(); ++id) {
+		BOOST_CHECK_SMALL(*id, 1e-10); 
+	}
+	
+}
diff --git a/mia/core/test_fft1d.cc b/mia/core/test_fft1d.cc
index 8491245..4fd5afb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f38af19..874c28b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 7bb4e8e..32d7d5a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@
  */
 
 #define BOOST_TEST_DYN_LINK
-
-#define EXPORT_HANDLER
 #include <cassert>
 #include <iostream>
 #include <cmath>
diff --git a/mia/core/test_filetools.cc b/mia/core/test_filetools.cc
index 564fb8b..bb8e0ca 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,12 +18,18 @@
  *
  */
 
-#include <stdexcept>
-#include <climits>
 
 #include <mia/internal/autotest.hh>
 #include <mia/core/filetools.hh>
 
+#include <stdexcept>
+#include <climits>
+
+
+#ifndef MAX_PATH
+#define MAX_PATH 4096
+#endif
+
 
 NS_MIA_USE
 using namespace std;
@@ -81,6 +87,37 @@ BOOST_FIXTURE_TEST_CASE( test_split_filename_number_pattern, Fixture_filename_sp
 
 }
 
+BOOST_AUTO_TEST_CASE( test_get_consecutive_numbered_files )
+{
+	string filename(MIA_SOURCE_ROOT"/testdata/IM-0001-0000.dcm");
+	size_t minrange = 0;
+	size_t maxrange = 0;
+	size_t format_width = 0; 
+	
+	auto result = get_filename_pattern_and_range(filename, minrange, maxrange, format_width);
+
+	BOOST_CHECK_EQUAL(minrange, 1u); 
+	BOOST_CHECK_EQUAL(maxrange, 18u); 
+	BOOST_CHECK_EQUAL(format_width, 4u);
+	BOOST_CHECK_EQUAL(result, string(MIA_SOURCE_ROOT"/testdata/IM-0001-%04d.dcm")); 
+}
+
+BOOST_AUTO_TEST_CASE( test_get_filename_pattern_and_range )
+{
+	string filename(MIA_SOURCE_ROOT"/testdata/IM-0001-0000.dcm");
+
+	auto filenames = get_consecutive_numbered_files(filename);
+
+	BOOST_CHECK_EQUAL(filenames.size(), 17u);
+	for (unsigned i = 1; i < filenames.size(); ++i) {
+		char buffer[MAX_PATH +1]; 
+		snprintf(buffer, MAX_PATH, MIA_SOURCE_ROOT"/testdata/IM-0001-%04d.dcm", i);
+		BOOST_CHECK_EQUAL(filenames[i-1], string(buffer));
+	}
+}
+
+
+
 void Fixture_filename_split_pattern::run(const string& name, const string& expect_base,
 					  const string& expect_suffix, const string& expect_number) const
 {
diff --git a/mia/core/test_filter.cc b/mia/core/test_filter.cc
index 736bae7..cf741e1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 dd6958d..b2f416b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 fed4c3c..366a4bd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5b9cfbe..5f1d49f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_gsl_matrix.cc b/mia/core/test_gsl_matrix.cc
new file mode 100644
index 0000000..d89c3dd
--- /dev/null
+++ b/mia/core/test_gsl_matrix.cc
@@ -0,0 +1,707 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 BOOST_TEST_DYN_LINK
+#define BOOST_TEST_DYN_LINK
+#endif
+
+#define BOOST_TEST_MAIN
+#define BOOST_TEST_ALTERNATIVE_INIT_API
+#include <boost/test/unit_test.hpp>
+#include <boost/test/floating_point_comparison.hpp>
+#include <mia/core/gsl_matrix.hh>
+
+#include <stdexcept>
+#include <sstream>
+
+using namespace gsl; 
+using namespace ::boost;
+using namespace ::boost::unit_test;
+
+using std::ostringstream;
+using std::string; 
+
+BOOST_AUTO_TEST_CASE( test_matrix_alloc_and_free ) 
+{
+	Matrix m(2,3, true); 
+	BOOST_CHECK_EQUAL(m.rows(), 2u); 
+	BOOST_CHECK_EQUAL(m.cols(), 3u); 
+
+	for(size_t i = 0; i < 2;++i) 
+		for(size_t j = 0; j < 2;++j) 
+			BOOST_CHECK_EQUAL(m(i,j), 0.0); 
+
+	m.set(1,2, 1.0); 
+	BOOST_CHECK_EQUAL(m(1,2), 1.0); 
+	
+	Matrix k(m); 
+	BOOST_CHECK_EQUAL(k.rows(), 2u); 
+	BOOST_CHECK_EQUAL(k.cols(), 3u); 
+	BOOST_CHECK_EQUAL(k(1,2), 1.0); 
+
+	k.set(0,2, 2.0); 
+	BOOST_CHECK_EQUAL(k(0,2), 2.0); 
+
+	m = k; 
+	BOOST_CHECK_EQUAL(k(0,2), 2.0); 
+
+}
+
+
+BOOST_AUTO_TEST_CASE( test_with_init ) 
+{
+	const double input[6]  = { 
+		1,2,3,4,5,6
+	}; 
+	
+	Matrix m(2,3, input); 
+
+	BOOST_CHECK_EQUAL(m(0,0), 1); 
+	BOOST_CHECK_EQUAL(m(0,1), 2); 
+	BOOST_CHECK_EQUAL(m(0,2), 3); 
+	BOOST_CHECK_EQUAL(m(1,0), 4); 
+	BOOST_CHECK_EQUAL(m(1,1), 5); 
+	BOOST_CHECK_EQUAL(m(1,2), 6); 
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_copy_ops ) 
+{
+	Matrix m(2,3, 2.0); 
+
+	BOOST_CHECK_EQUAL(m(0,0), 2.0); 
+	BOOST_CHECK_EQUAL(m(0,1), 2.0); 
+	BOOST_CHECK_EQUAL(m(0,2), 2.0); 
+	BOOST_CHECK_EQUAL(m(1,0), 2.0); 
+	BOOST_CHECK_EQUAL(m(1,1), 2.0); 
+	BOOST_CHECK_EQUAL(m(1,2), 2.0);
+
+	Matrix m2(2,3, 1.0);
+
+	BOOST_CHECK_EQUAL(m2.rows(), 2u); 
+	BOOST_CHECK_EQUAL(m2.cols(), 3u); 
+			  
+	m2.reset(3, 2, 3.0);
+
+	BOOST_CHECK_EQUAL(m2.rows(), 3u); 
+	BOOST_CHECK_EQUAL(m2.cols(), 2u);
+	
+	BOOST_CHECK_EQUAL(m2(0,0), 3.0); 
+	BOOST_CHECK_EQUAL(m2(0,1), 3.0); 
+	BOOST_CHECK_EQUAL(m2(1,0), 3.0); 
+	BOOST_CHECK_EQUAL(m2(1,1), 3.0); 
+	BOOST_CHECK_EQUAL(m2(2,0), 3.0); 
+	BOOST_CHECK_EQUAL(m2(2,1), 3.0);
+
+	Matrix *m3 = &m2;
+	m3->reset(2, 3, 4.0); 
+	
+	m2 = *m3;
+
+	BOOST_CHECK_EQUAL(m2.rows(), 2u); 
+	BOOST_CHECK_EQUAL(m2.cols(), 3u);
+	
+	BOOST_CHECK_EQUAL(m2(0,0), 4.0); 
+	BOOST_CHECK_EQUAL(m2(0,1), 4.0); 
+	BOOST_CHECK_EQUAL(m2(0,2), 4.0); 
+	BOOST_CHECK_EQUAL(m2(1,0), 4.0); 
+	BOOST_CHECK_EQUAL(m2(1,1), 4.0); 
+	BOOST_CHECK_EQUAL(m2(1,2), 4.0);
+
+	m2 = m;
+
+	BOOST_CHECK_EQUAL(m2.rows(), 2u); 
+	BOOST_CHECK_EQUAL(m2.cols(), 3u); 
+	
+	BOOST_CHECK_EQUAL(m2(0,0), 2.0); 
+	BOOST_CHECK_EQUAL(m2(0,1), 2.0); 
+	BOOST_CHECK_EQUAL(m2(0,2), 2.0); 
+	BOOST_CHECK_EQUAL(m2(1,0), 2.0); 
+	BOOST_CHECK_EQUAL(m2(1,1), 2.0); 
+	BOOST_CHECK_EQUAL(m2(1,2), 2.0);
+
+
+	const double in_values[6] = {5, 6, 7, 8, 9, 2};
+	const double *iv = in_values;
+
+	for (auto im = m.begin(); im != m.end(); ++im, ++iv){
+		*im = *iv;
+	}
+	
+	BOOST_CHECK_EQUAL(m(0,0), 5.0); 
+	BOOST_CHECK_EQUAL(m(0,1), 6.0); 
+	BOOST_CHECK_EQUAL(m(0,2), 7.0); 
+	BOOST_CHECK_EQUAL(m(1,0), 8.0); 
+	BOOST_CHECK_EQUAL(m(1,1), 9.0); 
+	BOOST_CHECK_EQUAL(m(1,2), 2.0);
+
+	auto im = m.begin(); 
+	BOOST_CHECK(im == m.begin()); 
+}
+
+BOOST_AUTO_TEST_CASE( test_print )
+{
+	Matrix m;
+	ostringstream s_empty;
+	s_empty << m;
+
+	BOOST_CHECK_EQUAL(s_empty.str(), string("[(null)]"));
+
+	double v[] = {1, 2}; 
+	
+	Matrix m12(1, 2, v);
+	ostringstream s_simple12;
+	s_simple12 << m12;
+	BOOST_CHECK_EQUAL(s_simple12.str(), string("[\n  1, 2, \n]"));
+	
+	const gsl_matrix *gslm = m12;
+	Matrix cm12(gslm);
+	ostringstream s_csimple12;
+	s_csimple12 << cm12;
+	BOOST_CHECK_EQUAL(s_csimple12.str(), string("[(const)\n  1, 2, \n]"));
+	
+	
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_const_iterator )
+{
+	const double input[6]  = { 
+		1,2,3,4,5,6
+	}; 
+	
+	Matrix m(2,3, input);
+
+	int v = 1; 
+	for ( auto i = m.begin(); i != m.end(); ++i, ++v) {
+		BOOST_CHECK_EQUAL(*i, v); 
+	}
+
+	auto i = m.begin();
+	BOOST_CHECK(i == m.begin()); 
+}
+
+BOOST_AUTO_TEST_CASE( test_sum )
+{
+	const double input1[6]  = { 
+		1,2,3,4,5,6
+	};
+	
+	const double input2[6]  = { 
+		5,4,3,2,1,0
+	}; 
+
+	
+	Matrix m1(2, 3, input1);
+	Matrix m2(2, 3, input2);
+
+	Matrix m3 = m1 + m2;
+
+	BOOST_CHECK_EQUAL(m3.rows(), 2u); 
+	BOOST_CHECK_EQUAL(m3.cols(), 3u); 
+	
+	BOOST_CHECK_EQUAL(m3(0,0), 6.0); 
+	BOOST_CHECK_EQUAL(m3(0,1), 6.0); 
+	BOOST_CHECK_EQUAL(m3(0,2), 6.0); 
+	BOOST_CHECK_EQUAL(m3(1,0), 6.0); 
+	BOOST_CHECK_EQUAL(m3(1,1), 6.0); 
+	BOOST_CHECK_EQUAL(m3(1,2), 6.0);
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_sum_fail )
+{
+	const double input1[6]  = { 
+		1,2,3,4,5,6
+	};
+	
+	const double input2[6]  = { 
+		5,4,3,2,1,0
+	}; 
+
+	
+	Matrix m1(2, 3, input1);
+	Matrix m2(3, 2, input2);
+
+	// this must fail 
+	BOOST_CHECK_THROW(m1 + m2, std::logic_error); 
+
+	
+}
+
+
+
+BOOST_AUTO_TEST_CASE( test_transpose ) 
+{
+	const double input[6]  = { 
+		1,2,3,4,5,6
+	}; 
+	
+	Matrix m(2,3, input); 
+	
+	auto t = m.transposed(); 
+
+	BOOST_CHECK_EQUAL(t.rows(), 3); 
+	BOOST_CHECK_EQUAL(t.cols(), 2); 
+	
+	BOOST_CHECK_EQUAL(t(0,0), 1); 
+	BOOST_CHECK_EQUAL(t(1,0), 2); 
+	BOOST_CHECK_EQUAL(t(2,0), 3); 
+	BOOST_CHECK_EQUAL(t(0,1), 4); 
+	BOOST_CHECK_EQUAL(t(1,1), 5); 
+	BOOST_CHECK_EQUAL(t(2,1), 6); 
+	
+}
+
+
+BOOST_AUTO_TEST_CASE( test_matrix_column_covariance ) 
+{
+	const double input[50]  = { 
+		1, 2, 3, 2, 1, 
+		2, 1, 2, 5, 2, 
+		3, 2, 5, 2, 5, 
+		2, 6, 2, 3, 8, 
+		4, 1, 6, 2, 1, 
+		4, 1, 2, 5, 5, 
+		2, 2, 3, 8, 7, 
+		2, 4, 8, 1, 4, 
+		1, 2, 3, 2, 2, 
+		5, 4, 2, 3, 3
+	}; 
+
+	Matrix m(10, 5, input); 
+	
+	auto cov = m.column_covariance(); 
+	
+
+	BOOST_CHECK_EQUAL(cov.rows(), 5); 
+	BOOST_CHECK_EQUAL(cov.cols(), 5); 
+
+	
+	const double test[25]  = {  
+		1.82222,  -0.11111,  -0.06667,   0.13333,   0.02222,
+		-0.11111,   2.72222,   0.00000,  -0.94444,   2.11111,
+		-0.06667,   0.00000,   4.26667,  -2.31111,  -0.86667,
+		0.13333,  -0.94444,  -2.31111,   4.45556,   2.28889,
+		0.02222,   2.11111,  -0.86667,   2.28889,   5.95556
+	}; 
+	
+	auto t = test; 
+	for (unsigned  r = 0; r < cov.rows(); ++r) 
+		for (unsigned  c = 0; c < cov.cols(); ++c, ++t) {
+			if (*t == 0.0) 
+				BOOST_CHECK_SMALL(cov(r,c), 1e-10); 
+			else 
+				BOOST_CHECK_CLOSE(cov(r,c), *t, 0.1); 
+		}
+}
+
+BOOST_AUTO_TEST_CASE( test_matrix_row_covariance ) 
+{
+	const double input[50]  = { 
+		1, 2, 3, 2, 1, 
+		2, 1, 2, 5, 2, 
+		3, 2, 5, 2, 5, 
+		2, 6, 2, 3, 8, 
+		4, 1, 6, 2, 1, 
+		4, 1, 2, 5, 5, 
+		2, 2, 3, 8, 7, 
+		2, 4, 8, 1, 4, 
+		1, 2, 3, 2, 2, 
+		5, 4, 2, 3, 3
+	}; 
+
+	Matrix m(10, 5, input); 
+	
+	auto cov = m.transposed().row_covariance(); 
+	
+
+	BOOST_CHECK_EQUAL(cov.rows(), 5); 
+	BOOST_CHECK_EQUAL(cov.cols(), 5); 
+
+	
+	const double test[25]  = {  
+		1.82222,  -0.11111,  -0.06667,   0.13333,   0.02222,
+		-0.11111,   2.72222,   0.00000,  -0.94444,   2.11111,
+		-0.06667,   0.00000,   4.26667,  -2.31111,  -0.86667,
+		0.13333,  -0.94444,  -2.31111,   4.45556,   2.28889,
+		0.02222,   2.11111,  -0.86667,   2.28889,   5.95556
+	}; 
+	
+	auto t = test; 
+	for (unsigned  r = 0; r < cov.rows(); ++r) 
+		for (unsigned  c = 0; c < cov.cols(); ++c, ++t) {
+			if (*t == 0.0) 
+				BOOST_CHECK_SMALL(cov(r,c), 1e-10); 
+			else 
+				BOOST_CHECK_CLOSE(cov(r,c), *t, 0.1); 
+		}
+}
+
+BOOST_AUTO_TEST_CASE( test_matrix_iterator ) 
+{
+	const double input[50]  = { 
+		1, 2, 3, 4, 5, 
+		6, 7, 8, 9,10, 
+	 	11, 12, 13, 14, 15, 
+		2, 6, 2, 3, 8, 
+		4, 1, 6, 2, 1, 
+		4, 1, 2, 5, 5, 
+		2, 2, 3, 8, 7, 
+		2, 4, 8, 1, 4, 
+		1, 2, 3, 2, 2, 
+		5, 4, 2, 3, 3
+	}; 
+
+	const double test_submatrix[21]  = { 
+	 	12, 13, 14,
+		6, 2, 3, 
+		1, 6, 2,
+		1, 2, 5,
+		2, 3, 8,
+		4, 8, 1,
+		2, 3, 2
+	}; 
+
+	Matrix m(10, 5, input); 
+
+	auto im = m.begin(); 
+	for (int i = 0; i < 50; ++i, ++im) {
+		BOOST_CHECK_EQUAL(*im, input[i]); 
+	}
+
+	// look at a view 
+
+	gsl_matrix_view mv = gsl_matrix_submatrix (m, 2, 1, 7, 3); 
+	
+	Matrix mvm(&mv.matrix); 
+	
+	auto imvm = mvm.begin(); 
+	for (int i = 0; i < 21; ++i, ++imvm) {
+		BOOST_CHECK_EQUAL(*imvm, test_submatrix[i]); 
+	}
+	
+	for(auto im2 = m.begin(); im2 != m.end(); ++im2) 
+		*im2 = 1; 
+
+	int k = 0; 
+	for (auto imvm2 = mvm.begin(); imvm2 != mvm.end(); ++imvm2, ++k) {
+		BOOST_CHECK_EQUAL(*imvm, 1); 
+	}
+	BOOST_CHECK_EQUAL(k, 21); 
+
+	
+
+}
+
+BOOST_AUTO_TEST_CASE( test_const_matrix_iterator ) 
+{
+	const double input[50]  = { 
+		1, 2, 3, 4, 5, 
+		6, 7, 8, 9,10, 
+	 	11, 12, 13, 14, 15, 
+		2, 6, 2, 3, 8, 
+		4, 1, 6, 2, 1, 
+		4, 1, 2, 5, 5, 
+		2, 2, 3, 8, 7, 
+		2, 4, 8, 1, 4, 
+		1, 2, 3, 2, 2, 
+		5, 4, 2, 3, 3
+	}; 
+
+	const double test_submatrix[21]  = { 
+	 	12, 13, 14,
+		6, 2, 3, 
+		1, 6, 2,
+		1, 2, 5,
+		2, 3, 8,
+		4, 8, 1,
+		2, 3, 2
+	}; 
+
+	const Matrix m(10, 5, input); 
+
+	auto im = m.begin(); 
+	for (int i = 0; i < 50; ++i, ++im) {
+		BOOST_CHECK_EQUAL(*im, input[i]); 
+	}
+
+	// look at a view 
+
+	gsl_matrix_const_view mv = gsl_matrix_const_submatrix (m, 2, 1, 7, 3); 
+	
+	const Matrix mvm(&mv.matrix); 
+	
+	auto imvm = mvm.begin(); 
+	for (int i = 0; i < 21; ++i, ++imvm) {
+		BOOST_CHECK_EQUAL(*imvm, test_submatrix[i]); 
+	}
+	
+
+}
+
+BOOST_AUTO_TEST_CASE( test_row_ops ) 
+{
+	const double input[50]  = { 
+		1, 2, 3, 4, 5, 
+		6, 7, 8, 9,10, 
+	 	11, 12, 13, 14, 15, 
+		2, 6, 2, 3, 8, 
+		4, 1, 6, 2, 1, 
+		4, 1, 2, 5, 5, 
+		2, 2, 3, 8, 7, 
+		2, 4, 8, 1, 4, 
+		1, 2, 3, 2, 2, 
+		5, 4, 2, 3, 3
+	}; 
+	
+	Matrix m(10, 5, input); 
+
+	auto mr = m.get_row(2); 
+	BOOST_CHECK_EQUAL(mr.size(), 5); 
+
+	BOOST_CHECK_EQUAL(mr[0], 11); 
+	BOOST_CHECK_EQUAL(mr[1], 12); 
+	BOOST_CHECK_EQUAL(mr[2], 13); 
+	BOOST_CHECK_EQUAL(mr[3], 14); 
+	BOOST_CHECK_EQUAL(mr[4], 15); 
+	
+	auto b = mr.begin(); 
+
+	BOOST_CHECK_EQUAL(*b, 11); ++b; 
+	BOOST_CHECK_EQUAL(*b, 12); ++b; 
+	BOOST_CHECK_EQUAL(*b, 13); ++b; 
+	BOOST_CHECK_EQUAL(*b, 14); ++b; 
+	BOOST_CHECK_EQUAL(*b, 15); ++b; 
+	
+	BOOST_CHECK(b == mr.end()); 
+
+	m.set_row(3, mr); 
+	auto mr3 = m.get_row(3); 
+	BOOST_CHECK_EQUAL(mr3.size(), 5); 
+
+	BOOST_CHECK_EQUAL(mr3[0], 11); 
+	BOOST_CHECK_EQUAL(mr3[1], 12); 
+	BOOST_CHECK_EQUAL(mr3[2], 13); 
+	BOOST_CHECK_EQUAL(mr3[3], 14); 
+	BOOST_CHECK_EQUAL(mr3[4], 15); 
+	
+
+}
+
+BOOST_AUTO_TEST_CASE( test_const_row_ops ) 
+{
+	const double input[50]  = { 
+		1, 2, 3, 4, 5, 
+		6, 7, 8, 9,10, 
+	 	11, 12, 13, 14, 15, 
+		2, 6, 2, 3, 8, 
+		4, 1, 6, 2, 1, 
+		4, 1, 2, 5, 5, 
+		2, 2, 3, 8, 7, 
+		2, 4, 8, 1, 4, 
+		1, 2, 3, 2, 2, 
+		5, 4, 2, 3, 3
+	}; 
+	
+	const Matrix m(10, 5, input); 
+
+	auto mr = m.get_row(2); 
+	BOOST_CHECK_EQUAL(mr.size(), 5); 
+
+	BOOST_CHECK_EQUAL(mr[0], 11); 
+	BOOST_CHECK_EQUAL(mr[1], 12); 
+	BOOST_CHECK_EQUAL(mr[2], 13); 
+	BOOST_CHECK_EQUAL(mr[3], 14); 
+	BOOST_CHECK_EQUAL(mr[4], 15); 
+	
+	auto b = mr.begin(); 
+
+	BOOST_CHECK_EQUAL(*b, 11); ++b; 
+	BOOST_CHECK_EQUAL(*b, 12); ++b; 
+	BOOST_CHECK_EQUAL(*b, 13); ++b; 
+	BOOST_CHECK_EQUAL(*b, 14); ++b; 
+	BOOST_CHECK_EQUAL(*b, 15); ++b; 
+	
+	BOOST_CHECK(b == mr.end()); 
+
+	double v_init[5] = {1, 2, 3, 4, 5}; 
+	
+	Vector v(5, v_init);
+
+	BOOST_CHECK_EQUAL(m.dot_row(9, v), 46.0); 
+}
+
+
+BOOST_AUTO_TEST_CASE( test_const_col_ops ) 
+{
+	const double input[50]  = { 
+		1, 2, 3, 4, 5, 
+		6, 7, 8, 9,10, 
+	 	11, 12, 13, 14, 15, 
+		2, 6, 2, 3, 8, 
+		4, 1, 6, 2, 1, 
+		4, 1, 2, 5, 5, 
+		2, 2, 3, 8, 7, 
+		2, 4, 8, 1, 4, 
+		1, 2, 3, 2, 2, 
+		5, 4, 2, 3, 3
+	}; 
+	
+	const Matrix m(10, 5, input); 
+
+	auto mr = m.get_column(2); 
+	BOOST_CHECK_EQUAL(mr.size(), 10); 
+
+	BOOST_CHECK_EQUAL(mr[0], 3); 
+	BOOST_CHECK_EQUAL(mr[1], 8); 
+	BOOST_CHECK_EQUAL(mr[2], 13); 
+	BOOST_CHECK_EQUAL(mr[3], 2); 
+	BOOST_CHECK_EQUAL(mr[4], 6); 
+
+	BOOST_CHECK_EQUAL(mr[5], 2); 
+	BOOST_CHECK_EQUAL(mr[6], 3); 
+	BOOST_CHECK_EQUAL(mr[7], 8); 
+	BOOST_CHECK_EQUAL(mr[8], 3); 
+	BOOST_CHECK_EQUAL(mr[9], 2); 	
+
+	
+	auto b = mr.begin(); 
+
+	BOOST_CHECK_EQUAL(*b, 3); ++b; 
+	BOOST_CHECK_EQUAL(*b, 8); ++b; 
+	BOOST_CHECK_EQUAL(*b, 13); ++b; 
+	BOOST_CHECK_EQUAL(*b, 2); ++b; 
+	BOOST_CHECK_EQUAL(*b, 6); ++b; 
+	BOOST_CHECK_EQUAL(*b, 2); ++b; 
+	BOOST_CHECK_EQUAL(*b, 3); ++b; 
+	BOOST_CHECK_EQUAL(*b, 8); ++b; 
+	BOOST_CHECK_EQUAL(*b, 3); ++b; 
+	BOOST_CHECK_EQUAL(*b, 2); ++b; 
+
+	BOOST_CHECK(b == mr.end()); 
+
+}
+
+
+BOOST_AUTO_TEST_CASE( test_matrix_inv_sqrt ) 
+{
+	const double input[16]  = {
+		0.25, 0.35, 0.1, 0.3, 
+		0.35, 0.25, 0.1, 0.3, 
+		0.1,  0.3, 0.25, 0.35,  
+		0.15, 0.45, 0.2, 0.7
+	}; 
+
+	Matrix m(4,4,input); 
+	matrix_inv_sqrt(m); 
+
+	       
+	BOOST_CHECK_CLOSE(m(0,0), 0.272403, 0.1); 
+	BOOST_CHECK_CLOSE(m(0,1), 0.919640, 0.1);
+	BOOST_CHECK_CLOSE(m(0,2),-0.228760, 0.1);
+	BOOST_CHECK_CLOSE(m(0,3),-0.166518, 0.1);
+
+	BOOST_CHECK_CLOSE(m(1,0), 0.937965, 0.1);
+	BOOST_CHECK_CLOSE(m(1,1),-0.201772, 0.1);
+	BOOST_CHECK_CLOSE(m(1,2), 0.120041, 0.1);
+	BOOST_CHECK_CLOSE(m(1,3), 0.255148, 0.1);
+
+	BOOST_CHECK_CLOSE(m(2,0), -0.079173, 0.1);
+	BOOST_CHECK_CLOSE(m(2,1), 0.271666, 0.1);
+	BOOST_CHECK_CLOSE(m(2,2), 0.957528, 0.1);
+	BOOST_CHECK_CLOSE(m(2,3), 0.055393, 0.1);
+
+	BOOST_CHECK_CLOSE(m(3,0), -0.199374, 0.1);
+	BOOST_CHECK_CLOSE(m(3,1), 0.199370, 0.1);
+	BOOST_CHECK_CLOSE(m(3,2), -0.128056, 0.1);
+	BOOST_CHECK_CLOSE(m(3,3), 0.950843, 0.1);
+
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_col_ops ) 
+{
+	const double input[50]  = { 
+		1, 2, 3, 4, 5, 
+		6, 7, 8, 9,10, 
+	 	11, 12, 13, 14, 15, 
+		2, 6, 2, 3, 8, 
+		4, 1, 6, 2, 1, 
+		4, 1, 2, 5, 5, 
+		2, 2, 3, 8, 7, 
+		2, 4, 8, 1, 4, 
+		1, 2, 3, 2, 2, 
+		5, 4, 2, 3, 3
+	}; 
+	
+	Matrix m(10, 5, input); 
+
+	auto mr = m.get_column(2); 
+	BOOST_CHECK_EQUAL(mr.size(), 10); 
+
+	BOOST_CHECK_EQUAL(mr[0], 3); 
+	BOOST_CHECK_EQUAL(mr[1], 8); 
+	BOOST_CHECK_EQUAL(mr[2], 13); 
+	BOOST_CHECK_EQUAL(mr[3], 2); 
+	BOOST_CHECK_EQUAL(mr[4], 6); 
+
+	BOOST_CHECK_EQUAL(mr[5], 2); 
+	BOOST_CHECK_EQUAL(mr[6], 3); 
+	BOOST_CHECK_EQUAL(mr[7], 8); 
+	BOOST_CHECK_EQUAL(mr[8], 3); 
+	BOOST_CHECK_EQUAL(mr[9], 2); 	
+
+	
+	auto b = mr.begin(); 
+
+	BOOST_CHECK_EQUAL(*b, 3); ++b; 
+	BOOST_CHECK_EQUAL(*b, 8); ++b; 
+	BOOST_CHECK_EQUAL(*b, 13); ++b; 
+	BOOST_CHECK_EQUAL(*b, 2); ++b; 
+	BOOST_CHECK_EQUAL(*b, 6); ++b; 
+	BOOST_CHECK_EQUAL(*b, 2); ++b; 
+	BOOST_CHECK_EQUAL(*b, 3); ++b; 
+	BOOST_CHECK_EQUAL(*b, 8); ++b; 
+	BOOST_CHECK_EQUAL(*b, 3); ++b; 
+	BOOST_CHECK_EQUAL(*b, 2); ++b; 
+
+	BOOST_CHECK(b == mr.end()); 
+
+	m.set_column(4, mr); 
+
+
+	auto mr3 = m.get_column(4); 
+	BOOST_CHECK_EQUAL(mr3.size(), 10); 
+
+	BOOST_CHECK_EQUAL(mr3[0], 3); 
+	BOOST_CHECK_EQUAL(mr3[1], 8); 
+	BOOST_CHECK_EQUAL(mr3[2], 13); 
+	BOOST_CHECK_EQUAL(mr3[3], 2); 
+	BOOST_CHECK_EQUAL(mr3[4], 6); 
+
+	BOOST_CHECK_EQUAL(mr3[5], 2); 
+	BOOST_CHECK_EQUAL(mr3[6], 3); 
+	BOOST_CHECK_EQUAL(mr3[7], 8); 
+	BOOST_CHECK_EQUAL(mr3[8], 3); 
+	BOOST_CHECK_EQUAL(mr3[9], 2); 	
+}
+
+
diff --git a/mia/core/test_gsl_matrix_vector_ops.cc b/mia/core/test_gsl_matrix_vector_ops.cc
new file mode 100644
index 0000000..c8b57e3
--- /dev/null
+++ b/mia/core/test_gsl_matrix_vector_ops.cc
@@ -0,0 +1,288 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/gsl_matrix_vector_ops.hh> 
+
+#ifndef BOOST_TEST_DYN_LINK
+#define BOOST_TEST_DYN_LINK
+#endif
+
+#define BOOST_TEST_MAIN
+#define BOOST_TEST_ALTERNATIVE_INIT_API
+#include <boost/test/unit_test.hpp>
+#include <boost/test/floating_point_comparison.hpp>
+
+#include <iostream>
+#include <cmath>
+
+using namespace gsl; 
+using std::sqrt; 
+
+BOOST_AUTO_TEST_CASE( test_vec_mult_marix ) 
+{
+        const double matrix_init[] = {
+                1, 2, 3, 
+                4, 5, 6
+        };
+
+        const double vector_init[] = {
+                2, 3
+        }; 
+
+        Matrix rhs(2,3, matrix_init); 
+        Vector lhs(2, false); 
+        Vector result(3, true); 
+        
+        std::copy(vector_init, vector_init + 2, lhs.begin()); 
+        
+        multiply_v_m(result, lhs, rhs);
+
+        BOOST_CHECK_CLOSE(result[0], 14, 0.1); 
+        BOOST_CHECK_CLOSE(result[1], 19, 0.1); 
+        BOOST_CHECK_CLOSE(result[2], 24, 0.1); 
+
+}
+
+BOOST_AUTO_TEST_CASE( test_mult_matrix_marix ) 
+{
+
+        const double lhs_init[] = {
+                2, 3, 
+                1, 2, 
+                -1, -2, 
+                4, 5
+        }; 
+
+        const double rhs_init[] = {
+                1, 2, 3, 
+                4, 5, 6
+        };
+
+
+        Matrix lhs(4, 2, lhs_init); 
+        Matrix rhs(2, 3, rhs_init); 
+
+        
+        Matrix result(4, 3, true); 
+        
+        multiply_m_m(result, lhs, rhs);
+
+        BOOST_CHECK_CLOSE(result(0, 0), 14, 0.1); 
+        BOOST_CHECK_CLOSE(result(0, 1), 19, 0.1); 
+        BOOST_CHECK_CLOSE(result(0, 2), 24, 0.1); 
+
+        BOOST_CHECK_CLOSE(result(1, 0),  9, 0.1); 
+        BOOST_CHECK_CLOSE(result(1, 1), 12, 0.1); 
+        BOOST_CHECK_CLOSE(result(1, 2), 15, 0.1); 
+
+        BOOST_CHECK_CLOSE(result(2, 0), -9, 0.1); 
+        BOOST_CHECK_CLOSE(result(2, 1),-12, 0.1); 
+        BOOST_CHECK_CLOSE(result(2, 2),-15, 0.1); 
+
+        BOOST_CHECK_CLOSE(result(3, 0), 24, 0.1); 
+        BOOST_CHECK_CLOSE(result(3, 1), 33, 0.1); 
+        BOOST_CHECK_CLOSE(result(3, 2), 42, 0.1); 
+
+}
+
+
+BOOST_AUTO_TEST_CASE( test_mult_matrix_matrixT ) 
+{
+
+        const double lhs_init[] = {
+                2, 3, 
+                1, 2, 
+                -1, -2, 
+                4, 5
+        }; 
+
+        const double rhs_init[] = {
+                1, 4,
+                2, 5, 
+		3, 6
+        };
+
+
+        Matrix lhs(4, 2, lhs_init); 
+        Matrix rhs(3, 2, rhs_init); 
+
+        
+        Matrix result(4, 3, true); 
+        
+        multiply_m_mT(result, lhs, rhs);
+
+        BOOST_CHECK_CLOSE(result(0, 0), 14, 0.1); 
+        BOOST_CHECK_CLOSE(result(0, 1), 19, 0.1); 
+        BOOST_CHECK_CLOSE(result(0, 2), 24, 0.1); 
+
+        BOOST_CHECK_CLOSE(result(1, 0),  9, 0.1); 
+        BOOST_CHECK_CLOSE(result(1, 1), 12, 0.1); 
+        BOOST_CHECK_CLOSE(result(1, 2), 15, 0.1); 
+
+        BOOST_CHECK_CLOSE(result(2, 0), -9, 0.1); 
+        BOOST_CHECK_CLOSE(result(2, 1),-12, 0.1); 
+        BOOST_CHECK_CLOSE(result(2, 2),-15, 0.1); 
+
+        BOOST_CHECK_CLOSE(result(3, 0), 24, 0.1); 
+        BOOST_CHECK_CLOSE(result(3, 1), 33, 0.1); 
+        BOOST_CHECK_CLOSE(result(3, 2), 42, 0.1); 
+
+}
+
+BOOST_AUTO_TEST_CASE( test_mult_matrixT_martix ) 
+{
+
+        const double lhs_init[] = {
+		2, 1, -1, 4, 
+		3, 2, -2, 5
+        }; 
+
+        const double rhs_init[] = {
+                1, 2, 3, 
+		4, 5, 6
+        };
+
+
+        Matrix lhs(2, 4, lhs_init); 
+        Matrix rhs(2, 3, rhs_init); 
+
+        
+        Matrix result(4, 3, true); 
+        
+        multiply_mT_m(result, lhs, rhs);
+
+        BOOST_CHECK_CLOSE(result(0, 0), 14, 0.1); 
+        BOOST_CHECK_CLOSE(result(0, 1), 19, 0.1); 
+        BOOST_CHECK_CLOSE(result(0, 2), 24, 0.1); 
+
+        BOOST_CHECK_CLOSE(result(1, 0),  9, 0.1); 
+        BOOST_CHECK_CLOSE(result(1, 1), 12, 0.1); 
+        BOOST_CHECK_CLOSE(result(1, 2), 15, 0.1); 
+
+        BOOST_CHECK_CLOSE(result(2, 0), -9, 0.1); 
+        BOOST_CHECK_CLOSE(result(2, 1),-12, 0.1); 
+        BOOST_CHECK_CLOSE(result(2, 2),-15, 0.1); 
+
+        BOOST_CHECK_CLOSE(result(3, 0), 24, 0.1); 
+        BOOST_CHECK_CLOSE(result(3, 1), 33, 0.1); 
+        BOOST_CHECK_CLOSE(result(3, 2), 42, 0.1); 
+
+}
+
+
+BOOST_AUTO_TEST_CASE( test_mult_vec_marix ) 
+{
+
+        const double matrix_init[] = {
+                1, 2, 
+                3, 4, 
+                5, 6
+        };
+
+        const double vector_init[] = {
+                2, 3
+        }; 
+
+
+        Matrix lhs(3,2, matrix_init); 
+        Vector rhs(2, false); 
+        Vector result(3, true); 
+        
+        std::copy(vector_init, vector_init + 2, rhs.begin()); 
+        
+        multiply_m_v(result, lhs, rhs);
+
+        BOOST_CHECK_CLOSE(result[0],  8, 0.1); 
+        BOOST_CHECK_CLOSE(result[1], 18, 0.1); 
+        BOOST_CHECK_CLOSE(result[2], 28, 0.1); 
+
+}
+
+BOOST_AUTO_TEST_CASE( test_mult_vec_vec ) 
+{
+        const double vector1_init[] = {
+                1, 2, 
+        };
+
+        const double vector2_init[] = {
+                2, 3
+        }; 
+
+
+        Vector lhs(2, false); 
+        Vector rhs(2, false); 
+        
+        std::copy(vector1_init, vector1_init + 2, lhs.begin()); 
+        std::copy(vector2_init, vector2_init + 2, rhs.begin()); 
+        
+        BOOST_CHECK_CLOSE(dot(lhs, rhs), 8, 0.1); 
+}
+
+
+BOOST_AUTO_TEST_CASE( test_matrix_orthogonalize ) 
+{
+        const double U_init[] = {
+                1.0, 0, 0, 0, 
+		0, 1.0/sqrt(2.0), 1.0/sqrt(2.0), 0, 
+		0, 1.0/sqrt(2.0), -1.0/sqrt(2.0), 0, 
+		0, 0, 0, 1.0 
+        };
+	
+        const double V_init[] = {
+                1.0/sqrt(2.0), 1.0/sqrt(2.0), 0, 
+		0, 1.0/sqrt(2.0), -1.0/sqrt(2.0), 0, 
+		0, 0,  1.0
+        }; 
+	
+	const double D_init[] = {
+		2, 0, 0, 
+		0, 3, 0, 
+		0, 0, 4, 
+		0, 0, 0
+	}; 
+	
+	Matrix U(4, 4, U_init);
+	Matrix V(3, 3, V_init);
+	Matrix D(4, 3, D_init);
+	Matrix temp(4, 3, false);
+		
+	Matrix M(4,3, false);
+		
+	multiply_m_m(temp, D, V);
+	multiply_m_m(M, U, temp);
+	
+	matrix_orthogonalize(M); 
+	
+	
+	for (int c = 0; c < 3; ++c) {
+		auto col_1 = gsl_matrix_column(M, c);
+		// should be unity
+		BOOST_CHECK_CLOSE(dot(&col_1.vector, &col_1.vector), 1.0, 0.1); 
+		for (int c2 = 0; c2 < c; ++c2) {
+			auto col_2 = gsl_matrix_column(M, c2); 
+			BOOST_CHECK_SMALL(dot(&col_1.vector, &col_2.vector), 1e-10); 
+			
+		}
+
+	}
+
+
+}
diff --git a/gsl++/test_multimin.cc b/mia/core/test_gsl_multimin.cc
similarity index 82%
rename from gsl++/test_multimin.cc
rename to mia/core/test_gsl_multimin.cc
index f2ee1e8..e03d7af 100644
--- a/gsl++/test_multimin.cc
+++ b/mia/core/test_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
 #include <boost/test/floating_point_comparison.hpp>
 #include <vector>
 
-#include <gsl++/multimin.hh>
+#include <mia/core/gsl_multimin.hh>
 
 using namespace gsl; 
 
@@ -37,9 +37,9 @@ class TestCFDFProblem : public CFDFMinimizer::Problem {
 public:
 	TestCFDFProblem(); 
 private: 
-	virtual double  do_f(const DoubleVector& x); 
-	virtual void    do_df(const DoubleVector&  x, DoubleVector&  g); 
-	virtual double  do_fdf(const DoubleVector&  x, DoubleVector&  g); 
+	virtual double  do_f(const Vector& x); 
+	virtual void    do_df(const Vector&  x, Vector&  g); 
+	virtual double  do_fdf(const Vector&  x, Vector&  g); 
 	std::vector<double> m_p; 
 }; 
 
@@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE(test_cfdf_multmin )
 {
 	CFDFMinimizer minimizer(CFDFMinimizer::PProblem(new TestCFDFProblem), gsl_multimin_fdfminimizer_conjugate_fr );
 	
-	DoubleVector x(2, false); 
+	Vector x(2, false); 
 	const size_t i0 = 0; 
 	const size_t i1 = 1; 
 
@@ -68,7 +68,7 @@ TestCFDFProblem::TestCFDFProblem():
 }
 	
 
-double  TestCFDFProblem::do_f(const DoubleVector&  v)
+double  TestCFDFProblem::do_f(const Vector&  v)
 {
 
 	const size_t i0 = 0; 
@@ -82,7 +82,7 @@ double  TestCFDFProblem::do_f(const DoubleVector&  v)
 	
 }
 
-void    TestCFDFProblem::do_df(const DoubleVector&  v, DoubleVector&  g)
+void    TestCFDFProblem::do_df(const Vector&  v, Vector&  g)
 {
 	const size_t i0 = 0; 
 	const size_t i1 = 1; 
@@ -94,7 +94,7 @@ void    TestCFDFProblem::do_df(const DoubleVector&  v, DoubleVector&  g)
 	g[i1] = 2.0 * m_p[3] * (y - m_p[1]);
 }
 
-double  TestCFDFProblem::do_fdf(const DoubleVector&  x, DoubleVector&  g)
+double  TestCFDFProblem::do_fdf(const Vector&  x, Vector&  g)
 {
 	do_df(x,g); 
 	return do_f(x); 
@@ -105,7 +105,7 @@ class TestCFProblem : public CFMinimizer::Problem {
 public:
 	TestCFProblem(); 
 private: 
-	virtual double  do_f(const DoubleVector& x); 
+	virtual double  do_f(const Vector& x); 
 	std::vector<double> m_p; 
 }; 
 
@@ -117,7 +117,7 @@ BOOST_AUTO_TEST_CASE(test_cf_multmin )
 	const size_t i0 = 0; 
 	const size_t i1 = 1; 
 
-	DoubleVector x(2, false); 
+	Vector x(2, false); 
 	x[i0] = 5.0; 
 	x[i1] = 7.0; 
 	
@@ -135,7 +135,7 @@ TestCFProblem::TestCFProblem():
 	copy(p_init, p_init+5, m_p.begin()); 
 }
 
-double  TestCFProblem::do_f(const DoubleVector&  v)
+double  TestCFProblem::do_f(const Vector&  v)
 {
 
 	const size_t i0 = 0; 
diff --git a/mia/core/test_gsl_pca.cc b/mia/core/test_gsl_pca.cc
new file mode 100644
index 0000000..e1cf77d
--- /dev/null
+++ b/mia/core/test_gsl_pca.cc
@@ -0,0 +1,83 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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 BOOST_TEST_DYN_LINK
+#define BOOST_TEST_DYN_LINK
+#endif
+
+#define BOOST_TEST_MAIN
+#define BOOST_TEST_ALTERNATIVE_INIT_API
+#include <boost/test/unit_test.hpp>
+#include <boost/test/floating_point_comparison.hpp>
+
+#include <mia/core/gsl_pca.hh>
+
+using namespace gsl; 
+
+BOOST_AUTO_TEST_CASE( test_matrix_pca ) 
+{
+        const double input[50]  = { 
+                1, 2, 3, 2, 1, 
+		2, 1, 2, 5, 2, 
+		3, 2, 5, 2, 5, 
+		2, 6, 2, 3, 8, 
+		4, 1, 6, 2, 1, 
+		4, 1, 2, 5, 5, 
+		2, 2, 3, 8, 7, 
+		2, 4, 8, 1, 4, 
+		1, 2, 3, 2, 2, 
+		5, 4, 2, 3, 3
+	}; 
+
+	Matrix m(10, 5, input); 
+
+        PCA pca(3, 0.0);
+        
+        auto result = pca.analyze(m.transposed());
+        BOOST_CHECK_EQUAL(result.eval.size(), 3u); 
+        BOOST_CHECK_CLOSE(result.eval[0], 8.785043, 0.1); 
+        BOOST_CHECK_CLOSE(result.eval[1], 5.462723, 0.1); 
+        BOOST_CHECK_CLOSE(result.eval[2], 2.673904, 0.1); 
+        
+
+        BOOST_CHECK_EQUAL(result.evec.rows(), 5u); 
+        BOOST_CHECK_EQUAL(result.evec.cols(), 3u); 
+        
+
+        // note that the sign is undefined, the test should honor this 
+        const double test_ev[15] = {
+                0.01448099,  -0.03862017, -0.07748999,
+                0.15538277,   0.55340859,  0.48156179,
+                -0.42010386,  0.47788917, -0.73357794,
+                0.55943565,  -0.44087868, -0.42617084,
+                0.69727398,   0.51912941, -0.20575562
+        }; 
+
+        const double *t = test_ev; 
+        for (unsigned r = 0; r < 5; ++r)
+                for (unsigned c = 0; c < 3; ++c, ++t) {
+                        BOOST_CHECK_CLOSE(result.evec(r,c), *t, 0.1); 
+                }
+                
+
+        
+}
diff --git a/gsl++/test_vector.cc b/mia/core/test_gsl_vector.cc
similarity index 53%
rename from gsl++/test_vector.cc
rename to mia/core/test_gsl_vector.cc
index a00ab40..98b3d91 100644
--- a/gsl++/test_vector.cc
+++ b/mia/core/test_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 @@
 #include <boost/mpl/vector.hpp>
 #include <boost/test/test_case_template.hpp>
 
-#include <gsl++/vector.hh>
+#include <mia/core/gsl_vector.hh>
 
 #include <vector>
+#include <iostream>
 
 
 using namespace gsl; 
@@ -41,16 +42,7 @@ using namespace ::boost::unit_test;
 
 namespace bmpl=boost::mpl;
 
-typedef bmpl::vector<DoubleVector, 
-		     FloatVector, 
-		     LongVector, 
-		     IntVector, 
-		     ShortVector, 
-		     CharVector,
-		     ULongVector,
-		     UIntVector,
-		     UShortVector,
-		     UCharVector>  test_types;
+typedef bmpl::vector<Vector>  test_types;
 
 
 BOOST_AUTO_TEST_CASE_TEMPLATE( test_vector_zero_init, T ,test_types ) 
@@ -92,7 +84,10 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_vector_copy_from, T ,test_types )
 	for(size_t i = 0; i < 5; ++i)
 		gsl_vector[i] = i+1; 
 	
-	std::vector<typename T::value_type> a(5); 
+	std::vector<typename T::value_type> a(5,6); 
+
+	BOOST_REQUIRE(gsl_vector.begin() != gsl_vector.end()); 
+	BOOST_REQUIRE(!(gsl_vector.begin() == gsl_vector.end())); 
 	copy(gsl_vector.begin(), gsl_vector.end(), a.begin()); 
 	
 	for(size_t i = 0; i < 5; ++i)
@@ -108,14 +103,13 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_vector_inplace_add, T ,test_types )
 	BOOST_REQUIRE(gsl_vector.size()== 5); 
 
 	for(size_t i = 0; i < 5; ++i) {
-		gsl_vector[i] += i+1; 
+		gsl_vector[i] = i; 
+		gsl_vector[i] += 1; 
 	}
 	
-	std::vector<typename T::value_type> a(5); 
-	copy(gsl_vector.begin(), gsl_vector.end(), a.begin()); 
-	
+
 	for(size_t i = 0; i < 5; ++i)
-		BOOST_CHECK_EQUAL(a[i], static_cast<typename T::value_type>(i + 1)); 
+		BOOST_CHECK_EQUAL(gsl_vector[i], static_cast<typename T::value_type>(i + 1)); 
 
 	
 }
@@ -125,7 +119,7 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( test_vector_inplace_add, T ,test_types )
 BOOST_AUTO_TEST_CASE( test_vector_non_owning ) 
 {									
 	gsl_vector *x = gsl_vector_calloc(10); 
-	DoubleVector wx(x); 
+	Vector wx(x); 
 	
 	const size_t i2 = 2; 
 
@@ -139,8 +133,8 @@ BOOST_AUTO_TEST_CASE( test_vector_non_owning )
 
 BOOST_AUTO_TEST_CASE( test_vector_copy ) 
 {
-	DoubleVector wx(10, false); 
-	DoubleVector wy(5, false); 
+	Vector wx(10, false); 
+	Vector wy(5, false); 
 	
 	const size_t i2 = 2; 
 	wx[i2] = 3.0; 
@@ -153,6 +147,98 @@ BOOST_AUTO_TEST_CASE( test_vector_copy )
 	wx = wy; 
 	BOOST_CHECK_EQUAL(wx.size(), 5u); 
 	BOOST_CHECK_EQUAL(wx[i2], 2.0); 
+}
+
+BOOST_AUTO_TEST_CASE( test_vector_iterator ) 
+{
+	Vector v(50, false); 
+	for (int i = 0; i < 50; ++i)
+		v[i] = i + 0; 
+
+	auto it_dv = v.begin(); 
+	for (int i = 0; i < 50; ++i, ++it_dv)
+		BOOST_CHECK_EQUAL(*it_dv, i); 
+	
+
+	gsl_vector_view vview = gsl_vector_subvector_with_stride (v, 2, 2, 20); 
+	
+	Vector dv_view(&vview.vector); 
+	
+	for (int i = 0; i < 20; ++i) {
+		BOOST_CHECK_EQUAL(dv_view[i], 2*i + 2); 
+	}
+
+	auto it_dv_base = dv_view.begin(); 
+	auto it_dv_view = dv_view.begin(); 
+
+	BOOST_CHECK(it_dv_base ==  it_dv_view); 
+	BOOST_CHECK(it_dv_base <=  it_dv_view); 
+	BOOST_CHECK(it_dv_base >=  it_dv_view); 
+	
+	BOOST_CHECK_EQUAL(*it_dv_view, 2); 
+	it_dv_view += 3; 
+
+	BOOST_CHECK(it_dv_base <  it_dv_view); 
+	BOOST_CHECK(it_dv_base <=  it_dv_view); 
+	BOOST_CHECK(it_dv_view >= it_dv_base); 
+	BOOST_CHECK(it_dv_view != it_dv_base); 
+
+
+	BOOST_CHECK_EQUAL(*it_dv_view, 8); 
+
+	it_dv_view -= -2; 
+	BOOST_CHECK_EQUAL(*it_dv_view, 12);
+
+	
+		
+}
+
+
+static void test_const_vector_iterator_impl(const Vector& v) 
+{
+	auto it_dv = v.begin(); 
+	for (int i = 0; i < 50; ++i, ++it_dv)
+		BOOST_CHECK_EQUAL(*it_dv, i); 
+	
+	
+	gsl_vector_const_view vview = gsl_vector_const_subvector_with_stride (v, 2, 2, 20); 
+	
+	const Vector dv_view(&vview.vector); 
+	
+	for (int i = 0; i < 20; ++i) {
+		BOOST_CHECK_EQUAL(dv_view[i], 2*i + 2); 
+	}
+	
+	auto it_dv_base = dv_view.begin(); 
+	auto it_dv_view = dv_view.begin(); 
 
+	BOOST_CHECK(it_dv_base ==  it_dv_view); 
+	BOOST_CHECK(it_dv_base <=  it_dv_view); 
+	BOOST_CHECK(it_dv_base >=  it_dv_view); 
+	
+	BOOST_CHECK_EQUAL(*it_dv_view, 2); 
+	it_dv_view += 3; 
+
+	BOOST_CHECK(it_dv_base <  it_dv_view); 
+	BOOST_CHECK(it_dv_base <=  it_dv_view); 
+	BOOST_CHECK(it_dv_view >= it_dv_base); 
+	BOOST_CHECK(it_dv_view != it_dv_base); 
+	
+
+	BOOST_CHECK_EQUAL(*it_dv_view, 8); 
+	
+	it_dv_view -= -2; 
+	BOOST_CHECK_EQUAL(*it_dv_view, 12);
+	
 }
 
+BOOST_AUTO_TEST_CASE( test_const_vector_iterator ) 
+{
+	Vector v(50, false); 
+	for (int i = 0; i < 50; ++i)
+		v[i] = i + 0; 
+
+	test_const_vector_iterator_impl(v); 
+}
+
+
diff --git a/mia/core/test_handler.cc b/mia/core/test_handler.cc
index 29a1092..9bd90c7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 +28,6 @@
 #include <mia/core/handler.hh>
 #include <mia/core/threadedmsg.hh>
 #include <mia/core/testplugin.hh>
-
-#include <tbb/parallel_reduce.h>
-#include <tbb/blocked_range.h>
-
 #include <boost/filesystem/path.hpp>
 
 NS_MIA_USE
@@ -49,7 +45,7 @@ BOOST_AUTO_TEST_CASE( test_dummy_plugin_handler_parallel )
 	CPluginSearchpath sp(true);
 	sp.add("testplug"); 
 	CTestPluginHandler::set_search_path(sp);
-	auto callback = [](const tbb::blocked_range<int>& range, int init){
+	auto callback = [](const C1DParallelRange& range, int init){
 		
 		CThreadMsgStream thread_stream;
 		TRACE_FUNCTION; 
@@ -81,7 +77,7 @@ BOOST_AUTO_TEST_CASE( test_dummy_plugin_handler_parallel )
 		return fails; 
 	}; 
 		
-	int fails = tbb::parallel_reduce( tbb::blocked_range<int>(0, 4, 1), 0, callback, [](int x, int y){return x+y;}); 
+	int fails = preduce( C1DParallelRange(0, 4, 1), 0, callback, [](int x, int y){return x+y;}); 
 
 	BOOST_CHECK_EQUAL(fails, 0); 
 
diff --git a/mia/core/test_helpers.hh b/mia/core/test_helpers.hh
index 4fd1c2e..423aa2a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0412af7..565fe64 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +106,22 @@ BOOST_AUTO_TEST_CASE( test_float_histogram)
 
 }
 
+BOOST_AUTO_TEST_CASE( test_histogram_excess_kurtosis_1 )
+{
+	vector<double> input{1,2,3,2,5,6,1,2,1,5}; 
+	THistogram<THistogramFeeder<float> > h(THistogramFeeder<float>(1,6,6));
+	h.push_range(input.begin(), input.end()); 
+
+	// test values have been evaluated by using octave 3.8.2
+	BOOST_CHECK_CLOSE(h.average(),  2.8, 0.1); 
+	BOOST_CHECK_CLOSE(h.deviation(), sqrt(3.5111), 0.1); 
+	BOOST_CHECK_CLOSE(h.skewness(), 0.62378, 0.1); 
+	BOOST_CHECK_CLOSE(h.excess_kurtosis(),  -1.1530, 0.1); 
+
+
+	
+}
+
 BOOST_AUTO_TEST_CASE( test_histogram2)
 {
 	const size_t nsamples = 31;
diff --git a/mia/core/test_history.cc b/mia/core/test_history.cc
index 3ac690d..bb34db1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0c92aac..ab1bd1e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 @@ BOOST_AUTO_TEST_CASE( test_mixing_ica_without_mean )
 
 	itpp::mat mix(init_mix, rows, nica, false);
 	itpp::mat ic(init_ic,  rows, elms, true);
-	vector<float> mean(rows, 0.0);
-
-	CICAAnalysis ica(ic, mix, mean);
+	vector<double> mean(rows, 0.0);
 
+	CICAAnalysisITPP ica(ic, mix, mean);
+	
 	for (int i = 0; i < rows; ++i) {
 		vector<float> mixed = ica.get_mix(i);
 		for (int k = 0; k < elms; ++k) {
@@ -116,9 +116,9 @@ BOOST_AUTO_TEST_CASE( test_mixing_ica_with_skip )
 
 	itpp::mat mix(init_mix, rows, nica, false);
 	itpp::mat ic(init_ic,  rows, elms, true);
-	vector<float> mean(rows, 0.0);
-
-	CICAAnalysis ica(ic, mix, mean);
+	vector<double> mean(rows, 0.0);
+    
+	CICAAnalysisITPP ica(ic, mix, mean);
 	CICAAnalysis::IndexSet skip;
 	skip.insert(skipnr);
 
@@ -162,9 +162,9 @@ BOOST_AUTO_TEST_CASE( test_partial_ica_mix )
 
 	itpp::mat mix(init_mix, rows, nica, false);
 	itpp::mat ic(init_ic,  rows, elms, true);
-	vector<float> mean(rows, 0.0);
+	vector<double> mean(rows, 0.0);
 
-	CICAAnalysis ica(ic, mix, mean);
+	CICAAnalysisITPP ica(ic, mix, mean);
 	CICAAnalysis::IndexSet components;
 	components.insert(1);
 	components.insert(2);
@@ -205,9 +205,9 @@ BOOST_AUTO_TEST_CASE( test_delta_ica_mix )
 
 	itpp::mat mix(init_mix, rows, nica, false);
 	itpp::mat ic(init_ic,  rows, elms, true);
-	vector<float> mean(rows, 0.0);
+	vector<double> mean(rows, 0.0);
 
-	CICAAnalysis ica(ic, mix, mean);
+	CICAAnalysisITPP ica(ic, mix, mean);
 	CICAAnalysis::IndexSet plus_components;
 	plus_components.insert(1);
 	plus_components.insert(2);
@@ -236,8 +236,9 @@ BOOST_AUTO_TEST_CASE( test_ica_with_zero_mean )
 		{ 4, -4,  -5,  -3,  6, -4, 6, -3, -1, 4 } ,
 		{ 5, -5,  -6,  -1,  2, -2, 6, -3, -1, 5 }
 	};
-
-	CICAAnalysis ica(rows, elms);
+	
+	CICAAnalysisITPP ica;
+	ica.initialize(rows, elms);
 
 	for (int i = 0; i < rows; ++i)
 		ica.set_row(i, data_rows[i], data_rows[i] + elms);
@@ -266,8 +267,9 @@ BOOST_AUTO_TEST_CASE( test_ica_with_some_mean )
 		{ 4, -4,  -5,  -3,  6, -4,  6, -3, -1, 4 },
 		{ 1, -9,  -10,  -5,  -2, -6,  2, -7, -5, 1 }
 	};
-
-	CICAAnalysis ica(rows, elms);
+	
+	CICAAnalysisITPP ica; 
+	ica.initialize(rows, elms);
 	for (int i = 0; i < rows; ++i)
 		ica.set_row(i, data_rows[i], data_rows[i] + elms);
 	ica.run(3, vector<vector<float> >());
@@ -291,7 +293,8 @@ BOOST_AUTO_TEST_CASE( test_ica_with_some_mean_unknown )
 		{ 1, -9,  -10,  -5,  -2, -6,  2, -7, -5, 1 }
 	};
 
-	CICAAnalysis ica(rows, elms);
+	CICAAnalysisITPP ica;
+	ica.initialize(rows, elms);
 
 	for (int i = 0; i < rows; ++i)
 		ica.set_row(i, data_rows[i], data_rows[i] + elms);
@@ -320,8 +323,9 @@ BOOST_AUTO_TEST_CASE( test_ica_with_some_mean_unknown_SYMM )
 		{ 1, -9,  -10,  -5,  -2, -6,  2, -7, -5, 1 }
 	};
 
-	CICAAnalysis ica(rows, elms);
-	ica.set_approach(FICA_APPROACH_SYMM); 
+	CICAAnalysisITPP ica;
+	ica.initialize(rows, elms);
+	ica.set_approach(CICAAnalysis::appr_symm);
 
 	for (int i = 0; i < rows; ++i)
 		ica.set_row(i, data_rows[i], data_rows[i] + elms);
@@ -351,8 +355,9 @@ BOOST_AUTO_TEST_CASE( test_ica_with_some_mean_unknown_normalized_mix )
 		{ 6, -2,  -5,  -13,  6, -4,  6, -3, -11, 14 },
 		{ 1, -9,  -10,  -5,  -2, -6,  2, -7, -5, 1 }
 	};
-
-	CICAAnalysis ica(rows, elms);
+	
+	CICAAnalysisITPP ica;
+	ica.initialize(rows, elms);
 
 	for (int i = 0; i < rows; ++i)
 		ica.set_row(i, data_rows[i], data_rows[i] + elms);
@@ -382,7 +387,8 @@ BOOST_AUTO_TEST_CASE( test_ica_with_some_mean_unknown_normalized )
 		{ 1, -9,  -10,  -5,  -2, -6,  2, -7, -5, 1 }
 	};
 
-	CICAAnalysis ica(rows, elms);
+	CICAAnalysisITPP ica;
+	ica.initialize(rows, elms);
 
 	for (int i = 0; i < rows; ++i)
 		ica.set_row(i, data_rows[i], data_rows[i] + elms);
@@ -412,7 +418,8 @@ BOOST_AUTO_TEST_CASE( test_ica_saftey_against_stupid )
 		{ 1, -9,  -10,  -5,  -2, -6,  2, -7, -5, 1 }
 	};
 
-	CICAAnalysis ica(rows, elms);
+	CICAAnalysisITPP ica;
+	ica.initialize(rows, elms);
 
 	for (int i = 0; i < rows; ++i)
 		ica.set_row(i, data_rows[i], data_rows[i] + elms);
@@ -436,7 +443,8 @@ BOOST_AUTO_TEST_CASE( test_ica_access_failtures )
 		{ 1, -9,  -10,  -5,  -2, -6,  2, -7, -5, 1 }
 	};
 
-	CICAAnalysis ica(rows, elms);
+	CICAAnalysisITPP ica;
+	ica.initialize(rows, elms);
 
 	for (size_t i = 0; i < rows; ++i)
 		ica.set_row(i, data_rows[i], data_rows[i] + elms);
diff --git a/mia/core/test_index.cc b/mia/core/test_index.cc
index 15f240b..dfd6f99 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 620d3d5..cf5f5a8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d463816..b91c1a5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
  * 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>
@@ -35,14 +36,14 @@ struct InterpolatorIDFixture  {
 
 	double df(double x) const;
 
-	void test_case(EInterpolation type, double tolerance = 0.1);
+	void test_case(const string& interpolator_kernel, double tolerance = 0.1);
 
 };
 
 BOOST_FIXTURE_TEST_CASE( test_linear, InterpolatorIDFixture)
 {
 
-	unique_ptr<C1DInterpolatorFactory>  ipf(create_1dinterpolation_factory(ip_linear, bc_mirror_on_bounds));
+	unique_ptr<C1DInterpolatorFactory>  ipf(new C1DInterpolatorFactory("bspline:d=1", "mirror"));
 	vector<double> data(512);
 
 
@@ -61,28 +62,28 @@ BOOST_FIXTURE_TEST_CASE( test_linear, InterpolatorIDFixture)
 
 BOOST_FIXTURE_TEST_CASE( test_bspline2, InterpolatorIDFixture)
 {
-	test_case(ip_bspline2);
+	test_case("bspline:d=2");
 }
 
 BOOST_FIXTURE_TEST_CASE( test_bspline3, InterpolatorIDFixture)
 {
-	test_case(ip_bspline3);
+	test_case("bspline:d=3");
 }
 
 BOOST_FIXTURE_TEST_CASE( test_bspline4, InterpolatorIDFixture)
 {
-	test_case(ip_bspline4);
+	test_case("bspline:d=4");
 }
 
 BOOST_FIXTURE_TEST_CASE( test_bspline5, InterpolatorIDFixture)
 {
-	test_case(ip_bspline5);
+	test_case("bspline:d=5");
 }
 
 
 BOOST_FIXTURE_TEST_CASE( test_omoms3, InterpolatorIDFixture)
 {
-	test_case(ip_omoms3);
+	test_case("omoms:d=3");
 }
 
 double InterpolatorIDFixture::f(double x) const
@@ -96,9 +97,9 @@ double InterpolatorIDFixture::df(double x) const
 }
 
 
-void InterpolatorIDFixture::test_case(EInterpolation type, double tolerance)
+void InterpolatorIDFixture::test_case(const string& interpolator_kernel, double tolerance)
 {
-	unique_ptr<C1DInterpolatorFactory>  ipf(create_1dinterpolation_factory(type,bc_mirror_on_bounds));
+	unique_ptr<C1DInterpolatorFactory>  ipf(new C1DInterpolatorFactory(interpolator_kernel,"mirror"));
 	vector<double> data(512); 
 	for(size_t x = 0; x < 512; ++x)
 		data[x] = f(x) ;
@@ -120,3 +121,162 @@ void InterpolatorIDFixture::test_case(EInterpolation type, double tolerance)
 	}
 }
 
+
+
+BOOST_AUTO_TEST_CASE( test_bspline0_zero )
+{
+	unique_ptr<C1DInterpolatorFactory>  ipf(new C1DInterpolatorFactory("bspline:d=0","zero"));
+
+	vector<double> data(10);
+	for(size_t x = 0; x < 10; ++x)
+		data[x] = x - 1 ;
+
+	unique_ptr< T1DInterpolator<double> > interp(ipf->create(data));
+
+	BOOST_CHECK_EQUAL( (*interp)(-1), 0.0);
+	BOOST_CHECK_EQUAL( (*interp)(11), 0.0);
+
+	for(size_t x = 0; x < 10; ++x) {
+		
+		BOOST_CHECK_EQUAL( (*interp)(x - 0.2), x - 1);
+		BOOST_CHECK_EQUAL( (*interp)(x + 0.2), x - 1);
+	
+	}
+}
+
+BOOST_AUTO_TEST_CASE( test_bspline0_repeat )
+{
+	unique_ptr<C1DInterpolatorFactory>  ipf(new C1DInterpolatorFactory("bspline:d=0","repeat"));
+
+	vector<double> data(10);
+	for(size_t x = 0; x < 10; ++x)
+		data[x] = x +1 ;
+
+	unique_ptr< T1DInterpolator<double> > interp(ipf->create(data));
+
+	BOOST_CHECK_EQUAL( (*interp)(-1), 1.0);
+	BOOST_CHECK_EQUAL( (*interp)(11), 10.0);
+
+	for(size_t x = 0; x < 10; ++x) {
+		
+		BOOST_CHECK_EQUAL( (*interp)(x - 0.2), x + 1);
+		BOOST_CHECK_EQUAL( (*interp)(x + 0.2), x + 1);
+	
+	}
+}
+
+
+BOOST_AUTO_TEST_CASE( test_bspline0_repeat_copy )
+{
+	unique_ptr<C1DInterpolatorFactory>  ipf(new C1DInterpolatorFactory("bspline:d=0","repeat"));
+
+	vector<double> data(10);
+	for(size_t x = 0; x < 10; ++x)
+		data[x] = x +1 ;
+
+	unique_ptr< T1DInterpolator<double> > interp(ipf->create(data));
+
+	BOOST_CHECK_EQUAL( (*interp)(-1), 1.0);
+	BOOST_CHECK_EQUAL( (*interp)(11), 10.0);
+
+	for(size_t x = 0; x < 10; ++x) {
+		
+		BOOST_CHECK_EQUAL( (*interp)(x - 0.2), x + 1);
+		BOOST_CHECK_EQUAL( (*interp)(x + 0.2), x + 1);
+	
+	}
+
+	C1DInterpolatorFactory other(*ipf); 
+
+	unique_ptr< T1DInterpolator<double> > interp2(other.create(data));
+
+	BOOST_CHECK_EQUAL( (*interp2)(-1), 1.0);
+	BOOST_CHECK_EQUAL( (*interp2)(11), 10.0);
+
+	for(size_t x = 0; x < 10; ++x) {
+		
+		BOOST_CHECK_EQUAL( (*interp2)(x - 0.2), x + 1);
+		BOOST_CHECK_EQUAL( (*interp2)(x + 0.2), x + 1);
+	
+	}
+
+
+	*ipf = other;
+	
+	unique_ptr< T1DInterpolator<double> > interp3(other.create(data));
+
+	BOOST_CHECK_EQUAL( (*interp3)(-1), 1.0);
+	BOOST_CHECK_EQUAL( (*interp3)(11), 10.0);
+
+	for(size_t x = 0; x < 10; ++x) {
+		
+		BOOST_CHECK_EQUAL( (*interp3)(x - 0.2), x + 1);
+		BOOST_CHECK_EQUAL( (*interp3)(x + 0.2), x + 1);
+	
+	}
+
+	
+}
+
+class CDummyLargeKernel: public CSplineKernel {
+public:
+	CDummyLargeKernel();
+	void get_weights(double x, VWeight& weight) const;
+	void get_derivative_weights(double x, VWeight& weight) const;
+	void get_derivative_weights(double x, VWeight& weight, int order) const;
+
+	
+}; 
+
+CDummyLargeKernel::CDummyLargeKernel():
+	CSplineKernel(6, -1, ip_unknown)
+{
+}
+
+void CDummyLargeKernel::get_weights(double MIA_PARAM_UNUSED(x), VWeight& weight) const
+{
+	fill(weight.begin(), weight.end(), 1.0/weight.size());
+	cvdebug() << "Dummy weights f=" << weight << "\n"; 
+}
+
+void CDummyLargeKernel::get_derivative_weights(double MIA_PARAM_UNUSED(x), VWeight& weight) const
+{
+	fill(weight.begin(), weight.end(), 0.5/weight.size());
+	cvdebug() << "Dummy weights df=" << weight << "\n"; 
+}
+
+void CDummyLargeKernel::get_derivative_weights(double MIA_PARAM_UNUSED(x), VWeight& weight, int order) const
+{
+	fill(weight.begin(), weight.end(), 1.0/(weight.size() * (order + 1)));
+}
+
+BOOST_AUTO_TEST_CASE( test_big_kernel )
+{
+	vector<double> data(30);
+	for(size_t x = 0; x < 30; ++x)
+		data[x] = x + 1;
+
+	cvdebug() << "Data = " << data << "\n"; 
+
+	PSplineKernel kernel(new CDummyLargeKernel); 
+	C1DInterpolatorFactory factory(kernel, *produce_spline_boundary_condition("repeat"));
+
+	unique_ptr< T1DInterpolator<double> > interp(factory.create(data));
+
+	
+	BOOST_CHECK_CLOSE( (*interp)(10), 10.0, 1e-5);
+
+	BOOST_CHECK_CLOSE(interp->derivative_at(10), 5, 1e-5);
+
+	// derivatives are cut off at the boundaries 
+	BOOST_CHECK_EQUAL(interp->derivative_at(-1), 0.0);
+	BOOST_CHECK_EQUAL(interp->derivative_at(31), 0.0);
+
+	CSplineKernel::VWeight weights(kernel->size()); 
+
+	kernel->get_derivative_weights(0, weights, 2);
+
+	for (auto w: weights) {
+		BOOST_CHECK_CLOSE(w, 1.0 / 21.0, 1e-5); 
+	}
+}
diff --git a/mia/core/test_iohandler.cc b/mia/core/test_iohandler.cc
index 42b37a0..7a9befd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +79,30 @@ BOOST_FIXTURE_TEST_CASE(  test_preferred_suffix, DummyPluginFixture )
 	const CTestIOPluginHandler::Instance&  handler = CTestIOPluginHandler::instance();
 	BOOST_CHECK_EQUAL(handler.get_preferred_suffix("datapool"), "@");
 	BOOST_CHECK_EQUAL(handler.get_preferred_suffix("la"), "hey");
+	
+	auto suffixset = handler.get_supported_suffix_set();
+	BOOST_CHECK_EQUAL(suffixset.size(), 4u); 
+	BOOST_CHECK(suffixset.find("la") != suffixset.end());
+	BOOST_CHECK(suffixset.find("lo") != suffixset.end());
+	BOOST_CHECK(suffixset.find("@") != suffixset.end());
+	BOOST_CHECK(suffixset.find("hey") != suffixset.end());
+
+	BOOST_CHECK(&handler.preferred_plugin("test.la.gz") == &handler.preferred_plugin("test.la.xz"));
+	BOOST_CHECK(&handler.preferred_plugin("test.la.gz") == &handler.preferred_plugin("test.la"));
+	BOOST_CHECK(&handler.preferred_plugin("test.la.gz") == &handler.preferred_plugin("test.la.bz2"));
+	BOOST_CHECK(&handler.preferred_plugin("test.la.gz") == &handler.preferred_plugin("test.la.Z"));
+
+	BOOST_CHECK_EQUAL(handler.preferred_plugin_ptr("test.la.gz"), handler.preferred_plugin_ptr("test.la.xz"));
+	BOOST_CHECK_EQUAL(handler.preferred_plugin_ptr("test.la.gz"), handler.preferred_plugin_ptr("test.la"));
+	BOOST_CHECK_EQUAL(handler.preferred_plugin_ptr("test.la.gz"), handler.preferred_plugin_ptr("test.la.bz2"));
+	BOOST_CHECK_EQUAL(handler.preferred_plugin_ptr("test.la.gz"), handler.preferred_plugin_ptr("test.la.Z"));
+	BOOST_CHECK(handler.preferred_plugin_ptr("unknown.le") == nullptr);
+	BOOST_CHECK(handler.preferred_plugin_ptr("some.datapool") != nullptr);
+	
+	BOOST_CHECK_THROW(handler.get_preferred_suffix("nonsense.les"), runtime_error);
+	BOOST_CHECK_THROW(handler.preferred_plugin("nonsense.nonsense"), invalid_argument);
+
 
-	BOOST_CHECK_THROW(handler.get_preferred_suffix("nonsense"), runtime_error);
 }
 
 BOOST_FIXTURE_TEST_CASE(  test_datapool_io, DummyPluginFixture )
diff --git a/mia/core/test_kernels.cc b/mia/core/test_kernels.cc
index f475495..dda81a4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 7e056eb..3c93530 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +28,18 @@
 NS_MIA_USE;
 using namespace std;
 
+BOOST_AUTO_TEST_CASE( test_closes_class_center )
+{
+	std::vector<double> classes{-10, 10, 20, 30};
+
+	BOOST_CHECK_EQUAL(kmeans_get_closest_clustercenter(classes, 3, -2), 0);
+	BOOST_CHECK_EQUAL(kmeans_get_closest_clustercenter(classes, 1, 30), 1);
+	BOOST_CHECK_EQUAL(kmeans_get_closest_clustercenter(classes, 4, 24), 2);
+	BOOST_CHECK_EQUAL(kmeans_get_closest_clustercenter(classes, 3, 28), 3);
+	BOOST_CHECK_EQUAL(kmeans_get_closest_clustercenter(classes, 4, 18), 2);
+
+}
+
 BOOST_AUTO_TEST_CASE( test_kmeans0 )
 {
 	const size_t nelements = 3;
diff --git a/mia/core/test_labelmap.cc b/mia/core/test_labelmap.cc
index c282273..cf722aa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 b9f68ce..e00922f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 524cd57..d1edbc3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_nccsum.cc b/mia/core/test_nccsum.cc
index b99c13d..16213ee 100644
--- a/mia/core/test_nccsum.cc
+++ b/mia/core/test_nccsum.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_noisegen.cc b/mia/core/test_noisegen.cc
index 7a142ef..32c615d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f88b493..84e0b15 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_optparam.cc b/mia/core/test_optparam.cc
index 025e69c..4481380 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,30 +118,19 @@ BOOST_AUTO_TEST_CASE( test_sucess2)
 BOOST_AUTO_TEST_CASE( test_fail1)
 {
 	params p_expect = { true, 5, 1.3, 7.1, "huhu" };
-	try {
-		char option_success[] = "plugin:kill=1,min=1.3,nana=name,max=7.1,no=5";
-		try_parsing_and_setting(option_success, p_expect);
-		BOOST_FAIL("did not catch the unknown parameter");
-	}
-	catch (invalid_argument& x) {
-		// it should throw ...
-		BOOST_MESSAGE(x.what());
-	}
-
+	
+	char option_success[] = "plugin:kill=1,min=1.3,nana=name,max=7.1,no=5";
+	
+	BOOST_CHECK_THROW(try_parsing_and_setting(option_success, p_expect), 
+			  invalid_argument);
 }
 
 BOOST_AUTO_TEST_CASE( test_fail2)
 {
 	params p_expect = { true, 5, 1.3, 7.1, "huhu" };
-	try {
-		char option_success[] = "plugin:min=1.3,nana=name,max=7.1";
-		try_parsing_and_setting(option_success, p_expect);
-		BOOST_FAIL("did not catch the missing parameter");
-	}
-	catch (invalid_argument& x) {
-		// it should throw ...
-		BOOST_MESSAGE(x.what());
-	}
+	
+	char option_success[] = "plugin:min=1.3,nana=name,max=7.1";
+	BOOST_CHECK_THROW(try_parsing_and_setting(option_success, p_expect), invalid_argument); 
 }
 
 
diff --git a/mia/core/test_parallelcxx11.cc b/mia/core/test_parallelcxx11.cc
new file mode 100644
index 0000000..e6aaa84
--- /dev/null
+++ b/mia/core/test_parallelcxx11.cc
@@ -0,0 +1,103 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/parallelcxx11.hh>
+#include <mia/internal/autotest.hh>
+using namespace mia;
+using namespace std; 
+
+BOOST_AUTO_TEST_CASE (test_preduce)
+{
+	int identity_value = 0;
+	C1DParallelRange range(0, 200, 10);
+
+	vector<int> input(200);
+	for (int i = 0; i < 200; ++i)
+		input[i] = i;
+
+	auto p_func = [&input](const C1DParallelRange& range, int in_value) {
+		for (auto i= range.begin(); i != range.end(); ++i) {
+			in_value += input[i]; 
+		}
+		return in_value; 
+	};
+
+	auto r_func = [](int a, int b){return a+b;}; 
+	
+	int result = preduce(range, identity_value, p_func, r_func); 
+	
+	BOOST_CHECK_EQUAL(result, 100*199); 
+	
+}
+
+BOOST_AUTO_TEST_CASE (test_preduce_vector_result)
+{
+	vector<int> identity_value(2, 0);
+	C1DParallelRange range(0, 200, 10);
+
+	vector<int> input(200);
+	for (int i = 0; i < 200; ++i)
+		input[i] = i;
+
+	auto p_func = [&input](const C1DParallelRange& range, vector<int> in_value) -> vector<int>{
+		for (auto i= range.begin(); i != range.end(); ++i) {
+			in_value[0] += input[i];
+			in_value[1] += 2 * input[i]; 
+		}
+		return in_value; 
+	};
+
+	auto r_func = [](const vector<int>& a, const vector<int>& b) -> vector<int>{
+		vector<int> out(a);
+		transform(out.begin(), out.end(), b.begin(), out.begin(), [](int ia, int ib){return ia + ib;}); 
+		return out;
+	}; 
+	
+	auto  result = preduce(range, identity_value, p_func, r_func);
+	
+	BOOST_CHECK_EQUAL(result.size(), 2u); 
+	BOOST_CHECK_EQUAL(result[0], 100*199);
+	BOOST_CHECK_EQUAL(result[1], 2 * 100*199); 
+	
+}
+
+
+BOOST_AUTO_TEST_CASE (test_pfor)
+{
+
+	C1DParallelRange range(0, 200, 10);
+
+	vector<int> input(200);
+	for (int i = 0; i < 200; ++i)
+		input[i] = i;
+
+	auto p_func = [&input](const C1DParallelRange& range) {
+		for (auto i= range.begin(); i != range.end(); ++i) {
+			input[i] *= 2; 
+		}
+	};
+
+
+	pfor(range, p_func); 
+	
+	for (int i = 0; i < 200; ++i) {
+		BOOST_CHECK_EQUAL(input[i], 2*i); 
+	}
+}
diff --git a/mia/core/test_parameter.cc b/mia/core/test_parameter.cc
index 8d38f7b..e0dc71f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +35,7 @@
 
 NS_MIA_USE
 
+
 using namespace std;
 BOOST_AUTO_TEST_CASE( test_params )
 {
@@ -59,35 +60,35 @@ BOOST_AUTO_TEST_CASE( test_params )
 
 }
 
-enum ETest {te_unknown, te_a, te_b, te_c};
+enum ETestParameter {tep_unknown, tep_a, tep_b, tep_c};
 
 BOOST_AUTO_TEST_CASE( test_dict_params)
 {
 
-	static const TDictMap<ETest>::Table table[] = {
-		{"a", te_a, "test a"},
-		{"b", te_b, "test b"},
-		{"c", te_c, "test c"},
-		{NULL, te_unknown, ""}
+	static const TDictMap<ETestParameter>::Table table[] = {
+		{"a", tep_a, "test a"},
+		{"b", tep_b, "test b"},
+		{"c", tep_c, "test c"},
+		{NULL, tep_unknown, ""}
 	};
 
-	const TDictMap<ETest> map(table, true);
-	ETest test1 = te_a;
+	const TDictMap<ETestParameter> map(table, true);
+	ETestParameter test1 = tep_a;
 
-	CDictParameter<ETest> testp1(test1, map, "some dictionary parameter");
+	CDictParameter<ETestParameter> testp1(test1, map, "some dictionary parameter");
 
-	BOOST_CHECK_EQUAL(test1, te_a);
+	BOOST_CHECK_EQUAL(test1, tep_a);
 
 	BOOST_CHECK(testp1.set("b"));
-	BOOST_CHECK_EQUAL(test1, te_b);
+	BOOST_CHECK_EQUAL(test1, tep_b);
 
 	BOOST_CHECK(testp1.set("c"));
-	BOOST_CHECK_EQUAL(test1, te_c);
+	BOOST_CHECK_EQUAL(test1, tep_c);
 	BOOST_CHECK(testp1.set("chajh"));
-	BOOST_CHECK_EQUAL(test1, te_unknown);
+	BOOST_CHECK_EQUAL(test1, tep_unknown);
 
-	const TDictMap<ETest> map2(table);
-	CDictParameter<ETest> testp2(test1, map2, "some dictionary parameter");
+	const TDictMap<ETestParameter> map2(table);
+	CDictParameter<ETestParameter> testp2(test1, map2, "some dictionary parameter");
 	BOOST_CHECK_THROW(testp2.set("chajh"), std::invalid_argument);
 
 
diff --git a/mia/core/test_parseroutput.cc b/mia/core/test_parseroutput.cc
index 83f0320..d6e7d9d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d1f6243..c804ab3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5180b93..f944407 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 7398bd5..26e3c2b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,14 +20,7 @@
 
 #include <mia/internal/autotest.hh>
 #include <mia/core/productcache.hh>
-
-#include <tbb/task_scheduler_init.h>
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-#include <tbb/atomic.h>
-
-using namespace tbb;
-
+#include <mia/core/parallel.hh>
 
 NS_MIA_USE
 using namespace std; 
@@ -119,17 +112,17 @@ BOOST_AUTO_TEST_CASE(test_basic_cache_enabled_global_clear)
 
 
 struct CacheAccessTest {
-	tbb::atomic<int> *n_errors; 
-	CacheAccessTest(tbb::atomic<int> *_nerr); 
-	void operator()( const blocked_range<int>& range ) const; 
+	ATOMIC<int> *n_errors; 
+	CacheAccessTest(ATOMIC<int> *_nerr); 
+	void operator()( const C1DParallelRange& range ) const; 
 }; 
 
-CacheAccessTest::CacheAccessTest(tbb::atomic<int> *_nerr):
+CacheAccessTest::CacheAccessTest(ATOMIC<int> *_nerr):
 	n_errors(_nerr)
 { 
 }
 
-void CacheAccessTest::operator() ( const blocked_range<int>& range ) const
+void CacheAccessTest::operator() ( const C1DParallelRange& range ) const
 {
 	try {	
 		for(auto i=range.begin(); i!=range.end(); ++i ) {
@@ -145,10 +138,10 @@ void CacheAccessTest::operator() ( const blocked_range<int>& range ) const
 }
 
 struct CacheWriteTest {
-	void operator()( const blocked_range<int>& range ) const; 
+	void operator()( const C1DParallelRange& range ) const; 
 }; 
 
-void CacheWriteTest::operator() ( const blocked_range<int>& range ) const
+void CacheWriteTest::operator() ( const C1DParallelRange& range ) const
 {
 	for(auto i=range.begin(); i!=range.end(); ++i ) {
 		stringstream s; 
@@ -159,17 +152,17 @@ void CacheWriteTest::operator() ( const blocked_range<int>& range ) const
 
 
 struct CacheReadTest {
-	tbb::atomic<int> *n_errors; 
-	CacheReadTest(tbb::atomic<int> *_nerr); 
-	void operator()( const blocked_range<int>& range ) const; 
+	ATOMIC<int> *n_errors; 
+	CacheReadTest(ATOMIC<int> *_nerr); 
+	void operator()( const C1DParallelRange& range ) const; 
 }; 
 
-CacheReadTest::CacheReadTest(tbb::atomic<int> *_nerr):
+CacheReadTest::CacheReadTest(ATOMIC<int> *_nerr):
 	n_errors(_nerr)
 { 
 }
 
-void CacheReadTest::operator() ( const blocked_range<int>& range ) const
+void CacheReadTest::operator() ( const C1DParallelRange& range ) const
 {
 	try {	
 		for(auto i=range.begin(); i!=range.end(); ++i ) {
@@ -195,25 +188,23 @@ BOOST_AUTO_TEST_CASE( test_cache_parallel_access )
 	the_cache.clear(); 
 	the_cache.enable_write(true); 
 
-
-	task_scheduler_init init;
-	tbb::atomic<int> n_errors; 
+	ATOMIC<int> n_errors; 
 	n_errors = 0; 
 
-	blocked_range<int> range( 0, 1000, 1 ); 
+	C1DParallelRange range( 0, 1000, 1 ); 
 	CacheAccessTest ptest(&n_errors); 
 	
 
 
-	parallel_for(range, ptest); 
+	pfor(range, ptest); 
 	BOOST_CHECK_EQUAL(n_errors, 0); 
 
 	CacheWriteTest wtest; 
-	parallel_for(range, wtest); 
+	pfor(range, wtest); 
 
 	n_errors = 0; 
 	CacheReadTest rtest(&n_errors);
-	parallel_for(range, rtest); 
+	pfor(range, rtest); 
 	BOOST_CHECK_EQUAL(n_errors, 0); 
 	
 	
diff --git a/mia/core/test_property_flags.cc b/mia/core/test_property_flags.cc
index 79c5593..ef2f89c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2890671..43e8df7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 9848825..f67c412 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 09d744f..c4a368a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ struct Scaler1DFixture  {
 	Scaler1DFixture(); 
 
 	double f(double x) const;
-	void test_size(EInterpolation type, size_t target_size);
+	void test_size(const string& interpolator_kernel, size_t target_size);
 	void test_scale_by_factor(const string& kernel_descr, double scale, size_t expected_size);
 
 
@@ -53,7 +53,7 @@ struct Scaler1DFixture  {
 
 BOOST_FIXTURE_TEST_CASE( test_bspline2_upscale, Scaler1DFixture)
 {
-	test_size(ip_bspline2, 500);
+	test_size("bspline:d=2", 500);
 }
 
 BOOST_FIXTURE_TEST_CASE( test_bspline2_upscale_scale, Scaler1DFixture)
@@ -78,44 +78,44 @@ BOOST_FIXTURE_TEST_CASE( test_bspline3_downscale_scale, Scaler1DFixture)
 
 BOOST_FIXTURE_TEST_CASE( test_bspline3_upscale, Scaler1DFixture)
 {
-	test_size(ip_bspline3, 500);
+	test_size("bspline:d=3", 500);
 }
 
 BOOST_FIXTURE_TEST_CASE( test_bspline3_downscale, Scaler1DFixture)
 {
-	test_size(ip_bspline3, 130);
+	test_size("bspline:d=3", 130);
 }
 
 
 BOOST_FIXTURE_TEST_CASE( test_bspline4_upscale, Scaler1DFixture)
 {
-	test_size(ip_bspline4, 500);
+	test_size("bspline:d=4", 500);
 }
 
 BOOST_FIXTURE_TEST_CASE( test_bspline4_downscale, Scaler1DFixture)
 {
-	test_size(ip_bspline4, 130);
+	test_size("bspline:d=4", 130);
 }
 
 
 BOOST_FIXTURE_TEST_CASE( test_bspline5_upscale, Scaler1DFixture)
 {
-	test_size(ip_bspline5, 500);
+	test_size("bspline:d=5", 500);
 }
 
 BOOST_FIXTURE_TEST_CASE( test_bspline5_downscale, Scaler1DFixture)
 {
-	test_size(ip_bspline5, 130);
+	test_size("bspline:d=5", 130);
 }
 
 
 BOOST_FIXTURE_TEST_CASE( test_omoms3_upscale, Scaler1DFixture)
 {
-	test_size(ip_omoms3, 500);
+	test_size("omoms:d=3", 500);
 }
 BOOST_FIXTURE_TEST_CASE( test_omoms3_downscale, Scaler1DFixture)
 {
-	test_size(ip_omoms3, 130);
+	test_size("omoms:d=3", 130);
 }
 
 
@@ -134,12 +134,12 @@ Scaler1DFixture::Scaler1DFixture():
 		data[x] = 200*f(intervall * x);
 }
 
-void Scaler1DFixture::test_size(EInterpolation type, size_t target_size)
+void Scaler1DFixture::test_size(const string& interpolator_kernel, size_t target_size)
 {
 	C1DScalar::std_double_vector result(target_size); 
 	
-	unique_ptr<C1DInterpolatorFactory>  ipf(create_1dinterpolation_factory(type, bc_mirror_on_bounds));	
-	C1DScalar scaler(*ipf->get_kernel(), data.size(), target_size); 
+	C1DInterpolatorFactory  ipf(interpolator_kernel, "mirror");	
+	C1DScalar scaler(*ipf.get_kernel(), data.size(), target_size); 
 
 	copy(data.begin(), data.end(), scaler.input_begin()); 
 	
diff --git a/mia/core/test_seriesstats.cc b/mia/core/test_seriesstats.cc
index 919c2c2..5588cde 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1a2694b..10a01ef 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ee9860e..52ded7e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 5cd29c5..76b1fe0 100644
--- a/mia/core/test_singular_refobj.cc
+++ b/mia/core/test_singular_refobj.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_slopeclassifier.cc b/mia/core/test_slopeclassifier.cc
index ac42213..82b3f90 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 af11d4d..de6de38 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,12 +19,11 @@
  */
 
 #include <mia/internal/autotest.hh>
+#include <mia/core/slopestatistics.hh>
 
 #include <stdexcept>
 #include <cmath>
-
-#include <mia/core/slopestatistics.hh>
-
+#include <numeric> 
 
 using namespace std;
 NS_MIA_USE
diff --git a/mia/core/test_sparse_histogram.cc b/mia/core/test_sparse_histogram.cc
new file mode 100644
index 0000000..7220cee
--- /dev/null
+++ b/mia/core/test_sparse_histogram.cc
@@ -0,0 +1,133 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/sparse_histogram.hh>
+
+NS_MIA_USE
+using std::vector;
+using std::invalid_argument;
+
+BOOST_AUTO_TEST_CASE( test_uint8 )
+{
+        vector <unsigned char> input = {1, 1, 200, 200, 200};
+
+        CSparseHistogram h;
+
+        BOOST_CHECK_EQUAL(h(input.begin(), input.end()), 5u);
+        
+        auto ch = h.get_compressed_histogram(); 
+        BOOST_REQUIRE(ch.size() == 2u);
+
+        BOOST_CHECK_EQUAL( ch[0].first,   1 );
+        BOOST_CHECK_EQUAL( ch[0].second,  2 ); 
+        BOOST_CHECK_EQUAL( ch[1].first, 200 );
+        BOOST_CHECK_EQUAL( ch[1].second,  3 );
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_sint8 )
+{
+        vector <signed char> input = {-2, -2, 30, 30, 30};
+
+        CSparseHistogram h;
+
+        BOOST_CHECK_EQUAL(h(input.begin(), input.end()), 5u);
+        
+        auto ch = h.get_compressed_histogram(); 
+        BOOST_REQUIRE(ch.size() == 2u);
+
+        BOOST_CHECK_EQUAL( ch[0].first, -2 );
+        BOOST_CHECK_EQUAL( ch[0].second, 2 ); 
+        BOOST_CHECK_EQUAL( ch[1].first, 30 );
+        BOOST_CHECK_EQUAL( ch[1].second, 3 );
+        
+}
+
+
+BOOST_AUTO_TEST_CASE( test_uint16 )
+{
+        vector <unsigned short> input = {1, 1, 400, 400, 400};
+
+        CSparseHistogram h;
+
+        BOOST_CHECK_EQUAL(h(input.begin(), input.end()), 5u);
+        
+        auto ch = h.get_compressed_histogram(); 
+        BOOST_REQUIRE(ch.size() == 2u);
+
+        BOOST_CHECK_EQUAL( ch[0].first,   1 );
+        BOOST_CHECK_EQUAL( ch[0].second,  2 ); 
+        BOOST_CHECK_EQUAL( ch[1].first, 400 );
+        BOOST_CHECK_EQUAL( ch[1].second,  3 );
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_sint16 )
+{
+        vector <signed short> input = {-200, -200, 300, 300, 300};
+
+        CSparseHistogram h;
+
+        BOOST_CHECK_EQUAL(h(input.begin(), input.end()), 5u);
+        
+        auto ch = h.get_compressed_histogram();
+        BOOST_CHECK_EQUAL(ch.size(), 2u);
+        BOOST_REQUIRE(ch.size() == 2u);
+
+        BOOST_CHECK_EQUAL( ch[0].first, -200 );
+        BOOST_CHECK_EQUAL( ch[0].second,   2 ); 
+        BOOST_CHECK_EQUAL( ch[1].first,  300 );
+        BOOST_CHECK_EQUAL( ch[1].second,   3 );
+        
+}
+
+BOOST_AUTO_TEST_CASE( test_unsupported )
+{
+        CSparseHistogram hsi;
+        vector <signed int> si = { -64000, -64000, 64002, 64002 }; 
+        BOOST_CHECK_THROW(hsi(si.begin(), si.end()), invalid_argument);
+
+        CSparseHistogram hui;
+        vector <unsigned int> ui = { 64000, 64000, 64002, 64002 }; 
+        BOOST_CHECK_THROW(hui(ui.begin(), ui.end()), invalid_argument);
+
+        CSparseHistogram hf;
+        vector <float> f = { -1.0f, -1.1f, 2.0f, 3.0f }; 
+        BOOST_CHECK_THROW(hf(si.begin(), si.end()), invalid_argument);
+
+        CSparseHistogram hd;
+        vector <double> d = { -1.0, -1.1, 2.0, 3.0 }; 
+        BOOST_CHECK_THROW(hd(d.begin(), d.end()), invalid_argument);
+       
+}
+
+BOOST_AUTO_TEST_CASE( test_mix_types )
+{
+        vector <signed short> input_ss = {-200, -200, 300, 300, 300};
+        vector <unsigned short> input_us = {200, 200, 400, 400, 400};
+        
+        CSparseHistogram h;
+
+        BOOST_CHECK_EQUAL(h(input_ss.begin(), input_ss.end()), 5u);
+        BOOST_CHECK_THROW(h(input_us.begin(), input_us.end()), invalid_argument);
+}
+
diff --git a/mia/core/test_sparse_solver.cc b/mia/core/test_sparse_solver.cc
index 3f837f2..9c9ae13 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 <mia/internal/autotest.hh>
 #include <mia/core/sparse_solver.hh>
+#include <numeric> 
 
 /**
    This test only tests the general idea of the unified solver class, and 
diff --git a/mia/core/test_splinekernel.cc b/mia/core/test_splinekernel.cc
index c2e7064..e03090b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,15 +18,16 @@
  *
  */
 
-#include <stdexcept>
-#include <climits>
 
 #include <mia/internal/autotest.hh>
-
-#include <boost/filesystem/path.hpp>
 #include <mia/core/splinekernel.hh>
 #include <mia/core/boundary_conditions.hh>
 
+#include <boost/filesystem/path.hpp>
+#include <stdexcept>
+#include <climits>
+
+
 namespace bfs=::boost::filesystem; 
 
 
diff --git a/mia/core/test_splineparzenmi.cc b/mia/core/test_splineparzenmi.cc
index 3043cbe..84f9097 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_sqmin.cc b/mia/core/test_sqmin.cc
index eb6b5fd..cdd1262 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 e9f129b..3c77278 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 5ed627e..d56c0ed 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index cf21fc3..32528a2 100644
--- a/mia/core/test_streamvector.cc
+++ b/mia/core/test_streamvector.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,21 @@ BOOST_AUTO_TEST_CASE( test_read_strings_to_empty_vector )
 	BOOST_CHECK_EQUAL(result[2], "test3");
 }
 
+BOOST_AUTO_TEST_CASE( test_read_int_to_empty_vector ) 
+{
+	istringstream is("1 , 2, 3"); 
+	
+	vector<int> result; 
+	is >> result; 
+
+	BOOST_REQUIRE(result.size() == 3u); 
+	
+	BOOST_CHECK_EQUAL(result[0], 1); 
+	BOOST_CHECK_EQUAL(result[1], 2); 
+	BOOST_CHECK_EQUAL(result[2], 3);
+}
+
+
 BOOST_AUTO_TEST_CASE( test_read_strings_to_presized_vector ) 
 {
 	istringstream is("test1,test2,test3"); 
@@ -73,6 +88,17 @@ BOOST_AUTO_TEST_CASE( test_read_strings_to_presized_vector_throw_not_enough )
 	BOOST_CHECK_THROW(is >> result, invalid_argument); 
 }
 
+BOOST_AUTO_TEST_CASE( test_write_vector_to_stream ) 
+{
+	vector<int> a = {1, 2, 3};
+
+	ostringstream s;
+	s << a;
+	BOOST_CHECK_EQUAL(s.str(), "1,2,3"); 
+	
+}
+
+
 BOOST_AUTO_TEST_CASE( test_read_float ) 
 {
 	istringstream is("1.0,1e-10,3.0"); 
@@ -89,7 +115,7 @@ BOOST_AUTO_TEST_CASE( test_read_float )
 
 BOOST_AUTO_TEST_CASE( test_read_float_fail ) 
 {
-	istringstream is("1.0f,1e-10,3.0"); 
+	istringstream is("a1.0a,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 25bc428..06088ca 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 +23,7 @@
 #include <mia/internal/autotest.hh>
 #include <iomanip>
 #include <mia/core/threadedmsg.hh>
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-using namespace tbb;
-
+#include <mia/core/parallel.hh>
 
 NS_MIA_USE;
 using namespace std;
@@ -35,14 +32,14 @@ using namespace std;
 struct ThreadFixture {
 	ThreadFixture(); 
 
-	void operator () ( const blocked_range<int>& range ) const; 
+	void operator () ( const C1DParallelRange& range ) const; 
 
 }; 
 
 struct ThreadFixture2 {
 	ThreadFixture2(); 
 
-	void operator () ( const blocked_range<int>& range ) const; 
+	void operator () ( const C1DParallelRange& range ) const; 
 }; 
 
 
@@ -53,7 +50,7 @@ ThreadFixture::ThreadFixture()
 	CThreadMsgStream::set_master_stream(master_stream); 
 }
 
-void ThreadFixture::operator () ( const blocked_range<int>& range ) const
+void ThreadFixture::operator () ( const C1DParallelRange& range ) const
 {
 	CThreadMsgStream thread_stream;
 
@@ -68,7 +65,7 @@ ThreadFixture2::ThreadFixture2()
 	CThreadMsgStream::set_master_stream(master_stream); 
 }
 
-void ThreadFixture2::operator () ( const blocked_range<int>& range ) const
+void ThreadFixture2::operator () ( const C1DParallelRange& range ) const
 {
 	CThreadMsgStream thread_stream;
 
@@ -85,7 +82,7 @@ BOOST_AUTO_TEST_CASE( test_threaded_msg )
 	auto old_level =  cverb.get_level();
 	cverb.set_verbosity(vstream::ml_message); 
 	ThreadFixture fix; 
-	parallel_for(blocked_range<int>( 0, 100), fix);
+	pfor(C1DParallelRange( 0, 100), fix);
 	
 	cverb.set_verbosity(old_level); 
 	
@@ -118,7 +115,7 @@ BOOST_AUTO_TEST_CASE( test_threaded_msg_sync )
 	auto old_level =  cverb.get_level();
 	cverb.set_verbosity(vstream::ml_message); 
 	ThreadFixture2 fix; 
-	parallel_for(blocked_range<int>( 0, 100), fix);
+	pfor(C1DParallelRange( 0, 100), fix);
 	
 	cverb.set_verbosity(old_level); 
 	
diff --git a/mia/core/test_tools.cc b/mia/core/test_tools.cc
index 4eabc41..b83cd86 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 201d186..de4ae26 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ BOOST_AUTO_TEST_CASE(test_sincos)
 	sincos(x, &s, &c); 
 	
 	BOOST_CHECK_CLOSE(c, 0.5, 0.01); 
-	BOOST_CHECK_CLOSE(c, sqrt(3.0)/2.0, 0.01); 
+	BOOST_CHECK_CLOSE(s, sqrt(3.0)/2.0, 0.01); 
 
 
 	double fx = M_PI/3.0; 
@@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(test_sincos)
 	sincos(fx, &fs, &fc); 
 	
 	BOOST_CHECK_CLOSE(fc, 0.5f, 0.01f); 
-	BOOST_CHECK_CLOSE(fc, sqrtf(3.0f)/2.0f, 0.01f); 
+	BOOST_CHECK_CLOSE(fs, sqrtf(3.0f)/2.0f, 0.01f); 
 
 #endif	
 }
diff --git a/mia/core/test_watch.cc b/mia/core/test_watch.cc
index 2c19141..473b040 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 cdcc2db..4819fda 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_xmlinterface.cc b/mia/core/test_xmlinterface.cc
index e0197b6..ac0826c 100644
--- a/mia/core/test_xmlinterface.cc
+++ b/mia/core/test_xmlinterface.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a96b414..dca8cab 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 66c03a2..3e1ba10 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3648a15..551c84c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/lolo.cc b/mia/core/testplug/lolo.cc
index 4d4b0c5..537f3c2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f9c78f3..83d41e6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/core/testplugin.hh
index 850ddc4..7dd8a0a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ public:
 
 template <> const char * const TPluginHandler<CTestPlugin>::m_help; 
 
-extern template class EXPORT_CORE TPluginHandler<CTestPlugin>;
+extern template class TPluginHandler<CTestPlugin>;
 
 /**
    \ingroup test 
diff --git a/mia/core/threadedmsg.cc b/mia/core/threadedmsg.cc
index 898c1ae..f341795 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +22,9 @@
 #include <iomanip>
 #include <mia/core/threadedmsg.hh>
 #include <sstream> 
-#include <tbb/mutex.h>
+
 #include <stdexcept>
+#include <mia/core/parallel.hh>
 #include <mia/core/msgstream.hh>
 
 NS_MIA_BEGIN
@@ -47,7 +48,7 @@ private:
 	std::ostringstream m_buffer; 
 	int m_id; 
 	static std::ostream *m_master;
-	static tbb::mutex m_master_lock; 
+	static CMutex m_master_lock; 
 	static int m_next_id; 
 }; 
 
@@ -112,11 +113,12 @@ void thread_streamredir::send_to_master()
 }
 
 std::ostream *thread_streamredir::m_master = &std::cerr;
-tbb::mutex thread_streamredir::m_master_lock; 
+CMutex thread_streamredir::m_master_lock; 
 int thread_streamredir::m_next_id = 0; 
 
 
 CThreadMsgStream::CThreadMsgStream():
+	// coverity[resource_leak] explanation below in destructor 
 	std::ostream(new thread_streamredir()), 
 	m_old(vstream::instance().set_stream(*this))
 {
@@ -126,6 +128,8 @@ CThreadMsgStream::~CThreadMsgStream()
 {
 	flush(); 
 	vstream::instance().set_stream(m_old);
+	// At this point we delete the thread_streamredir object that is
+	// created in the constructor 
 	delete rdbuf();
 }
 
diff --git a/mia/core/threadedmsg.hh b/mia/core/threadedmsg.hh
index 6e8087d..8c4e4e3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8d6dcb8..2282911 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 ea6770a..cd8e5f1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 30d1bce..3a468ba 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/type_traits.hh b/mia/core/type_traits.hh
index c7dd0f7..33939a4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,28 @@ NS_MIA_BEGIN
 
 /// @cond INTERNAL 
 
+template <typename T> 
+struct __holder_type_dispatch  {
+	typedef T type; 
+}; 
+
+
+template <> 
+struct __holder_type_dispatch<bool>  {
+	typedef unsigned char type; 
+}; 
+
+
+template <typename T>
+struct __is_mask_pixel {
+	static const bool value = false;
+}; 
+
+template <>
+struct __is_mask_pixel<bool> {
+	static const bool value = true;
+}; 
+
 /**
    @ingroup traits 
    @brief A trait to derive the actual type handled by a plug-in based on some 
diff --git a/mia/core/typedescr.cc b/mia/core/typedescr.cc
index b072053..8379dbc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c1a1949..f9fd9d7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 cdd9890..6903f2a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 +129,13 @@ void FSearchFiles::operator()(const std::string& path) {
 
 #ifndef _GNU_SOURCE
 // there should be an intrinsic (at least on intel) 
-void sincosf(float x, float *s, float *c)
+void EXPORT_CORE sincosf(float x, float *s, float *c)
 {
 	*s = sinf(x); 
 	*c = cosf(x); 
 }
 
-void sincos(double x, double *s, double *c)
+void EXPORT_CORE sincos(double x, double *s, double *c)
 {
 	*s = sin(x); 
 	*c = cos(x); 
diff --git a/mia/core/utils.hh b/mia/core/utils.hh
index 50bb911..f9ab369 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 +73,13 @@ public:
    \ingroup misc
    Provide sincosf conveniance functions for sin and cos if the GNU GCC extension is not available. 
  */
-void sincosf(float x, float *sin, float *cos); 
+void EXPORT_CORE sincosf(float x, float *sin, float *cos); 
 
 /**
    \ingroup misc
    Provide sincosf conveniance functions for sin and cos if the GNU GCC extension is not available. 
  */
-void sincos(double x, double *sin, double *cos); 
+void EXPORT_CORE sincos(double x, double *sin, double *cos); 
 #endif
 
 /**
diff --git a/mia/core/vector.hh b/mia/core/vector.hh
index bf31d1e..e1d79c7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ struct array_void_destructor {
 */
 
 template <typename T> 
-class Vector {
+class TCArrayWrapper {
 public: 
 	
 	/// \cond STLCOMPAT 
@@ -90,7 +90,7 @@ public:
 	   \param n 
 	   \param clean initialize vector to 0
 	 */
-	Vector(size_t n, bool clean = true):
+	TCArrayWrapper(size_t n, bool clean = true):
 		m_size(n),
 		m_data(new T[n], array_destructor<T>()),
 		m_cdata(m_data.get())
@@ -103,7 +103,7 @@ public:
 	    between the original and the copied vector 
 	    \param other
 	*/
-	Vector(const Vector<T>& other):
+	TCArrayWrapper(const TCArrayWrapper<T>& other):
 		m_size(other.m_size),
 		m_data(other.m_data),
 		m_cdata(other.m_cdata)
@@ -111,7 +111,7 @@ public:
 	}
 
 	/// assignment operator 
-	Vector<T>& operator = (const Vector<T>& other)
+	TCArrayWrapper<T>& operator = (const TCArrayWrapper<T>& other)
 	{
 		m_size = other.m_size; 
 		m_data = other.m_data; 
@@ -125,7 +125,7 @@ public:
 	   \param n size of input array
 	   \param init allocated input data
 	 */
-	Vector(size_t n, T *init):
+	TCArrayWrapper(size_t n, T *init):
 		m_size(n),
 		m_data(init, array_void_destructor<T>()),
 		m_cdata(init)
@@ -138,7 +138,7 @@ public:
 	   \param n size of input array
 	   \param init allocated input data
 	 */
-	Vector(size_t n, const T *init):
+	TCArrayWrapper(size_t n, const T *init):
 		m_size(n),
 		m_cdata(init)
 	{
@@ -151,9 +151,9 @@ public:
 	reference operator[] (size_t i) {
 		assert(i < m_size); 
 		DEBUG_ASSERT_RELEASE_THROW(m_data && m_data.unique(), 
-					   "Vector::operator[]: No writeable data availabe or not unique,"
-					   " call Vector::make_unique() first or enforce the use of  "
-					   "'Vector::operator[](...) const'");
+					   "TCArrayWrapper::operator[]: No writeable data availabe or not unique,"
+					   " call TCArrayWrapper::make_unique() first or enforce the use of  "
+					   "'TCArrayWrapper::operator[](...) const'");
 		return m_data.get()[i]; 
 	}
 
@@ -170,9 +170,9 @@ public:
 	 */
 	iterator begin() {
 		DEBUG_ASSERT_RELEASE_THROW(m_data && m_data.unique(), 
-					   "Vector::begin(): No writeable data availabe or not unique, "
-					   "call Vector::make_unique() first or enforce the use of "
-					   "'Vector::begin() const'");
+					   "TCArrayWrapper::begin(): No writeable data availabe or not unique, "
+					   "call TCArrayWrapper::make_unique() first or enforce the use of "
+					   "'TCArrayWrapper::begin() const'");
 		return m_data.get(); 
 	}
 
@@ -181,9 +181,9 @@ public:
 	 */
 	iterator end() {
 		DEBUG_ASSERT_RELEASE_THROW(m_data && m_data.unique(), 
-					   "Vector::begin(): No writeable data availabe or not unique, "
-					   "call Vector::make_unique() first or enforce the use of "
-					   "'Vector::end() const'");
+					   "TCArrayWrapper::begin(): No writeable data availabe or not unique, "
+					   "call TCArrayWrapper::make_unique() first or enforce the use of "
+					   "'TCArrayWrapper::end() const'");
 		return m_data.get() + m_size; 
 	}
 	
@@ -237,7 +237,7 @@ private:
 
 
 template <typename T> 
-std::ostream&  operator << (std::ostream& os, const Vector<T>& v) 
+std::ostream&  operator << (std::ostream& os, const TCArrayWrapper<T>& v) 
 {
         os << "["; 
         for(auto i: v) 
@@ -252,7 +252,7 @@ std::ostream&  operator << (std::ostream& os, const Vector<T>& v)
     
     STL vector like c-array wrapper for double floating point arrays
 */
-typedef Vector<double> CDoubleVector; 
+typedef TCArrayWrapper<double> CDoubleVector; 
 
 NS_MIA_END
 
diff --git a/mia/core/watch.cc b/mia/core/watch.cc
index f5c4bf3..96cd829 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 3bb0a42..76d5bc5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 51da392..8364c13 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 <map>
 #include <algorithm>
+#include <numeric>
 #include <stdexcept>
 #include <cmath>
 
diff --git a/mia/core/waveletslopeclassifier.hh b/mia/core/waveletslopeclassifier.hh
index 5ddb8f5..9f7dee9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/xmlinterface.cc b/mia/core/xmlinterface.cc
index 48e53e3..a74f596 100644
--- a/mia/core/xmlinterface.cc
+++ b/mia/core/xmlinterface.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@ struct CXMLElementImpl {
         ~CXMLElementImpl();
         
         xmlNodePtr element;
-	vector<CXMLElement::Pointer> children; 
+        vector<CXMLElement::Pointer> children;
 }; 
 
 CXMLElementImpl::CXMLElementImpl(const char *name)
@@ -67,7 +67,7 @@ CXMLElement::~CXMLElement()
 CXMLElement::Pointer CXMLElement::add_child(const char *name)
 {
         Pointer result = make_shared<CXMLElement>(name);
-	impl->children.push_back(result); 
+        impl->children.push_back(result);
         xmlAddChild(impl->element, result->impl->element); 
         return result; 
 }
@@ -85,7 +85,7 @@ void CXMLElement::set_attribute(const char *name, const std::string& value)
 	}else{
 		xmlChar *path = xmlGetNodePath(impl->element); 
 		cvdebug() << "CXMLElement: trying to add attribute " << name << " a second time to '"
-			  << path << "'\n";
+                  << path << "'\n";
 		xmlFree(path);
 		xmlFree(attr);
 	}
@@ -142,7 +142,7 @@ string CXMLDocument::write_to_string_formatted() const
                                1);
 
         stringstream out_string;
-	out_string << doc_txt_ptr; 
+        out_string << doc_txt_ptr;
         free(doc_txt_ptr);
         return out_string.str(); 
 }
diff --git a/mia/core/xmlinterface.hh b/mia/core/xmlinterface.hh
index 17a4ba1..96ed2b8 100644
--- a/mia/core/xmlinterface.hh
+++ b/mia/core/xmlinterface.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/autotest.hh b/mia/internal/autotest.hh
index 8a90a17..7cdb7a7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/main.hh b/mia/internal/main.hh
index 6f2cab8..7385e55 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 39c0e56..be819de 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 32e6ab2..531a928 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/mesh.hh
index 55df13a..4490b16 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 f7d72be..adc4fae 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 32adee6..828d631 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/mesh/filter.hh
index c12d537..308104b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/addscale.cc b/mia/mesh/filter/addscale.cc
index cacd415..fec461d 100644
--- a/mia/mesh/filter/addscale.cc
+++ b/mia/mesh/filter/addscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/addscale.hh b/mia/mesh/filter/addscale.hh
index 39237d6..c3bb862 100644
--- a/mia/mesh/filter/addscale.hh
+++ b/mia/mesh/filter/addscale.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/deltrianglesbynormal.cc b/mia/mesh/filter/deltrianglesbynormal.cc
index 791f67a..59d5720 100644
--- a/mia/mesh/filter/deltrianglesbynormal.cc
+++ b/mia/mesh/filter/deltrianglesbynormal.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
 #include <mia/mesh/filter/deltrianglesbynormal.hh>
 #include <mia/mesh/triangle_neighbourhood.hh>
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
 #include <mia/core/threadedmsg.hh>
 
 
@@ -33,9 +32,6 @@
 NS_BEGIN(mia_meshfilter_deltribynormal) 
 using namespace mia; 
 using namespace std; 
-using tbb::blocked_range; 
-using tbb::parallel_for; 
-
 
 CDeleteTriangleByNormalMeshFilter::CDeleteTriangleByNormalMeshFilter(const C3DFVector& point_direction, float angle):
 	m_point_direction(point_direction), 
@@ -56,7 +52,7 @@ PTriangleMesh CDeleteTriangleByNormalMeshFilter::do_filter(const CTriangleMesh&
 	// evaluate the triangle normals, 
 	vector<bool>  keep(mesh.triangle_size(), false); 
 
-	auto run_triangles = [this, &mesh, &keep](const blocked_range<unsigned>& range) {
+	auto run_triangles = [this, &mesh, &keep](const C1DParallelRange& range) {
 		CThreadMsgStream thread_stream;		
 		for (auto i = range.begin(); i != range.end(); ++i) {
 			auto& t = mesh.triangle_at(i); 
@@ -83,7 +79,7 @@ PTriangleMesh CDeleteTriangleByNormalMeshFilter::do_filter(const CTriangleMesh&
 	}; 
 	
 	// estimate which triangles to keep 
-	parallel_for(blocked_range<unsigned>(0, mesh.triangle_size()), run_triangles); 
+	pfor(C1DParallelRange(0, mesh.triangle_size()), run_triangles); 
 
 	// iteratively re-add all triangles that have at least two neighbours within the keep 
 	CTrianglesWithAdjacentList trineigh(mesh); 
diff --git a/mia/mesh/filter/deltrianglesbynormal.hh b/mia/mesh/filter/deltrianglesbynormal.hh
index 6a7e71c..c72f568 100644
--- a/mia/mesh/filter/deltrianglesbynormal.hh
+++ b/mia/mesh/filter/deltrianglesbynormal.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 4efac0d..a025a09 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d4c0c73..9d8f351 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/selectbig.cc b/mia/mesh/filter/selectbig.cc
index 7943500..2ef474b 100644
--- a/mia/mesh/filter/selectbig.cc
+++ b/mia/mesh/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/selectbig.hh b/mia/mesh/filter/selectbig.hh
index b281908..fc6d58d 100644
--- a/mia/mesh/filter/selectbig.hh
+++ b/mia/mesh/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_addscale.cc b/mia/mesh/filter/test_addscale.cc
index e2baf36..2818273 100644
--- a/mia/mesh/filter/test_addscale.cc
+++ b/mia/mesh/filter/test_addscale.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_deltrianglesbynormal.cc b/mia/mesh/filter/test_deltrianglesbynormal.cc
index 2d5bec2..dfc01f2 100644
--- a/mia/mesh/filter/test_deltrianglesbynormal.cc
+++ b/mia/mesh/filter/test_deltrianglesbynormal.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0bb4557..01f6046 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_selectbig.cc b/mia/mesh/filter/test_selectbig.cc
index 74461a5..ca33f1c 100644
--- a/mia/mesh/filter/test_selectbig.cc
+++ b/mia/mesh/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 96868ae..0ecdf36 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 a797434..66287ca 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 c1f3872..c7bea16 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 da7b8f7..c1105f2 100644
--- a/mia/mesh/io/CMakeLists.txt
+++ b/mia/mesh/io/CMakeLists.txt
@@ -28,3 +28,5 @@ PLUGINGROUP_WITH_PREFIX2(
   "${iomesh}" 
   "${MIAMESHLIBS}" 
 )
+
+NEW_TEST(meshio miamesh)
diff --git a/mia/mesh/io/gts.cc b/mia/mesh/io/gts.cc
index f1591e4..2a0e037 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 645985a..471479f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +35,8 @@
 #include <mia/mesh/triangularMesh.hh>
 #include <mia/mesh/triangulate.hh>
 
+// documentation of the format:
+// http://www.geomview.org/docs/html/OFF.html
 
 NS_BEGIN(off_mesh_io)
 
@@ -56,35 +58,18 @@ private:
 	virtual bool do_save(string const &  filename, const CTriangleMesh& data)const;
 	virtual const string  do_get_descr()const;
 
-#ifndef USE_FILEIO
-	PTriangleMesh do_load_it(istream& inp)const;
-	bool do_save(ostream& os, const CTriangleMesh& data) const;
-	bool load_vertices(istream &inp,
-			   CTriangleMesh::PVertexfield vertices,
-			   CTriangleMesh::PNormalfield normals,
-			   CTriangleMesh::PSolorfield colors,
-			   CTriangleMesh::PScalefield scale,
-			   bool has_texturcoord,
-			   unsigned int nvertices)const;
-
-	bool load_triangles(istream& inp, vector<CTriangleMesh::triangle_type>& tri,
-			    unsigned int nfaces, unsigned int nvertice,
-			    const CPolyTriangulator& triangulator)const;
-#else
 	PTriangleMesh do_load_it(CInputFile& inp)const;
 
 	bool load_vertices(CInputFile &inp,
 			   CTriangleMesh::PVertexfield vertices,
 			   CTriangleMesh::PNormalfield normals,
 			   CTriangleMesh::PColorfield colors,
-			   CTriangleMesh::PScalefield scale,
-			   bool has_texturcoord,
+			   bool has_texture_coordinates, 
 			   unsigned int nvertices)const;
 
 	bool load_triangles(CInputFile& inp, vector<CTriangleMesh::triangle_type>& tri,
 			    unsigned int nfaces, unsigned int nvertice,
 			    const CPolyTriangulator& triangulator)const;
-#endif
 	bool read_polygon(istream& inp, vector<CTriangleMesh::triangle_type>& tri,
 			  unsigned int nvertices,const CPolyTriangulator& triangulator)const;
 
@@ -107,25 +92,19 @@ COffMeshIO::COffMeshIO():CMeshIOPlugin(format)
 
 const string  COffMeshIO::do_get_descr()const
 {
-	return string("plugin to load/store some Geomview OFF Files");
+	return string("plugin to load/store some Geomview OFF files. "
+		      "Supported is only the ASCII format 3D meshes with normales and per-vertex RGB colors. "
+		      "Alpha values and texture coordinates, as well as per face properties are ignored. "
+		      "Polygons are read and triangulated. "
+		);
 }
 
 PTriangleMesh COffMeshIO::do_load(string const &  filename)const
 {
-#ifdef  USE_FILEIO
 	CInputFile f(filename);
 	if (!f)
 		return PTriangleMesh();
 	return do_load_it(f);
-#else
-	if ( filename == "-" ) {
-		return do_load_it(cin);
-	}else{
-		ifstream inp(filename);
-		return inp.good() ? do_load_it(inp) : PTriangleMesh();
-	}
-#endif
-
 }
 
 void COffMeshIO::skip_to_newline(istream& inp)const
@@ -136,63 +115,6 @@ void COffMeshIO::skip_to_newline(istream& inp)const
 	}while (c != '\n' && inp.good());
 }
 
-#ifndef USE_FILEIO
-
-bool COffMeshIO::load_vertices(istream &inp,
-				  CTriangleMesh::PVertexfield vertices,
-				  CTriangleMesh::PNormalfield normals,
-				  CTriangleMesh::PColorfield colors,
-				  CTriangleMesh::PScalefield scale,
-				  bool has_texturcoord,
-				  unsigned int nvertices)const
-{
-	unsigned int i = 0;
-
-	float sink;
-
-	CTriangleMesh::vertex_iterator v = vertices->begin();
-
-
-	if (normals && colors &&  scale) {
-		CTriangleMesh::normal_iterator n = normals->begin();
-		CTriangleMesh::color_iterator  c = colors->begin();
-		CTriangleMesh::scale_iterator  s = scale->begin();
-
-		if (has_texturcoord) {
-			while (i < nvertices  && inp.good()) {
-
-				inp >> v->x >> v->y >> v->z;
-				inp >> n->x >> n->y >> n->z;
-				inp >> c->x >> c->y >> c->z;
-				inp >> *s;
-				inp >> sink >> sink;
-				++v; ++n; ++s; ++c; ++i;
-			}
-		}else
-			while (i < nvertices  && inp.good()) {
-				inp >> v->x >> v->y >> v->z;
-				inp >> n->x >> n->y >> n->z;
-				inp >> c->x >> c->y >> c->z;
-				inp >> *s;
-				++v; ++n; ++s; ++c; ++i;
-			}
-
-	}else if (normals) {
-		CTriangleMesh::normal_iterator n = normals->begin();
-		while (i < nvertices  && inp.good()) {
-			inp >> v->x >> v->y >> v->z;
-			inp >> n->x >> n->y >> n->z;
-			++v; ++n; ++i;
-		}
-	}else
-		while (i < nvertices  && inp.good()) {
-			inp >> v->x >> v->y >> v->z;
-			++v; ++i;
-		}
-	return i == nvertices;
-}
-#else
-
 static bool read_line(char *buf, size_t size, FILE *f)
 {
 	char *success;
@@ -204,72 +126,86 @@ static bool read_line(char *buf, size_t size, FILE *f)
 }
 
 bool COffMeshIO::load_vertices(CInputFile& inf,
-				  CTriangleMesh::PVertexfield vertices,
-				  CTriangleMesh::PNormalfield normals,
-				  CTriangleMesh::PColorfield colors,
-				  CTriangleMesh::PScalefield scale,
-				  bool has_texturcoord,
-				  unsigned int nvertices)const
+			       CTriangleMesh::PVertexfield vertices,
+			       CTriangleMesh::PNormalfield normals,
+			       CTriangleMesh::PColorfield colors,
+			       bool has_texture_coordinates, 
+			       unsigned int nvertices)const
 {
 	unsigned int i = 0;
 
 	CTriangleMesh::vertex_iterator v = vertices->begin();
 
+	CTriangleMesh::normal_iterator n;
+	CTriangleMesh::color_iterator  c; 
+
+	int expect_count = has_texture_coordinates ? 5 : 2; 
+	int c_offest = 0;
+	if (normals) {
+		n = normals->begin();
+		c_offest += 3;
+		expect_count += 3; 
+	}
+	
+	if (colors) {
+		c = colors->begin();
+		expect_count += 3; 
+	}
+
 	char buf[2048];
 
 	bool success = read_line(buf, 2048, inf);
 	if (!success)
 		return false;
 
+	int first_count = 0; 
 
-	if (normals && colors &&  scale) {
-		CTriangleMesh::normal_iterator n = normals->begin();
-		CTriangleMesh::color_iterator  c = colors->begin();
-		CTriangleMesh::scale_iterator  s = scale->begin();
-
-		if (has_texturcoord) {
-			do {
-				float sink; // texture coordinates are currently rejected
-				sscanf(buf, "%f %f %f %f %f %f %f %f %f %f %f %f",
-				       &v->x, &v->y, &v->z,
-				       &n->x, &n->y, &n->z,
-				       &c->x, &c->y, &c->z,
-				       &*s,
-				       &sink,
-				       &sink);
-				++v; ++n; ++s; ++c; ++i;
-			}while (i < nvertices && read_line(buf, 2048, inf));
-
-		}else
-			do  {
-				sscanf(buf, "%f %f %f %f %f %f %f %f %f %f",
-				       &v->x, &v->y, &v->z,
-				       &n->x, &n->y, &n->z,
-				       &c->x, &c->y, &c->z,
-				       &*s);
-				++v; ++n; ++s; ++c; ++i;
-			}  while (i < nvertices && read_line(buf, 2048, inf));
-	}else if (normals) {
-		CTriangleMesh::normal_iterator n = normals->begin();
-		do  {
-			sscanf(buf, "%f %f %f %f %f %f",
-			       &v->x, &v->y, &v->z,
-			       &n->x, &n->y, &n->z);
-			++v; ++n; ++i;
-		}while (i < nvertices && read_line(buf, 2048, inf));
-	}else
-		do  {
-			istringstream line(buf); line >> v->x >> v->y >>v->z;
-
-			++v; ++i;
-
-		}while (i < nvertices && read_line(buf, 2048, inf));
-	return i == nvertices;
-}
-#endif
-
+	do {
+		float x[9];
+		float *xc = &x[c_offest];
+		
+		int count = sscanf(buf, "%f %f %f %f %f %f %f %f %f %f %f %f",
+				   &v->x, &v->y, &v->z,
+				   &x[0], &x[1], &x[2],
+				   &x[3], &x[4], &x[5], &x[6],
+				   &x[7], &x[8]);
+
+		if (count < expect_count) {
+			throw create_exception<runtime_error>("OFF: unsupported file type. "
+							      "Most likely the file type uses color map indices."); 
+		}
 
+		if (first_count > 0) {
+			if (first_count != count) {
+				throw create_exception<runtime_error>("OFF: inconsistent vertex definitions"); 
+			}
+		}else{
+			first_count = count; 
+		}
+		
+		if (normals) {
+			n->x = x[0];
+			n->y = x[1];
+			n->z = x[2];
+			++n;
+			count -= 6; 
+		}
+		
+		if (colors) {
+			if (count < 3)
+				throw create_exception<invalid_argument>("OFF: color indices not supported"); 
+			c->x = xc[0] < 1.0 ? xc[0] : xc[0]/ 255.0f;
+			c->y = xc[1] < 1.0 ? xc[1] : xc[1]/ 255.0f;
+			c->z = xc[2] < 1.0 ? xc[2] : xc[2]/ 255.0f;
+			++c; 
+		}
+		
+		++v;
+		++i; 
+	} while (i < nvertices && read_line(buf, 2048, inf));
 
+	return i == nvertices;
+}
 
 bool COffMeshIO::read_polygon(istream& inp, vector<CTriangleMesh::triangle_type>& tri,
 			      unsigned int nvertices,
@@ -290,8 +226,8 @@ bool COffMeshIO::read_polygon(istream& inp, vector<CTriangleMesh::triangle_type>
 
 	}else {
 		vector<unsigned int> poly(nvert);
-
-		for (int k = 0; k < nvert; ++k) {
+		
+		for (unsigned  k = 0; k < poly.size(); ++k) {
 			inp >> ws >> poly[k];
 			if (poly[k] >= nvertices) {
 				cverr() << "COffMeshIO::load_triangles: index out of range\n";
@@ -304,8 +240,6 @@ bool COffMeshIO::read_polygon(istream& inp, vector<CTriangleMesh::triangle_type>
 	return true;
 }
 
-
-#ifdef USE_FILEIO
 bool COffMeshIO::load_triangles(CInputFile& inp, vector<CTriangleMesh::triangle_type>& tri,
 				unsigned int nfaces, unsigned int nvertices,
 				const CPolyTriangulator& triangulator)const
@@ -334,39 +268,6 @@ bool COffMeshIO::load_triangles(CInputFile& inp, vector<CTriangleMesh::triangle_
 	return true;
 }
 
-#else
-
-bool COffMeshIO::load_triangles(istream& inp, vector<CTriangleMesh::triangle_type>& tri,
-				unsigned int nfaces, unsigned int nvertices,
-				const CPolyTriangulator& triangulator)const
-{
-	inp >> noskipws;
-
-	int show_thresh_start = nfaces / 50;
-	int show_thresh = show_thresh_start;
-	int nfaces_start = nfaces;
-
-	while (nfaces-- && inp.good()){
-
-		if (!read_polygon(inp, tri, nvertices, triangulator))
-			return false;
-
-		show_thresh--;
-		if (!show_thresh) {
-			show_thresh = show_thresh_start;
-
-			if (m_cb)
-				m_cb->show_progress(nfaces_start - nfaces, nfaces_start);
-		}
-
-		skip_to_newline(inp);
-	}
-	++nfaces;
-	inp >> skipws;
-	return nfaces == 0;
-}
-
-#endif
 
 class CTriangleChecker {
 public:
@@ -440,8 +341,6 @@ void CTriangleChecker::evaluate()
 }
 
 
-#ifdef USE_FILEIO
-
 enum EVertexFlags {vt_texture = 1,
 		   vt_color   = 2,
 		   vt_normal  = 4,
@@ -513,17 +412,20 @@ PTriangleMesh COffMeshIO::do_load_it(CInputFile& inp)const
 	}
 
 	if (vertex_size != 3) {
-		cverr() << "currently only 3D vertexes are supported\n";
-		return PTriangleMesh();
+		throw create_exception<invalid_argument>("OFF: currently only 3D vertexes are supported, ",
+							 "file contains ", vertex_size, "D vertices");
 	}
 
 	int n_vertices = 0;
 	int n_faces = 0;
 	int n_edges = 0;
 
-	if (fscanf(inp, "%d %d %d", &n_vertices, &n_faces, &n_edges)!= 3) {
-		cverr() << "OFF: parse error\n";
-		return PTriangleMesh();
+	char buffer[2049];
+	if (!read_line(buffer, 2048, inp))
+		throw create_exception<runtime_error>("OFF: Unable to read from input file.");
+	
+	if (sscanf(buffer, "%d %d %d", &n_vertices, &n_faces, &n_edges)!= 3) {
+		throw create_exception<runtime_error>("OFF: parse error reading from '", buffer, "'");
 	}
 
 	cvdebug() << "found file with " <<n_vertices << " vertices, and " <<  n_faces << " faces\n";
@@ -531,35 +433,27 @@ PTriangleMesh COffMeshIO::do_load_it(CInputFile& inp)const
 	CTriangleMesh::PVertexfield vertices(new CTriangleMesh::CVertexfield(n_vertices));
 	CTriangleMesh::PNormalfield normals;
 	CTriangleMesh::PColorfield  colors;
-	CTriangleMesh::PScalefield  scale;
-
-
 
 	if (flags & vt_color) {
 		colors.reset(new CTriangleMesh::CColorfield(n_vertices));
-		scale.reset(new CTriangleMesh::CScalefield(n_vertices));
 	}
 
 	if (flags & vt_normal) {
 		normals.reset(new CTriangleMesh::CNormalfield(n_vertices));
 	}
 
-	if ( !load_vertices(inp, vertices, normals, colors, scale, flags & vt_texture, n_vertices)) {
-		return PTriangleMesh();
+	if ( !load_vertices(inp, vertices, normals, colors, flags & vt_texture, n_vertices)) {
+		throw create_exception<runtime_error>("OFF: Error reading vertices");
 	}
 
-
-	// now read the triangles
 	vector<CTriangleMesh::triangle_type> tri;
 
 	CPolyTriangulator triangulator(*vertices);
 
 	if (!load_triangles(inp, tri, n_faces, n_vertices, triangulator)) {
-		cverr() << "error reading faces\n";
-		return PTriangleMesh();
+		throw create_exception<runtime_error>("OFF: Error reading triangles");
 	}
 
-	//#ifndef ENABLE_DEBUG
 	CTriangleChecker tricheck;
 	for(vector<CTriangleMesh::triangle_type>::const_iterator i = tri.begin();
 	    i != tri.end(); ++i)
@@ -568,160 +462,12 @@ PTriangleMesh COffMeshIO::do_load_it(CInputFile& inp)const
 
 	cvdebug() << "tricheck.print();\n";
 	tricheck.print();
-//#endif
-
 
 	CTriangleMesh::PTrianglefield triangles(new CTriangleMesh::CTrianglefield(tri.size()));
 	copy(tri.begin(), tri.end(), triangles->begin());
-	return PTriangleMesh(new CTriangleMesh(triangles, vertices, normals, colors, scale));
-
-}
-
-#else
-
-//#ifndef ENABLE_DEBUG
-
-
-PTriangleMesh COffMeshIO::do_load_it(istream& inp)const
-{
-	string head;
-	inp >> head;
-	const char *chead = head.c_str();
-
-	bool has_texturcoord = !strncmp(chead, "ST", 2);
-	if (has_texturcoord) chead += 2;
-
-	bool has_color = *chead == 'C';
-	if (has_color) {
-		++chead;
-		cvdebug() << "OFF: found color" << endl;
-	}
-	bool has_normal = *chead == 'N';
-	if (has_normal) {
-		++chead;
-		cvdebug() << "OFF: found normal" << endl;
-	}
-
-
-	if (*chead == '4') {
-		cverr() << "COffMeshIO::load: only 3-component vertices supported" << endl;
-		return PTriangleMesh();
-	}else if (*chead == 'n') {
-		cverr() << "COffMeshIO::load: only 3-component vertices supported" << endl;
-		return PTriangleMesh();
-	}
-
-	if (strncmp(chead, "OFF", 3)) {
-		cverr() << "COffMeshIO::load: OFF Header malformed" << endl;
-		// technically the missing header is allowed, but I won't support it now
-		return PTriangleMesh();
-	}
-
-	cvdebug() << "OFF: found complete header" << endl;
-
-	unsigned int nvertices;
-	unsigned int nfaces;
-	unsigned int nedges;
-
-	inp >> nvertices >> nfaces >> nedges;
-
-	cvdebug() << "read " << nvertices << " vertices and " << nfaces << " faces " << endl;
-
-	CTriangleMesh::PVertexfield vertices(new CTriangleMesh::vertexfield_type(nvertices));
-	CTriangleMesh::PNormalfield normals;
-	CTriangleMesh::PColorfield colors;
-	CTriangleMesh::PScalefield scale;
-
-	if (has_normal) normals.reset(new CTriangleMesh::normalfield_type(nvertices));
-	if (has_color)  {
-		colors.reset(new CTriangleMesh::colorfield_type(nvertices));
-		scale.reset(new CTriangleMesh::scalefield_type(nvertices));
-	}
-
-	if ( !load_vertices(inp, vertices, normals, colors, scale, has_texturcoord, nvertices)) {
-		return PTriangleMesh();
-	}
-
-	vector<C3DBounds> tri;
-	if (!load_triangles(inp, tri, nfaces, nvertices)) {
-		cverr() << "reading faces failed" << endl;
-		return PTriangleMesh();
-	}
-
-//#ifndef ENABLE_DEBUG
-	CTriangleChecker tricheck;
-	tricheck(tri);
-	cvdebug() << "tricheck.print();" << endl;
-	tricheck.print();
-//#endif
-
-	CTriangleMesh::CTrianglefield triangles(new CTriangleMesh::trianglefield_type(tri.size()));
-	copy(tri.begin(), tri.end(), triangles->begin());
-	return PTriangleMesh(new CTriangleMesh(triangles, vertices, normals, colors, scale));
-}
-#endif
-
+	return PTriangleMesh(new CTriangleMesh(triangles, vertices, normals, colors, nullptr));
 
-#ifndef USE_FILEIO
-bool COffMeshIO::do_save(ostream& os, const CTriangleMesh& data) const
-{
-
-	int flags = data.get_available_data();
-
-	// write header
-	if ( (flags & CTriangleMesh::ed_scale)  || (flags & CTriangleMesh::ed_color)) os << 'C';
-	if (  flags & CTriangleMesh::ed_normal )                       os << 'N';
-	os << "OFF" << endl;
-
-	// write number of whatever
-	os << data.vertices_size() << " " << data.triangle_size() << " 0" << endl;
-
-	for (size_t i = 0; i < data.vertices_size() || os.bad(); ++i) {
-		const CTriangleMesh::vertex_type& v = data.vertex_at(i);
-		os << v.x << " " << v.y << " " << v.z;
-
-		if (flags & CTriangleMesh::ed_normal) {
-			const CTriangleMesh::normal_type& n = data.normal_at(i);
-			os << " " << n.x << " " << n.y << " " << n.z;
-		}
-		if (flags & CTriangleMesh::ed_color && flags & CTriangleMesh::ed_scale) {
-			const CTriangleMesh::color_type& c = data.color_at(i);
-			os << " " << c.x << " " << c.y << " " << c.z;
-			os << " " << data.scale_at(i);
-		}else if (flags & CTriangleMesh::ed_color && !(flags & CTriangleMesh::ed_scale)) {
-			const CTriangleMesh::color_type& c = data.color_at(i);
-			os << " " << c.x << " " << c.y << " " << c.z;
-			os << " 1.0";
-		}else if ( !(flags & CTriangleMesh::ed_color) && flags & CTriangleMesh::ed_scale) {
-			os << " 1.0 1.0 1.0 " << data.scale_at(i);
-		}
-		os << endl;
-	}
-
-	CTriangleMesh::const_triangle_iterator tb = data.triangles_begin();
-	CTriangleMesh::const_triangle_iterator te = data.triangles_end();
-
-	while (tb != te && os.good()) {
-		os << "3 " << tb->x << " " << tb->y << " " << tb->z << endl;
-		++tb;
-	}
-	return os.good();
-}
-
-bool COffMeshIO::do_save(const CTriangleMesh& data, string const &  filename)const
-{
-	m_cb = cb;
-
-	if (filename == "-")
-		return do_save(cout, data);
-	else {
-		ofstream os(filename);
-		if (os.bad())
-			return false;
-		return do_save(os, data);
-	}
 }
-#else
 
 bool COffMeshIO::do_save(string const &  filename, const CTriangleMesh& data)const
 {
@@ -745,6 +491,11 @@ bool COffMeshIO::do_save(string const &  filename, const CTriangleMesh& data)con
 
 	int written = 1;
 
+	if (flags & CTriangleMesh::ed_scale) {
+		cvwarn() << "OFF-save: Mesh has scale values, but they are "
+			 << "not supported by the OFF file format and will be lost\n"; 
+	}
+
 	for (size_t i = 0; i < data.vertices_size() && written > 0; ++i) {
 		const CTriangleMesh::vertex_type& v = data.vertex_at(i);
 		fprintf(f, "%f %f %f",v.x,v.y, v.z);
@@ -753,14 +504,9 @@ bool COffMeshIO::do_save(string const &  filename, const CTriangleMesh& data)con
 			const CTriangleMesh::normal_type& n = data.normal_at(i);
 			written += fprintf(f, " %f %f %f",n.x,n.y, n.z);
 		}
-		if (flags & CTriangleMesh::ed_color && flags & CTriangleMesh::ed_scale) {
+		if (flags & CTriangleMesh::ed_color) {
 			const CTriangleMesh::color_type& c = data.color_at(i);
-			written += fprintf(f, " %f %f %f %f",c.x,c.y, c.z, data.scale_at(i));
-		}else if (flags & CTriangleMesh::ed_color && !(flags & CTriangleMesh::ed_scale)) {
-			const CTriangleMesh::color_type& c = data.color_at(i);
-			written += fprintf(f, " %f %f %f 1.0",c.x,c.y, c.z);
-		}else if ( !(flags & CTriangleMesh::ed_color) && flags & CTriangleMesh::ed_scale) {
-			written += fprintf(f, "1.0 1.0 1.0");
+			written += fprintf(f, " %f %f %f",c.x,c.y, c.z);
 		}
 		written += fprintf(f,"\n");
 	}
@@ -774,7 +520,6 @@ bool COffMeshIO::do_save(string const &  filename, const CTriangleMesh& data)con
 	}
 	return written > 0;
 }
-#endif
 
 }
 
diff --git a/mia/mesh/io/ply.cc b/mia/mesh/io/ply.cc
index 3b8f552..1eaba82 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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/core/filter.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/mesh/triangularMesh.hh>
+#include <mia/mesh/triangulate.hh>
 
 NS_BEGIN(ply_mesh_io)
 
@@ -69,81 +70,230 @@ const string  TPlyMeshIO::do_get_descr()const
 	return string("Ply triangle mesh input/output support");
 }
 
-const string kennung("ply");
-const string kelement("element");
-const string kvertex("vertex");
-const string kface("face");
-const string end_header("end_header");
+// read the next line and skip comments
+// 
+static void get_line(char *buffer, string const &  filename, FILE *file)
+{
+	do {
+		if (!fgets(buffer, 2048, file)) {
+			throw create_exception<runtime_error>("Ply: Bougus file '", filename, "'");		
+		}
+	} while (!strncmp(buffer, "comment ", 8));
+	cvdebug() << "Read line '"  << buffer << "'\n"; 
+	
+}
 
 
-class FReadElement {
-	FILE *f;
-public:
-	FReadElement(FILE *_f):f(_f){};
-
-	template <typename Element>
-	void operator()(Element& elm) {
-		char buffer[2048];
-		if (!fgets(buffer, 2048, f))
-			throw runtime_error("Read PLY: unable to read sufficient data");
-		istringstream s(buffer);
-		s >> elm.x >> elm.y >> elm.z;
+static vector<pair<string, vector<string>> > get_properties(char *buffer, string const &filename, FILE *file)
+{
+	vector<pair<string, vector<string>>> result;
+	while (!strncmp(buffer, "property ", 9)) {
+		istringstream is(buffer);
+		string key, name, type;  
+		is >> key >> type;
+		if (type == "list") {
+			vector<string> s;
+			while (is.eof()) {
+				is >> name;
+				if (!name.empty()) 
+					s.push_back(name); 
+			}
+		}else{ 
+			is >> name;
+			result.push_back(make_pair(type, vector<string>{name}));
+		}
+		get_line(buffer, filename, file); 
 	}
-};
+	return result; 
+}
 
+map<string, int> key_flag_mapping = {
+	{"x", 1},
+	{"y", 2},
+	{"z", 4},
+	{"nx", 8},
+	{"ny",16},
+	{"nz",32},
+	{"red", 64},
+	{"green",128},
+	{"blue",256},
+	{"scale",512}}; 
+
+void read_vertex_data(CTriangleMesh::CVertexfield& v,
+		      CTriangleMesh::PNormalfield n, 
+		      CTriangleMesh::PColorfield c,
+		      CTriangleMesh::PScalefield s,
+		      char *buffer, const string&  filename, FILE *file)
+{
+	for (unsigned i = 0; i < v.size(); ++i) {
+		get_line(buffer, filename, file);
+		
+		istringstream buf(buffer);
+
+		buf >> v[i].x >> v[i].y >> v[i].z;
+		if (n) {
+			buf >> (*n)[i].x >> (*n)[i].y >> (*n)[i].z;
+		}
+		if (c) {
+			buf >> (*c)[i].x >> (*c)[i].y >> (*c)[i].z;
+		}
+		if (s) {
+			buf >> (*s)[i];
+		}
+	}
+}
 
-class FReadFloatElement {
-	FILE *f;
-public:
-	FReadFloatElement(FILE *_f):f(_f){};
-	void operator()(CTriangleMesh::CVertexfield::value_type& elm) {
-		if (fscanf(f,"%f %f %f",&elm.x, &elm.y, &elm.z) != 3) {
-			throw runtime_error("Read PLY: unable to read sufficient data");
+void read_faces(CTriangleMesh::CTrianglefield& triangles, unsigned n_faces, 
+		const CTriangleMesh::CVertexfield& vertices,
+		char *buffer, const string&  filename, FILE *file)
+{
+	unsigned count;
+	vector<unsigned> v(3);
+	typedef TPolyTriangulator<CTriangleMesh::CVertexfield, vector<unsigned int> >  CPolyTriangulator;
+	
+	CPolyTriangulator triangulator(vertices); 
+	
+	for (unsigned i = 0; i < n_faces; ++i) {
+		get_line(buffer, filename, file);
+
+		istringstream buf(buffer);
+		buf >> count;
+		if (count > v.max_size()) {
+			throw create_exception<runtime_error>("PLY: ", filename, ": ", count, " vertices specified ",
+							      "but implementation only supports up to ", v.max_size()); 
+		}
+		
+		v.resize(count);
+		for (unsigned i = 0; i < count; ++i) {
+			buf >> v[i];
+		}
+		if (count < 3) {
+			cvwarn() << "PLY_Face with less than 3 vertices in '" << filename << "' ignoring";
+		}
+		if (count > 3) {
+			vector<CTriangleMesh::triangle_type> tri; 
+			triangulator.triangulate(tri, v);
+			for (auto t: tri)
+				triangles.push_back(t); 
+		}else{
+			cvdebug() << "Read triangle <" << v << "> from buffer '" << buffer << "'\n"; 
+			triangles.push_back(CTriangleMesh::triangle_type(v[0], v[1], v[2])); 
 		}
 	}
-};
+}
 
+pair<int, map<string, int>> get_data_flags(const vector<pair<string, vector<string>> >& vertex_properties,
+					   const string& filename)
+{
+	int available_flags = 0;
+	
+	map<string, int> mapping; 
+	for (unsigned i = 0; i < vertex_properties.size(); ++i) {
+		mapping[vertex_properties[i].first] = i;
+
+		auto key_flag = key_flag_mapping.find(vertex_properties[i].second[0]); 
+		if (key_flag != key_flag_mapping.end()) {
+			available_flags |= key_flag->second;
+			cvdebug() << "available_flags= " << available_flags << " with key " << vertex_properties[i].second[0] << "\n"; 
+		} else
+			cvwarn() << "PLY: unsupported property '" << vertex_properties[i].second[0]
+				 << "' found in '" << filename << ", ignoring\n";
+	}
+
+	int type_flags = 0; 
+	if ((available_flags  & 7) == 7)
+		type_flags |= CTriangleMesh::ed_vertex;
+	
+	if ((available_flags  & 0x38) == 0x38)
+		type_flags |= CTriangleMesh::ed_normal; 
+
+	if ((available_flags  & 0x1C0) == 0x1C0)
+		type_flags |= CTriangleMesh::ed_color;
+
+	if ((available_flags  & 0x200) == 0x200)
+		type_flags |= CTriangleMesh::ed_scale;
+	
+	return make_pair(type_flags, mapping); 
+	
+}
 
 PTriangleMesh TPlyMeshIO::do_load(string const &  filename) const
 {
-	char buffer[1024];
+	cvdebug() << "Load as PLY?\n"; 
+	char buffer[2048];
 	int n_vertices = 0;
-	int n_face = 0;
+	unsigned n_face = 0;
 
 	CInputFile f(filename);
 	if (!f)
 		return PTriangleMesh();
 
-	if ( (!fgets(buffer, 1024, f)) || strncmp(buffer,"ply",3))
+	if ( (!fgets(buffer, 1024, f)) || strncmp(buffer,"ply",3)) {
+		cvdebug() << "Not a PLY file\n"; 
 		return PTriangleMesh();
+	}
 
-	if ( (!fgets(buffer, 1024, f)) || (sscanf(buffer,"element vertex %d",&n_vertices)!= 1))
-		return PTriangleMesh();
+	if ( (!fgets(buffer, 1024, f)) || strncmp(buffer,"format ",7)) {
+		throw create_exception<runtime_error>("Ply: Format specifier missing '", filename, "'");
+	}
 
-	if ( (!fgets(buffer, 1024, f)) || (sscanf(buffer,"element face %d",&n_face)!= 1))
-		return PTriangleMesh();
+	// now we must check the type of file, only support ascii though
+	
+	get_line(buffer, filename, f);
+	
+	if (sscanf(buffer,"element vertex %d",&n_vertices)!= 1)
+		throw create_exception<runtime_error>("Ply: Bougus file '", filename,
+						      "', can't parse vertex count from '",buffer,"'.");
+	
+	get_line(buffer, filename, f);
 
-	if ( (!fgets(buffer, 1024, f)) || strncmp(buffer,"end_header",10))
-		return PTriangleMesh();
+	auto vertex_properties = get_properties(buffer, filename, f); 
 
+	if (sscanf(buffer,"element face %d",&n_face)!= 1)
+		throw create_exception<runtime_error>("Ply: Unsupported file '", filename, "', can't parse face count from '",
+						      buffer, "'");
 
-	CTriangleMesh::PVertexfield vertices(new  CTriangleMesh::CVertexfield(n_vertices));
-	if (!vertices)
-		return PTriangleMesh();
+	get_line(buffer, filename, f);
+	auto face_properties = get_properties(buffer, filename, f); 
 
-	CTriangleMesh::PTrianglefield triangles(new  CTriangleMesh::CTrianglefield(n_face));
+	if (strncmp(buffer,"end_header",10))
+		throw create_exception<runtime_error>("Ply: Header end marker not found in '", filename, "'.");
 
 
-	try {
-		for_each(vertices->begin(), vertices->end(),FReadElement(f));
-		for_each(triangles->begin(), triangles->end(),FReadElement(f));
+	CTriangleMesh::PVertexfield vertices(new CTriangleMesh::CVertexfield(n_vertices));
+	CTriangleMesh::PNormalfield normals;
+	CTriangleMesh::PColorfield colors;
+	CTriangleMesh::PScalefield scales; 
+
+	auto flags_and_map = get_data_flags(vertex_properties, filename);
+	auto flags = flags_and_map.first; 
+	
+	if (!(flags & CTriangleMesh::ed_vertex))
+		throw create_exception<runtime_error>("Ply: No supported vertex properties found in '", filename, "'.");
+
+	if (flags & CTriangleMesh::ed_normal) {
+		cvdebug() << "PLY: have normals\n"; 
+		normals.reset(new CTriangleMesh::CNormalfield(n_vertices));
 	}
-	catch (exception& e) {
-		cverr() << e.what() << "\n";
-        return PTriangleMesh();
+	if (flags & CTriangleMesh::ed_color)
+		colors.reset(new CTriangleMesh::CColorfield(n_vertices));
+	if (flags & CTriangleMesh::ed_scale)
+		scales.reset(new CTriangleMesh::CScalefield(n_vertices));
+
+	read_vertex_data(*vertices, normals, colors, scales, buffer, filename, f);
+	
+	CTriangleMesh::PTrianglefield triangles(new  CTriangleMesh::CTrianglefield);
+
+	if (n_face > triangles->max_size()) {
+		throw create_exception<runtime_error>("PLY: ", filename, ": ", n_face, " triangles specified ",
+						      "but implementation only supports up to ", triangles->max_size()); 
 	}
+		
+	triangles->reserve(n_face); 
+
+	read_faces(*triangles, n_face, *vertices, buffer, filename, f);
 
-	return PTriangleMesh(new CTriangleMesh(triangles, vertices));
+	return PTriangleMesh(new CTriangleMesh(triangles, vertices, normals, colors, scales));
 }
 
 template <class T>
@@ -152,20 +302,102 @@ class FWriteElement {
 public:
 	FWriteElement(ostream& __os):os(__os){};
 	void operator()(const T3DVector<T>& elm) {
-		os << elm.x << " " <<  elm.y << " " <<  elm.z << "\n";
+		os  <<  "3 " << elm.x << " " <<  elm.y << " " <<  elm.z << "\n";
 	}
 };
 
+class CElementWriter {
+public: 
+	CElementWriter(): m_next(nullptr) {}
+	void write(const CTriangleMesh& mesh, ostream& os, unsigned i)  {
+		do_write(mesh, os, i);
+		if (m_next) {
+			os << " "; 
+			m_next->write(mesh, os, i);
+		}
+	}
+
+	void append(CElementWriter *w) {
+		if (m_next)
+			m_next->append(w);
+		else
+			m_next = w; 
+	}
+private:
+	virtual void do_write(const CTriangleMesh& mesh, ostream& os, unsigned i) = 0; 
+	CElementWriter *m_next; 
+}; 
+
+class CVertexWriter : public CElementWriter{
+	virtual void do_write(const CTriangleMesh& mesh, ostream& os, unsigned i) {
+		auto v = mesh.vertex_at(i);
+		os << v.x << " " << v.y << " " << v.z; 
+	}
+}; 
+
+class CNormalWriter : public CElementWriter{
+	virtual void do_write(const CTriangleMesh& mesh, ostream& os, unsigned i) {
+		auto v = mesh.normal_at(i);
+		os << v.x << " " << v.y << " " << v.z; 
+	}
+}; 
+
+class CColorWriter : public CElementWriter{
+	virtual void do_write(const CTriangleMesh& mesh, ostream& os, unsigned i) {
+		auto v = mesh.color_at(i);
+		os << v.x << " " << v.y << " " << v.z; 
+	}
+}; 
+
+class CScaleWriter : public CElementWriter{
+	virtual void do_write(const CTriangleMesh& mesh, ostream& os, unsigned i) {
+		auto v = mesh.scale_at(i);
+		os << v; 
+	}
+}; 
+
+
 bool TPlyMeshIO::do_save_it(const CTriangleMesh& mesh, ostream& os)const
 {
 	os << "ply\n";
+	os << "format ascii 1.0\n";
 	os << "element vertex " <<  mesh.vertices_size() << "\n";
+	// add properties
+	os << "property float32 x\n";
+	os << "property float32 y\n";
+	os << "property float32 z\n";
+
+	CVertexWriter writer; 
+	
+	if (mesh.get_available_data() & CTriangleMesh::ed_normal) {
+		os << "property float32 nx\n";
+		os << "property float32 ny\n";
+		os << "property float32 nz\n";
+		writer.append(new CNormalWriter); 
+	}
+	
+	if (mesh.get_available_data() & CTriangleMesh::ed_color) {
+		os << "property float32 red\n";
+		os << "property float32 green\n";
+		os << "property float32 blue\n";
+		writer.append(new CColorWriter); 
+	}
+	
+	if (mesh.get_available_data() & CTriangleMesh::ed_scale) {
+		os << "property float32 scale\n";
+		writer.append(new CScaleWriter); 
+	}
 	os << "element face " << mesh.triangle_size() << "\n";
+	os << "property list uint8 uint32 vertex_index\n"; 
 	os << "end_header\n";
 
-	for_each(mesh.vertices_begin(),mesh.vertices_end(),   FWriteElement<float>(os));
-	for_each(mesh.triangles_begin(),mesh.triangles_end(), FWriteElement<unsigned int>(os));
+	for (unsigned i = 0; i < mesh.vertices_size(); ++i) {
+		writer.write(mesh, os, i);
+		os << "\n"; 
+	}
 
+	for_each(mesh.triangles_begin(),mesh.triangles_end(), FWriteElement<unsigned int>(os));
+	
 	return true;
 }
 
diff --git a/mia/mesh/io/stl.cc b/mia/mesh/io/stl.cc
index ea50e07..9c31dd6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +131,7 @@ PTriangleMesh CSTLMeshIO::load_ascii(istream& f)const
 
 	f >> tag;
 	if (tag != start_face) {
-		cvdebug() << "Loading solid " <<solid_name << "\n";
+		cvdebug() << "Loading solid " <<tag  << "\n";
 		f >> tag;
 	}
 
@@ -195,7 +195,7 @@ PTriangleMesh CSTLMeshIO::load_ascii(istream& f)const
 		     i != vmap.end(); ++i)
 			(*vertices)[i->second] = i->first;
 
-		cvwarn() << "For nor we throw away the normals of the file\n";
+		cvinfo() << "STL: For now the face normals given in the file are thrown away\n";
 
 		CTriangleMesh::PTrianglefield tri(new CTriangleMesh::CTrianglefield(faces.size()));
 		copy(faces.begin(), faces.end(), tri->begin());
@@ -204,8 +204,8 @@ PTriangleMesh CSTLMeshIO::load_ascii(istream& f)const
 	}
 
 fail:
-	cverr() << "not a valid ascii STL mesh file\n";
-	return PTriangleMesh();
+	throw create_exception<runtime_error>("STL: not a valid ascii STL mesh file\n");
+
 }
 
 PTriangleMesh CSTLMeshIO::do_load(string const &  filename)const
@@ -221,14 +221,7 @@ PTriangleMesh CSTLMeshIO::do_load(string const &  filename)const
 		result = load_ascii(cin);
 
 	if (!result) { // probably a binary file
-
-		cvdebug() << "Try STL binary file\n";
-		CInputFile f(filename);
-
-		if (!f)
-			return PTriangleMesh();
-
-		cvdebug() << "If this is a binary STL mesh then it can not yet be loaded\n";
+		cvinfo() << "If this is a binary STL mesh then it is not (yet) supported\n";
 		return PTriangleMesh();
 	}
 	return PTriangleMesh(result);
diff --git a/mia/mesh/io/test_meshio.cc b/mia/mesh/io/test_meshio.cc
new file mode 100644
index 0000000..fc0a699
--- /dev/null
+++ b/mia/mesh/io/test_meshio.cc
@@ -0,0 +1,593 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/mesh/triangularMesh.hh>
+
+#include <set>
+#include <ostream>
+
+
+using namespace mia;
+using namespace std;
+
+
+template <typename V>
+struct vector3d_less {
+	bool operator()( const V& lhs, const V& rhs ) const {
+		return (lhs.x < rhs.x) || (lhs.x == rhs.x && (lhs.y < rhs.y || (lhs.y == rhs.y && lhs.z < rhs.z))); 
+	}
+}; 
+
+set<C3DFVector, vector3d_less<C3DFVector> > test_vertices = {
+        C3DFVector(2,0,0), C3DFVector(-2,0,0), 
+        C3DFVector(0,2,0), C3DFVector(0,-2,0), 
+        C3DFVector(0,0,1), C3DFVector(0,0,-1)
+};
+
+set<C3DFVector, vector3d_less<C3DFVector> > test_normals = {
+        C3DFVector(1,0,0), C3DFVector(-1,0,0), 
+        C3DFVector(0,1,0), C3DFVector(0,-1,0), 
+        C3DFVector(0,0,1), C3DFVector(0,0,-1)
+};
+
+set<C3DFVector, vector3d_less<C3DFVector> > test_colors = {
+        C3DFVector(0.1, 0.5, 0.5), C3DFVector(0.2, 0.6, 0.7), 
+        C3DFVector(0.3, 0.6, 0.7), C3DFVector(0.4, 0.6, 0.7), 
+        C3DFVector(0.5, 0.6, 0.7), C3DFVector(0.6, 0.6, 0.7)
+};
+
+set<float> test_scale = {
+	0.1, 2.2, 4.3, 3.4, 0.5, 0.6
+};
+
+typedef CTriangleMesh::triangle_type Triangle; 
+
+set<Triangle, vector3d_less<Triangle>>  test_triangles = 
+        {Triangle(4, 0, 2), Triangle(4, 2, 1), 
+         Triangle(4, 1, 3), Triangle(4, 3, 0), 
+         Triangle(5, 2, 0), Triangle(5, 1, 2), 
+         Triangle(5, 3, 1), Triangle(5, 0, 3)};
+
+
+template <typename T>
+ostream& operator << (ostream& os, const set<T, vector3d_less<T>>& s)
+{
+	os << "set:[";
+	for (auto x: s)
+		os << "<" << x << "> ";
+	os << "]\n";
+	return os; 
+}
+
+
+template <typename IT, typename T> 
+void test_set_equal(const IT begin, IT end,
+		    const set<T, vector3d_less<T>>& expect)
+{
+        set<T, vector3d_less<T>> loaded(begin, end);
+        BOOST_CHECK_EQUAL(loaded.size(), expect.size());
+
+	BOOST_CHECK(loaded == expect);
+	cvdebug() << loaded << "\n";
+	cvdebug() << expect << "\n"; 
+        
+}
+
+template <typename IT, typename T> 
+void test_set_equal(const IT begin, IT end,
+		    const set<T>& expect)
+{
+        set<T> loaded(begin, end);
+        BOOST_CHECK_EQUAL(loaded.size(), expect.size());
+
+	BOOST_CHECK(loaded == expect);
+        
+}
+
+
+const char test_mesh_off[] =
+	       "OFF\n"
+		"\n"
+		"6 8 0\n"
+		"2.000000 0.000000 0.000000\n"
+		"-2.000000 0.000000 0.000000\n"
+		"0.000000 2.000000 0.000000\n"
+		"0.000000 -2.000000 0.000000\n"
+		"0.000000 0.000000 1.000000\n"
+		"0.000000 0.000000 -1.000000\n"
+		"3 4 0 2\n"
+		"3 4 2 1\n"
+		"3 4 1 3\n"
+		"3 4 3 0\n"
+		"3 5 2 0\n"
+		"3 5 1 2\n"
+		"3 5 3 1\n"
+		"3 5 0 3\n";
+
+const char test_mesh_ply[] = "ply\n"
+			       "format ascii 1.0\n"
+			       "element vertex 6\n"
+			       "property float32 x\n"
+			       "property float32 y\n"
+			       "property float32 z\n"
+			       "element face 8\n"
+			       "property list uint8 uint32 vertex_index\n"
+			       "end_header\n"
+			       "2 0 0\n"
+			       "-2 0 0\n"
+			       "0 2 0\n"
+			       "0 -2 0\n"
+			       "0 0 1\n"
+			       "0 0 -1\n"
+			       "3 4 0 2\n"
+			       "3 4 2 1\n"
+			       "3 4 1 3\n"
+			       "3 4 3 0\n" 
+			       "3 5 2 0\n"
+			       "3 5 1 2\n" 
+			       "3 5 3 1\n"
+			       "3 5 0 3\n"; 
+
+		       
+
+const char test_mesh_normals_off[] =
+	"NOFF\n"
+		"\n"
+		"6 8 0\n"
+		"2.000000 0.000000 0.000000 1.000000 0.000000 0.000000\n"
+		"-2.000000 0.000000 0.000000 -1.000000 0.000000 0.000000\n"
+		"0.000000 2.000000 0.000000 0.000000 1.000000 0.000000\n"
+		"0.000000 -2.000000 0.000000 0.000000 -1.000000 0.000000\n"
+		"0.000000 0.000000 1.000000 0.000000 0.000000 1.000000\n"
+		"0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000\n"
+		"3 4 0 2\n"
+		"3 4 2 1\n"
+		"3 4 1 3\n"
+		"3 4 3 0\n"
+		"3 5 2 0\n"
+		"3 5 1 2\n"
+		"3 5 3 1\n"
+		"3 5 0 3\n";
+
+const char test_mesh_normals_colors_ply[] =
+			       "ply\n"
+			       "format ascii 1.0\n"
+			       "element vertex 6\n"
+			       "property float32 x\n"
+			       "property float32 y\n"
+			       "property float32 z\n"
+			       "property float32 nx\n"
+			       "property float32 ny\n"
+			       "property float32 nz\n"
+			       "property float32 red\n"
+			       "property float32 green\n"
+			       "property float32 blue\n"
+			       "element face 8\n"
+			       "property list uint8 uint32 vertex_index\n"
+			       "end_header\n"
+			       "2 0 0 1 0 0 0.1 0.5 0.5\n"
+			       "-2 0 0 -1 0 0 0.2 0.6 0.7\n"
+			       "0 2 0 0 1 0 0.3 0.6 0.7\n"
+			       "0 -2 0 0 -1 0 0.4 0.6 0.7\n"
+			       "0 0 1 0 0 1 0.5 0.6 0.7\n"
+			       "0 0 -1 0 0 -1 0.6 0.6 0.7\n"
+			       "3 4 0 2\n"
+			       "3 4 2 1\n"
+			       "3 4 1 3\n"
+			       "3 4 3 0\n"
+			       "3 5 2 0\n"
+			       "3 5 1 2\n" 
+			       "3 5 3 1\n"
+			       "3 5 0 3\n"; 
+
+const char test_mesh_normals_scale_ply[] =
+			       "ply\n"
+			       "format ascii 1.0\n"
+			       "element vertex 6\n"
+			       "property float32 x\n"
+			       "property float32 y\n"
+			       "property float32 z\n"
+			       "property float32 nx\n"
+			       "property float32 ny\n"
+			       "property float32 nz\n"
+			       "property float32 scale\n"
+			       "element face 8\n"
+			       "property list uint8 uint32 vertex_index\n"
+			       "end_header\n"
+			       "2 0 0 1 0 0 0.1\n"
+			       "-2 0 0 -1 0 0 2.2\n"
+			       "0 2 0 0 1 0 4.3\n"
+			       "0 -2 0 0 -1 0 3.4\n"
+			       "0 0 1 0 0 1 0.5\n"
+			       "0 0 -1 0 0 -1 0.6\n"
+			       "3 4 0 2\n"
+			       "3 4 2 1\n"
+			       "3 4 1 3\n"
+			       "3 4 3 0\n"
+			       "3 5 2 0\n"
+			       "3 5 1 2\n" 
+			       "3 5 3 1\n"
+			       "3 5 0 3\n"; 
+
+
+const char test_mesh_normals_ply[] =
+			       "ply\n"
+			       "format ascii 1.0\n"
+			       "element vertex 6\n"
+			       "property float32 x\n"
+			       "property float32 y\n"
+			       "property float32 z\n"
+			       "property float32 nx\n"
+			       "property float32 ny\n"
+			       "property float32 nz\n"
+			       "element face 8\n"
+			       "property list uint8 uint32 vertex_index\n"
+			       "end_header\n"
+			       "2 0 0 1 0 0\n"
+			       "-2 0 0 -1 0 0\n"
+			       "0 2 0 0 1 0\n"
+			       "0 -2 0 0 -1 0\n"
+			       "0 0 1 0 0 1\n"
+			       "0 0 -1 0 0 -1\n"
+			       "3 4 0 2\n"
+			       "3 4 2 1\n"
+			       "3 4 1 3\n"
+			       "3 4 3 0\n"
+			       "3 5 2 0\n"
+			       "3 5 1 2\n" 
+			       "3 5 3 1\n"
+			       "3 5 0 3\n"; 
+			       
+
+const char test_mesh_normals_colors_off[] = 
+			       "CNOFF\n"
+			       "\n"
+			       "6 8 0\n"
+			       "2.000000 0.000000 0.000000 1.000000 0.000000 0.000000 0.100000 0.500000 0.500000\n"
+			       "-2.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 0.200000 0.600000 0.700000\n"
+			       "0.000000 2.000000 0.000000 0.000000 1.000000 0.000000 0.300000 0.600000 0.700000\n"
+			       "0.000000 -2.000000 0.000000 0.000000 -1.000000 0.000000 0.400000 0.600000 0.700000\n"
+			       "0.000000 0.000000 1.000000 0.000000 0.000000 1.000000 0.500000 0.600000 0.700000\n"
+			       "0.000000 0.000000 -1.000000 0.000000 0.000000 -1.000000 0.600000 0.600000 0.700000\n"
+			       "3 4 0 2\n"
+			       "3 4 2 1\n"
+			       "3 4 1 3\n"
+			       "3 4 3 0\n"
+			       "3 5 2 0\n"
+			       "3 5 1 2\n"
+			       "3 5 3 1\n"
+			       "3 5 0 3\n"; 
+
+
+extern const char test_mesh_stl[]; 
+
+static void run_simple_octaedron_test(const char *in_file, const char *test_file, const string& test_string); 
+static void run_octaedron_vertex_normal_test(const char *in_file, const char *test_file, const string& test_string); 
+static void run_octaedron_vertex_normal_color_test(const char *in_file, const char *test_file, const string& test_string);
+static void run_octaedron_vertex_normal_scale_test(const char *in_file, const char *test_file, const string& test_string); 
+
+
+BOOST_AUTO_TEST_CASE( test_load_save_octaedron_off )
+{
+	run_simple_octaedron_test(MIA_SOURCE_ROOT"/testdata/octahedron.off", "testmesh.OFF", test_mesh_off); 
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_octaedron_ply )
+{
+	run_simple_octaedron_test(MIA_SOURCE_ROOT"/testdata/octahedron.ply", "testmesh.ply", test_mesh_ply); 
+}
+
+
+
+BOOST_AUTO_TEST_CASE( test_load_save_octaedron_with_vertex_normals_off )
+{
+	run_octaedron_vertex_normal_test(MIA_SOURCE_ROOT"/testdata/octahedron-with-normals.off", "testmesh-n.OFF", test_mesh_normals_off); 
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_octaedron_with_vertex_normals_ply )
+{
+	run_octaedron_vertex_normal_test(MIA_SOURCE_ROOT"/testdata/octahedron-with-normals.ply", "testmesh-n.PLY", test_mesh_normals_ply); 
+}
+
+
+BOOST_AUTO_TEST_CASE( test_load_save_octaedron_with_vertex_normals_colors_off )
+{
+	run_octaedron_vertex_normal_color_test(MIA_SOURCE_ROOT"/testdata/octahedron-with-normals-and-color.off",
+					       "octahedron-nc.OFF", test_mesh_normals_colors_off); 
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_octaedron_with_vertex_normals_colors_ply )
+{
+	run_octaedron_vertex_normal_color_test(MIA_SOURCE_ROOT"/testdata/octahedron-with-normals-and-color.ply",
+					       "octahedron-nc.PLY", test_mesh_normals_colors_ply); 
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_octaedron_with_vertex_normals_scale_ply )
+{
+
+	run_octaedron_vertex_normal_scale_test(MIA_SOURCE_ROOT"/testdata/octahedron-with-normals-and-scale.ply",
+					       "octahedron-ns.PLY", test_mesh_normals_scale_ply); 
+}
+
+
+BOOST_AUTO_TEST_CASE( test_load_off_errors )
+{
+        BOOST_CHECK_THROW(CMeshIOPluginHandler::instance().load(MIA_SOURCE_ROOT"/testdata/4D.off"), invalid_argument);
+        BOOST_CHECK_THROW(CMeshIOPluginHandler::instance().load(MIA_SOURCE_ROOT"/testdata/ND.off"), invalid_argument);
+	BOOST_CHECK_THROW(CMeshIOPluginHandler::instance().load(MIA_SOURCE_ROOT"/testdata/vertex_error.off"), runtime_error);
+}
+
+set<C3DFVector, vector3d_less<C3DFVector> > test_poly_vertices = {
+        C3DFVector(1,0,0), C3DFVector(1,1,0), 
+        C3DFVector(2,1,0), C3DFVector(2,3,0)
+};
+
+
+BOOST_AUTO_TEST_CASE( test_load_off_poly )
+{
+	auto mesh = CMeshIOPluginHandler::instance().load(MIA_SOURCE_ROOT"/testdata/poly.off");
+	test_set_equal(mesh->vertices_begin(), mesh->vertices_end(), test_poly_vertices);
+	BOOST_CHECK_EQUAL(mesh->triangle_size(), 2u);
+
+	BOOST_CHECK_EQUAL(mesh->triangle_at(0), Triangle(2,3,0)); 
+	BOOST_CHECK_EQUAL(mesh->triangle_at(1), Triangle(1,2,0));
+	
+}
+
+static void run_simple_octaedron_test(const char *in_file, const char *test_file, const string& test_string)
+{
+        auto mesh = CMeshIOPluginHandler::instance().load(in_file);
+
+	BOOST_CHECK_EQUAL(mesh->get_available_data(), CTriangleMesh::ed_vertex); 
+	
+        test_set_equal(mesh->vertices_begin(), mesh->vertices_end(), test_vertices);
+        test_set_equal(mesh->triangles_begin(), mesh->triangles_end(), test_triangles); 
+
+	BOOST_REQUIRE(CMeshIOPluginHandler::instance().save(test_file, *mesh));
+
+	auto mesh2 = CMeshIOPluginHandler::instance().load(test_file);
+
+        test_set_equal(mesh2->vertices_begin(), mesh2->vertices_end(), test_vertices);
+        test_set_equal(mesh2->triangles_begin(), mesh2->triangles_end(), test_triangles); 
+
+	// check file output 
+	FILE *testfile = fopen(test_file, "r");
+	BOOST_REQUIRE(testfile); 
+	char buffer[2000];
+	memset(buffer, 0, 2000); 
+	size_t flen = test_string.length(); //don't count terminating 0 
+	size_t read_bytes = fread(buffer, 1, 2000, testfile);
+	fclose(testfile);
+
+	BOOST_CHECK_EQUAL(read_bytes, flen);
+	BOOST_CHECK(!strcmp(buffer, test_string.c_str()));
+
+	cvdebug() << "Read: '" << buffer << "'\n"; 
+	
+	unlink(test_file); 
+}
+
+	
+static void run_octaedron_vertex_normal_test(const char *in_file, const char *test_file, const string& test_string)
+{
+
+
+        auto mesh = CMeshIOPluginHandler::instance().load(in_file);
+        
+        test_set_equal(mesh->vertices_begin(), mesh->vertices_end(), test_vertices);
+        test_set_equal(mesh->triangles_begin(), mesh->triangles_end(), test_triangles); 
+        test_set_equal(mesh->normals_begin(), mesh->normals_end(), test_normals);
+
+	BOOST_REQUIRE(CMeshIOPluginHandler::instance().save(test_file, *mesh));
+
+	auto mesh2 = CMeshIOPluginHandler::instance().load(test_file);
+
+        test_set_equal(mesh2->vertices_begin(), mesh2->vertices_end(), test_vertices);
+        test_set_equal(mesh2->triangles_begin(), mesh2->triangles_end(), test_triangles); 
+        test_set_equal(mesh2->normals_begin(), mesh2->normals_end(), test_normals);
+
+	// check file output 
+	FILE *testfile = fopen(test_file, "r");
+	BOOST_REQUIRE(testfile); 
+	char buffer[2000];
+	memset(buffer, 0, 2000); 
+	size_t flen = test_string.length();
+	size_t read_bytes = fread(buffer, 1, 2000, testfile);
+	fclose(testfile);
+
+	BOOST_CHECK_EQUAL(read_bytes, flen);
+	BOOST_CHECK(!strcmp(buffer, test_string.c_str()));
+
+	cvdebug() << "Read: '" << buffer << "'\n";
+	
+	unlink(test_file); 
+	
+}
+
+void run_octaedron_vertex_normal_color_test(const char *in_file, const char *test_file, const string& test_string)
+{
+	auto mesh = CMeshIOPluginHandler::instance().load(in_file);
+        
+        test_set_equal(mesh->vertices_begin(), mesh->vertices_end(), test_vertices);
+        test_set_equal(mesh->triangles_begin(), mesh->triangles_end(), test_triangles); 
+        test_set_equal(mesh->normals_begin(), mesh->normals_end(), test_normals);
+	test_set_equal(mesh->color_begin(), mesh->color_end(), test_colors);
+
+	BOOST_REQUIRE(CMeshIOPluginHandler::instance().save(test_file, *mesh));
+
+	auto mesh2 = CMeshIOPluginHandler::instance().load(test_file);
+
+        test_set_equal(mesh2->vertices_begin(), mesh2->vertices_end(), test_vertices);
+        test_set_equal(mesh2->triangles_begin(), mesh2->triangles_end(), test_triangles); 
+        test_set_equal(mesh2->normals_begin(), mesh2->normals_end(), test_normals);
+	test_set_equal(mesh2->color_begin(), mesh2->color_end(), test_colors);
+
+	// check file output 
+	FILE *testfile = fopen(test_file, "r");
+	BOOST_REQUIRE(testfile); 
+	char buffer[2000];
+	memset(buffer, 0, 2000); 
+	size_t flen = test_string.length(); //don't count terminating 0 
+	size_t read_bytes = fread(buffer, 1, 2000, testfile);
+	fclose(testfile);
+
+	BOOST_CHECK_EQUAL(read_bytes, flen);
+	BOOST_CHECK(!strcmp(buffer, test_string.c_str()));
+
+	cvdebug() << "Read: '" << buffer << "'\n";
+	
+	unlink(test_file); 
+}
+
+void run_octaedron_vertex_normal_scale_test(const char *in_file, const char *test_file, const string& test_string)
+{
+	auto mesh = CMeshIOPluginHandler::instance().load(in_file);
+        
+        test_set_equal(mesh->vertices_begin(), mesh->vertices_end(), test_vertices);
+        test_set_equal(mesh->triangles_begin(), mesh->triangles_end(), test_triangles); 
+        test_set_equal(mesh->normals_begin(), mesh->normals_end(), test_normals);
+	test_set_equal(mesh->scale_begin(), mesh->scale_end(), test_scale);
+
+	BOOST_REQUIRE(CMeshIOPluginHandler::instance().save(test_file, *mesh));
+
+	auto mesh2 = CMeshIOPluginHandler::instance().load(test_file);
+
+        test_set_equal(mesh2->vertices_begin(), mesh2->vertices_end(), test_vertices);
+        test_set_equal(mesh2->triangles_begin(), mesh2->triangles_end(), test_triangles); 
+        test_set_equal(mesh2->normals_begin(), mesh2->normals_end(), test_normals);
+	test_set_equal(mesh2->scale_begin(), mesh2->scale_end(), test_scale);
+
+	// check file output 
+	FILE *testfile = fopen(test_file, "r");
+	BOOST_REQUIRE(testfile); 
+	char buffer[2000];
+	memset(buffer, 0, 2000); 
+	size_t flen = test_string.length(); //don't count terminating 0 
+	size_t read_bytes = fread(buffer, 1, 2000, testfile);
+	fclose(testfile);
+
+	BOOST_CHECK_EQUAL(read_bytes, flen);
+	BOOST_CHECK(!strcmp(buffer, test_string.c_str()));
+
+	cvdebug() << "Read: '" << buffer << "'\n";
+	
+	unlink(test_file); 
+}
+
+BOOST_AUTO_TEST_CASE( test_load_save_octaedron_stl )
+{
+	const char *test_file = "testmesh.stl";
+	string test_string(test_mesh_stl); 
+        auto mesh = CMeshIOPluginHandler::instance().load(MIA_SOURCE_ROOT"/testdata/octahedron.stl");
+
+	BOOST_CHECK_EQUAL(mesh->get_available_data(), CTriangleMesh::ed_vertex); 
+	
+        test_set_equal(mesh->vertices_begin(), mesh->vertices_end(), test_vertices);
+	// missing triangles test, can't be done like above, because the triangles are build
+	// from the vertex list. 
+	
+
+	BOOST_REQUIRE(CMeshIOPluginHandler::instance().save(test_file, *mesh));
+
+	auto mesh2 = CMeshIOPluginHandler::instance().load(test_file);
+
+        test_set_equal(mesh2->vertices_begin(), mesh2->vertices_end(), test_vertices);
+        //test_set_equal(mesh2->triangles_begin(), mesh2->triangles_end(), test_triangles); 
+
+	// check file output 
+	FILE *testfile = fopen(test_file, "r");
+	BOOST_REQUIRE(testfile); 
+	char buffer[2000];
+	memset(buffer, 0, 2000); 
+	size_t flen = test_string.length(); //don't count terminating 0 
+	size_t read_bytes = fread(buffer, 1, 2000, testfile);
+	fclose(testfile);
+
+	BOOST_CHECK_EQUAL(read_bytes, flen);
+	BOOST_CHECK(!strcmp(buffer, test_string.c_str()));
+
+	cvdebug() << "Read: '" << buffer << "'\n"; 
+	
+	unlink(test_file); 
+}
+
+
+extern const char test_mesh_stl[] =
+"solid\n"
+"  facet normal 0.408248 0.408248 0.816497\n"
+"    outer loop\n"
+"      vertex 0 0 1\n"
+"      vertex 2 0 0\n"
+"      vertex 0 2 0\n"
+"    endloop\n"
+"  endfacet\n"
+"  facet normal -0.408248 0.408248 0.816497\n"
+"    outer loop\n"
+"      vertex 0 0 1\n"
+"      vertex 0 2 0\n"
+"      vertex -2 0 0\n"
+"    endloop\n"
+"  endfacet\n"
+"  facet normal -0.408248 -0.408248 0.816497\n"
+"    outer loop\n"
+"      vertex 0 0 1\n"
+"      vertex -2 0 0\n"
+"      vertex 0 -2 0\n"
+"    endloop\n"
+"  endfacet\n"
+"  facet normal 0.408248 -0.408248 0.816497\n"
+"    outer loop\n"
+"      vertex 0 0 1\n"
+"      vertex 0 -2 0\n"
+"      vertex 2 0 0\n"
+"    endloop\n"
+"  endfacet\n"
+"  facet normal 0.408248 0.408248 -0.816497\n"
+"    outer loop\n"
+"      vertex 0 0 -1\n"
+"      vertex 0 2 0\n"
+"      vertex 2 0 0\n"
+"    endloop\n"
+"  endfacet\n"
+"  facet normal -0.408248 0.408248 -0.816497\n"
+"    outer loop\n"
+"      vertex 0 0 -1\n"
+"      vertex -2 0 0\n"
+"      vertex 0 2 0\n"
+"    endloop\n"
+"  endfacet\n"
+"  facet normal -0.408248 -0.408248 -0.816497\n"
+"    outer loop\n"
+"      vertex 0 0 -1\n"
+"      vertex 0 -2 0\n"
+"      vertex -2 0 0\n"
+"    endloop\n"
+"  endfacet\n"
+"  facet normal 0.408248 -0.408248 -0.816497\n"
+"    outer loop\n"
+"      vertex 0 0 -1\n"
+"      vertex 2 0 0\n"
+"      vertex 0 -2 0\n"
+"    endloop\n"
+"  endfacet\n"
+"endsolid\n"; 
diff --git a/mia/mesh/test_triangle_neighbourhood.cc b/mia/mesh/test_triangle_neighbourhood.cc
index 033ca40..05a2c8f 100644
--- a/mia/mesh/test_triangle_neighbourhood.cc
+++ b/mia/mesh/test_triangle_neighbourhood.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,3 +72,274 @@ BOOST_AUTO_TEST_CASE(test_neighborhood)
         
 
 }
+
+BOOST_AUTO_TEST_CASE(test_normals_explicite_evaluate)
+{
+        auto vertices = CTriangleMesh::PVertexfield(new CTriangleMesh::CVertexfield({C3DFVector(2,0,0), C3DFVector(-2,0,0), 
+                                        C3DFVector(0,2,0), C3DFVector(0,-2,0), 
+                                        C3DFVector(0,0,2), C3DFVector(0,0,-2)})); 
+	
+	typedef CTriangleMesh::triangle_type Triangle; 
+	
+	auto triangles = CTriangleMesh::PTrianglefield(
+		new CTriangleMesh::CTrianglefield(
+			{Triangle(4, 0, 2), Triangle(4, 2, 1), 
+			 Triangle(4, 1, 3), Triangle(4, 3, 0), 
+			 Triangle(5, 2, 0), Triangle(5, 1, 2), 
+			 Triangle(5, 3, 1), Triangle(5, 0, 3)}));
+
+	vector<C3DFVector> test_normals = {
+		C3DFVector( 1,  0,  0),
+		C3DFVector(-1,  0,  0),
+		C3DFVector( 0,  1,  0),
+		C3DFVector( 0, -1,  0),
+		C3DFVector( 0,  0,  1),
+		C3DFVector( 0,  0, -1)
+	};
+	
+	
+	
+	CTriangleMesh mesh(triangles, vertices);
+
+	BOOST_CHECK( !mesh.get_normal_pointer() );
+	BOOST_CHECK( !mesh.get_color_pointer() );
+
+	mesh.evaluate_normals(); 
+	BOOST_CHECK( mesh.get_normal_pointer() );
+		
+	auto ni = mesh.normals_begin();
+	auto ne = mesh.normals_end();
+
+	auto ntest = test_normals.begin();
+
+	BOOST_CHECK_EQUAL(std::distance(ni, ne), 6); 
+
+	while (ni != ne) {
+		BOOST_CHECK_CLOSE(ni->x, ntest->x, 0.1);
+		BOOST_CHECK_CLOSE(ni->y, ntest->y, 0.1);
+		BOOST_CHECK_CLOSE(ni->z, ntest->z, 0.1); 
+		++ni; ++ntest; 
+	}
+	
+	
+}
+
+BOOST_AUTO_TEST_CASE(test_normals_implicite_evaluate)
+{
+        auto vertices = CTriangleMesh::PVertexfield(new CTriangleMesh::CVertexfield({C3DFVector(2,0,0), C3DFVector(-2,0,0), 
+                                        C3DFVector(0,2,0), C3DFVector(0,-2,0), 
+                                        C3DFVector(0,0,2), C3DFVector(0,0,-2)})); 
+	
+	typedef CTriangleMesh::triangle_type Triangle; 
+	
+	auto triangles = CTriangleMesh::PTrianglefield(
+		new CTriangleMesh::CTrianglefield(
+			{Triangle(4, 0, 2), Triangle(4, 2, 1), 
+			 Triangle(4, 1, 3), Triangle(4, 3, 0), 
+			 Triangle(5, 2, 0), Triangle(5, 1, 2), 
+			 Triangle(5, 3, 1), Triangle(5, 0, 3)}));
+
+	vector<C3DFVector> test_normals = {
+		C3DFVector( 1,  0,  0),
+		C3DFVector(-1,  0,  0),
+		C3DFVector( 0,  1,  0),
+		C3DFVector( 0, -1,  0),
+		C3DFVector( 0,  0,  1),
+		C3DFVector( 0,  0, -1)
+	};
+	
+	const CTriangleMesh mesh(triangles, vertices);
+
+	BOOST_CHECK( mesh.get_vertex_pointer() );
+	BOOST_CHECK( mesh.get_triangle_pointer() );
+	
+	BOOST_CHECK( !mesh.get_normal_pointer() );
+	BOOST_CHECK( !mesh.get_color_pointer() );
+
+	auto ni = mesh.normals_begin();
+	auto ne = mesh.normals_end();
+
+	BOOST_CHECK( mesh.get_normal_pointer() );
+	auto ntest = test_normals.begin();
+
+	BOOST_CHECK_EQUAL(std::distance(ni, ne), 6); 
+
+	while (ni != ne) {
+		BOOST_CHECK_CLOSE(ni->x, ntest->x, 0.1);
+		BOOST_CHECK_CLOSE(ni->y, ntest->y, 0.1);
+		BOOST_CHECK_CLOSE(ni->z, ntest->z, 0.1); 
+		++ni; ++ntest; 
+	}
+	
+	// test scales is empty and not allocated 
+	auto sb = mesh.scale_begin();
+	auto se = mesh.scale_end();
+
+	BOOST_CHECK(sb == se); 
+
+	// test color is empty and not allocated 
+	auto cb = mesh.color_begin();
+	auto ce = mesh.color_end();
+
+	BOOST_CHECK(cb == ce); 
+
+	
+}
+
+BOOST_AUTO_TEST_CASE(test_allocate_only_begin_first)
+{
+        auto vertices = CTriangleMesh::PVertexfield(new CTriangleMesh::CVertexfield({C3DFVector(2,0,0), C3DFVector(-2,0,0), 
+                                        C3DFVector(0,2,0), C3DFVector(0,-2,0), 
+                                        C3DFVector(0,0,2), C3DFVector(0,0,-2)})); 
+	
+	typedef CTriangleMesh::triangle_type Triangle; 
+	
+	auto triangles = CTriangleMesh::PTrianglefield(
+		new CTriangleMesh::CTrianglefield(
+			{Triangle(4, 0, 2), Triangle(4, 2, 1), 
+			 Triangle(4, 1, 3), Triangle(4, 3, 0), 
+			 Triangle(5, 2, 0), Triangle(5, 1, 2), 
+			 Triangle(5, 3, 1), Triangle(5, 0, 3)}));
+
+
+	CTriangleMesh mesh(triangles, vertices);
+	
+	BOOST_CHECK( !mesh.get_normal_pointer() );
+	BOOST_CHECK( !mesh.get_color_pointer() );
+
+	auto ni = mesh.normals_begin();
+	BOOST_CHECK( mesh.get_normal_pointer() );
+	
+	auto ne = mesh.normals_end();
+	BOOST_CHECK_EQUAL(std::distance(ni, ne), 6); 
+
+	while (ni != ne) {
+		BOOST_CHECK_EQUAL(ni->x, 0.0f);
+		BOOST_CHECK_EQUAL(ni->y, 0.0f);
+		BOOST_CHECK_EQUAL(ni->z, 0.0f); 
+		++ni; 
+	}
+
+	auto sb = mesh.scale_begin();
+	BOOST_CHECK_EQUAL(std::distance(sb, mesh.scale_end()), 6);
+
+	auto cb = mesh.color_begin();
+	BOOST_CHECK( mesh.get_color_pointer() );
+	BOOST_CHECK_EQUAL(std::distance(cb, mesh.color_end()), 6); 
+
+}
+
+BOOST_AUTO_TEST_CASE(test_allocate_only_end_first)
+{
+        auto vertices = CTriangleMesh::PVertexfield(new CTriangleMesh::CVertexfield({C3DFVector(2,0,0), C3DFVector(-2,0,0), 
+                                        C3DFVector(0,2,0), C3DFVector(0,-2,0), 
+                                        C3DFVector(0,0,2), C3DFVector(0,0,-2)})); 
+	
+	typedef CTriangleMesh::triangle_type Triangle; 
+	
+	auto triangles = CTriangleMesh::PTrianglefield(
+		new CTriangleMesh::CTrianglefield(
+			{Triangle(4, 0, 2), Triangle(4, 2, 1), 
+			 Triangle(4, 1, 3), Triangle(4, 3, 0), 
+			 Triangle(5, 2, 0), Triangle(5, 1, 2), 
+			 Triangle(5, 3, 1), Triangle(5, 0, 3)}));
+
+
+	CTriangleMesh mesh(triangles, vertices);
+	
+	BOOST_CHECK( !mesh.get_normal_pointer() );
+	BOOST_CHECK( !mesh.get_color_pointer() );
+
+	auto ne = mesh.normals_end();
+	BOOST_CHECK( mesh.get_normal_pointer() );
+	
+	auto ni = mesh.normals_begin();
+	
+	BOOST_CHECK_EQUAL(std::distance(ni, ne), 6); 
+
+	while (ni != ne) {
+		BOOST_CHECK_EQUAL(ni->x, 0.0f);
+		BOOST_CHECK_EQUAL(ni->y, 0.0f);
+		BOOST_CHECK_EQUAL(ni->z, 0.0f); 
+		++ni; 
+	}
+
+	auto se = mesh.scale_end();
+	BOOST_CHECK_EQUAL(std::distance(mesh.scale_begin(), se), 6);
+
+	auto ce = mesh.color_end();
+	BOOST_CHECK( mesh.get_color_pointer() );
+	BOOST_CHECK_EQUAL(std::distance(mesh.color_begin(), ce), 6); 
+	
+}
+
+BOOST_AUTO_TEST_CASE( test_clone_connectivity )
+{
+        auto vertices = CTriangleMesh::PVertexfield(new CTriangleMesh::CVertexfield({C3DFVector(2,0,0), C3DFVector(-2,0,0), 
+                                        C3DFVector(0,2,0), C3DFVector(0,-2,0), 
+                                        C3DFVector(0,0,2), C3DFVector(0,0,-2)})); 
+	
+	typedef CTriangleMesh::triangle_type Triangle; 
+	
+	auto triangles = CTriangleMesh::PTrianglefield(
+		new CTriangleMesh::CTrianglefield(
+			{Triangle(4, 0, 2), Triangle(4, 2, 1), 
+			 Triangle(4, 1, 3), Triangle(4, 3, 0), 
+			 Triangle(5, 2, 0), Triangle(5, 1, 2), 
+			 Triangle(5, 3, 1), Triangle(5, 0, 3)}));
+
+
+	CTriangleMesh mesh(triangles, vertices);
+
+	CTriangleMesh clone_c = mesh.clone_connectivity();
+
+	BOOST_CHECK_EQUAL(mesh.triangle_size(), clone_c.triangle_size());
+	BOOST_CHECK_EQUAL(mesh.vertices_size(), clone_c.vertices_size());
+
+	for (unsigned  i = 0; i < mesh.triangle_size(); ++i)
+		BOOST_CHECK_EQUAL(mesh.triangle_at(i), clone_c.triangle_at(i)); 
+
+	for (unsigned  i = 0; i < mesh.vertices_size(); ++i)
+		BOOST_CHECK_EQUAL(clone_c.vertex_at(i), C3DFVector::_0);
+	
+	
+}
+
+class CMockDeform {
+public:
+	C3DFVector apply(const C3DFVector& MIA_PARAM_UNUSED(x)) const {
+		return C3DFVector(2,3,4); 
+	}
+};
+
+
+BOOST_AUTO_TEST_CASE( test_scale_evaluation )
+{
+        auto vertices = CTriangleMesh::PVertexfield(new CTriangleMesh::CVertexfield({C3DFVector(2,0,0), C3DFVector(-2,0,0), 
+                                        C3DFVector(0,2,0), C3DFVector(0,-2,0), 
+                                        C3DFVector(0,0,2), C3DFVector(0,0,-2)})); 
+	
+	typedef CTriangleMesh::triangle_type Triangle; 
+	
+	auto triangles = CTriangleMesh::PTrianglefield(
+		new CTriangleMesh::CTrianglefield(
+			{Triangle(4, 0, 2), Triangle(4, 2, 1), 
+			 Triangle(4, 1, 3), Triangle(4, 3, 0), 
+			 Triangle(5, 2, 0), Triangle(5, 1, 2), 
+			 Triangle(5, 3, 1), Triangle(5, 0, 3)}));
+
+
+	CTriangleMesh mesh(triangles, vertices);
+
+	CMockDeform deform;
+	CTriangleMesh colored = colorize_mesh(mesh, deform);
+
+	BOOST_CHECK_EQUAL(std::distance(colored.scale_begin(), colored.scale_end()), 6);
+
+	vector<double> test_scale = {2, -2, 3, -3, 4, -4};
+	auto ts = test_scale.begin(); 
+	for (auto ci = colored.scale_begin(); ci != colored.scale_end(); ++ci, ++ts) {
+		BOOST_CHECK_CLOSE(*ci, *ts, 0.0001); 
+	}
+	
+}
diff --git a/mia/mesh/test_triangulate.cc b/mia/mesh/test_triangulate.cc
index bc2550b..2c0e48e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/triangle_neighbourhood.cc b/mia/mesh/triangle_neighbourhood.cc
index f1e9639..371de0d 100644
--- a/mia/mesh/triangle_neighbourhood.cc
+++ b/mia/mesh/triangle_neighbourhood.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/triangle_neighbourhood.hh b/mia/mesh/triangle_neighbourhood.hh
index c7d12e7..6b21ff1 100644
--- a/mia/mesh/triangle_neighbourhood.hh
+++ b/mia/mesh/triangle_neighbourhood.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 733fba1..96c7903 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,16 +25,12 @@
 #include <set>
 #include <mia/mesh/triangularMesh.hh>
 
-#include <tbb/parallel_for.h>
-#include <tbb/parallel_reduce.h>
-#include <tbb/blocked_range.h>
-
+#include <mia/core/parallel.hh>
 #include <mia/core/threadedmsg.hh>
 
 
 NS_MIA_BEGIN
 
-using namespace tbb;
 using namespace std;
 using namespace boost;
 
@@ -154,7 +150,7 @@ void CTriangleMeshData::evaluate_normals()
 	typedef CTriangleMesh::normal_type normal_type; 
 	typedef CTriangleMesh::triangle_type triangle_type; 
 
-	auto run_triangles = [this, &ctriangles, &normalize](const blocked_range<unsigned>& range, 
+	auto run_triangles = [this, &ctriangles, &normalize](const C1DParallelRange& range, 
 						 const vector<normal_type>& cnormals) {
 		vector<normal_type> normals(cnormals); 
 		CThreadMsgStream thread_stream;
@@ -188,31 +184,29 @@ void CTriangleMeshData::evaluate_normals()
 	
 	auto reduce_normals = [](const vector<normal_type>& lhs, const vector<normal_type>& rhs) -> vector<normal_type> {
 		vector<normal_type> result(lhs); 
-		parallel_for(blocked_range<unsigned>(0,result.size()), 
-			     [&result, &rhs](const blocked_range<unsigned>& range) {
-				     for (auto i= range.begin(); i != range.end(); ++i) 
-					     result[i] += rhs[i]; 
-			     }); 
+		pfor(C1DParallelRange(0,result.size()), 
+		     [&result, &rhs](const C1DParallelRange& range) {
+			     for (auto i= range.begin(); i != range.end(); ++i) 
+				     result[i] += rhs[i]; 
+		     }); 
 		return result; 
 	}; 
-
+	
 	vector<normal_type> normals_accumulator(m_normals->size());
 	
-	normals_accumulator = parallel_reduce(blocked_range<unsigned>(0, ctriangles.size(), 100), normals_accumulator, 
-					      run_triangles, reduce_normals);
-
-	parallel_for(blocked_range<unsigned>(0, normals_accumulator.size()),
-		     [this, &normals_accumulator](const blocked_range<unsigned>& range){
-			     for (auto i= range.begin(); i != range.end(); ++i) {
-				     C3DFVector n = normals_accumulator[i];
-				     auto nn = n.norm2();
-				     (*m_normals)[i] = (nn > 0) ? n / sqrt(nn) : C3DFVector::_0; 
-			     }
-		     });
+	normals_accumulator = preduce(C1DParallelRange(0, ctriangles.size(), 100), normals_accumulator, 
+				      run_triangles, reduce_normals);
 	
+	pfor(C1DParallelRange(0, normals_accumulator.size()),
+	     [this, &normals_accumulator](const C1DParallelRange& range){
+		     for (auto i= range.begin(); i != range.end(); ++i) {
+			     C3DFVector n = normals_accumulator[i];
+			     auto nn = n.norm2();
+			     (*m_normals)[i] = (nn > 0) ? n / sqrt(nn) : C3DFVector::_0; 
+		     }
+	     });
 }
 
-
 CTriangleMesh::CTriangleMesh(const CTriangleMesh& orig):
 	data(new CTriangleMeshData(*orig.data))
 {
@@ -239,9 +233,8 @@ CTriangleMesh::CTriangleMesh(PTrianglefield triangles, PVertexfield vertices):
 
 CTriangleMesh CTriangleMesh::clone_connectivity()const
 {
-	PVertexfield vertices(new CVertexfield(vertices_size()));
-	CTriangleMesh result(data->m_triangles, vertices);
-	return result;
+	PVertexfield  vf(new CVertexfield(vertices_size())); 
+	return CTriangleMesh(data->m_triangles, vf);
 }
 
 CTriangleMesh *CTriangleMesh::clone() const
@@ -260,6 +253,23 @@ const void *CTriangleMesh::get_vertex_pointer()const
 	return data->m_vertices ? &(*data->m_vertices)[0].x : NULL;
 }
 
+const CTriangleMesh::CVertexfield& CTriangleMesh::get_vertices() const
+{
+	if (data->m_vertices)
+		return *data->m_vertices;
+	else
+		throw logic_error("CTriangleMesh::get_vertices(): no vertices available"); 
+}
+
+const CTriangleMesh::CTrianglefield& CTriangleMesh::get_triangles() const
+{
+	if (data->m_triangles)
+		return *data->m_triangles;
+	else
+		throw logic_error("CTriangleMesh::get_triangles(): no triangles available"); 
+}
+
+
 const void *CTriangleMesh::get_normal_pointer()const
 {
 	return data->m_normals ? &(*data->m_normals)[0].x : NULL;
@@ -402,7 +412,7 @@ CTriangleMesh::normal_iterator CTriangleMesh::normals_end()
 	else
 		ensure_single_refered(data->m_normals);
 
-	return data->m_normals->begin();
+	return data->m_normals->end();
 }
 
 CTriangleMesh::const_scale_iterator CTriangleMesh::scale_begin()const
@@ -589,11 +599,11 @@ template <> const char *  const
 TPluginHandler<CMeshIOPlugin>::m_help =  
    "These plug-ins implement loading and saving of simple triangular meshes from and to various file formats.";
 
-template class TIOPlugin<CTriangleMesh>;
-template class TPluginHandler<CMeshIOPlugin>;
-template class TIOPluginHandler<CMeshIOPlugin>;
-template class THandlerSingleton<TIOPluginHandler<CMeshIOPlugin> >;
-
+template class EXPORT_MESH TPlugin<CTriangleMesh, io_plugin_type>; 
+template class EXPORT_MESH TIOPlugin<CTriangleMesh>;
+template class EXPORT_MESH TPluginHandler<CMeshIOPlugin>;
+template class EXPORT_MESH TIOPluginHandler<CMeshIOPlugin>;
+template class EXPORT_MESH THandlerSingleton<TIOPluginHandler<CMeshIOPlugin> >;
 
 
 NS_MIA_END
diff --git a/mia/mesh/triangularMesh.hh b/mia/mesh/triangularMesh.hh
index 6a430b3..0140e99 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 +226,10 @@ public:
 	 */
 	const color_type&       color_at(unsigned int i)const;
 
+
+	const CVertexfield& get_vertices() const;
+	const CTrianglefield& get_triangles() const; 
+
 	/// \cond SELFEXPLAINING 
 	const_triangle_iterator triangles_begin() const;
 	triangle_iterator       triangles_begin();
@@ -339,6 +343,9 @@ CTriangleMesh colorize_mesh(const CTriangleMesh& mesh, const Deformation& deform
 /// IO plugin for triangular meshes
 typedef TIOPlugin<CTriangleMesh> CMeshIOPlugin;
 
+extern template class EXPORT_MESH TPlugin<CTriangleMesh, io_plugin_type>; 
+extern template class EXPORT_MESH TIOPlugin<CTriangleMesh>; 
+
 /// Plug-in handler for triangulat mesh IO 
 typedef THandlerSingleton<TIOPluginHandler<CMeshIOPlugin> > CMeshIOPluginHandler;
 
diff --git a/mia/mesh/triangulate.hh b/mia/mesh/triangulate.hh
index 69fcbe3..774a0c9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cxx b/mia/template/bandpass.cxx
index 5a26405..52169b3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d807da2..be4854f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 231b6f3..557762d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 75103be..288b619 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 249edea..bab5bae 100644
--- a/mia/template/combiner.cxx
+++ b/mia/template/combiner.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/template/combiner.hh
index 9a1d6cc..4881248 100644
--- a/mia/template/combiner.hh
+++ b/mia/template/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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_filter.hh b/mia/template/combiner_filter.hh
index c09da0d..e86b4f1 100644
--- a/mia/template/combiner_filter.hh
+++ b/mia/template/combiner_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cxx b/mia/template/convert.cxx
index c3ca2cf..cf549e3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 29f7634..de4b256 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2e645d6..db4e96a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8b099c9..a10a40d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0486126..c289df8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 d8c0a22..f5c253f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 770a6d0..ab2abd0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 86077aa..9dafb7c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 688952c..6f795af 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 94cbe02..a35536d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 1f80af7..93a35f9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 0260629..256aa94 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/labelmap.cxx b/mia/template/labelmap.cxx
index afa2f3d..c35cd72 100644
--- a/mia/template/labelmap.cxx
+++ b/mia/template/labelmap.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/labelmap.hh b/mia/template/labelmap.hh
index 2edc2c8..437f23d 100644
--- a/mia/template/labelmap.hh
+++ b/mia/template/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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 143298e..e4cfde1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index a2c634f..bdfc4eb 100644
--- a/mia/template/masked_cost.cxx
+++ b/mia/template/masked_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/template/masked_cost.hh
index 7ea7ba6..697a501 100644
--- a/mia/template/masked_cost.hh
+++ b/mia/template/masked_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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/template/mi.hh
index 15ccd55..c29b76c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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
index 3c818f4..2919d72 100644
--- a/mia/template/mi_masked.cxx
+++ b/mia/template/mi_masked.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/template/mi_masked.hh
index c0e49d0..864d246 100644
--- a/mia/template/mi_masked.hh
+++ b/mia/template/mi_masked.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cxx b/mia/template/multicost.cxx
index 0905738..de2fceb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 2c30bcc..7dd7586 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 fa76e61..27214ba 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.hh b/mia/template/nonrigidregister.hh
index 790c542..2d3e3d3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 86f39a1..2e53b68 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 af75a50..6fa90af 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/similarity_profile.cxx b/mia/template/similarity_profile.cxx
index bad7573..79f31cc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,29 +49,6 @@ 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)
-{
-}
-
-template <int dim>
-TSimilarityProfile<dim>& TSimilarityProfile<dim>::operator = (const TSimilarityProfile<dim>& other)
-{
-	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; 
-	}
-	return *this; 
-}
-
-template <int dim>
 float TSimilarityProfile<dim>::get_peak_frequency() const
 {
 	if (!m_peak_freq_valid) {
@@ -101,10 +78,10 @@ std::vector<size_t> TSimilarityProfile<dim>::get_periodic_subset() const
 
 	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]) || (delta > m_max_delta))  {
+		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; 
 			delta = 0; 
@@ -118,10 +95,10 @@ std::vector<size_t> TSimilarityProfile<dim>::get_periodic_subset() const
 		
 	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]) || (delta > m_max_delta)) {
+		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; 
 			delta = 0; 
diff --git a/mia/template/similarity_profile.hh b/mia/template/similarity_profile.hh
index 3770608..dca578e 100644
--- a/mia/template/similarity_profile.hh
+++ b/mia/template/similarity_profile.hh
@@ -2,7 +2,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,10 +62,10 @@ public:
 			   size_t reference, size_t max_delta); 
 	
 	/// copy constructor 
-	TSimilarityProfile(const TSimilarityProfile<dim>& org); 
+	TSimilarityProfile(const TSimilarityProfile<dim>& org) = default; 
 	
 	/// assignment operator 
-	TSimilarityProfile<dim>& operator = (const TSimilarityProfile<dim>& org); 
+	TSimilarityProfile<dim>& operator = (const TSimilarityProfile<dim>& org)  = default; 
 
 	
 	/// \returns the peak frequency coefficent and its index
diff --git a/mia/template/ssd-automask.cxx b/mia/template/ssd-automask.cxx
index 3673d40..e7a3974 100644
--- a/mia/template/ssd-automask.cxx
+++ b/mia/template/ssd-automask.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,15 +22,13 @@
 #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 <mia/core/parallel.hh>
 
 #include <numeric>
 #include <limits>
 
 NS_BEGIN(NS)
 
-
 struct SRA {
 	size_t n; 
 	double sum;
@@ -47,34 +45,33 @@ struct FEvalSSDAuto : public mia::TFilter<double> {
 		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::preduce(mia::C1DParallelRange(0, a.size()), result_accumulator, 
+				[this, &a, &b](const mia::C1DParallelRange& 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; 
-
 }; 
 
 
diff --git a/mia/template/ssd-automask.hh b/mia/template/ssd-automask.hh
index 5129556..a3cb785 100644
--- a/mia/template/ssd-automask.hh
+++ b/mia/template/ssd-automask.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +22,7 @@
 #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 <mia/core/parallel.hh>
 
 #include <numeric>
 #include <limits>
diff --git a/mia/template/ssd.hh b/mia/template/ssd.hh
index 621a442..f944990 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ssd_masked.cxx b/mia/template/ssd_masked.cxx
index 11f130a..5212020 100644
--- a/mia/template/ssd_masked.cxx
+++ b/mia/template/ssd_masked.cxx
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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/ssd_masked.hh b/mia/template/ssd_masked.hh
index 350065e..1ae2dee 100644
--- a/mia/template/ssd_masked.hh
+++ b/mia/template/ssd_masked.hh
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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.cxx b/mia/template/trackpoint.cxx
index 611b079..587c42d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6279244..305f6be 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 326f6e7..b8ca43e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 8a74838..5ec4493 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; 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 6fbdbce..2b8c47b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -323,7 +323,7 @@ TWatershedFilterPlugin<dim>::TWatershedFilterPlugin():
 	this->add_parameter("n", make_param(m_neighborhood, "sphere:r=1", false, "Neighborhood for watershead region growing")); 
 	this->add_parameter("mark", new mia::CBoolParameter(m_with_borders, false, "Mark the segmented watersheds with a special gray scale value")); 
 	this->add_parameter("thresh", make_coi_param(m_thresh, 0, 1.0, false, "Relative gradient norm threshold. The actual value "
-						     "threshhold value is thresh * (max_grad - min_grad) + min_grad. Bassins "
+						     "threshold value is thresh * (max_grad - min_grad) + min_grad. Bassins "
 						     "separated by gradients with a lower norm will be joined"));  
 	this->add_parameter("evalgrad", new mia::CBoolParameter(m_eval_grad, false, "Set to 1 if the input image does "
 								"not represent a gradient norm image")); 
diff --git a/mia/test/testhelpers.hh b/mia/test/testhelpers.hh
index 59bd1f0..3920022 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/miaconfig.h.cmake b/miaconfig.h.cmake
index 79e6d73..599dfd5 100644
--- a/miaconfig.h.cmake
+++ b/miaconfig.h.cmake
@@ -11,4 +11,5 @@
 #define PLUGIN_SEARCH_PATH  "@PLUGIN_SEARCH_PATH@"
 #define PLUGIN_INSTALL_PATH  "@PLUGIN_INSTALL_PATH@"
 
-#cmakedefine LONG_64BIT 1 
+#cmakedefine LONG_64BIT 1
+#cmakedefine HAVE_TBB 1 
diff --git a/octave/miaoct.cc b/octave/miaoct.cc
index 56b4b50..94362e1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 d4297a9..ff4cf6c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dbinarycombine.cc b/src/2dbinarycombine.cc
index c4b6148..be1e0c8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dcost.cc b/src/2dcost.cc
index c820cf5..81cabdf 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 994e9cc..7710cd9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2ddistance.cc b/src/2ddistance.cc
index a3ba659..e0acfa8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2deval-transformquantity.cc b/src/2deval-transformquantity.cc
index 9e17ba4..b0f7c83 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "3deval-transformquantity"
-
 #include <fstream>
 #include <ostream>
 #include <cstring>
diff --git a/src/2dforce.cc b/src/2dforce.cc
index 4f760f7..c42a578 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dfuzzysegment.cc b/src/2dfuzzysegment.cc
index 8e161c3..89105f1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dgrayimage-combine-to-rgb.cc b/src/2dgrayimage-combine-to-rgb.cc
index a15ebfc..84d48b7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dgroundtruthreg.cc b/src/2dgroundtruthreg.cc
index 55462eb..3695512 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyocard"
 #include <iomanip>
 #include <ostream>
 #include <fstream>
@@ -166,7 +165,7 @@ int do_main( int argc, char *argv[] )
 	options.add(make_opt( pgt_params.beta, "beta", 'B', "temporal second derivative penalty weight", 
 				    CCmdOptionFlags::required));
 	options.add(make_opt( pgt_params.rho_thresh, "rho_thresh", 'R', 
-				    "crorrelation threshhold for neighborhood analysis", CCmdOptionFlags::required));
+				    "correlation threshold for neighborhood analysis", CCmdOptionFlags::required));
 
 
 	
diff --git a/src/2dimagecombine-dice.cc b/src/2dimagecombine-dice.cc
index 21520e7..54fd397 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dimagecombiner.cc b/src/2dimagecombiner.cc
index 04a3118..68ce7bd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dimagecreator.cc b/src/2dimagecreator.cc
index ddec5e6..ef083d3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dimagefilter.cc b/src/2dimagefilter.cc
index 4b713a4..f8c75be 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dimagefilterstack.cc b/src/2dimagefilterstack.cc
index 0427a73..64a2188 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dimagefullstats.cc b/src/2dimagefullstats.cc
index ae031f6..dff210a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dimageregistration.cc b/src/2dimageregistration.cc
index a67fca4..4636ad7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dimageselect.cc b/src/2dimageselect.cc
index 61cfe0f..31293f9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dimageseries-maximum-intensity-projection.cc b/src/2dimageseries-maximum-intensity-projection.cc
index 709d8df..d8f37e3 100644
--- a/src/2dimageseries-maximum-intensity-projection.cc
+++ b/src/2dimageseries-maximum-intensity-projection.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dimagestack-cmeans.cc b/src/2dimagestack-cmeans.cc
index 08b1749..c1387ff 100644
--- a/src/2dimagestack-cmeans.cc
+++ b/src/2dimagestack-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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,127 +48,6 @@ const SProgramDescription g_description = {
 	{pdi_example_code, "-i image0000.png -o cmeans,txt --histogram-tresh=5 --classes 3"}
 }; 
 
-class CFullHistogram : public TFilter<size_t> {
-        
-public: 
-        CFullHistogram();
-
-        template <typename T>
-        size_t operator ()(const T2DImage<T>& image); 
-
-        vector<pair<int, unsigned long>> get_compressed_histogram()const; 
- 
-	
-private: 
-        
-        vector<unsigned long> m_histogram; 
-
-        int m_shift; 
-        EPixelType m_pixeltype; 
-
-        
-        
-}; 
-
-template <typename T> 
-struct dispatch_by_pixeltype {
-        static void apply(const T2DImage<T>& MIA_PARAM_UNUSED(image), vector<unsigned long>& MIA_PARAM_UNUSED(histogram)){
-                throw invalid_argument("Input pixel type not supported"); 
-        }
-}; 
-
-template <> 
-struct dispatch_by_pixeltype<unsigned char> {
-        static void apply(const C2DUBImage& image, vector<unsigned long>& histogram){
-                for (auto p: image) {
-                        ++histogram[p]; 
-                }
-        }
-}; 
-
-template <> 
-struct dispatch_by_pixeltype<unsigned short> {
-        static void apply(const C2DUSImage& image, vector<unsigned long>& histogram){
-                for (auto p: image) {
-                        ++histogram[p]; 
-                }
-        }
-}; 
-
-template <> 
-struct dispatch_by_pixeltype<signed char> {
-        static void apply(const C2DSBImage& image, vector<unsigned long>& histogram){
-		int shift = -numeric_limits<signed char>::min(); 
-                for (auto p: image) {
-                        ++histogram[shift + p]; 
-                }
-        }
-}; 
-
-template <> 
-struct dispatch_by_pixeltype<signed short> {
-        static void apply(const C2DSSImage& image, vector<unsigned long>& histogram){
-                int shift = -numeric_limits<signed short>::min(); 
-                for (auto p: image) {
-                        ++histogram[shift + p]; 
-                }
-        }
-}; 
-
-CFullHistogram::CFullHistogram():
-        m_shift(0), 
-        m_pixeltype(it_none)
-{
-}
-
-template <typename T>
-size_t CFullHistogram::operator ()(const T2DImage<T>& image)
-{
-        if (m_pixeltype ==it_none) {
-                m_pixeltype = image.get_pixel_type();
-		m_shift = -numeric_limits<T>::min(); 
-                switch (m_pixeltype) {
-                case it_sbyte:
-                case it_ubyte:
-                        m_histogram.resize(256);
-                        break; 
-                case it_sshort:
-                case it_ushort:
-                        m_histogram.resize(65536);
-                        break; 
-                default:
-                        throw create_exception<invalid_argument>("Input pixel type '", CPixelTypeDict.get_name(m_pixeltype),
-                                                                 "' not supported."); 
-                }
-                        
-        } else if (m_pixeltype != image.get_pixel_type()){
-                throw create_exception<invalid_argument>("Input pixels not of consisted type, started with ",
-                                                         CPixelTypeDict.get_name(m_pixeltype), ", but got now ",
-                                                         CPixelTypeDict.get_name(image.get_pixel_type())); 
-        }
-
-        dispatch_by_pixeltype<T>::apply(image, m_histogram);
-
-        return image.size(); 
-}
-
-vector<pair<int, unsigned long>> CFullHistogram::get_compressed_histogram()const
-{
-
-        int nonzero_bins = 0;
-        for (auto b: m_histogram) {
-                if (b > 0)
-                        ++nonzero_bins; 
-        }
-
-        vector<pair<int, unsigned long>> result;
-        result.reserve(nonzero_bins);
-        for (unsigned i = 0; i < m_histogram.size(); ++i) {
-                if (m_histogram[i] != 0)
-                        result.push_back(make_pair(i - m_shift, m_histogram[i])); 
-        }
-        return result; 
-}
 
 
 int do_main( int argc, char *argv[] )
@@ -215,7 +94,7 @@ int do_main( int argc, char *argv[] )
 		throw invalid_argument(string("no files match pattern ") + src_basename);
 
 
-        CFullHistogram histo;
+        CSparseHistogram histo;
         size_t n_pixels = 0; 
         for (size_t i = start_filenum; i < end_filenum; ++i) {
                 string src_name = create_filename(src_basename.c_str(), i);
@@ -246,11 +125,11 @@ int do_main( int argc, char *argv[] )
                 --ie;
         }
 
-        vector<pair<int, unsigned long>> threshed_histo(ii, ie);
+	CSparseHistogram::Compressed threshed_histo(ii, ie);
 
 	CMeans::DVector class_centers; 
 	
-	CMeans cmeans(0.01, 0.00001, class_center_initializer);
+	CMeans cmeans(0.00001, class_center_initializer);
 	CMeans::SparseProbmap pv = cmeans.run(threshed_histo,  class_centers);
 
 	pv.save(out_probmap); 
diff --git a/src/2dimagestats.cc b/src/2dimagestats.cc
index 349adea..31ed608 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dlerp.cc b/src/2dlerp.cc
index 7e58b34..3c62f86 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dmany2one-nonrigid.cc b/src/2dmany2one-nonrigid.cc
index 236fc0a..ba76ef6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmany3one"
-
 #include <fstream>
 #include <libxml++/libxml++.h>
 #include <itpp/signal/fastica.h>
@@ -35,10 +33,7 @@
 #include <mia/2d/imageio.hh>
 #include <mia/internal/main.hh>
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-
-using namespace tbb;
+#include <mia/core/parallel.hh>
 using namespace std;
 using namespace mia;
 
@@ -101,7 +96,7 @@ struct SeriesRegistration {
 		reference(_reference)
 		{
 		}
-	void operator()( const blocked_range<int>& range ) const {
+	void operator()( const C1DParallelRange& range ) const {
 		CThreadMsgStream thread_stream;
 		TRACE_FUNCTION; 
 		auto m =  CMinimizerPluginHandler::instance().produce(minimizer);
@@ -189,7 +184,7 @@ int do_main( int argc, char *argv[] )
 	SeriesRegistration sreg(*input_images, minimizer, cost_functions, 
 				mg_levels, transform_creator, reference); 
 
-	parallel_for(blocked_range<int>( 0, input_images->size()), sreg);
+	pfor(C1DParallelRange( 0, input_images->size()), sreg);
 
 	bool success = true; 
 	auto ii = input_images->begin(); 
diff --git a/src/2dmulti-force.cc b/src/2dmulti-force.cc
index a8f3cd6..20fb2e4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dmulti-nrreg.cc b/src/2dmulti-nrreg.cc
index 6059995..6c7fdcd 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dmultiimageregistration.cc b/src/2dmultiimageregistration.cc
index 0cd7325..7b53718 100644
--- a/src/2dmultiimageregistration.cc
+++ b/src/2dmultiimageregistration.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 91a09d1..2e7ec08 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dmultiimagevar.cc b/src/2dmultiimagevar.cc
index 9dab501..9e3235a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dmyocard-ica.cc b/src/2dmyocard-ica.cc
index 54e66a0..6b98899 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyocard"
 #include <iomanip>
 #include <ostream>
 #include <fstream>
@@ -31,6 +30,7 @@
 
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
+#include <mia/core/ica.hh>
 #include <mia/2d/ica.hh>
 #include <mia/core/slopeclassifier.hh>
 
@@ -57,11 +57,16 @@ const SProgramDescription g_description = {
 	{pdi_example_code, "-i imageXXXX.exr -o ref -k 2 -C 5 -m -n"}
 }; 
 
+
+// this needs to be replaced by a parameter
+CICAAnalysisITPPFactory icatool;
+
 unique_ptr<C2DImageSeriesICA> get_ica(vector<C2DFImage>& series, bool strip_mean,
 				      size_t& components, bool ica_normalize, int max_iterations)
 {
 	srand(time(NULL));
-	unique_ptr<C2DImageSeriesICA> ica(new C2DImageSeriesICA(series, false));
+
+        unique_ptr<C2DImageSeriesICA> ica(new C2DImageSeriesICA(icatool, series, false));
 	if (components > 0) {
 		ica->set_max_iterations(max_iterations);
 		ica->run(components, strip_mean, ica_normalize);
@@ -70,7 +75,7 @@ unique_ptr<C2DImageSeriesICA> get_ica(vector<C2DFImage>& series, bool strip_mean
 		// highly correlated curves.
 		float min_cor = 0.0;
 		for (int i = 7; i > 3; --i) {
-			unique_ptr<C2DImageSeriesICA> l_ica(new C2DImageSeriesICA(series, false));
+            unique_ptr<C2DImageSeriesICA> l_ica(new C2DImageSeriesICA(icatool, series, false));
 			l_ica->set_max_iterations(max_iterations);
 			l_ica->run(i, strip_mean, ica_normalize);
 
@@ -88,14 +93,6 @@ unique_ptr<C2DImageSeriesICA> get_ica(vector<C2DFImage>& series, bool strip_mean
 	return ica;
 }
 
-
-unique_ptr<C2DImageSeriesICA> get_ica_auto(vector<C2DFImage>& series, size_t& max_components )
-{
-	unique_ptr<C2DImageSeriesICA> ica(new C2DImageSeriesICA(series, false));
-	max_components = ica->run_auto(max_components, 3, 0.7);
-	return ica;
-}
-
 void save_feature_image_unnamed(const string& base, int id, size_t max_comp,
 			const C2DImageSeriesICA& ica)
 {
@@ -357,7 +354,6 @@ int do_main( int argc, char *argv[] )
 	string feature_image_base;
 	string numbered_feature_image;
 	float LV_mask = 0.0; // no mask
-	bool auto_comp = false;
 	int max_iterations = 0;
 
 	const auto& imageio = C2DImageIOPluginHandler::instance();
@@ -387,10 +383,6 @@ int do_main( int argc, char *argv[] )
 
 	options.add(make_opt( LV_mask, "LV-crop-amp", 'L', "LV crop mask amplification, 0.0 = don't crop"));
 
-
-	options.add(make_opt( auto_comp, "auto-components", 'a',
-				    "automatic esitmation of number of components based on correlation."
-				    " Implies -m and -n (Experimental)"));
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
 
@@ -427,13 +419,12 @@ int do_main( int argc, char *argv[] )
 
 	cvmsg()<< "Got series of " << series.size() << " images\n";
 	// always strip mean
-	unique_ptr<C2DImageSeriesICA> ica = auto_comp ?
-		get_ica_auto(series, components ):
+	unique_ptr<C2DImageSeriesICA> ica = 
 		get_ica(series, strip_mean, components, ica_normalize, max_iterations);
 	CSlopeClassifier::Columns curves = ica->get_mixing_curves();
 
 	CICAAnalysis::IndexSet component_set = skip_only_periodic ?
-		get_all_without_periodic(curves, strip_mean || auto_comp):
+		get_all_without_periodic(curves, strip_mean):
 		get_LV_RV_Perfusion(curves);
 
 
@@ -547,7 +538,7 @@ int do_main( int argc, char *argv[] )
 		if ( cls.get_baseline_idx() >= 0) {
 			save_feature_image(feature_image_base, "baseline", cls.get_baseline_idx(), components, *ica);
 		}
-		if (strip_mean||auto_comp)
+		if (strip_mean)
 			save_feature_image(feature_image_base, "mean", -1, components, *ica);
 	}
 	if (!coefs_name.empty())
diff --git a/src/2dmyocard-icaseries.cc b/src/2dmyocard-icaseries.cc
index f344407..57dd3fe 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyocard"
 #include <iomanip>
 #include <ostream>
 #include <fstream>
@@ -33,6 +32,7 @@
 
 
 #include <mia/core.hh>
+#include <mia/core/ica.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 #include <mia/2d/ica.hh>
@@ -126,7 +126,10 @@ int do_main( int argc, char *argv[] )
 		ica.set_max_ica_iterations(max_ica_iterations); 
 	
 
-	if (!ica.run(series)) {
+    // this needs to be replaced by a parameter
+    CICAAnalysisITPPFactory icatool;
+
+    if (!ica.run(series, icatool)) {
 		// ICA + classifictaion failed, 
 		// save the mixing matrix if requested 
 		if (!save_crop_feature.empty()) 
diff --git a/src/2dmyocard-segment.cc b/src/2dmyocard-segment.cc
index ec57817..f25dd7a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyocard-segment"
 #include <iomanip>
 #include <ostream>
 #include <fstream>
@@ -34,6 +33,7 @@
 #include <mia/core.hh>
 #include <mia/core/meanvar.hh>
 #include <mia/core/tools.hh>
+#include <mia/core/ica.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 #include <mia/2d/ica.hh>
@@ -43,6 +43,8 @@
 #include <mia/2d/transformfactory.hh>
 #include <mia/2d/datafield.cxx>
 
+#include <numeric> 
+
 NS_MIA_USE;
 using namespace std; 
 
@@ -465,10 +467,10 @@ int do_main( int argc, char *argv[] )
 		if (max_ica_iterations) 
 			ica->set_max_ica_iterations(max_ica_iterations); 
 		
-		
-		if (!ica->run(series)) {
-			ica->set_approach(FICA_APPROACH_SYMM); 
-			ica->run(series); 
+        CICAAnalysisITPPFactory icaatool;
+        if (!ica->run(series, icaatool)) {
+            ica->set_approach(CICAAnalysis::appr_symm);
+            ica->run(series, icaatool);
 		}
 		
 		rv_idx = ica->get_RV_idx(); 
diff --git a/src/2dmyocard-upsloap.cc b/src/2dmyocard-upsloap.cc
index 9092126..6c51e98 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@
  */
 
 
-#define VSTREAM_DOMAIN "2dmyocard"
 #include <iomanip>
 #include <ostream>
 #include <fstream>
diff --git a/src/2dmyoica-full.cc b/src/2dmyoica-full.cc
index 7237527..ed8376f 100644
--- a/src/2dmyoica-full.cc
+++ b/src/2dmyoica-full.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyoica-full"
-
 #include <fstream>
 #include <itpp/signal/fastica.h>
 
@@ -28,6 +26,7 @@
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/errormacro.hh>
 #include <mia/core/minimizer.hh>
+#include <mia/core/ica.hh>
 #include <mia/core/attribute_names.hh>
 #include <mia/2d/nonrigidregister.hh>
 #include <mia/2d/perfusion.hh>
@@ -38,10 +37,7 @@
 #include <boost/filesystem/path.hpp>
 
 #include <libxml++/libxml++.h> 
-#include <tbb/parallel_for.h>
-#include <tbb/parallel_reduce.h>
-#include <tbb/blocked_range.h>
-using namespace tbb;
+#include <mia/core/parallel.hh>
 
 using namespace std;
 using namespace mia;
@@ -153,7 +149,7 @@ struct SeriesRegistration {
                 global_reference(_global_reference)
 		{
 		}
-	P2DTransformation operator()( const blocked_range<int>& range, P2DTransformation init) const {
+	P2DTransformation operator()( const C1DParallelRange& range, P2DTransformation init) const {
 		CThreadMsgStream thread_stream;
 		TRACE_FUNCTION; 
                 P2DTransformation result = init; 
@@ -191,46 +187,48 @@ void run_registration_pass(CSegSetWithImages& input_set,
 				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; 
-                                                       });
-
+	P2DTransformation inv_transf = preduce(C1DParallelRange( 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);
-                                             }
-                                     }
-                             });
+                pfor(C1DParallelRange( 0, references.size()), 
+		     [&inv_transf_ref, &frames, skip_images, global_reference, &input_images](const C1DParallelRange& 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 components, bool normalize, bool no_meanstrip, int max_ica_iterations, 
-					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, float min_rel_frequency)
+                                        C2DImageSeries& references,
+                                        int components, bool normalize, bool no_meanstrip, int max_ica_iterations,
+                                        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, float min_rel_frequency,
+                                        const CICAAnalysisFactory& icatool)
 {
-        int current_pass = 0; 
-	bool do_continue=true; 
-	bool lastpass = false; 
-	vector<C2DFImage> references_float; 
-	do {
-		++current_pass; 
+    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); 
@@ -246,16 +244,16 @@ void run_nonlinear_registration_passes (CSegSetWithImages& input_set,
 		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); 
+        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()); 
+        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 (!ica2.run(series, icatool)) {
+            ica2.set_approach(CICAAnalysis::appr_symm);
+            ica2.run(series, icatool);
 		}
 		
 		divcurlweight /= divcurlweight_divider; 
@@ -279,7 +277,7 @@ void run_linear_registration_passes (CSegSetWithImages& input_set,
                                      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)
+                                     float min_rel_frequency, const CICAAnalysisFactory& icatool)
 {
         int current_pass = 0; 
 	bool do_continue=true; 
@@ -310,9 +308,9 @@ void run_linear_registration_passes (CSegSetWithImages& input_set,
 		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 (!ica2.run(series, icatool)) {
+            ica2.set_approach(CICAAnalysis::appr_symm);
+            ica2.run(series, icatool);
 		}
 		
 		references_float = ica2.get_references(); 
@@ -453,26 +451,26 @@ int do_main( int argc, char *argv[] )
                              "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',
+    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"));
@@ -506,37 +504,38 @@ int do_main( int argc, char *argv[] )
 	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(); 
+    // copy the original image if the global reference it set, because in this case we
+    // want the original sized data as result
 
-        
-        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.  
+    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()); 
-	
+    transform(input_images.begin() + skip_images, input_images.end(),
+              series.begin(), FCopy2DImageToFloatRepn());
+
 
-	// run ICA
-	unique_ptr<C2DPerfusionAnalysis> ica(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
+    // run ICA
+    unique_ptr<C2DPerfusionAnalysis> ica(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip));
 	if (max_ica_iterations) 
-		ica->set_max_ica_iterations(max_ica_iterations); 
+        ica->set_max_ica_iterations(max_ica_iterations);
 
-	if (rel_min_bf >= 0) 
+    if (rel_min_bf >= 0)
 		ica->set_min_movement_frequency(rel_min_bf); 
 
 
-	ica->set_approach(FICA_APPROACH_DEFL); 
-	if (!ica->run(series)) {
+    CICAAnalysisITPPFactory icatool;
+    ica->set_approach(CICAAnalysis::appr_defl);
+    if (!ica->run(series, icatool)) {
 		ica.reset(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
-		ica->set_approach(FICA_APPROACH_SYMM); 
-		if (!ica->run(series)) 
+        ica->set_approach(CICAAnalysis::appr_symm);
+        if (!ica->run(series, icatool))
 			box_scale = false; 
 	}		
 
@@ -592,7 +591,7 @@ int do_main( int argc, char *argv[] )
                 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); 
+                                                mg_levels, max_linear_passes, imagecost, global_reference, rel_min_bf, icatool);
 
         if (max_nonlinear_passes > 0) {
 		// if we come from the linear registration, then the references must be re-generated
@@ -608,9 +607,9 @@ int do_main( int argc, char *argv[] )
 			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 (!ica2.run(series, icatool)) {
+                ica2.set_approach(CICAAnalysis::appr_symm);
+                ica2.run(series, icatool);
 			}
 			
 			references_float = ica2.get_references(); 
@@ -623,7 +622,7 @@ int do_main( int argc, char *argv[] )
                                                    skip_images,  nonlinear_minimizer, 
                                                    mg_levels, c_rate, c_rate_divider, 
                                                    divcurlweight, divcurlweight_divider, 
-                                                   max_nonlinear_passes, imagecost, global_reference, rel_min_bf); 
+                                                   max_nonlinear_passes, imagecost, global_reference, rel_min_bf, icatool);
 	}
 	cvmsg() << "Registration finished\n"; 
 
diff --git a/src/2dmyoica-nonrigid-parallel.cc b/src/2dmyoica-nonrigid-parallel.cc
index ed49328..0475779 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyoica"
-
 #include <fstream>
 #include <libxml++/libxml++.h>
 #include <itpp/signal/fastica.h>
@@ -36,12 +34,11 @@
 #include <mia/2d/imageio.hh>
 #include <mia/2d/segsetwithimages.hh>
 #include <mia/2d/transformfactory.hh>
+#include <mia/core/ica.hh>
 
 #include <boost/filesystem.hpp>
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-using namespace tbb;
+#include <mia/core/parallel.hh>
 
 using namespace std;
 using namespace mia;
@@ -149,7 +146,7 @@ struct SeriesRegistration {
 		skip_images(_skip_images)
 		{
 		}
-	void operator()( const blocked_range<int>& range ) const {
+	void operator()( const C1DParallelRange& range ) const {
 		CThreadMsgStream thread_stream;
 		TRACE_FUNCTION; 
 
@@ -176,7 +173,7 @@ void run_registration_pass(CSegSetWithImages& input_set,
 	SeriesRegistration sreg(input_images, frames, references, minimizer, 
 				mg_levels, create_transform_creator(c_rate, divcurlweight), 
 				imagecost, skip_images); 
-	parallel_for(blocked_range<int>( 0, references.size()), sreg);
+	pfor(C1DParallelRange( 0, references.size()), sreg);
 	input_set.set_images(input_images);
 }
 
@@ -346,12 +343,12 @@ int do_main( int argc, char *argv[] )
 	if (rel_min_bf > 0) 
 		ica->set_min_movement_frequency(rel_min_bf); 
 
-
-	ica->set_approach(FICA_APPROACH_DEFL); 
-	if (!ica->run(series)) {
+    CICAAnalysisITPPFactory icatool;
+    ica->set_approach(CICAAnalysis::appr_defl);
+    if (!ica->run(series, icatool)) {
 		ica.reset(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
-		ica->set_approach(FICA_APPROACH_SYMM); 
-		if (!ica->run(series)) 
+        ica->set_approach(CICAAnalysis::appr_symm);
+        if (!ica->run(series, icatool))
 			box_scale = false; 
 
 	}		
@@ -425,9 +422,9 @@ int do_main( int argc, char *argv[] )
 		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 (!ica2.run(series, icatool)) {
+            ica2.set_approach(CICAAnalysis::appr_symm);
+            ica2.run(series, icatool);
 		}
 		if (lastpass) 
 			break; 
@@ -453,9 +450,9 @@ int do_main( int argc, char *argv[] )
 	transform(input_set.get_images().begin() + skip_images, 
 		  input_set.get_images().end(), series.begin(), FCopy2DImageToFloatRepn()); 
 	
-	if (!ica_final.run(series)) {
-			ica_final.set_approach(FICA_APPROACH_SYMM); 
-			ica_final.run(series); 
+    if (!ica_final.run(series, icatool)) {
+            ica_final.set_approach(CICAAnalysis::appr_symm);
+            ica_final.run(series, icatool);
 	}
 
 	if (!save_crop_feature.empty()) {
diff --git a/src/2dmyoica-nonrigid.cc b/src/2dmyoica-nonrigid.cc
index 3efa899..0c9fc55 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyoica"
-
 #include <fstream>
 #include <libxml++/libxml++.h>
 #include <itpp/signal/fastica.h>
@@ -30,6 +28,7 @@
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/errormacro.hh>
 #include <mia/core/minimizer.hh>
+#include <mia/core/ica.hh>
 #include <mia/core/attribute_names.hh>
 #include <mia/2d/nonrigidregister.hh>
 #include <mia/2d/perfusion.hh>
@@ -298,11 +297,12 @@ int do_main( int argc, char *argv[] )
 	if (rel_min_bf > 0) 
 		ica->set_min_movement_frequency(rel_min_bf); 
 
-	ica->set_approach(FICA_APPROACH_DEFL); 
-	if (!ica->run(series)) {
+    CICAAnalysisITPPFactory icatool;
+    ica->set_approach(CICAAnalysis::appr_defl);
+    if (!ica->run(series, icatool)) {
 		ica.reset(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
-		ica->set_approach(FICA_APPROACH_SYMM); 
-		if (!ica->run(series)) 
+        ica->set_approach(CICAAnalysis::appr_symm);
+        if (!ica->run(series, icatool))
 			box_scale = false; 
 	}
 	
@@ -361,9 +361,9 @@ int do_main( int argc, char *argv[] )
 		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 (!ica2.run(series, icatool)) {
+            ica2.set_approach(CICAAnalysis::appr_symm);
+            ica2.run(series, icatool);
 		}
 		if (lastpass) 
 			break; 
@@ -390,9 +390,9 @@ int do_main( int argc, char *argv[] )
 	transform(input_set.get_images().begin() + skip_images, 
 		  input_set.get_images().end(), series.begin(), FCopy2DImageToFloatRepn()); 
 	
-	if (!ica_final.run(series)) {
-			ica_final.set_approach(FICA_APPROACH_SYMM); 
-			ica_final.run(series); 
+    if (!ica_final.run(series, icatool)) {
+            ica_final.set_approach(CICAAnalysis::appr_symm);
+            ica_final.run(series, icatool);
 	}
 	if( input_set.get_RV_peak() < 0) 
 		input_set.set_RV_peak(ica_final.get_RV_peak_time() + skip_images); 
diff --git a/src/2dmyoica-nonrigid2.cc b/src/2dmyoica-nonrigid2.cc
index 5c341ea..0923ab3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyoica"
-
 #include <fstream>
 #include <libxml++/libxml++.h>
 #include <itpp/signal/fastica.h>
@@ -29,6 +27,7 @@
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/errormacro.hh>
 #include <mia/core/minimizer.hh>
+#include <mia/core/ica.hh>
 #include <mia/2d/nonrigidregister.hh>
 #include <mia/2d/perfusion.hh>
 #include <mia/2d/segsetwithimages.hh>
@@ -241,11 +240,12 @@ int do_main( int argc, char *argv[] )
 	if (max_ica_iterations) 
 		ica->set_max_ica_iterations(max_ica_iterations); 
 
-	ica->set_approach(FICA_APPROACH_DEFL); 
-	if (!ica->run(series)) {
+    CICAAnalysisITPPFactory icatool;
+    ica->set_approach(CICAAnalysis::appr_defl);
+    if (!ica->run(series, icatool)) {
 		ica.reset(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
-		ica->set_approach(FICA_APPROACH_SYMM); 
-		if (!ica->run(series)) 
+        ica->set_approach(CICAAnalysis::appr_symm);
+        if (!ica->run(series, icatool))
 			box_scale = false; 
 	}
 
@@ -299,10 +299,10 @@ int do_main( int argc, char *argv[] )
 		transform(registered.begin() + skip_images, 
 			  registered.end(), series.begin(), FCopy2DImageToFloatRepn()); 
 
-		if (!ica2.run(series))
-			ica2.set_approach(FICA_APPROACH_SYMM); 
+        if (!ica2.run(series, icatool))
+            ica2.set_approach(CICAAnalysis::appr_symm);
 
-		ica2.run(series); 
+        ica2.run(series, icatool);
 		divcurlweight /= divcurlweight_divider; 
 		if (c_rate > 1) 
 			c_rate /= c_rate_divider; 
diff --git a/src/2dmyoicapgt.cc b/src/2dmyoicapgt.cc
index 56aadec..40f8ede 100644
--- a/src/2dmyoicapgt.cc
+++ b/src/2dmyoicapgt.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyoica-pgt"
-
 #include <fstream>
 #include <itpp/signal/fastica.h>
 
@@ -28,6 +26,7 @@
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/errormacro.hh>
 #include <mia/core/minimizer.hh>
+#include <mia/core/ica.hh>
 #include <mia/core/attribute_names.hh>
 #include <mia/2d/nonrigidregister.hh>
 #include <mia/2d/perfusion.hh>
@@ -38,10 +37,7 @@
 #include <libxml++/libxml++.h> 
 #include <boost/filesystem/path.hpp>
 
-#include <tbb/parallel_for.h>
-#include <tbb/parallel_reduce.h>
-#include <tbb/blocked_range.h>
-using namespace tbb;
+#include <mia/core/parallel.hh>
 
 using namespace std;
 using namespace mia;
@@ -158,7 +154,7 @@ struct SeriesRegistration {
                 global_reference(_global_reference)
 		{
 		}
-	P2DTransformation operator()( const blocked_range<int>& range, P2DTransformation init) const {
+	P2DTransformation operator()( const C1DParallelRange& range, P2DTransformation init) const {
 		CThreadMsgStream thread_stream;
 		TRACE_FUNCTION; 
                 P2DTransformation result = init; 
@@ -195,26 +191,26 @@ void run_registration_pass(CSegSetWithImages& input_set,
 				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; 
-                                                       });
-
+	P2DTransformation inv_transf = preduce(C1DParallelRange( 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);
-                                             }
-                                     }
-                             });
+                pfor(C1DParallelRange( 0, references.size()), 
+		     [&inv_transf_ref, &frames, skip_images, global_reference, &input_images](const C1DParallelRange& 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);
 }
@@ -255,10 +251,10 @@ void run_linear_registration_passes (CSegSetWithImages& input_set,
                                      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)
+                                     float min_rel_frequency, const CICAAnalysisITPPFactory& icatool)
 {
-        int current_pass = 0; 
-	bool do_continue=true; 
+    int current_pass = 0;
+    bool do_continue=true;
 	bool lastpass = false; 
 	vector<C2DFImage> references_float; 
 	do {
@@ -282,9 +278,9 @@ void run_linear_registration_passes (CSegSetWithImages& input_set,
 		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 (!ica2.run(series, icatool)) {
+            ica2.set_approach(CICAAnalysis::appr_symm);
+            ica2.run(series, icatool);
 		}
 		if (lastpass) 
 			break; 
@@ -384,7 +380,8 @@ int do_main( int argc, char *argv[] )
 	size_t skip_images = 0; 
 	size_t max_ica_iterations = 400; 
 	C2DPerfusionAnalysis::EBoxSegmentation 
-		segmethod=C2DPerfusionAnalysis::bs_features; 
+            segmethod=C2DPerfusionAnalysis::bs_features;
+    CICAAnalysisITPPFactory icatool;
 
 	float min_breathing_frequency = -1.0f; 
 
@@ -431,10 +428,10 @@ int do_main( int argc, char *argv[] )
                              "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', 
+    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, 
@@ -480,7 +477,7 @@ int do_main( int argc, char *argv[] )
 	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"));
+				    "correlation threshold for neighborhood analysis"));
 
 	
 		
@@ -518,11 +515,11 @@ int do_main( int argc, char *argv[] )
 		ica->set_min_movement_frequency(rel_min_bf); 
 
 
-	ica->set_approach(FICA_APPROACH_DEFL); 
-	if (!ica->run(series)) {
+    ica->set_approach(CICAAnalysis::appr_defl);
+    if (!ica->run(series, icatool)) {
 		ica.reset(new C2DPerfusionAnalysis(components, normalize, !no_meanstrip)); 
-		ica->set_approach(FICA_APPROACH_SYMM); 
-		if (!ica->run(series)) 
+        ica->set_approach(CICAAnalysis::appr_symm);
+        if (!ica->run(series, icatool))
 			box_scale = false; 
 	}		
 
@@ -578,7 +575,7 @@ int do_main( int argc, char *argv[] )
                 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); 
+                                                mg_levels, max_linear_passes, imagecost, global_reference, rel_min_bf, icatool);
 
         if (max_nonlinear_passes > 0) 
                 run_nonlinear_registration_passes (input_set,  pgt_alpha, pgt_beta, pgt_rho_thresh,
diff --git a/src/2dmyomilles.cc b/src/2dmyomilles.cc
index be9c64e..ac82447 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmilles"
-
 #include <fstream>
 #include <libxml++/libxml++.h>
 #include <boost/filesystem.hpp>
@@ -30,6 +28,7 @@
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/errormacro.hh>
 #include <mia/core/minimizer.hh>
+#include <mia/core/ica.hh>
 #include <mia/2d/rigidregister.hh>
 #include <mia/2d/perfusion.hh>
 #include <mia/2d/imageio.hh>
@@ -214,9 +213,11 @@ int do_main( int argc, char *argv[] )
 		ica.set_max_ica_iterations(max_ica_iterations); 
 	if (use_guess_model) 
 		ica.set_use_guess_model(); 
-	if (!ica.run(series)) {
-		ica.set_approach(FICA_APPROACH_SYMM); 
-		if (!ica.run(series) )
+
+    CICAAnalysisITPPFactory icatool;
+    if (!ica.run(series, icatool)) {
+        ica.set_approach(CICAAnalysis::appr_symm);
+        if (!ica.run(series, icatool) )
 			cvwarn() << "ICA analysis didn't converge, results might by bougus\n";
 	}
 
@@ -300,9 +301,9 @@ int do_main( int argc, char *argv[] )
 	
 		transform(input_images.begin() + skip_images, 
 			  input_images.end(), series.begin(), FCopy2DImageToFloatRepn()); 
-		if (!ica2.run(series))
-			ica2.set_approach(FICA_APPROACH_SYMM); 
-		if (ica2.run(series) ) {
+        if (!ica2.run(series, icatool))
+            ica2.set_approach(CICAAnalysis::appr_symm);
+        if (ica2.run(series, icatool) ) {
 			references_float = ica2.get_references(); 
 
 			transform(references_float.begin(), references_float.end(), 
diff --git a/src/2dmyoperiodic-nonrigid.cc b/src/2dmyoperiodic-nonrigid.cc
index 8a3668e..c44bec9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyoperiodic"
-
 #include <fstream>
 #include <sstream>
 #include <iomanip>
diff --git a/src/2dmyopgt-nonrigid.cc b/src/2dmyopgt-nonrigid.cc
index ab47cc2..212eafc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyopgt"
 #include <iomanip>
 #include <ostream>
 #include <fstream>
@@ -147,7 +146,7 @@ int do_main( int argc, char *argv[] )
 	options.add(make_opt( alpha, "alpha", 'A', "spacial neighborhood penalty weight"));
 	options.add(make_opt( beta, "beta", 'B', "temporal second derivative penalty weight"));
 	options.add(make_opt( rho_thresh, "rho-thresh", 'R', 
-				    "crorrelation threshhold for neighborhood analysis"));
+				    "correlation threshold for neighborhood analysis"));
 	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")); 
 	
diff --git a/src/2dmyoserial-nonrigid.cc b/src/2dmyoserial-nonrigid.cc
index c07c9c9..6cfb0bc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyoserial"
-
 #include <fstream>
 #include <libxml++/libxml++.h>
 #include <itpp/signal/fastica.h>
diff --git a/src/2dmyoseries-compdice.cc b/src/2dmyoseries-compdice.cc
index c609856..80a180b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@
  */
 
 
-#define VSTREAM_DOMAIN "2dmyoseries-dice"
-
 #include <libxml++/libxml++.h>
 #include <mia/core/msgstream.hh>
 #include <mia/internal/main.hh>
diff --git a/src/2dmyoseries-dice.cc b/src/2dmyoseries-dice.cc
index 0e9101d..453d9c2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyoseries-dice"
-
 #include <libxml++/libxml++.h>
 #include <mia/core/msgstream.hh>
 #include <mia/core/cmdlineparser.hh>
diff --git a/src/2dmyoset-all2one-nonrigid.cc b/src/2dmyoset-all2one-nonrigid.cc
index 6cc1f5e..f72f906 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dall2one"
-
 #include <fstream>
 #include <libxml++/libxml++.h>
 #include <boost/filesystem.hpp>
@@ -34,10 +32,8 @@
 #include <mia/2d/segsetwithimages.hh>
 
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
 
-using namespace tbb;
 using namespace std;
 using namespace mia;
 
@@ -99,7 +95,7 @@ struct SeriesRegistration {
 		reference(_reference)
 		{
 		}
-	void operator()( const blocked_range<int>& range ) const {
+	void operator()( const C1DParallelRange& range ) const {
 		CThreadMsgStream thread_stream;
 		TRACE_FUNCTION; 
 		auto m =  CMinimizerPluginHandler::instance().produce(minimizer);
@@ -183,7 +179,7 @@ int do_main( int argc, char *argv[] )
 	SeriesRegistration sreg(input_set, input_images, minimizer, cost_functions, 
 				mg_levels, transform_creator, reference); 
 	
-	parallel_for(blocked_range<int>( skip, input_images.size()), sreg);
+	pfor(C1DParallelRange( skip, input_images.size()), sreg);
 	
 	
 	input_set.set_images(input_images); 									  
diff --git a/src/2dnrreg.cc b/src/2dnrreg.cc
index 175817f..18a6608 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 6ce21e2..7821a48 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dseghausdorff.cc b/src/2dseghausdorff.cc
index 9b32100..5ab1709 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dsegment-ahmed.cc b/src/2dsegment-ahmed.cc
index 910a09a..a13df15 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +161,8 @@ template <class T>
 CSegment2d::result_type CSegment2d::operator()(const T2DImage<T>& image)
 {
 	// first evaluate the histogram borders and get the initial class centers
-	T minh=0; 
-	T maxh=numeric_limits<T>::max(); 
+	typename T2DImage<T>::value_type minh=0; 
+	typename T2DImage<T>::value_type maxh=numeric_limits<T>::max(); 
 	
 
 	get_min_max(image.begin(), image.end(), minh, maxh);  
diff --git a/src/2dsegment-fuzzyw.cc b/src/2dsegment-fuzzyw.cc
index 243973c..fe20777 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 <memory>
 #include <vector>
+#include <numeric>
 
 using namespace mia;
 using namespace std; 
diff --git a/src/2dsegment-local-cmeans.cc b/src/2dsegment-local-cmeans.cc
new file mode 100644
index 0000000..a8a3cb4
--- /dev/null
+++ b/src/2dsegment-local-cmeans.cc
@@ -0,0 +1,438 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/core/histogram.hh>
+#include <mia/core/cmdlineparser.hh>
+#include <mia/core/cmeans.hh>
+#include <mia/2d.hh>
+
+#include <memory>
+#include <vector>
+#include <numeric>
+
+using namespace mia;
+using namespace std; 
+
+typedef vector<C2DFImage> C2DFImageVec;
+
+const SProgramDescription g_description = {
+        {pdi_group, "Analysis, filtering, combining, and segmentation of 2D images"}, 
+	{pdi_short, "Run a c-means segmentation of a 2D image."}, 
+	{pdi_description, "This program runs the segmentation of a 2D image by applying "
+	 "a localized c-means approach that helps to overcome intensity inhomogeneities "
+	 "in the image. The approach evaluates a global c-means clustering, and then "
+	 "separates the image into overlapping regions where more c-means iterations "
+	 "are run only including the locally present classes, i.e. the classes that "
+	 "relatively contain more pixels than a given threshhold."}, 
+	{pdi_example_descr, "Run the segmentation on image test.png using three classes, "
+	 "local regions of 40 pixels (grid width 20 pixels), and a class ignore threshhold of 0.01." }, 
+	{pdi_example_code, "-i test.png -o label.png -n 3 -g 20 -t 0.01"}
+}; 
+
+class FRunHistogram : public TFilter<void> {
+public: 
+	template <typename T> 
+	void operator()(const T2DImage<T>& image);
+
+	CSparseHistogram::Compressed get_histogram() const; 
+	
+private: 
+	CSparseHistogram m_sparse_histogram; 
+}; 
+
+class FLocalCMeans: public TFilter<void> {
+public: 
+	typedef map<int, CMeans::DVector> Probmap; 
+
+	
+	FLocalCMeans(float epsilon, const vector<double>& global_class_centers,
+		     const C2DBounds& start, const C2DBounds& end,
+		     const Probmap& global_probmap,
+		     float rel_cluster_threshold, 
+		     const map<int, unsigned>& segmap, 
+		     vector<C2DFDatafield>& prob_buffer);
+	
+	template <typename T> 
+	void operator()(const T2DImage<T>& image);
+private:
+
+	const float m_epsilon;
+	const vector<double>& m_global_class_centers;
+	const C2DBounds m_start;
+	const C2DBounds m_end;
+	const Probmap& m_global_probmap;
+	const float m_rel_cluster_threshold; 
+	const map<int, unsigned>& m_segmap;
+	vector<C2DFDatafield>& m_prob_buffer;
+	size_t m_count; 
+	
+}; 
+
+class FCrispSeg: public TFilter<P2DImage> {
+public:
+	FCrispSeg(const map<int, unsigned>& segmap):
+		m_segmap(segmap)
+		{
+		}
+
+	template <typename T> 
+	P2DImage operator()(const T2DImage<T>& image) const {
+		P2DImage out_image = make_shared<C2DUBImage>(image.get_size());
+		C2DUBImage *help = static_cast<C2DUBImage*>(out_image.get());
+		transform(image.begin(), image.end(), help->begin(),
+			  [this](T x){return m_segmap.at(x);}); 
+		return out_image; 
+	}
+private:
+	const map<int, unsigned>& m_segmap;
+}; 
+
+
+int do_main(int argc, char *argv[])
+{
+
+	string in_filename; 
+	string out_filename;
+	string out_filename2;
+	string cls_filename;
+	string debug_filename; 
+	
+        int blocksize = 15;
+	double rel_cluster_threshold = 0.02;
+
+	float cmeans_epsilon = 0.0001; 
+	
+	CMeans::PInitializer class_center_initializer; 
+		
+	const auto& image2dio = C2DImageIOPluginHandler::instance();
+
+	CCmdOptionList opts(g_description);
+        opts.set_group("File-IO"); 
+	opts.add(make_opt( in_filename, "in-file", 'i', "image to be segmented",
+			   CCmdOptionFlags::required_input, &image2dio )); 
+	opts.add(make_opt( out_filename, "out-file", 'o', "class label image based on "
+			   "merging local labels", CCmdOptionFlags::output, &image2dio ));
+
+	opts.add(make_opt( out_filename2, "out-global-crisp", 'G', "class label image based on "
+			   "global segmentation", CCmdOptionFlags::output, &image2dio ));
+	opts.add(make_opt( cls_filename, "class-prob", 'C', "class probability image file, filetype "
+			   "must support floating point multi-frame images", CCmdOptionFlags::output, &image2dio ));
+	
+        opts.set_group("Parameters"); 
+	opts.add(make_opt( blocksize, EParameterBounds::bf_min_closed, {3},
+			   "grid-spacing", 'g', "Spacing of the grid used to modulate "
+			   "the intensity inhomogeneities"));
+	opts.add(make_opt( class_center_initializer, "kmeans:nc=3",
+			   "cmeans", 'c', "c-means initializer"));
+	opts.add(make_opt( cmeans_epsilon, EParameterBounds::bf_min_open,
+			   {0.0}, "c-means-epsilon", 'e', "c-means breaking condition for update tolerance"));
+	opts.add(make_opt( rel_cluster_threshold, EParameterBounds::bf_min_closed | EParameterBounds::bf_max_open,
+			   {0.0,1.0}, "relative-cluster-threshhold", 't', "Number of intensity classes to segment")); 
+
+	
+	if (opts.parse(argc, argv) != CCmdOptionList::hr_no)
+		return EXIT_SUCCESS; 
+
+	if (out_filename.empty() && out_filename2.empty()) {
+		throw invalid_argument("You must specify at least one output file"); 
+	}
+	
+	auto in_image = load_image2d(in_filename);
+
+	FRunHistogram global_histogram; 
+
+	mia::accumulate(global_histogram, *in_image);
+	
+	CMeans globale_cmeans(cmeans_epsilon, class_center_initializer); 
+
+	auto gh = global_histogram.get_histogram();
+
+	CMeans::DVector global_class_centers;
+	auto global_sparse_probmap = globale_cmeans.run(gh, global_class_centers, false);
+
+	cvinfo() << "Histogram range: [" << gh[0].first << ", " << gh[gh.size()-1].first << "]\n"; 
+	cvinfo() << "Global class centers: " << global_class_centers << "\n";
+	cvinfo() << "Probmap size = " << global_sparse_probmap.size()
+		 << " weight number " << global_sparse_probmap[0].second.size() << "\n"; 
+
+	auto n_classes = global_class_centers.size(); 
+	
+	// need the normalized class centers
+	
+	
+	
+	map<int, unsigned> segmap;
+	for_each(global_sparse_probmap.begin(), global_sparse_probmap.end(),
+		 [&segmap](const CMeans::SparseProbmap::value_type& x) {
+			 int c = 0;
+			 float max_prob = 0.0f;
+			 for (unsigned i = 0; i< x.second.size(); ++i) {
+				 auto f = x.second[i]; 
+				 if (f > max_prob) {
+					 max_prob = f;
+					 c = i; 
+				 };
+			 }
+			 segmap[x.first] = c; 
+		 }); 
+
+
+	FLocalCMeans::Probmap global_probmap;
+	for (auto k : global_sparse_probmap) {
+		global_probmap[k.first] = k.second; 
+	}; 
+	
+	if (!out_filename2.empty()) {
+		FCrispSeg cs(segmap);
+		auto crisp_global_seg = mia::filter(cs, *in_image);
+		if (!save_image (out_filename2, crisp_global_seg)) {
+			cverr() << "Unable to save to '" << out_filename2 << "'\n"; 
+		}
+	}
+	
+	int  nx = (in_image->get_size().x + blocksize - 1) / blocksize;
+	int  ny = (in_image->get_size().y + blocksize - 1) / blocksize;
+	int  start_x = (nx * blocksize - in_image->get_size().x) / 2; 
+	int  start_y = (ny * blocksize - in_image->get_size().y) / 2; 
+
+	
+	
+	vector<C2DFDatafield> prob_buffer(global_class_centers.size());
+	for (unsigned i = 0; i < global_class_centers.size(); ++i)
+		prob_buffer[i] = C2DFDatafield(in_image->get_size()); 
+	
+	for (int  iy_base = start_y; iy_base < (int)in_image->get_size().y; iy_base +=  blocksize) {
+		unsigned iy = iy_base < 0 ? 0 : iy_base;
+		unsigned iy_end = iy_base +  2 * blocksize;
+		if (iy_end > in_image->get_size().y)
+			iy_end = in_image->get_size().y; 
+		
+		for (int ix_base = start_x; ix_base < (int)in_image->get_size().x; ix_base +=  blocksize) {
+			unsigned ix = ix_base < 0 ? 0 : ix_base;
+			unsigned ix_end = ix_base +  2 * blocksize;
+			if (ix_end > in_image->get_size().x)
+				ix_end = in_image->get_size().x; 
+			
+
+			FLocalCMeans lcm(cmeans_epsilon, global_class_centers,
+					 C2DBounds(ix, iy), C2DBounds(ix_end, iy_end),
+					 global_probmap,
+					 rel_cluster_threshold,
+					 segmap, 
+					 prob_buffer);
+			
+			mia::accumulate(lcm, *in_image); 
+		}
+	}
+	// save the prob images ?
+	// normalize probability images
+	C2DFImage sum(prob_buffer[0]);
+	for (unsigned c = 1; c < n_classes; ++c) {
+		transform(sum.begin(), sum.end(), prob_buffer[c].begin(), sum.begin(),
+			  [](float x, float y){return x+y;}); 
+	}
+	for (unsigned c = 0; c < n_classes; ++c) {
+		transform(sum.begin(), sum.end(), prob_buffer[c].begin(), prob_buffer[c].begin(),
+			  [](float s, float p){return p/s;});
+	}
+	if (!cls_filename.empty()) {
+		C2DImageIOPluginHandler::Instance::Data classes;
+
+		for (unsigned c = 0; c < n_classes; ++c)
+			classes.push_back(make_shared<C2DFImage>(prob_buffer[c]));
+
+		if (!C2DImageIOPluginHandler::instance().save(cls_filename, classes))
+			cverr() << "Error writing class images to '" << cls_filename << "'\n"; 
+	}
+	
+	
+	// now for each pixel we have a probability sume that should take inhomogeinities
+	// into account
+
+	C2DUBImage out_image(in_image->get_size(), *in_image);
+	fill(out_image.begin(), out_image.end(), 0);
+
+	for (unsigned c = 1; c < n_classes; ++c) {
+		auto iout = out_image.begin();
+		auto eout = out_image.end();
+		
+		auto itest = prob_buffer[0].begin();
+		auto iprob = prob_buffer[c].begin();
+
+		while ( iout != eout ){
+			if (*itest < *iprob) {
+				*itest = *iprob;
+				*iout = c; 
+			}
+			++iout; ++itest; ++iprob; 
+		}
+	}
+
+	return save_image(out_filename, out_image) ? EXIT_SUCCESS : EXIT_FAILURE; 
+}
+
+
+template <typename T> 
+void FRunHistogram::operator()(const T2DImage<T>& image)
+{
+	m_sparse_histogram(image.begin(), image.end()); 
+}
+
+CSparseHistogram::Compressed FRunHistogram::get_histogram() const
+{
+	return m_sparse_histogram.get_compressed_histogram(); 
+}
+
+
+FLocalCMeans::FLocalCMeans(float epsilon, const vector<double>& global_class_centers,
+		     const C2DBounds& start, const C2DBounds& end,
+		     const Probmap& global_probmap,
+		     float rel_cluster_threshold, 
+		     const map<int, unsigned>& segmap, 
+		     vector<C2DFDatafield>& prob_buffer):
+	m_epsilon(epsilon),
+	m_global_class_centers(global_class_centers),
+	m_start(start),
+	m_end(end),
+	m_global_probmap(global_probmap),
+	m_rel_cluster_threshold(rel_cluster_threshold),
+	m_segmap(segmap), 
+	m_prob_buffer(prob_buffer),
+	m_count((m_end - m_start).product())
+{
+}
+
+template <typename T> 
+void FLocalCMeans::operator()(const T2DImage<T>& image)
+{
+	cvmsg() << "Start subrange ["<< m_start << "]-["<< m_end<<"]\n";
+	
+	// obtain the histogram for the current patch 
+	CSparseHistogram histogram;
+	histogram(image.begin_range(m_start, m_end), 
+		  image.end_range(m_start, m_end));
+	auto ch = histogram.get_compressed_histogram();
+
+	// calculate the class avaliability in the patch
+	vector<double> partition(m_global_class_centers.size());
+	
+	for (auto idx: ch) {
+		const double n = idx.second; 
+		auto v = m_global_probmap.at(idx.first);
+		transform(partition.begin(), partition.end(), v.begin(),
+			  partition.begin(), [n](double p, double value){return p + n * value;}); 
+	}
+	auto part_thresh = std::accumulate(partition.begin(), partition.end(), 0.0) * m_rel_cluster_threshold; 
+	
+	cvinfo() << "Partition = " << partition << "\n";
+
+	// select the classes that should be used further on
+	vector<double> retained_class_centers;
+	vector<unsigned> used_classed; 
+	for (unsigned i = 0; i < partition.size(); ++i) {
+		if (partition[i] >= part_thresh) {
+			retained_class_centers.push_back(m_global_class_centers[i]);
+			used_classed.push_back(i);
+		}
+	}
+	
+
+	// prepare linear interpolation summing 
+	auto center = C2DFVector((m_end + m_start)) / 2.0f;
+	auto max_distance = C2DFVector((m_end - m_start)) / 2.0f;
+	
+	
+	if (retained_class_centers.size() > 1)  {
+		
+		ostringstream cci_descr;
+		cci_descr << "predefined:cc=[" << retained_class_centers<<"]";
+		cvinfo() << "Initializing local cmeans with '" << cci_descr.str()
+			 << " for retained classes " << used_classed << "'\n"; 
+		auto cci = CMeansInitializerPluginHandler::instance().produce(cci_descr.str()); 
+
+
+		// remove data that was globally assigned to now unused class
+		CSparseHistogram::Compressed cleaned_histogram;
+		cleaned_histogram.reserve(ch.size());
+		
+		// copy used intensities 
+		for (auto c: used_classed) {
+			for (auto ich: ch) {
+				if ( m_segmap.at(ich.first) == c) {
+					cleaned_histogram.push_back(ich);
+				}
+			}
+		}
+		
+		// evluate the local c-means classification 
+		CMeans local_cmeans(m_epsilon, cci);
+		auto local_map = local_cmeans.run(cleaned_histogram,  retained_class_centers);
+
+		// create a lookup map intensity -> probability vector 
+		map<unsigned short, CMeans::DVector> mapper;
+		for (auto i: local_map) {
+			mapper[i.first] = i.second; 
+		}
+
+
+		// now add the new probabilities to the global maps.
+		auto ii = image.begin_range(m_start, m_end);
+		auto ie = image.end_range(m_start, m_end);
+		while (ii != ie) {
+			auto probs = mapper.find(*ii);
+			auto delta = (C2DFVector(ii.pos()) - center) / max_distance;
+			float lin_scale = (1.0 - std::fabs(delta.x))* (1.0 - std::fabs(delta.y));
+			
+			if (probs != mapper.end()) {
+				for (unsigned c = 0; c < used_classed.size();  ++c) {
+					m_prob_buffer[used_classed[c]](ii.pos()) += lin_scale * probs->second[c];
+				}
+			}else{ // not in local map: retain global probabilities 
+				auto v = m_global_probmap.at(*ii);
+				for (unsigned c = 0; c < v.size();  ++c) {
+					m_prob_buffer[c](ii.pos()) += lin_scale * v[c];
+				}
+			}
+			++ii;
+		}
+		
+		
+	}else{// only one class retained, add 1.0 to probabilities, linearly smoothed 
+		cvdebug() << "Only one class used:" << used_classed[0] << "\n"; 
+		auto ii = m_prob_buffer[used_classed[0]].begin_range(m_start, m_end);
+		auto ie = m_prob_buffer[used_classed[0]].end_range(m_start, m_end);
+		
+		while (ii != ie)  {
+			auto delta = (C2DFVector(ii.pos()) - center) / max_distance;
+			*ii += (1.0 - std::fabs(delta.x))* (1.0 - std::fabs(delta.y)); ;
+			++ii; 
+		}
+		
+	}
+	cvmsg() << "Done subrange ["<< m_start << "]-["<< m_end<<"]\n"; 
+}
+
+#include <mia/internal/main.hh>
+MIA_MAIN(do_main); 
+
diff --git a/src/2dsegment-local-kmeans.cc b/src/2dsegment-local-kmeans.cc
new file mode 100644
index 0000000..c2a444c
--- /dev/null
+++ b/src/2dsegment-local-kmeans.cc
@@ -0,0 +1,366 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/core/histogram.hh>
+#include <mia/core/cmdlineparser.hh>
+#include <mia/core/kmeans.hh>
+#include <mia/2d.hh>
+
+#include <memory>
+#include <vector>
+
+using namespace mia;
+using namespace std; 
+
+typedef vector<C2DFImage> C2DFImageVec;
+
+const SProgramDescription g_description = {
+        {pdi_group, "Analysis, filtering, combining, and segmentation of 2D images"}, 
+	{pdi_short, "Run a k-means segmentation of a 2D image."}, 
+	{pdi_description, "This program runs the segmentation of a 2D image by applying "
+	 "a localized k-means approach that helps to overcome intensity inhomogeneities "
+	 "in the image. The approach evaluates a global k-means clustering, and then "
+	 "separates the image into overlapping regions where more k-means iterations "
+	 "are run only including the locally present classes, i.e. the classes that "
+	 "relatively contain more pixels than a given threshhold."}, 
+	{pdi_example_descr, "Run the segmentation on image test.png using three classes, "
+	 "local regions of 40 pixels (grid width 20 pixels), and a class ignore threshhold of 0.01." }, 
+	{pdi_example_code, "-i test.png -o label.png -n 3 -g 20 -t 0.01"}
+}; 
+
+
+class FKmeans: public TFilter<vector<double>> {
+public: 
+	FKmeans(const vector<double>& in_classes, vector<C2DSBImage>& class_output, double rel_cluster_threshold);
+	void set_range(const C2DBounds& start, const C2DBounds& end, int xtarget, int ytarget);
+
+	template <typename T>
+	vector<double> operator () (const T2DImage<T>& image);
+
+private:
+	vector<double> m_in_classes;
+	vector<C2DSBImage>& m_class_output;
+	double m_rel_cluster_threshold; 
+	C2DBounds m_start; 
+	C2DBounds m_end;
+	int m_xtarget;
+	int m_ytarget; 
+}; 
+
+class FKMeansLocal: public TFilter<P2DImage> {
+public:
+	FKMeansLocal(const vector<C2DDImage>& class_centers); 
+
+	template <typename T>
+	P2DImage operator () (const T2DImage<T>& image) const;
+private:
+	const vector<C2DDImage>& m_class_centers; 
+}; 
+
+
+int do_main(int argc, char *argv[])
+{
+
+	string in_filename; 
+	string out_filename;
+	string out_filename2;
+	string debug_filename; 
+	
+        int blocksize = 20;
+	unsigned n_classes = 3;
+	double rel_cluster_threshold = 0.0001;
+
+		
+	const auto& image2dio = C2DImageIOPluginHandler::instance();
+
+	CCmdOptionList opts(g_description);
+        opts.set_group("File-IO"); 
+	opts.add(make_opt( in_filename, "in-file", 'i', "image to be segmented", CCmdOptionFlags::required_input, &image2dio )); 
+	opts.add(make_opt( out_filename, "out-file", 'o', "class label image based on merging local labels", CCmdOptionFlags::output, &image2dio ));
+	opts.add(make_opt( out_filename2, "out-file2", 'O', "class label image based on classifying by using the interpolated class centers ",
+			   CCmdOptionFlags::output, &image2dio ));
+	opts.add(make_opt( debug_filename, "debug-centers", 'D', "Save the class center images to a debug file (type is double)",
+			   CCmdOptionFlags::output, &image2dio ));
+
+	
+        opts.set_group("Parameters"); 
+	opts.add(make_opt( blocksize, EParameterBounds::bf_min_closed, {3},
+			   "grid-spacing", 'g', "Spacing of the grid used to modulate the intensity inhomogeneities"));
+	opts.add(make_opt( n_classes, EParameterBounds::bf_closed_interval, {2u,127u},
+			   "nclasses", 'n', "Number of intensity classes to segment")); 
+	opts.add(make_opt( rel_cluster_threshold, EParameterBounds::bf_min_closed | EParameterBounds::bf_max_open,
+			   {0.0,1.0}, "relative-cluster-threshhold", 't', "Number of intensity classes to segment")); 
+
+
+	
+	if (opts.parse(argc, argv) != CCmdOptionList::hr_no)
+		return EXIT_SUCCESS; 
+
+	if (out_filename.empty() && out_filename2.empty()) {
+		throw invalid_argument("You must specify at least one output file"); 
+	}
+	
+	auto in_image = load_image2d(in_filename);
+	stringstream kfilter_ss;
+	kfilter_ss << "kmeans:c=" << n_classes; 
+
+	auto full_kmeans = run_filter(in_image, kfilter_ss.str().c_str());
+
+	vector <C2DSBImage> class_output(4, C2DSBImage(in_image->get_size()));
+	for (auto image : class_output) {
+		fill(image.begin(), image.end(), -1); 
+	}
+	
+	auto full_classes_ptr = full_kmeans->get_attribute(ATTR_IMAGE_KMEANS_CLASSES);
+	const CVDoubleAttribute& full_classes = dynamic_cast<const CVDoubleAttribute&>(*full_classes_ptr); 
+	
+	FKmeans local_kmeans(full_classes, class_output, rel_cluster_threshold);
+
+	// true block size is selected so that the start and end pixles are on the boundaries
+	unsigned nx = (in_image->get_size().x + blocksize - 1) / blocksize;
+	unsigned ny = (in_image->get_size().y  + blocksize - 1)/ blocksize;
+	double scalex = double(in_image->get_size().x - 1) / double (nx-1);
+	double scaley = double(in_image->get_size().y - 1) / double (ny-1);   
+
+	cvmsg() << "using a scale factor of " << scalex << " x "<< scaley << "\n"; 
+
+	int xtarget = 0;
+	int ytarget = 0;
+
+	vector<C2DDImage> local_class_center_img(n_classes, C2DDImage(C2DBounds(nx, ny))); 
+
+	vector<C2DDImage::iterator> ilcc;
+	for (unsigned i = 0; i < n_classes; ++i) {
+		ilcc.push_back(local_class_center_img[i].begin()); 
+	}
+	
+	for (unsigned iy = 0; iy < ny; ++iy, ytarget = (ytarget + 1)%2) {
+		for (unsigned ix = 0; ix < nx; ++ix, xtarget = (xtarget + 1)%2) {
+			
+			C2DBounds start(static_cast<unsigned>(ix * scalex),static_cast<unsigned>(iy * scaley));
+			C2DBounds end(static_cast<unsigned>(2 * (ix +1) * scalex),static_cast<unsigned>( 2 * (iy +1) * scaley));
+
+			if (start.x > in_image->get_size().x)
+				start.x = 0;
+			
+			if (start.y > in_image->get_size().y)
+				start.y = 0; 
+
+			if (end.x > in_image->get_size().x)
+				end.x = in_image->get_size().x;
+			
+			if (end.y > in_image->get_size().y)
+				end.y = in_image->get_size().y; 
+
+			local_kmeans.set_range(start, end, xtarget, ytarget);
+
+			auto local_class_centers = mia::accumulate(local_kmeans, *in_image);
+			for (unsigned i = 0; i < n_classes; ++i) {
+				*ilcc[i]++ = local_class_centers[i];
+			}
+		}
+	}
+
+	if (!out_filename.empty())  {
+		// merge the class labels;
+		cvmsg() << "Create result image of size" << in_image->get_size() << "\n"; 
+		C2DUBImage result_labels(in_image->get_size(), *in_image);
+		
+		auto iout = result_labels.begin();
+		auto eout = result_labels.end();
+		
+		vector<C2DSBImage::const_iterator> ii; 
+		
+		for (int i = 0; i < 4; ++i) {
+			ii.push_back(class_output[i].begin());
+		}
+		
+		vector<unsigned> counts(n_classes); 
+		while (iout != eout)  {
+			fill(counts.begin(), counts.end(), 0);
+			for (int i = 0; i < 4; ++i) {
+				if (*ii[i] >= 0) {
+					++counts[*ii[i]];
+				}
+				++ii[i]; 
+			}
+			unsigned max_count = 0;
+			int max_class = -1;
+			
+			unsigned k = 0; 
+			
+			while ( (max_count << 1) < n_classes && k < n_classes ) {
+				if (max_count < counts[k]) {
+					max_count = counts[k];
+					max_class = k; 
+				}
+				++k; 
+			}
+			*iout = max_class; 
+			++iout; 
+		}
+		save_image(out_filename, result_labels);
+	}
+
+	if (!out_filename2.empty()){
+		cvmsg() << "Save interpolated class center based labeling to " << out_filename2 << "\n"; 
+		stringstream scale_filter_ss;
+		scale_filter_ss << "scale:sx=" << in_image->get_size().x
+				<< ",sy=" << in_image->get_size().y << ",interp=[bspline:d=1]"; 
+		auto scale_filter = produce_2dimage_filter(scale_filter_ss.str().c_str()); 
+
+		C2DImageIOPPH::Data scaled_images;
+		transform(local_class_center_img.begin(), local_class_center_img.end(),
+			  back_inserter<C2DImageIOPPH::Data>(scaled_images),
+			  [ scale_filter ](const C2DDImage& img){return scale_filter->filter(img);}); 
+
+		transform(scaled_images.begin(), scaled_images.end(), local_class_center_img.begin(),
+			  [](P2DImage img){ return dynamic_cast<const C2DDImage&>(*img);}); 
+		
+		if (!debug_filename.empty()) {
+			image2dio.save(debug_filename, scaled_images); 
+		}
+		
+		FKMeansLocal means_local(local_class_center_img);
+		auto result = mia::filter(means_local, *in_image);
+
+		save_image(out_filename2, result);
+	}
+	
+	return EXIT_SUCCESS; 
+	
+}
+
+
+FKmeans::FKmeans(const vector<double>& in_classes, vector<C2DSBImage>& class_output,
+		 double rel_cluster_threshold):
+	m_in_classes(in_classes),
+	m_class_output(class_output),
+	m_rel_cluster_threshold(rel_cluster_threshold)
+{
+}
+
+void FKmeans::set_range(const C2DBounds& start, const C2DBounds& end, int xtarget, int ytarget)
+{
+	m_start = start; 
+	m_end = end;
+	m_xtarget = xtarget;
+	m_ytarget = ytarget; 
+}
+	
+
+template <typename T>
+vector<double> FKmeans::operator () (const T2DImage<T>& image)
+{
+	auto ibegin = image.begin_range(m_start, m_end);
+	auto iend = image.end_range(m_start, m_end);
+	
+	auto i = ibegin;
+	
+	size_t n = 0; 
+	vector<size_t> cluster_sizes(m_in_classes.size());
+	size_t l = m_in_classes.size() - 1; 
+	
+	while ( i != iend ) {
+		const unsigned c = kmeans_get_closest_clustercenter(m_in_classes, l, *i); 
+		++cluster_sizes[c]; 
+		++i;
+		++n; 
+	}
+	
+	vector<double> rel_cluster_sizes(m_in_classes.size());
+	transform(cluster_sizes.begin(), cluster_sizes.end(), rel_cluster_sizes.begin(),
+		  [n](double x){return x / n;});
+	
+	cvinfo() << "Block [" << m_start << "],[" <<  m_end <<"] Relative cluster sizes: " << rel_cluster_sizes << "\n"; 
+	
+	vector<short> map_idx; 
+	vector<double> result; 
+	for (unsigned i = 0; i < m_in_classes.size(); ++i) {
+		if (rel_cluster_sizes[i] > m_rel_cluster_threshold) {
+			result.push_back(m_in_classes[i]);
+			map_idx.push_back(i); 
+		}
+	}
+	
+	vector<int> class_relation(n);
+	
+	int biggest_class = -1; 
+	// iterate to update the class centers  
+	for (size_t  l = 1; l < 4; l++) {
+		if (kmeans_step(ibegin, iend, class_relation.begin(), result,
+				result.size() - 1, biggest_class)) 
+			break; 
+	}
+	
+	transform(class_relation.begin(), class_relation.end(),
+		  m_class_output[m_ytarget * 2 + m_xtarget].begin_range(m_start, m_end), 
+		  [map_idx](int idx) {return map_idx[idx];});
+
+	// put the classes back into the right size
+	vector<double> remapped_result(m_in_classes); 
+	for (unsigned i =0; i < result.size(); ++i) {
+		remapped_result[map_idx[i]] = result[i]; 
+	}
+	cvinfo() << "remapped cc=" << remapped_result << "\n"; 
+	return remapped_result; 
+}
+
+FKMeansLocal::FKMeansLocal(const vector<C2DDImage>& class_centers):
+	m_class_centers(class_centers)
+{
+}
+
+template <typename T>
+P2DImage FKMeansLocal::operator () (const T2DImage<T>& image) const
+{
+	C2DUBImage *result_labels = new C2DUBImage(image.get_size(), image);
+
+	auto i = image.begin();
+	auto iout = result_labels->begin();
+	auto eout = result_labels->end();
+	
+	vector<C2DDImage::const_iterator> ii;
+	unsigned n_classes = m_class_centers.size(); 
+	
+	for (unsigned i = 0; i < n_classes; ++i) {
+		ii.push_back(m_class_centers[i].begin());
+	}
+	vector<double> centers( n_classes ); 
+	while (iout != eout)  {
+		for (unsigned i = 0; i < n_classes; ++i) {
+			centers[i] = *ii[i];
+			++ii[i]; 
+		}
+		*iout = kmeans_get_closest_clustercenter(centers, n_classes-1, *i); 
+
+		++iout; ++i; 
+	}
+	return P2DImage(result_labels); 
+}
+
+
+#include <mia/internal/main.hh>
+MIA_MAIN(do_main); 
+
diff --git a/src/2dsegment-per-pixel-kmeans.cc b/src/2dsegment-per-pixel-kmeans.cc
new file mode 100644
index 0000000..1098e37
--- /dev/null
+++ b/src/2dsegment-per-pixel-kmeans.cc
@@ -0,0 +1,239 @@
+/* -*- mia-c++  -*-
+ *
+ * This file is part of MIA - a toolbox for medical image analysis 
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
+ *
+ * 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/core/histogram.hh>
+#include <mia/core/cmdlineparser.hh>
+#include <mia/core/kmeans.hh>
+#include <mia/core/parallel.hh>
+#include <mia/core/threadedmsg.hh>
+#include <mia/2d.hh>
+
+#include <memory>
+#include <vector>
+
+using namespace mia;
+using namespace std; 
+
+typedef vector<C2DFImage> C2DFImageVec;
+
+const SProgramDescription g_description = {
+        {pdi_group, "Analysis, filtering, combining, and segmentation of 2D images"}, 
+	{pdi_short, "Run a k-means segmentation of a 2D image."}, 
+	{pdi_description, "This program runs the segmentation of a 2D image by applying "
+	 "a localized k-means approach that helps to overcome intensity inhomogeneities "
+	 "in the image. The approach evaluates a global k-means clustering, and then "
+	 "separates the image into overlapping regions where more k-means iterations "
+	 "are run only including the locally present classes, i.e. the classes that "
+	 "relatively contain more pixels than a given threshhold."}, 
+	{pdi_example_descr, "Run the segmentation on image test.png using three classes, "
+	 "local regions of 40 pixels (grid width 20 pixels), and a class ignore threshhold of 0.01." }, 
+	{pdi_example_code, "-i test.png -o label.png -n 3 -g 20 -t 0.01"}
+}; 
+
+
+class FKmeans: public TFilter<unsigned> {
+public: 
+	FKmeans(const vector<double>& in_classes, double rel_cluster_threshold);
+	void set_position_and_range(int x, int y, const C2DBounds& start, const C2DBounds& end);
+
+	template <typename T>
+	unsigned operator () (const T2DImage<T>& image) const;
+
+private:
+	vector<double> m_in_classes;
+	double m_rel_cluster_threshold; 
+	C2DBounds m_start; 
+	C2DBounds m_end;
+	int m_x;
+	int m_y; 
+}; 
+
+class FKMeansLocal: public TFilter<P2DImage> {
+public:
+	FKMeansLocal(const vector<C2DDImage>& class_centers); 
+
+	template <typename T>
+	P2DImage operator () (const T2DImage<T>& image) const;
+private:
+	const vector<C2DDImage>& m_class_centers; 
+}; 
+
+
+int do_main(int argc, char *argv[])
+{
+
+	string in_filename; 
+	string out_filename;
+	
+        int window = 20;
+	unsigned n_classes = 3;
+	double rel_cluster_threshold = 0.0001;
+
+		
+	const auto& image2dio = C2DImageIOPluginHandler::instance();
+
+	CCmdOptionList opts(g_description);
+        opts.set_group("File-IO"); 
+	opts.add(make_opt( in_filename, "in-file", 'i', "image to be segmented", CCmdOptionFlags::required_input, &image2dio )); 
+	opts.add(make_opt( out_filename, "out-file", 'o', "class label image based on merging local labels",
+			   CCmdOptionFlags::required_output, &image2dio ));
+
+	
+        opts.set_group("Parameters"); 
+	opts.add(make_opt( window, EParameterBounds::bf_min_closed, {3},
+			   "window", 'w', "Window size around the pixel to be analyzed"));
+	opts.add(make_opt( n_classes, EParameterBounds::bf_closed_interval, {2u,127u},
+			   "nclasses", 'n', "Number of intensity classes to segment")); 
+	opts.add(make_opt( rel_cluster_threshold, EParameterBounds::bf_min_closed | EParameterBounds::bf_max_open,
+			   {0.0,1.0}, "relative-cluster-threshhold", 't', "Number of intensity classes to segment")); 
+
+
+	
+	if (opts.parse(argc, argv) != CCmdOptionList::hr_no)
+		return EXIT_SUCCESS; 
+
+	auto in_image = load_image2d(in_filename);
+	stringstream kfilter_ss;
+	kfilter_ss << "kmeans:c=" << n_classes; 
+
+	auto full_kmeans = run_filter(in_image, kfilter_ss.str().c_str());
+	
+	auto full_classes_ptr = full_kmeans->get_attribute(ATTR_IMAGE_KMEANS_CLASSES);
+	const CVDoubleAttribute& full_classes = dynamic_cast<const CVDoubleAttribute&>(*full_classes_ptr); 
+	
+	C2DUBImage result_labels(in_image->get_size(), *in_image);
+
+	auto run_classification = [&result_labels, &full_classes, rel_cluster_threshold, window, &in_image]
+		(const C1DParallelRange& range) {
+		CThreadMsgStream thread_stream;
+		FKmeans local_kmeans(full_classes, rel_cluster_threshold);
+		
+		for( int y=range.begin(); y!=range.end(); ++y ) {
+			auto ir = result_labels.begin_at(0,y); 
+			for (unsigned x = 0; x < in_image->get_size().x; ++x, ++ir) {
+			
+				C2DBounds start( x - window, y - window);
+				C2DBounds end( x + window, y + window);
+				
+				if (start.x > in_image->get_size().x)
+					start.x = 0;
+				
+				if (start.y > in_image->get_size().y)
+					start.y = 0; 
+				
+				if (end.x > in_image->get_size().x)
+					end.x = in_image->get_size().x;
+				
+				if (end.y > in_image->get_size().y)
+					end.y = in_image->get_size().y; 
+				
+				local_kmeans.set_position_and_range(x, y, start, end);
+
+				*ir = mia::filter(local_kmeans, *in_image);
+			}
+		}
+	}; 
+	pfor(C1DParallelRange( 0, in_image->get_size().y), run_classification);  
+
+	save_image(out_filename, result_labels);
+	return EXIT_SUCCESS; 
+	
+}
+
+
+FKmeans::FKmeans(const vector<double>& in_classes, 
+		 double rel_cluster_threshold):
+	m_in_classes(in_classes),
+	m_rel_cluster_threshold(rel_cluster_threshold)
+{
+}
+
+void FKmeans::set_position_and_range(int x, int y, const C2DBounds& start, const C2DBounds& end)
+{
+	m_start = start; 
+	m_end = end;
+	m_x = x;
+	m_y = y;
+
+
+}
+	
+
+template <typename T>
+unsigned FKmeans::operator () (const T2DImage<T>& image) const 
+{
+	size_t n =  (m_end.x - m_start.x) *(m_end.y - m_start.y); 
+	vector<T> buffer(n); 
+
+	copy(image.begin_range(m_start, m_end), image.end_range(m_start, m_end), buffer.begin()); 
+	auto i = buffer.begin();
+	auto iend = buffer.end();
+	
+	vector<size_t> cluster_sizes(m_in_classes.size());
+	size_t l = m_in_classes.size() - 1; 
+
+	vector<int> class_relation(n);
+	auto ic = class_relation.begin();
+	
+	while ( i != iend ) {
+		const unsigned c = kmeans_get_closest_clustercenter(m_in_classes, l, *i); 
+		++cluster_sizes[c];
+		*ic++ = c;  
+		++i;
+	}
+
+	vector<double> rel_cluster_sizes(m_in_classes.size());
+	transform(cluster_sizes.begin(), cluster_sizes.end(), rel_cluster_sizes.begin(),
+		  [n](double x){return x / n;});
+	
+	
+	vector<double> result(m_in_classes); 
+	vector<bool> fixed_centers(m_in_classes.size(), false); 
+	for (unsigned i = 0; i < m_in_classes.size(); ++i) {
+		if (rel_cluster_sizes[i] <= m_rel_cluster_threshold) {
+			fixed_centers[i] = true; 
+		}
+	}
+
+	int biggest_class = -1; 
+	// iterate to update the class centers  
+	for (size_t  l = 1; l < 4; l++) {
+		if (kmeans_step_with_fixed_centers(buffer.begin(), buffer.end(), class_relation.begin(),
+						   result, fixed_centers, result.size() - 1, biggest_class)) 
+			break; 
+	}
+	
+	auto c = kmeans_get_closest_clustercenter(result, result.size() - 1, image(m_x,m_y));
+	
+	cvdebug() << "Block [" << m_x << ":" << m_y << "]@["<< m_start
+		  << "],[" <<  m_end <<"] "<< image(m_x,m_y) << " c=" << c 
+		  << ", Relative cluster sizes: " << rel_cluster_sizes << "\n";
+	return c; 
+
+}
+
+
+#include <mia/internal/main.hh>
+MIA_MAIN(do_main); 
+
diff --git a/src/2dsegmentcropbox.cc b/src/2dsegmentcropbox.cc
index 6fa7574..8572522 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dsegseriesstats.cc b/src/2dsegseriesstats.cc
index d99be5e..b616564 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyosegstats"
-
 #include <libxml++/libxml++.h>
 #include <mia/core/msgstream.hh>
 #include <mia/core/cmdlineparser.hh>
diff --git a/src/2dsegshift.cc b/src/2dsegshift.cc
index 474c998..d9839c1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dsegshiftperslice.cc b/src/2dsegshiftperslice.cc
index 8bc827d..521d64c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dseries-mincorr.cc b/src/2dseries-mincorr.cc
index 373b364..9328e4b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dmyocard"
 #include <iomanip>
 #include <ostream>
 #include <fstream>
diff --git a/src/2dseries-sectionmask.cc b/src/2dseries-sectionmask.cc
index 4f73943..86a63f7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dseries-segdistance.cc b/src/2dseries-segdistance.cc
index 31fceed..1364216 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "SEGBORDERDIST" 
-
 #include <iterator>
 #include <algorithm>
 #include <iostream>
@@ -37,6 +35,8 @@
 #include <mia/2d/imageio.hh>
 #include <mia/2d/filter.hh>
 
+#include <numeric> 
+
 using namespace std;
 using namespace mia;
 using xmlpp::DomParser;
diff --git a/src/2dseries2dordermedian.cc b/src/2dseries2dordermedian.cc
index 99cab7c..18555b2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "SER2DGRADMedian"
-
 #include <iostream>
 #include <fstream>
 #include <iomanip>
@@ -30,7 +28,7 @@
 #include <boost/algorithm/minmax_element.hpp>
 
 #include <mia/internal/main.hh>
-#include <mia/2d/filterchain.hh>
+#include <mia/2d/filter.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/segsetwithimages.hh>
 #include <mia/core.hh>
diff --git a/src/2dseries2sets.cc b/src/2dseries2sets.cc
index efed751..e7220af 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "series2set" 
 #include <fstream>
 #include <libxml++/libxml++.h>
 #include <mia/core/cmdlineparser.hh>
diff --git a/src/2dseriescorr.cc b/src/2dseriescorr.cc
index 85414c6..68b38b0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dseriescorr"
 #include <iomanip>
 #include <ostream>
 #include <fstream>
diff --git a/src/2dseriesgradMAD.cc b/src/2dseriesgradMAD.cc
index 1cb1afd..b7ca57e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "SERGRADVAR"
-
 #include <iostream>
 #include <iomanip>
 #include <string>
@@ -28,7 +26,7 @@
 #include <stdexcept>
 
 #include <mia/internal/main.hh>
-#include <mia/2d/filterchain.hh>
+#include <mia/2d/filter.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/segsetwithimages.hh>
 #include <mia/core.hh>
diff --git a/src/2dseriesgradvariation.cc b/src/2dseriesgradvariation.cc
index ffc2ca4..7afdeef 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "SERGRADVAR"
-
 #include <iostream>
 #include <iomanip>
 #include <string>
diff --git a/src/2dserieshausdorff.cc b/src/2dserieshausdorff.cc
index 5053728..80a5969 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dseriessmoothgradMAD.cc b/src/2dseriessmoothgradMAD.cc
index 4893ccb..bffa290 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "SERGRADVAR"
-
 #include <iostream>
 #include <iomanip>
 #include <string>
@@ -28,7 +26,7 @@
 #include <stdexcept>
 
 #include <mia/internal/main.hh>
-#include <mia/2d/filterchain.hh>
+#include <mia/2d/filter.hh>
 #include <mia/2d/imageio.hh>
 #include <mia/2d/segsetwithimages.hh>
 #include <mia/core.hh>
diff --git a/src/2dseriestovolume.cc b/src/2dseriestovolume.cc
index bf39234..6d8d944 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dstack-cmeans-presegment.cc b/src/2dstack-cmeans-presegment.cc
index 4878ca4..e218034 100644
--- a/src/2dstack-cmeans-presegment.cc
+++ b/src/2dstack-cmeans-presegment.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,137 +49,19 @@ const SProgramDescription g_description = {
 	{pdi_example_code, "-i imageXXXX.png -o foreground -t png --histogram-tresh=30 --classes 2 --label 1"}
 }; 
 
-class CFullHistogram : public TFilter<size_t> {
-        
-public: 
-        CFullHistogram();
-
-        template <typename T>
-        size_t operator ()(const T2DImage<T>& image); 
-
-        vector<pair<int, unsigned long>> get_compressed_histogram()const; 
-        
-private: 
-        
-        vector<unsigned long> m_histogram; 
-
-        int m_shift; 
-        EPixelType m_pixeltype; 
-
-        
-        
-}; 
-
-template <typename T> 
-struct dispatch_by_pixeltype {
-        static void apply(const T2DImage<T>& MIA_PARAM_UNUSED(image), vector<unsigned long>& MIA_PARAM_UNUSED(histogram)){
-                throw invalid_argument("Input pixel type not supported"); 
-        }
-}; 
-
-template <> 
-struct dispatch_by_pixeltype<unsigned char> {
-        static void apply(const C2DUBImage& image, vector<unsigned long>& histogram){
-                for (auto p: image) {
-                        ++histogram[p]; 
-                }
-        }
-}; 
-
-template <> 
-struct dispatch_by_pixeltype<unsigned short> {
-        static void apply(const C2DUSImage& image, vector<unsigned long>& histogram){
-                for (auto p: image) {
-                        ++histogram[p]; 
-                }
-        }
-}; 
-
-template <> 
-struct dispatch_by_pixeltype<signed char> {
-        static void apply(const C2DSBImage& image, vector<unsigned long>& histogram){
-		int shift = -numeric_limits<signed char>::min(); 
-                for (auto p: image) {
-                        ++histogram[shift + p]; 
-                }
-        }
-}; 
-
-template <> 
-struct dispatch_by_pixeltype<signed short> {
-        static void apply(const C2DSSImage& image, vector<unsigned long>& histogram){
-                int shift = -numeric_limits<signed short>::min(); 
-                for (auto p: image) {
-                        ++histogram[shift + p]; 
-                }
-        }
-}; 
-
-CFullHistogram::CFullHistogram():
-        m_shift(0), 
-        m_pixeltype(it_none)
-{
-}
-
-template <typename T>
-size_t CFullHistogram::operator ()(const T2DImage<T>& image)
-{
-        if (m_pixeltype ==it_none) {
-                m_pixeltype = image.get_pixel_type();
-		m_shift = -numeric_limits<T>::min(); 
-                switch (m_pixeltype) {
-                case it_sbyte:
-                case it_ubyte:
-                        m_histogram.resize(256);
-                        break; 
-                case it_sshort:
-                case it_ushort:
-                        m_histogram.resize(65536);
-                        break; 
-                default:
-                        throw create_exception<invalid_argument>("Input pixel type '", CPixelTypeDict.get_name(m_pixeltype),
-                                                                 "' not supported."); 
-                }
-                        
-        } else if (m_pixeltype != image.get_pixel_type()){
-                throw create_exception<invalid_argument>("Input pixels not of consisted type, started with ",
-                                                         CPixelTypeDict.get_name(m_pixeltype), ", but got now ",
-                                                         CPixelTypeDict.get_name(image.get_pixel_type())); 
-        }
-
-        dispatch_by_pixeltype<T>::apply(image, m_histogram);
-
-        return image.size(); 
-}
-
-vector<pair<int, unsigned long>> CFullHistogram::get_compressed_histogram()const
-{
-
-        int nonzero_bins = 0;
-        for (auto b: m_histogram) {
-                if (b > 0)
-                        ++nonzero_bins; 
-        }
-
-        vector<pair<int, unsigned long>> result;
-        result.reserve(nonzero_bins);
-        for (unsigned i = 0; i < m_histogram.size(); ++i) {
-                if (m_histogram[i] != 0)
-                        result.push_back(make_pair(i - m_shift, m_histogram[i])); 
-        }
-        return result; 
-}
-
-typedef map<double, CMeans::DVector> Probmap; 
-
+typedef map<short, CMeans::DVector> Probmap; 
 class FGetClassSeedMask: public TFilter<P2DImage> {
-public: 
+public:
+
+	
 	FGetClassSeedMask(const Probmap& map,
 			  int low_end, int low_label, int high_end, int high_label,
 			  const int label, float prob_thresh);
 
 	template <typename T> 
-	P2DImage operator() (const T2DImage<T>& image) const;   
+	P2DImage operator() (const T2DImage<T>& image) const;
+
+	P2DImage operator() (const C2DBitImage& image) const;
 private:
 	const Probmap& m_map;
 
@@ -205,6 +87,10 @@ FGetClassSeedMask::FGetClassSeedMask(const Probmap& map,
 {
 }
 
+P2DImage FGetClassSeedMask::operator() (const C2DBitImage& MIA_PARAM_UNUSED(image)) const
+{
+	throw invalid_argument("Unsupported input pixel type: This classification doesn't make sense for binary images"); 
+}
 					    
 template <typename T> 
 P2DImage FGetClassSeedMask::operator() (const T2DImage<T>& image) const
@@ -296,7 +182,7 @@ int do_main( int argc, char *argv[] )
 		throw invalid_argument(string("no files match pattern ") + src_basename);
 
 
-        CFullHistogram histo;
+        CSparseHistogram histo;
         size_t n_pixels = 0; 
         for (size_t i = start_filenum; i < end_filenum; ++i) {
                 string src_name = create_filename(src_basename.c_str(), i);
@@ -333,11 +219,11 @@ int do_main( int argc, char *argv[] )
                 --ie;
         }
 
-        vector<pair<int, unsigned long>> threshed_histo(ii, ie);
+	CSparseHistogram::Compressed threshed_histo(ii, ie);
 
 	CMeans::DVector class_centers; 
 	
-	CMeans cmeans(0.01, 0.00001, class_center_initializer);
+	CMeans cmeans(0.00001, class_center_initializer);
 	CMeans::SparseProbmap pv = cmeans.run(threshed_histo,  class_centers);
 
 	Probmap pmap; 
diff --git a/src/2dstackfilter.cc b/src/2dstackfilter.cc
index 5f83dd4..21db469 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +17,6 @@
  * along with MIA; if not, see <http://www.gnu.org/licenses/>.
  *
  */
-#define VSTREAM_DOMAIN "2dstackfilter" 
-
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
diff --git a/src/2dto3dimage.cc b/src/2dto3dimage.cc
index 84f0f28..a7b87c0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dto3dimageb.cc b/src/2dto3dimageb.cc
index 09a80af..45e76ca 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dtrackpixelmovement.cc b/src/2dtrackpixelmovement.cc
index 38b49cd..ed0dd25 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "2dtrack-pixelmovement"
-
 #include <fstream>
 #include <ostream>
 
diff --git a/src/2dtransform.cc b/src/2dtransform.cc
index 1d5b1a1..fa2d044 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/2dtransformation-to-strain.cc b/src/2dtransformation-to-strain.cc
index 7f2340c..310c6d2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "mia-2dtransformation-to-tensor"
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/msgstream.hh>
 #include <mia/core/file.hh>
diff --git a/src/3dbinarycombine.cc b/src/3dbinarycombine.cc
index 63eee7b..8da0935 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dbrainextractT1.cc b/src/3dbrainextractT1.cc
index 640a57b..b379145 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dcombine-imageseries.cc b/src/3dcombine-imageseries.cc
index a58745e..64b5342 100644
--- a/src/3dcombine-imageseries.cc
+++ b/src/3dcombine-imageseries.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dcombine-mr-segmentations.cc b/src/3dcombine-mr-segmentations.cc
index 17968f4..04635f1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dcost-translatedgrad.cc b/src/3dcost-translatedgrad.cc
index 4116cf4..9f6c7f4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "mia-3dcost-translatedgrad"
 #include <mia/core/cmdlineparser.hh>
 #include <mia/3d/transformio.hh>
 #include <mia/3d/transformfactory.hh>
diff --git a/src/3dcost.cc b/src/3dcost.cc
index c622f73..28960e7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 55c8657..98a955e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3ddeform.cc b/src/3ddeform.cc
index 2d92db3..93afc6a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3ddistance-stats.cc b/src/3ddistance-stats.cc
index 9b52c6f..4f14c90 100644
--- a/src/3ddistance-stats.cc
+++ b/src/3ddistance-stats.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3ddistance.cc b/src/3ddistance.cc
index c037d02..17ea7f9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3deval-transformquantity.cc b/src/3deval-transformquantity.cc
index bc0d858..ff96582 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "3deval-transformquantity"
-
 #include <fstream>
 #include <ostream>
 #include <cstring>
diff --git a/src/3dfield2norm.cc b/src/3dfield2norm.cc
index 525f737..283aae9 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dforce.cc b/src/3dforce.cc
index bc731aa..3d5a19a 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 +108,7 @@ int do_main(int argc, char **argv)
 	C3DImageIOPluginHandler::Instance::Data vout;
 	vout.push_back(result);
 
-	imageio.save(out_filename, vout);
-
-	return EXIT_SUCCESS;
+	return imageio.save(out_filename, vout) ? EXIT_SUCCESS : EXIT_FAILURE; 
 }
 
 
diff --git a/src/3dfuzzysegment.cc b/src/3dfuzzysegment.cc
index 924dc70..5003e63 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dgetsize.cc b/src/3dgetsize.cc
index e378d79..ab23865 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dgetslice.cc b/src/3dgetslice.cc
index 94759ff..7d37937 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dimageaddattributes.cc b/src/3dimageaddattributes.cc
index 23f57a5..9560736 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dimagecombine.cc b/src/3dimagecombine.cc
index a64a03b..3462052 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dimagecreator.cc b/src/3dimagecreator.cc
index 5c66135..cce60b2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dimagefilter.cc b/src/3dimagefilter.cc
index da8319f..82bbe20 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dimagefilterstack.cc b/src/3dimagefilterstack.cc
index dc36f0c..a74d170 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dimageselect.cc b/src/3dimageselect.cc
index 8c67852..140caec 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dimagestatistics-in-mask.cc b/src/3dimagestatistics-in-mask.cc
index 6fbb8c2..2cbf2cc 100644
--- a/src/3dimagestatistics-in-mask.cc
+++ b/src/3dimagestatistics-in-mask.cc
@@ -2,7 +2,7 @@
  *
  * This file is part of MIA - a toolbox for medical image analysis 
  * 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  *
  * pez-tools is free software; you can redistribute it and/or modify
diff --git a/src/3dimagestats.cc b/src/3dimagestats.cc
index 7dd38ca..d59f278 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dlandmarks-distances.cc b/src/3dlandmarks-distances.cc
index c8a14ca..2f1aed8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "mia-3dlandmark-distance"
 #include <mia/core/cmdlineparser.hh>
 #include <mia/3d/landmarklistio.hh>
 #include <mia/3d/transformio.hh>
diff --git a/src/3dlandmarks-transform.cc b/src/3dlandmarks-transform.cc
index b743835..203c84c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "mia-3dlandmark-transform"
 #include <mia/core/cmdlineparser.hh>
 #include <mia/3d/landmarklistio.hh>
 #include <mia/3d/transformio.hh>
diff --git a/src/3dlerp.cc b/src/3dlerp.cc
index 134214a..8ea4f07 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 @@ BOOST_AUTO_TEST_CASE( run_self_test )
 
 	const C3DFImage* result = dynamic_cast<const C3DFImage*>(R.get());
 	BOOST_REQUIRE(result);
-
+	
+	// the model for BOOST_REQUIRE schould have caught this .... 
+	// coverity[forward_null]
 	BOOST_CHECK_CLOSE( (*result)(0,0,0), 1.5f, 0.1f);
 	BOOST_CHECK_CLOSE( (*result)(0,1,0), 2.5f, 0.1f);
 
diff --git a/src/3dmany2one-nonrigid.cc b/src/3dmany2one-nonrigid.cc
index 383cbe0..f075849 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "3dmany3one"
-
 #include <fstream>
 #include <libxml++/libxml++.h>
 #include <itpp/signal/fastica.h>
@@ -34,10 +32,7 @@
 #include <mia/3d/transformfactory.hh>
 #include <mia/3d/imageio.hh>
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-
-using namespace tbb;
+#include <mia/core/parallel.hh>
 using namespace std;
 using namespace mia;
 
@@ -104,7 +99,7 @@ struct SeriesRegistration {
 		reference(_reference)
 		{
 		}
-	void operator()( const blocked_range<int>& range ) const {
+	void operator()( const C1DParallelRange& range ) const {
 		CThreadMsgStream thread_stream;
 		TRACE_FUNCTION; 
 		auto m =  CMinimizerPluginHandler::instance().produce(minimizer);
@@ -188,7 +183,7 @@ int do_main( int argc, char *argv[] )
 	SeriesRegistration sreg(*input_images, minimizer, cost_functions, 
 				mg_levels, transform_creator, reference); 
 
-	parallel_for(blocked_range<int>( 0, input_images->size()), sreg);
+	pfor(C1DParallelRange( 0, input_images->size()), sreg);
 
 	bool success = true; 
 	auto ii = input_images->begin(); 
diff --git a/src/3dmaskseeded.cc b/src/3dmaskseeded.cc
index 751cbf5..636d9a8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dmotioncompica-nonrigid.cc b/src/3dmotioncompica-nonrigid.cc
index aaf8b83..fcd0123 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "3dmotioncompica"
-
 #include <fstream>
 #include <libxml++/libxml++.h>
 #include <itpp/signal/fastica.h>
@@ -31,15 +29,13 @@
 #include <mia/core/filetools.hh>
 #include <mia/core/errormacro.hh>
 #include <mia/core/minimizer.hh>
+#include <mia/core/ica.hh>
 #include <mia/3d/nonrigidregister.hh>
 #include <mia/3d/imageio.hh>
 #include <mia/3d/filter.hh>
 #include <mia/3d/ica.hh>
 
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-using namespace tbb;
-
+#include <mia/core/parallel.hh>
 
 using namespace std;
 using namespace mia;
@@ -122,7 +118,7 @@ struct SeriesRegistration {
 		skip_images(_skip_images)
 		{
 		}
-	void operator()( const blocked_range<int>& range ) const {
+	void operator()( const C1DParallelRange& range ) const {
 		CThreadMsgStream thread_stream;
 		TRACE_FUNCTION; 
 		auto m =  CMinimizerPluginHandler::instance().produce(minimizer);
@@ -144,7 +140,7 @@ void run_registration_pass(C3DImageSeries& input_images, const C3DImageSeries& r
 	SeriesRegistration sreg(input_images,references, minimizer, 
 				mg_levels, create_transform_creator(c_rate, divcurlweight), 
 				imagecost, skip_images); 
-	parallel_for(blocked_range<int>( 0, references.size()), sreg);
+	pfor(C1DParallelRange( 0, references.size()), sreg);
 }
 
 void save_references(const string& save_ref, int current_pass, int skip_images, const C3DImageSeries& references)
@@ -258,11 +254,12 @@ int do_main( int argc, char *argv[] )
 	
 
 	// run ICA
-	C3DImageSeriesICA ica(series, false); 
+    CICAAnalysisITPPFactory icatool;
+    C3DImageSeriesICA ica(icatool, series, false);
 	if (max_ica_iterations) 
 		ica.set_max_iterations(max_ica_iterations); 
 	if (!ica.run(components, !no_meanstrip, !no_normalize)) {
-		ica.set_approach(FICA_APPROACH_SYMM); 
+        ica.set_approach(CICAAnalysis::appr_symm);
 		if (!ica.run(components, !no_meanstrip, !no_normalize))
 			cvwarn() << "ICA not converged, but the SYMM approach has given something to work with ...\n";
 	}
@@ -320,11 +317,11 @@ int do_main( int argc, char *argv[] )
 
 		
 		
-		C3DImageSeriesICA ica2(series, false); 
+        C3DImageSeriesICA ica2(icatool, series, false);
 		if (max_ica_iterations) 
 			ica2.set_max_iterations(max_ica_iterations); 
 		if (!ica2.run(components, !no_meanstrip, !no_normalize)) {
-			ica2.set_approach(FICA_APPROACH_SYMM); 
+            ica2.set_approach(CICAAnalysis::appr_symm);
 			ica2.run(components, !no_meanstrip, !no_normalize); 
 		}
 		
diff --git a/src/3dmulti-nrreg.cc b/src/3dmulti-nrreg.cc
index 1f4dbba..1a97c30 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dnonrigidreg-alt.cc b/src/3dnonrigidreg-alt.cc
index a035465..643942c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dnonrigidreg.cc b/src/3dnonrigidreg.cc
index 2de5f1a..9ff69ab 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dnrreg.cc b/src/3dnrreg.cc
index ff61308..d328d1d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dprealign-nonrigid.cc b/src/3dprealign-nonrigid.cc
index f3439c0..2133077 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "3dprealign"
-
 #include <fstream>
 #include <sstream>
 #include <iomanip>
diff --git a/src/3dpropose-boundingbox.cc b/src/3dpropose-boundingbox.cc
index dc56c45..33791c7 100644
--- a/src/3dpropose-boundingbox.cc
+++ b/src/3dpropose-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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3drigidreg.cc b/src/3drigidreg.cc
index 51ead53..f5357a1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dsegment-ahmed.cc b/src/3dsegment-ahmed.cc
index 96b57e1..83fee79 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +161,8 @@ template <class T>
 CSegment3d::result_type CSegment3d::operator()(const T3DImage<T>& image)
 {
 	// first evaluate the histogram borders and get the initial class centers
-	T minh=0; 
-	T maxh=numeric_limits<T>::max(); 
+	typename T3DImage<T>::value_type minh=0; 
+	typename T3DImage<T>::value_type maxh=numeric_limits<T>::max(); 
 	
 
 	get_min_max(image.begin(), image.end(), minh, maxh);  
diff --git a/src/3dserial-nonrigid.cc b/src/3dserial-nonrigid.cc
index be623d3..f21df8e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "3dmyoserial"
-
 #include <fstream>
 #include <libxml++/libxml++.h>
 #include <itpp/signal/fastica.h>
diff --git a/src/3dseries-track-intensity.cc b/src/3dseries-track-intensity.cc
index 91e3ecb..270ebb8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "3dseries-track-intensity"
-
 #include <fstream>
 #include <ostream>
 
diff --git a/src/3dtrackpixelmovement.cc b/src/3dtrackpixelmovement.cc
index 18e7602..aec67a3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "3dtrack-pixelmovement"
-
 #include <fstream>
 #include <ostream>
 
diff --git a/src/3dtransform.cc b/src/3dtransform.cc
index 7dbc7dd..a1c2fc8 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@
  */
 
 
-#define VSTREAM_DOMAIN "mia-3dtransform"
 #include <mia/core/cmdlineparser.hh>
 #include <mia/3d/transformio.hh>
 #include <mia/3d/imageio.hh>
diff --git a/src/3dtransform2vf.cc b/src/3dtransform2vf.cc
index e4a3e45..94e147c 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "mia-3dtransform"
 #include <mia/core/cmdlineparser.hh>
 #include <mia/3d/transformio.hh>
 #include <mia/3d/vfio.hh>
diff --git a/src/3dvectorfieldcreate.cc b/src/3dvectorfieldcreate.cc
index d578050..c833e43 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/3dvf2transform.cc b/src/3dvf2transform.cc
index e2161c9..12b06b6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "mia-3dvftotransform"
 #include <mia/core/cmdlineparser.hh>
 #include <mia/3d/transformio.hh>
 #include <mia/3d/transformfactory.hh>
diff --git a/src/3dvfcompare.cc b/src/3dvfcompare.cc
index 9d2b9ee..7ccb9dc 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "mia-3dtransform"
 #include <mia/core/cmdlineparser.hh>
 #include <mia/3d/vfio.hh>
 #include <mia/internal/main.hh>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 31c229e..55bb09d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -57,6 +57,9 @@ DEFEXE(2dimagecombine-dice mia2d )
 DEFEXE(2dfuzzysegment     mia2d )
 DEFEXE(2dsegment-ahmed    mia2d )
 DEFEXE(2dsegment-fuzzyw   mia2d )
+DEFEXE(2dsegment-local-cmeans    mia2d )
+DEFEXE(2dsegment-local-kmeans    mia2d )
+DEFEXE(2dsegment-per-pixel-kmeans mia2d )
 DEFEXE(2dmultiimagevar    mia2d )
 DEFEXE(2dmultiimageregistration    mia2d )
 DEFEXE(2dmulti-force      mia2d )
@@ -92,14 +95,14 @@ DEFEXE(2dseries-mincorr       mia2dmyocardperf )
 DEFEXE(2dseries-sectionmask   mia2dmyocardperf )
 DEFEXE(2dmyoseries-dice       mia2dmyocardperf )
 DEFEXE(2dmyoseries-compdice   mia2dmyocardperf )
-DEFEXE(2dmyocard-segment      mia2dmyocardperf )
 DEFEXE(2dmyopgt-nonrigid      mia2dmyocardperf )
 DEFEXE(2dmany2one-nonrigid    mia2dmyocardperf )
 DEFEXE(2dmyoset-all2one-nonrigid    mia2dmyocardperf )
 
 IF(ITPP_FOUND) 
-  DEFEXE(2dmyoica-full      mia2dmyocardperf )
-  DEFEXE(2dmyoicapgt        mia2dmyocardperf )
+  DEFEXE(2dmyocard-segment      mia2dmyocardperf )
+  DEFEXE(2dmyoica-full          mia2dmyocardperf )
+  DEFEXE(2dmyoicapgt            mia2dmyocardperf )
   DEFEXE(2dmyomilles            mia2dmyocardperf )
   DEFEXE(2dmyocard-ica          mia2dmyocardperf )
   DEFEXE(2dmyocard-icaseries    mia2dmyocardperf )
diff --git a/src/cmeans.cc b/src/cmeans.cc
index 29e3cbe..088160f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
 #include <numeric>
 #include <fstream>
 
-#ifdef HAVE_BLAS
-extern "C" {
-#include <cblas.h>
-}
-#endif
-
-
+#include <gsl/gsl_blas.h>
 #include <mia/core/msgstream.hh>
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/probmap.hh>
@@ -143,26 +137,10 @@ double CCMeans::update_class_centers(double_vector& class_center, double_vector
 	for (size_t i = 0; i < class_center.size(); ++i) {
 		float cc = class_center[i]; 
 		
-#ifdef HAVE_BLAS
+
 		double sum_prob   = cblas_ddot(histo.size(), &histo[0], 1, &pv[i][0], 1);
 		double sum_weight = cblas_ddot(histo.size(), &shisto[0], 1, &pv[i][0], 1); 
-#else		
-		double_vector::const_iterator ihelp = histo.begin(); 
-		double_vector::const_iterator shelp = shisto.begin(); 
-		double_vector::const_iterator iprob = pv[i].begin(); 
-		double_vector::const_iterator eprob = pv[i].end();
-		
-		double sum_prob = 0.0; 
-		double sum_weight = 0.0; 
-	
-		for (size_t  ix = 0; ix < histo.size(); ++ix, ++iprob, ++ihelp, ++shelp) {
-			if (*iprob > 0.0f) {
-				sum_prob += *iprob * *ihelp; 
-				sum_weight += *iprob * *shelp; 
-			}
-		}
-		
-#endif		
+
 		if (sum_prob  != 0.0) // move slowly in the direction of new center
 			cc += 0.5 * (sum_weight / sum_prob - cc); 
 		else {
diff --git a/src/distance-mesh2mask.cc b/src/distance-mesh2mask.cc
index c68e3e9..ad74cca 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "Distance Mesh to Mask" 
-
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
diff --git a/src/filenumberpattern.cc b/src/filenumberpattern.cc
index ca1bafc..3c04181 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,9 @@ int do_main( int argc, char *argv[] )
 
 	size_t format_width = get_filename_number_pattern_width(in_filename);
 	cout << setw(format_width) << setfill('0') << 0;
+
+	// end of program, so it's not important to restore the stream state
+	// coverity[stream_format_state] 
 	return 0;
 }
 
diff --git a/src/fluid2d/NR2DMatrix.hh b/src/fluid2d/NR2DMatrix.hh
index 858a14f..03c30e6 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 edba83b..cec18b3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 77556a4..410d82d 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 6e709ee..178e4ef 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 02a7836..64ed760 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 1b10fb8..495ba69 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 e21c3a4..3b57caa 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 +147,7 @@ int do_main(int argc, char *argv[])
 	unsigned int y_shift = 0;
 
 
-	unique_ptr<C2DInterpolatorFactory>   ipfactory(create_2dinterpolation_factory(ip_bspline3, bc_mirror_on_bounds));
+	C2DInterpolatorFactory   ipfactory("bspline:d=3", "mirror");
 
 
 	while (GlobalSize.x >> x_shift > grid_start){
@@ -176,7 +176,7 @@ int do_main(int argc, char *argv[])
 			result = upscale(result, ModelScale->get_size());
 
 		register_level(*ModelScale,*RefScale,result,regrid_thresh,epsilon,
-			       (x_shift >y_shift ? x_shift : y_shift)+1,elastic,mu, lambda, *ipfactory);
+			       (x_shift >y_shift ? x_shift : y_shift)+1,elastic,mu, lambda, ipfactory);
 
 		if (alter)
 			alter = !alter;
@@ -195,7 +195,7 @@ int do_main(int argc, char *argv[])
 	cvmsg() << "Finales Level" << result.get_size() << "\n";
 
 	result = upscale(result, Model->get_size());
-	register_level(*Model,*Reference,result,regrid_thresh,epsilon,1,elastic,mu, lambda, *ipfactory);
+	register_level(*Model,*Reference,result,regrid_thresh,epsilon,1,elastic,mu, lambda, ipfactory);
 
 	cvmsg() << "Gesamtzeit: " << time(NULL)-start_time << "\n";
 
diff --git a/src/fluid2d/types.hh b/src/fluid2d/types.hh
index a6c752a..29406d0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 7ff25de..8bd5747 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 cc8ebd2..33059b5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 6981074..31522b2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 0e0233c..30032ab 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 163237f..4cb57b2 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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.cc b/src/fluid3d/sor_solver.cc
index 22218ea..ee27674 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 +21,11 @@
 #include <errno.h>
 
 #include <mia/core/threadedmsg.hh>
-#include <tbb/parallel_reduce.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
 
 #include "sor_solver.hh"
 
 
-
 #include <iostream>
 using namespace std;
 using namespace mia;
@@ -255,7 +253,7 @@ int TSORSolver::solve(const C3DFVectorfield& b, C3DFVectorfield *xvf)
 	  are not syncronized. This is not a big deal, because the solver is stable, in the worst case convergence 
 	  is a bit slower. 
 	 */
-	auto solve_slice = [this, &b, &xvf](const tbb::blocked_range<size_t>& range, float res) -> float{
+	auto solve_slice = [this, &b, &xvf](const C1DParallelRange& range, float res) -> float{
 		CThreadMsgStream thread_stream;
 		for (auto z = range.begin(); z != range.end();++z) {
 			int hardcode = z * d_xy + size.x + 1;
@@ -275,8 +273,8 @@ int TSORSolver::solve(const C3DFVectorfield& b, C3DFVectorfield *xvf)
 
 	float residuum = 0.0; 
 	do {
-		residuum = tbb::parallel_reduce( tbb::blocked_range<size_t>(1, size.z-1, 4), 0.0f, solve_slice, 
-						 [](float x, float y){return x+y;}); 
+		residuum = preduce( C1DParallelRange(1, size.z-1, 4), 0.0f, solve_slice, 
+				    [](float x, float y){return x+y;}); 
 		
 		if (firsttime) {
 			firstres = residuum;
@@ -333,7 +331,7 @@ int TSORASolver::solve(const C3DFVectorfield& b,C3DFVectorfield *xvf)
 	  up memory access.
 	*/
 	auto first_run =[this, &b, &xvf, &residua, &update_needed]
-		(const tbb::blocked_range<size_t>& range, float firstres) -> float {
+		(const C1DParallelRange& range, float firstres) -> float {
 		CThreadMsgStream thread_stream;
 		for (auto z = range.begin(); z != range.end();++z) {
 			int hardcode = z * d_xy + size.x + 1;
@@ -356,14 +354,15 @@ int TSORASolver::solve(const C3DFVectorfield& b,C3DFVectorfield *xvf)
 		return firstres; 
 	};
 	
-	firstres = tbb::parallel_reduce( tbb::blocked_range<size_t>(1, size.z-1, 4), 0.0f, first_run, 
-				    [](float x, float y){return x+y;}); 
-
+	firstres = preduce( C1DParallelRange(1, size.z-1, 4), 0.0f, first_run, 
+			    [](float x, float y){return x+y;}); 
+	
 	doorstep = firstres / gSize;
 	lastres = firstres;
 	int nIter = 1;
 
-	auto iterate_run =[this, &b, &xvf, &doorstep, &residua, &update_needed, &need_update](const tbb::blocked_range<size_t>& range, float res) -> float {
+	auto iterate_run =[this, &b, &xvf, &doorstep, &residua, &update_needed, &need_update]
+		(const C1DParallelRange& range, float res) -> float {
 		CThreadMsgStream thread_stream;
 		for (auto z = range.begin(); z != range.end();++z) {
 			int hardcode = z * d_xy + size.x + 1;
@@ -391,19 +390,19 @@ int TSORASolver::solve(const C3DFVectorfield& b,C3DFVectorfield *xvf)
 	};
 
 	do {
-		res = tbb::parallel_reduce( tbb::blocked_range<size_t>(1, size.z-1, 4), 0.0f, iterate_run, 
-					    [](float x, float y){return x+y;}); 
+		res = preduce( C1DParallelRange(1, size.z-1, 4), 0.0f, iterate_run, 
+			       [](float x, float y){return x+y;}); 
 		
 		doorstep = res * res / (gSize * lastres * nIter * nIter);
 		lastres = res;
 		
 		// FIXME replace this by STL confom fill
 		update_needed->clear();
-
+		
 		std::swap(update_needed, need_update); 
 		cvinfo() << "SORA: [" << ++nIter << "]" << res << "\n";
 	}while (res > firstres * rel_res && nIter < max_steps && res > abs_res );
-
+	
 	// return why we have finished
 	if (nIter >= max_steps) return 1;
 	if (res < firstres * rel_res) return 2;
diff --git a/src/fluid3d/sor_solver.hh b/src/fluid3d/sor_solver.hh
index 62dcd5e..cfb4f23 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 9573858..1f85b10 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 e01ce8f..f88b8d3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
 #include <mia/3d/deformer.hh>
 
 #include <mia/core/threadedmsg.hh>
-#include <tbb/parallel_reduce.h>
-#include <tbb/parallel_for.h>
-#include <tbb/blocked_range.h>
-
+#include <mia/core/parallel.hh>
 
 //#include "3Dinterpolator.hh"
 #include "vfluid.hh"
@@ -168,7 +165,7 @@ inline C3DFVector TFluidReg::forceAt(int hardcode,float *misma)const
 
 float  TFluidReg::calculatePerturbation()
 {
-	auto callback = [this](const tbb::blocked_range<size_t>& range, float gamma) -> float{
+	auto callback = [this](const C1DParallelRange& range, float gamma) -> float{
 		C3DBounds max_p; 
 		for (auto z = range.begin(); z != range.end();++z)
 			for (size_t y = Start.y; y < End.y; y++)  {
@@ -185,17 +182,17 @@ float  TFluidReg::calculatePerturbation()
 		return gamma; 
 	}; 
 
-	float gamma = tbb::parallel_reduce( tbb::blocked_range<size_t>(Start.z, End.z, 1), 
-					   0.0f, callback, 
-					   [](float x, float y){return max(x,y);}); 
-
+	float gamma = preduce( C1DParallelRange(Start.z, End.z, 1), 
+			       0.0f, callback, 
+			       [](float x, float y){return max(x,y);}); 
+	
 	cvinfo() << "pert = " << gamma << "\n";
 	return gamma;
 }
 
 float  TFluidReg::calculateJacobian()const
 {
-	auto callback = [this](const tbb::blocked_range<size_t>& range, float jmin) -> float{
+	auto callback = [this](const C1DParallelRange& range, float jmin) -> float{
 		for (auto z = range.begin(); z != range.end();++z)
 			for (size_t y = Start.y+1; y < End.y-1; y++)
 				for (size_t x = Start.x+1; x < End.x-1; x++) {
@@ -206,9 +203,9 @@ float  TFluidReg::calculateJacobian()const
 	}; 
 	
 	
-	float jmin = tbb::parallel_reduce( tbb::blocked_range<size_t>(Start.z + 1, End.z-1, 1), 
-					   numeric_limits<float>::max(), callback, 
-					   [](float x, float y){return min(x,y);}); 
+	float jmin = preduce( C1DParallelRange(Start.z + 1, End.z-1, 1), 
+			      numeric_limits<float>::max(), callback, 
+			      [](float x, float y){return min(x,y);}); 
 	cvinfo() << "jacobian = " << jmin << endl;
         return jmin;
 }
@@ -324,7 +321,7 @@ void TFluidReg::DeleteTemps()
 
 float	TFluidReg::calculateForces()
 {
-	auto callback = [this](const tbb::blocked_range<size_t>& range, float mismatch) -> float{
+	auto callback = [this](const C1DParallelRange& range, float mismatch) -> float{
 		CThreadMsgStream thread_stream;
 		C3DBounds max_p; 
 		for (auto z = range.begin(); z != range.end();++z) {
@@ -342,11 +339,11 @@ float	TFluidReg::calculateForces()
 		return mismatch; 
         }; 
 	
-	float mismatch = tbb::parallel_reduce( tbb::blocked_range<size_t>(Start.z, End.z, 1), 
-					       0.0f, callback, 
-					       [](float x, float y){return x + y;}); 
+	float mismatch = preduce( C1DParallelRange(Start.z, End.z, 1), 
+				  0.0f, callback, 
+				  [](float x, float y){return x + y;}); 
+	
 	
-
 	return mismatch/ref.size();
 }
 
@@ -398,9 +395,9 @@ float  TFluidReg::perturbationAt(int x, int y, int z)
 
 void  TFluidReg::ApplyShift()
 {
-	auto callback = [this](const tbb::blocked_range<size_t>& range){
+	auto callback = [this](const C1DParallelRange& range){
 		CThreadMsgStream thread_stream;
-
+		
 		for (auto z = range.begin(); z != range.end();++z) {
 			int iz = z - Start.z; 
 			int iy = 0;
@@ -411,10 +408,10 @@ void  TFluidReg::ApplyShift()
 			}
 		}
 	}; 
-	tbb::parallel_for(tbb::blocked_range<size_t>(Start.z, End.z, 1), callback); 
-
+	pfor(C1DParallelRange(Start.z, End.z, 1), callback); 
+	
 	tmp = C3DFImage(src.get_size());
-
+	
 
 
 	FDeformer3D deformer(*u, ipf);
@@ -503,7 +500,7 @@ P3DFVectorfield upscale( const C3DFVectorfield& vf, C3DBounds size)
 	float iy_mult = 1.0f / y_mult;
 	float iz_mult = 1.0f / z_mult;
 
-	auto callback = [&](const tbb::blocked_range<size_t>& range){
+	auto callback = [&](const C1DParallelRange& range){
 		CThreadMsgStream thread_stream;
 		
 		for (auto z = range.begin(); z != range.end();++z) { 
@@ -516,8 +513,8 @@ P3DFVectorfield upscale( const C3DFVectorfield& vf, C3DBounds size)
 				}
 		}
 	}; 
-	tbb::parallel_for(tbb::blocked_range<size_t>(0, size.z, 1), callback);
-
+	pfor(C1DParallelRange(0, size.z, 1), callback);
+	
 	return Result;
 }
 
diff --git a/src/fluid3d/vfluid.hh b/src/fluid3d/vfluid.hh
index 853e742..b83324b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 c24040b..0ba675f 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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_backend.cc b/src/isosurface/iso_backend.cc
index f91c040..0cf80d5 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 8772b56..b77becb 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/mesh_convert.cc b/src/isosurface/mesh_convert.cc
index c08e10a..9e869d1 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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 f52a98e..73ee689 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/mesh-deformable-model.cc b/src/mesh-deformable-model.cc
index 55f6448..ad9684e 100644
--- a/src/mesh-deformable-model.cc
+++ b/src/mesh-deformable-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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,7 @@
 
 #include <mia/core/threadedmsg.hh>
 #include <mia/core/nccsum.hh>
-#include <tbb/parallel_reduce.h>
-#include <tbb/blocked_range.h>
+#include <mia/core/parallel.hh>
 
 NS_MIA_USE;
 using namespace std;
@@ -143,7 +142,7 @@ PTriangleMesh DeformableModel::run(const CTriangleMesh& mesh, const C3DFImage& r
 	typedef pair<float, float> result_t; 
 	
 	auto apply =[this, &out_vertex, &result, &model, &gradient, &R]
-		(const tbb::blocked_range<size_t>& range, result_t res) -> result_t {
+		(const C1DParallelRange& range, result_t res) -> result_t {
 		CThreadMsgStream msks; 
 		for (auto i = range.begin(); i != range.end(); ++i) {
 			auto& vertex = result->vertex_at(i); 
@@ -189,13 +188,13 @@ PTriangleMesh DeformableModel::run(const CTriangleMesh& mesh, const C3DFImage& r
 		result_t r{0.0f, 0.0f}; 
 
 		
-		r = parallel_reduce(tbb::blocked_range<size_t>(0, model.size(), model.size() / 1000 ), r, apply, 
-				[](const result_t& a, const result_t& b) -> result_t {
-					result_t r; 
-					r.first = a.first + b.first; 
-					r.second = a.second > b.second ? a.second : b.second; 
-					return r; 
-				});
+		r = preduce(C1DParallelRange(0, model.size(), model.size() / 1000 ), r, apply, 
+			    [](const result_t& a, const result_t& b) -> result_t {
+				    result_t r; 
+				    r.first = a.first + b.first; 
+				    r.second = a.second > b.second ? a.second : b.second; 
+				    return r; 
+			    });
                 
                 copy(out_vertex.begin(), out_vertex.end(), result->vertices_begin()); 
 		result->evaluate_normals();
diff --git a/src/mesh-to-maskimage.cc b/src/mesh-to-maskimage.cc
index f24debc..ffec078 100644
--- a/src/mesh-to-maskimage.cc
+++ b/src/mesh-to-maskimage.cc
@@ -1,7 +1,7 @@
 /* -*- mia-c++  -*-
  *
  * This file is part of MIA - a toolbox for medical image analysis 
- * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/meshdistance-to-stackmask.cc b/src/meshdistance-to-stackmask.cc
index 0a9d3a9..747a3c7 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,8 +18,6 @@
  *
  */
 
-#define VSTREAM_DOMAIN "Distance Mesh to Mask" 
-
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -66,7 +64,7 @@ struct FDistAcummulator : public TFilter<void> {
 	template <typename T> 
 	void operator ()(const T2DImage<T>& image) {
 		C2DFImage buf(image.get_size()); 
-		distance_transform_prepare(image.begin(), image.end(), buf.begin()); 
+		distance_transform_prepare(image.begin(), image.end(), buf.begin(), __is_mask_pixel<T>::value); 
 		m_distance.push_slice(m_z, buf); 
 		++m_z; 
 	}
diff --git a/src/meshfilter.cc b/src/meshfilter.cc
index 59bc833..2eb98e3 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/multihist.cc b/src/multihist.cc
index 1dad1af..1fb360e 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/multiimage-cmeans.cc b/src/multiimage-cmeans.cc
index 02a2998..2971de3 100644
--- a/src/multiimage-cmeans.cc
+++ b/src/multiimage-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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/myowavelettest.cc b/src/myowavelettest.cc
index dc91712..657b4d0 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 +18,11 @@
  *
  */
 
-#define VSTREAM_DOMAIN "wavelet"
-
 #include <fstream>
 #include <sstream>
 #include <iostream>
 #include <stdexcept>
-#include <gsl++/wavelet.hh>
+#include <mia/core/gsl_wavelet.hh>
 
 #include <mia/core/msgstream.hh>
 #include <mia/core/cmdlineparser.hh>
diff --git a/src/plugin-help.cc b/src/plugin-help.cc
index 8693b15..24768c4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/raw2image.cc b/src/raw2image.cc
index a337ba3..e1dfcab 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/raw2volume.cc b/src/raw2volume.cc
index 95deaf0..aeb9f58 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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/test_plugins_as_installed.cc b/src/test_plugins_as_installed.cc
index bbaf29c..7c885d4 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -203,7 +203,7 @@ BOOST_FIXTURE_TEST_CASE(test_CNoiseGeneratorPluginHandler,PluginTestFixture)
 BOOST_FIXTURE_TEST_CASE(test_C1DSpacialKernelPluginHandler,PluginTestFixture) 
 {
 	set<string> test_data = {
-		"gauss", "cdiff"
+		"gauss", "cdiff", "scharr"
 	}; 
 	test(C1DSpacialKernelPluginHandler::instance().get_set(), test_data); 
 }
@@ -262,10 +262,11 @@ BOOST_FIXTURE_TEST_CASE(test_C2DFilterPluginHandler,PluginTestFixture)
 		"adaptmed", "admean", "aniso", "bandpass", "binarize", "combiner",
 		"convert", "close", "crop", "dilate", "distance", 
 		"downscale", "erode", "gauss", "gradnorm", "invert", "kmeans", 
-		"label", "labelmap", "labelscale", "load", "mask", "mean", "median", "mlv", 
+		"label", "labelmap", "labelscale", "load", "mask", "mean", "meanvar",
+		"median", "medianmad", "mlv", 
 		"ngfnorm", "noise", "open", "pruning", "regiongrow", "sandp", 
 		"scale", "selectbig", "sepconv", "shmean", "sobel",
-		"sort-label", "sws", "tee", "thinning", "thresh",
+		"sort-label", "sws", "tee", "thinning", "thresh", "tmean", 
 		"transform", "ws"
 	};
 #ifdef HAVE_MAXFLOW
diff --git a/src/wavelettrans.cc b/src/wavelettrans.cc
index 20186d5..5e30a44 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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,13 +18,12 @@
  *
  */
 
-#define VSTREAM_DOMAIN "wavelet"
-
+#include <cmath>
 #include <fstream>
 #include <sstream>
 #include <iostream>
 #include <stdexcept>
-#include <gsl++/wavelet.hh>
+#include <mia/core/gsl_wavelet.hh>
 
 #include <mia/core/msgstream.hh>
 #include <mia/core/cmdlineparser.hh>
diff --git a/test/test_ioplugins.cc b/test/test_ioplugins.cc
index 2a0f0a1..0a8c631 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * MIA is free 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_minimizer.cc b/test/test_minimizer.cc
index f189b8c..4d1551b 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-2015 Gert Wollny
+ * Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
  *
  * 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 @@
 #include <mia/core/minimizer.hh>
 #include <mia/core/cmdlineparser.hh>
 #include <mia/core/msgstream.hh>
-
+#include <numeric>
 
 
 using namespace std; 
diff --git a/testdata/4D.off b/testdata/4D.off
new file mode 100644
index 0000000..fe336cb
--- /dev/null
+++ b/testdata/4D.off
@@ -0,0 +1,6 @@
+4OFF
+3 1 3
+1 0 0 0
+0 1 0 0
+0 0 0 1
+1 2 3
diff --git a/testdata/EnIm1.dcm b/testdata/EnIm1.dcm
new file mode 100644
index 0000000..8856d51
Binary files /dev/null and b/testdata/EnIm1.dcm differ
diff --git a/testdata/ND.off b/testdata/ND.off
new file mode 100644
index 0000000..a1ecd3d
--- /dev/null
+++ b/testdata/ND.off
@@ -0,0 +1,7 @@
+nOFF
+5
+3 1 3
+1 0 0 0 0
+0 1 3 0 0
+0 0 0 1 2
+1 2 3
diff --git a/testdata/binary100x2uc.bmp b/testdata/binary100x2uc.bmp
new file mode 100644
index 0000000..9b4a11e
Binary files /dev/null and b/testdata/binary100x2uc.bmp differ
diff --git a/testdata/gray100x2c-4bit.bmp b/testdata/gray100x2c-4bit.bmp
new file mode 100644
index 0000000..34ad5c7
Binary files /dev/null and b/testdata/gray100x2c-4bit.bmp differ
diff --git a/testdata/gray100x2c.bmp b/testdata/gray100x2c.bmp
new file mode 100644
index 0000000..e63e713
Binary files /dev/null and b/testdata/gray100x2c.bmp differ
diff --git a/testdata/gray100x2uc-4bit.bmp b/testdata/gray100x2uc-4bit.bmp
new file mode 100644
index 0000000..843fc6c
Binary files /dev/null and b/testdata/gray100x2uc-4bit.bmp differ
diff --git a/testdata/gray20x20c.bmp b/testdata/gray20x20c.bmp
new file mode 100644
index 0000000..a683130
Binary files /dev/null and b/testdata/gray20x20c.bmp differ
diff --git a/testdata/gray20x20c.jpg b/testdata/gray20x20c.jpg
new file mode 100644
index 0000000..5ca5d58
Binary files /dev/null and b/testdata/gray20x20c.jpg differ
diff --git a/testdata/gray20x20c.tif b/testdata/gray20x20c.tif
new file mode 100644
index 0000000..8533f30
Binary files /dev/null and b/testdata/gray20x20c.tif differ
diff --git a/testdata/gray2x3-1.png b/testdata/gray2x3-1.png
new file mode 100644
index 0000000..e564586
Binary files /dev/null and b/testdata/gray2x3-1.png differ
diff --git a/testdata/gray2x3-1.tif b/testdata/gray2x3-1.tif
new file mode 100644
index 0000000..bcbca6d
Binary files /dev/null and b/testdata/gray2x3-1.tif differ
diff --git a/testdata/gray2x3-16.png b/testdata/gray2x3-16.png
new file mode 100644
index 0000000..5862b5d
Binary files /dev/null and b/testdata/gray2x3-16.png differ
diff --git a/testdata/gray2x3-16.tif b/testdata/gray2x3-16.tif
new file mode 100644
index 0000000..9e7a91c
Binary files /dev/null and b/testdata/gray2x3-16.tif differ
diff --git a/testdata/gray2x3-multiframe.tif b/testdata/gray2x3-multiframe.tif
new file mode 100644
index 0000000..00ff1d0
Binary files /dev/null and b/testdata/gray2x3-multiframe.tif differ
diff --git a/testdata/gray2x3.bmp b/testdata/gray2x3.bmp
new file mode 100644
index 0000000..ae29abb
Binary files /dev/null and b/testdata/gray2x3.bmp differ
diff --git a/testdata/gray2x3.c b/testdata/gray2x3.c
new file mode 100644
index 0000000..91376ad
--- /dev/null
+++ b/testdata/gray2x3.c
@@ -0,0 +1,12 @@
+/* GIMP RGB C-Source image dump (gray2x3.c) */
+
+static const struct {
+  guint  	 width;
+  guint  	 height;
+  guint  	 bytes_per_pixel; /* 2:RGB16, 3:RGB, 4:RGBA */ 
+  guint8 	 pixel_data[2 * 3 * 3 + 1];
+} gimp_image = {
+  2, 3, 3,
+  "\0\0\0???\200\200\200\276\276\276\345\345\345\377\377\377",
+};
+
diff --git a/testdata/gray2x3.jpg b/testdata/gray2x3.jpg
new file mode 100644
index 0000000..96265b7
Binary files /dev/null and b/testdata/gray2x3.jpg differ
diff --git a/testdata/gray2x3.png b/testdata/gray2x3.png
new file mode 100644
index 0000000..1915e7e
Binary files /dev/null and b/testdata/gray2x3.png differ
diff --git a/testdata/gray2x3.tif b/testdata/gray2x3.tif
new file mode 100644
index 0000000..5f76c8f
Binary files /dev/null and b/testdata/gray2x3.tif differ
diff --git a/testdata/octahedron-with-normals-and-color.off b/testdata/octahedron-with-normals-and-color.off
new file mode 100644
index 0000000..af985f7
--- /dev/null
+++ b/testdata/octahedron-with-normals-and-color.off
@@ -0,0 +1,17 @@
+CNOFF
+# Octaeder with normals,  wit color information 
+6 8 12
+2 0 0 1 0 0 0.1 0.5 0.5 
+-2 0 0 -1 0 0 0.2 0.6 0.7
+0  2  0 0 1 0 0.3 0.6 0.7
+0 -2  0 0 -1 0 0.4 0.6 0.7
+0  0  1 0 0 1 0.5 0.6 0.7
+0  0 -1 0 0 -1 0.6 0.6 0.7
+3 4 0 2
+3 4 2 1 
+3 4 1 3
+3 4 3 0 
+3 5 2 0
+3 5 1 2 
+3 5 3 1
+3 5 0 3
diff --git a/testdata/octahedron-with-normals-and-color.ply b/testdata/octahedron-with-normals-and-color.ply
new file mode 100644
index 0000000..e5c9821
--- /dev/null
+++ b/testdata/octahedron-with-normals-and-color.ply
@@ -0,0 +1,32 @@
+ply
+format ascii 1.0
+comment Octaeder
+comment with normal
+comment without color information
+element vertex 6
+property float32 x
+property float32 y
+property float32 z
+property float32 nx
+property float32 ny
+property float32 nz
+property float32 red
+property float32 green
+property float32 blue
+element face 8
+property list uint8 uint32 vertex_index
+end_header
+2 0 0 1 0 0 0.1 0.5 0.5 
+-2 0 0 -1 0 0 0.2 0.6 0.7
+0  2  0 0 1 0 0.3 0.6 0.7
+0 -2  0 0 -1 0 0.4 0.6 0.7
+0  0  1 0 0 1 0.5 0.6 0.7
+0  0 -1 0 0 -1 0.6 0.6 0.7
+3 4 0 2
+3 4 2 1 
+3 4 1 3
+3 4 3 0 
+3 5 2 0
+3 5 1 2 
+3 5 3 1
+3 5 0 3
diff --git a/testdata/octahedron-with-normals-and-scale.ply b/testdata/octahedron-with-normals-and-scale.ply
new file mode 100644
index 0000000..c7f6fcd
--- /dev/null
+++ b/testdata/octahedron-with-normals-and-scale.ply
@@ -0,0 +1,30 @@
+ply
+format ascii 1.0
+comment Octaeder
+comment with normal
+comment without color information
+element vertex 6
+property float32 x
+property float32 y
+property float32 z
+property float32 nx
+property float32 ny
+property float32 nz
+property float32 scale
+element face 8
+property list uint8 uint32 vertex_index
+end_header
+2 0 0 1 0 0 0.1
+-2 0 0 -1 0 0 2.2
+0 2 0 0 1 0 4.3
+0 -2 0 0 -1 0 3.4
+0 0 1 0 0 1 0.5
+0 0 -1 0 0 -1 0.6
+3 4 0 2
+3 4 2 1 
+3 4 1 3
+3 4 3 0 
+3 5 2 0
+3 5 1 2 
+3 5 3 1
+3 5 0 3
diff --git a/testdata/octahedron-with-normals.off b/testdata/octahedron-with-normals.off
new file mode 100644
index 0000000..8c92c5a
--- /dev/null
+++ b/testdata/octahedron-with-normals.off
@@ -0,0 +1,17 @@
+NOFF
+# Octaeder with normals,  without color information 
+6 8 12
+2 0 0 1 0 0
+-2 0 0 -1 0 0
+0  2  0 0 1 0
+0 -2  0 0 -1 0
+0  0  1 0 0 1
+0  0 -1 0 0 -1
+3 4 0 2
+3 4 2 1 
+3 4 1 3
+3 4 3 0 
+3 5 2 0
+3 5 1 2 
+3 5 3 1
+3 5 0 3
diff --git a/testdata/octahedron-with-normals.ply b/testdata/octahedron-with-normals.ply
new file mode 100644
index 0000000..8a6fb8d
--- /dev/null
+++ b/testdata/octahedron-with-normals.ply
@@ -0,0 +1,29 @@
+ply
+format ascii 1.0
+comment Octaeder
+comment with normal
+comment without color information
+element vertex 6
+property float32 x
+property float32 y
+property float32 z
+property float32 nx
+property float32 ny
+property float32 nz
+element face 8
+property list uint8 uint32 vertex_index
+end_header
+2 0 0 1 0 0
+-2 0 0 -1 0 0
+0  2  0 0 1 0
+0 -2  0 0 -1 0
+0  0  1 0 0 1
+0  0 -1 0 0 -1
+3 4 0 2
+3 4 2 1 
+3 4 1 3
+3 4 3 0 
+3 5 2 0
+3 5 1 2 
+3 5 3 1
+3 5 0 3
diff --git a/testdata/octahedron.off b/testdata/octahedron.off
new file mode 100644
index 0000000..f06384f
--- /dev/null
+++ b/testdata/octahedron.off
@@ -0,0 +1,17 @@
+OFF
+# Octaeder without color information 
+6 8 12
+2 0 0
+-2 0 0
+0  2  0
+0 -2  0
+0  0  1
+0  0 -1
+3 4 0 2
+3 4 2 1 
+3 4 1 3
+3 4 3 0 
+3 5 2 0
+3 5 1 2 
+3 5 3 1
+3 5 0 3
diff --git a/testdata/octahedron.ply b/testdata/octahedron.ply
new file mode 100644
index 0000000..c89497b
--- /dev/null
+++ b/testdata/octahedron.ply
@@ -0,0 +1,24 @@
+ply
+format ascii 1.0
+comment Octaeder without color information
+element vertex 6
+property float32 x
+property float32 y
+property float32 z
+element face 8
+property list uint8 int32 vertex_index
+end_header
+2 0 0
+-2 0 0
+0  2  0
+0 -2  0
+0  0  1
+0  0 -1
+3 4 0 2
+3 4 2 1 
+3 4 1 3
+3 4 3 0 
+3 5 2 0
+3 5 1 2 
+3 5 3 1
+3 5 0 3
diff --git a/testdata/octahedron.stl b/testdata/octahedron.stl
new file mode 100644
index 0000000..879d210
--- /dev/null
+++ b/testdata/octahedron.stl
@@ -0,0 +1,58 @@
+solid
+  facet normal 0.408248 0.408248 0.816497
+    outer loop
+      vertex 0 0 1
+      vertex 2 0 0
+      vertex 0 2 0
+    endloop
+  endfacet
+  facet normal -0.408248 0.408248 0.816497
+    outer loop
+      vertex 0 0 1
+      vertex 0 2 0
+      vertex -2 0 0
+    endloop
+  endfacet
+  facet normal -0.408248 -0.408248 0.816497
+    outer loop
+      vertex 0 0 1
+      vertex -2 0 0
+      vertex 0 -2 0
+    endloop
+  endfacet
+  facet normal 0.408248 -0.408248 0.816497
+    outer loop
+      vertex 0 0 1
+      vertex 0 -2 0
+      vertex 2 0 0
+    endloop
+  endfacet
+  facet normal 0.408248 0.408248 -0.816497
+    outer loop
+      vertex 0 0 -1
+      vertex 0 2 0
+      vertex 2 0 0
+    endloop
+  endfacet
+  facet normal -0.408248 0.408248 -0.816497
+    outer loop
+      vertex 0 0 -1
+      vertex -2 0 0
+      vertex 0 2 0
+    endloop
+  endfacet
+  facet normal -0.408248 -0.408248 -0.816497
+    outer loop
+      vertex 0 0 -1
+      vertex 0 -2 0
+      vertex -2 0 0
+    endloop
+  endfacet
+  facet normal 0.408248 -0.408248 -0.816497
+    outer loop
+      vertex 0 0 -1
+      vertex 2 0 0
+      vertex 0 -2 0
+    endloop
+  endfacet
+endsolid
diff --git a/testdata/poly.off b/testdata/poly.off
new file mode 100644
index 0000000..28fac44
--- /dev/null
+++ b/testdata/poly.off
@@ -0,0 +1,8 @@
+OFF
+4 1 4
+1 0 0
+1 1 0
+2 1 0
+2 3 0 
+4 0 1 2 3
+
diff --git a/testdata/rgb3x2-24bit.bmp b/testdata/rgb3x2-24bit.bmp
new file mode 100644
index 0000000..0213f25
Binary files /dev/null and b/testdata/rgb3x2-24bit.bmp differ
diff --git a/testdata/rgb3x2-24bit.jpg b/testdata/rgb3x2-24bit.jpg
new file mode 100644
index 0000000..4198a44
Binary files /dev/null and b/testdata/rgb3x2-24bit.jpg differ
diff --git a/testdata/rgb3x2-24bit.png b/testdata/rgb3x2-24bit.png
new file mode 100644
index 0000000..b1d8a58
Binary files /dev/null and b/testdata/rgb3x2-24bit.png differ
diff --git a/testdata/vertex_error.off b/testdata/vertex_error.off
new file mode 100644
index 0000000..1ab4176
--- /dev/null
+++ b/testdata/vertex_error.off
@@ -0,0 +1,7 @@
+OFF
+# Octaeder without color information 
+4 1 4
+1 0 0
+1 1 0
+2 1 
+

-- 
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