From 7fb2825e2af89bbf7d871d61c072816178de9356 Mon Sep 17 00:00:00 2001
From: Jurjan Bootsma <jbootsma@km3net.de>
Date: Mon, 7 Nov 2022 08:21:08 +0000
Subject: [PATCH] Add JOscProb tools and interactive sliders for oscillation
 probabilities

---
 .gitlab-ci.yml                                |    2 +-
 examples/interactive_oscprob.ipynb            |  439 ++++++
 examples/oscprob_python.ipynb                 |  402 +++++
 scripts/create_venv.sh                        |    4 +-
 setup.py                                      |    2 +-
 src/jpp/JIO/JBufferedIO.hh                    |   27 +-
 src/jpp/JIO/JFileStreamIO.hh                  |   21 +
 src/jpp/JIO/JSerialisable.hh                  |   30 +-
 src/jpp/JLang/JAbstractFile.hh                |   95 ++
 src/jpp/JLang/JAbstractIO.hh                  |  114 ++
 src/jpp/JLang/JAnyType.hh                     |   31 +
 src/jpp/JLang/JAssert.hh                      |    8 +-
 src/jpp/JLang/JCategory.hh                    |   41 +
 src/jpp/JLang/JColorFacet.hh                  |  358 +++++
 src/jpp/JLang/JComparisonAvailable.hh         |  129 ++
 src/jpp/JLang/JEquation.hh                    |  381 +++++
 src/jpp/JLang/JEquationFacet.hh               |  611 ++++++++
 src/jpp/JLang/JEquationParameters.hh          |  454 ++++++
 src/jpp/JLang/JException.hh                   |   28 +-
 src/jpp/JLang/JFile.hh                        |  168 +++
 src/jpp/JLang/JFileDescriptorMask.hh          |  290 ++++
 src/jpp/JLang/JFileStream.hh                  |   89 ++
 src/jpp/JLang/JFileStreamBuffer.hh            |  258 ++++
 src/jpp/JLang/JLangToolkit.hh                 |   19 +-
 src/jpp/JLang/JManip.hh                       |   43 +
 src/jpp/JLang/JObjectIO.hh                    |   39 +-
 src/jpp/JLang/JObjectStreamIO.hh              |   48 +
 src/jpp/JLang/JParameter.hh                   |  197 +++
 src/jpp/JLang/JPrintHelper.hh                 |  214 +++
 src/jpp/JLang/JSTDTypes.hh                    |   40 +-
 src/jpp/JLang/JStreamAvailable.hh             |  173 +++
 src/jpp/JLang/JStreamState.hh                 |   77 +
 src/jpp/JLang/JString.hh                      |  502 +++++++
 src/jpp/JLang/JStringFacet.hh                 |  313 ++++
 src/jpp/JLang/JStringStream.hh                |   72 +
 src/jpp/JLang/JTest.hh                        |   49 +
 src/jpp/JLang/JTimeval.hh                     |  209 +++
 src/jpp/JLang/JTypeList.hh                    |  460 ++++++
 src/jpp/JLang/JValue.hh                       |  239 +++
 src/jpp/JLang/JVectorize.hh                   |   19 +-
 src/jpp/JMath/JMath.hh                        |    4 +-
 src/jpp/JMath/JMathSupportkit.hh              |   91 +-
 src/jpp/JOscProb/JBaselineCalculator.hh       |  195 +++
 src/jpp/JOscProb/JOscChannel.hh               |  328 +++++
 src/jpp/JOscProb/JOscParameters.hh            |  128 ++
 src/jpp/JOscProb/JOscParametersGrid.hh        |  129 ++
 src/jpp/JOscProb/JOscParametersInterface.hh   |  440 ++++++
 src/jpp/JOscProb/JOscProb.hh                  |   46 +
 src/jpp/JOscProb/JOscProbInterpolator.hh      |  331 +++++
 .../JOscProb/JOscProbInterpolatorInterface.hh |  115 ++
 src/jpp/JOscProb/JOscProbToolkit.hh           |  122 ++
 src/jpp/JPhysics/JConstants.hh                |    1 +
 src/jpp/JPhysics/JGeane.hh                    |   82 +-
 src/jpp/JPhysics/JNPE_t.hh                    |   24 +-
 src/jpp/JPhysics/JPDFTable.hh                 |   56 +-
 src/jpp/JPhysics/JPDFToolkit.hh               |  184 +--
 src/jpp/JPhysics/JPDFTransformer.hh           |   12 +-
 src/jpp/JPhysics/JPDFTypes.hh                 |   34 +-
 src/jpp/JPhysics/JPDF_t.hh                    |    4 +-
 src/jpp/JSystem/JDate.hh                      |  298 ++++
 src/jpp/JSystem/JStat.hh                      |  177 +++
 src/jpp/JTools/JAbstractCollection.hh         |   34 +-
 src/jpp/JTools/JAbstractHistogram.hh          |  177 +++
 src/jpp/JTools/JArray.hh                      |   54 +-
 src/jpp/JTools/JCollection.hh                 |   19 +-
 src/jpp/JTools/JGrid.hh                       |   49 +-
 src/jpp/JTools/JGridMap.hh                    |    1 +
 src/jpp/JTools/JHermiteSpline.hh              |   18 +-
 src/jpp/JTools/JHistogram.hh                  |   11 +
 src/jpp/JTools/JHistogram1D.hh                |  650 +++++++++
 src/jpp/JTools/JMultiFunction.hh              |   54 +-
 src/jpp/JTools/JMultiKey.hh                   |   20 +-
 src/jpp/JTools/JMultiMap.hh                   | 1121 ++++++--------
 src/jpp/JTools/JMultiMapTransformer.hh        |    2 +-
 src/jpp/JTools/JPolint.hh                     |  203 +--
 src/jpp/JTools/JQuadrature.hh                 |   32 +-
 src/jpp/JTools/JRange.hh                      |   47 +-
 src/jpp/JTools/JResult.hh                     |   10 +-
 src/jpp/JTools/JSet.hh                        |   34 +
 src/jpp/JTools/JSpline.hh                     |   64 +-
 src/jpp/JTools/JTransformableMultiFunction.hh |   14 +-
 src/jpp/Jeep/JColor.hh                        |   27 +
 src/jpp/Jeep/JComparisonToolkit.hh            |   69 +
 src/jpp/Jeep/JMessage.hh                      |  102 ++
 src/jpp/Jeep/JPrint.hh                        |  138 ++
 src/jpp/Jeep/JProperties.hh                   | 1294 +++++++++++++++++
 src/jpp/Jeep/JStreamToolkit.hh                |  538 +++++++
 src/jpp/Jeep/JeepToolkit.hh                   |   40 +
 src/jpp/README.md                             |    2 +-
 src/jppy/JppyOscProbInterpolator.hh           |  161 ++
 src/jppy/__init__.py                          |    2 +
 src/jppy/geane.cc                             |   20 +-
 src/jppy/lang.cc                              |   45 +
 src/jppy/oscprob.cc                           |  403 +++++
 src/jppy/pdf_evaluator.py                     |    2 +-
 src/jppy/utils.hh                             |   28 +
 tests/test_joscprob.py                        |   78 +
 97 files changed, 13759 insertions(+), 1300 deletions(-)
 create mode 100644 examples/interactive_oscprob.ipynb
 create mode 100644 examples/oscprob_python.ipynb
 create mode 100644 src/jpp/JLang/JAbstractFile.hh
 create mode 100644 src/jpp/JLang/JAbstractIO.hh
 create mode 100644 src/jpp/JLang/JAnyType.hh
 create mode 100644 src/jpp/JLang/JCategory.hh
 create mode 100644 src/jpp/JLang/JColorFacet.hh
 create mode 100644 src/jpp/JLang/JComparisonAvailable.hh
 create mode 100644 src/jpp/JLang/JEquation.hh
 create mode 100644 src/jpp/JLang/JEquationFacet.hh
 create mode 100644 src/jpp/JLang/JEquationParameters.hh
 create mode 100644 src/jpp/JLang/JFile.hh
 create mode 100644 src/jpp/JLang/JFileDescriptorMask.hh
 create mode 100644 src/jpp/JLang/JFileStream.hh
 create mode 100644 src/jpp/JLang/JFileStreamBuffer.hh
 create mode 100644 src/jpp/JLang/JObjectStreamIO.hh
 create mode 100644 src/jpp/JLang/JParameter.hh
 create mode 100644 src/jpp/JLang/JPrintHelper.hh
 create mode 100644 src/jpp/JLang/JStreamAvailable.hh
 create mode 100644 src/jpp/JLang/JStreamState.hh
 create mode 100644 src/jpp/JLang/JString.hh
 create mode 100644 src/jpp/JLang/JStringFacet.hh
 create mode 100644 src/jpp/JLang/JStringStream.hh
 create mode 100644 src/jpp/JLang/JTest.hh
 create mode 100644 src/jpp/JLang/JTimeval.hh
 create mode 100644 src/jpp/JLang/JTypeList.hh
 create mode 100644 src/jpp/JLang/JValue.hh
 create mode 100644 src/jpp/JOscProb/JBaselineCalculator.hh
 create mode 100644 src/jpp/JOscProb/JOscChannel.hh
 create mode 100644 src/jpp/JOscProb/JOscParameters.hh
 create mode 100644 src/jpp/JOscProb/JOscParametersGrid.hh
 create mode 100644 src/jpp/JOscProb/JOscParametersInterface.hh
 create mode 100644 src/jpp/JOscProb/JOscProb.hh
 create mode 100644 src/jpp/JOscProb/JOscProbInterpolator.hh
 create mode 100644 src/jpp/JOscProb/JOscProbInterpolatorInterface.hh
 create mode 100644 src/jpp/JOscProb/JOscProbToolkit.hh
 create mode 100644 src/jpp/JSystem/JDate.hh
 create mode 100644 src/jpp/JSystem/JStat.hh
 create mode 100644 src/jpp/JTools/JAbstractHistogram.hh
 create mode 100644 src/jpp/JTools/JHistogram1D.hh
 create mode 100644 src/jpp/Jeep/JColor.hh
 create mode 100644 src/jpp/Jeep/JComparisonToolkit.hh
 create mode 100644 src/jpp/Jeep/JMessage.hh
 create mode 100644 src/jpp/Jeep/JPrint.hh
 create mode 100644 src/jpp/Jeep/JProperties.hh
 create mode 100644 src/jpp/Jeep/JStreamToolkit.hh
 create mode 100644 src/jppy/JppyOscProbInterpolator.hh
 create mode 100644 src/jppy/lang.cc
 create mode 100644 src/jppy/oscprob.cc
 create mode 100644 src/jppy/utils.hh
 create mode 100644 tests/test_joscprob.py

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 07735bb..f820315 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -17,7 +17,7 @@ stages:
 .virtualenv_template: &virtualenv_definition |
   ./scripts/create_venv.sh
   source venv/bin/activate
-  pip install .
+  python3 -m pip install .
 
 .test_template: &test_definition |
   source venv/bin/activate
diff --git a/examples/interactive_oscprob.ipynb b/examples/interactive_oscprob.ipynb
new file mode 100644
index 0000000..ea5a998
--- /dev/null
+++ b/examples/interactive_oscprob.ipynb
@@ -0,0 +1,439 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "5030a86c",
+   "metadata": {},
+   "source": [
+    "# Interactive neutrino oscillation probabilities sliders\n",
+    "\n",
+    "_Authors: Jurjan Bootsma, Bouke Jung, Maarten de Jong_"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d45f6adf",
+   "metadata": {},
+   "source": [
+    "The following plots show the neutrino oscillation probabilities against the energy and cosine of the zenith angle. The user can choose which neutrino flavour goes in, which neutrino flavour goes out and if these are particles or anti-particles. Then the user can also use sliders to vary the fundamental oscillation parameters and see the shape of the probabilities change."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "f90eeda5",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "jppy version: 3.4.2.dev83+g6f357bb.d20221031\n"
+     ]
+    }
+   ],
+   "source": [
+    "import os\n",
+    "import ipywidgets as iw\n",
+    "import matplotlib.pyplot as plt\n",
+    "import numpy as np\n",
+    "import jppy\n",
+    "import matplotlib.colors as colors\n",
+    "\n",
+    "print(f\"jppy version: {jppy.version}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "1cb7d5ea",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "RuntimeError",
+     "evalue": "/project/antares/jurjanbootsma/software/Jpp/software/JOscProb/JOscProbInterpolator.hh:148\nJOscProbInterpolator::load(): Error reading file /project/antares/jurjanbootsma/software/Jpp/data//JOscProbTable.NO.dat",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[0;31mRuntimeError\u001b[0m                              Traceback (most recent call last)",
+      "\u001b[0;32m<ipython-input-12-ad85b220ede2>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0minput_file\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpandvars\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"$JPP_DATA/JOscProbTable.NO.dat\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0minterpolator\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mjppy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moscprob\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mJppyOscProbInterpolator\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput_file\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
+      "\u001b[0;31mRuntimeError\u001b[0m: /project/antares/jurjanbootsma/software/Jpp/software/JOscProb/JOscProbInterpolator.hh:148\nJOscProbInterpolator::load(): Error reading file /project/antares/jurjanbootsma/software/Jpp/data//JOscProbTable.NO.dat"
+     ]
+    }
+   ],
+   "source": [
+    "input_file = os.path.expandvars(\"$JPP_DATA/JOscProbTable.NO.dat\")\n",
+    "interpolator = jppy.oscprob.JppyOscProbInterpolator(input_file)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "3490ab1b",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "3a5d629af193412ebd78699aa1cc04e4",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "interactive(children=(Dropdown(description='Flavour in', index=1, options=(('Electron', 12), ('Muon', 14), ('T…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "#Plot of oscillation probabilities against the energy\n",
+    "\n",
+    "num=500\n",
+    "\n",
+    "Es = np.logspace(0,2,num=num,base=10)\n",
+    "\n",
+    "opts = dict(continuous_update=False)\n",
+    "@iw.interact\n",
+    "def show_pdf(flavour_in=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)],\n",
+    "                                    description=\"Flavour in\",value=14),\n",
+    "             flavour_out=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)],\n",
+    "                                     description=\"Flavour out\",value=14),\n",
+    "             CParity=iw.Dropdown(options=[(\"Particle\",1),(\"Antiparticle\",-1)],\n",
+    "                                 description=\"C Parity\"),\n",
+    "             zenith_angle=iw.FloatSlider(min=-1,max=0,step=0.01,\n",
+    "                                         description=\"$cosθ_{zenith}$\",value=-0.5,**opts),\n",
+    "             sinsqTh12=iw.FloatSlider(min=0.27,max=0.34,step=0.01,\n",
+    "                                      description=\"$sin^2θ_{12}$\",value=0.304,**opts),\n",
+    "             dM21sq=iw.FloatSlider(min=6.93,max=7.95,step=0.01,\n",
+    "                                   description=\"$\\Delta m_{21}^2[10^{-5}]$\",value=7.42,**opts),\n",
+    "             sinsqTh13=iw.FloatSlider(min=0.021,max=0.024,step=0.001,\n",
+    "                                      description=\"$sin^2θ_{13}$\",value=0.02246,readout_format='.3f',**opts),\n",
+    "             dM31sq=iw.FloatSlider(min=2.45,max=2.59,step=0.01,\n",
+    "                                   description=\"$\\Delta m_{31}^2[10^{-3}]$\",value=2.51, **opts),\n",
+    "             sinsqTh23=iw.FloatSlider(min=0.41,max=0.62,step=0.01,\n",
+    "                                      description=\"$sin^2θ_{23}$\",value=0.45,**opts),\n",
+    "             deltaCP=iw.FloatSlider(min=0,max=2,step=0.01,\n",
+    "                                    description=\"$\\delta_{CP} / \\pi$\",value=1.28,**opts)):\n",
+    "    \n",
+    "    #Convert mass differences to eV^2\n",
+    "    dM21sq=dM21sq*10**-5\n",
+    "    dM31sq=dM31sq*10**-3\n",
+    "    \n",
+    "    zenith_angles = np.tile(zenith_angle, num)\n",
+    "    \n",
+    "    #Set oscillation channel and parameters and perform interpolation\n",
+    "    channel = jppy.oscprob.JOscChannel(flavour_in, flavour_out, CParity)\n",
+    "    \n",
+    "    parameters = jppy.oscprob.JOscParameters(dM21sq, dM31sq, deltaCP, sinsqTh12, sinsqTh13, sinsqTh23)\n",
+    "    \n",
+    "    probs = interpolator(parameters, channel, Es, zenith_angles)\n",
+    "\n",
+    "    #The plot\n",
+    "    fig, ax = plt.subplots(figsize=(8,4))\n",
+    "    ax.plot(Es, probs)\n",
+    "    ax.set_xscale('log')\n",
+    "    ax.set_ylim(0, 1.05)\n",
+    "    plt.grid()\n",
+    "    ax.set_xlabel('E [GeV]', fontsize=15)\n",
+    "    ax.set_ylabel('Probability', fontsize=15)\n",
+    "    \n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2922002a",
+   "metadata": {},
+   "source": [
+    "Varying zenith angles"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "053d7a58",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "657c1d5482b741ecbb9670227de0ea83",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "interactive(children=(Dropdown(description='Flavour in', index=1, options=(('Electron', 12), ('Muon', 14), ('T…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "#Plot of oscillation probabilities against the cosine of the zenith angle\n",
+    "\n",
+    "num=1000\n",
+    "\n",
+    "zenith_angles = np.linspace(-1,-0.05,num=num)\n",
+    "\n",
+    "opts = dict(continuous_update=False)\n",
+    "@iw.interact\n",
+    "def show_pdf(flavour_in=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)],\n",
+    "                                    description=\"Flavour in\",value=14),\n",
+    "             flavour_out=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)],\n",
+    "                                     description=\"Flavour out\",value=14),\n",
+    "             CParity=iw.Dropdown(options=[(\"Particle\",1),(\"Antiparticle\",-1)],\n",
+    "                                 description=\"C Parity\"),\n",
+    "             E=iw.FloatLogSlider(value=5,base=10,min=0,max=2,\n",
+    "                                 description=\"Energy\",step=0.1,**opts),\n",
+    "             sinsqTh12=iw.FloatSlider(min=0.27,max=0.34,step=0.01,\n",
+    "                                      description=\"$sin^2θ_{12}$\",value=0.304,**opts),\n",
+    "             dM21sq=iw.FloatSlider(min=6.93,max=7.95,step=0.01,\n",
+    "                                   description=\"$\\Delta m_{21}^2[10^{-5}]$\",value=7.42,**opts),\n",
+    "             sinsqTh13=iw.FloatSlider(min=0.021,max=0.024,step=0.001,\n",
+    "                                      description=\"$sin^2θ_{13}$\",value=0.02246,readout_format='.3f',**opts),\n",
+    "             dM31sq=iw.FloatSlider(min=2.45,max=2.59,step=0.01,\n",
+    "                                   description=\"$\\Delta m_{31}^2[10^{-3}]$\",value=2.51, **opts),\n",
+    "             sinsqTh23=iw.FloatSlider(min=0.41,max=0.62,step=0.01,\n",
+    "                                      description=\"$sin^2θ_{23}$\",value=0.45,**opts),\n",
+    "             deltaCP=iw.FloatSlider(min=0,max=2,step=0.01,\n",
+    "                                    description=\"$\\delta_{CP} / \\pi$\",value=1.28,**opts)):\n",
+    "    \n",
+    "    #Converting units to eV^2\n",
+    "    dM21sq=dM21sq*10**-5\n",
+    "    dM31sq=dM31sq*10**-3\n",
+    "\n",
+    "    Es = np.tile(E, num)\n",
+    "    \n",
+    "    #Set oscillation channel and parameters and perform interpolation\n",
+    "    channel = jppy.oscprob.JOscChannel(flavour_in, flavour_out, CParity)\n",
+    "    \n",
+    "    parameters = jppy.oscprob.JOscParameters(dM21sq, dM31sq, deltaCP, sinsqTh12, sinsqTh13, sinsqTh23)\n",
+    "    \n",
+    "    probs = interpolator(parameters, channel, Es, zenith_angles)\n",
+    "    \n",
+    "    fig, ax = plt.subplots(figsize=(8,4))\n",
+    "    ax.plot(zenith_angles, probs)\n",
+    "    ax.set_ylim(0, 1.05)\n",
+    "    plt.grid()\n",
+    "    ax.set_xlabel('Cosine of zenith angle', fontsize=15)\n",
+    "    ax.set_ylabel('Probability', fontsize=15)\n",
+    "    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "a3e803f1",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "5951ffcd9df348998343dd2e58a1280f",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "interactive(children=(Dropdown(description='Flavour in', index=1, options=(('Electron', 12), ('Muon', 14), ('T…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "#2D density plot\n",
+    "\n",
+    "num_E = 250\n",
+    "num_angle = 250\n",
+    "\n",
+    "Es = np.logspace(0,2,num=num_E,base=10)\n",
+    "angles = np.linspace(-1,-0.05,num=num_angle)\n",
+    "\n",
+    "Es_meshgrid, angles_meshgrid = np.meshgrid(Es, angles)\n",
+    "\n",
+    "opts = dict(continuous_update=False)\n",
+    "@iw.interact\n",
+    "def show_pdf(flavour_in=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)],\n",
+    "                                    description=\"Flavour in\",value=14),\n",
+    "             flavour_out=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)],\n",
+    "                                     description=\"Flavour out\",value=14),\n",
+    "             CParity=iw.Dropdown(options=[(\"Particle\",1),(\"Antiparticle\",-1)],\n",
+    "                                 description=\"C Parity\"),\n",
+    "             sinsqTh12=iw.FloatSlider(min=0.27,max=0.34,step=0.01,\n",
+    "                                      description=\"$sin^2θ_{12}$\",value=0.304,**opts),\n",
+    "             dM21sq=iw.FloatSlider(min=6.93,max=7.96,step=0.01,\n",
+    "                                   description=\"$\\Delta m_{21}^2[10^{-5}]$\",value=7.42,**opts),\n",
+    "             sinsqTh13=iw.FloatSlider(min=0.021,max=0.024,step=0.001,\n",
+    "                                      description=\"$sin^2θ_{13}$\",value=0.02246,readout_format='.3f',**opts),\n",
+    "             dM31sq=iw.FloatSlider(min=2.45,max=2.59,step=0.01,\n",
+    "                                   description=\"$\\Delta m_{31}^2[10^{-3}]$\",value=2.51, **opts),\n",
+    "             sinsqTh23=iw.FloatSlider(min=0.41,max=0.62,step=0.01,\n",
+    "                                      description=\"$sin^2θ_{23}$\",value=0.45,**opts),\n",
+    "             deltaCP=iw.FloatSlider(min=0,max=2,step=0.01,\n",
+    "                                    description=\"$\\delta_{CP} / \\pi$\",value=1.28,**opts)):\n",
+    "    \n",
+    "    #Converting units to eV^2\n",
+    "    dM21sq=dM21sq*10**-5\n",
+    "    dM31sq=dM31sq*10**-3  \n",
+    "    \n",
+    "    parameters = jppy.oscprob.JOscParameters(sinsqTh12=sinsqTh12,\n",
+    "                                             dM21sq=dM21sq,\n",
+    "                                             sinsqTh13=sinsqTh13,\n",
+    "                                             dM31sq=dM31sq,\n",
+    "                                             sinsqTh23=sinsqTh23,\n",
+    "                                             deltaCP=deltaCP)\n",
+    "\n",
+    "    channel = jppy.oscprob.JOscChannel(flavour_in, flavour_out, CParity)\n",
+    "    \n",
+    "    probs = interpolator(parameters, channel, Es_meshgrid.flatten(), angles_meshgrid.flatten())\n",
+    "    probs_2D = np.reshape(probs, (num_angle,num_E))\n",
+    "    \n",
+    "    fig, ax = plt.subplots(figsize=(8,6))\n",
+    "    pos=ax.imshow(probs_2D, cmap='PuBu',vmin=0,vmax=1, origin = 'lower',\n",
+    "                  extent=(np.amin(Es), np.amax(Es), np.amin(angles), np.amax(angles)),aspect='auto')\n",
+    "    plt.colorbar(pos,ax=ax)\n",
+    "    ax.set_xlabel('E / GeV', fontsize=15)\n",
+    "    ax.set_ylabel('Cosine of zenith angle', fontsize=15)\n",
+    "    ticks = [1,50,100]\n",
+    "    tick_labels = [\"1\",\"10\",\"100\"]\n",
+    "    plt.xticks(ticks,labels=tick_labels)\n",
+    "    \n",
+    "    plt.show()\n",
+    "\n",
+    "    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "e3b721f1",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "baseline = interpolator.get_baseline_calculator()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "2f5d67ce",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "a089d3c7e4084006a7659955b795002b",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "interactive(children=(Dropdown(description='Flavour in', index=1, options=(('Electron', 12), ('Muon', 14), ('T…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "#2D density plot\n",
+    "\n",
+    "num_L_E = 200\n",
+    "num_angle = 200\n",
+    "\n",
+    "L_Es = np.linspace(500,10000,num=num_L_E)\n",
+    "angles = np.linspace(-1,-0.05,num=num_angle)\n",
+    "#angles=angles[::-1]\n",
+    "\n",
+    "Ls = np.zeros(num_angle)\n",
+    "for i in range(0, num_angle):\n",
+    "    L = baseline(angles[i])\n",
+    "    Ls[i] = L\n",
+    "\n",
+    "L_Es = L_Es[::-1]\n",
+    "\n",
+    "L_E_meshgrid, L_meshgrid = np.meshgrid(L_Es, Ls)\n",
+    "L_E_meshgrid, angles_meshgrid = np.meshgrid(L_Es, angles)\n",
+    "Es_meshgrid = L_meshgrid/L_E_meshgrid\n",
+    "\n",
+    "opts = dict(continuous_update=False)\n",
+    "@iw.interact\n",
+    "def show_pdf(flavour_in=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)],\n",
+    "                                    description=\"Flavour in\",value=14),\n",
+    "             flavour_out=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)],\n",
+    "                                     description=\"Flavour out\",value=14),\n",
+    "             CParity=iw.Dropdown(options=[(\"Particle\",1),(\"Antiparticle\",-1)],\n",
+    "                                 description=\"C Parity\"),\n",
+    "             sinsqTh12=iw.FloatSlider(min=0.27,max=0.34,step=0.01,\n",
+    "                                      description=\"$sin^2θ_{12}$\",value=0.304,**opts),\n",
+    "             dM21sq=iw.FloatSlider(min=6.93,max=7.96,step=0.01,\n",
+    "                                   description=\"$\\Delta m_{21}^2[10^{-5}]$\",value=7.42,**opts),\n",
+    "             sinsqTh13=iw.FloatSlider(min=0.021,max=0.024,step=0.001,\n",
+    "                                      description=\"$sin^2θ_{13}$\",value=0.02246,readout_format='.3f',**opts),\n",
+    "             dM31sq=iw.FloatSlider(min=2.45,max=2.59,step=0.01,\n",
+    "                                   description=\"$\\Delta m_{31}^2[10^{-3}]$\",value=2.51, **opts),\n",
+    "             sinsqTh23=iw.FloatSlider(min=0.41,max=0.62,step=0.01,\n",
+    "                                      description=\"$sin^2θ_{23}$\",value=0.45,**opts),\n",
+    "             deltaCP=iw.FloatSlider(min=0,max=2,step=0.01,\n",
+    "                                    description=\"$\\delta_{CP} / \\pi$\",value=1.28,**opts)):\n",
+    "    \n",
+    "    #Converting units to eV^2\n",
+    "    dM21sq=dM21sq*10**-5\n",
+    "    dM31sq=dM31sq*10**-3  \n",
+    "    \n",
+    "    parameters = jppy.oscprob.JOscParameters(sinsqTh12=sinsqTh12,\n",
+    "                                             dM21sq=dM21sq,\n",
+    "                                             sinsqTh13=sinsqTh13,\n",
+    "                                             dM31sq=dM31sq,\n",
+    "                                             sinsqTh23=sinsqTh23,\n",
+    "                                             deltaCP=deltaCP)\n",
+    "\n",
+    "    channel = jppy.oscprob.JOscChannel(flavour_in, flavour_out, CParity)\n",
+    "    \n",
+    "    probs = interpolator(parameters, channel, Es_meshgrid.flatten(), angles_meshgrid.flatten())\n",
+    "    probs_2D = np.reshape(probs, (num_angle,num_L_E))\n",
+    "    probs_2D = probs_2D[:, ::-1]\n",
+    "    \n",
+    "    fig, ax = plt.subplots(figsize=(8,6))\n",
+    "    pos=ax.imshow(probs_2D, cmap='PuBu',vmin=0,vmax=1, origin = 'lower',\n",
+    "                  extent=(np.amin(L_Es), np.amax(L_Es), np.amin(angles), np.amax(angles)),aspect='auto')\n",
+    "    plt.colorbar(pos,ax=ax)\n",
+    "    ax.set_xlabel('L/E [km/GeV]', fontsize=15)\n",
+    "    ax.set_ylabel('Cosine of zenith angle', fontsize=15)\n",
+    "    \n",
+    "    plt.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "926a92f8",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.6.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/examples/oscprob_python.ipynb b/examples/oscprob_python.ipynb
new file mode 100644
index 0000000..7121b70
--- /dev/null
+++ b/examples/oscprob_python.ipynb
@@ -0,0 +1,402 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "df0497ff",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "jppy version: 3.4.1.dev38+g19af23d.d20221023\n"
+     ]
+    }
+   ],
+   "source": [
+    "import os\n",
+    "import ipywidgets as iw\n",
+    "import matplotlib.pyplot as plt\n",
+    "import numpy as np\n",
+    "import jppy\n",
+    "\n",
+    "print(f\"jppy version: {jppy.version}\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "66947fea",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "loading oscillation probability table from file /home/yugen96/work/KM3NeT/software/Jpp/Jpp_dev/data//JOscProbTable.NO.dat... OK\n"
+     ]
+    }
+   ],
+   "source": [
+    "#Reading the data\n",
+    "\n",
+    "input_file = os.path.expandvars(\"${JPP_DATA}/JOscProbTable.NO.dat\")\n",
+    "interpolator = jppy.oscprob.JppyOscProbInterpolator(input_file)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "9e442279",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "JFlavour_t.ELECTRON\n",
+      "JChargeParity_t.PARTICLE\n"
+     ]
+    }
+   ],
+   "source": [
+    "#Set the channel\n",
+    "\n",
+    "flavour1 = jppy.oscprob.JFlavour_t(12)\n",
+    "flavour2 = jppy.oscprob.JFlavour_t(14)\n",
+    "CParity = jppy.oscprob.JChargeParity_t(1)\n",
+    "\n",
+    "channel = jppy.oscprob.JOscChannel(flavour1, flavour2, CParity)\n",
+    "print(jppy.oscprob.JFlavour_t.ELECTRON)\n",
+    "\n",
+    "print(channel.Cparity)\n",
+    "\n",
+    "xs = np.logspace(1, 5, num=50, base=10)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "id": "c52117ec",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[0.00916337]\n"
+     ]
+    }
+   ],
+   "source": [
+    "xs = np.linspace(10,1000,1000)\n",
+    "#xs = np.logspace(1, 3, num=50, base=10)\n",
+    "parameters = jppy.oscprob.JOscParameters(False)\n",
+    "\n",
+    "parameters.set(\"sinsqTh12\", 0.35,\n",
+    "               \"sinsqTh13\", 0.025, \n",
+    "               \"sinsqTh23\", 0.62)\n",
+    "\n",
+    "probs = interpolator(parameters,channel,[10],[-1])\n",
+    "print(probs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "8ed821ca",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "d3d4d717a6964b5185fb6380c4cc8d37",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "interactive(children=(Dropdown(description='flavour_in', options=(('Electron', 12), ('Muon', 14), ('Tau', 16))…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "xs = np.linspace(10,1000,1000)\n",
+    "\n",
+    "opts = dict(continuous_update=False)\n",
+    "@iw.interact\n",
+    "def show_pdf(flavour_in=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)], value=12),\n",
+    "             flavour_out=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)], value=14),\n",
+    "             CParity=iw.Dropdown(options=[(\"Particle\",1),(\"Antiparticle\",-1)]),\n",
+    "             sinsqTh12=iw.FloatSlider(min=0.2, max=0.35, step=0.01, value=0.304, **opts),\n",
+    "             dM21sq=iw.FloatSlider(min=6.93e-5, max=7.96e-5, step=10e-7, value=7.42e-5,readout_format='.5f', **opts),\n",
+    "             sinsqTh13=iw.FloatSlider(min=0.017, max=0.025, step=0.001, value=0.02246,readout_format='.3f', **opts),\n",
+    "             dM31sq=iw.FloatSlider(min=0.00245,max=0.00269, step=0.00001, value=2.51e-3,readout_format='.4f', **opts),\n",
+    "             sinsqTh23=iw.FloatSlider(min=0.38, max=0.62, step=0.01, value=0.45, **opts),\n",
+    "             deltaCP=iw.FloatSlider(min=0, max=2, step=0.01, value=1.28, **opts)):\n",
+    "    parameters = jppy.oscprob.JOscParameters(sinsqTh12=sinsqTh12,\n",
+    "                                             dM21sq=dM21sq,\n",
+    "                                             sinsqTh13=sinsqTh13,\n",
+    "                                             dM31sq=dM31sq,\n",
+    "                                             sinsqTh23=sinsqTh23,\n",
+    "                                             deltaCP=deltaCP)\n",
+    "    \n",
+    "    channel = jppy.oscprob.JOscChannel(jppy.oscprob.JFlavour_t(flavour_in), \n",
+    "                                       jppy.oscprob.JFlavour_t(flavour_out), \n",
+    "                                       jppy.oscprob.JChargeParity_t(CParity))\n",
+    "    \n",
+    "    pdf = lambda E: interpolator(channel,[E],[1])\n",
+    "    \n",
+    "    ys = list(map(pdf, xs))\n",
+    "    y_above = np.max(ys)*1.25\n",
+    "    fig, ax = plt.subplots(figsize=(8,4))\n",
+    "    ax.plot(xs, ys)\n",
+    "    ax.set_xscale('log')\n",
+    "    ax.set_ylim(0, 0.065)\n",
+    "    #ax.set_ylim(0, 1.1)\n",
+    "    plt.grid()\n",
+    "    ax.set_xlabel('E / GeV', fontsize=15)\n",
+    "    ax.set_ylabel('Probability', fontsize=15)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8da9161d",
+   "metadata": {},
+   "source": [
+    "Tests"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "eff09816",
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "5572aeec763046f8a292d18224dc21bc",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "interactive(children=(Dropdown(description='flavour_in', index=1, options=(('Electron', 12), ('Muon', 14), ('T…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "#Test if all the probilities add up to 1\n",
+    "\n",
+    "xs = np.linspace(10,1000,1000)\n",
+    "\n",
+    "opts = dict(continuous_update=False)\n",
+    "@iw.interact\n",
+    "def show_pdf(flavour_in=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)], value=14),\n",
+    "             CParity=iw.Dropdown(options=[(\"Particle\",1),(\"Antiparticle\",-1)]),\n",
+    "             sinsqTh12=iw.FloatSlider(min=0.2, max=0.35, step=0.01, value=0.304, **opts),\n",
+    "             dM21sq=iw.FloatSlider(min=6.93e-5, max=7.96e-5, step=10e-7, value=7.42e-5,readout_format='.1e', **opts),\n",
+    "             sinsqTh13=iw.FloatSlider(min=0.017, max=0.025, step=0.001, value=0.02246,readout_format='.3f', **opts),\n",
+    "             dM31sq=iw.FloatSlider(min=0.00245,max=0.00269, step=0.00001, value=2.51e-3,readout_format='.4f', **opts),\n",
+    "             sinsqTh23=iw.FloatSlider(min=0.38, max=0.62, step=0.01, value=0.45, **opts),\n",
+    "             deltaCP=iw.FloatSlider(min=0, max=2, step=0.01, value=1.28, **opts)):\n",
+    "    parameters = jppy.oscprob.JOscParameters(sinsqTh12=sinsqTh12,\n",
+    "                                             dM21sq=dM21sq,\n",
+    "                                             sinsqTh13=sinsqTh13,\n",
+    "                                             dM31sq=dM31sq,\n",
+    "                                             sinsqTh23=sinsqTh23,\n",
+    "                                             deltaCP=deltaCP)\n",
+    "    \n",
+    "    interpolator = jppy.oscprob.JOscProbInterpolator8D(table, parameters)\n",
+    "    channel = jppy.oscprob.JOscChannel(jppy.oscprob.JFlavour_t(flavour_in), \n",
+    "                                       jppy.oscprob.JFlavour_t(12), \n",
+    "                                       jppy.oscprob.JChargeParity_t(CParity))\n",
+    "    \n",
+    "    pdf1 = lambda E: interpolator(channel,[E],[1])\n",
+    "    ys1 = list(map(pdf1, xs))\n",
+    "    \n",
+    "    interpolator = jppy.oscprob.JOscProbInterpolator8D(table, parameters)\n",
+    "    channel = jppy.oscprob.JOscChannel(jppy.oscprob.JFlavour_t(flavour_in), \n",
+    "                                       jppy.oscprob.JFlavour_t(14), \n",
+    "                                       jppy.oscprob.JChargeParity_t(CParity))\n",
+    "    \n",
+    "    pdf2 = lambda E: interpolator(channel,[E],[1])\n",
+    "    ys2 = list(map(pdf2, xs))\n",
+    "    \n",
+    "    channel = jppy.oscprob.JOscChannel(jppy.oscprob.JFlavour_t(flavour_in), \n",
+    "                                       jppy.oscprob.JFlavour_t(16), \n",
+    "                                       jppy.oscprob.JChargeParity_t(CParity))\n",
+    "    \n",
+    "    pdf3 = lambda E: interpolator(channel,[E],[1])\n",
+    "    ys3 = list(map(pdf3, xs))\n",
+    "    \n",
+    "    ys_total = np.array(ys1)+np.array(ys2)+np.array(ys3)\n",
+    "    \n",
+    "    fig, ax = plt.subplots(figsize=(8,4))\n",
+    "    ax.plot(xs, ys_total)\n",
+    "    ax.set_xscale('log')\n",
+    "    #ax.set_yscale('log')\n",
+    "    ax.set_ylim(0, 1.1)\n",
+    "    #ax.set_ylim(0, y_above)\n",
+    "    plt.grid()\n",
+    "    ax.set_xlabel('E / GeV', fontsize=15)\n",
+    "    ax.set_ylabel('Probability', fontsize=15)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "d8a39610",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "c162f1ad82054a51bf899ba21175b933",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "interactive(children=(Dropdown(description='flavour_in', options=(('Electron', 12), ('Muon', 14), ('Tau', 16))…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Cparity=1\n",
+      "in=12\n",
+      "out=14\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "17418bc8597745df8bfa08915922548f",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "interactive(children=(FloatSlider(value=0.304, continuous_update=False, description='sinsqTh12', max=0.35, min…"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "#Met goede y-as\n",
+    "\n",
+    "xs = np.linspace(10,1000,1000)\n",
+    "\n",
+    "opts = dict(continuous_update=False)\n",
+    "@iw.interact\n",
+    "def choose_channel(flavour_in=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)], value=12),\n",
+    "                   flavour_out=iw.Dropdown(options=[(\"Electron\",12),(\"Muon\",14),(\"Tau\",16)], value=14),\n",
+    "                   CParity=iw.Dropdown(options=[(\"Particle\",1),(\"Antiparticle\",-1)])):\n",
+    "    channel = jppy.oscprob.JOscChannel(jppy.oscprob.JFlavour_t(flavour_in), \n",
+    "                                       jppy.oscprob.JFlavour_t(flavour_out), \n",
+    "                                       jppy.oscprob.JChargeParity_t(CParity))\n",
+    "    \n",
+    "print(channel)\n",
+    "\n",
+    "opts = dict(continuous_update=False)\n",
+    "@iw.interact    \n",
+    "def show_pdf(sinsqTh12=iw.FloatSlider(min=0.2, max=0.35, step=0.01, value=0.304, **opts),\n",
+    "             dM21sq=iw.FloatSlider(min=6.93e-5, max=7.96e-5, step=10e-7, value=7.42e-5,readout_format='.5f', **opts),\n",
+    "             sinsqTh13=iw.FloatSlider(min=0.017, max=0.025, step=0.001, value=0.02246,readout_format='.3f', **opts),\n",
+    "             dM31sq=iw.FloatSlider(min=0.00245,max=0.00269, step=0.00001, value=2.51e-3,readout_format='.4f', **opts),\n",
+    "             sinsqTh23=iw.FloatSlider(min=0.38, max=0.62, step=0.01, value=0.45, **opts),\n",
+    "             deltaCP=iw.FloatSlider(min=0, max=2, step=0.01, value=1.28, **opts)):\n",
+    "    parameters = jppy.oscprob.JOscParameters(sinsqTh12=sinsqTh12,\n",
+    "                                             dM21sq=dM21sq,\n",
+    "                                             sinsqTh13=sinsqTh13,\n",
+    "                                             dM31sq=dM31sq,\n",
+    "                                             sinsqTh23=sinsqTh23,\n",
+    "                                             deltaCP=deltaCP)\n",
+    "    interpolator = jppy.oscprob.JOscProbInterpolator8D(table, parameters)\n",
+    "    \n",
+    "    pdf = lambda E: interpolator.__call__(channel,E,1)\n",
+    "    ys = list(map(pdf, xs))\n",
+    "    y_above = np.max(ys)*1.25\n",
+    "    fig, ax = plt.subplots(figsize=(8,4))\n",
+    "    ax.plot(xs, ys)\n",
+    "    ax.set_xscale('log')\n",
+    "    #ax.set_yscale('log')\n",
+    "    ax.set_ylim(0, 0.065)\n",
+    "    #ax.set_ylim(0, y_above)\n",
+    "    plt.grid()\n",
+    "    ax.set_xlabel('E / GeV', fontsize=15)\n",
+    "    ax.set_ylabel('Probability', fontsize=15)\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "id": "110c92f3",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[3, 6, 9, 12]\n"
+     ]
+    }
+   ],
+   "source": [
+    "xs=[1,2,3,4]\n",
+    "ys=[2,4,6,8]\n",
+    "\n",
+    "def func(a,b):\n",
+    "    return a+b\n",
+    "\n",
+    "pdf = lambda a,b: func(a,b)\n",
+    "zs = list(map(pdf,xs,ys))\n",
+    "print(zs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7b58ec32",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.6.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/scripts/create_venv.sh b/scripts/create_venv.sh
index a7c2168..5cbc2b7 100755
--- a/scripts/create_venv.sh
+++ b/scripts/create_venv.sh
@@ -1,8 +1,8 @@
 #!/usr/bin/env bash
 if [ ! -d "venv" ]; then
     echo "Creating a fresh virtualenv..."
-    pip install -U pip setuptools wheel
-    python -m venv venv
+    python3 -m pip install -U pip setuptools wheel pybind11
+    python3 -m venv venv
 else
     echo "Virtualenv already created."
 fi
diff --git a/setup.py b/setup.py
index 29a355f..2d0f2bd 100644
--- a/setup.py
+++ b/setup.py
@@ -105,7 +105,7 @@ if __name__ == '__main__':
                     get_pybind_include(user=True),
                     get_jpp_include()
                 ],
-                language='c++') for module in ['constants', 'geane', 'pdf', 'npe']
+                language='c++') for module in ['constants', 'geane', 'pdf', 'npe', 'oscprob', 'lang']
         ],
         cmdclass = dict(
             build_ext = BuildExt
diff --git a/src/jpp/JIO/JBufferedIO.hh b/src/jpp/JIO/JBufferedIO.hh
index 864c003..0961c74 100644
--- a/src/jpp/JIO/JBufferedIO.hh
+++ b/src/jpp/JIO/JBufferedIO.hh
@@ -39,9 +39,7 @@ namespace JIO {
       size   = std::max(__size, 1024);
       buffer = new char[size];
 
-      pos = 0;
-      ls  = 0;
-      eof = true;
+      reset();
     }
 
 
@@ -119,8 +117,17 @@ namespace JIO {
       return n;
     }
 
-
   protected:
+    /**
+     * Reset.
+     */
+    void reset()
+    {
+      pos = 0;
+      ls  = 0;
+      eof = true;
+    }
+
     JLANG::JSinglePointer<JReader> in;
 
     char* buffer;  //!< internal buffer
@@ -128,6 +135,12 @@ namespace JIO {
     int   pos;     //!< pointer to begin of available data
     int   ls;      //!< pointer to end   of available data
     bool  eof;     //!< end of file
+
+  private:
+    JBufferedReader(const JBufferedReader&);
+    JBufferedReader(JBufferedReader&&);
+    JBufferedReader& operator=(const JBufferedReader&);
+    JBufferedReader& operator=(JBufferedReader&&);
   };
 
 
@@ -225,6 +238,12 @@ namespace JIO {
     char* buffer;  //!< internal buffer
     int   size;    //!< size of internal buffer
     int   pos;     //!< pointer to end of buffered data
+
+  private:
+    JBufferedWriter(const JBufferedWriter&);
+    JBufferedWriter(JBufferedWriter&&);
+    JBufferedWriter& operator=(const JBufferedWriter&);
+    JBufferedWriter& operator=(JBufferedWriter&&);
   };
 }
 
diff --git a/src/jpp/JIO/JFileStreamIO.hh b/src/jpp/JIO/JFileStreamIO.hh
index f6640de..3da62d1 100644
--- a/src/jpp/JIO/JFileStreamIO.hh
+++ b/src/jpp/JIO/JFileStreamIO.hh
@@ -63,6 +63,27 @@ namespace JIO {
     {
       static_cast<std::ifstream*>(this)->open(file_name, std::ios::binary);
     }
+
+
+    /**
+     * Clear status of reader.
+     */
+    virtual void clear() override
+    {
+      std::ifstream  ::clear();
+      JBufferedReader::clear();
+    }
+
+
+    /**
+     * Rewind.
+     */
+    void rewind()
+    {
+      seekg(0);   // rewind file stream
+
+      reset();    // reset buffer
+    }
   };
 
 
diff --git a/src/jpp/JIO/JSerialisable.hh b/src/jpp/JIO/JSerialisable.hh
index e72fa05..6401f16 100644
--- a/src/jpp/JIO/JSerialisable.hh
+++ b/src/jpp/JIO/JSerialisable.hh
@@ -147,21 +147,21 @@ namespace JIO {
     }
 
 
-    JWriter& operator<<(const bool&                   value) { write((const char*) &value, sizeof(bool));                   return *this; }
-    JWriter& operator<<(const char&                   value) { write((const char*) &value, sizeof(char));                   return *this; } 
-    JWriter& operator<<(const unsigned char&          value) { write((const char*) &value, sizeof(unsigned char));          return *this; }
-    JWriter& operator<<(const short&                  value) { write((const char*) &value, sizeof(short));                  return *this; }
-    JWriter& operator<<(const unsigned short&         value) { write((const char*) &value, sizeof(unsigned short));         return *this; }
-    JWriter& operator<<(const int&                    value) { write((const char*) &value, sizeof(int));                    return *this; }
-    JWriter& operator<<(const unsigned int&           value) { write((const char*) &value, sizeof(unsigned int));           return *this; }
-    JWriter& operator<<(const long int&               value) { write((const char*) &value, sizeof(long int));               return *this; }
-    JWriter& operator<<(const unsigned long int&      value) { write((const char*) &value, sizeof(unsigned long int));      return *this; }
-    JWriter& operator<<(const long long int&          value) { write((const char*) &value, sizeof(long long int));          return *this; }
-    JWriter& operator<<(const unsigned long long int& value) { write((const char*) &value, sizeof(unsigned long long int)); return *this; }
-    JWriter& operator<<(const float&                  value) { write((const char*) &value, sizeof(float));                  return *this; }
-    JWriter& operator<<(const double&                 value) { write((const char*) &value, sizeof(double));                 return *this; }
-    JWriter& operator<<(const long double&            value) { write((const char*) &value, sizeof(long double));            return *this; }
-    JWriter& operator<<(const JLANG::JObjectID&       value) { return (*this) << value.getID(); }
+    JWriter& operator<<(const bool                   value) { write((const char*) &value, sizeof(bool));                   return *this; }
+    JWriter& operator<<(const char                   value) { write((const char*) &value, sizeof(char));                   return *this; } 
+    JWriter& operator<<(const unsigned char          value) { write((const char*) &value, sizeof(unsigned char));          return *this; }
+    JWriter& operator<<(const short                  value) { write((const char*) &value, sizeof(short));                  return *this; }
+    JWriter& operator<<(const unsigned short         value) { write((const char*) &value, sizeof(unsigned short));         return *this; }
+    JWriter& operator<<(const int                    value) { write((const char*) &value, sizeof(int));                    return *this; }
+    JWriter& operator<<(const unsigned int           value) { write((const char*) &value, sizeof(unsigned int));           return *this; }
+    JWriter& operator<<(const long int               value) { write((const char*) &value, sizeof(long int));               return *this; }
+    JWriter& operator<<(const unsigned long int      value) { write((const char*) &value, sizeof(unsigned long int));      return *this; }
+    JWriter& operator<<(const long long int          value) { write((const char*) &value, sizeof(long long int));          return *this; }
+    JWriter& operator<<(const unsigned long long int value) { write((const char*) &value, sizeof(unsigned long long int)); return *this; }
+    JWriter& operator<<(const float                  value) { write((const char*) &value, sizeof(float));                  return *this; }
+    JWriter& operator<<(const double                 value) { write((const char*) &value, sizeof(double));                 return *this; }
+    JWriter& operator<<(const long double            value) { write((const char*) &value, sizeof(long double));            return *this; }
+    JWriter& operator<<(const JLANG::JObjectID&      value) { return (*this) << value.getID(); }
 
 
     /**
diff --git a/src/jpp/JLang/JAbstractFile.hh b/src/jpp/JLang/JAbstractFile.hh
new file mode 100644
index 0000000..261bb26
--- /dev/null
+++ b/src/jpp/JLang/JAbstractFile.hh
@@ -0,0 +1,95 @@
+#ifndef __JLANG__JABSTRACTFILE__
+#define __JLANG__JABSTRACTFILE__
+
+#include <stdio.h>
+
+#include "JLang/JComparable.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * The JAbstractFile class encapsulates the c-style file descriptor.
+   */
+  class JAbstractFile :
+    public JComparable<JAbstractFile>
+  {
+  public:
+
+    static const int FILE_CLOSED = -1;
+
+
+    /**
+     * Default constructor.
+     */
+    JAbstractFile() :
+      fileDescriptor(FILE_CLOSED)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  file            file descriptor
+     */
+    JAbstractFile(const int file) :
+      fileDescriptor(file)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  stream          file stream
+     */
+    JAbstractFile(FILE* stream) :
+      fileDescriptor(fileno(stream))
+    {}
+
+
+    /**
+     * Less than operation.
+     *
+     * \param  file      JAbstractFile to be compared
+     * \return           true if this file descriptor is less; else false
+     */
+    bool less(const JAbstractFile& file) const
+    {
+      return getFileDescriptor() < file.getFileDescriptor();
+    }
+
+
+    /**
+     * Get file descriptor.
+     *
+     * \return                file descriptor
+     */
+    int getFileDescriptor() const
+    {
+      return fileDescriptor;
+    }
+
+
+    /**
+     * Get open status.
+     */
+    bool is_open() const
+    {
+      return fileDescriptor != FILE_CLOSED;
+    }
+
+
+  protected:
+    int fileDescriptor;
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JAbstractIO.hh b/src/jpp/JLang/JAbstractIO.hh
new file mode 100644
index 0000000..df617ab
--- /dev/null
+++ b/src/jpp/JLang/JAbstractIO.hh
@@ -0,0 +1,114 @@
+#ifndef __JLANG__JABSTRACTIO__
+#define __JLANG__JABSTRACTIO__
+
+#include <istream>
+#include <ostream>
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Interface for ASCII input using standard streams.
+   */
+  class JStreamInput {
+  public:
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JStreamInput()
+    {}
+
+
+    /**
+     * Stream input.
+     *
+     * \param  in      input stream
+     * \return         input stream
+     */
+    virtual std::istream& read(std::istream& in) = 0;
+
+
+    /**
+     * Read object from input.
+     *
+     * \param  in       input stream
+     * \param  object   object
+     * \return          input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JStreamInput& object)
+    {
+      return object.read(in);
+    }
+  };
+
+
+  /**
+   * Interface for ASCII output using standard streams.
+   */
+  class JStreamOutput {
+  public:
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JStreamOutput()
+    {}
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out     output stream
+     * \return         output stream
+     */
+    virtual std::ostream& write(std::ostream& out) const = 0;
+
+
+    /**
+     * Write object to output.
+     *
+     * \param  out      output stream
+     * \param  object   object
+     * \return          output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JStreamOutput& object)
+    {
+      return object.write(out);
+    }
+  };
+
+
+  /**
+   * Interface for ASCII output with prefix and postfix using standard streams.
+   */
+  class JStreamSuffixOutput {
+  public:
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JStreamSuffixOutput()
+    {}
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out           output stream
+     * \param  prefix        prefix
+     * \param  postfix       postfix
+     * \return               output stream
+     */
+    virtual std::ostream& write(std::ostream& out,
+				const char*   prefix, 
+				const char    postfix) const = 0;
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JAnyType.hh b/src/jpp/JLang/JAnyType.hh
new file mode 100644
index 0000000..52deec8
--- /dev/null
+++ b/src/jpp/JLang/JAnyType.hh
@@ -0,0 +1,31 @@
+#ifndef __JLANG__JANYTYPE__
+#define __JLANG__JANYTYPE__
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Auxiliary class for any type definition.
+   * This class can be used to test the validity of an expression through type conversion.
+   */
+  struct JAnyType {
+    /**
+     * Type conversion operation.
+     *
+     * \param  any_type         any type
+     */
+    template<class T>
+    JAnyType(const T& any_type)
+    {}
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JAssert.hh b/src/jpp/JLang/JAssert.hh
index 78e69fd..96d3588 100644
--- a/src/jpp/JLang/JAssert.hh
+++ b/src/jpp/JLang/JAssert.hh
@@ -13,16 +13,18 @@ namespace JLANG {
   /**
    * Generation of compiler error.
    */
-  template<bool>
+  template<bool, class T = void>
   struct JAssert;
 
   /**
    * Implementation of valid assertion.
    */
-  template<>
-  struct JAssert<true> 
+  template<class T>
+  struct JAssert<true, T> 
   {
     static const bool value = true;
+
+    typedef T type;
   };
 }
 
diff --git a/src/jpp/JLang/JCategory.hh b/src/jpp/JLang/JCategory.hh
new file mode 100644
index 0000000..dc15ba2
--- /dev/null
+++ b/src/jpp/JLang/JCategory.hh
@@ -0,0 +1,41 @@
+#ifndef __JLANG__JCATEGORY
+#define __JLANG__JCATEGORY
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Auxiliary class to define value, reference and pointer types for given data type and category.
+   */
+  template<class T, bool is_constant>
+  struct JCategory;
+
+  /**
+   * Specialisation of JCategory for constant (i.e.\ non-modifiable) data type.
+   */
+  template<class T>
+  struct JCategory<T, true> {
+    typedef const T       value_type;
+    typedef const T&      reference_type;
+    typedef const T*      pointer_type;
+  };
+
+  /**
+   * Specialisation of JCategory for modifiable (i.e.\ non-constant) data type.
+   */
+  template<class T>
+  struct JCategory<T, false> {
+    typedef T             value_type;
+    typedef T&            reference_type;
+    typedef T*            pointer_type;
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JColorFacet.hh b/src/jpp/JLang/JColorFacet.hh
new file mode 100644
index 0000000..1dee175
--- /dev/null
+++ b/src/jpp/JLang/JColorFacet.hh
@@ -0,0 +1,358 @@
+#ifndef __JLANG__JCOLORFACET__
+#define __JLANG__JCOLORFACET__
+
+#include <locale>
+#include <ostream>
+#include <string>
+#include <vector>
+#include <map>
+
+#include "JLang/JType.hh"
+#include "JLang/JTypeList.hh"
+#include "JLang/JSinglePointer.hh"
+#include "JLang/JException.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+
+namespace JLANG {
+
+  /**
+   * Enumeration of text colors.
+   */
+  enum JColor_t {
+    RED,              //!< red
+    GREEN,            //!< green
+    BLUE,             //!< blue
+    WHITE,            //!< white
+    CYAN,             //!< cyan
+    PURPLE,           //!< purple
+    YELLOW,           //!< yellow
+    RESET,            //!< reset
+    BOLD              //!< bold
+  };
+
+
+  /**
+   * Facet interface to specify text color.
+   * This class extends the std::locale::facet class.
+   */
+  struct JColorFacet : 
+    public std::locale::facet
+  {
+    static std::locale::id  id;
+
+  
+    /**
+     * Constructor.
+     *
+     * \param  refs      reference count
+     */
+    JColorFacet(std::size_t refs = 0) :
+      std::locale::facet(refs)
+    {}
+
+
+    /**
+     * Print color.
+     *
+     * \param  color     code
+     * \return           text
+     */
+    virtual const char* c_str(const JColor_t color) const = 0;
+
+
+    /**
+     * Clone this facet.
+     *
+     * \return           pointer to newly created facet
+     */
+    virtual JColorFacet* clone() const = 0;
+
+
+    /**
+     * Check color.
+     *
+     * \param  color     code
+     * \return           true if color; else false
+     */
+    static inline bool is_color(const int color)
+    {
+      return !is_bold(color) && !is_reset(color);
+    }
+
+
+    /**
+     * Check bold.
+     *
+     * \param  color     code
+     * \return           true if bold; else false
+     */
+    static inline bool is_bold(const int color)
+    {
+      return color == BOLD;
+    }
+
+
+    /**
+     * Check reset.
+     *
+     * \param  color     code
+     * \return           true if reset; else false
+     */
+    static inline bool is_reset(const int color)
+    {
+      return color == RESET;
+    }
+  private:
+
+    JColorFacet(const JColorFacet&);          // not defined
+    void operator=(const JColorFacet&);       // not defined
+  };
+
+
+  /**
+   * Facet class to specify text color for ASCII.
+   */
+  struct JColorFacetASCII : 
+    public JColorFacet
+  {
+    /**
+     * Get name of facet.
+     *
+     * \return           name
+     */
+    static inline const char* getName() 
+    {
+      return "ASCII";
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  refs      reference count
+     */
+    JColorFacetASCII(std::size_t refs = 0) :
+      JColorFacet(refs)
+    {}
+
+
+    /**
+     * Print color.
+     *
+     * \param  color     code
+     * \return           text
+     */
+    virtual const char* c_str(const JColor_t color) const override 
+    {
+      switch (color) {
+      case RED:     return "\033[91m"; 
+      case GREEN:   return "\033[92m"; 
+      case BLUE:    return "\033[94m";
+      case WHITE:   return "\033[97m";
+      case CYAN:    return "\033[96m";
+      case PURPLE:  return "\033[95m";
+      case YELLOW:  return "\033[93m";
+      case BOLD:    return "\033[1m";
+      case RESET:   return "\033[0m";
+      default:      return "";
+      }
+    }
+
+
+    /**
+     * Clone this facet.
+     *
+     * \return           pointer to newly created facet
+     */
+    virtual JColorFacetASCII* clone() const override 
+    {
+      return new JColorFacetASCII();
+    }
+  };
+
+
+  /**
+   * Facet class to specify text color for ELcode.
+   */
+  struct JColorFacetELcode : 
+    public JColorFacet
+  {
+    /**
+     * Get name of facet.
+     *
+     * \return           name
+     */
+    static inline const char* getName() 
+    {
+      return "ELcode";
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  refs      reference count
+     */
+    JColorFacetELcode(std::size_t refs = 0) :
+      JColorFacet(refs)
+    {}
+
+
+    /**
+     * Print color.
+     *
+     * \param  color     code
+     * \return           text
+     */
+    virtual const char* c_str(const JColor_t color) const override 
+    {
+      static std::string buffer;
+
+      history.push_back(color);
+
+      switch (color) {
+
+      case RED:    return "[color=red]";
+      case GREEN:  return "[color=green]";
+      case BLUE:   return "[color=blue]";
+      case WHITE:  return "[color=white]";
+      case CYAN:   return "[color=cyan]";
+      case PURPLE: return "[color=purple]";
+      case YELLOW: return "[color=yellow]";
+      case BOLD:   return "[bold]";
+
+      case RESET:
+
+	buffer.clear();
+
+	for (std::vector<int>::const_reverse_iterator i = history.rbegin(); i != history.rend(); ++i) {
+	  if      (is_color(*i)) 
+	    buffer += "[/color]";
+	  else if (is_bold (*i)) 
+	    buffer += "[/bold]";
+	  else
+	    ;
+	}
+
+	history.clear();
+
+	return buffer.c_str();
+	
+      default:     return "";
+      }
+    }
+
+
+    /**
+     * Clone this facet.
+     *
+     * \return           pointer to newly created facet
+     */
+    virtual JColorFacetELcode* clone() const override 
+    {
+      return new JColorFacetELcode();
+    }
+
+  private:
+    mutable std::vector<int> history;
+  };
+
+
+  /**
+   * Typelist of color facets.
+   */
+  typedef JTYPELIST<JColorFacetASCII, JColorFacetELcode>::typelist    JColorFacetTypes_t;
+
+
+  /**
+   * Auxiliary map for color facets.
+   */
+  struct JColorFacetMap_t :
+    public std::map<std::string, JSinglePointer<JColorFacet> >
+  {
+    typedef std::map<std::string, JSinglePointer<JColorFacet> >  map_type;
+    typedef typename map_type::key_type                          key_type;
+    typedef typename map_type::mapped_type                       mapped_type;
+    typedef typename map_type::value_type                        value_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JColorFacetMap_t()
+    {
+      for_each(*this, JType<JColorFacetTypes_t>());
+    }
+
+
+    /**
+     * Get value for given key.
+     *
+     * Note that this method will throw an error if given key is absent.
+     *
+     * \param  key       key
+     * \return           value
+     */
+    const mapped_type& operator[](const key_type& key) const
+    {
+      const_iterator p = find(key);
+
+      if (p != this->end()) {
+	return p->second;
+      }
+
+      THROW(JNullPointerException, "Invalid key " << key);
+    }
+
+
+    /**
+     * Insert data type.
+     *
+     * \param  type      data type
+     */
+    template<class T>
+    void operator()(const JType<T>& type) 
+    {
+      insert(value_type(T::getName(), new T()));
+    }
+  };
+
+
+  /**
+   * Color facets.
+   */
+  static const JColorFacetMap_t   color_facets;
+}
+
+
+/**
+ * Print color.
+ *
+ * \param  out               output stream
+ * \param  color             color
+ * \return                   output stream
+ */
+inline std::ostream& operator<<(std::ostream& out, const JLANG::JColor_t color)
+{
+  using namespace std;
+  using namespace JPP;
+
+  const locale& loc = out.getloc();
+          
+  if      (has_facet<JColorFacetASCII>(loc)) 
+    return out << use_facet<JColorFacetASCII> (loc).c_str(color);
+  else if (has_facet<JColorFacetELcode>(loc)) 
+    return out << use_facet<JColorFacetELcode>(loc).c_str(color);
+  else
+    return out << JColorFacetASCII().c_str(color);
+}
+
+#endif
diff --git a/src/jpp/JLang/JComparisonAvailable.hh b/src/jpp/JLang/JComparisonAvailable.hh
new file mode 100644
index 0000000..8bd8350
--- /dev/null
+++ b/src/jpp/JLang/JComparisonAvailable.hh
@@ -0,0 +1,129 @@
+
+#ifndef __JLANG__JCOMPARISONAVAILABLE__
+#define __JLANG__JCOMPARISONAVAILABLE__
+
+#include "JLang/JNullType.hh"
+#include "JLang/JAnyType.hh"
+#include "JLang/JVoid.hh"
+#include "JLang/JTest.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Local namespace for fallback implementations for comparison operators.
+   */  
+  namespace JLOCAL {
+    
+    /**
+     * Fallback implementations for comparison operators.
+     */
+    inline JNullType operator==(JAnyType, JAnyType) { return JNullType(); }
+    inline JNullType operator!=(JAnyType, JAnyType) { return JNullType(); }
+    inline JNullType operator< (JAnyType, JAnyType) { return JNullType(); }
+    inline JNullType operator> (JAnyType, JAnyType) { return JNullType(); }
+    inline JNullType operator<=(JAnyType, JAnyType) { return JNullType(); }
+    inline JNullType operator>=(JAnyType, JAnyType) { return JNullType(); }
+
+    
+    /**
+     * Test availability of comparison operators of non-composite data types.
+     */
+    template<class T, class JType_t = void>
+    class JComparisonAvailable :
+      public JTest
+    {
+      using JTest::test;
+    
+      static JTrue test(const bool&);
+    
+      static T& getReference();
+    
+    public:
+      static const bool has_eq = JTEST(test(getReference() == getReference()));  //!< true if operator== available; else false
+      static const bool has_ne = JTEST(test(getReference() != getReference()));  //!< true if operator!= available; else false
+      static const bool has_lt = JTEST(test(getReference() <  getReference()));  //!< true if operator<  available; else false
+      static const bool has_gt = JTEST(test(getReference() >  getReference()));  //!< true if operator>  available; else false
+      static const bool has_le = JTEST(test(getReference() <= getReference()));  //!< true if operator<= available; else false
+      static const bool has_ge = JTEST(test(getReference() >= getReference()));  //!< true if operator>= available; else false
+    };
+
+
+    /**
+     * Test availability of comparison operators of data types which have a type definitions for first_type and second_type.
+     * This applies to STL containers such as std::map.
+     * Note that STL provides for the comparison of the container based on comparisons of its elements.
+     */
+    template<class T>
+    class JComparisonAvailable<T, typename JVoid<typename T::second_type>::type>
+    {
+      typedef typename T::first_type     first_type;
+      typedef typename T::second_type    second_type;
+
+    public:
+      static const bool has_eq = JComparisonAvailable<first_type>::has_eq && JComparisonAvailable<second_type>::has_eq;
+      static const bool has_ne = JComparisonAvailable<first_type>::has_ne && JComparisonAvailable<second_type>::has_ne;
+      static const bool has_lt = JComparisonAvailable<first_type>::has_lt && JComparisonAvailable<second_type>::has_lt;
+      static const bool has_gt = JComparisonAvailable<first_type>::has_gt && JComparisonAvailable<second_type>::has_gt;
+      static const bool has_le = JComparisonAvailable<first_type>::has_le && JComparisonAvailable<second_type>::has_le;
+      static const bool has_ge = JComparisonAvailable<first_type>::has_ge && JComparisonAvailable<second_type>::has_ge;
+    };
+
+
+    /**
+     * Test availability of comparison operators of data types which have a type definition for value_type.
+     * This applies to STL containers such as std::vector and std::set.
+     * Note that STL provides for the comparison of the container based on comparisons of its elements.
+     */
+    template<class T>
+    class JComparisonAvailable<T, typename JVoid<typename T::value_type>::type> :
+      public JComparisonAvailable<typename T::value_type>
+    {};
+
+
+    /**
+     * Template base class for data structures without equality capability.
+     * This class implements the operators <tt> == != </tt>.
+     */
+    template<class T>
+    class JNoequals {
+    private:
+      /**
+       * Equal operator.
+       *
+       * \param  first        first object
+       * \param  second       second object
+       * \return              true if two objects are equal; else false
+       */
+      friend JNullType operator==(const T& first, const T& second)
+      { 
+	return JNullType();
+      }
+
+
+      /**
+       * Not equal operator.
+       *
+       * \param  first        first object
+       * \param  second       second object
+       * \return              true if two objects are not equal; else false
+       */
+      friend JNullType operator!=(const T& first, const T& second)
+      {
+	return JNullType();
+      }
+    };
+  }
+
+  using JLOCAL::JComparisonAvailable;
+  using JLOCAL::JNoequals;
+}
+
+#endif
diff --git a/src/jpp/JLang/JEquation.hh b/src/jpp/JLang/JEquation.hh
new file mode 100644
index 0000000..7a727ca
--- /dev/null
+++ b/src/jpp/JLang/JEquation.hh
@@ -0,0 +1,381 @@
+#ifndef __JLANG__JEQUATION__
+#define __JLANG__JEQUATION__
+
+#include <string>
+#include <locale>
+#include <cstdio>
+#include <sstream>
+
+#include "JLang/JString.hh"
+#include "JLang/JEquationFacet.hh"
+#include "JLang/JValue.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * General purpose equation class.
+   *
+   * An equation could have the following formats:
+   *
+   * <pre>
+   *       \<skip line\>  "comment"  \<end of line\>
+   *       \<skip line\>  "comment"  \<end of line\>
+   *       \<key\> \<separator\> \<value\> \<end of line\>
+   *       \<key\> \<separator\> \<left bracket\> \<value\> \<value> \<right bracket\> \<end of line\>
+   *       \<key\>\<division\>\<key\> \<separator\> \<value\> \<end of line\>
+   * </pre>
+   * In this:
+   *        - lines starting with one of the skip line characters are ignored;
+   *        - <tt>key</tt>   is the key of the equation; 
+   *        - <tt>value</tt> is the value of the equation; and 
+   *        - <tt>' '</tt> could be any of the specified white space characters.
+   *
+   * In case of a division of the key, the value of the equation will include
+   * the following key up to the end of line.
+   * The special characters are defined in the JEquationParameters class.
+   * The use of this class for I/O is handled via the JEquationFacet class.
+   */
+  class JEquation {
+  public:
+    /**
+     * Auxiliary data structure for equation.
+     */
+    template<class T>
+    struct equation_type {
+      /**
+       * Constructor.
+       *
+       * \param  __key            key
+       * \param  __value          value
+       */
+      equation_type(const std::string __key,
+		    const T&          __value) :
+	key  (__key),
+	value(__value)
+      {}
+
+
+      /**
+       * Write equation to output stream.
+       *
+       * \param  out              output stream
+       * \param  equation         equation
+       * \return                  output stream
+       */
+      friend inline std::ostream& operator<<(std::ostream& out, const equation_type& equation)
+      {
+	using namespace std;
+	
+	ostream::sentry sentry(out);
+	
+	if (sentry) {
+	  
+	  const locale& loc = out.getloc();
+	  
+	  if (has_facet<JEquationFacet>(loc)) {
+	    
+	    const JEquationFacet& facet = use_facet<JEquationFacet>(loc);
+	    
+	    out << equation.key;
+	    out << facet.getDefaultSeparator();
+	    out << equation.value;
+	    out << facet.getDefaultEndOfLine();
+	    
+	  } else {
+	    
+	    out << equation.key;
+	    out << '=';
+	    out << equation.value;
+	    out << endl;
+	  }
+	}
+
+	return out;
+      }
+
+      std::string key;
+      const T&    value;
+    };
+
+
+    /**
+     * Auxiliary method to create equation type.
+     *
+     * \param  key              key
+     * \param  value            value
+     */
+    template<class T>
+    static inline equation_type<T> make_equation(const std::string& key, const T& value)
+    {
+      return equation_type<T>(key, value);
+    }
+    
+    
+    /**
+     * Default constructor.
+     */
+    JEquation() :
+      key  (),
+      sep  ('\0'),
+      value()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  key              key
+     * \param  value            value
+     */
+    JEquation(const std::string& key, const std::string& value) :
+      key  (key),
+      sep  ('\0'),
+      value(value)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  buffer           input
+     * \param  facet            facet
+     */
+    JEquation(const std::string& buffer, const JEquationFacet& facet)
+    {
+      setEquation(buffer, facet);
+    }
+
+
+    /**
+     * Get key.
+     *
+     * \return                  key
+     */
+    const std::string& getKey() const
+    {
+      return key;
+    }
+
+
+    /**
+     * Get separator.
+     *
+     * \return                  separator
+     */
+    const char getSeparator() const
+    {
+      return sep;
+    }
+
+
+    /**
+     * Get value.
+     *
+     * \return                  value
+     */
+    const std::string& getValue() const
+    {
+      return value;
+    }
+
+
+    /**
+     * Read equation from input stream.
+     *
+     * \param  in               input stream
+     * \param  equation         equation
+     * \return                  input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JEquation& equation)
+    {
+      using namespace std;
+
+      istream::sentry sentry(in, false);
+
+      if (sentry) {
+
+	equation = JEquation();
+
+	const locale& loc = in.getloc();
+
+	if (has_facet<JEquationFacet>(loc)) {
+
+	  const JEquationFacet& facet = use_facet<JEquationFacet>(loc);
+
+	  ios_base::iostate state = in.rdstate();
+
+
+	  for (int c; (c = in.peek()) != EOF && facet.isSkipLine((char) c); ) {
+	    facet.ignore(in);
+	  }
+
+
+	  if (state == ios_base::goodbit) facet.get(in, istreambuf_iterator<char>(), in, state, equation.key);
+	  if (state == ios_base::goodbit) facet.get(in, istreambuf_iterator<char>(), in, state, equation.sep);
+	  if (state == ios_base::goodbit) facet.getline(in, equation.value);
+
+
+	  // remove white spaces and brackets before evaluation
+
+	  if (facet.isSeparator(equation.sep)) {
+
+	    JString::const_iterator         p = equation.value. begin();
+	    JString::const_reverse_iterator q = equation.value.rbegin();
+
+	    for ( ; ; ++p, ++q) {
+
+	      for ( ; p != equation.value. end() && facet.isWhiteSpace(*p); ++p) {}
+	      for ( ; q != equation.value.rend() && facet.isWhiteSpace(*q); ++q) {}
+	    
+	      if (p == equation.value. end() || *p != facet.getLeftBracket() ||
+		  q == equation.value.rend() || *q != facet.getRightBracket()) {
+		break;
+	      }
+	    }
+
+	    if (p != equation.value.begin() || q != equation.value.rbegin()) {
+	      equation.value = string(p, q.base());
+	    }
+	  }
+
+          if (state != ios_base::goodbit && state != ios_base::eofbit) {
+            in.setstate(state);
+	  }
+
+	  if (!(state & ios_base::eofbit)) {
+	    if (!facet.isDivision (equation.sep) &&
+		!facet.isSeparator(equation.sep)) {
+	      in.setstate(ios_base::badbit);
+	    }
+	  }
+
+	} else {
+
+	  in.setstate(ios_base::failbit);
+	}
+      }
+
+      return in;
+    }
+
+
+    /**
+     * Write equation to output stream.
+     *
+     * \param  out              output stream
+     * \param  equation         equation
+     * \return                  output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JEquation& equation)
+    {
+      using namespace std;
+
+      ostream::sentry sentry(out);
+
+      if (sentry) {
+
+	const locale& loc = out.getloc();
+
+	if (has_facet<JEquationFacet>(loc)) {
+
+	  const JEquationFacet& facet = use_facet<JEquationFacet>(loc);
+
+	  out << equation.key;
+	  out << facet.getDefaultSeparator();
+	  out << equation.value;
+	  out << facet.getDefaultEndOfLine();
+
+	} else {
+
+	  out << equation.key;
+	  out << equation.sep;
+	  out << equation.value;
+	  out << endl;
+	}
+      }
+
+      return out;
+    }
+
+
+    /**
+     * Set equation.
+     *
+     * \param  buffer           input
+     * \param  facet            facet
+     * \return                  this equation
+     */
+    JEquation& setEquation(const std::string& buffer, const JEquationFacet& facet)
+    {
+      using namespace std;
+
+      istringstream in(buffer);
+
+      in.imbue(locale(in.getloc(), facet.clone()));
+
+      in >> *this;
+
+      return *this;
+    }
+
+
+    /**
+     * Set this equation to its value.
+     *
+     * \param  facet            facet
+     * \return                  this equation
+     */
+    JEquation& setEquation(const JEquationFacet& facet)
+    {
+      setEquation(getValue(), facet);
+
+      return *this;
+    }
+
+
+    /**
+     * Extract equation.
+     *
+     * \param  buffer           input
+     * \param  facet            facet
+     * \return                  equation
+     */
+    static JEquation valueOf(const std::string& buffer, const JEquationFacet& facet)
+    {
+      return JEquation(buffer, facet);
+    }
+
+
+    /**
+     * Convert equation to string.
+     *
+     * \return                  string
+     */
+    std::string toString() const
+    {
+      std::string buffer;
+
+      buffer += getKey();
+      buffer += getSeparator();
+      buffer += getValue();
+
+      return buffer;
+    }
+
+  protected:
+    JString   key;
+    char      sep;
+    JString   value;
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JEquationFacet.hh b/src/jpp/JLang/JEquationFacet.hh
new file mode 100644
index 0000000..b3c9992
--- /dev/null
+++ b/src/jpp/JLang/JEquationFacet.hh
@@ -0,0 +1,611 @@
+#ifndef __JLANG__JEQUATIONFACET__
+#define __JLANG__JEQUATIONFACET__
+
+#include <istream>
+#include <ostream>
+#include <locale>
+#include <string>
+#include <iterator>
+#include <cstdio>
+#include <limits>
+
+#include "JLang/JStringFacet.hh"
+#include "JLang/JEquationParameters.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Facet class to specify parsing of equations in currect locale (see class JLANG::JEquation).
+   * Tokens are defined as a piece of text delimited by various markers according the facet.
+   * The list of markers is defined by the JLANG::JEquationParameters data structure.
+   * This class extends the JLANG::JStringFacet and JLANG::JEquationParameters classes.
+   */
+  class JEquationFacet: 
+    public JStringFacet,
+    public JEquationParameters
+  {
+  public:
+
+    using JStringFacet::get;
+    using JStringFacet::put;
+
+
+    /**
+     * Default constructor.
+     */
+    JEquationFacet() :
+      JStringFacet(),
+      JEquationParameters()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  parameters   equation parameters
+     */
+    JEquationFacet(const JEquationParameters& parameters) :
+      JStringFacet(),
+      JEquationParameters(parameters)
+    {}
+
+
+    /**
+     * Clone this facet.
+     *
+     * \return           pointer to newly created facet
+     */
+    virtual JEquationFacet* clone() const override 
+    {
+      return new JEquationFacet(static_cast<const JEquationParameters&>(*this));
+    }
+
+
+    /**
+     * Get character.
+     *
+     * \param  __begin   begin position of input stream
+     * \param  __end     end   position of input stream
+     * \param  format    format
+     * \param  result    status after input operation
+     * \param  buffer    output character
+     * \return           position of input stream
+     */
+    istreambuf_iterator get(const istreambuf_iterator __begin,
+			    const istreambuf_iterator __end,
+			    const std::ios_base&      format,
+			    std::ios_base::iostate&   result,
+			    char&                     buffer) const
+    {
+      return do_get(__begin, __end, format, result, buffer);
+    }
+
+
+    /**
+     * Put character.
+     *
+     * \param  out       begin position of output stream
+     * \param  format    format
+     * \param  c         fill character
+     * \param  buffer    input character
+     * \return           position of output stream buffer
+     */
+    ostreambuf_iterator put(ostreambuf_iterator  out,
+			    const std::ios_base& format,
+			    const char           c,
+			    const char           buffer) const
+    {
+      return do_put(out, format, c, buffer);
+    }
+
+
+    /**
+     * Get combined prefix for output.
+     *
+     * \param  prefix    prefix
+     * \param  name      name
+     * \return           prefix
+     */
+    const std::string getPrefix(const std::string& prefix, const std::string& name) const
+    {
+      if (prefix.empty())
+	return name;
+      else
+	return prefix + getDefaultDivision() + name;
+    }
+
+
+    /**
+     * Pop white spaces.
+     *
+     * \param  in        input stream
+     * \return           input stream
+     */
+    std::istream& pop(std::istream& in) const
+    {
+      try {
+	for (int c; (c = in.peek()) != EOF && isWhiteSpace((char) c); ) { in.get(); }
+      }
+      catch(const std::exception& error) {};
+
+      return in;
+    }
+
+  protected:
+    /**
+     * Get string.
+     *
+     * \param  __begin   begin position of input stream
+     * \param  __end     end   position of input stream
+     * \param  format    format
+     * \param  result    status after input operation
+     * \param  buffer    output string
+     * \return           position of input stream
+     */
+    virtual istreambuf_iterator do_get(const istreambuf_iterator __begin,
+				       const istreambuf_iterator __end,
+				       const std::ios_base&      format,
+				       std::ios_base::iostate&   result,
+				       std::string&              buffer) const override
+    {
+      using namespace std;
+
+      result = (ios_base::iostate) 0;  // reset I/O status
+
+      streamsize n = format.width();   // number of characters to read
+
+      if (n == 0) {
+	n = numeric_limits<streamsize>::max();
+      }
+
+      istreambuf_iterator i = __begin;
+
+      while (i != __end && isWhiteSpace(*i)) {
+	++i;
+      }
+
+      if (i == __end) {
+
+	result |= ios_base::failbit;	
+	result |= ios_base::eofbit;
+
+      } else if (isSeparator(*i) ||
+		 isEndOfLine(*i) ||
+		 isDivision (*i)) {
+
+	result |= ios_base::failbit;	
+
+      } else { 
+
+	buffer.clear();
+	buffer.push_back(*i);
+
+	for (++i, --n; i != __end && n != 0 && (!isWhiteSpace(*i) &&
+						!isSeparator (*i) &&
+						!isEndOfLine (*i) &&
+						!isDivision  (*i)); ++i, --n)
+	  buffer.push_back(*i);
+
+	if (i == __end) {
+	  result |= ios_base::eofbit;
+	}
+      }
+
+      return i;
+    }
+
+
+    /**
+     * Get character.
+     *
+     * \param  __begin   begin position of input stream
+     * \param  __end     end   position of input stream
+     * \param  format    format
+     * \param  result    status after input operation
+     * \param  buffer    output character
+     * \return           position of input stream
+     */
+    virtual istreambuf_iterator do_get(const istreambuf_iterator __begin,
+				       const istreambuf_iterator __end,
+				       const std::ios_base&      format,
+				       std::ios_base::iostate&   result,
+				       char&                     buffer) const
+    {
+      using namespace std;
+
+      result = (ios_base::iostate) 0;  // reset I/O status
+
+      istreambuf_iterator i = __begin;
+
+      while (i != __end && isWhiteSpace(*i)) {
+	++i;
+      }
+
+      if (i == __end) {
+
+	result |= ios_base::failbit;	
+	result |= ios_base::eofbit;
+
+      } else if (!isDivision(*i) && !isSeparator(*i)) {
+
+	result |= ios_base::failbit;	
+
+      } else {
+
+	buffer = *i++;
+      }
+
+      return i;
+    }
+
+
+    /**
+     * Put string.
+     *
+     * \param  out       begin position of output stream
+     * \param  format    format
+     * \param  c         fill character
+     * \param  buffer    input string
+     * \return           current position of output stream
+     */
+    virtual ostreambuf_iterator do_put(ostreambuf_iterator  out,
+				       const std::ios_base& format,
+				       const char           c,
+				       const std::string&   buffer) const override
+    {
+      using namespace std;
+
+      if (format.flags() & ios_base::right) {
+	for (streamsize i = buffer.size(); i < format.width(); ++i, ++out) {
+	  *out = c;
+	}
+      }
+
+      for (string::const_iterator i = buffer.begin(); i != buffer.end(); ++i, ++out) {
+	*out = *i;
+      }
+	
+      if (format.flags() & ios_base::left) {
+	for (streamsize i = buffer.size(); i < format.width(); ++i, ++out) {
+	  *out = c;
+	}
+      }
+
+      return out;
+    }
+
+
+    /**
+     * Put character.
+     *
+     * \param  out       begin position of output stream
+     * \param  format    format
+     * \param  c         fill character
+     * \param  buffer    input character
+     * \return           current position of output stream
+     */
+    virtual ostreambuf_iterator do_put(ostreambuf_iterator  out,
+				       const std::ios_base& format,
+				       const char           c,
+				       const char           buffer) const
+    {
+      using namespace std;
+
+      if (format.flags() & ios_base::right) {
+	for (streamsize i = 1; i < format.width(); ++i, ++out) {
+	  *out = c;
+	}
+      }
+
+      *out = buffer;
+      ++out;
+	
+      if (format.flags() & ios_base::left) {
+	for (streamsize i = 1; i < format.width(); ++i, ++out) {
+	  *out = c;
+	}
+      }
+
+      return out;
+    }
+
+
+    /**
+     * \cond NEVER
+     * Ignore characters until next end of line.
+     *
+     * \param  __begin   begin position of input stream
+     * \param  __end     end   position of input stream
+     * \return           position of input stream
+     * \endcond
+     */
+    /*
+    virtual istreambuf_iterator do_ignore(const istreambuf_iterator __begin,
+					  const istreambuf_iterator __end) const
+    {
+      istreambuf_iterator i = __begin;
+
+      while (i != __end && !isEndOfLine(*i)) {
+	++i;
+      }
+	
+      while (i != __end &&  isEndOfLine(*i)) {
+	++i;          // skip end of line(s)
+      }
+
+      return i;
+    }
+    */
+
+    /**
+     * Read string.
+     *
+     * \param  __begin   begin position of input stream
+     * \param  __end     end   position of input stream
+     * \param  result    status after input operation
+     * \param  buffer    output string
+     * \return           position of input stream
+     */
+    virtual istreambuf_iterator do_getline(const istreambuf_iterator __begin,
+					   const istreambuf_iterator __end,
+					   std::ios_base::iostate&   result,
+					   std::string&              buffer) const override
+    {
+      using namespace std;
+
+      result = (ios_base::iostate) 0;  // reset I/O status
+
+      istreambuf_iterator i = __begin;
+
+      while (i != __end && isWhiteSpace(*i) && !isEndOfLine(*i)) {
+	++i;
+      }
+
+      if (i == __end) {
+
+	result |= ios_base::failbit;	
+	result |= ios_base::eofbit;
+
+      } else if (isEndOfLine(*i)) {
+
+	buffer.clear();
+
+      } else {
+
+	buffer.clear();
+
+	for (int count = 0; i != __end && (count != 0 || !isEndOfLine(*i)); ++i) {
+
+	  buffer.push_back(*i);
+
+	  if        (isLeftBracket (*i)) {
+	    ++count;
+	  } else if (isRightBracket(*i)) {
+	    --count;
+	  }
+	}
+
+	while (i != __end && isEndOfLine(*i)) {
+	  ++i;          // skip end of line(s)
+	}
+      }
+
+      return i;
+    }
+
+  private:
+
+    JEquationFacet(const JEquationFacet&);   // not defined
+    void operator=(const JEquationFacet&);   // not defined
+  };
+
+
+  /**
+   * Auxiliary class for end of line.
+   */
+  struct JEndOfLine
+  {
+    /**
+     * Default constructor.
+     */
+    JEndOfLine() :
+      index(0)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  i         index
+     * \return           this JEndOfLine
+     */
+    const JEndOfLine& operator()(const unsigned int i) const
+    {
+      index = i;
+
+      return *this;
+    }
+
+
+    /**
+     * Print end of line.
+     *
+     * \param  out       output stream
+     * \param  eol       end of line
+     * \return           output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JEndOfLine& eol)
+    {
+      using namespace std;
+
+      if (has_facet<JEquationFacet>(out.getloc()))
+	out << use_facet<JEquationFacet>(out.getloc()).getPreferredEndOfLine(eol.index);
+      else
+	out << '\n';
+
+      eol.index = 0;
+      
+      return out;
+    }
+
+  private:
+    mutable unsigned int index;
+  };
+
+
+  /**
+   * Type definition of stream manipulator for equational I/O.
+   */
+  typedef JLANG::JEquationFacet    setequation;
+
+
+  /**
+   * Parse facet.
+   *
+   * \param  in             input stream
+   * \param  facet          facet
+   * \return                input stream
+   */
+  inline std::istream& operator>>(std::istream& in, const JLANG::JEquationFacet& facet)
+  {
+    using namespace std;
+  
+    in.imbue(locale(in.getloc(), facet.clone()));
+  
+    return in;
+  }
+
+
+  /**
+   * Parse facet.
+   *
+   * \param  out            output stream
+   * \param  facet          facet
+   * \return                output stream
+   */
+  inline std::ostream& operator<<(std::ostream& out, const JLANG::JEquationFacet& facet)
+  {
+    using namespace std;
+  
+    out.imbue(locale(out.getloc(), facet.clone()));
+  
+    return out;
+  }
+
+
+  /**
+   * Print white space.
+   *
+   * \param  out       output stream
+   * \return           output stream
+   */
+  inline std::ostream& white_space(std::ostream& out)
+  {
+    using namespace std;
+    using namespace JLANG;
+  
+    if (has_facet<JEquationFacet>(out.getloc()))
+      out << use_facet<JEquationFacet>(out.getloc()).getDefaultWhiteSpace();
+    else
+      out << ' ';
+  
+    return out;
+  }
+
+
+  /**
+   * Print division.
+   *
+   * \param  out       output stream
+   * \return           output stream
+   */
+  inline std::ostream& division(std::ostream& out)
+  {
+    using namespace std;
+    using namespace JLANG;
+  
+    if (has_facet<JEquationFacet>(out.getloc()))
+      out << use_facet<JEquationFacet>(out.getloc()).getDefaultDivision();
+    else
+      out << '.';
+  
+    return out;
+  }
+
+
+  /**
+   * Print separator.
+   *
+   * \param  out       output stream
+   * \return           output stream
+   */
+  inline std::ostream& separator(std::ostream& out)
+  {
+    using namespace std;
+    using namespace JLANG;
+
+    if (has_facet<JEquationFacet>(out.getloc()))
+      out << use_facet<JEquationFacet>(out.getloc()).getDefaultSeparator();
+    else
+      out << '=';
+  
+    return out;
+  }
+
+
+  /**
+   * Print end of line.
+   */
+  static const JLANG::JEndOfLine end_of_line;
+
+
+  /**
+   * Print left bracket.
+   *
+   * \param  out       output stream
+   * \return           output stream
+   */
+  inline std::ostream& left_bracket(std::ostream& out)
+  {
+    using namespace std;
+    using namespace JLANG;
+  
+    if (has_facet<JEquationFacet>(out.getloc()))
+      out << use_facet<JEquationFacet>(out.getloc()).getLeftBracket();
+    else
+      out << '(';
+  
+    return out;
+  }
+
+
+  /**
+   * Print right bracket.
+   *
+   * \param  out       output stream
+   * \return           output stream
+   */
+  inline std::ostream& right_bracket(std::ostream& out)
+  {
+    using namespace std;
+    using namespace JLANG;
+
+    if (has_facet<JEquationFacet>(out.getloc()))
+      out << use_facet<JEquationFacet>(out.getloc()).getRightBracket();
+    else
+      out << ')';
+  
+    return out;
+  }
+}
+
+#endif
diff --git a/src/jpp/JLang/JEquationParameters.hh b/src/jpp/JLang/JEquationParameters.hh
new file mode 100644
index 0000000..592d2dd
--- /dev/null
+++ b/src/jpp/JLang/JEquationParameters.hh
@@ -0,0 +1,454 @@
+#ifndef __JLANG__JEQUATIONPARAMETERS__
+#define __JLANG__JEQUATIONPARAMETERS__
+
+#include <string>
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+  
+
+  /**
+   * Simple data structure to support I/O of equations (see class JLANG::JEquation).
+   */
+  class JEquationParameters {
+  public:
+    /**
+     * Default constructor.
+     */
+    JEquationParameters()
+    {
+      this->sep   = "=";
+      this->eol   = "\n\r;";
+      this->div   = "./";
+      this->skip  = "#";
+      this->left  = '(';
+      this->right = ')';
+      this->ws    = " \t\n\v\f\r";
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param sep          separator   characters
+     * \param eol          end of line characters
+     * \param div          division    characters
+     * \param skip         skip line   characters
+     * \param left         left  bracket
+     * \param right        right bracket
+     * \param ws           white space characters
+     */
+    JEquationParameters(const std::string& sep,
+			const std::string& eol,
+			const std::string& div,
+			const std::string& skip,
+			const char         left  = '(',
+			const char         right = ')',
+			const std::string& ws    = " \t\n\v\f\r")
+    {
+      this->sep   = sep;
+      this->eol   = eol;
+      this->div   = div;
+      this->skip  = skip;
+      this->left  = left;
+      this->right = right;
+      this->ws    = ws;
+    }
+
+
+    /**
+     * Get equation parameters.
+     *
+     * \return             equation parameters
+     */
+    const JEquationParameters& getEquationParameters() const
+    {
+      return *this;
+    }
+
+
+    /**
+     * Set equation parameters.
+     *
+     * \param  buffer      equation parameters
+     */
+    void setEquationParameters(const JEquationParameters& buffer)
+    {
+      static_cast<JEquationParameters&>(*this) = buffer;
+    }
+
+
+    /**
+     * Get default separator character.
+     *
+     * \return             separator between parameter and its value
+     */
+    const char getDefaultSeparator() const
+    { 
+      if (sep.empty())
+	return '=';
+      else
+	return sep[0];
+    }
+
+
+    /**
+     * Get separator characters.
+     *
+     * \return             separator between parameter and its value
+     */
+    const std::string& getSeparator() const
+    { 
+      return sep;
+    }
+
+
+    /**
+     * Set separator character(s).
+     *
+     * \param sep          separator between parameter and its value
+     */
+    void setSeparator(const std::string& sep) 
+    { 
+      this->sep = sep; 
+    }
+
+
+    /**
+     * Get default end of line character.
+     *
+     * \return             end of line character
+     */
+    const char getDefaultEndOfLine() const
+    { 
+      if (eol.empty())
+	return '\n';
+      else
+	return eol[0];
+    }
+
+
+    /**
+     * Get preferred end of line character.
+     *
+     * \param  index       index
+     * \return             end of line character
+     */
+    const char getPreferredEndOfLine(const unsigned int index) const
+    { 
+      if      (eol.empty())
+	return '\n';
+      else if (index < eol.size())
+	return eol[index];
+      else
+	return eol[0];
+    }
+
+
+    /**
+     * Get end of line characters.
+     *
+     * \return             end of line characters
+     */
+    const std::string& getEndOfLine() const
+    { 
+      return eol;
+    }
+
+
+    /**
+     * Set end of line characters.
+     *
+     * \param eol          end of line character
+     */
+    void setEndOfLine(const std::string& eol) 
+    { 
+      this->eol = eol;
+    }
+
+
+    /**
+     * Get default division character.
+     *
+     * \return             division character
+     */
+    const char getDefaultDivision() const
+    { 
+      if (div.empty())
+	return '.';
+      else
+	return div[0];
+    }
+
+
+    /**
+     * Get division characters.
+     *
+     * \return             division characters
+     */
+    const std::string& getDivision() const
+    { 
+      return div;
+    }
+
+
+    /**
+     * Set division characters.
+     *
+     * \param div          division characters
+     */
+    void setDivision(const std::string& div) 
+    { 
+      this->div = div;
+    }
+
+
+    /**
+     * Get default skip line character.
+     *
+     * \return             skip line character
+     */
+    const char getDefaultSkipLine() const
+    { 
+      if (skip.empty())
+	return '#';
+      else
+	return skip[0];
+    }
+
+
+    /**
+     * Get skip line characters.
+     *
+     * \return             skip line characters
+     */
+    const std::string& getSkipLine() const
+    { 
+      return skip;
+    }
+
+
+    /**
+     * Set skip line characters.
+     *
+     * \param skip         skip line characters
+     */
+    void setSkipLine(const std::string& skip) 
+    { 
+      this->skip = skip;
+    }
+
+
+    /**
+     * Set brackets.
+     *
+     * \param  left        left  bracket
+     * \param  right       right bracket
+     */
+    void setBrackets(const char left, const char right)
+    {
+      this->left  = left;
+      this->right = right;
+    }
+
+
+    /**
+     * Get left bracket.
+     *
+     * \return             left bracket
+     */
+    char getLeftBracket() const
+    {
+      return left;
+    }
+
+
+    /**
+     * Get right bracket.
+     *
+     * \return             right bracket
+     */
+    char getRightBracket() const
+    {
+      return right;
+    }
+
+
+    /**
+     * Get default white space character.
+     *
+     * \return             white space character
+     */
+    const char getDefaultWhiteSpace() const
+    { 
+      if (ws.empty())
+	return ' ';
+      else
+	return ws[0];
+    }
+
+
+    /**
+     * Get white space characters.
+     *
+     * \return             white space characters
+     */
+    const std::string& getWhiteSpace() const
+    { 
+      return ws;
+    }
+
+
+    /**
+     * Set white space characters.
+     *
+     * \param ws           white space characters
+     */
+    void setWhiteSpace(const std::string& ws) 
+    { 
+      this->ws = ws;
+    }
+
+
+    /** 
+     * Join equation parameters.
+     *
+     * \param value        equation parameters
+     */
+    JEquationParameters& join(const JEquationParameters& value)
+    { 
+      using namespace std;
+
+      for (string::const_iterator i = value.sep.begin(); i != value.sep.end(); ++i) {
+	if (!isSeparator(*i)) {
+	  sep += *i;
+	}
+      }
+
+      for (string::const_iterator i = value.eol.begin(); i != value.eol.end(); ++i) {
+	if (!isEndOfLine(*i)) {
+	  eol += *i;
+	}
+      }
+
+      for (string::const_iterator i = value.div.begin(); i != value.div.end(); ++i) {
+	if (!isDivision(*i)) {
+	  div += *i;
+	}
+      }
+
+      for (string::const_iterator i = value.skip.begin(); i != value.skip.end(); ++i) {
+	if (!isSkipLine(*i)) {
+	  skip += *i;
+	}
+      }
+
+      for (string::const_iterator i = value.ws.begin(); i != value.ws.end(); ++i) {
+	if (!isWhiteSpace(*i)) {
+	  ws += *i;
+	}
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Test for separator character.
+     * 
+     * \param c            character
+     * \result             true if separator; else false
+     */
+    inline bool isSeparator(const char c) const
+    { 
+      return sep .find(c) != std::string::npos;
+    }
+
+
+    /**
+     * Test for end of line character.
+     * 
+     * \param c            character
+     * \result             true if end of line; else false
+     */
+    inline bool isEndOfLine   (const char c) const { return eol .find(c) != std::string::npos; }
+
+
+    /**
+     * Test for division character.
+     * 
+     * \param c            character
+     * \result             true if division; else false
+     */
+    inline bool isDivision(const char c) const
+    { 
+      return div .find(c) != std::string::npos;
+    }
+
+
+    /**
+     * Test for skip line character.
+     * 
+     * \param c            character
+     * \result             true if skip line; else false
+     */
+    inline bool isSkipLine(const char c) const
+    { 
+      return skip.find(c) != std::string::npos;
+    }
+
+
+    /**
+     * Test for left bracket character.
+     * 
+     * \param c            character
+     * \result             true if left bracket; else false
+     */
+    inline bool isLeftBracket(const char c) const
+    { 
+      return c == left;
+    }
+
+
+    /**
+     * Test for right bracket character.
+     * 
+     * \param c            character
+     * \result             true if right bracket; else false
+     */
+    inline bool isRightBracket(const char c) const
+    { 
+      return c == right;
+    }
+
+
+    /**
+     * Test for white space character.
+     * 
+     * \param c            character
+     * \result             true if white space; else false
+     */
+    inline bool isWhiteSpace(const char c) const
+    { 
+      return ws  .find(c) != std::string::npos;
+    }
+
+  protected:
+    std::string sep;
+    std::string eol;
+    std::string div;
+    std::string skip;
+    char        left;
+    char        right;
+    std::string ws;
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JException.hh b/src/jpp/JLang/JException.hh
index 5892627..0c3cbea 100644
--- a/src/jpp/JLang/JException.hh
+++ b/src/jpp/JLang/JException.hh
@@ -354,6 +354,24 @@ namespace JLANG {
   };
 
 
+  /**
+   * Exception for recovery of file.
+   */
+  class JFileRecoveryException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JFileRecoveryException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
   /**
    * Exception for reading of file.
    */
@@ -660,6 +678,14 @@ namespace JLANG {
   };
 }
 
+/**
+ * Make exception.
+ *
+ * \param  JException_t    exception
+ * \param  A               message
+ */
+#define MAKE_EXCEPTION(JException_t, A) JException_t(static_cast<std::ostringstream&>(JLANG::JException::getOstream() << __FILE__ << ':' << __LINE__ << std::endl << A).str())
+
 /**
  * Marco for throwing exception with std::ostream compatible message.
  *
@@ -667,7 +693,7 @@ namespace JLANG {
  * \param  A               message
  */
 #ifndef THROW
-#define THROW(JException_t, A) do { throw JException_t(static_cast<std::ostringstream&>(JLANG::JException::getOstream() << __FILE__ << ':' << __LINE__ << std::endl << A).str()); } while(0)
+#define THROW(JException_t, A) do { throw MAKE_EXCEPTION(JException_t, A); } while(0)
 #endif
 
 #endif
diff --git a/src/jpp/JLang/JFile.hh b/src/jpp/JLang/JFile.hh
new file mode 100644
index 0000000..967fbae
--- /dev/null
+++ b/src/jpp/JLang/JFile.hh
@@ -0,0 +1,168 @@
+#ifndef __JLANG__JFILE__
+#define __JLANG__JFILE__
+
+#include <fcntl.h>
+
+#include "JLang/JBinaryIO.hh"
+#include "JLang/JAbstractFile.hh"
+#include "JLang/JFileDescriptorMask.hh"
+#include "JLang/JTimeval.hh"
+#include <unistd.h>
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * The JFile class extends the JAbstractFile class.
+   * This class implements the JBinaryInput and JBinaryOutput interfaces.
+   */
+  class JFile :
+    public JAbstractFile,
+    public JBinaryInput,
+    public JBinaryOutput
+  {
+  public:
+    /**
+     * Default constructor.
+     */
+    JFile() :
+      JAbstractFile(),
+      result(0)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  file            file descriptor
+     */
+    JFile(const JAbstractFile& file) :
+      JAbstractFile(file),
+      result(1)
+    {}
+
+
+    /**
+     * Close file.
+     */
+    void close()
+    {
+      if (fileDescriptor != FILE_CLOSED) {
+
+        ::close(fileDescriptor);
+
+        fileDescriptor = FILE_CLOSED;
+	result         = 0;
+      }
+    }
+
+
+    /**
+     * Read data from file.
+     *
+     * \param  buffer       buffer
+     * \param  length       number of bytes to read
+     * \return              number of bytes read
+     */
+    virtual int read(char* buffer, const int length)
+    {
+      return (result = ::read(fileDescriptor, buffer, length));
+    }
+    
+
+    /**
+     * Write data to file.
+     *
+     * \param  buffer       buffer
+     * \param  length       number of bytes to write
+     * \return              number of bytes written
+     */
+    virtual int write(const char* buffer, const int length)
+    {
+      return (result = ::write(fileDescriptor, buffer, length));
+    }
+
+
+    /**
+     * Check availability of input.
+     * This method returns true if at least one byte can be read without blocking.
+     *
+     * \param  timeout      timeout
+     * \return              true if ready to read; else false
+     */
+    bool in_avail(JTimeval timeout = JTimeval::min()) const
+    {
+      return JFileDescriptorMask(*this).in_avail(timeout);
+    }
+
+
+    /**
+     * Check availability of output.
+     * This method returns true if at least one byte can be written without blocking.
+     *
+     * \param  timeout      timeout
+     * \return              true if ready to write; else false
+     */
+    bool out_avail(JTimeval timeout = JTimeval::min()) const
+    {
+      return JFileDescriptorMask(*this).out_avail(timeout);
+    }
+
+
+    /**
+     * Check status.
+     *
+     * \return              true if last I/O operation successful; else false
+     */
+    virtual bool good() const
+    {
+      return is_open() && !eof() && !bad();
+    }
+
+
+    /**
+     * Check status.
+     *
+     * \return              true if last I/O operation caused logical error; else false
+     */
+    virtual bool fail() const
+    {
+      return result == 0;
+    }
+
+
+    /**
+     * Check status.
+     *
+     * \return              true if last I/O operation caused read/write error; else false
+     */
+    virtual bool bad() const
+    {
+      return fail();
+    }
+
+
+    /**
+     * Check end of file.
+     *
+     * \return              true if end of file; else false
+     */
+    virtual bool eof() const
+    {
+      return result == EOF;
+    }
+
+
+  private:
+    int result;
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JFileDescriptorMask.hh b/src/jpp/JLang/JFileDescriptorMask.hh
new file mode 100644
index 0000000..9a9d17e
--- /dev/null
+++ b/src/jpp/JLang/JFileDescriptorMask.hh
@@ -0,0 +1,290 @@
+#ifndef __JLANG__JFILEDESCRIPTORMASK__
+#define __JLANG__JFILEDESCRIPTORMASK__
+
+#include <sys/select.h>
+
+#include "JLang/JAbstractFile.hh"
+#include "JLang/JTimeval.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Auxiliary class for method select.
+   * This class encapsulates the <tt>fd_set</tT> data structure.
+   */
+  class JFileDescriptorMask :
+    protected fd_set
+  {
+  public:
+
+
+    static const int MAXIMUM_FILE_DESCRIPTOR = FD_SETSIZE;
+
+
+    /**
+     * Default constructor.
+     */
+    JFileDescriptorMask() :
+      maximum_file_descriptor   (0),
+      number_of_file_descriptors(0)
+    {
+      FD_ZERO(get());
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  file                 file descriptor
+     */
+    JFileDescriptorMask(const JAbstractFile& file) :
+      maximum_file_descriptor   (0),
+      number_of_file_descriptors(0)
+    {
+      FD_ZERO(get());
+
+      set(file);
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  file_descriptor      file descriptor
+     */
+    JFileDescriptorMask(const int file_descriptor) :
+      maximum_file_descriptor   (0),
+      number_of_file_descriptors(0)
+    {
+      FD_ZERO(get());
+
+      set(file_descriptor);
+    }
+
+
+    /**
+     * Get pointer to mask.
+     *
+     * \return                      pointer to mask
+     */
+    const fd_set* get() const
+    {
+      return static_cast<const fd_set*>(this);
+    }
+
+
+    /**
+     * Get pointer to mask.
+     *
+     * \return                      pointer to mask
+     */
+    fd_set* get()
+    {
+      return static_cast<fd_set*>(this);
+    }
+
+
+    /**
+     * Address of operator.
+     *
+     * \return                      pointer to mask
+     */
+    const fd_set* operator &() const
+    {
+      return get();
+    }
+
+
+    /**
+     * Address of operator.
+     *
+     * \return                      pointer to mask
+     */
+    fd_set* operator &()
+    {
+      return get();
+    }
+
+
+    /**
+     * Reset mask.
+     * A hard reset causes the reset of the complete mask whereas
+     * a soft reset causes the reset of the internal parameters only.
+     *
+     * \param  option               true hard reset; else soft reset
+     */
+    void reset(const bool option = true)
+    {
+      if (option) {
+
+	switch (number_of_file_descriptors) {
+
+	case 0:
+	  break;
+	  
+	case 1:
+	  FD_CLR(maximum_file_descriptor, get());
+	  break;
+	  
+	default:
+	  FD_ZERO(get());
+	  break;
+	}
+      }
+
+      maximum_file_descriptor    = 0;
+      number_of_file_descriptors = 0;
+    }
+
+
+    /**
+     * Set file descriptor.
+     *
+     * \param  file_descriptor      file descriptor
+     */
+    void set(const int file_descriptor)
+    {
+      if (!has(file_descriptor)) {
+
+	FD_SET(file_descriptor, get());
+
+	if (file_descriptor > maximum_file_descriptor) {
+	  maximum_file_descriptor = file_descriptor;
+	}
+
+	++number_of_file_descriptors;
+      }
+    }
+
+
+    /**
+     * Set file.
+     *
+     * \param  file                 file
+     */
+    void set(const JAbstractFile& file)
+    {
+      set(file.getFileDescriptor());
+    }
+
+
+    /**
+     * Reset file descriptor.
+     *
+     * \param  file_descriptor      file descriptor
+     */
+    void reset(const int file_descriptor)
+    {
+      if (has(file_descriptor)) {
+
+	FD_CLR(file_descriptor, get());
+
+	while (!has(maximum_file_descriptor) && maximum_file_descriptor != 0)
+	  --maximum_file_descriptor;
+	
+	--number_of_file_descriptors;
+      }
+    }
+
+
+    /**
+     * Reset file.
+     *
+     * \param  file                 file
+     */
+    void reset(const JAbstractFile& file)
+    {
+      reset(file.getFileDescriptor());
+    }
+
+
+    /**
+     * Has file descriptor.
+     *
+     * \param  file_descriptor      file descriptor
+     * \return                      true if file descriptor set; else false
+     */
+    bool has(const int file_descriptor) const
+    {
+      return FD_ISSET(file_descriptor, get());
+    }
+
+
+    /**
+     * Has file.
+     *
+     * \param  file                 file
+     * \return                      true if file set; else false
+     */
+    bool has(const JAbstractFile& file) const
+    {
+      return has(file.getFileDescriptor());
+    }
+
+
+    /**
+     * Get number of file descriptors.
+     *
+     * \return                      number of file descriptors
+     */
+    int getNumberOfFileDescriptors() const
+    {
+      return maximum_file_descriptor;
+    }
+
+
+    /**
+     * Check setting of file descriptors.
+     *
+     * \return                      true if no file descriptors are set; else false
+     */
+    bool empty() const
+    {
+      return number_of_file_descriptors == 0;
+    }
+
+
+    /**
+     * Check availability of input.
+     * This method returns true is at least one byte can be read without blocking.
+     * Following a select() call, this method overwrites the internal mask!
+     *
+     * \param  timeout      timeout
+     * \return              true if ready to read; else false
+     */
+    bool in_avail(JTimeval timeout = JTimeval::min())
+    {
+      return ::select(getNumberOfFileDescriptors() + 1, get(), NULL, NULL, &timeout) > 0;
+    }
+
+
+    /**
+     * Check availability of output.
+     * This method returns true is at least one byte can be written without blocking.
+     * Following a select() call, this method overwrites the internal mask!
+     *
+     * \param  timeout      timeout
+     * \return              true if ready to write; else false
+     */
+    bool out_avail(JTimeval timeout = JTimeval::min())
+    {
+      return ::select(getNumberOfFileDescriptors() + 1, NULL, get(), NULL, &timeout) > 0;
+    }
+
+
+  private:
+    int maximum_file_descriptor;
+    int number_of_file_descriptors;
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JFileStream.hh b/src/jpp/JLang/JFileStream.hh
new file mode 100644
index 0000000..0845cd2
--- /dev/null
+++ b/src/jpp/JLang/JFileStream.hh
@@ -0,0 +1,89 @@
+#ifndef __JLANG__JFILESTREAM__
+#define __JLANG__JFILESTREAM__
+
+#include <istream>
+#include <ostream>
+
+#include "JLang/JFile.hh"
+#include "JLang/JFileStreamBuffer.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Streaming of input.
+   */
+  class JFileInputStream : 
+    protected JFileInputStreamBuffer,
+    public    std::istream
+  {   
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  file            file
+     * \param  size            size of internal buffer
+     */
+    JFileInputStream(const JAbstractFile& file,
+		     const std::size_t    size = 65536) :
+      JFileInputStreamBuffer(file, size),
+      std::istream(this)
+    {}
+  };  
+
+  
+  /**
+   * Streaming of output.
+   */
+  class JFileOutputStream : 
+    protected JFileOutputStreamBuffer, 
+    public    std::ostream
+  {  
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  file            file
+     * \param  size            size of internal buffer
+     */
+    JFileOutputStream(const JAbstractFile& file,
+		      const std::size_t    size = 65536) :
+      JFileOutputStreamBuffer(file, size),
+      std::ostream(this)
+    {}
+  };  
+
+
+  /**
+   * Streaming of input and output.
+   */
+  class JFileStream : 
+    protected JFileStreamBuffer,
+    public    std::iostream
+  {   
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  in              input  file
+     * \param  out             output file
+     * \param  size            size of internal buffer
+     */
+    JFileStream(const JAbstractFile& in,
+		const JAbstractFile& out,
+		const std::size_t    size = 65536) :
+      JFileStreamBuffer (in, out, size),
+      std::iostream(this)
+    {}
+  };  
+}
+
+#endif
diff --git a/src/jpp/JLang/JFileStreamBuffer.hh b/src/jpp/JLang/JFileStreamBuffer.hh
new file mode 100644
index 0000000..b040b58
--- /dev/null
+++ b/src/jpp/JLang/JFileStreamBuffer.hh
@@ -0,0 +1,258 @@
+#ifndef __JLANG__JFILESTREAMBUFFER__
+#define __JLANG__JFILESTREAMBUFFER__
+
+#include <streambuf>
+#include <stdio.h>
+#include <string.h>
+#include <vector>
+
+#include "JLang/JFile.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Input file stream buffer.
+   */
+  class JFileInputStreamBuffer : 
+    protected virtual std::vector<char>,
+    public    virtual std::streambuf
+  {   
+  public:
+
+
+    typedef traits_type::int_type        int_type;
+    
+
+    /**
+     * Constructor.
+     *
+     * \param  file            file
+     * \param  size            size of internal buffer
+     * \param  put_back        number of put back characters
+     */
+    JFileInputStreamBuffer(const JAbstractFile& file,
+			   const std::size_t    size = 65536,
+			   const std::size_t    put_back = 8) :
+      in    (file),
+      memory(put_back)
+    {
+      resize(size + put_back),
+
+      setg(this->data(), this->data(), this->data());
+    }
+
+    
+    /**
+     * Check underflow.
+     * This method reads as many bytes as possible.
+     *
+     * \return                 first character if OK; else EOF
+     */
+    virtual int_type underflow() override 
+    {   
+      if (gptr() >= egptr()) {
+
+	char* __begin = this->data();
+
+	if (eback() == __begin) { 
+	  
+	  // push put back characters
+
+	  memmove(__begin, egptr() - memory, memory);
+	
+	  __begin += memory;
+	}
+	
+	const size_t len = in.read(__begin, this->size() - (__begin - this->data()));
+	
+	if (len != 0)
+	  setg(this->data(), __begin, __begin + len);
+	else
+	  return traits_type::eof();
+      }
+	
+      return *gptr();
+    } 
+
+
+    /**
+     * Check availability of input.
+     * This method returns true if at least one byte can be read without blocking.
+     *
+     * \param  timeout      timeout
+     * \return              true if ready to read; else false
+     */
+    bool in_avail(JTimeval timeout = JTimeval::min()) const
+    {
+      return JFileDescriptorMask(in).in_avail(timeout);
+    }
+
+  protected:
+    JFile       in;
+    std::size_t memory;
+
+  private:
+    JFileInputStreamBuffer(const JFileInputStreamBuffer&);
+    JFileInputStreamBuffer(JFileInputStreamBuffer&&);
+    JFileInputStreamBuffer& operator=(const JFileInputStreamBuffer&);
+    JFileInputStreamBuffer& operator=(JFileInputStreamBuffer&&);
+  };  
+
+  
+  /**
+   * Output file stream buffer.
+   */
+  class JFileOutputStreamBuffer : 
+    protected virtual std::vector<char>,
+    public    virtual std::streambuf
+  {  
+  public:
+
+
+    typedef traits_type::int_type        int_type;
+    typedef std::streamsize              streamsize;
+
+
+    /**
+     * Constructor.
+     *
+     * \param  file            file
+     * \param  size            size of internal buffer
+     */
+    JFileOutputStreamBuffer(const JAbstractFile& file,
+			    const std::size_t    size = 65536) :
+      out    (file)
+    {
+      // reserve one byte for overflow character
+
+      resize(size);
+
+      setp(this->data(), this->data() + this->size() - 1);
+    }
+
+
+    /**
+     * Destructor.
+     */
+    virtual ~JFileOutputStreamBuffer()
+    {
+      sync();
+    }
+
+
+    /**
+     * Check overflow.
+     * This method writes one byte if possible.
+     *
+     * \param  c               character
+     * \return                 c if OK; else EOF
+     */
+    virtual int_type overflow(int_type c) override 
+    {
+      if (c != traits_type::eof()) {
+
+	*pptr() = (char) c;
+
+	pbump(1);
+
+	if (flush() == traits_type::eof()) {
+	  return traits_type::eof();
+	}
+      }
+
+      return c;
+    }
+
+
+    /**
+     * Synchronise buffer.
+     */
+    virtual int sync() override 
+    {
+      if (flush() == traits_type::eof())
+	return -1;
+      else
+	return  0;
+    }
+
+
+    /**
+     * Check availability of output.
+     * This method returns true if at least one byte can be written without blocking.
+     *
+     * \param  timeout      timeout
+     * \return              true if ready to write; else false
+     */
+    bool out_avail(JTimeval timeout = JTimeval::min()) const
+    {
+      return JFileDescriptorMask(out).out_avail(timeout);
+    }
+
+  protected:
+    /**
+     * Flush internal buffer.
+     */
+    int flush()
+    {
+      const int len = pptr() - pbase();
+      
+      if (len != 0) {
+
+	if (out.write(this->data(), len) != len) {
+	  return traits_type::eof();
+	}
+
+	pbump(-len);
+      }
+
+      return len;
+    }
+
+
+    JFile       out;
+
+  private:
+    JFileOutputStreamBuffer(const JFileOutputStreamBuffer&);
+    JFileOutputStreamBuffer(JFileOutputStreamBuffer&&);
+    JFileOutputStreamBuffer& operator=(const JFileOutputStreamBuffer&);
+    JFileOutputStreamBuffer& operator=(JFileOutputStreamBuffer&&);
+  };  
+
+
+
+  /**
+   * Input and output file stream buffer.
+   */
+  class JFileStreamBuffer : 
+    public JFileInputStreamBuffer,
+    public JFileOutputStreamBuffer
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  in              input  file
+     * \param  out             output file
+     * \param  size            size of internal buffer
+     * \param  put_back        number of put back characters
+     */
+    JFileStreamBuffer(const JAbstractFile& in,
+		      const JAbstractFile& out,
+		      const std::size_t    size = 65536,
+		      const std::size_t    put_back = 8) :
+      JFileInputStreamBuffer (in,  size, put_back),
+      JFileOutputStreamBuffer(out, size)
+    {}
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JLangToolkit.hh b/src/jpp/JLang/JLangToolkit.hh
index a9abcf2..afcecf1 100644
--- a/src/jpp/JLang/JLangToolkit.hh
+++ b/src/jpp/JLang/JLangToolkit.hh
@@ -114,7 +114,7 @@ namespace JLANG {
 
   /**
    * Replace tokens in string.\n
-   * Returns a copy of the string, with all occurences of <tt>target</tt> replaced by <tt>replacement</tt>.
+   * Returns a copy of the string, with all occurrences of <tt>target</tt> replaced by <tt>replacement</tt>.
    *
    * \param  input          input       string
    * \param  target         target      string
@@ -137,7 +137,22 @@ namespace JLANG {
 
   /**
    * Replace characters in string.\n
-   * Returns a copy of the string, with all occurences of <tt>target</tt> replaced by <tt>replacement</tt>.
+   * Returns a copy of the string, with all occurrences of <tt>target</tt> replaced by <tt>replacement</tt>.
+   *
+   * \param  input          input       string
+   * \param  target         target      character
+   * \param  replacement    replacement string
+   * \return                modified    string
+   */
+  inline std::string replace(const std::string& input, const char target, const std::string& replacement)
+  {
+    return replace(input, std::string(1, target), replacement);
+  }
+
+
+  /**
+   * Replace characters in string.\n
+   * Returns a copy of the string, with all occurrences of <tt>target</tt> replaced by <tt>replacement</tt>.
    *
    * \param  input          input       string
    * \param  target         target      character
diff --git a/src/jpp/JLang/JManip.hh b/src/jpp/JLang/JManip.hh
index a4b2193..fed93e3 100644
--- a/src/jpp/JLang/JManip.hh
+++ b/src/jpp/JLang/JManip.hh
@@ -5,6 +5,7 @@
 #include <ostream>
 #include <sstream>
 #include <iomanip>
+#include <functional>
 
 
 /**
@@ -713,4 +714,46 @@ inline void setFormat(const JFormat_t& format)
   getFormat<T>() = format;
 }
 
+
+/**
+ * Auxiliary data structure to convert (lambda) function to printable object.
+ *
+ * The (lambda) function should conform with the type definition LAMBDA::function_type.\n
+ * This data structure acts as a simple "wrapper" and should be used if the lambda has capture functionality.
+ */
+struct LAMBDA {
+  /**
+   * Type definition of print function.
+   */
+  typedef std::function<void(std::ostream&)>  function_type;
+
+
+  /**
+   * Constructor.
+   *
+   * \param  f1         (lambda) function
+   */
+  LAMBDA(const function_type& f1) :
+    f1(f1)
+  {}
+
+
+  /**
+   * Write printable object to output stream.
+   *
+   * \param  out        output stream
+   * \param  object     printable object
+   * \return            output stream
+   */
+  friend inline std::ostream& operator<<(std::ostream& out, const LAMBDA& object)
+  {
+    object.f1(out);
+
+    return out;
+  }
+
+private:
+  const function_type& f1;
+};
+
 #endif
diff --git a/src/jpp/JLang/JObjectIO.hh b/src/jpp/JLang/JObjectIO.hh
index c10939a..1ad1b86 100644
--- a/src/jpp/JLang/JObjectIO.hh
+++ b/src/jpp/JLang/JObjectIO.hh
@@ -1,6 +1,7 @@
 #ifndef __JLANG__JOBJECTIO__
 #define __JLANG__JOBJECTIO__
 
+#include <string>
 #include <fstream>
 
 #include "JLang/JType.hh"
@@ -51,7 +52,7 @@ namespace JLANG {
    * \param  object          object to be read
    */
   template<class JReader_t, class T>
-  inline void load(const char* file_name, T& object)
+  inline void load(const std::string& file_name, T& object)
   {
     load(file_name, object, JType<JReader_t>());
   }
@@ -64,7 +65,7 @@ namespace JLANG {
    * \param  object          object to be written
    */
   template<class JWriter_t, class T>
-  inline void store(const char* file_name, const T& object)
+  inline void store(const std::string& file_name, const T& object)
   {
     store(file_name, object, JType<JWriter_t>());
   }
@@ -88,9 +89,9 @@ namespace JLANG {
    * \param  type            reader type
    */
   template<class JReader_t, class T>
-  inline void load(const char* file_name, T& object, JType<JReader_t> type)
+  inline void load(const std::string& file_name, T& object, JType<JReader_t> type)
   {
-    JReader_t in(file_name);
+    JReader_t in(file_name.c_str());
     
     if (!in) {
       THROW(JFileOpenException, "Error opening file: " << file_name);
@@ -124,9 +125,9 @@ namespace JLANG {
    * \param  type            writer type
    */
   template<class JWriter_t, class T>
-  inline void store(const char* file_name, const T& object, JType<JWriter_t> type)
+  inline void store(const std::string& file_name, const T& object, JType<JWriter_t> type)
   {
-    JWriter_t out(file_name);
+    JWriter_t out(file_name.c_str());
 
     if (!out) {
       THROW(JFileOpenException, "Error opening file: " << file_name);
@@ -136,6 +137,32 @@ namespace JLANG {
 
     out.close();
   }
+
+
+  /**
+   * Load object from input file.
+   *
+   * \param  file_name       file name
+   * \param  object          object to be read
+   */
+  template<class T>
+  inline void load(const std::string& file_name, T& object)
+  {
+    load(file_name, object, JType<std::ifstream>());
+  }
+
+
+  /**
+   * Store object to output file.
+   *
+   * \param  file_name       file name
+   * \param  object          object to be written
+   */
+  template<class T>
+  inline void store(const std::string& file_name, const T& object)
+  {
+    store(file_name, object, JType<std::ofstream>());
+  }
 }
 
 #endif
diff --git a/src/jpp/JLang/JObjectStreamIO.hh b/src/jpp/JLang/JObjectStreamIO.hh
new file mode 100644
index 0000000..335c94f
--- /dev/null
+++ b/src/jpp/JLang/JObjectStreamIO.hh
@@ -0,0 +1,48 @@
+#ifndef __JLANG__JOBJECTSTREAMIO__
+#define __JLANG__JOBJECTSTREAMIO__
+
+#include <fstream>
+
+#include "JLang/JObjectIO.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Auxiliary base class for storing and loading a single object to and from an ASCII file, respectively. 
+   * The implementation of this functionality is based on a static cast of 
+   * the given template parameter (known as "curiously recurring template pattern").
+   */
+  template<class T>
+  struct JObjectStreamIO {
+    /**
+     * Load from input file.
+     *
+     * \param  file_name               file name
+     */
+    void load(const char* file_name)
+    {
+      JLANG::load<std::ifstream>(file_name, static_cast<T&>(*this));
+    }
+
+
+    /**
+     * Store to output file.
+     *
+     * \param  file_name               file name
+     */
+    void store(const char* file_name) const
+    {
+      JLANG::store<std::ofstream>(file_name, static_cast<const T&>(*this));
+    }
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JParameter.hh b/src/jpp/JLang/JParameter.hh
new file mode 100644
index 0000000..c60e63a
--- /dev/null
+++ b/src/jpp/JLang/JParameter.hh
@@ -0,0 +1,197 @@
+#ifndef __JLANG__JPARAMETER__
+#define __JLANG__JPARAMETER__
+
+#include <istream>
+#include <ostream>
+
+#include "JLang/JClass.hh"
+#include "JLang/JComparable.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+  
+  
+  /**
+   * Parameter class.
+   *
+   * This class is a simple wrapper around the template parameter with an additional status value.\n
+   * The status value indicates whether the parameter has been defined or not.\n
+   * A parameter is defined when a value has been assigned or correctly read.\n
+   * Note that the comparison between parameter objects is based on the philosophy "undefined = any value".\n
+   * Hence, if any of the two parameter values is undefined, they are considered equal.\n
+   * The comparison between a parameter object with a template value is based 
+   * on the internal value of the parameter object via implicit type conversion,
+   * regardless of its state.
+   */
+  template<class T>
+  class JParameter :
+    public JComparable< JParameter<T> >
+  {
+  public:
+
+    typedef typename JClass<T>::argument_type  argument_type;
+
+    /**
+     * Default constructor.
+     */
+    JParameter() :
+      __value(),
+      is_defined(false)
+    {}
+
+  
+    /**
+     * Constructor.
+     *
+     * \param  value        value
+     */
+    explicit JParameter(const argument_type& value) :
+      __value(value),
+      is_defined(true)
+    {}
+
+
+    /**
+     * Assignment operator.
+     *
+     * \param  value        value
+     * \return              this parameter
+     */
+    JParameter<T>& operator=(const argument_type& value)
+    {
+      setValue(value);
+
+      return *this;
+    }
+
+
+    /**
+     * Get value of parameter.
+     *
+     * \return              value
+     */
+    const T& getValue() const 
+    { 
+      return __value; 
+    }
+
+
+    /**
+     * Get value of parameter.
+     *
+     * \return              value
+     */
+    T& getValue() 
+    { 
+      return __value; 
+    }
+
+
+    /**
+     * Set value.
+     *
+     * \param  value        value
+     */
+    void setValue(const argument_type& value)
+    {
+      __value    = value;
+      is_defined = true;
+    }
+
+
+    /**
+     * Type conversion operator.
+     *
+     * \return              value
+     */
+    operator const T&() const
+    { 
+      return getValue();
+    }
+
+
+    /**
+     * Type conversion operator.
+     *
+     * \return              value
+     */
+    operator T&()       
+    {
+      return getValue();
+    }
+
+
+    /**
+     * Get status of parameter.
+     *
+     * \return              true if value has been defined (by read or assignment); else false
+     */
+    const bool isDefined() const
+    {
+      return is_defined;
+    }
+
+
+    /**
+     * Less than method.
+     *
+     * This method evaluates to true if both parameter values are defined and
+     * this value is less than the value of the given parameter object.
+     *
+     * \param   parameter   parameter
+     * \return              true if both defined and first value less than second value; else false
+     */
+    inline bool less(const JParameter<T>& parameter) const
+    {
+      return this->isDefined() && parameter.isDefined() && this->getValue() < parameter.getValue();
+    }
+    
+
+    /**
+     * Stream input.
+     *
+     * \param  in           input stream
+     * \param  parameter    parameter
+     * \return              input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JParameter<T>& parameter)
+    {
+      in >> parameter.__value;
+
+      parameter.is_defined = (bool) in;
+
+      return in;
+    }
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out          output stream
+     * \param  parameter    parameter
+     * \return              output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JParameter<T>& parameter)
+    {
+      if (parameter.is_defined) {
+	out << parameter.__value;
+      }
+      
+      return out;
+    }
+
+
+  protected:
+    T    __value;
+    bool is_defined;
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JPrintHelper.hh b/src/jpp/JLang/JPrintHelper.hh
new file mode 100644
index 0000000..def019d
--- /dev/null
+++ b/src/jpp/JLang/JPrintHelper.hh
@@ -0,0 +1,214 @@
+#ifndef __JLANG__JPRINTHELPER__
+#define __JLANG__JPRINTHELPER__
+
+#include <ostream>
+
+#include "JLang/JType.hh"
+#include "JLang/JBool.hh"
+#include "JLang/JTest.hh"
+#include "JLang/JClass.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+  
+  /**
+   * Auxiliary class to print via member method <tt>const char* __str__() const;</tt>.
+   */
+  class JPrintHelper {
+    /**
+     * Print interface.
+     */
+    struct JTypeout {
+      /**
+       * Virtual destructor.
+       */
+      virtual ~JTypeout()
+      {}
+
+      
+      /**
+       * Print object.
+       *
+       * \param  out           output stream
+       * \param  p             pointer to object
+       * \return               output stream
+       */
+      virtual std::ostream& print(std::ostream& out, const void* p) const = 0;
+    };
+
+  
+    /**
+     * Type writer implementation of interface JTypeout based on member method <tt>const char* __str__() const;</tt>
+     */
+    template<class T>
+    struct JTypewriter :
+      public JTypeout
+    {
+      /**
+       * Print object.
+       *
+       * \param  out           output stream
+       * \param  p             pointer to object
+       * \return               output stream
+       */
+      virtual std::ostream& print(std::ostream& out, const void* p) const override 
+      {
+	return out << ((const T*) p)->__str__();;
+      }
+    };
+
+
+    /**
+     * Get type writer.
+     *
+     * \param  type          type
+     * \param  option        true
+     */
+    template<class T>
+    static JTypeout* get(JType<T> type, JBool<true> option)
+    {
+      return new JTypewriter<T>();
+    }
+  
+    const void* p;             //!< pointer to object
+    JTypeout*   typeout;       //!< pointer to printer interface
+  
+
+  public:
+    /**
+     * Test for availability of member method <tt>const char* __str__() const;</tt>.
+     */
+    template<class T, bool is_primitive = JClass<T>::is_primitive>
+    class JMemberMethod :
+      public JTest
+    {
+      using JTest::test;
+  
+      template<class U>
+      static JTrue test(JTypecheck<const char* (U::*)() const, &U::__str__>*);
+  
+    public:
+      static const bool __str__ = JTEST(test<T>(0));
+    };
+    
+
+    /**
+     * Specialisation of JMemberMethod for primitive data types. 
+     */
+    template<class T>
+    struct JMemberMethod<T, true>
+    {
+      static const bool __str__ = false;
+    };
+
+      
+    /**
+     * Constructor
+     *
+     * \param  object        object
+     */
+    template<class T>
+    JPrintHelper(const T& object) :
+      p(&object),
+      typeout(get(JType<T>(), JBool<JMemberMethod<T>::__str__>()))
+    {}
+
+
+    /**
+     * Destructor.
+     */
+    ~JPrintHelper()
+    {
+      delete typeout;
+    }
+
+    
+    /**
+     * Print object.
+     *
+     * \param  out           output stream
+     * \return               output stream
+     */
+    inline std::ostream& print(std::ostream& out) const
+    {
+      return typeout->print(out, p);
+    }
+
+  private:
+    JPrintHelper(const JPrintHelper&);
+    JPrintHelper(JPrintHelper&&);
+    JPrintHelper& operator=(const JPrintHelper&);
+    JPrintHelper& operator=(JPrintHelper&&);
+  };
+
+  
+  /**
+   * Auxiliary class to temporarily replace std::ostream. 
+   */
+  struct JPrinter {
+    /**
+     * Constructor.
+     *
+     * \param  out           output stream
+     */
+    JPrinter(std::ostream& out) :
+      __out(out)
+    {}
+
+
+    /**
+     * Type definition of I/O operator.
+     */
+    typedef std::ostream& (*io_manip) (std::ostream&);
+    
+
+    /**
+     * Parse I/O manipulator.
+     *
+     * \param  manip         I/O manipulator
+     * \return               output stream
+     */
+    inline std::ostream& operator<<(io_manip manip)
+    { 
+      return __out << manip;
+    }
+
+
+    /**
+     * Parse object.
+     *
+     * \param  object        object
+     * \return               output stream
+     */
+    template<class T>
+    inline std::ostream& operator<<(const T& object)
+    {
+      return __out << object;
+    }   
+    
+  private:
+    std::ostream& __out;
+  };
+}
+
+
+/**
+ * Print object via helper.
+ *
+ * \param  out           output stream
+ * \param  object        object
+ * \return               output stream
+ */
+inline JLANG::JPrinter operator<<(std::ostream& out, const JLANG::JPrintHelper& object)
+{
+  return object.print(out);
+}
+
+#endif
diff --git a/src/jpp/JLang/JSTDTypes.hh b/src/jpp/JLang/JSTDTypes.hh
index e29dc2c..9811aaa 100644
--- a/src/jpp/JLang/JSTDTypes.hh
+++ b/src/jpp/JLang/JSTDTypes.hh
@@ -8,30 +8,22 @@
  * \author mdejong
  */
 
-#include <vector>
-#include <set>
-#include <utility>
-#include <map>
-#include <list>
-#include <iterator>
-
-// TODO: this gives an ambigous error on macOS with std::pair
-// namespace std {
-//   template<class JElement_t, class JAllocator_t>                                    class vector;
-//   template<class JElement_t, class JComparator_t, class JAllocator_t>               class set;
-//   template<class JElement_t, class JComparator_t, class JAllocator_t>               class multiset;
-//   template<class JFirst_t, class JSecond_t>                                         struct pair;
-//   template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>   class map;
-//   template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>   class multimap;
-//   template<class Category, class T, class Distance, class Pointer, class Reference> struct iterator;
-// #ifdef _GLIBCXX_USE_CXX11_ABI
-//   inline namespace __cxx11 {
-//     template<class JElement_t, class JAllocator_t>                                  class list;
-//   }
-// #else
-//   template<class JElement_t, class JAllocator_t>                                    class list;
-// #endif
-// }
+namespace std {
+  template<class JElement_t, class JAllocator_t>                                    class vector;
+  template<class JElement_t, class JComparator_t, class JAllocator_t>               class set;
+  template<class JElement_t, class JComparator_t, class JAllocator_t>               class multiset;
+  template<class JFirst_t, class JSecond_t>                                         class pair;
+  template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>   class map;
+  template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>   class multimap;
+  template<class Category, class T, class Distance, class Pointer, class Reference> struct iterator;
+#ifdef _GLIBCXX_USE_CXX11_ABI
+  inline namespace __cxx11 {
+    template<class JElement_t, class JAllocator_t>                                  class list;
+  }
+#else
+  template<class JElement_t, class JAllocator_t>                                    class list;
+#endif 
+}
 
 #endif
 
diff --git a/src/jpp/JLang/JStreamAvailable.hh b/src/jpp/JLang/JStreamAvailable.hh
new file mode 100644
index 0000000..0ac9aa3
--- /dev/null
+++ b/src/jpp/JLang/JStreamAvailable.hh
@@ -0,0 +1,173 @@
+#ifndef __JLANG__JSTREAMAVAILABLE__
+#define __JLANG__JSTREAMAVAILABLE__
+
+#include <istream>
+#include <ostream>
+
+#include "JLang/JAnyType.hh"
+#include "JLang/JNullType.hh"
+#include "JLang/JTest.hh"
+#include "JLang/JBool.hh"
+#include "JLang/JPrintHelper.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+/**
+ * Fallback implementation for <tt>std::istream& operator>>(std::istream, T&)</tt> 
+ * for types that don't support the stream operator.
+ *
+ * \param  in          input stream
+ * \param  any_type    any  type
+ * \return             null type
+ */
+JLANG::JNullType operator>>(std::istream& in, JLANG::JAnyType any_type);
+  
+  
+/**
+ * \cond NEVER
+ * Fallback implementation for <tt>std::ostream& operator<<(std::ostream, const T&)</tt>
+ * for types that don't support the stream operator.
+ *
+ * \param  out         output stream
+ * \param  any_type    any  type
+ * \return             null type
+ * \endcond
+ */
+//JLANG::JNullType operator<<(std::ostream& out, JLANG::JAnyType any_type);
+
+
+/**
+ * Test availability of stream operators.
+ */
+template<class T, bool __str__ = JLANG::JPrintHelper::JMemberMethod<T>::__str__>
+class JStreamAvailable :
+  public JLANG::JTest
+{
+  using JLANG::JTest::test;
+  
+  static JTrue test(std::istream&);
+  static JTrue test(std::ostream&);
+    
+  static T& getReference();
+
+  static std::istream& is();
+  static std::ostream& os();
+    
+public:
+  static const bool has_istream = JTEST(test(is() >> getReference()));  //!< true if <tt>std::istream& operator>>(std::istream&, T&)</tt> is defined; else false
+  static const bool has_ostream = JTEST(test(os() << getReference()));  //!< true if <tt>std::ostream& operator<<(std::ostream&, const T&)</tt> is defined; else false
+};
+
+
+/**
+ * Specialisation of JStreamAvailable for class without member method <tt>__str__</tt>.
+ */
+template<class T>
+class JStreamAvailable<T, true> :
+  public JLANG::JTest
+{
+public:
+  static const bool has_istream = JStreamAvailable<T, false>::has_istream;
+  static const bool has_ostream = true;
+};
+
+
+/**
+ * Auxiliary data structure for handling std::ostream.
+ */
+struct STREAM {
+protected:
+  /**
+   * Auxiliary class for format stream.
+   */
+  struct JStream
+  {
+    /**
+     * Constructor.
+     *
+     * \param  out         output stream
+     * \param  message     message printed in case operator std::ostream<< is unavailable
+     */
+    JStream(std::ostream& out, const std::string& message) :
+      out    (out),
+      message(message)
+    {}
+
+
+    /**
+     * Write value to output stream.
+     *
+     * \param  value       value
+     * \return             this JStream
+     */
+    template<class T>
+    std::ostream& operator<<(const T& value)
+    {
+      using namespace JPP;
+
+      return print(out, value, JBool<JStreamAvailable<T>::has_ostream>());
+    }
+
+  private:
+    /**
+     * Print value if given option is true.
+     *
+     * \param  out         output stream
+     * \param  value       value
+     * \param  option      true
+     * \return             output stream
+     */
+    template<class T>
+    std::ostream& print(std::ostream& out, const T& value, const JLANG::JBool<true>& option)
+    {
+      return out << value;
+    }
+
+    /**
+     * Print value if given option is true.
+     *
+     * \param  out         output stream
+     * \param  value       value
+     * \param  option      false
+     * \return             output stream
+     */
+    template<class T>
+    std::ostream& print(std::ostream& out, const T& value, const JLANG::JBool<false>& option)
+    {
+      return out << message;
+    }
+
+    std::ostream& out; 
+    std::string   message;
+  };
+
+  std::string message;
+
+public:
+  /**
+   * Constructor.
+   *
+   * \param  message     message printed in case operator std::ostream<< is unavailable
+   */
+  STREAM(const std::string& message = "") :
+    message(message)
+  {}
+
+
+  /**
+   * Format specifier.
+   *
+   * \param  out           output stream
+   * \param  format        format
+   * \return               output stream
+   */
+  friend inline JStream operator<<(std::ostream& out, const STREAM& format)
+  {
+    return JStream(out, format.message);
+  }
+};
+
+#endif
diff --git a/src/jpp/JLang/JStreamState.hh b/src/jpp/JLang/JStreamState.hh
new file mode 100644
index 0000000..c3f2206
--- /dev/null
+++ b/src/jpp/JLang/JStreamState.hh
@@ -0,0 +1,77 @@
+#ifndef __JLANG__JSTREAMSTATE__
+#define __JLANG__JSTREAMSTATE__
+
+#include <istream>
+#include <ostream>
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * This class can be used to temporarily exchange the states between streams.
+   * The constructor transfers the state from the first stream to the second stream and
+   * the destructor transfers back the state from the second stream to the first stream.
+   */
+  class JStreamState {
+  public:
+    /**
+     * Constructor.
+     * The stream state of <tt>from</tt> is transfered to stream state of <tt>to</tt>.
+     *
+     * \param  from            output stream
+     * \param  to              output stream
+     */
+    JStreamState(std::ostream& from,
+		 std::ostream& to) :
+      __from(from),
+      __to  (to)
+    {
+      __to.setstate(__from.rdstate());
+    }
+
+
+    /**
+     * Constructor.
+     * The stream state of <tt>from</tt> is transfered to stream state of <tt>to</tt>.
+     *
+     * \param  from            input stream
+     * \param  to              input stream
+     */
+    JStreamState(std::istream& from,
+		 std::istream& to) :
+      __from(from),
+      __to  (to)
+    {
+      __to.setstate(__from.rdstate());
+    }
+
+    
+    /**
+     * Destructor.
+     * The stream state is transfered back.
+     */
+    ~JStreamState()
+    {
+      __from.setstate(__to.rdstate());
+    }
+
+  private:
+    std::ios& __from;
+    std::ios& __to;
+
+    JStreamState(const JStreamState&);
+    JStreamState(JStreamState&&);
+    JStreamState& operator=(const JStreamState&);
+    JStreamState& operator=(JStreamState&&);
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JString.hh b/src/jpp/JLang/JString.hh
new file mode 100644
index 0000000..7c10c99
--- /dev/null
+++ b/src/jpp/JLang/JString.hh
@@ -0,0 +1,502 @@
+#ifndef __JLANG__JSTRING__
+#define __JLANG__JSTRING__
+
+#include <string>
+#include <sstream>
+#include <limits>
+#include <ctype.h>
+#include <stdio.h>
+
+#include "JLang/JStringFacet.hh"
+#include "JLang/JException.hh"
+#include "JLang/JLangToolkit.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Wrapper class around STL string class.
+   */
+  class JString :
+    public std::string
+  {
+  public:
+
+    using std::string::replace;
+    using std::string::assign;
+
+
+    /**
+     * Default constructor.
+     */
+    JString() :
+      std::string()
+    {}
+   
+    
+    /**
+     * Constructor.
+     *
+     * \param  buffer         string
+     */
+    explicit JString(const std::string& buffer) :
+      std::string(buffer)
+    {}
+     
+    
+    /**
+     * Constructor.
+     *
+     * \param  c              char
+     */
+    explicit JString(const char c):
+      std::string(1,c)
+    {}
+
+    
+    /**
+     * Constructor.
+     *
+     * \param  buffer         string
+     * \param  length         length
+     */
+    explicit JString(const char* buffer, const std::string::size_type length) :
+      std::string(buffer, length)
+    {}
+    
+    
+    /**
+     * Constructor.
+     *
+     * \param  value          value
+     */
+    template<class T>
+    JString(const T& value) :
+      std::string(valueOf(value))
+    {}
+
+
+    /**
+     * Constructor.\n
+     * Each '%' in the format string will be replaced by the corresponding argument.
+     *
+     * \param  format           format
+     * \param  args             values
+     */
+    template<class ...Args>
+    JString(const char* format, const Args& ...args) :
+      std::string(format)
+    {
+      __set__(args...);
+    }
+
+
+    /**
+     * Constructor.\n
+     * This constructor compiles (see below) the input string.
+     *
+     * \param  buffer         input string
+     * \param  facet          facet
+     */
+    JString(const JString& buffer, const JStringFacet& facet) :
+      std::string(buffer)
+    {
+      compile(facet);
+    }
+ 
+
+    /**
+     * Compile token with given facet.\n
+     * This method uses the given facet to parse the input string.
+     * The result is then compatible with the definition of a token and may be empty.
+     *
+     * \param  facet          facet
+     * \result                this string
+     */
+    JString& compile(const JStringFacet& facet)
+    {
+      using namespace std;
+
+      istringstream is(*this);
+
+      ios_base::iostate state;
+
+      facet.get(is, istreambuf_iterator<char>(), is, state, *this);
+
+      return *this;
+    }
+
+
+
+    /**
+     * Test if this string starts with the specified prefix.
+     *
+     * \param  prefix         prefix
+     * \return                true if this string starts with prefix; else false
+     */
+    bool startsWith(const std::string& prefix) const
+    {						
+      return this->size() >= prefix.size() && this->substr(0, prefix.size()) == prefix;
+    }
+
+
+    /**
+     * Test if this string ends with the specified suffix.
+     *
+     * \param  suffix         suffix
+     * \return                true if this string ends with suffix; else false
+     */
+    bool endsWith(const std::string& suffix) const
+    {						
+      return this->size() >= suffix.size() && this->substr(this->size() - suffix.size()) == suffix;
+    }
+    
+
+    /**
+     * Replace characters.
+     *
+     * \param  target         target character
+     * \param  replacement    replacement character
+     * \param  max            maximum number of replacements
+     * \return                this string
+     */
+    JString& replace(const char         target,
+		     const char         replacement,
+		     const std::size_t  max = std::numeric_limits<std::size_t>::max())
+    {
+      for (std::size_t i = this->find(target), n = max; i != std::string::npos && n != 0; i = find(target,i), --n) {
+	(*this)[i] = replacement;
+      }
+      
+      return *this;
+    }
+
+    
+    /**
+     * Replace character sequences.
+     *
+     * \param  target         target string
+     * \param  replacement    replacement string
+     * \param  max            maximum number of replacements
+     * \return                this string
+     */
+    JString& replace(const std::string& target,
+		     const std::string& replacement,
+		     const std::size_t  max = std::numeric_limits<std::size_t>::max())
+    {
+      for (std::size_t i = this->find(target), n = max; i != std::string::npos && n != 0; i = this->find(target,i), --n) {
+	replace(this->begin() + i, this->begin() + i + target.length(), replacement);
+      }
+      
+      return *this;
+    }
+
+    
+    /**
+     * Replace character sequence.
+     *
+     * \param  target         target string
+     * \param  value          value
+     * \param  max            maximum number of replacements
+     * \return                this string
+     */
+    template<class T>
+    JString& replace(const std::string& target,
+		     const T&           value,
+		     const std::size_t  max = std::numeric_limits<std::size_t>::max())
+    {
+      for (std::size_t i = this->find(target), n = max; i != std::string::npos && n != 0; i = this->find(target,i), --n) {
+	replace(this->begin() + i, this->begin() + i + target.length(), JString(value));
+      }
+      
+      return *this;
+    }
+
+    
+    /**
+     * Trim string.\n
+     * Returns the modified string, with leading and trailing white spaces omitted.
+     *
+     * \return                this string
+     */
+    JString& trim()
+    {
+      *this = JLANG::trim(*this);
+ 
+      return *this;
+    }
+
+    
+    /**
+     * Trim string.\n
+     * Returns the modified string, with leading and trailing target characters omitted.
+     *
+     * \param  c              strip character
+     * \return                this string
+     */
+    JString& trim(const char c)
+    {
+      *this = JLANG::trim(*this, c);
+
+      return *this;
+    }
+
+    
+    /**
+     * Trim string.\n
+     * Returns the modified string, with leading and trailing target characters omitted.
+     *
+     * \param  target         character(s) to strip
+     * \return                this string
+     */
+    JString trim(const std::string& target)
+    {
+      *this = JLANG::trim(*this, target);
+
+      return *this;
+    }
+
+    
+    /**
+     * Convert all character to upper case.
+     *
+     * \return                this string
+     */
+    JString& toUpper()
+    {
+      for (iterator i = begin(); i != end(); ++i) {
+	*i = toupper(*i);
+      }
+
+      return *this;
+    }
+
+    
+    /**
+     * Convert all character to lower case.
+     *
+     * \return                this string
+     */
+    JString& toLower()
+    {
+      for (iterator i = begin(); i != end(); ++i) {
+	*i = tolower(*i);
+      }
+
+      return *this;
+    }
+
+    
+    /**
+     * Convert enumeration type to string.
+     *
+     * \param  input          value
+     * \return                string
+     */
+    static JString valueOf(const int input)
+    {
+      std::ostringstream os;
+
+      if (os << input)
+	return JString(os.str());
+      else
+	throw JException("JString::valueOf()");
+    }
+
+    
+    /**
+     * Convert value to string.
+     *
+     * \param  input          value
+     * \return                string
+     */
+    template<class T>
+    static JString valueOf(const T& input)
+    {
+      std::ostringstream os;
+
+      if (os << input)
+	return JString(os.str());
+      else
+	throw JException("JString::valueOf()");
+    }
+
+
+    /**
+     * Convert string to value.
+     *
+     * \param  input          string
+     * \return                value
+     */
+    template<class T>
+    static const T& toValue(const JString& input)
+    {
+      static T value;
+
+      std::istringstream is(input);
+
+      if (is >> value)
+	return value;
+      else
+	throw JException("JString::toValue<T>()");
+    }
+
+    
+    /**
+     * Assign (part of) string to value.
+     *
+     * \param  output         value
+     * \return                remaining string
+     */
+    template<class T>
+    JString& assign(T& output)
+    {
+      using namespace std;
+
+      istringstream is(*this);
+
+      is >> output;
+
+      if (!is) {
+	throw JException("JString::assign()");
+      }
+
+      this->assign(istreambuf_iterator<char>(is),
+		   istreambuf_iterator<char>());
+
+      return *this;
+    }
+ 
+
+    /**
+     * Read string from input stream.
+     *
+     * \param  in             input stream
+     * \param  object         string
+     * \return                input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JString& object)
+    {
+      using namespace std;
+
+      istream::sentry sentry(in);   // skips white spaces
+
+      if (sentry) {
+
+        const locale& loc = in.getloc();
+
+        if (has_facet<JStringFacet>(loc)) {
+
+          ios_base::iostate state;
+
+          use_facet<JStringFacet>(loc).get(in, istreambuf_iterator<char>(), in, state, object);
+
+          if (state != ios_base::goodbit && state != ios_base::eofbit) {
+	    in.setstate(state);
+	  }
+
+        } else {
+
+          in >> static_cast<string&>(object);
+	}
+      }
+
+      return in;
+    }
+
+
+    /**
+     * Write string to output stream.
+     *
+     * \param  out            output stream
+     * \param  object         string
+     * \return                output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JString& object)
+    {
+      using namespace std;
+
+      const locale& loc = out.getloc();
+
+      if (has_facet<JStringFacet>(loc)) {
+
+        use_facet<JStringFacet>(loc).put(out, out, out.fill(), object);
+
+      } else {
+
+        out << static_cast<const string&>(object);
+      }
+
+      return out;
+    }
+
+  private:
+    /**
+     * Recursive method for formatting string.
+     *
+     * \param  value            next value
+     * \param  args             remaining values
+     */
+    template<class T, class ...Args>
+    void __set__(const T& value, const Args& ...args)
+    {
+      using namespace std;
+
+      const size_t pos = this->find('%');
+
+      if (pos != string::npos) {
+
+	replace(pos, 1, JString::valueOf(value));
+
+	__set__(args...);
+      }
+    }
+
+
+    /**
+     * Termination method for formatting string.
+     */
+    void __set__() const
+    {}
+  };
+
+
+  /**
+   * Read string from input stream until end of line.
+   *
+   * \param  in             input stream
+   * \param  object         string
+   * \return                input stream
+   */
+  inline std::istream& getline(std::istream& in, JString& object)
+  {
+    using namespace std;
+    
+    istream::sentry sentry(in, true);   // do not skip white spaces
+    
+    if (sentry) {
+      
+      const locale& loc = in.getloc();
+      
+      if (has_facet<JStringFacet>(loc))	{
+
+	use_facet<JStringFacet>(loc).getline(in, object);
+
+      } else {
+
+	getline(in, static_cast<string&>(object));
+      }
+    }
+
+    return in;
+  }
+}
+
+#endif
diff --git a/src/jpp/JLang/JStringFacet.hh b/src/jpp/JLang/JStringFacet.hh
new file mode 100644
index 0000000..27a8cfa
--- /dev/null
+++ b/src/jpp/JLang/JStringFacet.hh
@@ -0,0 +1,313 @@
+#ifndef __JLANG__JSTRINGFACET__
+#define __JLANG__JSTRINGFACET__
+
+#include <istream>
+#include <ostream>
+#include <locale>
+#include <string>
+#include <iterator>
+#include <limits>
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Facet class to specify parsing of a JLANG::JString object.
+   * This class extends the std::locale::facet class.
+   */
+  class JStringFacet : 
+    public std::locale::facet
+  {
+  public:
+
+    static std::locale::id  id;
+
+
+    typedef std::istreambuf_iterator<char, std::char_traits<char> >    istreambuf_iterator;
+    typedef std::ostreambuf_iterator<char, std::char_traits<char> >    ostreambuf_iterator;
+
+
+  
+    /**
+     * Constructor.
+     *
+     * \param  refs      reference count
+     */
+    JStringFacet(std::size_t refs = 0) :
+      std::locale::facet(refs)
+    {}
+
+
+    /**
+     * Clone this facet.
+     *
+     * \return           pointer to newly created facet
+     */
+    virtual JStringFacet* clone() const
+    {
+      return new JStringFacet();
+    }
+
+
+    /**
+     * Get string.
+     *
+     * \param  __begin   begin position of input stream
+     * \param  __end     end   position of input stream
+     * \param  format    format
+     * \param  result    status after input operation
+     * \param  buffer    output string
+     * \return           position of input stream
+     */
+    istreambuf_iterator get(const istreambuf_iterator __begin,
+			    const istreambuf_iterator __end,
+			    const std::ios_base&      format,
+			    std::ios_base::iostate&   result,
+			    std::string&              buffer) const
+    {
+      return do_get(__begin, __end, format, result, buffer);
+    }
+
+
+    /**
+     * Put string.
+     *
+     * \param  out       begin position of output stream
+     * \param  format    format
+     * \param  c         fill character
+     * \param  buffer    input string
+     * \return           position of output stream buffer
+     */
+    ostreambuf_iterator put(ostreambuf_iterator  out,
+			    const std::ios_base& format,
+			    const char           c,
+			    const std::string&   buffer) const
+    {
+      return do_put(out, format, c, buffer);
+    }
+
+
+    /**
+     * Ignore characters until next end of line.
+     *
+     * \param  in        input stream
+     * \return           input stream
+     */
+    inline std::istream& ignore(std::istream& in) const
+    {      
+      if (do_ignore(in, istreambuf_iterator()) == istreambuf_iterator()) {
+	in.setstate(std::ios_base::eofbit);
+      }
+
+      return in;
+    }
+
+
+    /**
+     * Read characters until next end of line.
+     *
+     * \param  in        input stream
+     * \param  buffer    output string
+     * \return           input stream
+     */
+    inline std::istream& getline(std::istream& in, 
+				 std::string&  buffer) const
+    {
+      using namespace std;
+
+      ios_base::iostate state = in.rdstate();
+
+      if (do_getline(in, istreambuf_iterator(), state, buffer) == istreambuf_iterator()) {
+	in.setstate(std::ios_base::eofbit);
+      }
+
+      if (state != ios_base::goodbit && state != ios_base::eofbit) {
+	in.setstate(state);
+      }
+
+      return in;
+    }
+
+
+    /**
+     * Get index for stream associated facet data.
+     *
+     * \return           index
+     */
+    static int getIndex() 
+    {
+      static int i = std::ios_base::xalloc();
+
+      return i;
+    }
+
+
+  protected:
+    /**
+     * Get string.
+     *
+     * \param  __begin   begin position of input stream
+     * \param  __end     end   position of input stream
+     * \param  format    format
+     * \param  result    status after input operation
+     * \param  buffer    output string
+     * \return           position of input stream
+     */
+    virtual istreambuf_iterator do_get(const istreambuf_iterator __begin,
+				       const istreambuf_iterator __end,
+				       const std::ios_base&      format,
+				       std::ios_base::iostate&   result,
+				       std::string&              buffer) const
+    {
+      using namespace std;
+
+      result = (ios_base::iostate) 0;  // reset I/O status
+
+      streamsize n = format.width();   // number of characters to read
+
+      if (n == 0) {
+	n = numeric_limits<streamsize>::max();
+      }
+
+      istreambuf_iterator i = __begin;
+
+      if (i == __end) {
+
+	result |= ios_base::failbit;	
+	result |= ios_base::eofbit;
+
+      } else {
+
+	buffer.clear();
+
+	buffer.push_back(*i);
+	  
+	for (++i, --n; i != __end && n != 0; ++i, --n) {
+	  buffer.push_back(*i);
+	}
+
+	if (i == __end) {
+	  result |= ios_base::eofbit;
+	}
+      }
+
+      return i;
+    }
+
+
+    /**
+     * Put string.
+     *
+     * \param  out       begin position of output stream
+     * \param  format    format
+     * \param  c         fill character
+     * \param  buffer    input string
+     * \return           current position of output stream
+     */
+    virtual ostreambuf_iterator do_put(ostreambuf_iterator  out,
+				       const std::ios_base& format,
+				       const char           c,
+				       const std::string&   buffer) const
+    {
+      using namespace std;
+
+      if (format.flags() & ios_base::right) {
+	for (streamsize i = buffer.size(); i < format.width(); ++i, ++out) {
+	  *out = c;
+	}
+      }
+
+      for (string::const_iterator i = buffer.begin(); i != buffer.end(); ++i, ++out) {
+	*out = *i;
+      }
+	
+      if (format.flags() & ios_base::left) {
+	for (streamsize i = buffer.size(); i < format.width(); ++i, ++out) {
+	  *out = c;
+	}
+      }
+
+      return out;
+    }
+
+
+    /**
+     * Ignore characters until next end of line.
+     *
+     * \param  __begin   begin position of input stream
+     * \param  __end     end   position of input stream
+     * \return           position of input stream
+     */
+    virtual istreambuf_iterator do_ignore(const istreambuf_iterator __begin,
+					  const istreambuf_iterator __end) const
+    {
+      istreambuf_iterator i = __begin;
+
+      while (i != __end && *i != '\n') {
+	++i;
+      }
+
+      while (i != __end && *i == '\n') {
+	++i;          // skip end of line(s)
+      }
+
+      return i;
+    }
+
+
+    /**
+     * Read string.
+     *
+     * \param  __begin   begin position of input stream
+     * \param  __end     end   position of input stream
+     * \param  result    status after input operation
+     * \param  buffer    output string
+     * \return           position of input stream
+     */
+    virtual istreambuf_iterator do_getline(const istreambuf_iterator __begin,
+					   const istreambuf_iterator __end,
+					   std::ios_base::iostate&   result,
+					   std::string&              buffer) const
+    {
+      using namespace std;
+
+      istreambuf_iterator i = __begin;
+
+      if (i == __end) {
+
+	result |= ios_base::failbit;	
+	result |= ios_base::eofbit;
+
+      } else {
+
+	buffer.clear();
+
+	for ( ; i != __end && *i != '\n'; ++i) {
+	  buffer.push_back(*i);
+	}
+
+	if (i != __end) {
+	  ++i;          // skip end of line
+	}
+      }
+
+      return i;
+    }
+
+
+  private:
+
+    JStringFacet(const JStringFacet&);        // not defined
+    void operator=(const JStringFacet&);      // not defined
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JStringStream.hh b/src/jpp/JLang/JStringStream.hh
new file mode 100644
index 0000000..724438c
--- /dev/null
+++ b/src/jpp/JLang/JStringStream.hh
@@ -0,0 +1,72 @@
+#ifndef __JLANG__JSTRINGSTREAM__
+#define __JLANG__JSTRINGSTREAM__
+
+#include <sstream>
+#include <fstream>
+
+#include "JLang/JStreamState.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Wrapper class around STL stringstream class to facilitate optional loading of data from file.
+   */
+  class JStringStream :
+    public std::stringstream,
+    public JStreamState
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * This constructor loads all data from given input stream.
+     *
+     * \param  in       input stream
+     */
+    JStringStream(std::istream& in) :
+      std::stringstream(),
+      JStreamState(in, static_cast<std::istream&>(*this))
+    {
+      using namespace std;
+
+      istream::sentry sentry(in);   // skips white spaces
+
+      if (sentry) {
+	(*this) << in.rdbuf();
+      }
+    }
+
+    
+    /**
+     * Load data from file with name corresponding to current contents.
+     *
+     * Note that if the file exists but is empty,
+     * the state of the stream is set to fail by C++ standard.
+     */
+    void load()
+    {
+      using namespace std;
+      
+      ifstream in(this->str().c_str());
+
+      if (in) {
+
+	this->str("");                     // reset
+
+	(*this) << in.rdbuf();             // copy
+
+	in.close();
+      }
+    }
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JTest.hh b/src/jpp/JLang/JTest.hh
new file mode 100644
index 0000000..52b95fa
--- /dev/null
+++ b/src/jpp/JLang/JTest.hh
@@ -0,0 +1,49 @@
+#ifndef __JLANG__JTEST__
+#define __JLANG__JTEST__
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Auxiliary base class for compile time evaluation of test.
+   *
+   * The derived class should implement the static method JTest::test,
+   * returning JTest::JTrue.
+   * The macro JTest::JTEST will then return true if the given test is successful.
+   */
+  struct JTest {
+  protected:
+    
+    struct JTrue  { char buffer; };  //!< definition of true
+    struct JFalse { int  buffer; };  //!< definition of false
+
+    static JFalse test(...);         //!< default false
+    
+    template<class __T__>
+    static JFalse test(...);         //!< default false
+
+    
+    /**
+     * Auxiliary class for type checking.
+     */
+    template<class U, U> struct JTypecheck;
+
+    
+    /**
+     * Test macro.
+     *
+     * \param  __A__        test
+     * \return              true if test successful; else false
+     */
+#define JTEST(__A__) (sizeof(__A__) == sizeof(JTrue))
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JTimeval.hh b/src/jpp/JLang/JTimeval.hh
new file mode 100644
index 0000000..3560c92
--- /dev/null
+++ b/src/jpp/JLang/JTimeval.hh
@@ -0,0 +1,209 @@
+#ifndef __JLANG__JTIMEVAL__
+#define __JLANG__JTIMEVAL__
+
+#include <sys/time.h>
+#include <istream>
+#include <ostream>
+#include <limits>
+
+#include "JLang/JComparable.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Auxiliary class for time values.
+   * This class encapsulates the <tt>timeval</tt> data structure.
+   */
+  class JTimeval :
+    public timeval,
+    public JComparable<JTimeval>
+  {
+  public:
+    /**
+     * Default constructor.
+     */
+    JTimeval()
+    {
+      this->tv_sec  = 0;
+      this->tv_usec = 0;
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  tv_us                time [us]
+     */
+    JTimeval(const int tv_us)
+    {
+      this->tv_sec  = 0;
+      this->tv_usec = tv_us;
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  tv_s                 time [s]
+     * \param  tv_us                time [us]
+     */
+    JTimeval(const int tv_s, const int tv_us)
+    {
+      this->tv_sec  = tv_s;
+      this->tv_usec = tv_us;
+    }
+
+
+    /**
+     * Get time value.
+     *
+     * \return                     time value
+     */
+    const JTimeval& getTimeval() const
+    {
+      return static_cast<const JTimeval&>(*this);
+    }
+
+
+    /**
+     * Get time value.
+     *
+     * \return                     time value
+     */
+    JTimeval& getTimeval()
+    {
+      return static_cast<JTimeval&>(*this);
+    }
+
+
+    /**
+     * Set time value.
+     *
+     * \param  timeval             time value
+     */
+    void setTimeval(const JTimeval& timeval)
+    {
+      static_cast<JTimeval&>(*this) = timeval;
+    }
+
+
+    /**
+     * Less than method.
+     *
+     * \param  value                time value
+     * \result                      true if this time value less than given time value; else false
+     */
+    inline bool less(const JTimeval& value) const
+    {
+      if (this->tv_sec == value.tv_sec)
+	return this->tv_usec < value.tv_usec;
+      else
+	return this->tv_sec  < value.tv_sec;
+    }
+
+
+    /**
+     * Get minimal time value.
+     *
+     * \return                      time value
+     */
+    static JTimeval min()
+    {
+      return JTimeval(0, 0);
+    }
+
+
+
+    /**
+     * Get maximal time value.
+     *
+     * \return                      time value
+     */
+    static JTimeval max()
+    {
+      return JTimeval(std::numeric_limits<int>::max(), std::numeric_limits<int>::max());
+    }
+
+
+
+    /**
+     * Get pointer to time value.
+     *
+     * \return                      pointer to time value
+     */
+    const timeval* get() const
+    {
+      return static_cast<const timeval*>(this);
+    }
+
+
+    /**
+     * Get pointer to time value.
+     *
+     * \return                      pointer to time value
+     */
+    timeval* get()
+    {
+      return static_cast<timeval*>(this);
+    }
+
+
+    /**
+     * Address of operator.
+     *
+     * \return                      pointer to time value
+     */
+    const timeval* operator &() const
+    {
+      return get();
+    }
+
+
+    /**
+     * Address of operator.
+     *
+     * \return                      pointer to time value
+     */
+    timeval* operator &()
+    {
+      return get();
+    }
+
+
+    /**
+     * Read time value from input.
+     *
+     * \param  in         input stream
+     * \param  time       time value
+     * \return            input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JTimeval& time)
+    {
+      return in >> time.tv_sec >> time.tv_usec;
+    }
+
+
+    /**
+     * Write time value to output.
+     *
+     * \param  out        output stream
+     * \param  time       time value
+     * \return            output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JTimeval& time)
+    {
+      return out << time.tv_sec << ' ' << time.tv_usec;
+    }
+  };
+}
+
+#endif
diff --git a/src/jpp/JLang/JTypeList.hh b/src/jpp/JLang/JTypeList.hh
new file mode 100644
index 0000000..71b74ce
--- /dev/null
+++ b/src/jpp/JLang/JTypeList.hh
@@ -0,0 +1,460 @@
+#ifndef __JLANG__JTYPELIST__
+#define __JLANG__JTYPELIST__
+
+#include "JLang/JNullType.hh"
+#include "JLang/JType.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Type list.
+   */
+  template<class JHead_t = JNullType, class JTail_t = JNullType>
+  struct JTypeList 
+  {
+    typedef JHead_t                  head_type;
+    typedef JTail_t                  tail_type;
+  };
+
+  
+  /**
+   * List of identical types.
+   */
+  template<unsigned int N, class T>
+  struct JMultipleType 
+  {
+    typedef JTypeList<T, typename JMultipleType<N-1, T>::typelist>       typelist;
+  };
+
+
+  /**
+   * Terminator class of list of identical types.
+   */
+  template<class T>
+  struct JMultipleType<1, T>
+  {
+    typedef JTypeList<T, JNullType>                                      typelist;
+  };
+
+
+  /**
+   * Append to type list.
+   *
+   * Source code is taken from reference:
+   * A. Alexandrescu, Modern C++ Design, Addison Wesley.
+   */
+  
+
+  /**
+   * Template specialisation of append to type list.
+   */
+  template<class JHead_t, class JTail_t>
+  struct JAppend
+  {
+    typedef JTypeList<JHead_t, JTail_t>                                  typelist;
+  };
+  
+
+  /**
+   * Template specialisation of append to type list.
+   */
+  template<>
+  struct JAppend<JNullType, JNullType>
+  {
+    typedef JTypeList<>                                                  typelist;
+  };
+  
+
+  /**
+   * Template specialisation of append to type list.
+   */
+  template<class T>
+  struct JAppend<JNullType, T>
+  {
+    typedef JTypeList<T>                                                 typelist;
+  };
+  
+
+  /**
+   * Template specialisation of append to type list.
+   */
+  template<class JHead_t, class JTail_t>
+  struct JAppend<JNullType, JTypeList<JHead_t, JTail_t> >
+  {
+    typedef JTypeList<JHead_t, JTail_t>                                  typelist;
+  };
+  
+
+  /**
+   * Template specialisation of append to type list.
+   */
+  template<class JHead_t, class JTail_t, class T>
+  struct JAppend<JTypeList<JHead_t, JTail_t>, T>
+  {
+    typedef JTypeList<JHead_t, typename JAppend<JTail_t, T>::typelist>   typelist;
+  };
+
+
+  /**
+   * Removal of data type from type list.
+   *
+   * Source code is taken from reference:
+   * A. Alexandrescu, Modern C++ Design, Addison Wesley.
+   */
+  template<class JTypelist_t, class T>
+  struct JRemove; 
+  
+
+  /**
+   * Template specialisation of removal of data type from type list.
+   */
+  template<class T>
+  struct JRemove<JNullType, T>
+  {
+    typedef JTypeList<>                                                  typelist;
+  };
+ 
+
+  /**
+   * Template specialisation of removal of data type from type list.
+   */
+  template<class T, class JTail_t>
+  struct JRemove<JTypeList<T, JTail_t>, T>
+  {
+    typedef JTail_t                                                      typelist;
+  };
+  
+
+  /**
+   * Template specialisation of removal of data type from type list.
+   */
+  template<class JHead_t, class JTail_t, class T>
+  struct JRemove<JTypeList<JHead_t, JTail_t>, T>
+  {
+    typedef JTypeList<JHead_t, typename JRemove<JTail_t, T>::typelist>   typelist;
+  };
+  
+
+  /**
+   * Template specialisation of removal of type list from type list.
+   */
+  template<class JHead_t1, class JTail_t1, class JHead_t2, class JTail_t2>
+  struct JRemove<JTypeList<JHead_t1, JTail_t1>, 
+		 JTypeList<JHead_t2, JTail_t2> >
+  {
+    typedef typename JRemove<typename JRemove<JTypeList<JHead_t1, JTail_t1>, JHead_t2>::typelist,
+			     JTail_t2>::typelist                                 typelist;
+  };
+  
+
+  /**
+   * Template specialisation of removal of type list from type list.
+   */
+  template<class JHead_t1, class JTail_t1, class JHead_t2>
+  struct JRemove<JTypeList<JHead_t1, JTail_t1>, 
+		 JTypeList<JHead_t2, JNullType> >
+  {
+    typedef typename JRemove<JTypeList<JHead_t1, JTail_t1>, JHead_t2>::typelist  typelist;
+  };
+
+
+  /**
+   * Length of type list.
+   *
+   * Source code is taken from reference:
+   * A. Alexandrescu, Modern C++ Design, Addison Wesley.
+   */
+  template<class JTypeList_t> struct JLength {};
+
+
+  /**
+   * Recursive length of type list.
+   */
+  template<class JHead_t, class JTail_t>
+  struct JLength< JTypeList<JHead_t, JTail_t> >
+  {
+    enum { value = 1 + JLength<JTail_t>::value };
+  };
+
+
+  /**
+   * Terminator class of length of type list.
+   */
+  template<>
+  struct JLength<JNullType> 
+  {
+    enum { value = 0 };
+  };
+
+
+  /**
+   * Test presence of data type in type list.
+   */
+  template<class JTypeList_t, class T>
+  struct JHasType;
+
+  
+  /**
+   * Recursive test of presence data type in type list.
+   */
+  template<class JHead_t, class JTail_t, class T>
+  struct JHasType<JTypeList<JHead_t, JTail_t>, T>
+  {
+    enum { value = JHasType<JTail_t, T>::value };
+  };
+  
+
+  /**
+   * Identify presence data type in type list.
+   */
+  template<class JTail_t, class T>
+  struct JHasType<JTypeList<T, JTail_t>, T>
+  {
+    enum { value = true };
+  };
+
+
+  /**
+   * Termination of recursive test of presence data type in type list.
+   */
+  template<class T>
+  struct JHasType<JNullType, T>
+  {
+    enum { value = false };
+  };
+  
+
+  /**
+   * Specialisation of JHasType for single class type.
+   */
+  template<class T>
+  struct JHasType<T, T>
+  {
+    enum { value = true };
+  };
+
+
+  /**
+   * Resolve template class to JTypeList.
+   */
+  template<class T>
+  struct JResolveTypeList
+  {
+    typedef JTypeList<T>                 typelist;
+  };
+  
+
+  /**
+   * Resolve JTypeList to JTypeList.
+   */
+  template<class JHead_t, class JTail_t>
+  struct JResolveTypeList< JTypeList<JHead_t, JTail_t> >
+  {
+    typedef JTypeList<JHead_t, JTail_t>  typelist;
+  };
+
+
+  /**
+   * Extraction of data type from type list.
+   *
+   * Source code is taken from reference:
+   * A. Alexandrescu, Modern C++ Design, Addison Wesley.
+   */
+  template<class JTypelist_t, unsigned int index, bool range_check = true>
+  struct JTypeAt;
+
+
+  /**
+   * Recursive extraction of data type from type list.
+   */
+  template<class JHead_t, class JTail_t, unsigned int index, bool range_check>
+  struct JTypeAt<JTypeList<JHead_t, JTail_t>, index, range_check>
+  {
+    typedef typename JTypeAt<JTail_t, index - 1, range_check>::value_type        value_type;
+  };
+
+
+  /**
+   * Termination of recursive extraction of data type from type list.
+   */
+  template<class JHead_t, class JTail_t, bool range_check>
+  struct JTypeAt<JTypeList<JHead_t, JTail_t>, 0, range_check>
+  {
+    typedef JHead_t                                                              value_type;
+  };
+
+
+  /**
+   * Termination of recursive extraction of data type from type list.
+   */
+  template<unsigned int index>
+  struct JTypeAt<JNullType, index, false>
+  {
+    typedef JNullType                                                            value_type;
+  };
+
+
+  /**
+   * Indexing of data type in type list.
+   */
+  template<class JTypeList_t, class T>
+  struct JIndexOf;
+
+  
+  /**
+   * Recursive indexing of data type in type list.
+   */
+  template<class JHead_t, class JTail_t, class T>
+  struct JIndexOf<JTypeList<JHead_t, JTail_t>, T>
+  {
+  private:
+    enum { tmp   = JIndexOf<JTail_t, T>::value };
+
+  public:
+    enum { value = (tmp == -1 ? -1 : tmp + 1) };
+  };
+  
+
+  /**
+   * Identify indexi of data type in type list.
+   */
+  template<class JTail_t, class T>
+  struct JIndexOf<JTypeList<T, JTail_t>, T>
+  {
+    enum { value = 0 };
+  };
+
+
+  /**
+   * Termination of recursive indexing of data type in type list.
+   */
+  template<class T>
+  struct JIndexOf<JNullType, T>
+  {
+    enum { value = -1 };
+  };  
+
+
+  /**
+   * Auxiliary class for recursive type list generation.
+   */
+  template<class T, class ...Args>
+  struct JTYPELIST {
+    typedef JTypeList<T, typename JTYPELIST<Args...>::typelist>  typelist;
+  };
+
+
+  /**
+   * Template specialisation for expanding type list.
+   */
+  template<class JHead_t, class JTail_t, class T, class ...Args>
+  struct JTYPELIST<JTypeList<JHead_t, JTail_t>, T, Args...> {
+    typedef JTypeList<JHead_t, typename JTYPELIST<JTail_t, T, Args...>::typelist>  typelist;
+  };
+
+
+  /**
+   * Template specialisation for expanding type list.
+   */
+  template<class JHead_t, class T, class ...Args>
+  struct JTYPELIST<JTypeList<JHead_t, JNullType>, T, Args...> {
+    typedef JTypeList<JHead_t, typename JTYPELIST<T, Args...>::typelist>  typelist;
+  };
+
+
+  /**
+   * Template specialisation for expanding type list.
+   */
+  template<class JHead_t, class JTail_t>
+  struct JTYPELIST< JTypeList<JHead_t, JTail_t> > {
+    typedef JTypeList<JHead_t, JTail_t>  typelist;
+  };
+
+
+  /**
+   * Termination class for type list generation.
+   */
+  template<class T>
+  struct JTYPELIST<T> {
+    typedef JTypeList<T>  typelist;
+  };
+
+
+  /**
+   * Termination class for type list generation.
+   */
+  template<>
+  struct JTYPELIST<JNullType> {
+    typedef JTypeList<>   typelist;
+  };
+
+
+  /**
+   * For each data type method.
+   *
+   * The given object should provide for the function object operator
+   * <pre>
+   *    template<class T>
+   *    void object()(JType<T> type);
+   * </pre>
+   *
+   * \param  object           object
+   * \param  typelist         type list
+   * \return                  object
+   */
+  template<class JObject_t, class JHead_t, class JTail_t>
+  JObject_t& for_each(JObject_t& object, JType< JTypeList<JHead_t, JTail_t> > typelist)
+  {
+    for_each(object, JType<JHead_t>());
+    for_each(object, JType<JTail_t>());
+
+    return object;
+  }
+
+
+  /**
+   * For each data type method.
+   *
+   * The given object should provide for the function object operator
+   * <pre>
+   *    template<class T>
+   *    void object()(JType<T> type);
+   * </pre>
+   *
+   * \param  object           object
+   * \param  type             type
+   * \return                  object
+   */
+  template<class JObject_t, class T>
+  JObject_t& for_each(JObject_t& object, JType<T> type)
+  {
+    object(type);
+
+    return object;
+  }
+
+
+  /**
+   * Termination method of for each data type method.
+   *
+   * \param  object           object
+   * \param  type             null type
+   * \return                  object
+   */
+  template<class JObject_t>
+  JObject_t& for_each(JObject_t& object, JType<JNullType> type)
+  {
+    return object;
+  }
+}
+
+#endif
diff --git a/src/jpp/JLang/JValue.hh b/src/jpp/JLang/JValue.hh
new file mode 100644
index 0000000..2b0e7d7
--- /dev/null
+++ b/src/jpp/JLang/JValue.hh
@@ -0,0 +1,239 @@
+#ifndef __JLANG__JVALUE__
+#define __JLANG__JVALUE__
+
+#include <istream>
+#include <ostream>
+#include <sstream>
+#include <string>
+
+#include "JLang/JAbstractIO.hh"
+#include "JLang/JEquationFacet.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Forward declaration for friend declaration of JValueOutput inside JValueInput.
+   */
+  template<class T>
+  class JValueOutput;
+
+
+  /**
+   * Wrapper class around template object.
+   * This class implements the JStreamInput interface.
+   * Note that this class can be used in conjuction with the JEquationFacet.
+   */
+  template<class T>
+  class JValueInput :
+    public JStreamInput
+  {
+  public:
+
+
+    friend class JValueOutput<T>;
+
+
+    /**
+     * Constructor.
+     *
+     * \param  object  input object
+     */
+    JValueInput(T& object) :
+      p(&object)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  ps      pointer to valid object
+     */
+    JValueInput(void* ps) :
+      p((T*) ps)
+    {}
+
+
+    operator const T&() const { return *p; }   //!< type conversion operator
+    operator       T&()       { return *p; }   //!< type conversion operator
+
+    
+    /**
+     * Stream input.
+     *
+     * \param  in      input stream
+     * \return         input stream
+     */
+    virtual std::istream& read(std::istream& in) override 
+    {
+      return in >> *p;
+    }
+
+
+  protected:
+    T* p;
+  };
+
+
+  /**
+   * Wrapper class around template object.
+   * This class implements the JStreamOutput interface.
+   * Note that this class can be used in conjuction with the JEquationFacet.
+   */
+  template<class T>
+  class JValueOutput :
+    public JStreamOutput
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  object  input object
+     */
+    JValueOutput(const T& object) :
+      p(&object)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  object  input object
+     */
+    JValueOutput(const JValueInput<T>& object) :
+      p(object.p)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  ps      pointer to valid object
+     */
+    JValueOutput(const void* ps) :
+      p((const T*) ps)
+    {}
+
+
+    operator const T&() const { return *p; }   //!< type conversion operator
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out     output stream
+     * \return         output stream
+     */
+    virtual std::ostream& write(std::ostream& out) const override 
+    {
+      return out << *p;
+    }
+
+
+  protected:
+    const T* p;
+  };
+
+
+  /**
+   * Wrapper class around template object.
+   * This class implements the JStreamInput and JStreamOutput interfaces.
+   */
+  template<class T>
+  class JValue :
+    public JValueInput <T>,
+    public JValueOutput<T>
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  object  input object
+     */
+    JValue(T& object) :
+      JValueInput <T>(&object),
+      JValueOutput<T>(&object)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  ps      pointer to valid object
+     */
+    JValue(void* ps) :
+      JValueInput <T>(ps) ,
+      JValueOutput<T>(ps)
+    {}
+  };
+
+
+  /**
+   * Read JStreamInput from input stream.
+   *
+   * \param  in        input stream
+   * \param  object    JStreamInput
+   * \return           input stream
+   */
+  template<class T>
+  inline std::istream& operator>>(std::istream& in, JValueInput<T>& object)
+  {
+    using namespace std;
+
+    istream::sentry sentry(in);   // skips white spaces
+
+    if (sentry) {
+
+      const locale& loc = in.getloc();
+
+      if (has_facet<JEquationFacet>(loc)) {
+
+	string buffer;
+
+	const JEquationFacet& facet = use_facet<JEquationFacet>(loc);
+
+	facet.getline(in, buffer);
+
+	istringstream is(buffer);
+
+	is.imbue(locale(in.getloc(), facet.clone()));
+
+	object.read(is);
+
+	if (is.fail()) {
+	  in.setstate(ios_base::badbit);
+	}
+
+      } else {
+
+	object.read(in);
+      }
+    }
+
+    return in;
+  }
+
+
+  /**
+   * Write JStreamOutput to output stream.
+   *
+   * \param  out       output stream
+   * \param  object    JStreamOutput
+   * \return           output stream
+   */
+  template<class T>
+  inline std::ostream& operator<<(std::ostream& out, const JValueOutput<T>& object)
+  {
+    return object.write(out);
+  }
+}
+
+#endif
diff --git a/src/jpp/JLang/JVectorize.hh b/src/jpp/JLang/JVectorize.hh
index f99038f..0f86cfc 100644
--- a/src/jpp/JLang/JVectorize.hh
+++ b/src/jpp/JLang/JVectorize.hh
@@ -1,6 +1,7 @@
 #ifndef __JLANG__JVECTORIZE__
 #define __JLANG__JVECTORIZE__
 
+#include <ostream>
 #include <vector>
 #include <iterator>
 
@@ -24,7 +25,23 @@ namespace JLANG {
   template<class JElement_t, class JAllocator_t = std::allocator<JElement_t> >
   struct array_type :
     public std::vector<JElement_t, JAllocator_t>
-  {};
+  {
+    /**
+     * Write array to output stream.
+     *
+     * \param  out          output stream
+     * \param  object       array
+     * \return              output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const array_type& object)
+    {
+      for (typename array_type::const_iterator i = object.begin(); i != object.end(); ++i) {
+	out << ' ' << *i;
+      }
+
+      return out;
+    }
+  };
 
 
   /**
diff --git a/src/jpp/JMath/JMath.hh b/src/jpp/JMath/JMath.hh
index 7221e22..623b7af 100644
--- a/src/jpp/JMath/JMath.hh
+++ b/src/jpp/JMath/JMath.hh
@@ -1,5 +1,5 @@
-#ifndef __JMATH__
-#define __JMATH__
+#ifndef __JMATH__JMATH__
+#define __JMATH__JMATH__
 
 #include <cmath>
 #include <iterator>
diff --git a/src/jpp/JMath/JMathSupportkit.hh b/src/jpp/JMath/JMathSupportkit.hh
index cfba6ad..8c2719c 100644
--- a/src/jpp/JMath/JMathSupportkit.hh
+++ b/src/jpp/JMath/JMathSupportkit.hh
@@ -34,7 +34,7 @@ namespace JMATH {
   {
     const double u = x / sigma;
 
-    if (fabs(u) < 10.0)
+    if (fabs(u) < 20.0)
       return exp(-0.5*u*u);
     else
       return 0.0;
@@ -85,6 +85,10 @@ namespace JMATH {
   /**
    * Incomplete gamma function.
    *
+   * Source code is taken from reference:
+   * Numerical Recipes in C++, W.H. Press, S.A. Teukolsky, W.T. Vetterling and B.P. Flannery,
+   * Cambridge University Press.
+   *
    * \param  a                    a
    * \param  x                    x
    * \return                      function value
@@ -93,24 +97,28 @@ namespace JMATH {
   {
     using namespace std;
 
-    const int max = 100;
+    const int max = 1000000;
 
     if (x <  0.0) { THROW(JValueOutOfRange, "x <  0 " << x); }
     if (a <= 0.0) { THROW(JValueOutOfRange, "a <= 0 " << a); }
  
     const double gln = lgamma(a);
 
-    if (x <  a + 1.0) {
+    if (x < a + 1.0) {
 
-      if (x <= 0.0) { 
+      if (x < 0.0) { 
 	THROW(JValueOutOfRange, "x <= 0 " << x);
       }
 
+      if (x == 0.0) {
+	return 0.0;
+      }
+
       double ap  = a;
-      double sum = 1.0 /a;
+      double sum = 1.0 / a;
       double del = sum;
 
-      for (int i = 1; i != max; ++i) {
+      for (int i = 0; i != max; ++i) {
 
 	ap  += 1.0;
 	del *= x/ap;
@@ -121,10 +129,14 @@ namespace JMATH {
 	}
       }
 
+      THROW(JValueOutOfRange, "i == " << max);
+
     } else {
 
+      const double FPMIN = numeric_limits<double>::min() / numeric_limits<double>::epsilon();
+
       double b = x + 1.0 - a;
-      double c = numeric_limits<double>::epsilon() / numeric_limits<double>::min();
+      double c = 1.0 / FPMIN;
       double d = 1.0 / b;
       double h = d;
 
@@ -135,14 +147,14 @@ namespace JMATH {
 	b += 2.0;
 	d  = an*d + b;
 
-	if (fabs(d) < numeric_limits<double>::min()) {
-	  d = numeric_limits<double>::min();
+	if (fabs(d) < FPMIN) {
+	  d = FPMIN;
 	}
 
 	c  = b + an/c;
 
-	if (fabs(c) < numeric_limits<double>::min()) {
-	  c = numeric_limits<double>::min();
+	if (fabs(c) < FPMIN) {
+	  c = FPMIN;
 	}
 
 	d  = 1.0/d;
@@ -156,10 +168,8 @@ namespace JMATH {
 	}
       }
 
-      THROW(JValueOutOfRange, "a " << a);
+      THROW(JValueOutOfRange, "i == " << max);
     }
-
-    return 0.0;
   }
 
 
@@ -170,7 +180,7 @@ namespace JMATH {
    * \param  x                    x
    * \return                      function value
    */
-  inline double legendre(const unsigned int n, const double x)
+  inline double legendre(const size_t n, const double x)
   {
     switch (n) {
 
@@ -186,7 +196,7 @@ namespace JMATH {
 	double p1 = 1.0;
 	double p2 = x;
 
-	for (unsigned int i = 2; i <= n; ++i) {
+	for (size_t i = 2; i <= n; ++i) {
 	  p0 = p1;
 	  p1 = p2;
 	  p2 = ((2*i-1) * x*p1  -  (i-1) * p0) / i;
@@ -205,14 +215,14 @@ namespace JMATH {
    * \param  k                    k
    * \return                      function value
    */
-  inline double binomial(const int n, const int k)
+  inline double binomial(const size_t n, const size_t k)
   {
-    if (k == 0 || n == k) {
-      return 1.0;
+    if (n == 0 || n < k) {
+      return 0.0;
     }
 
-    if (n <= 0 || k < 0 || n < k) {
-      return 0.0;
+    if (k == 0 || n == k) {
+      return 1.0;
     }
 
     const int k1 = std::min(k, n - k);
@@ -226,6 +236,45 @@ namespace JMATH {
 
     return value;
   }
+
+
+  /**
+   * Poisson probability density distribition.
+   *
+   * \param  n                    number of occurences
+   * \param  mu                   expectation value
+   * \return                      probability
+   */
+  inline double poisson(const size_t n, const double mu)
+  {
+    using namespace std;
+
+    if (mu > 0.0) {
+
+      if (n > 0)
+	return exp(n*log(mu) - lgamma(n+1) - mu);
+      else
+	return exp(-mu);
+    } else if (mu == 0.0) {
+
+      return (n == 0 ? 1.0 : 0.0);
+    }
+ 
+    THROW(JValueOutOfRange, "mu <= 0 " << mu);
+  }
+
+
+  /**
+   * Poisson cumulative density distribition.
+   *
+   * \param  n                    number of occurences
+   * \param  mu                   expectation value
+   * \return                      probability
+   */
+  inline double Poisson(const size_t n, const double mu)
+  {
+    return 1.0 - Gamma(n + 1, mu);
+  }
 }
 
 #endif
diff --git a/src/jpp/JOscProb/JBaselineCalculator.hh b/src/jpp/JOscProb/JBaselineCalculator.hh
new file mode 100644
index 0000000..602556d
--- /dev/null
+++ b/src/jpp/JOscProb/JBaselineCalculator.hh
@@ -0,0 +1,195 @@
+#ifndef __JOSCPROB__JBASELINECALCULATOR__
+#define __JOSCPROB__JBASELINECALCULATOR__
+
+#include "JIO/JSerialisable.hh"
+
+
+/**
+ * \author bjung
+ * Auxiliary data structure for storing and computing oscillation baselines.
+ */
+
+namespace JOSCPROB {}
+namespace JPP { using namespace JOSCPROB; }
+
+namespace JOSCPROB {
+
+  using JIO::JReader;
+  using JIO::JWriter;
+  using JIO::JSerialisable;
+
+
+  /**
+   * Auxiliary data structure for storing and calculating baselines.
+   */
+  struct JBaselineCalculator :
+    public JSerialisable
+  {
+    /**
+     * Default constructor.
+     */
+    JBaselineCalculator() :
+      Lmin(0.0),
+      Lmax(0.0)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  Lmin     Minimum baseline [km]
+     * \param  Lmax     Maximum baseline [km]
+     */
+    JBaselineCalculator(const double Lmin,
+			const double Lmax) :
+      Lmin(Lmin),
+      Lmax(Lmax)
+    {}
+
+
+    /**
+     * Get minimum baseline.
+     *
+     * \return                 maximum baseline [km]
+     */
+    double getMinimumBaseline() const
+    {
+      return Lmin;
+    }
+
+    
+    /**
+     * Get maximum baseline.
+     *
+     * \return                 maximum baseline [km]
+     */
+    double getMaximumBaseline() const
+    {
+      return Lmax;
+    }
+
+
+    /**
+     * Get inner radius.
+     *
+     * \return                inner radius [km]
+     */
+    double getInnerRadius() const
+    {
+      return 0.5 * (Lmax - Lmin);
+    }
+
+
+    /**
+     * Get outer radius.
+     *
+     * \return                outer radius [km]
+     */
+    double getOuterRadius() const
+    {
+      return 0.5 * (Lmax + Lmin);;
+    }
+    
+
+    /**
+     * Get cosine zenith angle for a given baseline.
+     *
+     * \param  L              baseline [km]
+     * \return                cosine zenith angle
+     */
+    double getCosth(const double L) const
+    {
+      static const double r = getInnerRadius();
+      static const double R = getOuterRadius();
+      
+      return (R*R - r*r - L*L) / (2*L*r);
+    }
+
+    
+    /**
+     * Get baseline for a given cosine zenith angle.
+     *
+     * \param  costh           cosine zenith angle
+     * \return                 baseline [km]
+     */
+    double getBaseline(const double costh) const
+    {
+      static const double r = getInnerRadius();
+      static const double R = getOuterRadius();
+
+      const double ct = (fabs(costh) < 1.0 ? costh : (costh < 0 ? -1.0 : 1.0));
+    
+      return (-r * ct + sqrt(R*R - r*r * (1 - ct) * (1 + ct)));
+    }
+
+
+    /**
+     * Get baseline for a given cosine zenith angle.
+     *
+     * \param  costh           cosine zenith angle
+     * \return                 baseline [km]
+     */
+    double operator()(const double costh) const
+    {
+      return getBaseline(costh);
+    }
+
+
+    /**
+     * Binary stream input of baseline extrema.
+     *
+     * \param  in              input stream
+     * \return                 input stream
+     */
+    JReader& read(JReader& in) override
+    {
+      return in >> Lmin >> Lmax;
+    }
+
+    
+    /**
+     * Binary stream output of oscillation parameters.
+     *
+     * \param  out             output stream
+     * \return                 output stream
+     */
+    JWriter& write(JWriter& out) const override
+    {
+      return out << Lmin << Lmax;
+    }
+
+
+    /**
+     * Stream input of baseline calculator.
+     *
+     * \param  in              input stream
+     * \param  object          object
+     * \return                 input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JBaselineCalculator& object)
+    {
+      return in >> object.Lmin >> object.Lmax;
+    }
+
+
+    /**
+     * Stream output of baseline calculator.
+     *
+     * \param  out             output stream
+     * \param  object          object
+     * \return                 output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JBaselineCalculator& object)
+    {
+      return out << FIXED(15,5) << object.Lmin << FIXED(15,5) << object.Lmax;
+    }
+
+    
+  protected:
+    
+    double Lmin; //!< Minimum baseline [km]
+    double Lmax; //!< Maximum baseline [km]
+  };
+}
+
+#endif
diff --git a/src/jpp/JOscProb/JOscChannel.hh b/src/jpp/JOscProb/JOscChannel.hh
new file mode 100644
index 0000000..b9e1e7d
--- /dev/null
+++ b/src/jpp/JOscProb/JOscChannel.hh
@@ -0,0 +1,328 @@
+#ifndef __JOSCPROB__JOSCCHANNEL__
+#define __JOSCPROB__JOSCCHANNEL__
+
+#include <iostream>
+
+#include "JLang/JComparable.hh"
+
+#include "Jeep/JProperties.hh"
+
+
+/**
+ * \author bjung
+ * \file
+ * Oscillation channels and auxiliary methods.
+ */
+
+namespace JOSCPROB {}
+namespace JPP { using namespace JOSCPROB; }
+
+namespace JOSCPROB {
+
+  using JLANG::JEquationParameters;
+
+
+  /**
+   * Neutrino flavours.
+   */
+  enum class JFlavour_t      { ELECTRON           = 12,
+			       MUON               = 14,
+			       TAU                = 16,
+			       FLAVOUR_UNDEFINED  =  0 };
+
+
+  /**
+   * Charge parities.
+   */
+  enum class JChargeParity_t { ANTIPARTICLE       = -1,
+			       PARTICLE           = +1,
+			       CPARITY_UNDEFINED  =  0 };
+  
+  
+  /**
+   * Auxiliary function for retrieving the flavour corresponding to a given PDG identifier.
+   *
+   * \param  pdgType             PDG particle identifier
+   */
+  inline JFlavour_t getFlavour(const int pdgType)
+  {
+    const int type = abs(pdgType);
+      
+    switch (type) {
+	
+    case (int) JFlavour_t::ELECTRON:
+    case (int) JFlavour_t::MUON:
+    case (int) JFlavour_t::TAU:
+      return static_cast<JFlavour_t>(type);
+    default:
+      return JFlavour_t::FLAVOUR_UNDEFINED;
+    }
+  }
+
+
+  /**
+   * Auxiliary function for retrieving the charge-parity of a given PDG type.
+   *
+   * \param  pdgType             PDG particle identifier
+   * \return                     charge-parity (1 for neutrinos; -1 for anti-neutrinos)
+   */
+  inline JChargeParity_t getChargeParity(const int pdgType)
+  {
+    if        (pdgType < 0) {
+      return JChargeParity_t::ANTIPARTICLE;
+    } else if (pdgType > 0) {
+      return JChargeParity_t::PARTICLE;
+    } else {
+      return JChargeParity_t::CPARITY_UNDEFINED;
+    }
+  }
+  
+  
+  /**
+   * Neutrino oscillation channel.
+   */  
+  struct JOscChannel :
+    public JLANG::JComparable<JOscChannel>
+  {
+    /**
+     * Default constructor.
+     */
+    JOscChannel() :
+      in     (JFlavour_t::FLAVOUR_UNDEFINED),
+      out    (JFlavour_t::FLAVOUR_UNDEFINED),
+      Cparity(JChargeParity_t::CPARITY_UNDEFINED)
+    {}
+
+
+    /**
+     * Constructor.				
+     *
+     * \param  in              input  flavour
+     * \param  out             output flavour
+     * \param  Cparity         charge parity
+     */
+    JOscChannel(const JFlavour_t      in,
+		const JFlavour_t      out,
+		const JChargeParity_t Cparity) :
+      in (in),
+      out(out),
+      Cparity(Cparity)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  in              input  flavour
+     * \param  out             output flavour
+     * \param  Cparity         charge parity
+     */
+    JOscChannel(const int in,
+		const int out,
+		const int Cparity) :
+      in (getFlavour(in)),
+      out(getFlavour(out)),
+      Cparity(getChargeParity(Cparity))
+    {}
+
+
+    /**
+     * Check validity of this oscillation channel.
+     *
+     * \return                 true if this oscillation channel is valid; else false.
+     */
+    inline bool is_valid() const
+    {
+      return (in      != JFlavour_t::FLAVOUR_UNDEFINED &&
+	      out     != JFlavour_t::FLAVOUR_UNDEFINED &&
+	      Cparity != JChargeParity_t::CPARITY_UNDEFINED);
+    }
+
+
+    /**
+     * Less-than method
+     *
+     * \param  channel         channel
+     * \return                 true this channel less than given channel; else false 
+     */
+    inline bool less(const JOscChannel& channel) const
+    {
+      if (this->Cparity == channel.Cparity) {
+	
+	if (this->in == channel.in) {
+	  
+	  return this->out < channel.out;
+	  
+	} else {
+	  
+	  return this->in < channel.in;
+	}
+	
+      } else {
+	
+	return this->Cparity < channel.Cparity;
+      }
+    }    
+
+
+    /**
+     * Write channel to output.
+     *
+     * \param  out           output stream
+     * \param  object        oscillation channel
+     * \return               output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JOscChannel& object)
+    {
+      return out << object.getProperties();
+    }
+
+
+    /** 
+     * Read channel from input.
+     *
+     * \param  in            input stream
+     * \param  object        oscillation channel
+     * \return               input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JOscChannel& object)
+    {
+      JProperties properties(object.getProperties());
+
+      in >> properties;
+
+      object.setProperties(properties);
+      
+      return in;
+    }
+
+
+    /**
+     * Get equation parameters.
+     *
+     * \return                 equation parameters
+     */
+    static inline JEquationParameters& getEquationParameters()
+    {
+      static JEquationParameters equation("=", "\n\r;,", "./", "#");
+
+      return equation;
+    }
+      
+
+    /**
+     * Set equation parameters.
+     *
+     * \param  equation        equation parameters
+     */
+    static inline void setEquationParameters(const JEquationParameters& equation)
+    {
+      getEquationParameters() = equation;
+    }
+
+    
+    /**
+     * Get properties of this class.
+     *
+     * \param  equation        equation parameters
+     */
+    JProperties getProperties(const JEquationParameters& equation = JOscChannel::getEquationParameters())
+    {
+      return JOscChannelHelper(*this, equation);
+    }
+
+
+    /**
+     * Get properties of this class.
+     *
+     * \param  equation        equation parameters
+     */
+    JProperties getProperties(const JEquationParameters& equation = JOscChannel::getEquationParameters()) const
+    {
+      return JOscChannelHelper(*this, equation);
+    }
+
+
+    /**
+     * Set properties of this class
+     *
+     * \param  properties      properties
+     */
+    void setProperties(const JProperties& properties)
+    {
+      this->in      = getFlavour     (properties.getValue<const int>("in"));
+      this->out     = getFlavour     (properties.getValue<const int>("out"));
+      this->Cparity = getChargeParity(properties.getValue<const int>("Cparity"));
+    }
+
+
+    JFlavour_t      in;      //!< Incoming  flavour
+    JFlavour_t      out;     //!< Outcoming flavour
+    JChargeParity_t Cparity; //!< Charge-parity
+
+    
+  private:
+    /**
+     * Auxiliary class for I/O of oscillation channel.
+     */
+    struct JOscChannelHelper :
+      public JProperties
+    {
+      /**
+       * Constructor.
+       *
+       * \param  object        oscillation channel
+       * \param  equation      equation    parameters 
+       */
+      template<class JOscChannel_t>
+      JOscChannelHelper(JOscChannel_t&             object,
+			const JEquationParameters& equation) :
+	JProperties(equation, 1),
+	in         ((int) object.in),
+	out        ((int) object.out),
+	Cparity    ((int) object.Cparity)
+      {
+	this->insert(gmake_property(in));
+	this->insert(gmake_property(out));
+	this->insert(gmake_property(Cparity));
+      }
+
+      int in;
+      int out;
+      int Cparity;
+    };
+  };
+
+
+  /**
+   * Declare group of neutrino oscillation channels.
+   */
+  static const JOscChannel getOscChannel[]  =  {
+    JOscChannel(JFlavour_t::ELECTRON,  JFlavour_t::ELECTRON,  JChargeParity_t::PARTICLE),
+    JOscChannel(JFlavour_t::ELECTRON,  JFlavour_t::MUON,      JChargeParity_t::PARTICLE),
+    JOscChannel(JFlavour_t::ELECTRON,  JFlavour_t::TAU,       JChargeParity_t::PARTICLE),
+    JOscChannel(JFlavour_t::MUON,      JFlavour_t::ELECTRON,  JChargeParity_t::PARTICLE),
+    JOscChannel(JFlavour_t::MUON,      JFlavour_t::MUON,      JChargeParity_t::PARTICLE),
+    JOscChannel(JFlavour_t::MUON,      JFlavour_t::TAU,       JChargeParity_t::PARTICLE),
+    JOscChannel(JFlavour_t::TAU,       JFlavour_t::ELECTRON,  JChargeParity_t::PARTICLE),
+    JOscChannel(JFlavour_t::TAU,       JFlavour_t::MUON,      JChargeParity_t::PARTICLE),
+    JOscChannel(JFlavour_t::TAU,       JFlavour_t::TAU,       JChargeParity_t::PARTICLE),
+    JOscChannel(JFlavour_t::ELECTRON,  JFlavour_t::ELECTRON,  JChargeParity_t::ANTIPARTICLE),
+    JOscChannel(JFlavour_t::ELECTRON,  JFlavour_t::MUON,      JChargeParity_t::ANTIPARTICLE),
+    JOscChannel(JFlavour_t::ELECTRON,  JFlavour_t::TAU,       JChargeParity_t::ANTIPARTICLE),
+    JOscChannel(JFlavour_t::MUON,      JFlavour_t::ELECTRON,  JChargeParity_t::ANTIPARTICLE),
+    JOscChannel(JFlavour_t::MUON,      JFlavour_t::MUON,      JChargeParity_t::ANTIPARTICLE),
+    JOscChannel(JFlavour_t::MUON,      JFlavour_t::TAU,       JChargeParity_t::ANTIPARTICLE),
+    JOscChannel(JFlavour_t::TAU,       JFlavour_t::ELECTRON,  JChargeParity_t::ANTIPARTICLE),
+    JOscChannel(JFlavour_t::TAU,       JFlavour_t::MUON,      JChargeParity_t::ANTIPARTICLE),
+    JOscChannel(JFlavour_t::TAU,       JFlavour_t::TAU,       JChargeParity_t::ANTIPARTICLE)
+  };
+
+
+  /**
+   * Number of neutrino oscillation channels.
+   */
+  static const unsigned int NUMBER_OF_OSCCHANNELS = sizeof(getOscChannel) / sizeof(JOscChannel);
+}
+
+#endif
diff --git a/src/jpp/JOscProb/JOscParameters.hh b/src/jpp/JOscProb/JOscParameters.hh
new file mode 100644
index 0000000..3d1d06a
--- /dev/null
+++ b/src/jpp/JOscProb/JOscParameters.hh
@@ -0,0 +1,128 @@
+#ifndef __JOSCPROB__JOSCPARAMETERS__
+#define __JOSCPROB__JOSCPARAMETERS__
+
+#include "JLang/JException.hh"
+
+#include "JOscProb/JOscParametersInterface.hh"
+
+
+/**
+ * \author bjung, mdejong
+ */
+
+namespace JOSCPROB {}
+namespace JPP { using namespace JOSCPROB; }
+
+namespace JOSCPROB {
+
+  using JLANG::JEquationParameters;
+
+  using JIO::JReader;
+  using JIO::JWriter;
+  
+
+  /**
+   * Data structure for single set of oscillation parameters.
+   */
+  struct JOscParameters :
+    public JOscParametersInterface<double>
+  {
+    typedef JOscParametersInterface<double>                           JOscParameters_t;
+    typedef typename JOscParameters_t::JParameter_t                       JParameter_t;
+    typedef typename JOscParameters_t::argument_type                     argument_type;
+
+    
+    /**
+     * Default constructor.
+     */
+    JOscParameters() :
+      JOscParameters_t()
+    {}
+
+
+    /**
+     * Constructor.
+     * 
+     * \param  dM21sq          Squared mass difference between the first and second neutrino mass eigenstates               [eV2]
+     * \param  dM31sq          Squared mass difference between the first and third neutrino mass eigenstates                [eV2]
+     * \param  deltaCP         PMNS phase angle                                                                             [pi rad]
+     * \param  sinsqTh12       Squared sine of the PMNS mixing angle between the first and second neutrino mass eigenstates [-]
+     * \param  sinsqTh13       Squared sine of the PMNS mixing angle between the first and third neutrino mass eigenstates  [-]
+     * \param  sinsqTh23       Squared sine of the PMNS mixing angle between the second and third neutrino mass eigenstates [-]
+     */
+    JOscParameters(const double dM21sq,
+		   const double dM31sq,
+		   const double deltaCP,
+		   const double sinsqTh12,
+		   const double sinsqTh13,
+		   const double sinsqTh23) :
+      JOscParameters_t(dM21sq,
+		       dM31sq,
+		       deltaCP,
+		       sinsqTh12,
+		       sinsqTh13,
+		       sinsqTh23)
+    {
+      if (!is_valid()) {
+	THROW(JLANG::JValueOutOfRange, "JOscParameters::JOscParameters(...): Invalid parameters " << *this);
+      }
+    }
+
+
+    /**
+     * Constructor.
+     * 
+     * \param  name            parameter name
+     * \param  value           parameter value
+     * \param  args            remaining pairs of parameter names and values
+     */
+    template<class ...Args>
+    JOscParameters(const std::string& name,
+		   const double       value,
+		   const Args&     ...args) :
+      JOscParameters_t(name, value, args...)
+    {
+      if (!is_valid()) {
+	THROW(JLANG::JValueOutOfRange, "JOscParameters::JOscParameters(...): Invalid parameters " << *this);
+      }
+    }
+    
+    
+    /**
+     * Constructor.
+     * 
+     * Values taken from the NuFIT 5.1 three-flavour global analysis best fit values in:\n
+     * https://arxiv.org/abs/2111.03086?context=hep-ex\n
+     * including the Super-Kamiokande atmospheric data.
+     *
+     * \param  useIO           toggle inverted ordering
+     */
+    JOscParameters(const bool useIO) :
+      JOscParameters_t(          7.42e-5,
+			useIO ? -2.490e-3 + 7.42e-5 : 2.510e-3,
+			useIO ?  1.544              : 1.278,
+				 0.304,
+			useIO ?  0.02241            : 0.02246,
+			useIO ?  0.570              : 0.450    )
+    {}
+
+
+    /**
+     * Check validity of oscillation parameters.
+     *
+     * \return                 true if valid; else false
+     */
+    bool is_valid() const override
+    {
+      if ((this->sinsqTh12.isDefined() && this->sinsqTh12.getValue() < 0.0) ||
+	  (this->sinsqTh13.isDefined() && this->sinsqTh13.getValue() < 0.0) ||
+	  (this->sinsqTh23.isDefined() && this->sinsqTh23.getValue() < 0.0)) {
+	return false;
+      }
+      
+      return true;
+    }
+  };
+}
+
+#endif
diff --git a/src/jpp/JOscProb/JOscParametersGrid.hh b/src/jpp/JOscProb/JOscParametersGrid.hh
new file mode 100644
index 0000000..83d2006
--- /dev/null
+++ b/src/jpp/JOscProb/JOscParametersGrid.hh
@@ -0,0 +1,129 @@
+#ifndef __JOSCPROB__JOSCPARAMETERSGRID__
+#define __JOSCPROB__JOSCPARAMETERSGRID__
+
+#include "JLang/JException.hh"
+
+#include "JTools/JGrid.hh"
+
+#include "JOscProb/JOscParametersInterface.hh"
+
+
+/**
+ * \author bjung, mdejong
+ */
+
+namespace JOSCPROB {}
+namespace JPP { using namespace JOSCPROB; }
+
+namespace JOSCPROB {
+
+  using JTOOLS::JGrid;
+  using JTOOLS::make_grid;
+  
+
+  /**
+   * Data structure for oscillation parameter grids.
+   */
+  struct JOscParametersGrid :
+    public JOscParametersInterface<JGrid<double> >
+  {
+    typedef JGrid<double>                                                      JGrid_t;
+    typedef JOscParametersInterface<JGrid_t>                          JOscParameters_t;
+    typedef typename JOscParameters_t::JParameter_t                       JParameter_t;
+    typedef typename JOscParameters_t::argument_type                     argument_type;
+
+    
+    /**
+     * Default constructor.
+     */
+    JOscParametersGrid() :
+      JOscParameters_t()
+    {}
+
+
+    /**
+     * Constructor.
+     * 
+     * \param  dM21sq          Squared mass difference between the first and second neutrino mass eigenstates               [eV2]
+     * \param  dM31sq          Squared mass difference between the first and third neutrino mass eigenstates                [eV2]
+     * \param  deltaCP         PMNS phase angle                                                                             [pi rad]
+     * \param  sinsqTh12       Squared sine of the PMNS mixing angle between the first and second neutrino mass eigenstates [-]
+     * \param  sinsqTh13       Squared sine of the PMNS mixing angle between the first and third neutrino mass eigenstates  [-]
+     * \param  sinsqTh23       Squared sine of the PMNS mixing angle between the second and third neutrino mass eigenstates [-]
+     */
+    JOscParametersGrid(const JGrid_t& dM21sq,
+		       const JGrid_t& dM31sq,
+		       const JGrid_t& deltaCP,
+		       const JGrid_t& sinsqTh12,
+		       const JGrid_t& sinsqTh13,
+		       const JGrid_t& sinsqTh23) :
+      JOscParameters_t(dM21sq,
+		       dM31sq,
+		       deltaCP,
+		       sinsqTh12,
+		       sinsqTh13,
+		       sinsqTh23)
+    {
+      if (!is_valid()) {
+	THROW(JLANG::JValueOutOfRange, "JOscParametersGrid::JOscParametersGrid(...): Invalid parameters " << *this);
+      }
+    }
+
+
+    /**
+     * Constructor.
+     * 
+     * \param  name            parameter name
+     * \param  value           parameter value
+     * \param  args            remaining pairs of parameter names and values
+     */
+    template<class ...Args>
+    JOscParametersGrid(const std::string& name,
+		       const JGrid_t&     value,
+		       const Args&     ...args) :
+      JOscParameters_t(name, value, args...)      
+    {
+      if (!is_valid()) {
+	THROW(JLANG::JValueOutOfRange, "JOscParametersGrid::JOscParametersGrid(...): Invalid parameters " << *this);
+      }
+    }
+
+
+    /**
+     * Constructor.
+     * 
+     * Values taken from the NuFIT 5.1 three-flavour global analysis best fit values in:\n
+     * https://arxiv.org/abs/2111.03086?context=hep-ex\n
+     * including the Super-Kamiokande atmospheric data.
+     *
+     * \param  useIO           toggle inverted ordering
+     */
+    JOscParametersGrid(const bool useIO) :
+      JOscParameters_t( make_grid(         7.42e-5                       ),
+			make_grid(useIO ? -2.490e-3 + 7.42e-5 : 2.510e-3 ),
+			make_grid(useIO ?  1.544              : 1.278    ),
+			make_grid(         0.304                         ),
+			make_grid(useIO ?  0.02241            : 0.02246  ),
+			make_grid(useIO ?  0.570              : 0.450)     )
+    {}
+   
+
+    /**
+     * Check validity of oscillation parameter grids.
+     *
+     * \return                 true if valid; else false
+     */
+    bool is_valid() const override
+    {
+      if ((this->sinsqTh12.isDefined() && this->sinsqTh12.getValue().getXmin() < 0.0) ||
+	  (this->sinsqTh13.isDefined() && this->sinsqTh13.getValue().getXmin() < 0.0) ||
+	  (this->sinsqTh23.isDefined() && this->sinsqTh23.getValue().getXmin() < 0.0)) {
+	return false;
+      }
+      
+      return true;
+    }
+  };
+}
+
+#endif
diff --git a/src/jpp/JOscProb/JOscParametersInterface.hh b/src/jpp/JOscProb/JOscParametersInterface.hh
new file mode 100644
index 0000000..e806081
--- /dev/null
+++ b/src/jpp/JOscProb/JOscParametersInterface.hh
@@ -0,0 +1,440 @@
+#ifndef __JOSCPROB__JOSCPARAMETERSINTERFACE__
+#define __JOSCPROB__JOSCPARAMETERSINTERFACE__
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+
+#include "JSystem/JStat.hh"
+
+#include "Jeep/JPrint.hh"
+#include "Jeep/JProperties.hh"
+
+#include "JIO/JSerialisable.hh"
+
+#include "JLang/JEquals.hh"
+#include "JLang/JParameter.hh"
+#include "JLang/JVectorize.hh"
+#include "JLang/JStringStream.hh"
+#include "JLang/JObjectStreamIO.hh"
+#include "JLang/JEquationParameters.hh"
+
+
+/**
+ * \author bjung, mdejong
+ */
+
+namespace JOSCPROB {}
+namespace JPP { using namespace JOSCPROB; }
+
+namespace JOSCPROB {
+
+  using JIO::JReader;
+  using JIO::JWriter;
+  using JIO::JSerialisable;
+
+  using JLANG::JEquals;
+  using JLANG::JParameter;
+  using JLANG::JObjectStreamIO;
+  using JLANG::JValueOutOfRange;
+  using JLANG::JEquationParameters;
+
+  
+  /**
+   * Abstract base class for sets of oscillation parameters.
+   */
+  template<class T>
+  struct JOscParametersInterface :
+    public JSerialisable,
+    public JObjectStreamIO<JOscParametersInterface<T> >,
+    public JEquals        <JOscParametersInterface<T> >
+  {
+    typedef JOscParametersInterface<T>                      JOscParameters_t;
+    typedef JParameter<T>                                       JParameter_t;
+    typedef typename JParameter_t::argument_type               argument_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JOscParametersInterface() :
+      dM21sq   (),
+      dM31sq   (),
+      deltaCP  (),
+      sinsqTh12(),
+      sinsqTh13(),
+      sinsqTh23()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  dM21sq          Squared mass difference between the first and second neutrino mass eigenstates               [eV2]
+     * \param  dM31sq          Squared mass difference between the first and third neutrino mass eigenstates                [eV2]
+     * \param  deltaCP         PMNS phase angle                                                                             [pi rad]
+     * \param  sinsqTh12       Squared sine of the PMNS mixing angle between the first and second neutrino mass eigenstates [-]
+     * \param  sinsqTh13       Squared sine of the PMNS mixing angle between the first and third neutrino mass eigenstates  [-]
+     * \param  sinsqTh23       Squared sine of the PMNS mixing angle between the second and third neutrino mass eigenstates [-]
+     */
+    JOscParametersInterface(const T& dM21sq,
+			    const T& dM31sq,
+			    const T& deltaCP,
+			    const T& sinsqTh12,
+			    const T& sinsqTh13,
+			    const T& sinsqTh23) :
+      dM21sq   (dM21sq),
+      dM31sq   (dM31sq),
+      deltaCP  (deltaCP),
+      sinsqTh12(sinsqTh12),
+      sinsqTh13(sinsqTh13),
+      sinsqTh23(sinsqTh23)
+    {}
+
+
+    /**
+     * Constructor.
+     * 
+     * \param  name            parameter name
+     * \param  value           parameter value
+     * \param  args            remaining pairs of parameter names and values
+     */
+    template<class ...Args>
+    JOscParametersInterface(const std::string& name,
+			    const T&           value,
+			    const Args&     ...args)
+    {
+      set(name, value, args...);
+    }
+
+
+    /**
+     * Set value for a given oscillation parameter.
+     *
+     * \param  name            parameter name
+     * \param  value           parameter value
+     */
+    void set(const std::string& name,
+	     const T&           value)
+    {
+      JProperties properties = this->getProperties();
+
+      JProperties::iterator i = properties.find(name);
+
+      if (i != properties.end()) {
+
+	i->second.setValue(JParameter_t(value));
+	
+      } else {
+	
+        THROW(JValueOutOfRange,
+	      "template<class T> JOscParametersInterface<T>::set(const std::string&, const T&): " <<
+	      "Invalid oscillation parameter name " << name << "; Valid options:\n"  << JLANG::get_keys(properties));
+      }
+    }
+
+
+    /**
+     * Set value for given list of oscillation parameters.
+     *
+     * \param  name            parameter name
+     * \param  value           parameter value
+     * \param  args            remaining pairs of parameter names and values
+     */
+    template<class ...Args>
+    void set(const std::string& name,
+	     const T&           value,
+	     const Args&     ...args)
+    {
+      set(name, value);
+      set(args...);
+    }
+
+
+    /**
+     * Join the given oscillation parameters with these oscillation parameters.
+     *
+     * \param  parameters      oscillation parameters
+     */
+    JOscParameters_t& join(const JOscParameters_t& parameters)
+    {
+      if (parameters.dM21sq.isDefined())    { this->dM21sq    = parameters.dM21sq;    }
+      if (parameters.dM31sq.isDefined())    { this->dM31sq    = parameters.dM31sq;    }
+      if (parameters.deltaCP.isDefined())   { this->deltaCP   = parameters.deltaCP;   }
+      if (parameters.sinsqTh12.isDefined()) { this->sinsqTh12 = parameters.sinsqTh12; }
+      if (parameters.sinsqTh13.isDefined()) { this->sinsqTh13 = parameters.sinsqTh13; }
+      if (parameters.sinsqTh23.isDefined()) { this->sinsqTh23 = parameters.sinsqTh23; }
+      
+      return *this;
+    }
+   
+
+    /**
+     * Get oscillation parameters.
+     *
+     * \return                 oscillation parameters
+     */
+    const JOscParameters_t& getOscParameters() const
+    {
+      return static_cast<const JOscParameters_t&>(*this);
+    }
+
+
+    /**
+     * Set oscillation parameters.
+     *
+     * \param  parameters      oscillation parameters
+     */
+    void setOscParameters(const JOscParameters_t& parameters)
+    {
+      static_cast<JOscParameters_t&>(*this) = parameters;
+    }
+
+
+    /**
+     * Check validity of oscillation parameters.
+     *
+     * \return                 true if valid; else false
+     */
+    virtual bool is_valid() const = 0;
+
+
+    /**
+     * Get size of this oscillation parameters set.
+     *
+     * \return                 size (= number of defined parameters)
+     */
+    virtual unsigned int size() const
+    {
+      return ((unsigned int) this->dM21sq.isDefined()    +
+	      (unsigned int) this->dM31sq.isDefined()    +
+	      (unsigned int) this->deltaCP.isDefined()   +
+	      (unsigned int) this->sinsqTh12.isDefined() +
+	      (unsigned int) this->sinsqTh13.isDefined() +
+	      (unsigned int) this->sinsqTh23.isDefined());
+    }
+
+
+    /**
+     * Check if this oscillations parameter set contains the given oscillation parameters.
+     *
+     * \param  parameters      oscillation parameters
+     * \return                 true if all given oscillation parameters\n
+     *                         are also defined in this oscillation parameters set
+     */
+    virtual bool contains(const JOscParameters_t& parameters) const
+    {
+      if ( (parameters.dM21sq.isDefined()    && !this->dM21sq.isDefined())    ||
+	   (parameters.dM31sq.isDefined()    && !this->dM31sq.isDefined())    ||
+	   (parameters.deltaCP.isDefined()   && !this->deltaCP.isDefined())   ||
+	   (parameters.sinsqTh12.isDefined() && !this->sinsqTh12.isDefined()) ||
+	   (parameters.sinsqTh13.isDefined() && !this->sinsqTh13.isDefined()) ||
+	   (parameters.sinsqTh23.isDefined() && !this->sinsqTh23.isDefined()) ) {
+	return false;
+      } else {
+	return true;
+      }
+    }
+
+
+    bool equals(const JOscParameters_t& parameters) const
+    {
+      return (this->dM21sq    == parameters.dM21sq    &&
+	      this->dM31sq    == parameters.dM31sq    &&
+	      this->deltaCP   == parameters.deltaCP   &&
+	      this->sinsqTh12 == parameters.sinsqTh12 &&
+	      this->sinsqTh13 == parameters.sinsqTh13 &&
+	      this->sinsqTh23 == parameters.sinsqTh23);
+    }
+
+
+    /**
+     * Stream input of oscillation parameters.
+     *
+     * \param  in              input stream
+     * \param  parameters      oscillation parameters
+     * \return                 input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JOscParameters_t& parameters)
+    {
+      using namespace std;
+      using namespace JPP;
+      
+      JStringStream is(in);
+
+      if (getFileStatus(is.str().c_str())) {
+	is.load();
+      }
+
+      JProperties properties(parameters.getProperties());
+
+      is >> properties;
+
+      parameters.setProperties(properties);
+
+      return in;
+    }
+
+
+    /**
+     * Stream output of oscillation parameters.
+     *
+     * \param  out             output stream
+     * \param  parameters      oscillation parameters
+     * \return                 output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JOscParameters_t& parameters)
+    {
+      return out << parameters.getProperties();
+    }
+
+
+    /**
+     * Binary stream input of oscillation parameters.
+     *
+     * \param  in              input stream
+     * \return                 input stream
+     */
+    JReader& read(JReader& in) override
+    {
+      JProperties properties = getProperties();
+
+      for (JProperties::iterator i = properties.begin(); i != properties.end(); ++i) {
+	
+	bool is_defined;
+	T    value;
+	
+	if ((in >> is_defined >> value) && is_defined) {
+
+	  JParameter_t& parameter = i->second.getValue<JParameter_t>();
+	  
+	  parameter.setValue(value);
+	}
+      }
+
+      return in;
+    }
+    
+
+    /**
+     * Binary stream output of oscillation parameters.
+     *
+     * \param  out             output stream
+     * \return                 output stream
+     */
+    JWriter& write(JWriter& out) const override
+    {
+      const JProperties properties = getProperties();
+
+      for (JProperties::const_iterator i = properties.cbegin(); i != properties.cend(); ++i) {
+
+	const JParameter_t& parameter = i->second.getValue<const JParameter_t>();	
+
+	out << parameter.isDefined() << parameter.getValue();
+      }
+
+      return out;
+    }
+    
+
+    /**
+     * Get equation parameters.
+     *
+     * \return                 equation parameters
+     */
+    static inline JEquationParameters& getEquationParameters()
+    {
+      static JEquationParameters equation("=", "\n\r;,", "./", "#");
+
+      return equation;
+    }
+      
+
+    /**
+     * Set equation parameters.
+     *
+     * \param  equation        equation parameters
+     */
+    static inline void setEquationParameters(const JEquationParameters& equation)
+    {
+      getEquationParameters() = equation;
+    }
+
+
+    /**
+     * Get properties of this class.
+     *
+     * \param  equation        equation parameters
+     */
+    JProperties getProperties(const JEquationParameters& equation = JOscParameters_t::getEquationParameters())
+    {
+      return JOscParametersHelper(*this, equation);
+    }
+
+
+    /**
+     * Get properties of this class.
+     *
+     * \param  equation        equation parameters
+     */
+    JProperties getProperties(const JEquationParameters& equation = JOscParameters_t::getEquationParameters()) const
+    {
+      return JOscParametersHelper(*this, equation);
+    }
+
+
+    /**
+     * Set properties of this class
+     *
+     * \param  properties      properties
+     */
+    void setProperties(const JProperties& properties)
+    {
+      this->dM21sq    = properties.getValue<JParameter_t>("dM21sq");
+      this->dM31sq    = properties.getValue<JParameter_t>("dM31sq");
+      this->deltaCP   = properties.getValue<JParameter_t>("deltaCP");
+      this->sinsqTh12 = properties.getValue<JParameter_t>("sinsqTh12");
+      this->sinsqTh13 = properties.getValue<JParameter_t>("sinsqTh13");
+      this->sinsqTh23 = properties.getValue<JParameter_t>("sinsqTh23");
+    }
+
+
+    JParameter_t dM21sq;     //!< Squared mass difference between the first and second neutrino mass eigenstates               [eV2]
+    JParameter_t dM31sq;     //!< Squared mass difference between the first and third neutrino mass eigenstates                [eV2]
+    JParameter_t deltaCP;    //!< PMNS phase angle                                                                             [pi * rad]
+    JParameter_t sinsqTh12;  //!< Squared sine of the PMNS mixing angle between the first and second neutrino mass eigenstates [-]
+    JParameter_t sinsqTh13;  //!< Squared sine of the PMNS mixing angle between the first and third neutrino mass eigenstates  [-]
+    JParameter_t sinsqTh23;  //!< Squared sine of the PMNS mixing angle between the second and third neutrino mass eigenstates [-]
+
+    
+  private:
+    
+    /**
+     * Auxiliary class for I/O of oscillation parameters.
+     */
+    struct JOscParametersHelper :
+      public JProperties
+    {
+      /**
+       * Constructor.
+       *
+       * \param  parameters    oscillation parameters
+       * \param  equation      equation    parameters 
+       */
+      template<class JOscParameters_t>
+      JOscParametersHelper(JOscParameters_t&          parameters,
+			   const JEquationParameters& equation) :
+	JProperties(equation, 1)
+      {
+	this->insert(gmake_property(parameters.dM21sq));
+	this->insert(gmake_property(parameters.dM31sq));
+	this->insert(gmake_property(parameters.deltaCP));	
+	this->insert(gmake_property(parameters.sinsqTh12));
+	this->insert(gmake_property(parameters.sinsqTh13));
+	this->insert(gmake_property(parameters.sinsqTh23));
+      }
+    };
+  };
+}
+
+#endif
diff --git a/src/jpp/JOscProb/JOscProb.hh b/src/jpp/JOscProb/JOscProb.hh
new file mode 100644
index 0000000..94c85ce
--- /dev/null
+++ b/src/jpp/JOscProb/JOscProb.hh
@@ -0,0 +1,46 @@
+#ifndef __JOSCPROB__JOSCPROB__
+#define __JOSCPROB__JOSCPROB__
+
+#include "JLang/JClonable.hh"
+
+#include "JOscProb/JOscChannel.hh"
+
+
+/**
+ * \author bjung
+ */
+
+namespace JOSCPROB {
+
+  using JLANG::JClonable;
+  
+
+  /**
+   * Low-level interface for retrieving the oscillation probability\n
+   * corresponding to a given oscillation channel, neutrino energy and zenith angle.
+   */
+  struct JOscProb :
+    public JClonable<JOscProb>
+  {
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JOscProb()
+    {}
+
+    
+    /**
+     * Get oscillation probability for given oscillation channel.
+     *
+     * \param  channel            oscillation channel
+     * \param  energy             neutrino energy     [GeV]
+     * \param  costh              cosine zenith angle
+     * \return                    oscillation probability
+     */
+    virtual double getOscProb(const JOscChannel& channel,
+			      const double       energy,
+			      const double       costh) const = 0;
+  };
+}
+
+#endif
diff --git a/src/jpp/JOscProb/JOscProbInterpolator.hh b/src/jpp/JOscProb/JOscProbInterpolator.hh
new file mode 100644
index 0000000..b37b181
--- /dev/null
+++ b/src/jpp/JOscProb/JOscProbInterpolator.hh
@@ -0,0 +1,331 @@
+#ifndef __JOSCPROB__JOSCPROBINTERPOLATOR__
+#define __JOSCPROB__JOSCPROBINTERPOLATOR__
+
+#include "Jeep/JMessage.hh"
+#include "Jeep/JProperties.hh"
+
+#include "JIO/JSerialisable.hh"
+#include "JIO/JFileStreamIO.hh"
+
+#include "JLang/JClonable.hh"
+#include "JLang/JObjectIO.hh"
+#include "JLang/JException.hh"
+
+#include "JTools/JPolint.hh"
+#include "JTools/JMapList.hh"
+#include "JTools/JCollection.hh"
+#include "JTools/JFunction1D_t.hh"
+#include "JTools/JMultiFunction.hh"
+#include "JTools/JFunctionalMap_t.hh"
+
+#include "JOscProb/JOscChannel.hh"
+#include "JOscProb/JOscParameters.hh"
+#include "JOscProb/JOscProbToolkit.hh"
+#include "JOscProb/JBaselineCalculator.hh"
+#include "JOscProb/JOscProbInterpolatorInterface.hh"
+
+
+/**
+ * \author bjung, mdejong
+ */
+
+namespace JOSCPROB {}
+namespace JPP { using namespace JOSCPROB; }
+
+namespace JOSCPROB {
+
+  using JEEP::JMessage;
+
+  using JLANG::JClonable;
+
+  using JTOOLS::JMultiFunction;
+  
+
+  /** 
+   * Template definition of a multi-dimensional oscillation probability interpolation table.
+   */
+  template<template<class, class> class JCollection_t = JTOOLS::JCollection,
+	   class JFunction1D_t                        = JTOOLS::JPolintFunction1D <1,
+										   JTOOLS::JElement2D<double, JTOOLS::JArray<NUMBER_OF_OSCCHANNELS, double> >,
+										   JCollection_t,
+										   JTOOLS::JArray<NUMBER_OF_OSCCHANNELS, double> >,
+	   class JFunctionalMaplist_t                 = JTOOLS::JMAPLIST          <JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint2FunctionalMap>::maplist >
+  class JOscProbInterpolator :
+    public JMultiFunction                                                               <JFunction1D_t, JFunctionalMaplist_t>,
+    public JClonable<JOscProbInterpolatorInterface, JOscProbInterpolator <JCollection_t, JFunction1D_t, JFunctionalMaplist_t> >,
+    public JMessage                                <JOscProbInterpolator <JCollection_t, JFunction1D_t, JFunctionalMaplist_t> >
+  {
+  public:
+
+    typedef JOscProbInterpolator<JCollection_t, JFunction1D_t, JFunctionalMaplist_t>                interpolator_type;
+    typedef JMultiFunction<JFunction1D_t, JFunctionalMaplist_t>                                    multifunction_type;
+
+    enum { NUMBER_OF_DIMENSIONS = multifunction_type::NUMBER_OF_DIMENSIONS };
+
+    typedef typename multifunction_type::abscissa_type                                                  abscissa_type;    
+    typedef typename multifunction_type::argument_type                                                  argument_type;
+    typedef typename multifunction_type::result_type                                                      result_type;
+    typedef typename multifunction_type::value_type                                                        value_type;
+
+    typedef typename multifunction_type::multimap_type                                                  multimap_type;
+
+    typedef typename multifunction_type::super_const_iterator                                    super_const_iterator;
+    typedef typename multifunction_type::super_iterator                                                super_iterator;
+    typedef typename multifunction_type::function_type                                                  function_type;
+
+    using JMessage<interpolator_type>::debug;
+
+    
+    /**
+     * Default constructor.
+     */
+    JOscProbInterpolator() :
+      multifunction_type(),
+      parameters(),
+      getBaseline()
+    {
+      this->set(JOscParameters(false)); // Initialize buffer with NuFIT NO best fit parameters
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  fileName             oscillation probability table filename
+     */
+    JOscProbInterpolator(const char* fileName) :
+      multifunction_type(),
+      parameters(),
+      getBaseline()
+    {
+      this->load(fileName);
+      this->set(JOscParameters(false)); // Initialize buffer with NuFIT NO best fit parameters      
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  fileName             oscillation probability table filename
+     * \param  parameters           oscillation parameters
+     */
+    JOscProbInterpolator(const char*           fileName,
+			 const JOscParameters& parameters) :
+      multifunction_type(),
+      parameters(),
+      getBaseline()
+    {
+      this->load(fileName);
+      this->set(parameters);
+    }
+
+
+    /**
+     * Load oscillation probability table from file.
+     *
+     * \param  fileName             oscillation probability table filename
+     */
+    void load(const char* fileName) override
+    {
+      using namespace std;
+      using namespace JPP;
+      
+      try {
+
+	NOTICE("loading oscillation probability table from file " << fileName << "... " << flush);
+	
+	JLANG::load<JIO::JFileStreamReader>(fileName, *this);
+
+	NOTICE("OK" << endl);
+      }
+      catch(const JException& error) {
+	THROW(JFileReadException, "JOscProbInterpolator::load(): Error reading file " << fileName);
+      }
+    }    
+
+
+    /**
+     * Get fixed oscillation parameters associated with this interpolation table.
+     *
+     * \return                    oscillation parameters
+     */
+    const JOscParameters& getTableParameters() const override
+    {
+      return parameters;
+    }
+
+
+    /**
+     * Get baseline calculator associated with this interpolation table.
+     *
+     * \return                    baseline calculator
+     */
+    const JBaselineCalculator& getBaselineCalculator() const override
+    {
+      return getBaseline;
+    }
+
+
+    /**
+     * Set oscillation parameters for interpolation.
+     *
+     * \return                      oscillation parameters
+     */
+    void set(JOscParameters parameters) override
+    {
+      using namespace JPP;
+      
+      parameters.join(this->parameters);
+      
+      const JProperties properties = parameters.getProperties();
+
+      for (JProperties::const_iterator i = properties.cbegin(); i != properties.cend(); ++i) {
+	
+	const JOscParameters::JParameter_t& parameter = i->second.getValue<JOscParameters::JParameter_t>();
+	
+	if (parameter.isDefined()) {
+	    
+	  const int index = std::distance(properties.cbegin(), i);
+
+	  this->buffer[index] = parameter.getValue();
+	  
+	} else {
+
+	  THROW(JNoValue,
+		"JOscProbInterpolator<...>::set(JOscParameters): " <<
+		"No value for parameter "                          << i->first);
+	}
+      }
+    }
+
+
+    /**
+     * Get oscillation probability for a given oscillation channel.
+     *
+     * \param  channel            oscillation channel
+     * \param  E                  neutrino energy [GeV]
+     * \param  costh              cosine zenith angle
+     * \return                    oscillation probability
+     */
+    double operator()(const JOscChannel&    channel,
+		      const double          E,
+		      const double          costh) const override
+    {
+      using namespace std;
+      using namespace JPP;
+
+      const JOscChannel* p = find(getOscChannel, getOscChannel + NUMBER_OF_OSCCHANNELS, channel);
+	
+      if (p != end(getOscChannel)) {
+	
+	const double L = getBaseline(costh);
+
+	this->buffer[NUMBER_OF_DIMENSIONS-2] = L/E;
+	this->buffer[NUMBER_OF_DIMENSIONS-1] = costh;
+
+	const argument_type* arguments = this->buffer.data();
+	
+	const size_t       index         = distance(getOscChannel, p);
+	const result_type& probabilities = this->evaluate(arguments);
+
+	return probabilities[index];
+	
+      } else {
+	
+	THROW(JValueOutOfRange, "JOscProbInterpolator<...>::operator(): Invalid oscillation channel " << channel << endl);
+      }
+    }
+
+
+    /**
+     * Get oscillation probability for a given set of oscillation parameters\n
+     * and a given oscillation channel.
+     *
+     * \param  channel            oscillation channel
+     * \param  parameters         oscillation parameters
+     * \param  E                  neutrino energy [GeV]
+     * \param  costh              cosine zenith angle
+     * \return                    oscillation probability
+     */
+    double operator()(const JOscParameters& parameters,
+		      const JOscChannel&    channel,
+		      const double          E,
+		      const double          costh) override
+    {
+      set(parameters);
+
+      return (*this)(channel, E, costh);      
+    }
+    
+    
+    /**
+     * Read from input.
+     *
+     * \param  in                   reader
+     * \return                      reader
+     */
+    JReader& read(JReader& in) override 
+    {
+      parameters.read(in);
+      getBaseline.read(in);
+      
+      in >> static_cast<multifunction_type&>(*this);
+      
+      this->compile();
+      
+      return in;
+    }
+    
+    
+    /**
+     * Write from input.
+     *
+     * \param  out                  writer
+     * \return                      writer
+     */
+    JWriter& write(JWriter& out) const override 
+    {
+      parameters.write(out);
+      getBaseline.write(out);
+      
+      out << static_cast<const multifunction_type&>(*this);
+
+      return out;
+    }
+
+    
+  private:
+
+    JOscParameters      parameters;  //!< Fixed oscillation parameters corresponding to the oscillation probability table
+    JBaselineCalculator getBaseline; //!< Baseline functor
+  };
+}
+
+
+namespace JEEP {
+
+  /**
+   * JMessage template specialization for oscillation probability interpolators.
+   */
+  template<template<class, class> class JCollection_t, class JFunction1D_t, class JFunctionalMaplist_t>
+  struct JMessage<JOSCPROB::JOscProbInterpolator<JCollection_t, JFunction1D_t, JFunctionalMaplist_t> >
+  {
+    static int debug;
+  };
+
+
+  /**
+   * Default verbosity for oscillation probability interpolators.
+   */
+  template<template<class, class> class JCollection_t, class JFunction1D_t, class JFunctionalMaplist_t>
+  int JMessage<JOSCPROB::JOscProbInterpolator<JCollection_t, JFunction1D_t, JFunctionalMaplist_t> >::debug = (int) notice_t;
+  
+}
+
+#endif
diff --git a/src/jpp/JOscProb/JOscProbInterpolatorInterface.hh b/src/jpp/JOscProb/JOscProbInterpolatorInterface.hh
new file mode 100644
index 0000000..6080140
--- /dev/null
+++ b/src/jpp/JOscProb/JOscProbInterpolatorInterface.hh
@@ -0,0 +1,115 @@
+#ifndef __JOSCPROB__JOSCPROBINTERPOLATORINTERFACE__
+#define __JOSCPROB__JOSCPROBINTERPOLATORINTERFACE__
+
+
+#include "JLang/JClonable.hh"
+
+#include "JIO/JSerialisable.hh"
+
+#include "JOscProb/JOscChannel.hh"
+#include "JOscProb/JOscParameters.hh"
+#include "JOscProb/JBaselineCalculator.hh"
+
+
+/**
+ * \author bjung, mdejong
+ */
+
+namespace JOSCPROB {
+
+  using JLANG::JClonable;
+
+  using JIO::JSerialisable;
+
+
+  /**
+   * Low-level interface for oscillation probability tables.
+   */
+  class JOscProbInterpolatorInterface :
+    public JSerialisable,
+    public JClonable<JOscProbInterpolatorInterface>
+  {
+  public:
+
+    /**
+     * Default constructor.
+     */
+    JOscProbInterpolatorInterface()
+    {}
+
+
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JOscProbInterpolatorInterface()
+    {}
+    
+
+    /**
+     * Load oscillation probability table from file.
+     *
+     * \param  fileName        oscillation probability table fileName
+     */
+    virtual void load(const char* fileName) = 0;
+    
+    
+    /**
+     * Get oscillation parameters.
+     *
+     * \return                 oscillation parameters
+     */
+    virtual const JOscParameters& getTableParameters() const = 0;
+
+
+    /**
+     * Get baseline calculator associated with this interpolation table.
+     *
+     * \return                    baseline calculator
+     */
+    virtual const JBaselineCalculator& getBaselineCalculator() const = 0;
+    
+
+    /**
+     * Set oscillation parameters.
+     *
+     * \param  parameters      oscillation parameters
+     */
+    virtual void set(JOscParameters parameters) = 0;
+
+
+    /**
+     * Get oscillation probability for a given oscillation channel.
+     *
+     * \param  channel            oscillation channel
+     * \param  E                  neutrino energy [GeV]
+     * \param  costh              cosine zenith angle
+     * \return                    oscillation probability
+     */
+    virtual double operator()(const JOscChannel&    channel,
+			      const double          E,
+			      const double          costh) const = 0;
+    
+    
+    /**
+     * Get oscillation probability for a given set of oscillation parameters\n
+     * and a given oscillation channel.
+     *
+     * \param  channel            oscillation channel
+     * \param  parameters         oscillation parameters
+     * \param  E                  neutrino energy [GeV]
+     * \param  costh              cosine zenith angle
+     * \return                    oscillation probability
+     */
+    virtual double operator()(const JOscParameters& parameters,
+			      const JOscChannel&    channel,
+			      const double          E,
+			      const double          costh)
+    {
+      set(parameters);
+
+      return (*this)(channel, E, costh);      
+    }
+  };
+}
+
+#endif
diff --git a/src/jpp/JOscProb/JOscProbToolkit.hh b/src/jpp/JOscProb/JOscProbToolkit.hh
new file mode 100644
index 0000000..a10f2b9
--- /dev/null
+++ b/src/jpp/JOscProb/JOscProbToolkit.hh
@@ -0,0 +1,122 @@
+#ifndef __JOSCPROB__JOSCPROBTOOLKIT__
+#define __JOSCPROB__JOSCPROBTOOLKIT__
+
+#include <string>
+
+#include "JLang/JException.hh"
+
+#include "JOscProb/JOscChannel.hh"
+
+
+/**
+ * \author bjung
+ * Auxiliary methods for oscillation probabilities.
+ */
+
+namespace JOSCPROB {}
+namespace JPP { using namespace JOSCPROB; }
+
+namespace JOSCPROB {
+
+  using JLANG::JValueOutOfRange;
+  
+
+  /**
+   * OscProb neutrino flavour identifiers.
+   */
+  enum class OscProbFlavour_t { ELECTRON,
+				MUON,
+				TAU };
+  
+  
+  /**
+   * Auxiliary function for retrieving the OscProb flavour identifier corresponding to a JOscProb flavour identifier.
+   *
+   * \param  flavour             flavour identifier
+   * \return                     OscProb flavour identifier
+   */
+  inline OscProbFlavour_t getOscProbFlavour(const JFlavour_t flavour)
+  {
+    switch(flavour) {
+    case JFlavour_t::ELECTRON:
+      return OscProbFlavour_t::ELECTRON;
+    case JFlavour_t::MUON:
+      return OscProbFlavour_t::MUON;
+    case JFlavour_t::TAU:
+      return OscProbFlavour_t::TAU;
+    default:
+      THROW(JLANG::JValueOutOfRange, "getOscProbFlavour(...): Invalid flavour " << (int) flavour);
+    }
+  }
+
+
+  /**
+   * Auxiliary function for retrieving the OscProb flavour identifier corresponding to a JOscProb flavour identifier.
+   *
+   * \param  flavour             flavour identifier
+   * \return                     OscProb flavour identifier
+   */
+  inline OscProbFlavour_t getOscProbFlavour(const int pdgType)
+  {
+    JFlavour_t flavour = getFlavour(pdgType);
+    
+    return getOscProbFlavour(flavour);
+  }
+
+
+  /**
+   * Auxiliary data structure to hold oscillation variable names.
+   */
+  struct JOscVars
+  {
+    /**
+     * Oscillation variable types.
+     */
+    enum type {
+      COSTH,
+      SINTH,
+      ENERGY,
+      LOG10E,
+      LOE,
+      BASELINE,
+      UNDEFINED
+    };
+
+    
+    static const char* const energy() { return "energy"; }   //!< energy [GeV]
+    static const char* const log10E() { return "log10E"; }   //!< logarithmic energy [GeV]
+    static const char* const LoE()    { return "LoE"; }      //!< L/E [km GeV-1]
+    
+    static const char* const costh()  { return "costh"; }    //!< cosine of zenith-angle
+    static const char* const sinth()  { return "sinth"; }    //!< sine of zenith-angle
+    static const char* const L()      { return "L"; }        //!< sine of zenith-angle
+
+    
+    /**
+     * Get oscillation variable type.
+     *
+     * \param  name                              oscillation variable name
+     * \return                                   oscillation variable type
+     */
+    static inline type getType(const std::string& name)
+    {
+      if        (name == energy()) {
+	return ENERGY;
+      } else if (name == costh()) {
+	return COSTH;
+      } else if (name == sinth()) {
+	return SINTH;
+      } else if (name == log10E()) {
+	return LOG10E;	
+      } else if (name == LoE()) {
+	return LOE;
+      } else if (name == L()) {
+	return BASELINE;	
+      } else {
+	THROW(JValueOutOfRange, "JOscVars::getType(): Invalid oscillation variable " << name);
+      }
+    }
+  };
+}
+
+#endif
diff --git a/src/jpp/JPhysics/JConstants.hh b/src/jpp/JPhysics/JConstants.hh
index 1dbebf2..52dab8c 100644
--- a/src/jpp/JPhysics/JConstants.hh
+++ b/src/jpp/JPhysics/JConstants.hh
@@ -25,6 +25,7 @@ namespace JPHYSICS {
   static const double C                         = 0.299792458;          //!< Speed of light in vacuum [m/ns]
   static const double C_INVERSE                 = 1.0/C;                //!< Inverse speed of light in vacuum [ns/m]
   static const double AVOGADRO                  = 6.0221415e23;         //!< Avogadro's number [gr^-1]
+  static const double NUCLEON_MOLAR_MASS        = 1.0;                  //!< nucleon molar mass [g/mol]
   static const double H                         = 4.13566733e-15;       //!< Planck constant [eV s]
   static const double HBAR                      = H/(2*PI);             //!< Planck constant [eV s]
   static const double HBARC                     = HBAR*C*1.0e9;         //!< Planck constant [eV m]
diff --git a/src/jpp/JPhysics/JGeane.hh b/src/jpp/JPhysics/JGeane.hh
index 4c0c3a3..82cbb86 100644
--- a/src/jpp/JPhysics/JGeane.hh
+++ b/src/jpp/JPhysics/JGeane.hh
@@ -21,11 +21,13 @@ namespace JPHYSICS {
   /**
    * Equivalent muon track length per unit shower energy.
    *
+   * See ANTARES internal note ANTARES-SOFT-2002-015, J.\ Brunner.
+   *
    * \return        equivalent muon track length [m/Gev]
    */
   inline double geanc()
   {
-    return 4.7;                   // dx/dE [m/GeV]
+    return 4.7319;                   // dx/dE [m/GeV]
   }
 
 
@@ -47,7 +49,7 @@ namespace JPHYSICS {
     /**
      * Get energy loss constant.
      *
-     * \return         Energy loss due to pair production and Bremstrahlung [m^-1]
+     * \return         Energy loss due to pair production and bremsstrahlung [m^-1]
      */
     virtual double getB() const = 0;
 
@@ -114,10 +116,10 @@ namespace JPHYSICS {
    * Function object for the energy loss of the muon.\n
    * The energy loss can be formulated as:
    *
-   *     \f[ -\frac{dE}{dx}  =  a + bE\f]
+   *     \f[ -\frac{dE}{dx}  =  a + bE \f]
    *
    * N.B:
-   * \f$a\f$ and \f$b\f$ are assumed constant (internal units m and GeV, respectively).
+   * \f$ a \f$ and \f$ b \f$ are assumed constant (internal units m and GeV, respectively).
    */
   class JGeane_t :
     public JGeane
@@ -126,7 +128,7 @@ namespace JPHYSICS {
     /**
      * constructor
      * \param  __a     Energy loss due to ionisation [GeV/m]
-     * \param  __b     Energy loss due to pair production and Bremstrahlung [m^-1]
+     * \param  __b     Energy loss due to pair production and bremsstrahlung [m^-1]
      */ 
     JGeane_t(const double __a,
 	     const double __b) :
@@ -149,7 +151,7 @@ namespace JPHYSICS {
     /**
      * Get energy loss constant.
      *
-     * \return         Energy loss due to pair production and Bremstrahlung [m^-1]
+     * \return         Energy loss due to pair production and bremsstrahlung [m^-1]
      */
     virtual double getB() const override 
     {
@@ -204,8 +206,8 @@ namespace JPHYSICS {
   class JGeaneWater : 
     public JGeane,
     protected std::map<double, JGeane_t>
-  {
-  public:
+  {    
+  public:    
     /**
      * Default constructor.
      */
@@ -237,7 +239,7 @@ namespace JPHYSICS {
      *
      * N.B. The return value corresponds to the medium-energy regime.
      *
-     * \return         Energy loss due to pair production and Bremstrahlung [m^-1]
+     * \return         Energy loss due to pair production and bremsstrahlung [m^-1]
      */
     virtual double getB() const override 
     {
@@ -257,7 +259,7 @@ namespace JPHYSICS {
       double E1 = E;
       double x1 = dx;
 
-      if (E1 > MASS_MUON) {
+      if (E1 > MASS_MUON / getSinThetaC()) {
 
 	const_iterator p = this->lower_bound(E1);
 
@@ -281,12 +283,68 @@ namespace JPHYSICS {
     }
 
 
+
+
+    /**
+     * Get energy loss due to ionisation.
+     *
+     * \param  E           initial energy                [GeV]
+     * \param  dx          distance traveled             [m]
+     * \return             energy loss due to ionisation [GeV]
+     */
+    double getEa(const double E, const double dx) const
+    {
+      using namespace std;
+      using namespace JPP;
+      
+      double Ea = 0.0;
+      
+      double E1 = E;
+      double x1 = dx;
+
+      if (E1 > MASS_MUON / getSinThetaC()) {
+
+	map<double, JGeane_t>::const_iterator p = this->lower_bound(E1);
+
+	do {
+
+	  --p;
+
+	  const double x2 = p->second.getX(E1, p->first);
+
+	  Ea += (x2 > x1 ? x1 : x2) * p->second.getA();
+	  E1  = p->first;
+	  
+	  x1 -= x2;
+	  
+	} while (p != this->cbegin() && x1 > 0.0);
+      }
+
+      return Ea;
+    }
+
+
+    /**
+     * Get energy loss due to pair production and bremsstrahlung.
+     *
+     * \param  E           initial energy                                        [GeV]
+     * \param  dx          distance traveled                                     [m]
+     * \return             energy loss due to pair production and bremsstrahlung [GeV]
+     */
+    double getEb(const double E, const double dx) const
+    {
+      const double dE = E - getE(E, dx);
+      
+      return dE - getEa(E, dx);
+    }
+
+
     /**
      * Get distance traveled by muon.
      *
      * \param  E0      Energy of muon at start [GeV]
      * \param  E1      Energy of muon at end   [GeV]
-     * \return         distance traveled [m]
+     * \return         distance traveled       [m]
      */
     virtual double getX(const double E0, 
 			const double E1) const override
@@ -294,7 +352,7 @@ namespace JPHYSICS {
       double E  = E0;
       double dx = 0.0;
 
-      if (E > MASS_MUON) {
+      if (E > MASS_MUON / getSinThetaC()) {
 
 	const_iterator p = this->lower_bound(E);
 
diff --git a/src/jpp/JPhysics/JNPE_t.hh b/src/jpp/JPhysics/JNPE_t.hh
index 6a3c9b8..c1e42b7 100644
--- a/src/jpp/JPhysics/JNPE_t.hh
+++ b/src/jpp/JPhysics/JNPE_t.hh
@@ -43,7 +43,9 @@ struct JMuonNPE_t {
 
     const JPDFType_t pdf_t[] = { DIRECT_LIGHT_FROM_MUON,
 				 SCATTERED_LIGHT_FROM_MUON,
-				 DIRECT_LIGHT_FROM_EMSHOWERS,
+				 DIRECT_LIGHT_FROM_DELTARAYS,
+				 SCATTERED_LIGHT_FROM_DELTARAYS,
+ 				 DIRECT_LIGHT_FROM_EMSHOWERS,
 				 SCATTERED_LIGHT_FROM_EMSHOWERS };
 
     const  int N = sizeof(pdf_t) / sizeof(pdf_t[0]);
@@ -60,7 +62,8 @@ struct JMuonNPE_t {
 
       JPDF_t pdf;
 
-      const string file_name = getFilename(fileDescriptor, pdf_t[i]);
+      const JPDFType_t type      = pdf_t[i];
+      const string     file_name = getFilename(fileDescriptor, type);
 
       cout << "loading PDF from file " << file_name << "... " << flush;
 
@@ -70,10 +73,12 @@ struct JMuonNPE_t {
 
       pdf.setExceptionHandler(supervisor);
 
-      if (!is_bremsstrahlung(pdf_t[i]))
-	Y1.push_back(JNPE_t(pdf));
-      else
+      if      (is_bremsstrahlung(type))
 	YB.push_back(JNPE_t(pdf));
+      else if (is_deltarays(type))
+	YA.push_back(JNPE_t(pdf));
+      else
+	Y1.push_back(JNPE_t(pdf));
     }
 
     // Add PDFs
@@ -81,8 +86,9 @@ struct JMuonNPE_t {
     cout << "adding PDFs... " << flush;
 
     Y1[1].add(Y1[0]); Y1.erase(Y1.begin());
+    YA[1].add(YA[0]); YA.erase(YA.begin());
     YB[1].add(YB[0]); YB.erase(YB.begin());
-
+  
     cout << "OK" << endl;
   }
 
@@ -106,17 +112,19 @@ struct JMuonNPE_t {
   {
     using namespace JPP;
 
-    const double yA = getNPE(Y1, R, theta, phi);
+    const double y1 = getNPE(Y1, R, theta, phi);
+    const double yA = getNPE(YA, R, theta, phi);
     const double yB = getNPE(YB, R, theta, phi);
 
     if (E >= MASS_MUON * INDEX_OF_REFRACTION_WATER)
-      return yA + E * yB;
+      return y1  +  getDeltaRaysFromMuon(E) * yA  +  E * yB;
     else
       return 0.0;
   }
 
 private:
   std::vector<JNPE_t> Y1;     //!< light from muon
+  std::vector<JNPE_t> YA;     //!< light from delta-rays
   std::vector<JNPE_t> YB;     //!< light from EM showers
 
   /**
diff --git a/src/jpp/JPhysics/JPDFTable.hh b/src/jpp/JPhysics/JPDFTable.hh
index 73670e2..8cd9510 100644
--- a/src/jpp/JPhysics/JPDFTable.hh
+++ b/src/jpp/JPhysics/JPDFTable.hh
@@ -8,6 +8,7 @@
 #include "JTools/JQuantiles.hh"
 #include "JTools/JSet.hh"
 #include "JTools/JRange.hh"
+#include "JMath/JMathSupportkit.hh"
 #include "JPhysics/JConstants.hh"
 #include "JPhysics/JPDFTransformer.hh"
 
@@ -74,8 +75,8 @@ namespace JPHYSICS {
      *
      * \param  input                multi-dimensional function
      */
-    template<class JPDF_t, class JPDFMaplist_t, class JPDFDistance_t>    
-    JPDFTable(const JTransformableMultiFunction<JPDF_t, JPDFMaplist_t, JPDFDistance_t>& input) :
+    template<class __JFunction_t, class __JMaplist_t, class __JDistance_t>    
+    JPDFTable(const JTransformableMultiFunction<__JFunction_t, __JMaplist_t, __JDistance_t>& input) :
       transformablemultifunction_type(input)
     {}
 
@@ -85,8 +86,8 @@ namespace JPHYSICS {
      *
      * \param  input                multi-dimensional histogram
      */
-    template<class JHistogram1D_t, class JHistogramMaplist_t, class JHistogramDistance_t>
-    JPDFTable(const JTransformableMultiHistogram<JHistogram1D_t, JHistogramMaplist_t, JHistogramDistance_t>& input) :
+    template<class JHistogram_t, class __JMaplist_t, class __JDistance_t>
+    JPDFTable(const JTransformableMultiHistogram<JHistogram_t, __JMaplist_t, __JDistance_t>& input) :
       transformablemultifunction_type(input)
     {}
 
@@ -113,7 +114,7 @@ namespace JPHYSICS {
 	      const double quantile       = 0.99)
     {
       using namespace std;
-      using namespace JTOOLS;
+      using namespace JPP;
 
       typedef typename transformer_type::array_type  array_type;
 
@@ -257,51 +258,6 @@ namespace JPHYSICS {
 
       return out;
     }
-
-  protected:
-    /**
-     * Gauss function (normalised to 1 at x = 0).
-     *
-     * \param  x                    x
-     * \param  sigma                sigma
-     * \return                      function value
-     */
-    static double gauss(const double x, const double sigma)
-    {
-      const double u = x / sigma;
-
-      if (fabs(u) < 10.0)
-	return exp(-0.5*u*u);
-      else
-	return 0.0;
-    }
-
-
-    /**
-     * Normalised Gauss function.
-     *
-     * \param  x                    x
-     * \param  sigma                sigma
-     * \return                      function value
-     */
-    static double Gauss(const double x, const double sigma)
-    {
-      return gauss(x, sigma) / sqrt(2.0*JTOOLS::PI) / sigma;
-    }
-
-
-    /**
-     * Normalised Gauss function.
-     *
-     * \param  x                    x
-     * \param  x0                   central value
-     * \param  sigma                sigma
-     * \return                      function value
-     */
-    static double Gauss(const double x, const double x0, const double sigma)
-    {
-      return Gauss(x - x0, sigma);
-    }
   };
 }
 
diff --git a/src/jpp/JPhysics/JPDFToolkit.hh b/src/jpp/JPhysics/JPDFToolkit.hh
index 23a3586..663f49c 100644
--- a/src/jpp/JPhysics/JPDFToolkit.hh
+++ b/src/jpp/JPhysics/JPDFToolkit.hh
@@ -1,13 +1,10 @@
 #ifndef __JPHYSICS__JPDFTOOLKIT__
 #define __JPHYSICS__JPDFTOOLKIT__
 
-#include <vector>
 #include <cmath>
 
-#include "JLang/JCC.hh"
 #include "JPhysics/JConstants.hh"
-#include "JTools/JFunction1D_t.hh"
-#include "JIO/JSerialisable.hh"
+
 
 /**
  * \file
@@ -20,11 +17,6 @@ namespace JPP { using namespace JPHYSICS; }
 
 namespace JPHYSICS {
 
-  using JIO::JReader;
-  using JIO::JWriter;
-  using JTOOLS::JGridPolint0Function1D_t;
-  using JTOOLS::JGridSplineFunction1D_t;
-
 
   /**
    * Get minimal wavelength for PDF evaluations.
@@ -120,6 +112,21 @@ namespace JPHYSICS {
   }
 
 
+  /**
+   * Emission profile of photons from delta-rays.
+   *
+   * Profile is taken from reference ANTARES-SOFT-2002-015, J.\ Brunner (fig.\ 3).
+   *
+   * \param  x      cosine emission angle
+   * \return        probability
+   */
+  inline double getDeltaRayProbability(const double x)
+  {
+    //return 1.0 / (4.0 * PI);
+    return 0.188 * exp(-1.25 * pow(fabs(x - 0.90), 1.30));
+  }
+
+
   /**
    * Rayleigh cross section.
    *
@@ -158,165 +165,6 @@ namespace JPHYSICS {
 
     return ls;
   }
-
-
-  /**
-   * Absorption length of pure water.
-   *
-   * CITATION:
-   * Jonasz M. 2007. Absorption coefficient of water: Data sources (www.tpdsci.com/Tpc/AbsCfOfWaterDat.php).
-   * In: Top. Part. Disp. Sci. (www.tpdsci.com). 			
-   *
-   * DATA FROM:
-   * Wozniak B., Wozniak S. B., Tyszka K., Ostrowska M., Majchrowski R., Ficek D., Dera J. 2005.
-   * Modelling the light absorption properties of particulate matter forming organic particles suspended in seawater. Part 2.
-   * Modelling results. Oceanologia 47, 621-662.
-   * see also
-   * Wozniak B., Dera J. 2007.
-   * Light absorption in sea water. Springer, Berlin, 456 pp. (see p. 62)
-   *
-   * NOTES:
-   * As stated by the data authors, the data are based on measurement results obtained by various authors 
-   * (interpolated by a linear approximation where applicable):
-   * Wavelength	Reference
-   * - 200-335 nm   Smith R.C., Baker K.S. 1981. Optical properties of the clearest natural waters (200-800 nm). Appl. Opt. 20, 177-184.
-   * - 340-370 nm   Sogandares F.M., Fry, E.S. 1997. Absorption spectrum (340 -640 nm) of pure water. I. Photothermal measurements Appl. Opt. 36, 8699-8709.
-   * - 380-700 nm   Pope R.M., Fry E.S. 1997. Absorption spectrum (380 -700 nm) of pure water. II. Integrating cavity measurements. Appl. Opt. 36, 8710-8723
-   */
-  class JAbsorptionLengthOfPureWater :
-    public JGridSplineFunction1D_t
-  {
-  public:
-    JAbsorptionLengthOfPureWater() 
-    {
-      //    wave-	absorption
-      //    length	coefficient
-      //    [um]	[1/m]
-      (*this)[0.200e3]  =  3.07;
-      (*this)[0.205e3]  =  2.53;
-      (*this)[0.210e3]  =  1.99;
-      (*this)[0.215e3]  =  1.65;
-      (*this)[0.220e3]  =  1.31;
-      (*this)[0.225e3]  =  1.1185;
-      (*this)[0.230e3]  =  0.927;
-      (*this)[0.235e3]  =  0.8235;
-      (*this)[0.240e3]  =  0.72;
-      (*this)[0.245e3]  =  0.6395;
-      (*this)[0.250e3]  =  0.559;
-      (*this)[0.255e3]  =  0.508;
-      (*this)[0.260e3]  =  0.457;
-      (*this)[0.265e3]  =  0.415;
-      (*this)[0.270e3]  =  0.373;
-      (*this)[0.275e3]  =  0.3305;
-      (*this)[0.280e3]  =  0.288;
-      (*this)[0.285e3]  =  0.2515;
-      (*this)[0.290e3]  =  0.215;
-      (*this)[0.295e3]  =  0.178;
-      (*this)[0.300e3]  =  0.141;
-      (*this)[0.305e3]  =  0.123;
-      (*this)[0.310e3]  =  0.105;
-      (*this)[0.315e3]  =  0.0947;
-      (*this)[0.320e3]  =  0.0844;
-      (*this)[0.325e3]  =  0.0761;
-      (*this)[0.330e3]  =  0.0678;
-      (*this)[0.335e3]  =  0.06195;
-      (*this)[0.340e3]  =  0.0325;
-      (*this)[0.345e3]  =  0.02645;
-      (*this)[0.350e3]  =  0.0204;
-      (*this)[0.355e3]  =  0.018;
-      (*this)[0.360e3]  =  0.0156;
-      (*this)[0.365e3]  =  0.0135;
-      (*this)[0.370e3]  =  0.0114;
-      (*this)[0.375e3]  =  0.011385;
-      (*this)[0.380e3]  =  0.01137;
-      (*this)[0.385e3]  =  0.00941;
-      (*this)[0.390e3]  =  0.00851;
-      (*this)[0.395e3]  =  0.00813;
-      (*this)[0.400e3]  =  0.00663;
-      (*this)[0.405e3]  =  0.0053;
-      (*this)[0.410e3]  =  0.00473;
-      (*this)[0.415e3]  =  0.00444;
-      (*this)[0.420e3]  =  0.00454;
-      (*this)[0.425e3]  =  0.00478;
-      (*this)[0.430e3]  =  0.00495;
-      (*this)[0.435e3]  =  0.0053;
-      (*this)[0.440e3]  =  0.00635;
-      (*this)[0.445e3]  =  0.00751;
-      (*this)[0.450e3]  =  0.00922;
-      (*this)[0.455e3]  =  0.00962;
-      (*this)[0.460e3]  =  0.00979;
-      (*this)[0.465e3]  =  0.01011;
-      (*this)[0.470e3]  =  0.0106;
-      (*this)[0.475e3]  =  0.0114;
-      (*this)[0.480e3]  =  0.0127;
-      (*this)[0.485e3]  =  0.0136;
-      (*this)[0.490e3]  =  0.015;
-      (*this)[0.495e3]  =  0.0173;
-      (*this)[0.500e3]  =  0.0204;
-      (*this)[0.505e3]  =  0.0256;
-      (*this)[0.510e3]  =  0.0325;
-      (*this)[0.515e3]  =  0.0396;
-      (*this)[0.520e3]  =  0.0409;
-      (*this)[0.525e3]  =  0.0417;
-      (*this)[0.530e3]  =  0.0434;
-      (*this)[0.535e3]  =  0.0452;
-      (*this)[0.540e3]  =  0.0474;
-      (*this)[0.545e3]  =  0.0511;
-      (*this)[0.550e3]  =  0.0565;
-      (*this)[0.555e3]  =  0.0596;
-      (*this)[0.560e3]  =  0.0619;
-      (*this)[0.565e3]  =  0.0642;
-      (*this)[0.570e3]  =  0.0695;
-      (*this)[0.575e3]  =  0.0772;
-      (*this)[0.580e3]  =  0.0896;
-      (*this)[0.585e3]  =  0.11;
-      (*this)[0.590e3]  =  0.1351;
-      (*this)[0.595e3]  =  0.1672;
-      (*this)[0.600e3]  =  0.2224;
-      (*this)[0.605e3]  =  0.2577;
-      (*this)[0.610e3]  =  0.2644;
-      (*this)[0.615e3]  =  0.2678;
-      (*this)[0.620e3]  =  0.2755;
-      (*this)[0.625e3]  =  0.2834;
-      (*this)[0.630e3]  =  0.2916;
-      (*this)[0.635e3]  =  0.3012;
-      (*this)[0.640e3]  =  0.3108;
-      (*this)[0.645e3]  =  0.325;
-      (*this)[0.650e3]  =  0.34;
-      (*this)[0.655e3]  =  0.371;
-      (*this)[0.660e3]  =  0.41;
-      (*this)[0.665e3]  =  0.429;
-      (*this)[0.670e3]  =  0.439;
-      (*this)[0.675e3]  =  0.448;
-      (*this)[0.680e3]  =  0.465;
-      (*this)[0.685e3]  =  0.486;
-      (*this)[0.690e3]  =  0.516;
-      (*this)[0.695e3]  =  0.559;
-      (*this)[0.700e3]  =  0.624;
-
-      compile();
-    }
-
-
-    /**
-     * Absorption length of pure water.
-     *
-     * \param  lambda     wavelength of light [nm]
-     * \return            absorption length   [m]
-     */
-    double operator()(const double lambda) const
-    {
-      const double y = JGridSplineFunction1D_t::operator()(lambda);
-      
-      return 1.0 / y;
-    }
-  };
-  
-
-  /**
-   * Function object for absorption length of pure water.
-   */
-  static const JAbsorptionLengthOfPureWater getAbsorptionLengthOfPureWater;
 }
 
 #endif
diff --git a/src/jpp/JPhysics/JPDFTransformer.hh b/src/jpp/JPhysics/JPDFTransformer.hh
index 59422f3..279b4aa 100644
--- a/src/jpp/JPhysics/JPDFTransformer.hh
+++ b/src/jpp/JPhysics/JPDFTransformer.hh
@@ -1065,7 +1065,7 @@ namespace JPHYSICS {
       const double theta = buffer[2];
       const double phi   = buffer[3];
 
-      const double ct0 = cd;
+      const double ct0 = (cd > -1.0 ? cd < +1.0 ? cd : +1.0 : -1.0);
       const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
     
       const double px = sin(theta)*cos(phi);
@@ -1166,6 +1166,16 @@ namespace JPHYSICS {
     {}    
 
     
+    /**
+     * Constructor.
+     *
+     * \param  transformer    transformer
+     */
+    JPDFTransformer(const JFunction4DTransformer_t& transformer) :
+      transformer(transformer)
+    {}
+
+
     /**
      * Constructor.
      *
diff --git a/src/jpp/JPhysics/JPDFTypes.hh b/src/jpp/JPhysics/JPDFTypes.hh
index 8c71d47..27ad9ce 100644
--- a/src/jpp/JPhysics/JPDFTypes.hh
+++ b/src/jpp/JPhysics/JPDFTypes.hh
@@ -4,7 +4,6 @@
 #include <string>
 #include <sstream>
 
-#include "JLang/JException.hh"
 #include "Jeep/JeepToolkit.hh"
 
 /**
@@ -18,8 +17,6 @@ namespace JPP { using namespace JPHYSICS; }
 
 namespace JPHYSICS {
 
-  using JLANG::JException;
-
 
   /**
    * PDF types
@@ -45,6 +42,8 @@ namespace JPHYSICS {
     DIRECT_LIGHT_FROM_BRIGHT_POINT     =   23,      //!< direct    light from bright point
     SCATTERED_LIGHT_FROM_BRIGHT_POINT  =   24,      //!< scattered light from bright point
 
+    LIGHT_FROM_ELONGATED_EMSHOWER      =  113,      //!< light from elongated EM shower
+
     LIGHT_FROM_MUON                    = 1001,      //!< direct and scattered light from muon
     LIGHT_FROM_EMSHOWERS               = 1003,      //!< direct and scattered light from EM showers
     LIGHT_FROM_DELTARAYS               = 1005,      //!< direct and scattered light from delta-rays
@@ -53,9 +52,6 @@ namespace JPHYSICS {
   };
 
 
-  static const char WILD_CARD = '%';            //!< wild card character for file name substitution
-
-
   /**
    * Get PDF label.
    *
@@ -101,22 +97,10 @@ namespace JPHYSICS {
   }
 
 
-  /**
-   * Check wild card.
-   *
-   * \param  file_name          file name
-   * \return                    true if wild card present; else false
-   */
-  inline bool hasWildCard(const std::string& file_name)
-  {
-    return (file_name.find(WILD_CARD) != std::string::npos);
-  }
-
-
   /**
    * Get PDF file name.
    *
-   * The input file name should contain the wild card character WILD_CARD 
+   * The input file name should contain the wild card character JEEP::FILENAME_WILD_CARD 
    * which will be replaced by the label corresponding to the given PDF type.
    * 
    * \param  file_name          input  file name
@@ -126,17 +110,7 @@ namespace JPHYSICS {
   inline std::string getFilename(const std::string& file_name, 
 				 const JPDFType_t   pdf)
   {
-    using namespace std;
-
-    string buffer = file_name;
-
-    string::size_type pos = buffer.find(WILD_CARD);
-    
-    if (pos == string::npos) {	  
-      throw JException(string("Method getFilename(): Missing wild card character \'") + WILD_CARD + "\'.");
-    }
-
-    return buffer.replace(pos, 1, getLabel(pdf));
+    return JEEP::setWildCard(file_name, getLabel(pdf));
   }
 
 
diff --git a/src/jpp/JPhysics/JPDF_t.hh b/src/jpp/JPhysics/JPDF_t.hh
index bfc0ff2..bf1493e 100644
--- a/src/jpp/JPhysics/JPDF_t.hh
+++ b/src/jpp/JPhysics/JPDF_t.hh
@@ -256,7 +256,7 @@ struct JMuonPDF_t {
     return h1;
   }
 
-  JPDF_t pdfA;   //!< PDF for minimum ionisong particle
+  JPDF_t pdfA;   //!< PDF for minimum ionising particle
   JPDF_t pdfB;   //!< PDF for average energy losses
   JPDF_t pdfC;   //!< PDF for delta-rays
 };
@@ -346,7 +346,7 @@ struct JShowerPDF_t {
    * The orientation of the PMT should be defined according this <a href="https://common.pages.km3net.de/jpp/JPDF.PDF">documentation</a>.\n
    * In this, the zenith and azimuth angles are limited to \f[\left[0, \pi\right]\f].
    *
-   * \param  E                  shower energy at minimum distance of approach [GeV]
+   * \param  E                  shower energy [GeV]
    * \param  D                  distance [m]
    * \param  cd                 cosine emission angle
    * \param  theta              PMT zenith  angle [rad]
diff --git a/src/jpp/JSystem/JDate.hh b/src/jpp/JSystem/JDate.hh
new file mode 100644
index 0000000..04d128b
--- /dev/null
+++ b/src/jpp/JSystem/JDate.hh
@@ -0,0 +1,298 @@
+#ifndef __JSYSTEM__JDATE__
+#define __JSYSTEM__JDATE__
+
+#include <time.h>
+#include <string>
+#include <istream>
+
+#include "JLang/JException.hh"
+
+/**
+ * \file
+ * Date and time functions.
+ * \author mdejong, bjung
+ */
+namespace JSYSTEM {}
+namespace JPP { using namespace JSYSTEM; }
+
+namespace JSYSTEM {
+  
+  /**
+   * Date and time formats.
+   */
+  enum JDateAndTimeFormat {
+    HUMAN_READABLE = 0,        //!< Human readable format (Www Mmm dd hh:mm:ss yyyy)
+    ISO8601        = 1         //!< ISO-8601 standard 
+  };
+  
+  
+  /**
+   * Get ASCII formatted date.
+   *
+   * \param  option   formatting option
+   * \return          date
+   */
+  inline const char* getDate(const JDateAndTimeFormat option = ISO8601)
+  {
+    static time_t    ts;
+    static const int        MAX_SIZE = 256;
+    static char      buffer[MAX_SIZE];
+
+    time(&ts);
+
+    switch (option) {
+      
+    case HUMAN_READABLE:
+      strftime(buffer, MAX_SIZE, "%x", localtime(&ts));
+      break;
+      
+    case ISO8601:
+      strftime(buffer, MAX_SIZE, "%F", localtime(&ts));
+      break;
+      
+    default:
+      THROW(JLANG::JValueOutOfRange, "JDate::getDate(): Invalid formatting option.");
+    }
+      
+    return buffer;
+  }
+
+  
+  /**
+   * Get ASCII formatted time.
+   *
+   * \param  option   formatting option
+   * \return          time
+   */
+  inline const char* getTime(const JDateAndTimeFormat option = ISO8601)
+  {
+    static time_t    ts;
+    static const int        MAX_SIZE = 256;
+    static char      buffer[MAX_SIZE];
+
+    time(&ts);
+
+    switch (option) {
+      
+    case HUMAN_READABLE:
+      strftime(buffer, MAX_SIZE, "%X %Z", localtime(&ts));
+      break;
+
+    case ISO8601:
+      strftime(buffer, MAX_SIZE, "%T%z", localtime(&ts));
+      break;
+
+    default:
+      THROW(JLANG::JValueOutOfRange, "JDate::getTime(): Invalid formatting option.");
+    }
+    
+    return buffer;
+  }
+
+
+  /**
+   * Auxililary class to get date and time.
+   */
+  struct JDateAndTime {
+    /**
+     * Default constructor.
+     */
+    JDateAndTime()
+    {
+      set();
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  t1       time
+     */
+    JDateAndTime(const time_t t1)
+    {
+      set(t1);
+    }
+
+
+    /**
+     * Smart pointer.
+     *
+     * \return          pointer to time structure
+     */
+    tm* operator->()
+    {
+      return tp;
+    }
+    
+
+    /**
+     * Smart pointer.
+     *
+     * \return          pointer to time structure
+     */
+    const tm* operator->() const
+    {
+      return tp;
+    }
+
+    int getSeconds() const { return tp->tm_sec; }           //!< seconds after the minute [0-59]
+    int getMinutes() const { return tp->tm_min; }           //!< minutes after the hour   [0-59]
+    int getHour()    const { return tp->tm_hour; }          //!< hours   after midnight   [0-23]
+    int getDay()     const { return tp->tm_mday; }          //!< day   of the month       [1-31]
+    int getMonth()   const { return tp->tm_mon  +    1; }   //!< month of the year        [1-12]
+    int getYear()    const { return tp->tm_year + 1900; }   //!< year a.d.
+
+
+    /**
+     * Type conversion operator.
+     *
+     * \return          ASCII formatted date and time
+     */
+    operator std::string() const
+    {
+      return toString();
+    }
+
+    
+    /**
+     * Function to check ISO-8601 conformity of string-formatted date and time.
+     *
+     * \param  datestr  string-formatted date and time
+     * \return          true if date and time are ISO-8601-conform; else false
+     */
+    inline static bool isISO8601(const std::string& datestr)
+    {
+      using namespace std;
+
+      const size_t pos = ( datestr.find('Z') != string::npos ? datestr.find('Z') :
+			  (datestr.find('+') != string::npos ? datestr.find('+') : datestr.find('-')) );
+
+      if (pos != string::npos) {
+	
+	static tm t;
+
+	const  string td = datestr.substr(0, pos);
+	const  string tz = datestr.substr(pos+1);
+	
+	const  char*  p0 = strptime(td.c_str(), "%FT%T", &t);
+	const  char*  p1 = ( tz.size() < 3 ? strptime(tz.c_str(), "%H",   &t) :
+			    (tz.size() < 5 ? strptime(tz.c_str(), "%H%M", &t) : strptime(tz.c_str(), "%H:%M", &t)) );
+
+	return ( (p0 != NULL && string(p0).empty()) && ((p1 != NULL && string(p1).empty()) || tz == "Z") );
+      }
+
+      return false;
+    }
+    
+
+    /**
+     * Get ASCII formatted date and time.
+     *
+     * \param  option   formatting option
+     * \return          ASCII formatted date and time
+     */
+    inline std::string toString(const JDateAndTimeFormat option = ISO8601) const
+    {
+      using namespace std;
+
+      mktime(tp);
+      
+      static const int        MAX_SIZE = 256;
+      static char      buffer[MAX_SIZE];
+      
+      switch (option) {
+	
+      case ISO8601:
+	strftime(buffer, MAX_SIZE, "%FT%T%z",           tp);
+	break;
+	
+      case HUMAN_READABLE:
+	strftime(buffer, MAX_SIZE, "%a %b %d %X %Z %Y", tp);
+	break;
+
+      default:
+	THROW(JLANG::JValueOutOfRange, "JDateAndTime::toString(): Invalid formatting option.");
+      }
+      
+      // remove the last character (carriage return) from the date string
+      
+      buffer[MAX_SIZE-1] = '\0';
+      
+      return string(buffer);
+    }
+
+
+    /**
+     * Set date and time.
+     *
+     * \return          date and time
+     */
+    inline const JDateAndTime& operator()() const
+    {
+      set();
+
+      return *this;
+    }
+
+
+    /**
+     * Set to actual time.
+     */
+    void set() const
+    {
+      time(&ts);
+
+      tp = localtime(&ts);
+    }
+
+
+    /**
+     * Set to given time.
+     *
+     * \param  t1       time
+     */
+    void set(const time_t t1) const
+    {
+      ts = t1;
+      tp = localtime(&t1);
+    }
+
+
+    /**
+     * Get elapsed time since given date and time.
+     *
+     * \param  object   date and time
+     * \return          time [s]
+     */
+    double getElapsedTime(const JDateAndTime& object) const
+    {
+      return difftime(this->ts, object.ts);
+    }
+
+
+    /**
+     * Write date and time to output.
+     *
+     * \param  out            output stream
+     * \param  object         date and time
+     * \return                output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JDateAndTime& object)
+    {
+      return out << object.toString();
+    }
+
+
+  private:
+    mutable time_t ts;
+    mutable tm*    tp;
+  };
+
+
+  /**
+   * Function object to get ASCII formatted date and time.
+   */
+  static JDateAndTime getDateAndTime;
+}
+
+#endif
diff --git a/src/jpp/JSystem/JStat.hh b/src/jpp/JSystem/JStat.hh
new file mode 100644
index 0000000..27dc0fb
--- /dev/null
+++ b/src/jpp/JSystem/JStat.hh
@@ -0,0 +1,177 @@
+#ifndef __JSYSTEM__JSTAT__
+#define __JSYSTEM__JSTAT__
+
+#include <sys/stat.h>
+#include <string>
+
+#include "JSystem/JDate.hh"
+#include "JLang/JAbstractObjectStatus.hh"
+
+
+/**
+ * \file
+ * File status.
+ * \author mdejong
+ */
+namespace JSYSTEM {}
+namespace JPP { using namespace JSYSTEM; }
+
+namespace JSYSTEM {
+
+  using JLANG::JAbstractObjectStatus;
+
+
+  /**
+   * Auxiliary class for file status.
+   * This class encapsulates the <tt>stat</tt> data structure.
+   */
+  struct JStat :
+    public stat,
+    public JAbstractObjectStatus
+  {
+    /**
+     * Default constructor.
+     */
+    JStat()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  file_name      file name
+     */
+    JStat(const char* file_name)
+    {
+      get(file_name);
+    }
+
+
+    /**
+     * Get status of object.
+     *
+     * \return                status of this object
+     */
+    virtual bool getStatus() const override 
+    {
+      return this->error == 0;
+    }
+     
+
+    /**
+     * Get status of file.
+     *
+     * \param  file_name      file name
+     * \return                file status
+     */
+    const JStat& get(const char* file_name) 
+    {
+      if (::stat(file_name, static_cast<stat*>(this)) != 0)
+	this->error = errno;
+      else
+	this->error = 0;
+
+      return *this;
+    }
+
+     
+    /**
+     * Get status of file.
+     *
+     * \param  file_name      file name
+     * \return                file status
+     */
+    const JStat& operator()(const char* file_name) 
+    {
+      return get(file_name);
+    }
+
+
+    /**
+     * Get UID of file.
+     *
+     * \return                UID
+     */
+    uid_t getUID() const
+    {
+      return this->st_uid;
+    }
+     
+
+    /**
+     * Get GID of file.
+     *
+     * \return                GID
+     */
+    uid_t getGID() const
+    {
+      return this->st_gid;
+    }
+     
+
+    /**
+     * Get size of file.
+     *
+     * \return                size [B]
+     */
+    off_t getSize() const
+    {
+      return this->st_size;
+    }
+     
+
+    /**
+     * Get time of last access.
+     *
+     * \return                date and time
+     */
+    JDateAndTime getTimeOfLastAccess() const
+    {
+      return JDateAndTime(this->st_atime);
+    }
+
+
+    /**
+     * Get time of last modification.
+     *
+     * \return                date and time
+     */
+    JDateAndTime getTimeOfLastModification() const
+    {
+      return JDateAndTime(this->st_mtime);
+    }
+
+
+    /**
+     * Get time of last change.
+     *
+     * \return                date and time
+     */
+    JDateAndTime getTimeOfLastChange() const
+    {
+      return JDateAndTime(this->st_ctime);
+    }
+
+
+    /**
+     * Get error of last call.
+     *
+     * \return                error
+     */
+    int getError() const
+    {
+      return this->error;
+    }
+
+    int error;  //!< error code from last call
+  };
+
+
+  /**
+   * Function object for file status.
+   */
+  static JStat getFileStatus;
+}
+
+#endif
+
diff --git a/src/jpp/JTools/JAbstractCollection.hh b/src/jpp/JTools/JAbstractCollection.hh
index 0145837..ba515aa 100644
--- a/src/jpp/JTools/JAbstractCollection.hh
+++ b/src/jpp/JTools/JAbstractCollection.hh
@@ -1,6 +1,8 @@
 #ifndef __JTOOLS__JABSTRACTCOLLECTION__
 #define __JTOOLS__JABSTRACTCOLLECTION__
 
+#include <math.h>
+
 
 /**
  * \author mdejong
@@ -10,13 +12,14 @@ namespace JTOOLS {}
 namespace JPP { using namespace JTOOLS; }
 
 namespace JTOOLS {
+  
 
   /**
    * Abstract interface for abscissa values of a collection of elements.
    */
   template<class JAbscissa_t>
-  struct JAbstractCollection {
-
+  struct JAbstractCollection
+  {
     typedef JAbscissa_t                                                   abscissa_type;
 
 
@@ -82,6 +85,33 @@ namespace JTOOLS {
 
       return false;
     }
+
+
+    /**
+     * Less than method.
+     *
+     * \param  first           first  abstract collection    
+     * \param  second          second abstract collection
+     * \return                 true if first collection is less than second collection; else false
+     */
+    friend inline bool operator<(const JAbstractCollection& first,
+				 const JAbstractCollection& second)
+    {
+      using namespace std;
+      
+      if (first.getSize() == second.getSize()) {
+
+	if (fabs(first.getXmin() - second.getXmin()) > 0.0) {
+	  return first.getXmin() < second.getXmin();
+	} else {
+	  return first.getXmax() < second.getXmax();
+	}
+	
+      } else {
+
+	return first.getSize() < second.getSize();
+      }
+    }
   };
 }
 
diff --git a/src/jpp/JTools/JAbstractHistogram.hh b/src/jpp/JTools/JAbstractHistogram.hh
new file mode 100644
index 0000000..15182bb
--- /dev/null
+++ b/src/jpp/JTools/JAbstractHistogram.hh
@@ -0,0 +1,177 @@
+#ifndef __JTOOLS__JABSTRACTHISTOGRAM__
+#define __JTOOLS__JABSTRACTHISTOGRAM__
+
+#include <istream>
+#include <ostream>
+
+#include "JTools/JRange.hh"
+#include "JTools/JGrid.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  /**
+   * Simple data structure for histogram binning.
+   */
+  template<class JAbscissa_t>
+  struct JAbstractHistogram :
+    public JRange<JAbscissa_t>
+  {
+
+    typedef JAbscissa_t               abscissa_type;
+    typedef JRange<abscissa_type>     range_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JAbstractHistogram() :
+      JRange<JAbscissa_t>(),
+      number_of_bins(0)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  nx              number of bins
+     * \param  xmin            lower limit
+     * \param  xmax            upper limit
+     */
+    JAbstractHistogram(const int           nx,
+		       const abscissa_type xmin,
+		       const abscissa_type xmax) :
+      JRange<JAbscissa_t>(xmin, xmax),
+      number_of_bins(nx)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  xmin            lower limit
+     * \param  xmax            upper limit
+     */
+    JAbstractHistogram(const abscissa_type xmin,
+		       const abscissa_type xmax) :
+      JRange<JAbscissa_t>(xmin, xmax),
+      number_of_bins(0)
+    {}
+
+
+    /**
+     * Get number of bins.
+     *
+     * \return                 number of bins
+     */
+    int getNumberOfBins() const
+    { 
+      return number_of_bins;
+    }
+
+
+    /**
+     * Get bin width.
+     *
+     * \return                 bin width
+     */
+    double getBinWidth() const
+    { 
+      return this->getLength() / this->getNumberOfBins();
+    }
+
+
+    /**
+     * Set bin width.
+     *
+     * If <tt>option < 0</tt>, adjust lower limit; if <tt>option > 0</tt>, adjust upper limit; else no adjustments.
+     *
+     * \param  dx              bin width
+     * \param  option          option
+     */
+    void setBinWidth(const abscissa_type dx, int option = 0)
+    { 
+      number_of_bins = (int) (this->getLength() / dx);
+
+      if (option < 0) { this->setLowerLimit(this->getUpperLimit() - number_of_bins + dx); }
+      if (option > 0) { this->setUpperLimit(this->getLowerLimit() + number_of_bins + dx); }
+    }
+
+
+    /**
+     * Check validity of histogram binning.
+     *
+     * \return                 true if both range and number of bins are valid; else false
+     */
+    bool is_valid() const
+    {
+      return static_cast<const range_type&>(*this).is_valid() && number_of_bins > 0;
+    }
+
+
+    /**
+     * Type conversion operator.
+     *
+     * \return                 grid
+     */
+    operator JGrid<abscissa_type> () const
+    {
+      return make_grid(this->getNumberOfBins() + 1, this->getLowerLimit(), this->getUpperLimit());
+    }
+
+    
+    /**
+     * Read histogram from input.
+     *
+     * \param  in              input stream
+     * \param  histogram       histogram
+     * \return                 input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JAbstractHistogram<JAbscissa_t>& histogram)
+    {
+      return in >> histogram.number_of_bins >> static_cast<range_type&>(histogram);
+    }
+
+
+    /**
+     * Write histogram to output.
+     *
+     * \param  out             output stream
+     * \param  histogram       histogram
+     * \return                 output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JAbstractHistogram<JAbscissa_t>& histogram)
+    {
+      return out << histogram.number_of_bins << ' ' << static_cast<const range_type&>(histogram);
+    }
+
+  protected:
+    int number_of_bins;
+  };
+
+
+  /**
+   * Helper method for JAbstractHistogram.
+   *
+   * \param  nx              number of bins
+   * \param  xmin            lower limit
+   * \param  xmax            upper limit
+   * \return                 histogram
+   */
+  template<class JAbscissa_t>
+  inline JAbstractHistogram<JAbscissa_t> make_histogram(const int         nx,
+							const JAbscissa_t xmin,
+							const JAbscissa_t xmax)
+  {
+    return JAbstractHistogram<JAbscissa_t>(nx, xmin, xmax);
+  }
+}
+
+#endif
diff --git a/src/jpp/JTools/JArray.hh b/src/jpp/JTools/JArray.hh
index 383b87a..c1e6095 100644
--- a/src/jpp/JTools/JArray.hh
+++ b/src/jpp/JTools/JArray.hh
@@ -59,7 +59,9 @@ namespace JTOOLS {
      * Default constructor.
      */
     JArray()
-    {}
+    {
+      fill(T());
+    }
 
 
     /**
@@ -255,7 +257,7 @@ namespace JTOOLS {
       if (index >= 0 && index < N)
 	return buffer[index];
       else
-	throw JIndexOutOfRange("JArray<>::at()");
+	THROW(JIndexOutOfRange, "invalid index " << 0 << " <= " << index << " < " << N);
     }
     
 
@@ -270,7 +272,7 @@ namespace JTOOLS {
       if (index >= 0 && index < N)
 	return buffer[index];
       else
-	throw JIndexOutOfRange("JArray<>::at()");
+	THROW(JIndexOutOfRange, "invalid index " << 0 << " <= " << index << " < " << N);
     }
 
 
@@ -329,6 +331,19 @@ namespace JTOOLS {
     }
 
 
+    /**
+     * Fill array.
+     *
+     * \param  value            value
+     */
+    void fill(argument_type value)
+    {
+      for (int i = 0; i != N; ++i) {
+	buffer[i] = value;
+      }
+    }
+
+
     /**
      * Negate array.
      *
@@ -659,7 +674,9 @@ namespace JTOOLS {
      * Default constructor.
      */
     JArray()
-    {}
+    {
+      fill(T());
+    }
 
 
     /**
@@ -722,11 +739,11 @@ namespace JTOOLS {
     /**
      * Initialise constructor.
      *
-     * \param  x                value;
+     * \param  value            value;
      */
-    JArray(argument_type x)
+    JArray(argument_type value)
     {
-      buffer[0] = x;
+      buffer[0] = value;
     }
 
 
@@ -778,10 +795,10 @@ namespace JTOOLS {
      */
     const_reference at(int index) const 
     { 
-      if (index >= 0 && index < N)
+      if (index == 0)
 	return buffer[index];
       else
-	throw JIndexOutOfRange("JArray<>::at()");
+	THROW(JIndexOutOfRange, "invalid index " << 0 << " <= " << index << " < " << N);
     }
     
 
@@ -793,10 +810,10 @@ namespace JTOOLS {
      */
     reference at(int index)
     { 
-      if (index >= 0 && index < N)
+      if (index == 0)
 	return buffer[index];
       else
-	throw JIndexOutOfRange("JArray<>::at()");
+	THROW(JIndexOutOfRange, "invalid index " << 0 << " <= " << index << " < " << N);
     }
 
 
@@ -833,6 +850,17 @@ namespace JTOOLS {
     }
 
 
+    /**
+     * Fill array.
+     *
+     * \param  value            value
+     */
+    void fill(argument_type value)
+    {
+      buffer[0] = value;
+    }
+
+
     /**
      * Negate array.
      *
@@ -1053,7 +1081,7 @@ namespace JTOOLS {
       if (index >= 0 && index < N)
 	return p[index];
       else
-	throw JIndexOutOfRange("JArray<>::at()");
+	THROW(JIndexOutOfRange, "invalid index " << 0 << " <= " << index << " < " << N);
     }
 
 
@@ -1209,7 +1237,7 @@ namespace JTOOLS {
       if (index >= 0 && index < N)
 	return p[index];
       else
-	throw JIndexOutOfRange("JArray<>::at()");
+	THROW(JIndexOutOfRange, "invalid index " << 0 << " <= " << index << " < " << N);
     }
 
 
diff --git a/src/jpp/JTools/JCollection.hh b/src/jpp/JTools/JCollection.hh
index a366cc3..916489d 100644
--- a/src/jpp/JTools/JCollection.hh
+++ b/src/jpp/JTools/JCollection.hh
@@ -266,13 +266,11 @@ namespace JTOOLS {
      */
     void transform(const transformer_type& transformer)
     {
-      collection_type buffer;
-
-      this->swap(buffer);
-
-      for (const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
-        this->insert(transformer(*i));
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+        *i = transformer(*i);
       }
+      
+      sort();
     }
 
 
@@ -724,12 +722,13 @@ namespace JTOOLS {
     {
       int n;
 
-      in >> n;
+      if (in >> n) {
 
-      collection.resize(n);
+	collection.resize(n);
 
-      for (typename JCollection::iterator i = collection.begin(); i != collection.end(); ++i) {
-        in >> *i;
+	for (typename JCollection::iterator i = collection.begin(); i != collection.end(); ++i) {
+	  in >> *i;
+	}
       }
 
       return in;
diff --git a/src/jpp/JTools/JGrid.hh b/src/jpp/JTools/JGrid.hh
index aeb6b45..6b4b8af 100644
--- a/src/jpp/JTools/JGrid.hh
+++ b/src/jpp/JTools/JGrid.hh
@@ -4,9 +4,12 @@
 #include <istream>
 #include <ostream>
 
-#include "JTools/JAbstractCollection.hh"
 #include "JLang/JClass.hh"
 
+#include "JIO/JSerialisable.hh"
+
+#include "JTools/JAbstractCollection.hh"
+
 
 /**
  * \author mdejong
@@ -17,6 +20,9 @@ namespace JPP { using namespace JTOOLS; }
 
 namespace JTOOLS {
 
+  using JIO::JReader;
+  using JIO::JWriter;
+  
   using JLANG::JClass;
 
   template<class JElement_t, class JDistance_t>
@@ -80,7 +86,7 @@ namespace JTOOLS {
      */
     virtual abscissa_type getX(int index) const override 
     {
-      return xmin  +  index * ((xmax - xmin) / (size - 1));
+      return (index == 0 ? xmin : xmin + index * ((xmax - xmin) / (size - 1)));
     }
 
     
@@ -132,6 +138,32 @@ namespace JTOOLS {
       return *this;
     }
 
+
+    /**
+     * Binary stream input.
+     *
+     * \param  in              input stream
+     * \param  grid            grid
+     * \return                 input stream
+     */
+    friend inline JReader& operator>>(JReader& in, JGrid<JAbscissa_t>& grid)
+    {
+      return in >> grid.size >> grid.xmin >> grid.xmax;
+    }
+
+
+    /**
+     * Binary stream output.
+     *
+     * \param  out             output stream
+     * \param  grid            grid
+     * \return                 output stream
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JGrid<JAbscissa_t>& grid)
+    {
+      return out << grid.size << grid.xmin << grid.xmax;
+    }    
+    
     
     /**
      * Read grid from input.
@@ -180,6 +212,19 @@ namespace JTOOLS {
   {
     return JGrid<JAbscissa_t>(nx, Xmin, Xmax);
   }
+
+
+  /**
+   * Helper method to create a grid with a single value.
+   *
+   * \param  value           value
+   * \return                 single-valued grid
+   */
+  template<class JAbscissa_t>
+  inline JGrid<JAbscissa_t> make_grid(const JAbscissa_t value)
+  {
+    return JGrid<JAbscissa_t>(1, value, value);
+  }  
 }
 
 #endif
diff --git a/src/jpp/JTools/JGridMap.hh b/src/jpp/JTools/JGridMap.hh
index 61b04fe..c4d37b8 100644
--- a/src/jpp/JTools/JGridMap.hh
+++ b/src/jpp/JTools/JGridMap.hh
@@ -3,6 +3,7 @@
 
 #include "JTools/JGridCollection.hh"
 #include "JTools/JMapCollection.hh"
+#include "JTools/JElement.hh"
 
 
 /**
diff --git a/src/jpp/JTools/JHermiteSpline.hh b/src/jpp/JTools/JHermiteSpline.hh
index e908e0a..e9ebd19 100644
--- a/src/jpp/JTools/JHermiteSpline.hh
+++ b/src/jpp/JTools/JHermiteSpline.hh
@@ -212,12 +212,12 @@ namespace JTOOLS {
      */
     virtual result_type evaluate(const argument_type* pX) const override 
     {
+      const argument_type x = *pX;
+
       if (this->size() <= 1u) {
-        return this->getExceptionHandler().action(JFunctionalException("JHermiteSplineFunction<>::evaluate() not enough data."));
+        return this->getExceptionHandler().action(MAKE_EXCEPTION(JFunctionalException, "not enough data " << STREAM("?") << x));
       }
 
-      const argument_type x = *pX;
-
       const_iterator p = this->lower_bound(x);
 
       if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
@@ -292,12 +292,12 @@ namespace JTOOLS {
      */
     virtual result_type evaluate(const argument_type* pX) const override 
     {
+      const argument_type x = *pX;
+
       if (this->size() <= 1u) {
-        return this->getExceptionHandler().action(JFunctionalException("JHermiteSplineFunction<>::evaluate() not enough data."));
+        return this->getExceptionHandler().action(MAKE_EXCEPTION(JFunctionalException, "not enough data " << STREAM("?") << x));
       }
 
-      const argument_type x = *pX;
-
       const_iterator p = this->lower_bound(x);
 
 
@@ -392,11 +392,11 @@ namespace JTOOLS {
      */
     virtual result_type evaluate(const argument_type* pX) const override 
     {
+      const argument_type x = *pX;
+
       if (this->size() <= 1u) {
-        return this->getExceptionHandler().action(JFunctionalException("JHermiteSplineFunction<>::evaluate() not enough data."));
+        return this->getExceptionHandler().action(MAKE_EXCEPTION(JFunctionalException, "not enough data " << STREAM("?") << x));
       }
-      
-      const argument_type x = *pX;
 
       const_iterator p = this->lower_bound(x);
 
diff --git a/src/jpp/JTools/JHistogram.hh b/src/jpp/JTools/JHistogram.hh
index 224f5e6..5a4a539 100644
--- a/src/jpp/JTools/JHistogram.hh
+++ b/src/jpp/JTools/JHistogram.hh
@@ -50,6 +50,17 @@ namespace JTOOLS {
     {}
 
 
+    /**
+     * Reset.
+     */
+    void reset()
+    {
+      this->underflow = JMATH::zero;
+      this->overflow  = JMATH::zero;
+      this->integral  = JMATH::zero;
+    }
+
+
     /**
      * Histogram filling.
      *
diff --git a/src/jpp/JTools/JHistogram1D.hh b/src/jpp/JTools/JHistogram1D.hh
new file mode 100644
index 0000000..344e1dc
--- /dev/null
+++ b/src/jpp/JTools/JHistogram1D.hh
@@ -0,0 +1,650 @@
+#ifndef __JHISTOGRAM1D__
+#define __JHISTOGRAM1D__
+
+#include "JTools/JHistogram.hh"
+#include "JTools/JDistance.hh"
+#include "JTools/JAbstractHistogram.hh"
+#include "JTools/JAbstractCollection.hh"
+#include "JTools/JCollection.hh"
+#include "JTools/JElement.hh"
+#include "JMath/JMath.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JMATH::JMath;
+  using JLANG::JClass;
+
+
+  /**
+   * Auxiliary class for merging of fixed number of consecutive bins.
+   */
+  template<class JElement_t>
+  struct JRebin {
+
+    typedef JElement_t                                   value_type;
+    typedef typename JElement_t::ordinate_type           contents_type;
+
+
+    /**
+     * Constructor.
+     *
+     * \param  n               number of bins to merge
+     */
+    JRebin(const int n) :
+      __n(n > 1 ? n : 1),
+      __i(0)
+      {}
+    
+    
+    /**
+     * Test whether bins should be merged.
+     *
+     * \param  first           first  bin
+     * \param  second          second bin
+     * \return                 true if bins should be merged; else false
+     */
+    bool operator()(const value_type& first, const value_type& second) const
+    {
+      return (__n != 1 && ++__i%__n != 0);
+    }
+    
+  private:
+    const   int __n;
+    mutable int __i;
+  };
+  
+  
+  /**
+   * Auxiliary class for merging of consecutive bins until minimal content is reached.
+   */
+  template<class JElement_t>
+  struct JContent {
+
+    typedef JElement_t                                   value_type;
+    typedef typename JElement_t::ordinate_type           contents_type;
+
+
+    /**
+     * Constructor.
+     *
+     * \param  y               minimal content
+     */
+    JContent(const contents_type y) :
+      __y(y)
+    {}
+    
+    
+    /**
+     * Test whether bins should be merged.
+     *
+     * \param  first           first  bin
+     * \param  second          second bin
+     * \return                 true if bins should be merged; else false
+     */
+    bool operator()(const value_type& first, const value_type& second) const
+    {
+      return (first.getY() + second.getY() < __y);
+    }
+    
+  private:
+    const contents_type __y;
+  };
+  
+
+
+  /**
+   * Histogram in 1D.
+   *
+   * This class implements the JHistogram interface.
+   */
+  template<class JElement_t,
+	   template<class, class> class JContainer_t,
+	   class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  class JHistogram1D :
+    public JContainer_t<JElement_t, JDistance_t>,
+    public JHistogram<typename JElement_t::abscissa_type, typename JElement_t::ordinate_type>,
+    public JMath< JHistogram1D<JElement_t, JContainer_t, JDistance_t> >
+  {
+  public:
+
+    enum { NUMBER_OF_DIMENSIONS = 1 };
+
+    typedef JContainer_t<JElement_t, JDistance_t>                                collection_type;
+
+    typedef typename collection_type::abscissa_type                              abscissa_type;
+    typedef typename collection_type::ordinate_type                              ordinate_type;
+    typedef typename collection_type::value_type                                 value_type;
+
+    typedef typename collection_type::const_iterator                             const_iterator;
+    typedef typename collection_type::const_reverse_iterator                     const_reverse_iterator;
+    typedef typename collection_type::iterator                                   iterator;
+    typedef typename collection_type::reverse_iterator                           reverse_iterator;
+
+    typedef JHistogram<abscissa_type, ordinate_type>                             histogram_type;
+
+    typedef typename histogram_type::contents_type                               contents_type;
+
+    typedef JTOOLS::JRebin  <value_type>                                         JRebin;
+    typedef JTOOLS::JContent<value_type>                                         JContent;
+
+
+    /**
+     * Default constructor.
+     */
+    JHistogram1D()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  bounds          bounds
+     */
+    JHistogram1D(const JAbstractHistogram<abscissa_type>& bounds)
+    {
+      this->configure(bounds);
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  bounds          bounds
+     */
+    JHistogram1D(const JAbstractCollection<abscissa_type>& bounds)
+    {
+      this->configure(bounds);
+    }
+
+
+    /**
+     * Reset.
+     */
+    void reset()
+    {
+      histogram_type::reset();
+
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	i->getY() = JMATH::zero;
+      }
+    }
+
+
+    /**
+     * Fill histogram.
+     *
+     * \param  pX              pointer to abscissa values
+     * \param  w               weight
+     */
+    virtual void evaluate(const abscissa_type* pX,
+			  typename JClass<contents_type>::argument_type w)
+    {
+      this->fill(*pX, w);
+    }
+
+
+    /**
+     * Fill histogram.
+     *
+     * \param  x               abscissa value
+     * \param  w               weight
+     */
+    void fill(typename JClass<abscissa_type>::argument_type x, 
+	      typename JClass<contents_type>::argument_type w)
+    {
+      this->integral  += w;
+
+      iterator p = this->lower_bound(x);
+	
+      if      (p == this->begin())
+	this->underflow += w;
+      else if (p == this->end())
+	this->overflow  += w;
+      else
+	(--p)->getY()   += w;
+    }
+
+    
+    /**
+     * Rebin histogram.
+     *
+     * \param  merge           rebin evaluator
+     */
+    template<class JRebin_t>
+    void rebin(JRebin_t merge)
+    {
+      if (this->size() > 1u) {
+
+	iterator out = this->begin();
+
+	for (const_iterator i = this->begin(); i != this->end(); ) {
+
+	  *out = *i;
+
+	  while (++i != this->end() && merge(*out,*i)) {
+	    out->getY() += i->getY();
+	  }
+
+	  ++out;
+	}
+
+	const_reverse_iterator __rbegin(out);
+
+	if (this->getDistance(__rbegin->getX(), this->rbegin()->getX()) > 0.0) {
+
+	  *out = *(this->rbegin());
+
+	  ++out;
+	}
+
+	this->resize(std::distance(this->begin(), out));
+      }
+    }
+
+
+    /**
+     * Add histogram.
+     *
+     * \param  histogram       histogram
+     * \return                 this histogram
+     */
+    JHistogram1D& add(const JHistogram1D& histogram)
+    {
+      collection_type::add(static_cast<const collection_type&>(histogram));
+      histogram_type ::add(static_cast<const histogram_type&> (histogram));
+
+      return *this;
+    }
+
+
+    /**
+     * Subtract histogram.
+     *
+     * \param  histogram       histogram
+     * \return                 this histogram
+     */
+    JHistogram1D& sub(const JHistogram1D& histogram)
+    {
+      collection_type::sub(static_cast<const collection_type&>(histogram));
+      histogram_type ::sub(static_cast<const histogram_type&> (histogram));
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           multiplication factor
+     * \return                 this histogram
+     */
+    JHistogram1D& mul(const double value)
+    {
+      collection_type::mul(value);
+      histogram_type ::mul(value);
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           division factor
+     * \return                 this histogram
+     */
+    JHistogram1D& div(const double value)
+    {
+      collection_type::div(value);
+      histogram_type ::div(value);
+
+      return *this;
+    }
+    
+
+    /**
+     * Read histogram from input.
+     *
+     * \param  in              reader
+     * \param  object          histogram
+     * \return                 reader
+     */
+    friend inline JReader& operator>>(JReader& in, JHistogram1D& object)
+    {
+      in >> static_cast<histogram_type&> (object);
+      in >> static_cast<collection_type&>(object);
+      
+      return in;
+    }
+
+
+    /**
+     * Write histogram to output.
+     *
+     * \param  out             writer
+     * \param  object          histogram
+     * \return                 writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JHistogram1D& object)
+    {
+      out << static_cast<const histogram_type&> (object);
+      out << static_cast<const collection_type&>(object);
+
+      return out;
+    }
+  };
+
+
+  /**
+   * Template specialisation if JHistogram1D class with bin centering.
+   *
+   * This class implements the JHistogram interface.
+   */
+  template<class JAbscissa_t,
+	   class JContents_t,
+	   template<class, class> class JContainer_t,
+	   class JDistance_t>
+  class JHistogram1D<JBin2D<JAbscissa_t, JContents_t>, JContainer_t, JDistance_t> :
+    public JContainer_t<JBin2D<JAbscissa_t, JContents_t>, JDistance_t>,
+    public JHistogram<JAbscissa_t, JContents_t>,
+    public JMath< JHistogram1D<JBin2D<JAbscissa_t, JContents_t>, JContainer_t, JDistance_t> >
+  {
+  public:
+
+    enum { NUMBER_OF_DIMENSIONS = 1 };
+
+    typedef JBin2D<JAbscissa_t, JContents_t>                                     element_type;
+    typedef JContainer_t<element_type, JDistance_t>                              collection_type;
+
+    typedef typename collection_type::abscissa_type                              abscissa_type;
+    typedef typename collection_type::ordinate_type                              ordinate_type;
+    typedef typename collection_type::value_type                                 value_type;
+
+    typedef typename collection_type::const_iterator                             const_iterator;
+    typedef typename collection_type::const_reverse_iterator                     const_reverse_iterator;
+    typedef typename collection_type::iterator                                   iterator;
+    typedef typename collection_type::reverse_iterator                           reverse_iterator;
+
+    typedef JHistogram<abscissa_type, ordinate_type>                             histogram_type;
+
+    typedef typename histogram_type::contents_type                               contents_type;
+
+    typedef JTOOLS::JRebin  <value_type>                                         JRebin;
+    typedef JTOOLS::JContent<value_type>                                         JContent;
+
+
+    /**
+     * Default constructor.
+     */
+    JHistogram1D()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  bounds          bounds
+     */
+    JHistogram1D(const JAbstractCollection<abscissa_type>& bounds)
+    {
+      this->set(bounds);
+    }
+
+
+    /**
+     * Fill histogram.
+     *
+     * \param  pX              pointer to abscissa values
+     * \param  w               weight
+     */
+    virtual void evaluate(const abscissa_type* pX,
+			  typename JClass<contents_type>::argument_type w)
+    {
+      this->fill(*pX, w);
+    }
+
+
+    /**
+     * Fill histogram.
+     *
+     * \param  x               abscissa value
+     * \param  w               weight
+     */
+    void fill(typename JClass<abscissa_type>::argument_type x, 
+	      typename JClass<contents_type>::argument_type w)
+    {
+      this->integral  += w;
+
+      iterator p = this->lower_bound(x);
+	
+      if      (p == this->begin())
+	this->underflow += w;
+      else if (p == this->end())
+	this->overflow  += w;
+      else
+	(--p)->fill(x, w);
+    }
+
+    
+    /**
+     * Rebin histogram.
+     *
+     * \param  merge           rebin evaluator
+     */
+    template<class JRebin_t>
+    void rebin(JRebin_t merge)
+    {
+      if (this->size() > 1u) {
+      
+	iterator out = this->begin();
+
+	for (const_iterator i = this->begin(); i != this->end(); ) {
+
+	  *out = *i;
+
+	  while (++i != this->end() && merge(*out,*i)) {
+	    out->add(*i);
+	  }
+
+	  ++out;
+	}
+
+	const_reverse_iterator __rbegin(out);
+
+	if (getDistance(__rbegin->getX(), this->rbegin()->getX()) > 0.0) {
+
+	  *out = *(this->rbegin());
+
+	  ++out;
+	}
+
+	this->resize(std::distance(this->begin(), out));
+      }
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           multiplication factor
+     */
+    JHistogram1D& mul(const double value)
+    {
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	i->mul(value);
+      }
+
+      histogram_type::mul(value);
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           division factor
+     */
+    JHistogram1D& div(const double value)
+    {
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	i->div(value);
+      }
+
+      histogram_type::div(value);
+
+      return *this;
+    }
+
+
+    /**
+     * Read histogram from input.
+     *
+     * \param  in              reader
+     * \param  object          histogram
+     * \return                 reader
+     */
+    friend inline JReader& operator>>(JReader& in, JHistogram1D& object)
+    {
+      in >> static_cast<histogram_type&> (object);
+      in >> static_cast<collection_type&>(object);
+      
+      return in;
+    }
+
+
+    /**
+     * Write histogram to output.
+     *
+     * \param  out             writer
+     * \param  object          histogram
+     * \return                 writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JHistogram1D& object)
+    {
+      out << static_cast<const histogram_type&> (object);
+      out << static_cast<const collection_type&>(object);
+
+      return out;
+    }
+
+  private:
+    /**
+     * Make methods inaccessible.
+     */
+    JHistogram1D& add(const JHistogram1D& histogram);   //!< addition    not allowed with bin centering
+    JHistogram1D& sub(const JHistogram1D& histogram);   //!< subtraction not allowed with bin centering
+  };
+
+
+  /**
+   * Conversion of histogram to probability density function (PDF).
+   *
+   * The PDF abscissa and contents are set to the bin center and contents divided the bin width, respectively.
+   *
+   * \param  input             histogram
+   * \param  output            mappable collection
+   */
+  template<class JElement_t, 
+	   template<class, class> class JContainer_t,
+	   class JDistance_t>
+  inline void makePDF(const JHistogram1D<JElement_t, JContainer_t, JDistance_t>& input, 
+		      typename JMappable<JElement_t>::map_type&                  output)
+  {
+    typedef typename JElement_t::abscissa_type                                            abscissa_type;
+    typedef typename JElement_t::ordinate_type                                            ordinate_type;
+    typedef typename JHistogram1D<JElement_t, JContainer_t, JDistance_t>::const_iterator  const_iterator;
+    
+    if (input.getSize() > 1) {
+      
+      for (const_iterator j = input.begin(), i = j++; j != input.end(); ++i, ++j) {
+	
+	const abscissa_type x = 0.5 * (i->getX() + j->getX());
+	const ordinate_type y = i->getY();
+	const double        w = input.getDistance(i->getX(), j->getX());
+	
+	output.put(x, y/w);
+      }
+    }
+  }
+  
+
+  /**
+   * Conversion of histogram to probability density function (PDF).
+   *
+   * The PDF abscissa and contents are set to the bin center and contents divided the bin width, respectively.
+   *
+   * \param  input             histogram
+   * \param  output            mappable collection
+   */
+  template<class JAbscissa_t,
+	   class JContents_t,
+	   template<class, class> class JContainer_t,
+	   class JDistance_t>
+  inline void makePDF(const JHistogram1D<JBin2D<JAbscissa_t, JContents_t>, JContainer_t, JDistance_t>& input, 
+		      JMappableCollection<JAbscissa_t, JContents_t>&                                   output)
+  {
+    typedef JAbscissa_t                                                                                         abscissa_type;
+    typedef JContents_t                                                                                         contents_type;
+    typedef typename JHistogram1D<JBin2D<JAbscissa_t, JContents_t>, JContainer_t, JDistance_t>::const_iterator  const_iterator;
+    
+    if (input.getSize() > 1) {
+      
+      for (const_iterator j = input.begin(), i = j++; j != input.end(); ++i, ++j) {
+	
+	const abscissa_type x = i->getBinCenter();
+	const contents_type y = i->getY();
+	const double        w = input.getDistance(i->getX(), j->getX());
+	
+	output.put(x, y/w);
+      }
+    }
+  }
+
+
+  /**
+   * Conversion of data points to integral values.
+   *
+   * The integration is based on the sum of bin contents of the input data points.
+   *
+   * \param  input             histogram
+   * \param  output            mappable collection
+   * \return                   integral
+   */
+  template<class JElement_t,
+           template<class, class> class JContainer_t,
+           class JDistance_t>
+  inline typename JElement_t::ordinate_type
+  integrate(const JHistogram1D<JElement_t, JContainer_t, JDistance_t>& input, 
+	    typename JMappable<JElement_t>::map_type&                  output)
+  {
+    typedef typename JElement_t::ordinate_type                                            ordinate_type;
+    typedef typename JHistogram1D<JElement_t, JContainer_t, JDistance_t>::const_iterator  const_iterator;
+    
+    ordinate_type V(JMATH::zero);
+    
+    if (input.getSize() > 1) {
+      
+      output.put(input.begin()->getX(), V);
+      
+      for (const_iterator j = input.begin(), i = j++; j != input.end(); ++i, ++j) {
+        
+        V += i->getY();
+
+        output.put(j->getX(), V);
+      }
+    }
+    
+    return V;
+  }
+}
+
+#endif
diff --git a/src/jpp/JTools/JMultiFunction.hh b/src/jpp/JTools/JMultiFunction.hh
index 715fed8..fdd2741 100644
--- a/src/jpp/JTools/JMultiFunction.hh
+++ b/src/jpp/JTools/JMultiFunction.hh
@@ -7,6 +7,7 @@
 #include "JTools/JArray.hh"
 #include "JTools/JMultiHistogram.hh"
 #include "JTools/JHistogramMap.hh"
+#include "JTools/JHistogram1D.hh"
 
 
 /**
@@ -49,9 +50,8 @@ namespace JTOOLS {
 
     typedef JFunction_t                                                   function_type;
 
-    typedef typename JFunction_t::value_type                              value_type;
-    typedef typename JFunction_t::argument_type                           argument_type;
-    typedef typename JFunction_t::supervisor_type                         supervisor_type;
+    typedef typename function_type::value_type                            value_type;
+    typedef typename function_type::argument_type                         argument_type;
 
     typedef typename multimap_type::abscissa_type                         abscissa_type;
     typedef typename multimap_type::ordinate_type                         ordinate_type;
@@ -65,6 +65,7 @@ namespace JTOOLS {
     typedef typename multimap_type::super_iterator                        super_iterator;
     typedef typename multimap_type::super_const_iterator                  super_const_iterator;
 
+    using JFunctional<abscissa_type, result_type>::setExceptionHandler;
     using multimap_type::insert;
 
 
@@ -116,8 +117,8 @@ namespace JTOOLS {
      *
      * \param  input                multidimensional function
      */
-    template<class JPDF_t, class JPDFMaplist_t, class JPDFDistance_t>    
-    void insert(const JMultiFunction<JPDF_t, JPDFMaplist_t, JPDFDistance_t>& input) 
+    template<class __JFunction_t, class __JMaplist_t, class __JDistance_t>    
+    void insert(const JMultiFunction<__JFunction_t, __JMaplist_t, __JDistance_t>& input) 
     {
       copy(input, *this);
     }
@@ -128,8 +129,8 @@ namespace JTOOLS {
      *
      * \param  input                multidimensional histogram
      */
-    template<class JHistogram_t, class JHistogramMaplist_t, class JHistogramDistance_t>
-    void insert(const JMultiHistogram<JHistogram_t, JHistogramMaplist_t, JHistogramDistance_t>& input)
+    template<class JHistogram_t, class __JMaplist_t, class __JDistance_t>
+    void insert(const JMultiHistogram<JHistogram_t, __JMaplist_t, __JDistance_t>& input)
     {
       this->insert(JMultiKey<0, argument_type>(), input);
     }
@@ -153,7 +154,7 @@ namespace JTOOLS {
      *
      * \param  supervisor      supervisor
      */
-    void setExceptionHandler(const supervisor_type& supervisor)
+    void setExceptionHandler(const typename function_type::supervisor_type& supervisor)
     {
       this->for_each(supervisor);
 
@@ -172,11 +173,15 @@ namespace JTOOLS {
     template<class ...Args>
     result_type operator()(const Args& ...args) const
     {
-      return this->evaluate(JArray<NUMBER_OF_DIMENSIONS, argument_type>(args...).data());
+      buffer.set(args...);
+
+      return this->evaluate(buffer.data());
     }
 
 
   protected:
+    mutable JArray<NUMBER_OF_DIMENSIONS, argument_type> buffer;
+
     /**
      * Insert multidimensional histogram at multidimensional key.
      *
@@ -193,7 +198,7 @@ namespace JTOOLS {
     {
       if (input.size() > 1) {
 
-	for (typename JHistogramMap<__JAbscissa_t, __JContents_t, __JMap_t, __JDistance_t>::const_iterator j = input.begin(), i = j++; j != input.end(); ++i, ++j) {
+	for (auto j = input.begin(), i = j++; j != input.end(); ++i, ++j) {
 	  
 	  const argument_type x = 0.5 * (i->getX() + j->getX());
 
@@ -201,7 +206,7 @@ namespace JTOOLS {
 	}
       }
     }
- 
+
 
     /**
      * Convert one-dimensional histogram to PDF and insert result at given multidimensional key.
@@ -209,9 +214,28 @@ namespace JTOOLS {
      * \param  key                  multidimensional key
      * \param  input                histogram
      */
-    template<class __JValue_t>
-    void insert(const JMultiKey<JMapLength<JMaplist_t>::value, argument_type>& key, 
-		const __JValue_t&                                              input)
+    template<class __JElement_t, template<class, class> class __JContainer_t, class __JDistance_t>
+    void insert(const JMultiKey<JMapLength<JMaplist_t>::value, argument_type>&   key, 
+		const JHistogram1D<__JElement_t, __JContainer_t, __JDistance_t>& input)
+ 
+    {
+      JFunction_t buffer;
+      
+      makePDF(input, buffer);
+      
+      multimap_type::insert(key, buffer);
+    }    
+
+
+    /**
+     * Convert multidimensional histogram to PDF and insert result at given multidimensional key.
+     *
+     * \param  key                  multidimensional key
+     * \param  input                multidimensional histogram
+     */
+    template<class JHistogram_t, class __JMaplist_t, class __JDistance_t>
+    void insert(const JMultiKey<JMapLength<JMaplist_t>::value, argument_type>&    key, 
+		const JMultiHistogram<JHistogram_t, __JMaplist_t, __JDistance_t>& input)
     {
       JFunction_t buffer;
       
@@ -232,7 +256,7 @@ namespace JTOOLS {
            class JDistance_t>
   class JMultiFunction<JConstantFunction1D<JArgument_t, JResult_t>, JMapList<JMap_t>, JDistance_t> :
     public JMap_t<JArgument_t, JResult_t, JDistance_t>,
-    public JFunction1D<JArgument_t, JResult_t>
+    public JFunction1D<JArgument_t, typename JMap_t<JArgument_t, JResult_t, JDistance_t>::result_type>
   {
   public:
 
diff --git a/src/jpp/JTools/JMultiKey.hh b/src/jpp/JTools/JMultiKey.hh
index 419ad0a..1722152 100644
--- a/src/jpp/JTools/JMultiKey.hh
+++ b/src/jpp/JTools/JMultiKey.hh
@@ -71,14 +71,14 @@ namespace JTOOLS {
 
     typedef JKey_t                                               key_type;
     typedef JMultiKey<N-1, JKey_t>                               mapped_type;
-    typedef std::pair<key_type, mapped_type>                     pair;
+    typedef std::pair<key_type, mapped_type>                     pair_type;
 
 
     /**
      * Default constructor.
      */
     JMultiKey() :
-      pair()
+      pair_type()
     {}
 
 
@@ -91,7 +91,7 @@ namespace JTOOLS {
      */
     JMultiKey(typename JClass<mapped_type>::argument_type __first,
 	      typename JClass<key_type>   ::argument_type __second) :
-      pair(__first.first, mapped_type(__first.second, __second))
+      pair_type(__first.first, mapped_type(__first.second, __second))
     {}
 
 
@@ -104,7 +104,7 @@ namespace JTOOLS {
      */
     JMultiKey(typename JClass<key_type>   ::argument_type __first,
 	      typename JClass<mapped_type>::argument_type __second) :	      
-      pair(__first, __second)
+      pair_type(__first, __second)
     {}
 
 
@@ -114,7 +114,7 @@ namespace JTOOLS {
      * \param   key          key
      */
     JMultiKey(typename JArgument<N, JKey_t>::argument_type key) :
-      pair(key.first, key.second)
+      pair_type(key.first, key.second)
     {}
 
 
@@ -225,14 +225,14 @@ namespace JTOOLS {
 
     typedef JKey_t                                               key_type;
     typedef JMultiKey<1, JKey_t>                                 mapped_type;
-    typedef std::pair<key_type, mapped_type>                     pair;
+    typedef std::pair<key_type, mapped_type>                     pair_type;
 
 
     /**
      * Default constructor.
      */
     JMultiKey() :
-      pair()
+      pair_type()
     {}
 
 
@@ -245,7 +245,7 @@ namespace JTOOLS {
      */
     JMultiKey(typename JClass<mapped_type>::argument_type __first,
 	      typename JClass<key_type>   ::argument_type __second) :
-      pair(__first.first, __second)
+      pair_type(__first.first, __second)
     {}
 
 
@@ -258,7 +258,7 @@ namespace JTOOLS {
      */
     JMultiKey(typename JClass<key_type>   ::argument_type __first,
 	      typename JClass<mapped_type>::argument_type __second) :
-      pair(__first, __second.first)
+      pair_type(__first, __second.first)
     {}
 
 
@@ -268,7 +268,7 @@ namespace JTOOLS {
      * \param   key          key
      */
     JMultiKey(typename JArgument<2, JKey_t>::argument_type key) :
-      pair(key.first, key.second)
+      pair_type(key.first, key.second)
     {}
 
 
diff --git a/src/jpp/JTools/JMultiMap.hh b/src/jpp/JTools/JMultiMap.hh
index d1ff254..a6cc8ca 100644
--- a/src/jpp/JTools/JMultiMap.hh
+++ b/src/jpp/JTools/JMultiMap.hh
@@ -1,23 +1,23 @@
 #ifndef __JTOOLS__JMULTIMAP__
 #define __JTOOLS__JMULTIMAP__
 
-#include "JLang/JSinglePointer.hh"
 #include "JLang/JEquals.hh"
 #include "JLang/JForwardIterator.hh"
 
+#include "JMath/JMath.hh"
+
 #include "JTools/JDistance.hh"
 #include "JTools/JPair.hh"
 #include "JTools/JMultiPair.hh"
 #include "JTools/JMapList.hh"
 #include "JTools/JAbstractMultiMap.hh"
 #include "JTools/JMultiKey.hh"
-#include "JMath/JMath.hh"
 
 
 /**
  * \file
  *
- * JMultiMap is a general purpose multidimensional map based on a type list of maps.
+ * General purpose multidimensional map based on a type list of maps.
  * \author mdejong
  */
 namespace JTOOLS {}
@@ -38,11 +38,12 @@ namespace JTOOLS {
    * the third to the list of maps used; and
    * the fourth to the distance operator.
    *
-   * In addition to the standard STL iterators, there is a 
-   * super_[const_[reverse_]]iterator for linear access to the multidimensional map.
-   * The access from the super_iterator to the actual elements in the multidimensional map
-   * is handeld via a the standard dereference and pointer operators yielding 
-   * a multidimensional key (see JTOOLS::JMultiKey) or pair (see JTOOLS::JMultiPair), respectively.
+   * In addition to the standard STL iterators, 
+   * there are super iteretors for linear access to the multidimensional map.\n
+   * The access from a super iterator to the actual elements in the multidimensional map
+   * is handled via the usual dereference and pointer operators.\n
+   * The multidimensional key (see JTOOLS::JMultiKey) and value can directly be obtained
+   * via member methods <tt>%getKey()</tt> and <tt>%getValue()</tt>, respectively.
    */
   template<class JAbscissa_t,
 	   class JOrdinate_t,
@@ -69,19 +70,19 @@ namespace JTOOLS {
     
     typedef JHead_t<JAbscissa_t,
 		    JMultiMap<JAbscissa_t, JOrdinate_t, JTail_t, JDistance_t>,
-		    JDistance_t>                             map_type;
-    
-    typedef JAbscissa_t                                      abscissa_type;
-    typedef JOrdinate_t                                      ordinate_type;
+		    JDistance_t>                                               map_type;
+
+    typedef JAbscissa_t                                                        abscissa_type;
+    typedef JOrdinate_t                                                        ordinate_type;
 
-    typedef typename map_type::key_type                      key_type;
-    typedef typename map_type::mapped_type                   mapped_type;
-    typedef typename map_type::value_type                    value_type;
+    typedef typename map_type::key_type                                        key_type;
+    typedef typename map_type::mapped_type                                     mapped_type;
+    typedef typename map_type::value_type                                      value_type;
 
-    typedef typename map_type::const_iterator                const_iterator;
-    typedef typename map_type::const_reverse_iterator        const_reverse_iterator;
-    typedef typename map_type::iterator                      iterator;
-    typedef typename map_type::reverse_iterator              reverse_iterator;
+    typedef typename map_type::const_iterator                                  const_iterator;
+    typedef typename map_type::const_reverse_iterator                          const_reverse_iterator;
+    typedef typename map_type::iterator                                        iterator;
+    typedef typename map_type::reverse_iterator                                reverse_iterator;
 
     using map_type::insert; 
     using map_type::configure; 
@@ -194,35 +195,48 @@ namespace JTOOLS {
       }
     }
 
-    
-    class super_const_iterator;  // forward declaration
-
+  private:    
 
     /**
-     * Multidimensional iterator. 
+     * Base class for multidimensional iterator.
      */
-    class super_iterator :
-      public JEquals         <super_iterator>,
-      public JForwardIterator<super_iterator>
+    template<class first_iterator, class second_iterator>
+    struct iterator_base :
+      public JEquals< iterator_base<first_iterator, second_iterator> >
     {
+      typedef std::pair<first_iterator, first_iterator>                          range_type;
+      typedef typename second_iterator::value_type                               value_type;
+      typedef JMultiKey <NUMBER_OF_DIMENSIONS, const abscissa_type>              multikey_type;
+      typedef JMultiPair<NUMBER_OF_DIMENSIONS, const abscissa_type, value_type>  multipair_type;
 
-      friend class JMultiMap;
-      friend class super_const_iterator;
-
-    public:
-
-      typedef int                                                                difference_type;
-      typedef JPair<const key_type&, typename mapped_type::super_iterator&>      value_type;
-      typedef JLANG::JSinglePointer<value_type>                                  pointer;
-      typedef JMultiPair<NUMBER_OF_DIMENSIONS, const JAbscissa_t, JOrdinate_t&>  reference;
-      typedef std::forward_iterator_tag                                          iterator_category;
-      typedef JMultiKey <NUMBER_OF_DIMENSIONS, const JAbscissa_t>                multikey_type;
 
       /**
-       * Default constructor.
+       * Auxiliary class for smart pointer.
        */
-      super_iterator()
-      {}
+      struct pointer_type :
+	private JPair<const key_type, second_iterator&>
+      {
+	/**
+	 * Constructor.
+	 *
+	 * \param  key             key
+	 * \param  value           value
+	 */
+	pointer_type(const key_type key, second_iterator& value) :
+	  JPair<const key_type, second_iterator&>(key, value)
+	{}
+
+
+	/**
+	 * Smart pointer operator.
+	 *
+	 * \return          pointer to object
+	 */
+	const JPair<const key_type, second_iterator&>* operator->() const
+	{
+	  return this;
+	}
+      };
 
 
       /**
@@ -230,9 +244,9 @@ namespace JTOOLS {
        *
        * \return                 pointer to pair of iterators
        */
-      pointer operator->()
-      { 
-	return pointer(new value_type(i->getX(), second));
+      pointer_type operator->()
+      {
+	return pointer_type(i->getX(), second);
       }
 
 
@@ -241,49 +255,26 @@ namespace JTOOLS {
        *
        * \return                 multidimensional pair
        */
-      reference operator*()
+      multipair_type operator*()
       {
-	return reference(i->getX(), *second);
+	return multipair_type(i->getX(), *second);
       }
 
-
+      
       /**
        * Equality of super iterator.
        *
        * \param  cursor          super iterator
        * \return                 true if equal; else false
        */
-      virtual bool equals(const super_iterator& cursor) const
+      bool equals(const iterator_base& cursor) const
       {
 	return i == cursor.i && (i == range.second || second.equals(cursor.second));
       }
 
-
-      /**
-       * Increment super_iterator.
-       *
-       * \return                 true if valid; else false
-       */
-      virtual bool increment() override 
-      {
-	if (!second.increment()) {
-
-	  while (++i != range.second) {
-
-	    second = i->getY().super_begin();
-	    
-	    if (second != i->getY().super_end()) {
-	      break;
-	    }
-	  }
-	}
-
-	return i != range.second;
-      }
-
       
       /**
-       * Get multi-dimensional key.
+       * Get multidimensional key.
        *
        * \return                 key
        */
@@ -298,472 +289,344 @@ namespace JTOOLS {
        *
        * \return                 value
        */
-      JOrdinate_t& getValue() 
+      value_type& getValue() 
       {
-	return second.getValue();
+	return this->second.getValue();
       }
 
 
-    private:
-      /**
-       * Constructor.
-       *
-       * \param  __begin         begin of data
-       * \param  __end           end   of data
-       */
-      super_iterator(iterator __begin,
-		     iterator __end) :
-	range(__begin, __end)
-      {
-	for (i = range.first; i != range.second; ++i) {
-
-	  second = i->getY().super_begin();
-
-	  if (second != i->getY().super_end()) {
-	    break;
-	  }
-	}
-      }
-
-
-      std::pair<iterator, iterator> range;
-      iterator i;
-      typename mapped_type::super_iterator second;
+    protected:
+      range_type      range;
+      first_iterator  i;
+      second_iterator second;
     };
 
 
     /**
-     * Multidimensional const_iterator. 
+     * Helper class for multidimensional iterator.
      */
-    class super_const_iterator :
-      public JEquals         <super_const_iterator>,
-      public JForwardIterator<super_const_iterator>
+    template<class first_iterator, class second_iterator>
+    struct iterator_helper :
+      public iterator_base<first_iterator, second_iterator>,
+      public JForwardIterator< iterator_helper<first_iterator, second_iterator> >
     {
-
-      friend class JMultiMap;
-
-    public:
-
-      typedef int                                                                      difference_type;
-      typedef JPair<const key_type&, typename mapped_type::super_const_iterator&>      value_type;
-      typedef JLANG::JSinglePointer<value_type>                                        pointer;
-      typedef JMultiPair<NUMBER_OF_DIMENSIONS, const JAbscissa_t, const JOrdinate_t&>  reference;
-      typedef std::forward_iterator_tag                                                iterator_category;      
-      typedef JMultiKey <NUMBER_OF_DIMENSIONS, const JAbscissa_t>                      multikey_type;
-      
-
       /**
        * Default constructor.
        */
-      super_const_iterator()
+      iterator_helper()
       {}
 
 
       /**
-       * Copy constructor.
-       *
-       * \param  cursor          super_iterator
-       */
-      super_const_iterator(super_iterator cursor) :
-	range (cursor.range),
-	i     (cursor.i),
-	second(cursor.second)
-      {}
-
-
-      /**
-       * Smart pointer operator.
+       * Constructor.
        *
-       * \return                 pointer to pair of iterators
+       * \param  __begin         begin of data
+       * \param  __end           end   of data
        */
-      pointer operator->()
-      { 
-	return pointer(new value_type(i->getX(), second));
-      }
-
+      iterator_helper(first_iterator __begin,
+		      first_iterator __end)
+      {
+	this->range = std::make_pair(__begin, __end);
 
-      /**
-       * Dereference operator.
-       *
-       * \return                 multidimensional pair
-       */
-      reference operator*()
-      { 
-	return reference(i->getX(), *second);
-      }
+	for (this->i = this->range.first; this->i != this->range.second; ++(this->i)) {
 
+	  this->second = this->i->getY().super_begin();
 
-      /**
-       * Equality of super iterator.
-       *
-       * \param  cursor          super iterator
-       * \return                 true if equal; else false
-       */
-      virtual bool equals(const super_const_iterator& cursor) const
-      {
-	return i == cursor.i && (i == range.second || second.equals(cursor.second));
+	  if (this->second != this->i->getY().super_end()) {
+	    break;
+	  }
+	}
       }
 
 
       /**
-       * Increment super_iterator.
+       * Increment super iterator.
        *
        * \return                 true if valid; else false
        */
-      virtual bool increment() override 
+      virtual bool increment() override
       {
-	if (!second.increment()) {
+	if (!this->second.increment()) {
 
-	  while (++i != range.second) {
+	  while (++(this->i) != this->range.second) {
 
-	    second = i->getY().super_begin();
+	    this->second = this->i->getY().super_begin();
 	    
-	    if (second != i->getY().super_end()) {
+	    if (this->second != this->i->getY().super_end()) {
 	      break;
 	    }
 	  }
 	}
 
-	return i != range.second;
+	return this->i != this->range.second;
       }
+    };
 
 
+    /**
+     * Helper class for multidimensional reverse iterator.
+     */
+    template<class first_iterator, class second_iterator>
+    struct reverse_iterator_helper :
+      public iterator_base<first_iterator, second_iterator>,
+      public JForwardIterator< reverse_iterator_helper<first_iterator, second_iterator> >
+    {
       /**
-       * Get multi-dimensional key.
-       *
-       * \return                 key
+       * Default constructor.
        */
-      multikey_type getKey() const
-      {
-	return multikey_type(i->getX(), second.getKey());
-      }
-
+      reverse_iterator_helper()
+      {}
       
-      /**
-       * Get value.
-       *
-       * \return                 value
-       */
-      const JOrdinate_t& getValue() 
-      {
-	return second.getValue();
-      }
 
-
-    private:
       /**
        * Constructor.
        *
        * \param  __begin         begin of data
        * \param  __end           end   of data
        */
-      super_const_iterator(const_iterator __begin,
-			   const_iterator __end) :
-	range(__begin, __end)
+      reverse_iterator_helper(first_iterator __begin,
+			      first_iterator __end)
       {
-	for (i = range.first; i != range.second; ++i) {
+	this->range = std::make_pair(__begin, __end);
+
+	for (this->i = this->range.first; this->i != this->range.second; ++(this->i)) {
 
-	  second = i->getY().super_begin();
+	  this->second = this->i->getY().super_rbegin();
 
-	  if (second != i->getY().super_end()) {
+	  if (this->second != this->i->getY().super_rend()) {
 	    break;
 	  }
 	}
       }
 
 
-      std::pair<const_iterator, const_iterator> range;
-      const_iterator i;
-      typename mapped_type::super_const_iterator second;
+      /**
+       * Increment super iterator.
+       *
+       * \return                 true if valid; else false
+       */
+      virtual bool increment() override
+      {
+	if (!this->second.increment()) {
+
+	  while (++(this->i) != this->range.second) {
+
+	    this->second = this->i->getY().super_rbegin();
+	    
+	    if (this->second != this->i->getY().super_rend()) {
+	      break;
+	    }
+	  }
+	}
+
+	return this->i != this->range.second;
+      }
     };
 
-    
-    class super_const_reverse_iterator;  // forward declaration
+  public:    
+
+    class super_const_iterator;  // forward declaration
 
 
     /**
-     * Multidimensional reverse iterator. 
+     * Multidimensional iterator. 
      */
-    class super_reverse_iterator :
-      public JEquals         <super_reverse_iterator>,
-      public JForwardIterator<super_reverse_iterator>
+    struct super_iterator :
+      public iterator_helper<iterator, typename mapped_type::super_iterator>
     {
 
       friend class JMultiMap;
-      friend class super_const_reverse_iterator;
-
-    public:
-
-      typedef int                                                                        difference_type;
-      typedef JPair<const key_type&, typename mapped_type::super_reverse_iterator&>      value_type;
-      typedef JLANG::JSinglePointer<value_type>                                          pointer;
-      typedef JMultiPair<NUMBER_OF_DIMENSIONS, const JAbscissa_t, JOrdinate_t&>          reference;
-      typedef std::forward_iterator_tag                                                  iterator_category;
-      typedef JMultiKey <NUMBER_OF_DIMENSIONS, const JAbscissa_t>                        multikey_type;
+      friend class super_const_iterator;
 
-      
       /**
        * Default constructor.
        */
-      super_reverse_iterator()
+      super_iterator()
       {}
 
-
+    private:
       /**
-       * Smart pointer operator.
+       * Constructor.
        *
-       * \return                 pointer to pair of iterators
+       * \param  __begin         begin of data
+       * \param  __end           end   of data
        */
-      pointer operator->()
-      { 
-	return pointer(new value_type(i->getX(), second));
-      }
+      super_iterator(iterator __begin,
+		     iterator __end) :
+	iterator_helper<iterator, typename mapped_type::super_iterator>(__begin, __end)
+      {}
+    };
 
 
-      /**
-       * Dereference operator.
-       *
-       * \return                 multidimensional pair
-       */
-      reference operator*()
-      {
-	return reference(i->getX(), *second);
-      }
+    /**
+     * Multidimensional const_iterator. 
+     */
+    struct super_const_iterator :
+      public iterator_helper<const_iterator, typename mapped_type::super_const_iterator>,
+      public JEquals<super_const_iterator, super_iterator>
+    {
 
+      friend class JMultiMap;
 
       /**
-       * Equality of super reverse iterator.
-       *
-       * \param  cursor          super reverse iterator
-       * \return                 true if equal; else false
+       * Default constructor.
        */
-      virtual bool equals(const super_reverse_iterator& cursor) const
-      {
-	return i == cursor.i && (i == range.second || second.equals(cursor.second));
-      }
+      super_const_iterator()
+      {}
 
 
       /**
-       * Increment super_iterator.
+       * Copy constructor.
        *
-       * \return                 true if valid; else false
+       * \param  cursor          super iterator
        */
-      virtual bool increment() override 
+      super_const_iterator(const super_iterator& cursor)
       {
-	if (!second.increment()) {
-
-	  while (++i != range.second) {
-
-	    second = i->getY().super_rbegin();
-	    
-	    if (!second.equals(i->getY().super_rend())) {
-	      break;
-	    }
-	  }
-	}
-
-	return i != range.second;
+	this->range  = cursor.range;
+	this->i      = cursor.i;
+	this->second = cursor.second;
       }
 
       
       /**
-       * Get multi-dimensional key.
+       * Equality of super iterator.
        *
-       * \return                 key
+       * \param  cursor          super iterator
+       * \return                 true if equal; else false
        */
-      multikey_type getKey() const
+      bool equals(const super_const_iterator& cursor) const
       {
-	return multikey_type(i->getX(), second.getKey());
+	return static_cast<const iterator_base<const_iterator, typename mapped_type::super_const_iterator>&>(*this).equals(cursor);
       }
 
       
       /**
-       * Get value.
+       * Equality of super iterator.
        *
-       * \return                 value
+       * \param  cursor          super iterator
+       * \return                 true if equal; else false
        */
-      JOrdinate_t& getValue() 
+      bool equals(const super_iterator& cursor) const
       {
-	return second.getValue();
+	return equals(super_const_iterator(cursor));
       }
 
-
     private:
       /**
        * Constructor.
        *
-       * \param  __begin         reverse begin of data
-       * \param  __end           reverse end   of data
+       * \param  __begin         begin of data
+       * \param  __end           end   of data
        */
-      super_reverse_iterator(reverse_iterator __begin,
-			     reverse_iterator __end) :
-	range(__begin, __end)
-      {
-	for (i = range.first; i != range.second; ++i) {
-
-	  second = i->getY().super_rbegin();
-
-	  if (!second.equals(i->getY().super_rend())) {
-	    break;
-	  }
-	}
-      }
-
-
-      std::pair<reverse_iterator, reverse_iterator> range;
-      reverse_iterator i;
-      typename mapped_type::super_reverse_iterator second;
+      super_const_iterator(const_iterator __begin,
+			   const_iterator __end) :
+	iterator_helper<const_iterator, typename mapped_type::super_const_iterator>(__begin, __end)
+      {}
     };
 
+    
+    class super_const_reverse_iterator;  // forward declaration
+
 
     /**
-     * Multidimensional const_reverse_iterator. 
+     * Multidimensional reverse iterator. 
      */
-    class super_const_reverse_iterator :
-      public JEquals         <super_const_reverse_iterator>,
-      public JForwardIterator<super_const_reverse_iterator>
+    struct super_reverse_iterator :
+      public reverse_iterator_helper<reverse_iterator, typename mapped_type::super_reverse_iterator>
     {
 
       friend class JMultiMap;
-
-    public:
-
-      typedef int                                                                              difference_type;
-      typedef JPair<const key_type&, typename mapped_type::super_const_reverse_iterator&>      value_type;
-      typedef JLANG::JSinglePointer<value_type>                                                pointer;
-      typedef JMultiPair<NUMBER_OF_DIMENSIONS, const JAbscissa_t, const JOrdinate_t&>          reference;
-      typedef std::forward_iterator_tag                                                        iterator_category;      
-      typedef JMultiKey <NUMBER_OF_DIMENSIONS, const JAbscissa_t>                              multikey_type;
-      
+      friend class super_const_reverse_iterator;
 
       /**
        * Default constructor.
        */
-      super_const_reverse_iterator()
+      super_reverse_iterator()
       {}
 
-
+    private:
       /**
-       * Copy constructor.
+       * Constructor.
        *
-       * \param  cursor          super_iterator
+       * \param  __begin         reverse begin of data
+       * \param  __end           reverse end   of data
        */
-      super_const_reverse_iterator(super_reverse_iterator cursor) :
-	range (cursor.range),
-	i     (cursor.i),
-	second(cursor.second)
+      super_reverse_iterator(reverse_iterator __begin,
+			     reverse_iterator __end) :
+	reverse_iterator_helper<reverse_iterator, typename mapped_type::super_reverse_iterator>(__begin, __end)
       {}
+    };
 
 
-      /**
-       * Smart pointer operator.
-       *
-       * \return                 pointer to pair of iterators
-       */
-      pointer operator->()
-      { 
-	return pointer(new value_type(i->getX(), second));
-      }
+    /**
+     * Multidimensional const reverse iterator. 
+     */
+    struct super_const_reverse_iterator :
+      public reverse_iterator_helper<const_reverse_iterator, typename mapped_type::super_const_reverse_iterator>,
+      public JEquals<super_const_reverse_iterator, super_reverse_iterator>
+    {
 
+      friend class JMultiMap;
 
       /**
-       * Dereference operator.
-       *
-       * \return                 multidimensional pair
+       * Default constructor.
        */
-      reference operator*()
-      { 
-	return reference(i->getX(), *second);
-      }
+      super_const_reverse_iterator()
+      {}
 
 
       /**
-       * Equality of super reverse iterator.
+       * Copy constructor.
        *
        * \param  cursor          super reverse iterator
-       * \return                 true if equal; else false
-       */
-      virtual bool equals(const super_const_reverse_iterator& cursor) const
-      {
-	return i == cursor.i && (i == range.second || second.equals(cursor.second));
-      }
-
-
-      /**
-       * Increment super_iterator.
-       *
-       * \return                 true if valid; else false
        */
-      virtual bool increment() override 
+      super_const_reverse_iterator(super_reverse_iterator cursor)
       {
-	if (!second.increment()) {
-
-	  while (++i != range.second) {
-
-	    second = i->getY().super_rbegin();
-	    
-	    if (second != i->getY().super_rend()) {
-	      break;
-	    }
-	  }
-	}
-
-	return i != range.second;
+	this->range  = cursor.range;
+	this->i      = cursor.i;
+	this->second = cursor.second;
       }
 
-
+      
       /**
-       * Get multi-dimensional key.
+       * Equality of super reverse iterator.
        *
-       * \return                 key
+       * \param  cursor          super reverse iterator
+       * \return                 true if equal; else false
        */
-      multikey_type getKey() const
+      bool equals(const super_const_reverse_iterator& cursor) const
       {
-	return multikey_type(i->getX(), second.getKey());
+	return static_cast<const iterator_base<const_reverse_iterator, typename mapped_type::super_const_reverse_iterator>&>(*this).equals(cursor);
       }
 
       
       /**
-       * Get value.
+       * Equality of super reverse iterator.
        *
-       * \return                 value
+       * \param  cursor          super reverse iterator
+       * \return                 true if equal; else false
        */
-      const JOrdinate_t& getValue() 
+      bool equals(const super_reverse_iterator& cursor) const
       {
-	return second.getValue();
+	return equals(super_const_reverse_iterator(cursor));
       }
 
-
     private:
       /**
        * Constructor.
-       *
-       * \param  __begin         begin of data
-       * \param  __end           end   of data
-       */
-      super_const_reverse_iterator(const_reverse_iterator __begin,
-				   const_reverse_iterator __end) :
-	range(__begin, __end)
-      {
-	for (i = range.first; i != range.second; ++i) {
-
-	  second = i->getY().super_rbegin();
-
-	  if (second != i->getY().super_rend()) {
-	    break;
-	  }
-	}
-      }
-
-
-      std::pair<const_reverse_iterator, const_reverse_iterator> range;
-      const_reverse_iterator i;
-      typename mapped_type::super_const_reverse_iterator second;
+       *
+       * \param  __begin         begin of data
+       * \param  __end           end   of data
+       */
+      super_const_reverse_iterator(const_reverse_iterator __begin,
+				   const_reverse_iterator __end) :
+	reverse_iterator_helper<const_reverse_iterator, typename mapped_type::super_const_reverse_iterator>(__begin, __end)
+      {}
     };
 
 
     /**
-     * Get super_iterator to begin of data.
+     * Get super iterator to begin of data.
      * 
      * \return                 super iterator
      */
@@ -774,7 +637,7 @@ namespace JTOOLS {
 
 
     /**
-     * Get super_reverse_iterator to reverse begin of data
+     * Get super iterator to reverse begin of data
      *
      * \return                  super reverse iterator
      */
@@ -785,7 +648,7 @@ namespace JTOOLS {
  
    
     /**
-     * Get super_iterator to end of data.
+     * Get super iterator to end of data.
      *
      * \return                 super iterator
      */
@@ -796,7 +659,7 @@ namespace JTOOLS {
 
 
     /**
-     * Get super_reverse_iterator to end of data.
+     * Get super iterator to reverse end of data.
      *
      * \return                 super reverse iterator
      */
@@ -807,7 +670,7 @@ namespace JTOOLS {
 
 
     /**
-     * Get super_iterator to begin of data.
+     * Get super iterator to begin of data.
      *
      * \return                 super iterator
      */
@@ -818,7 +681,7 @@ namespace JTOOLS {
 
 
     /**
-     * Get super_reverse_iterator to begin of data.
+     * Get super iterator to reverse begin of data.
      *
      * \return                 super iterator
      */
@@ -829,7 +692,7 @@ namespace JTOOLS {
  
    
     /**
-     * Get super_iterator to end of data.
+     * Get super iterator to end of data.
      *
      * \return                 super iterator
      */
@@ -840,7 +703,7 @@ namespace JTOOLS {
 
 
     /**
-     * Get super_reverse_iterator to end of data.
+     * Get super iterator to reverse end of data.
      *
      * \return                 super iterator
      */
@@ -856,7 +719,7 @@ namespace JTOOLS {
      * \param  key             multidimensional key
      * \return                 value
      */
-    ordinate_type& get(const JMultiKey<NUMBER_OF_DIMENSIONS, abscissa_type>& key)
+    ordinate_type& get(const JMultiKey<NUMBER_OF_DIMENSIONS, const abscissa_type>& key)
     {
       return this->get(key.first).get(key.second);
     }
@@ -868,7 +731,7 @@ namespace JTOOLS {
      * \param  key             multidimensional key
      * \param  value           value
      */
-    void insert(const JMultiKey<NUMBER_OF_DIMENSIONS, abscissa_type>& key, const ordinate_type& value)
+    void insert(const JMultiKey<NUMBER_OF_DIMENSIONS, const abscissa_type>& key, const ordinate_type& value)
     {
       (*this)[key.first].insert(key.second, value);
     }
@@ -879,18 +742,7 @@ namespace JTOOLS {
      *
      * \param  value           multidimensional pair
      */
-    void insert(const JMultiPair<NUMBER_OF_DIMENSIONS, abscissa_type, ordinate_type>& value)
-    {
-      (*this)[value.first].insert(value.second);
-    }
-
-
-    /**
-     * Insert element.
-     *
-     * \param  value           multidimensional iterator value
-     */
-    void insert(const typename super_iterator::reference& value)
+    void insert(const JMultiPair<NUMBER_OF_DIMENSIONS, const abscissa_type, const ordinate_type&>& value)
     {
       (*this)[value.first].insert(value.second);
     }
@@ -899,9 +751,9 @@ namespace JTOOLS {
     /**
      * Insert element.
      *
-     * \param  value           multidimensional iterator value
+     * \param  value           multidimensional pair
      */
-    void insert(const typename super_const_iterator::reference& value)
+    void insert(const JMultiPair<NUMBER_OF_DIMENSIONS, const abscissa_type, ordinate_type&>& value)
     {
       (*this)[value.first].insert(value.second);
     }
@@ -923,21 +775,20 @@ namespace JTOOLS {
 
     enum { NUMBER_OF_DIMENSIONS = 1 };
 
-    typedef JHead_t<JAbscissa_t, JOrdinate_t, JDistance_t>   map_type;
+    typedef JHead_t<JAbscissa_t, JOrdinate_t, JDistance_t>                     map_type;
     
-    typedef JAbscissa_t                                      abscissa_type;
-    typedef JOrdinate_t                                      ordinate_type;
-
-    typedef typename map_type::key_type                      key_type;
-    typedef typename map_type::mapped_type                   mapped_type;
-    typedef typename map_type::value_type                    value_type;
-
-    typedef typename map_type::const_iterator                const_iterator;
-    typedef typename map_type::const_reverse_iterator        const_reverse_iterator;
-
-    typedef typename map_type::iterator                      iterator;
-    typedef typename map_type::reverse_iterator              reverse_iterator;
-
+    typedef JAbscissa_t                                                        abscissa_type;
+    typedef JOrdinate_t                                                        ordinate_type;
+
+    typedef typename map_type::key_type                                        key_type;
+    typedef typename map_type::mapped_type                                     mapped_type;
+    typedef typename map_type::value_type                                      value_type;
+
+    typedef typename map_type::const_iterator                                  const_iterator;
+    typedef typename map_type::const_reverse_iterator                          const_reverse_iterator;
+    typedef typename map_type::iterator                                        iterator;
+    typedef typename map_type::reverse_iterator                                reverse_iterator;
+     
     using map_type::insert; 
     using map_type::configure; 
     using map_type::get; 
@@ -1041,35 +892,68 @@ namespace JTOOLS {
       this->configure(bounds(key));
     }
 
-
-    class super_const_iterator;  // forward declaration
-
+  private:
 
     /**
-     * Terminator class of multidimensional iterator. 
+     * Helper class for multidimensional iterator.
      */
-    class super_iterator :
-      public JEquals         <super_iterator>,
-      public JForwardIterator<super_iterator>
+    template<class iterator_type, class ordinate_type>
+    struct iterator_helper :
+      public JEquals         < iterator_helper<iterator_type, ordinate_type> >,
+      public JForwardIterator< iterator_helper<iterator_type, ordinate_type> >
     {
+      typedef std::pair<iterator_type, iterator_type>                            range_type;
+      typedef ordinate_type                                                      value_type;
+      typedef JMultiKey <NUMBER_OF_DIMENSIONS, const abscissa_type>              multikey_type;
+      typedef JMultiPair<NUMBER_OF_DIMENSIONS, const abscissa_type, value_type>  multipair_type;
 
-      friend class JMultiMap;
-      friend class super_const_iterator;
-
-    public:
-
-      typedef size_t                                          difference_type;      
-      typedef JPair<const key_type&, mapped_type&>            value_type;
-      typedef JLANG::JSinglePointer<value_type>               pointer;
-      typedef JMultiPair<1, const JAbscissa_t, JOrdinate_t&>  reference;
-      typedef std::forward_iterator_tag                       iterator_category;      
-      typedef JMultiKey <1, const JAbscissa_t>                multikey_type;
 
+      /**
+       * Auxiliary class for pair via smart pointer.
+       */
+      struct pointer_type :
+	private JPair<const key_type, value_type>
+      {
+	/**
+	 * Constructor.
+	 *
+	 * \param  key             key
+	 * \param  value           value
+	 */
+	pointer_type(const key_type key, value_type value) :
+	  JPair<const key_type, value_type>(key, value)
+	{}
+
+
+	/**
+	 * Smart pointer operator.
+	 *
+	 * \return          pointer to object
+	 */
+	const JPair<const key_type, value_type>* operator->() const
+	{
+	  return this;
+	}
+      };
+    
 
       /**
        * Default constructor.
        */
-      super_iterator()
+      iterator_helper()
+      {}
+      
+
+      /**
+       * Constructor.
+       *
+       * \param  __begin         begin of data
+       * \param  __end           end   of data
+       */
+      iterator_helper(iterator_type __begin,
+		      iterator_type __end) :
+	range(__begin, __end),
+	i(__begin)
       {}
 
 
@@ -1078,9 +962,9 @@ namespace JTOOLS {
        *
        * \return                 pointer to pair of iterators
        */
-      pointer operator->()
-      { 
-	return pointer(new value_type(i->getX(), i->getY()));
+      pointer_type operator->()
+      {
+	return pointer_type(i->getX(), i->getY());
       }
 
 
@@ -1089,37 +973,37 @@ namespace JTOOLS {
        *
        * \return                 multidimensional pair
        */
-      reference operator*()
+      multipair_type operator*()
       { 
-	return reference(i->getX(), i->getY());
+	return multipair_type(i->getX(), i->getY());
       }
 
-
+      
       /**
        * Equality of super iterator.
        *
        * \param  cursor          super iterator
        * \return                 true if equal; else false
        */
-      virtual bool equals(const super_iterator& cursor) const
+      bool equals(const iterator_helper& cursor) const
       {
 	return i == cursor.i;
       }
 
 
       /**
-       * Increment super_iterator.
+       * Increment super iterator.
        *
        * \return                 true if valid; else false
        */
-      virtual bool increment() override 
+      virtual bool increment() override
       {
 	return ++i != range.second;
       }
 
-      
+
       /**
-       * Get multi-dimensional key.
+       * Get multidimensional key.
        *
        * \return                 key
        */
@@ -1134,11 +1018,37 @@ namespace JTOOLS {
        *
        * \return                 value
        */
-      JOrdinate_t& getValue() 
+      value_type getValue() 
       {
 	return i->getY();
       }
 
+      
+      range_type    range;
+      iterator_type i;
+    };
+
+  public:
+
+    class super_const_iterator;  // forward declaration
+
+
+    /**
+     * Terminator class of multidimensional iterator. 
+     */
+    struct super_iterator :
+      public iterator_helper<iterator, ordinate_type&>
+    {
+
+      friend class JMultiMap;
+      friend class super_const_iterator;
+
+      /**
+       * Default constructor.
+       */
+      super_iterator()
+      {}
+
     private:
       /**
        * Constructor.
@@ -1148,36 +1058,21 @@ namespace JTOOLS {
        */
       super_iterator(iterator __begin,
 		     iterator __end) :
-	range(__begin, __end),
-	i    (__begin)
+	iterator_helper<iterator, ordinate_type&>(__begin, __end)
       {}
-
-
-      std::pair<iterator, iterator> range;
-      iterator i;
     };
 
 
     /**
      * Terminator class of multidimensional const_iterator. 
      */
-    class super_const_iterator :
-      public JEquals         <super_const_iterator>,
-      public JForwardIterator<super_const_iterator>
+    struct super_const_iterator :
+      public iterator_helper<const_iterator, const ordinate_type&>,
+      public JEquals<super_const_iterator, super_iterator>
     {
 
       friend class JMultiMap;
 
-    public:
-
-      typedef size_t                                                difference_type;      
-      typedef JPair<const key_type&, const mapped_type&>            value_type;
-      typedef JLANG::JSinglePointer<value_type>                     pointer;
-      typedef JMultiPair<1, const JAbscissa_t, const JOrdinate_t&>  reference;
-      typedef std::forward_iterator_tag                             iterator_category;      
-      typedef JMultiKey <1, const JAbscissa_t>                      multikey_type;
-      
-
       /**
        * Default constructor.
        */
@@ -1188,78 +1083,36 @@ namespace JTOOLS {
       /**
        * Copy constructor.
        *
-       * \param  cursor          super_iterator
-       */
-      super_const_iterator(super_iterator cursor) :
-	range(cursor.range),
-	i    (cursor.i)
-      {}
-
-
-      /**
-       * Smart pointer operator.
-       *
-       * \return                 pointer to pair of iterators
+       * \param  cursor          super iterator
        */
-      pointer operator->()
+      super_const_iterator(super_iterator cursor)
       {
-	return pointer(new value_type(i->getX(), i->getY()));
-      }
-
-
-      /**
-       * Dereference operator.
-       *
-       * \return                 multidimensional pair
-       */
-      reference operator*()
-      { 
-	return reference(i->getX(), i->getY());
+	this->range = cursor.range;
+	this->i     = cursor.i;
       }
 
-
+      
       /**
        * Equality of super iterator.
        *
        * \param  cursor          super iterator
        * \return                 true if equal; else false
        */
-      virtual bool equals(const super_const_iterator& cursor) const
-      {
-	return i == cursor.i;
-      }
-
-
-      /**
-       * Increment super_iterator.
-       *
-       * \return                 true if valid; else false
-       */
-      virtual bool increment() override 
-      {
-	return ++i != range.second;
-      }
-
-      
-      /**
-       * Get multi-dimensional key.
-       *
-       * \return                 key
-       */
-      multikey_type getKey() const
+      bool equals(const super_const_iterator& cursor) const
       {
-	return multikey_type(i->getX());
+	return this->i == cursor.i;
       }
 
       
       /**
-       * Get value.
+       * Equality of super iterator.
        *
-       * \return                 value
+       * \param  cursor          super iterator
+       * \return                 true if equal; else false
        */
-      const JOrdinate_t& getValue() 
+      bool equals(const super_iterator& cursor) const
       {
-	return i->getY();
+	return this->i == cursor.i;
       }
 
     private:
@@ -1271,13 +1124,8 @@ namespace JTOOLS {
        */
       super_const_iterator(const_iterator __begin,
 			   const_iterator __end) :
-	range(__begin, __end),
-	i    (__begin)
+	iterator_helper<const_iterator, const ordinate_type&>(__begin, __end)
       {}
-
-
-      std::pair<const_iterator, const_iterator> range;
-      const_iterator i;
     };
 
 
@@ -1287,97 +1135,19 @@ namespace JTOOLS {
     /**
      * Terminator class of multidimensional reverse iterator. 
      */
-    class super_reverse_iterator :
-      public JEquals         <super_iterator>,
-      public JForwardIterator<super_iterator>
+    struct super_reverse_iterator :
+      public iterator_helper<reverse_iterator, ordinate_type&>
     {
 
       friend class JMultiMap;
       friend class super_const_reverse_iterator;
 
-    public:
-
-      typedef size_t                                          difference_type;      
-      typedef JPair<const key_type&, mapped_type&>            value_type;
-      typedef JLANG::JSinglePointer<value_type>               pointer;
-      typedef JMultiPair<1, const JAbscissa_t, JOrdinate_t&>  reference;
-      typedef std::forward_iterator_tag                       iterator_category;      
-      typedef JMultiKey <1, const JAbscissa_t>                multikey_type;
-
-
       /**
        * Default constructor.
        */
       super_reverse_iterator()
       {}
 
-
-      /**
-       * Smart pointer operator.
-       *
-       * \return                 pointer to pair of reverse iterators
-       */
-      pointer operator->()
-      { 
-	return pointer(new value_type(i->getX(), i->getY()));
-      }
-
-
-      /**
-       * Dereference operator.
-       *
-       * \return                 multidimensional pair
-       */
-      reference operator*()
-      { 
-	return reference(i->getX(), i->getY());
-      }
-
-
-      /**
-       * Equality of super reverse iterator.
-       *
-       * \param  cursor          super reverse iterator
-       * \return                 true if equal; else false
-       */
-      virtual bool equals(const super_reverse_iterator& cursor) const
-      {
-	return i == cursor.i;
-      }
-
-
-      /**
-       * Increment super_reverse_iterator.
-       *
-       * \return                 true if valid; else false
-       */
-      virtual bool increment() override 
-      {
-	return ++i != range.second;
-      }
-
-      
-      /**
-       * Get multi-dimensional key.
-       *
-       * \return                 key
-       */
-      multikey_type getKey() const
-      {
-	return multikey_type(i->getX());
-      }
-
-      
-      /**
-       * Get value.
-       *
-       * \return                 value
-       */
-      JOrdinate_t& getValue() 
-      {
-	return i->getY();
-      }
-
     private:
       /**
        * Constructor.
@@ -1387,36 +1157,21 @@ namespace JTOOLS {
        */
       super_reverse_iterator(reverse_iterator __begin,
 			     reverse_iterator __end) :
-	range(__begin, __end),
-	i    (__begin)
+	iterator_helper<reverse_iterator, ordinate_type&>(__begin, __end)
       {}
-
-
-      std::pair<reverse_iterator, reverse_iterator> range;
-      reverse_iterator i;
     };
 
 
     /**
      * Terminator class of multidimensional const_iterator. 
      */
-    class super_const_reverse_iterator :
-      public JEquals         <super_const_reverse_iterator>,
-      public JForwardIterator<super_const_reverse_iterator>
+    struct super_const_reverse_iterator :
+      public iterator_helper<const_reverse_iterator, const ordinate_type&>,
+      public JEquals<super_const_reverse_iterator, super_reverse_iterator>
     {
 
       friend class JMultiMap;
 
-    public:
-
-      typedef size_t                                                difference_type;      
-      typedef JPair<const key_type&, const mapped_type&>            value_type;
-      typedef JLANG::JSinglePointer<value_type>                     pointer;
-      typedef JMultiPair<1, const JAbscissa_t, const JOrdinate_t&>  reference;
-      typedef std::forward_iterator_tag                             iterator_category;      
-      typedef JMultiKey <1, const JAbscissa_t>                      multikey_type;
-      
-
       /**
        * Default constructor.
        */
@@ -1427,78 +1182,36 @@ namespace JTOOLS {
       /**
        * Copy constructor.
        *
-       * \param  cursor          super_iterator
-       */
-      super_const_reverse_iterator(super_reverse_iterator cursor) :
-	range(cursor.range),
-	i    (cursor.i)
-      {}
-
-
-      /**
-       * Smart pointer operator.
-       *
-       * \return                 pointer to pair of iterators
+       * \param  cursor          super reverse iterator
        */
-      pointer operator->()
+      super_const_reverse_iterator(super_reverse_iterator cursor)
       {
-	return pointer(new value_type(i->getX(), i->getY()));
-      }
-
-
-      /**
-       * Dereference operator.
-       *
-       * \return                 multidimensional pair
-       */
-      reference operator*()
-      { 
-	return reference(i->getX(), i->getY());
+	this->range = cursor.range;
+	this->i     = cursor.i;
       }
 
-
+      
       /**
        * Equality of super reverse iterator.
        *
        * \param  cursor          super reverse iterator
        * \return                 true if equal; else false
        */
-      virtual bool equals(const super_const_reverse_iterator& cursor) const
-      {
-	return i == cursor.i;
-      }
-
-
-      /**
-       * Increment super_iterator.
-       *
-       * \return                 true if valid; else false
-       */
-      virtual bool increment() override 
+      bool equals(const super_const_reverse_iterator& cursor) const
       {
-	return ++i != range.second;
-      }
-
-      
-      /**
-       * Get multi-dimensional key.
-       *
-       * \return                 key
-       */
-      multikey_type getKey() const
-      {
-	return multikey_type(i->getX());
+	return this->i == cursor.i;
       }
 
       
       /**
-       * Get value.
+       * Equality of super reverse iterator.
        *
-       * \return                 value
+       * \param  cursor          super reverse iterator
+       * \return                 true if equal; else false
        */
-      const JOrdinate_t& getValue() 
+      bool equals(const super_reverse_iterator& cursor) const
       {
-	return i->getY();
+	return this->i == cursor.i;
       }
 
     private:
@@ -1510,20 +1223,15 @@ namespace JTOOLS {
        */
       super_const_reverse_iterator(const_reverse_iterator __begin,
 				   const_reverse_iterator __end) :
-	range(__begin, __end),
-	i    (__begin)
+	iterator_helper<const_reverse_iterator, const ordinate_type&>(__begin, __end)
       {}
-
-
-      std::pair<const_reverse_iterator, const_reverse_iterator> range;
-      const_reverse_iterator i;
     };
 
 
-     /**
-     * Get super_iterator to begin of data.
+    /**
+     * Get super iterator to begin of data.
      *
-     * \return             super_iterator
+     * \return             super iterator
      */
     super_const_iterator super_begin() const
     {
@@ -1532,9 +1240,9 @@ namespace JTOOLS {
 
 
     /**
-     * Get super_reverse_iterator to reverse begin of data.
+     * Get super iterator to reverse begin of data.
      *
-     * \return             super_reverse_iterator
+     * \return             super reverse iterator
      */
     super_const_reverse_iterator super_rbegin() const
     {
@@ -1543,9 +1251,9 @@ namespace JTOOLS {
  
    
     /**
-     * Get super_iterator to end of data.
+     * Get super iterator to end of data.
      *
-     * \return             super_iterator
+     * \return             super iterator
      */
     super_const_iterator super_end() const
     {
@@ -1554,9 +1262,9 @@ namespace JTOOLS {
 
     
     /**
-     * Get super_reverse_iterator to reverse end of data.
+     * Get super iterator to reverse end of data.
      *
-     * \return             super_reverse_iterator
+     * \return             super reverse iterator
      */
     super_const_reverse_iterator super_rend() const
     {
@@ -1565,9 +1273,9 @@ namespace JTOOLS {
 
 
     /**
-     * Get super_iterator to begin of data.
+     * Get super iterator to begin of data.
      *
-     * \return             super_iterator
+     * \return             super iterator
      */
     super_iterator super_begin()
     {
@@ -1576,9 +1284,9 @@ namespace JTOOLS {
 
 
     /**
-     * Get super_reverse_iterator to reverse begin of data.
+     * Get super iterator to reverse begin of data.
      *
-     * \return             super_reverse_iterator
+     * \return             super reverse iterator
      */
     super_reverse_iterator super_rbegin()
     {
@@ -1587,9 +1295,9 @@ namespace JTOOLS {
  
    
     /**
-     * Get super_iterator to end of data.
+     * Get super iterator to end of data.
      *
-     * \return             super_iterator
+     * \return             super iterator
      */
     super_iterator super_end()
     {
@@ -1598,9 +1306,9 @@ namespace JTOOLS {
  
    
     /**
-     * Get super_reverse_iterator to end of data.
+     * Get super iterator to reverse end of data.
      *
-     * \return             super_reverse_iterator
+     * \return             super reverse iterator
      */
     super_reverse_iterator super_rend()
     {
@@ -1614,7 +1322,7 @@ namespace JTOOLS {
      * \param  key             multidimensional key
      * \return                 value
      */
-    ordinate_type& get(const JMultiKey<1, abscissa_type>& key)
+    ordinate_type& get(const JMultiKey<NUMBER_OF_DIMENSIONS, abscissa_type>& key)
     {
       return get(key.first);
     }
@@ -1626,7 +1334,7 @@ namespace JTOOLS {
      * \param  key          multidimensional key
      * \param  value        value
      */
-    void insert(const JMultiKey<1, JAbscissa_t>& key, const JOrdinate_t& value)
+    void insert(const JMultiKey<NUMBER_OF_DIMENSIONS, const abscissa_type>& key, const ordinate_type& value)
     {
       insert(value_type(key.first, value));
     }
@@ -1637,18 +1345,7 @@ namespace JTOOLS {
      *
      * \param  value        multidimensional pair
      */
-    void insert(const JMultiPair<1, JAbscissa_t, JOrdinate_t>& value)
-    {
-      insert(value_type(value.first, value.second));
-    }
-
-
-    /**
-     * Insert element.
-     *
-     * \param  value        multidimensional iterator value
-     */
-    void insert(const typename super_iterator::reference& value)
+    void insert(const JMultiPair<NUMBER_OF_DIMENSIONS, const abscissa_type, const ordinate_type&>& value)
     {
       insert(value_type(value.first, value.second));
     }
@@ -1657,9 +1354,9 @@ namespace JTOOLS {
     /**
      * Insert element.
      *
-     * \param  value        multidimensional iterator value
+     * \param  value        multidimensional pair
      */
-    void insert(const typename super_const_iterator::reference& value)
+    void insert(const JMultiPair<NUMBER_OF_DIMENSIONS, const abscissa_type, ordinate_type&>& value)
     {
       insert(value_type(value.first, value.second));
     }
diff --git a/src/jpp/JTools/JMultiMapTransformer.hh b/src/jpp/JTools/JMultiMapTransformer.hh
index 50dc1e1..2d1aeca 100644
--- a/src/jpp/JTools/JMultiMapTransformer.hh
+++ b/src/jpp/JTools/JMultiMapTransformer.hh
@@ -27,7 +27,7 @@ namespace JTOOLS {
    *
    * The template parameters refer to the dimension of the map and the data type of the argument, respectively.
    *
-   * This class extends the JClonable and JSerialisable interfacea.
+   * This class extends the JClonable and JSerialisable interfaces.
    */
   template<unsigned int N, class JArgument_t>
   class JMultiMapTransformer :
diff --git a/src/jpp/JTools/JPolint.hh b/src/jpp/JTools/JPolint.hh
index d843fa3..2ae1614 100644
--- a/src/jpp/JTools/JPolint.hh
+++ b/src/jpp/JTools/JPolint.hh
@@ -8,6 +8,7 @@
 #include "JLang/JException.hh"
 #include "JLang/JAssert.hh"
 #include "JLang/JBool.hh"
+#include "JLang/JStreamAvailable.hh"
 #include "JTools/JFunctional.hh"
 #include "JTools/JDistance.hh"
 #include "JTools/JResult.hh"
@@ -96,69 +97,80 @@ namespace JTOOLS {
      */
     virtual result_type evaluate(const argument_type* pX) const override 
     {
-      if (this->size() <= 1u) {
-        return this->getExceptionHandler().action(JFunctionalException("JPolintFunction<>::evaluate() not enough data."));
-      }
-
       const argument_type x = *pX;
 
-      const_iterator p = this->lower_bound(x);
+      if (this->size() > 1u) {
+	
+	const_iterator p = this->lower_bound(x);
 
-      if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
-          (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
-        return this->getExceptionHandler().action(JValueOutOfRange("JPolintFunction::evaluate() x out of range."));
-      }
+	if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
+	    (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
 
-      ++pX;  // next argument value
+	  return this->getExceptionHandler().action(MAKE_EXCEPTION(JValueOutOfRange, "abscissa out of range " 
+								   << STREAM("?") << x                      << " <> " 
+								   << STREAM("?") << this->begin() ->getX() << ' '
+								   << STREAM("?") << this->rbegin()->getX()));
+	}
 
+	++pX;  // next argument value
 
-      const int n = std::min((int) (N + 1), (int) this->size());         // number of points to interpolate      
 
-      for (int i = n/2; i != 0 && p != this->end();   --i, ++p) {}       // move p to begin of data
-      for (int i = n  ; i != 0 && p != this->begin(); --i, --p) {}
+	const int n = std::min((int) (N + 1), (int) this->size());         // number of points to interpolate      
 
+	for (int i = n/2; i != 0 && p != this->end();   --i, ++p) {}       // move p to begin of data
+	for (int i = n  ; i != 0 && p != this->begin(); --i, --p) {}
 
-      int j = 0;
 
-      for (int i = 0; i != n; ++p, ++i) {
+	int j = 0;
+
+	for (int i = 0; i != n; ++p, ++i) {
 	
-	u[i] = this->getDistance(x, p->getX());
-	v[i] = function_type::getValue(p->getY(), pX);
-	w[i] = v[i];
+	  u[i] = this->getDistance(x, p->getX());
+	  v[i] = function_type::getValue(p->getY(), pX);
+	  w[i] = v[i];
 
-	if (fabs(u[i]) < fabs(u[j])) {
-	  j = i;
+	  if (fabs(u[i]) < fabs(u[j])) {
+	    j = i;
+	  }
 	}
-      }
 
       
-      result_type y = v[j];
+	result_type y = v[j];
 
-      --j;
+	--j;
 
-      for (int m = 1; m != n; ++m) {
+	for (int m = 1; m != n; ++m) {
 
-	for (int i = 0; i != n-m; ++i) {
+	  for (int i = 0; i != n-m; ++i) {
 
-	  const double ho = u[ i ];
-	  const double hp = u[i+m];
-	  const double dx = ho - hp;
+	    const double ho = u[ i ];
+	    const double hp = u[i+m];
+	    const double dx = ho - hp;
 
-	  v[i]  = v[i+1];
-	  v[i] -= w[ i ];
-	  w[i]  = v[ i ];
+	    v[i]  = v[i+1];
+	    v[i] -= w[ i ];
+	    w[i]  = v[ i ];
 
-	  v[i] *= ho/dx;
-	  w[i] *= hp/dx;
+	    v[i] *= ho/dx;
+	    w[i] *= hp/dx;
+	  }
+
+	  if (2*(j+1) < n - m)
+	    y += v[j+1];
+	  else
+	    y += w[j--];
 	}
 
-	if (2*(j+1) < n - m)
-	  y += v[j+1];
-	else
-	  y += w[j--];
-      }
+	return y;
+	
+      } else if (this->size() == 1u && this->getDistance(x, this->begin()->getX()) <= distance_type::precision) {
+			
+	return function_type::getValue(this->begin()->getY(), ++pX);
+	
+      } else {
 
-      return y;
+        return this->getExceptionHandler().action(MAKE_EXCEPTION(JFunctionalException, "not enough data " << STREAM("?") << x));	
+      }
     }
 
   protected: 
@@ -227,29 +239,39 @@ namespace JTOOLS {
      */
     virtual result_type evaluate(const argument_type* pX) const override 
     {
-      if (this->size() <= 1u) {
-        return this->getExceptionHandler().action(JFunctionalException("JPolintFunction<>::evaluate() not enough data."));
-      }
-
       const argument_type x = *pX;
 
-      const_iterator p = this->lower_bound(x);
+      if (this->size() > 1u) {
+	
+	const_iterator p = this->lower_bound(x);
 
-      if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
-          (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
+	if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
+	    (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
 
-        return this->getExceptionHandler().action(JValueOutOfRange("JPolintFunction::evaluate() x out of range."));
-      }
+	  return this->getExceptionHandler().action(MAKE_EXCEPTION(JValueOutOfRange, "abscissa out of range " 
+								   << STREAM("?") << x                      << " <> " 
+								   << STREAM("?") << this->begin() ->getX() << ' '
+								   << STREAM("?") << this->rbegin()->getX()));
+	}
 
-      ++pX;  // next argument value
+	++pX;  // next argument value
+
+
+	const_iterator q = p--;
 
+	if (q == this->begin() || this->getDistance(x, q->getX()) < this->getDistance(p->getX(), x)) 
+	  return function_type::getValue(q->getY(), pX);
+	else
+	  return function_type::getValue(p->getY(), pX);
 
-      const_iterator q = p--;
+      } else if (this->size() == 1u && this->getDistance(x, this->begin()->getX()) <= distance_type::precision) {
+			
+	return function_type::getValue(this->begin()->getY(), ++pX);
+	
+      } else {
 
-      if (q == this->begin() || this->getDistance(x, q->getX()) < this->getDistance(p->getX(), x)) 
-	return function_type::getValue(q->getY(), pX);
-      else
-	return function_type::getValue(p->getY(), pX);
+        return this->getExceptionHandler().action(MAKE_EXCEPTION(JFunctionalException, "not enough data " << STREAM("?") << x));	
+      }
     }
 
   protected:
@@ -312,38 +334,48 @@ namespace JTOOLS {
      */
     virtual result_type evaluate(const argument_type* pX) const override 
     {
-      if (this->size() <= 1u) {
-        return this->getExceptionHandler().action(JFunctionalException("JPolintFunction<>::evaluate() not enough data."));
-      }
-
       const argument_type x = *pX;
 
-      const_iterator p = this->lower_bound(x);
+      if (this->size() > 1u) {
 
-      if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
-          (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
+	const_iterator p = this->lower_bound(x);
 
-        return this->getExceptionHandler().action(JValueOutOfRange("JPolintFunction::evaluate() x out of range."));
-      }
+	if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
+	    (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
 
-      ++pX;  // next argument value
+	  return this->getExceptionHandler().action(MAKE_EXCEPTION(JValueOutOfRange, "abscissa out of range " 
+								   << STREAM("?") << x                      << " <> " 
+								   << STREAM("?") << this->begin() ->getX() << ' '
+								   << STREAM("?") << this->rbegin()->getX()));
+	}
+
+	++pX;  // next argument value
 
 
-      const_iterator q = p--;
+	const_iterator q = p--;
 
-      const double dx = this->getDistance(p->getX(), q->getX());
-      const double a  = this->getDistance(x, q->getX()) / dx;
-      const double b  = 1.0 - a;
+	const double dx = this->getDistance(p->getX(), q->getX());
+	const double a  = this->getDistance(x, q->getX()) / dx;
+	const double b  = 1.0 - a;
 
-      ya = function_type::getValue(p->getY(), pX);
-      yb = function_type::getValue(q->getY(), pX);
+	ya = function_type::getValue(p->getY(), pX);
+	yb = function_type::getValue(q->getY(), pX);
 
-      ya *= a;
-      yb *= b;
+	ya *= a;
+	yb *= b;
 
-      ya += yb;
+	ya += yb;
 
-      return ya;
+	return ya;
+	
+      } else if (this->size() == 1u && this->getDistance(x, this->begin()->getX()) <= distance_type::precision) {
+	
+	return function_type::getValue(this->begin()->getY(), ++pX);
+	
+      } else {
+
+        return this->getExceptionHandler().action(MAKE_EXCEPTION(JFunctionalException, "not enough data " << STREAM("?") << x));	
+      }
     }
 
   protected:
@@ -419,19 +451,20 @@ namespace JTOOLS {
      */
     virtual result_type evaluate(const argument_type* pX) const override 
     {
+      const argument_type x = *pX;
+
       if (this->size() <= 1u) {
-        return this->getExceptionHandler().action(JFunctionalException("JPolintFunction<>::evaluate() not enough data."));
+        return this->getExceptionHandler().action(MAKE_EXCEPTION(JFunctionalException, "not enough data " << STREAM("?") << x));
       }
 
-      const argument_type x = *pX;
-
       const_iterator p = this->lower_bound(x);
 
       if        (p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) {
 
         try {
 
-          result   = this->getExceptionHandler().action(JValueOutOfRange("JPolintFunction<>::operator() x < xmin."));
+          result   = this->getExceptionHandler().action(MAKE_EXCEPTION(JValueOutOfRange, "abscissa out of range " 
+								       << STREAM("?") << x << " < " << STREAM("?") << this->begin() ->getX()));
 
           // overwrite integral values
 
@@ -448,7 +481,8 @@ namespace JTOOLS {
 
         try {
 
-          result   = this->getExceptionHandler().action(JValueOutOfRange("JPolintFunction<>::operator() x > xmax."));
+          result   = this->getExceptionHandler().action(MAKE_EXCEPTION(JValueOutOfRange, "abscissa out of range " 
+								       << STREAM("?") << x << " > " << STREAM("?") << this->rbegin() ->getX()));
 
           // overwrite integral values
 
@@ -640,18 +674,21 @@ namespace JTOOLS {
      */
     result_type evaluate(const argument_type* pX) const
     {
+      const argument_type x = *pX;
+
       if (this->size() <= N) {
-	THROW(JFunctionalException, "JPolintFunction<>::evaluate() not enough data.");
+        THROW(JFunctionalException, "not enough data " << STREAM("?") << x);
       }
 
-      const argument_type x = *pX;
-
       const_iterator p = this->lower_bound(x);
 
       if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
           (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
 
-        THROW(JValueOutOfRange, "JPolintFunction::evaluate() x out of range.");
+        THROW(JValueOutOfRange, "abscissa out of range " 
+	      << STREAM("?") << x                      << " <> " 
+	      << STREAM("?") << this->begin() ->getX() << ' '
+	      << STREAM("?") << this->rbegin()->getX());
       }
 
       ++pX;  // next argument value
diff --git a/src/jpp/JTools/JQuadrature.hh b/src/jpp/JTools/JQuadrature.hh
index c29f1c9..2bfaeb5 100644
--- a/src/jpp/JTools/JQuadrature.hh
+++ b/src/jpp/JTools/JQuadrature.hh
@@ -28,7 +28,7 @@ namespace JTOOLS {
   /**
    * Type definition for numerical integration.
    *
-   *          \f$\displaystyle \int_{x_1}^{x_2} f(x) dx = \sum_{i=1}^{N} w_i f(x_i) \f$
+   *          \f[\displaystyle \int_{x_1}^{x_2} f(x) dx = \sum_{i=1}^{N} w_i f(x_i) \f]
    *
    * The abscissa and ordinate values of the collection can be used
    * as abscissa and weight values of the summation to approximately
@@ -48,8 +48,8 @@ namespace JTOOLS {
     /**
      * General purpose constructor.
      *
-     * The template argument should correspond to a function requiring two arguments.
-     * These two arguments should correspond to the lower and upper integration limit, respectively.
+     * The template argument should correspond to a function requiring two arguments.\n
+     * These two arguments should correspond to the lower and upper integration limit, respectively.\n
      * The given function should return the value of the integral between the two integration limits. 
      *
      * \param  xmin       minimal x
@@ -102,7 +102,7 @@ namespace JTOOLS {
 
 
   /**
-   * Numerical integrator for <tt>W(x) = 1</tt>.
+   * Numerical integrator for \f$ W(x) = 1 \f$.
    * 
    * Gauss-Legendre integration code is taken from reference:
    * Numerical Recipes in C++, W.H. Press, S.A. Teukolsky, W.T. Vetterling and B.P. Flannery, 
@@ -163,7 +163,7 @@ namespace JTOOLS {
 
 
   /**
-   * Numerical integrator for <tt>W(x) = x^a e^(-x)</tt>.
+   * Numerical integrator for \f$ W(x) = x^{a} \, e^{-x} \f$.
    *
    * Gauss-Laguerre integration code is taken from reference:
    * Numerical Recipes in C++, W.H. Press, S.A. Teukolsky, W.T. Vetterling and B.P. Flannery, 
@@ -187,15 +187,16 @@ namespace JTOOLS {
     {
       const int number_of_iterations = 100;
 
-      double z, z1;
+      double z1;
       double p0, p1, p2, pp;
       
+      double z = (1.0 + alf) * (3.0 + 0.92*alf) / (1.0 + 2.4*n + 1.8*alf); 
+
       for (int i = 0; i < n; ++i) {
 	
 	switch (i) {
 
 	case 0:
-	  z  = (1.0 + alf) * (3.0 + 0.92*alf) / (1.0 + 2.4*n + 1.8*alf);
 	  break;
 
 	case 1:
@@ -208,10 +209,7 @@ namespace JTOOLS {
 	  break;
 	}
 
-
-	int k;
-
-	for (k = 0; k != number_of_iterations; ++k) {
+	for (int k = 0; k != number_of_iterations; ++k) {
 	  
 	  p1 = 0.0;
 	  p2 = 1.0;
@@ -242,7 +240,7 @@ namespace JTOOLS {
 
 
   /**
-   * Numerical integrator for <tt>W(x) = e^-(x^2)</tt>.
+   * Numerical integrator for \f$ W(x) = e^{-x^{2}} \f$.
    *
    * Gauss-Hermite integration code is taken from reference:
    * Numerical Recipes in C++, W.H. Press, S.A. Teukolsky, W.T. Vetterling and B.P. Flannery, 
@@ -331,8 +329,7 @@ namespace JTOOLS {
 
 
   /**
-   * Numerical integrator for <tt>W(x) = (1 + g^2 - 2gx)^a</tt>.
-   * For this, <tt>g > 0</tt>.
+   * Numerical integrator for \f$ W(x) = (1 + g^{2} - 2gx)^{a} \f$, where \f$ g > 0 \f$.
    *
    * Henyey-Greenstein integration points and weights.
    */ 
@@ -435,8 +432,7 @@ namespace JTOOLS {
 
 
   /**
-   * Numerical integrator for <tt>W(x) = (1 + g*x*x)</tt>.
-   * For this, <tt>g > 0</tt>.
+   * Numerical integrator for \f$ W(x) = 1 + g \, x^{2} \f$, where \f$ g > 0 \f$.
    *
    * Rayleigh integration points and weights.
    */ 
@@ -479,7 +475,7 @@ namespace JTOOLS {
 
 
   /**
-   * Numerical integrator for <tt>W(x) = |x| / sqrt(1 - x*x)</tt>
+   * Numerical integrator for \f$ W(x) = \left|x\right| / \sqrt{1 - x^{2}} \f$.
    *
    * Co-tangent integration points and weights.
    */ 
@@ -508,7 +504,7 @@ namespace JTOOLS {
 
 
   /**
-   * Numerical integrator for <tt>W(x) = |x| / sqrt(1 - x*x), x > 0 </tt> and <tt>W(x) =  1, x <= 0</tt>.
+   * Numerical integrator for \f$ W(x) = \left|x\right| / \sqrt{1 - x^{2}} \f$ for \f$ x > 0 \f$ and \f$ W(x) = 1 \f$ for \f$ x \le 0 \f$.
    *
    * Bi-tangent integration points and weights.
    */ 
diff --git a/src/jpp/JTools/JRange.hh b/src/jpp/JTools/JRange.hh
index 93ce131..4033778 100644
--- a/src/jpp/JTools/JRange.hh
+++ b/src/jpp/JTools/JRange.hh
@@ -375,17 +375,16 @@ namespace JTOOLS {
 
     /**
      * Test overlap with given range.\n
-     * The result is equivalent to join(range).is_valid().
      *
      * \param  range            range
      * \return                  true if there is a non-zero overlap; else false
      */
     bool overlap(const range_type& range) const
     {  
-      return (compare(getLowerLimit(), range.getUpperLimit()) &&
-	      compare(range.getLowerLimit(), getUpperLimit()));
+      return (!compare(range.getUpperLimit(), getLowerLimit()) &&
+	      !compare(getUpperLimit(), range.getLowerLimit()));
     }
-
+    
 
     /**
      * Include given value to range.\n
@@ -395,15 +394,15 @@ namespace JTOOLS {
      * \param  x                value
      * \return                  range
      */
-    range_type include(argument_type x)
+    range_type& include(argument_type x)
     {
       if (compare(x, getLowerLimit())) { setLowerLimit(x); }
       if (compare(getUpperLimit(), x)) { setUpperLimit(x); }
 
       return *this;
     }
-
-
+    
+    
     /**
      * Join ranges.\n
      * The new lower limit is the maximim of the two lower limits and\n
@@ -414,7 +413,7 @@ namespace JTOOLS {
      * \param  range            range
      */
     range_type& join(const range_type& range)
-    {  
+    {
       if (compare(getLowerLimit(), range.getLowerLimit())) { setLowerLimit(range.getLowerLimit()); }
       if (compare(range.getUpperLimit(), getUpperLimit())) { setUpperLimit(range.getUpperLimit()); }
 
@@ -437,8 +436,8 @@ namespace JTOOLS {
 
       return *this;
     }
-
-
+    
+    
     /**
      * Add offset.
      *
@@ -527,18 +526,6 @@ namespace JTOOLS {
     }
 
 
-    /**
-     * Get expected number of occurances of given rate within this interval.
-     *
-     * \param  R                rate
-     * \return                  expectation value
-     */
-    T getN(const double R) const
-    {
-      return R * (getUpperLimit() - getLowerLimit());
-    }
-
-
     /**
      * Get minimum possible value.
      *
@@ -700,7 +687,7 @@ namespace JTOOLS {
     return JRange<T, JComparator_t>(first).combine(second);
   }
 
-
+  
   /**
    * Auxiliary method to create range of values.
    *
@@ -713,6 +700,20 @@ namespace JTOOLS {
   {
     return JRange<T>(x,y);
   } 
+
+
+  /**
+   * Get expected number of occurrences due to given rate within specified interval.
+   *
+   * \param  range            interval
+   * \param  R                rate
+   * \return                  expectation value
+   */
+  template<class T>
+  inline double getN(const JRange<T>& range, const double R)
+  {
+    return R * (range.getUpperLimit() - range.getLowerLimit());
+  }
 }
 
 #endif
diff --git a/src/jpp/JTools/JResult.hh b/src/jpp/JTools/JResult.hh
index bd3f3a1..412e42f 100644
--- a/src/jpp/JTools/JResult.hh
+++ b/src/jpp/JTools/JResult.hh
@@ -374,7 +374,7 @@ namespace JTOOLS {
     /**
      * Constructor.\n
      * This constructor refers to the result of a signal with a constant rate <tt>R</tt>
-     * to produce an event occuring at the given moment <tt>x</tt> within the fixed range <tt>X</tt>.
+     * to produce an event occurring at the given moment <tt>x</tt> within the fixed range <tt>X</tt>.
      *
      * \param  R               rate
      * \param  x               abscissa value
@@ -781,7 +781,7 @@ namespace JTOOLS {
      *
      * \return                  result
      */
-    static result_type get_total_integral(typename JLANG::JClass<T>::argument_type value)
+    static result_type get_total_integral(const JResultDerivative<T>& value)
     {
       return JMATH::zero;
     }
@@ -831,7 +831,7 @@ namespace JTOOLS {
      *
      * \return                  result
      */
-    static result_type get_total_integral(typename JLANG::JClass<T>::argument_type value)
+    static result_type get_total_integral(const JResultHesse<T>& value)
     {
       return JMATH::zero;
     }
@@ -881,7 +881,7 @@ namespace JTOOLS {
      *
      * \return                  result
      */
-    static result_type get_total_integral(typename JLANG::JClass<T>::argument_type value)
+    static result_type get_total_integral(const JResultPDF<T>& value)
     {
       return JResultEvaluator<T>::get_value(value.V);
     }
@@ -931,7 +931,7 @@ namespace JTOOLS {
      *
      * \return                  result
      */
-    static result_type get_total_integral(typename JLANG::JClass<T>::argument_type value)
+    static result_type get_total_integral(const JResultPolynome<N, T>& value)
     {
       return JMATH::zero;
     }
diff --git a/src/jpp/JTools/JSet.hh b/src/jpp/JTools/JSet.hh
index b5a90c9..155838e 100644
--- a/src/jpp/JTools/JSet.hh
+++ b/src/jpp/JTools/JSet.hh
@@ -130,6 +130,40 @@ namespace JTOOLS {
 
       return *this;
     }
+
+
+    /**
+     * Read set from input.
+     *
+     * \param  in       input stream
+     * \param  object   object
+     * \return          input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JSet<JAbscissa_t>& object)
+    {
+      for (JAbscissa_t value; in >> value; ) {
+	object.insert(value);
+      }
+
+      return in;
+    }
+
+
+    /**
+     * Write set to output.
+     *
+     * \param  out      output stream
+     * \param  object   object
+     * \return          output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JSet<JAbscissa_t>& object)
+    {
+      for (typename JSet<JAbscissa_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+	out << ' ' << *i;
+      }
+
+      return out;
+    }
   };
 
 
diff --git a/src/jpp/JTools/JSpline.hh b/src/jpp/JTools/JSpline.hh
index cfd7843..e139af3 100644
--- a/src/jpp/JTools/JSpline.hh
+++ b/src/jpp/JTools/JSpline.hh
@@ -6,6 +6,7 @@
 #include "JMath/JZero.hh"
 #include "JLang/JException.hh"
 #include "JLang/JClass.hh"
+#include "JLang/JStreamAvailable.hh"
 #include "JTools/JFunctional.hh"
 #include "JTools/JDistance.hh"
 #include "JTools/JResult.hh"
@@ -364,28 +365,38 @@ namespace JTOOLS {
      */
     virtual result_type evaluate(const argument_type* pX) const override 
     {
-      if (this->size() <= 1u) {
-        return this->getExceptionHandler().action(JFunctionalException("JSplineFunction<>::evaluate() not enough data."));
-      }
-
       const argument_type x = *pX;
 
-      const_iterator p = this->lower_bound(x);
+      if (this->size() > 1u) {
 
-      if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
-          (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
+	const_iterator p = this->lower_bound(x);
 
-        return this->getExceptionHandler().action(JValueOutOfRange("JSplineFunction::evaluate() x out of range."));
-      }
+	if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
+	    (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
 
-      const_iterator q = p--;
+	  return this->getExceptionHandler().action(MAKE_EXCEPTION(JValueOutOfRange, "abscissa out of range " 
+								   << STREAM("?") << x                      << " <> " 
+								   << STREAM("?") << this->begin() ->getX() << ' '
+								   << STREAM("?") << this->rbegin()->getX()));
+	}
 
-      const double dx = this->getDistance(p->getX(), q->getX());
-      const double a  = this->getDistance(x, q->getX()) / dx;
-      const double b  = 1.0 - a;
+	const_iterator q = p--;
 
-      return a * p->getY() + b * q->getY()
-	- a*b * ((a + 1.0)*p->getU() + (b + 1.0)*q->getU()) * dx*dx/6;
+	const double dx = this->getDistance(p->getX(), q->getX());
+	const double a  = this->getDistance(x, q->getX()) / dx;
+	const double b  = 1.0 - a;
+
+	return (a * p->getY() + b * q->getY()
+		- a*b * ((a + 1.0)*p->getU() + (b + 1.0)*q->getU()) * dx*dx/6);
+	
+      } else if (this->size() == 1u && this->getDistance(x, this->begin()->getX()) <= distance_type::precision) {
+
+	return this->begin()->getY();
+	
+      } else {
+
+        return this->getExceptionHandler().action(MAKE_EXCEPTION(JFunctionalException, "not enough data " << STREAM("?") << x));
+      }
     }
   };
 
@@ -441,19 +452,22 @@ namespace JTOOLS {
      */
     virtual result_type evaluate(const argument_type* pX) const override 
     {
+      const argument_type x = *pX;
+
       if (this->size() <= 1u) {
-        return this->getExceptionHandler().action(JFunctionalException("JSplineFunction<>::evaluate() not enough data."));
+        return this->getExceptionHandler().action(MAKE_EXCEPTION(JFunctionalException, "not enough data " << STREAM("?") << x));
       }
 
-      const argument_type x = *pX;
-
       const_iterator p = this->lower_bound(x);
 
 
       if ((p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) ||
           (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision)) {
 
-        return this->getExceptionHandler().action(JValueOutOfRange("JSplineFunction::evaluate() x out of range."));
+        return this->getExceptionHandler().action(MAKE_EXCEPTION(JValueOutOfRange, "abscissa out of range " 
+								 << STREAM("?") << x                      << " <> " 
+								 << STREAM("?") << this->begin() ->getX() << ' '
+								 << STREAM("?") << this->rbegin()->getX()));
       }
 
       const_iterator q = p--;
@@ -563,11 +577,11 @@ namespace JTOOLS {
      */
     virtual result_type evaluate(const argument_type* pX) const override 
     {
+      const argument_type x = *pX;
+
       if (this->size() <= 1u) {
-        return this->getExceptionHandler().action(JFunctionalException("JSplineFunction<>::evaluate() not enough data."));
+        return this->getExceptionHandler().action(MAKE_EXCEPTION(JFunctionalException, "not enough data " << STREAM("?") << x));
       }
-      
-      const argument_type x = *pX;
 
       const_iterator p = this->lower_bound(x);
 
@@ -575,7 +589,8 @@ namespace JTOOLS {
 
 	try {
 
-	  result   = this->getExceptionHandler().action(JValueOutOfRange("JSplineFunction<>::operator() x < xmin."));
+          result   = this->getExceptionHandler().action(MAKE_EXCEPTION(JValueOutOfRange, "abscissa out of range " 
+								       << STREAM("?") << x << " < " << STREAM("?") << this->begin() ->getX()));
 
 	  // overwrite integral values
 
@@ -592,7 +607,8 @@ namespace JTOOLS {
 
 	try {
 
-	  result   = this->getExceptionHandler().action(JValueOutOfRange("JSplineFunction<>::operator() x > xmax."));
+          result   = this->getExceptionHandler().action(MAKE_EXCEPTION(JValueOutOfRange, "abscissa out of range " 
+								       << STREAM("?") << x << " > " << STREAM("?") << this->rbegin() ->getX()));
 
 	  // overwrite integral values
 
diff --git a/src/jpp/JTools/JTransformableMultiFunction.hh b/src/jpp/JTools/JTransformableMultiFunction.hh
index 125547e..cc465ee 100644
--- a/src/jpp/JTools/JTransformableMultiFunction.hh
+++ b/src/jpp/JTools/JTransformableMultiFunction.hh
@@ -8,6 +8,9 @@
 #include "JTools/JMultiMapTransformer.hh"
 #include "JTools/JFunctional.hh"
 #include "JTools/JArray.hh"
+#include "JTools/JMultiHistogram.hh"
+#include "JTools/JHistogramMap.hh"
+#include "JTools/JHistogram1D.hh"
 #include "JTools/JResultTransformer.hh"
 #include "JTools/JTransformableMultiHistogram.hh"
 
@@ -118,8 +121,8 @@ namespace JTOOLS {
      *
      * \param  input                multidimensional function
      */
-    template<class JPDF_t, class JPDFMaplist_t, class JPDFDistance_t>    
-    void insert(const JTransformableMultiFunction<JPDF_t, JPDFMaplist_t, JPDFDistance_t>& input) 
+    template<class __JFunction_t, class __JMaplist_t, class __JDistance_t>    
+    void insert(const JTransformableMultiFunction<__JFunction_t, __JMaplist_t, __JDistance_t>& input) 
     {
       this->transformer.reset(input.transformer->clone());
 
@@ -132,8 +135,8 @@ namespace JTOOLS {
      *
      * \param  input                multidimensional histogram
      */
-    template<class JHistogram_t, class JHistogramMaplist_t, class JHistogramDistance_t>
-    void insert(const JTransformableMultiHistogram<JHistogram_t, JHistogramMaplist_t, JHistogramDistance_t>& input)
+    template<class JHistogram_t, class __JMaplist_t, class __JDistance_t>
+    void insert(const JTransformableMultiHistogram<JHistogram_t, __JMaplist_t, __JDistance_t>& input)
     {
       this->transformer.reset(input.transformer->clone());
 
@@ -266,9 +269,6 @@ namespace JTOOLS {
 
 
     JLANG::JSharedPointer<transformer_type> transformer;
-
-  private:
-    mutable JArray<NUMBER_OF_DIMENSIONS, argument_type> buffer;
   };
   
 
diff --git a/src/jpp/Jeep/JColor.hh b/src/jpp/Jeep/JColor.hh
new file mode 100644
index 0000000..f64d9f0
--- /dev/null
+++ b/src/jpp/Jeep/JColor.hh
@@ -0,0 +1,27 @@
+#ifndef __JEEP__JCOLOR__
+#define __JEEP__JCOLOR__
+
+/**
+ * \file
+ * I/O coloring auxiliaries.
+ * \author mdejong
+ */
+
+#include "JLang/JColorFacet.hh"
+
+namespace JEEP {}
+namespace JPP { using namespace JEEP; }
+
+namespace JEEP {
+
+  using JLANG::RED;
+  using JLANG::GREEN;
+  using JLANG::BLUE;
+  using JLANG::WHITE;
+  using JLANG::CYAN;
+  using JLANG::PURPLE;
+  using JLANG::YELLOW;
+  using JLANG::RESET;
+  using JLANG::BOLD;
+}
+#endif
diff --git a/src/jpp/Jeep/JComparisonToolkit.hh b/src/jpp/Jeep/JComparisonToolkit.hh
new file mode 100644
index 0000000..d75b85d
--- /dev/null
+++ b/src/jpp/Jeep/JComparisonToolkit.hh
@@ -0,0 +1,69 @@
+#ifndef __JEEP__JCOMPARISONTOOLKIT__
+#define __JEEP__JCOMPARISONTOOLKIT__
+
+#include "JLang/JComparisonAvailable.hh"
+#include "JLang/JBool.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JEEP {}
+namespace JPP { using namespace JEEP; }
+
+namespace JEEP {
+
+  using JLANG::JComparisonAvailable;
+  using JLANG::JBool;
+
+    
+
+  /**
+   * Comparison of comparable objects.
+   *
+   * \param  first         first  object
+   * \param  second        second object
+   * \return               true if objects are equal; else false
+   */
+  template<class T>
+  inline bool compareObjects(const T& first,
+			     const T& second,
+			     JBool<true>)
+  {
+    return first == second;
+  }
+    
+
+  /**
+   * Comparison of uncomparable objects.
+   *
+   * \param  first         first  object
+   * \param  second        second object
+   * \return               false
+   */
+  template<class T>
+  inline bool compareObjects(const T& first,
+			     const T& second,
+			     JBool<false>)
+  {
+    return false;
+  }
+    
+
+  /**
+   * Comparison of objects.
+   *
+   * \param  first         first  object
+   * \param  second        second object
+   * \return               true if objects are comparable and equal; else false
+   */
+  template<class T>
+  inline bool compareObjects(const T& first,
+			     const T& second)
+  { 
+    return compareObjects(first, second, JBool<JComparisonAvailable<T>::has_eq>());
+  }
+}
+
+#endif
diff --git a/src/jpp/Jeep/JMessage.hh b/src/jpp/Jeep/JMessage.hh
new file mode 100644
index 0000000..fda4996
--- /dev/null
+++ b/src/jpp/Jeep/JMessage.hh
@@ -0,0 +1,102 @@
+#ifndef __JEEP__JMESSAGE__
+#define __JEEP__JMESSAGE__
+
+#include <iostream>
+
+#include "JLang/JFileStream.hh"
+#include "Jeep/JColor.hh"
+
+
+/**
+ * \file
+ * General purpose messaging.
+ * \author mdejong
+ */
+
+extern int  debug;   //!< debug level
+extern int  qaqc;    //!< QA/QC file descriptor
+
+namespace JEEP {}
+namespace JPP { using namespace JEEP; }
+
+namespace JEEP {
+
+  /**
+   * Debug level.
+   */
+  enum JMessage_t {
+    
+    debug_t   = 3,    //!< debug
+    status_t  = 2,    //!< status
+    warning_t = 2,    //!< warning
+    notice_t  = 1,    //!< notice
+    error_t   = 0,    //!< error
+    fatal_t   = 0     //!< fatal; exit
+  };
+
+
+  /**
+   * Auxiliary class for handling debug parameter within a class.
+   * Note that the derived class should include the statement <tt>using JMessage<..>::debug;</tt>
+   * otherwise the linker will fail.
+   */
+  template<class T>
+  struct JMessage {
+    static int debug;    // debug level
+  };
+
+  
+  /**
+   * debug level (default is off).
+   */
+  template<class T>
+  int JMessage<T>::debug = 0;
+}
+
+
+/**
+ * Message macros.
+ *
+ * \param  A          std::ostream compatible output
+ */
+#define DEBUG(A)   do { if (debug >= JEEP::debug_t)   { std::cout << A << std::flush; }          } while (0)
+#define STATUS(A)  do { if (debug >= JEEP::status_t)  { std::cout << A << std::flush; }          } while (0)
+#define NOTICE(A)  do { if (debug >= JEEP::notice_t)  { std::cerr << A << std::flush; }          } while (0)
+#define WARNING(A) do { if (debug >= JEEP::warning_t) { std::cerr << "WARNING: " << A << std::flush; }          } while (0)
+#define ERROR(A)   do {                               { std::cerr << "ERROR: "   << A << std::flush; }          } while (0)
+#define FATAL(A)   do {                               { std::cerr << "FATAL: "   << A << std::endl; exit(1);  } } while (0)
+
+
+/**
+ * Make std::ostream compatible output for variadic macro.
+ *
+ * When called,
+ *  - first argument should correspond to a dummy value;
+ *  - second to the ##__VA_ARGS__ macro; and
+ *  - third to the fall back value (e.g.\ "");
+ *
+ * \param  A           dummy value
+ * \param  B           ##__VA_ARGS__ macro
+ * \return             output
+ */
+#define VARGS_STREAM(A, B, ...) B
+
+
+/**
+ * Assert macro.
+ *
+ * \param  A          test
+ */
+#define ASSERT(A, ...)  do {						\
+    if (A) { NOTICE(JEEP::GREEN << "Test at " << __FILE__ << ":" << __LINE__ << " (" << #A << ") \"" << VARGS_STRING("", ##__VA_ARGS__, "") << "\" passed." << JEEP::RESET << std::endl); } \
+    else   { FATAL (JEEP::RED   << "Test at " << __FILE__ << ":" << __LINE__ << " (" << #A << ") \"" << VARGS_STRING("", ##__VA_ARGS__, "") << "\" failed." << JEEP::RESET << std::endl); } } while (0)
+
+
+/**
+ * QA/QC output macro.
+ *
+ * \param  A          ostream compatible output
+ */
+#define QAQC(A) do { if (qaqc > 0) { JLANG::JFileOutputStream(qaqc) << A; } } while (0)
+
+#endif
diff --git a/src/jpp/Jeep/JPrint.hh b/src/jpp/Jeep/JPrint.hh
new file mode 100644
index 0000000..cad2b94
--- /dev/null
+++ b/src/jpp/Jeep/JPrint.hh
@@ -0,0 +1,138 @@
+#ifndef __JEEP__JPRINT__
+#define __JEEP__JPRINT__
+
+#include <string>
+#include <ostream>
+#include <sstream>
+#include <iomanip>
+
+#include "JLang/JManip.hh"
+#include "Jeep/JStreamToolkit.hh"
+
+
+/**
+ * \file
+ * I/O formatting auxiliaries.
+ * \author mdejong
+ */
+namespace JEEP {}
+namespace JPP { using namespace JEEP; }
+
+
+namespace JEEP {
+
+  /**
+   * Get output stream for conversion to std::string.
+   *
+   * Note that the stream is emptied before use.
+   * 
+   * \return           output stream
+   */
+  inline std::ostream& getOstream()
+  {
+    static std::ostringstream buffer;
+
+    buffer.str("");
+
+    return buffer;
+  }
+
+
+  /**
+   * Get output C-string.
+   *
+   * Note that this method is needed to guarentee livetime of underlying std::string.
+   *
+   * \param  input     input
+   * \return           C-string
+   */
+  inline const char* getCString(const std::string& input)
+  {
+    static std::string buffer;
+
+    buffer = input;
+
+    return buffer.c_str();
+  }
+}
+
+/**
+ * Auxiliary data structure for streaming of STL containers.
+ *
+ * This manipulator transfers the following stream operation to method JEEP::writeObject
+ * so that all STL containers can directly be printed.
+ */
+struct JEEPZ
+{
+protected:
+  /**
+   * Auxiliary class for format STL containers.
+   */
+  struct JStream
+  {
+    /**
+     * Constructor.
+     *
+     * \param  out         output stream
+     */
+    JStream(std::ostream& out) :
+      out(out)
+    {}
+
+
+    /**
+     * Write value to output stream.
+     *
+     * \param  value       value
+     * \return             this JSTDStreamer
+     */
+    template<class T>
+    std::ostream& operator<<(const T& value)
+    {
+      return JEEP::writeObject(out, value);
+    }
+
+  private:
+    std::ostream& out;
+  };
+
+public:
+  /**
+   * Default constructor.
+   */
+  JEEPZ()
+  {}
+
+
+  /**
+   * Format specifier.
+   *
+   * \param  out           output stream
+   * \param  format        format
+   * \return               output stream
+   */
+  friend inline JStream operator<<(std::ostream& out, const JEEPZ& format)
+  {
+    return JStream(out);
+  }
+};
+
+
+/**
+ * Make string.
+ *
+ * \param  A           std::ostream compatible construct
+ * \return             std::string
+ */
+#define MAKE_STRING(A) (static_cast<std::ostringstream&>(JEEP::getOstream() << A << std::flush)).str()
+
+
+/**
+ * Make C-string.
+ *
+ * \param  A           std::ostream compatible construct
+ * \return             C-string
+ */
+#define MAKE_CSTRING(A) JEEP::getCString(MAKE_STRING(A))
+
+#endif
diff --git a/src/jpp/Jeep/JProperties.hh b/src/jpp/Jeep/JProperties.hh
new file mode 100644
index 0000000..cc64a39
--- /dev/null
+++ b/src/jpp/Jeep/JProperties.hh
@@ -0,0 +1,1294 @@
+#ifndef __JEEP__JPROPERTIES__
+#define __JEEP__JPROPERTIES__
+
+#include <string>
+#include <istream>
+#include <ostream>
+#include <fstream>
+#include <sstream>
+#include <map>
+#include <vector>
+
+#include "JLang/JAbstractIO.hh"
+#include "JLang/JException.hh"
+#include "JLang/JSharedPointer.hh"
+#include "JLang/JEquationParameters.hh"
+#include "JLang/JEquationFacet.hh"
+#include "JLang/JEquation.hh"
+#include "JLang/JComparisonAvailable.hh"
+#include "JLang/JCategory.hh"
+#include "JLang/JClass.hh"
+#include "Jeep/JStreamToolkit.hh"
+#include "Jeep/JComparisonToolkit.hh"
+#include "Jeep/JMessage.hh"
+
+
+/**
+ * \file
+ * Utility class to parse parameter values.
+ * \author mdejong
+ */
+namespace JEEP {}
+namespace JPP { using namespace JEEP; }
+
+namespace JEEP {
+  
+  using JLANG::JStreamInput;
+  using JLANG::JStreamOutput;
+  using JLANG::JStreamSuffixOutput;
+  using JLANG::JFileOpenException;
+  using JLANG::JFileReadException;
+  using JLANG::JSharedPointer;
+  using JLANG::JEquationParameters;
+  using JLANG::JEquationFacet;
+  using JLANG::JEquation;
+  using JLANG::JComparisonAvailable;
+  using JLANG::JPropertiesException;
+
+
+  /**
+   * Check for stream state.
+   *
+   * Note that end-of-file is not defined as an error so to normally process e.g.\ std::string and std::vector.
+   *
+   * \param  in            input stream
+   * \return               true if failure; else false
+   */
+  inline bool fail(std::istream& in)
+  {
+    return in.bad() || (in.fail() && !in.eof());
+  }
+  
+
+  /**
+   * Interface for I/O of properties element.
+   */
+  class JPropertiesElementInterface :
+    public JStreamInput,
+    public JStreamOutput,
+    public JStreamSuffixOutput
+  {
+  public:
+
+    using JStreamOutput::write;
+    using JStreamSuffixOutput::write;
+    
+    
+    /**
+     * Get properties type.
+     *
+     * \return               false
+     */
+    virtual bool is_properties() const 
+    { 
+      return false;
+    }
+
+
+    /**
+     * Equality between property element interfaces.
+     *
+     * \param  element       properties element interface
+     * \return               false
+     */
+    virtual bool equals(const JPropertiesElementInterface& element) const 
+    {
+      return false;
+    }
+  };
+
+
+  class JPropertiesElement;     // Forward declaration.
+
+
+  /**
+   * Template class for I/O of properties element. 
+   *
+   * This class implements the JPropertiesElementInterface interface.
+   */
+  template<class T>
+  class JPropertiesTemplateElement :
+    public JPropertiesElementInterface 
+  {
+
+    friend class JPropertiesElement;
+
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  value         reference of template object
+     */
+    JPropertiesTemplateElement(T& value) : 
+      JPropertiesElementInterface(),
+      object(value)
+    {}
+
+ 
+    /**
+     * Stream input.
+     *
+     * \param  in            input stream
+     * \return               input stream
+     */
+    virtual std::istream& read(std::istream& in) override 
+    {
+      using namespace std;
+
+      readObject(in, object);
+
+      string buffer;
+
+      in >> buffer;
+
+      if (!buffer.empty()) {
+	THROW(JPropertiesException, "JProperties: pending data <" << buffer << (in.peek() != EOF ? "..." : "") << ">");
+      }
+
+      return in;
+    }
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out           output stream
+     * \param  prefix        prefix
+     * \param  postfix       postfix
+     * \return               output stream
+     */
+    virtual std::ostream& write(std::ostream& out,
+				const char*   prefix, 
+				const char    postfix) const override
+    { 
+      return writeObject(out, prefix, object, postfix);
+    }
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out           output stream
+     * \return               output stream
+     */
+    virtual std::ostream& write(std::ostream& out) const override 
+    { 
+      return writeObject(out, object);
+    }
+
+
+    /**
+     * Equality between property element interfaces.
+     *
+     * \param  element       properties element interface
+     * \return               true if equal; else false
+     */
+    virtual bool equals(const JPropertiesElementInterface& element) const override 
+    { 
+      const JPropertiesTemplateElement<T>* p = dynamic_cast<const JPropertiesTemplateElement<T>*>(&element);
+
+      if (p != NULL)
+	return compareObjects(object, p->object);
+      else
+	return false;
+    }
+
+
+  protected:
+    T& object;
+  };
+
+
+  /**
+   * Template specialisation of JPropertiesTemplateElement for const data type.
+   *
+   * This class implements the JPropertiesElementInterface interface.
+   */
+  template<class T>
+  class JPropertiesTemplateElement<const T> : 
+    public JPropertiesElementInterface 
+  {
+
+    friend class JPropertiesElement;
+
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  value         reference of template object
+     */
+    JPropertiesTemplateElement(const T& value) : 
+      JPropertiesElementInterface(),
+      object(value)
+    {}
+
+
+    /**
+     * Stream input.
+     *
+     * \param  in            input stream
+     * \return               input stream
+     */
+    virtual std::istream& read(std::istream& in) override 
+    {
+      THROW(JPropertiesException, "JPropertiesTemplateElement<>::read() reading of const data type.");
+    }
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out           output stream
+     * \return               output stream
+     */
+    virtual std::ostream& write(std::ostream& out) const override 
+    { 
+      return writeObject(out, object);
+    }
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out           output stream
+     * \param  prefix        prefix
+     * \param  postfix       postfix
+     * \return               output stream
+     */
+    virtual std::ostream& write(std::ostream& out,
+				const char*   prefix, 
+				const char    postfix) const
+    { 
+      return writeObject(out, prefix, object, postfix);
+    }
+
+
+    /**
+     * Equality between property element interfaces.
+     *
+     * \param  element       properties element interface
+     * \return               true if equal; else false
+     */
+    virtual bool equals(const JPropertiesElementInterface& element) const override 
+    { 
+      const JPropertiesTemplateElement<const T>* p = dynamic_cast<const JPropertiesTemplateElement<const T>*>(&element);
+
+      if (p != NULL)
+	return compareObjects(object, p->object);
+      else
+	return false;
+    }
+
+
+  protected:
+    const T& object;
+  };
+
+
+  /**
+   * The property value class.
+   * This class consists of a pointer to the JPropertiesElementInterface.
+   * This class implements the assignment and type conversion operators.
+   */
+  class JPropertiesElement :
+    public JSharedPointer<JPropertiesElementInterface>
+  {
+  public:
+    /**
+     * Default constructor.
+     */
+    JPropertiesElement() :
+      end_marker(false)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  value         reference to template object
+     */
+    template<class T>
+    JPropertiesElement(T& value) :
+      end_marker(false)
+    {
+      reset(new JPropertiesTemplateElement<T>(value));
+    }
+
+
+    /**
+     * Equality between property elements.
+     *
+     * \param  element       properties element
+     * \return               true if equal; else false
+     */
+    bool equals(const JPropertiesElement& element) const 
+    { 
+      return get()->equals(*element.get());
+    }
+
+    
+    /**
+     * Assignment operator.
+     *
+     * \param  value         reference to template object
+     * \return               this JPropertiesElement
+     */
+    template<class T>
+    JPropertiesElement& operator=(T& value)
+    {
+      reset(new JPropertiesTemplateElement<T>(value));
+
+      return *this;
+    }
+
+    
+    /**
+     * Get value.
+     *
+     * \return               value of this JPropertiesElement
+     */
+    template<class T>
+    const T& getValue() const
+    {
+      const JPropertiesTemplateElement<T>* p = dynamic_cast<const JPropertiesTemplateElement<T>*>(this->get());
+
+      if (p != NULL)
+	return p->object;
+      else
+	THROW(JPropertiesException, "Inconsistent data type.");
+    }
+
+    
+    /**
+     * Get value.
+     *
+     * \return               value of this JPropertiesElement
+     */
+    template<class T>
+    T& getValue()
+    {
+      JPropertiesTemplateElement<T>* p = dynamic_cast<JPropertiesTemplateElement<T>*>(this->get());
+
+      if (p != NULL)
+	return p->object;
+      else
+	THROW(JPropertiesException, "Inconsistent data type.");
+    }
+
+
+    
+    /**
+     * Set value of this JPropertiesElement.
+     *
+     * \param  value         value
+     */
+    template<class T>
+    void setValue(const T& value)
+    {
+      JPropertiesTemplateElement<T>* p = dynamic_cast<JPropertiesTemplateElement<T>*>(this->get());
+
+      if (p != NULL)
+	p->object = value;
+      else
+	THROW(JPropertiesException, "Inconsistent data type.");
+    }
+
+
+    /**
+     * Convert to string.
+     *
+     * \return               value of this JPropertiesElement
+     */
+    std::string toString() const
+    {
+      std::ostringstream os;
+      
+      get()->write(os, "", '\0');
+
+      return os.str();
+    }
+
+    
+    /**
+     * Convert to template type.
+     *
+     * \return               value of this JPropertiesElement
+     */
+    template<class T>
+    T toValue() const
+    {
+      T value;
+
+      std::istringstream in(this->toString());
+
+      in >> value;
+
+      return value;
+    }
+
+    
+    /**
+     * Type conversion operator.
+     *
+     * \return               value of this JPropertiesElement
+     */
+    template<class T>
+    operator const T&() const
+    {
+      return getValue<T>();
+    }
+
+
+    /**
+     * Get end marker.
+     *
+     * \return               end marker
+     */
+    bool getEndMarker() const
+    {
+      return end_marker;
+    }
+
+
+    /**
+     * Set end marker.
+     *
+     * \param  marker        if true stop reading after this properties element, else continue
+     */
+    void setEndMarker(const bool marker)
+    {
+      end_marker = marker;
+    }
+
+
+  private:
+    bool end_marker;
+  };
+
+
+  /**
+   * Utility class to parse parameter values.
+   *
+   * The mapping between a parameter (of any type) and a value
+   * has to be defined in the user's program, e.g.
+   *
+   *\code{.cpp}
+   
+   #include "Jeep/JProperties.hh"
+
+   ifstream in(filename.c_str());
+    
+   JProperties zap;
+   
+   int    integer_value;
+   double double_value;
+   string string_value;
+   
+   zap.insert(make_property(integer_value));   // key == parameter name
+   zap.insert(make_property(double_value));    // key == parameter name
+   
+   zap["mies"] = string_value;
+   
+   zap.read(in);
+   zap.write(cout);
+   \endcode
+   */
+  class JProperties : 
+    public std::map<std::string, JPropertiesElement>,
+    public JEquationParameters,
+    public JMessage<JProperties>
+  {
+  public:
+
+    typedef std::map<std::string, JPropertiesElement>                  JMap_t;
+
+    using JMessage<JProperties>::debug;
+
+    
+    /**
+     * Utility method to strip off all leading characters from a string until specified character(s).
+     *
+     * \param  buffer        input string
+     * \param  sep           last character(s) to strip
+     * \return               modified string
+     */
+    static inline std::string getKey(const std::string& buffer, const std::string& sep)
+    {
+      using namespace std;
+
+      const size_type pos = buffer.find_last_of(sep);
+
+      if (pos != string::npos)
+	return buffer.substr(pos + 1);
+      else
+	return buffer;
+    }
+
+
+    /**
+     * Auxiliary class to handle input from file.
+     *
+     * The assignment of a value will cause the file with the corresponding name to be opened and read. 
+     * The contents of the file are processed in the same way as any input to the associated JProperties object.
+     */
+    class JFileReader {
+    public:
+      JFileReader(JProperties& __properties) :
+	properties(__properties)
+      {}
+  
+
+      /**
+       * Assignment operator.
+       *
+       * \param  file_name       file name
+       * \return                 this JFileReader
+       */
+      JFileReader& operator=(const std::string& file_name)
+      {
+	read(file_name);
+      
+	return *this;
+      }
+    
+
+      /**
+       * Stream input.
+       *
+       * \param  in              input stream
+       * \param  fileReader      file reader object
+       * \return                 input stream
+       */
+      friend inline std::istream& operator>>(std::istream& in, JProperties::JFileReader& fileReader)
+      {
+	std::string file_name;
+      
+	in >> file_name;
+      
+	fileReader.read(file_name);
+
+	return in;
+      }
+
+
+      /**
+       * Stream output.
+       *
+       * \param  out             output stream
+       * \param  fileReader      file reader
+       * \return                 output stream
+       */
+      friend inline std::ostream& operator<<(std::ostream& out, const JProperties::JFileReader& fileReader)
+      {
+	return out;
+      }
+
+
+    private:
+      /**
+       * Read properties from file.
+       *
+       * \param  file_name       file name
+       */
+      void read(const std::string& file_name)
+      {
+	std::ifstream in(file_name.c_str());
+      
+	if (!in) {
+	  THROW(JFileOpenException, "JFileReader: error opening file " << file_name);
+	}
+
+	properties.read(in);
+      
+	if (in.bad()) {
+	  THROW(JFileReadException, "JFileReader: error reading file " << file_name);
+	}
+
+	in.close();
+      }
+
+
+      JProperties& properties;
+    };
+
+
+    /**
+     * Constructor.
+     *
+     * \param  debug             debug level
+     */
+    JProperties(const int debug = 0) :
+      JMap_t(),
+      JEquationParameters()
+    {
+      this->debug = debug;
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  parameters        equation parameters
+     * \param  debug             debug level
+     */
+    JProperties(const JEquationParameters& parameters,
+		const int debug = 0) :
+      JMap_t(),
+      JEquationParameters(parameters)
+    {
+      this->debug = debug;
+    }
+
+
+    /**
+     * Put object at given key.
+     *
+     * \param  key               key
+     * \param  object            object
+     */
+    template<class T>
+    void put(const std::string& key, T& object)
+    {
+      this->insert(value_type(key, JPropertiesElement(object)));
+    }
+    
+
+    /** 
+     * Join properties objects.
+     *
+     * \param  properties        properties
+     */
+    JProperties& join(const JProperties& properties)
+    { 
+      JEquationParameters::join(properties);
+
+      insert(properties.begin(), properties.end());
+
+      return *this;
+    }
+
+    
+    /**
+     * Read equation.
+     *
+     * \param  equation          equation
+     * \return                   status
+     */
+    bool read(const JEquation& equation)
+    {
+      using namespace std;
+
+      iterator p = find(equation.getKey());
+	  
+      DEBUG("Processing key: " << equation.getKey() << ' ' << (p != end()) << endl);
+      
+      if (p != end()) {
+	  
+	istringstream is(equation.getValue());
+
+	if        (isDivision(equation.getSeparator())) {
+	    
+	  if (p->second->is_properties()) {
+
+	    p->second->read(is);
+	      
+	  } else {
+	    
+	    ERROR("JProperties::read(): no properties object after division <" << equation.getKey() << ">" << endl);
+	  }
+	  
+	} else if (isSeparator(equation.getSeparator())) {
+	  
+	  try {
+	    p->second->read(is);     
+	  }
+	  catch(const exception& error) {
+	    ERROR("JProperties::read(): read error at key <" << equation.getKey() << "> " << error.what() << endl);
+	  }
+	  
+	} else {
+	  
+	  ERROR("JProperties::read(): illegal character following key <" << equation.getKey() << "> " << equation.getSeparator() << endl);
+	}
+	
+	if (p->second.getEndMarker()) {
+	  return false;
+	}
+	
+	if (fail(is)) {
+	  
+	  ERROR("JProperties::read(): error reading data for key <" << equation.getKey() << "> " << equation.getValue() << endl);
+	}
+	
+      } else {
+	
+	WARNING("JProperties::read(): unknown key <" << equation.getKey() << ">" << endl);
+      }
+
+      return true;
+    }
+
+
+    /**
+     * Read from input string.
+     *
+     * \param  buffer            input string
+     * \return                   read status
+     */
+    bool read(const std::string& buffer) 
+    { 
+      std::istringstream in(buffer); 
+
+      return !fail(read(in));
+    }
+
+
+    /**
+     * Read from input stream.
+     *
+     * The input format is:
+     * <pre>
+     *	  [\<key\>\<sub\>]\<key\>\<sep\>\<value\>\<eol\>
+     *	  [\<key\>\<sub\>]\<key\>\<sep\>\<value\>\<eol\>
+     * </pre>
+     * In this, white spaces are ignored.
+     * The reading of key and value pairs is controlled by the JLANG::JEquationFacet class.
+     *
+     * \param  in                input stream
+     * \return                   input stream
+     */
+    std::istream& read(std::istream& in)
+    {
+      using namespace std;
+
+      in.imbue(locale(in.getloc(), new JEquationFacet(*this)));
+
+      for (JEquation equation; in >> equation && read(equation); ) {}
+
+      return in;
+    }
+
+
+    /**
+     * Read from input stream according given format.
+     *
+     * For each key in the format specification,
+     * a corresponding value will be read from the input stream.
+     *
+     * \param  in                input stream
+     * \param  format            format
+     * \return                   input stream
+     */
+    std::istream& read(std::istream& in, const std::string& format) 
+    {
+      using namespace std;
+      
+      istringstream is(format);
+
+      vector<string> buffer;
+
+      for (string key; is >> key; ) {
+        buffer.push_back(key);
+      }
+
+      return read(in, buffer.begin(), buffer.end());
+    }
+
+
+    /**
+     * Read from input stream according given format.
+     *
+     * For each key in the format specification,
+     * a corresponding value will be read from the input stream.
+     *
+     * \param  in                input stream
+     * \param  __begin           begin of format
+     * \param  __end             end   of format
+     * \return                   input stream
+     */
+    template<class T>
+    std::istream& read(std::istream& in, T __begin, T __end)
+    {
+      using namespace std;
+      
+      for (T i = __begin; i != __end; ++i) {
+
+	iterator p = find(*i);
+	  
+	if (p != end()) {
+
+	  p->second->read(in);
+	  
+	} else {
+	
+	  WARNING("JProperties::read(): unknown key <" << *i << ">" << endl);
+	}
+      }
+
+      return in;
+    }
+
+    
+    /** 
+     * Write the current parameter values.
+     *
+     * The output format is
+     *
+     *	  [\<key\>\<sub\>]\<key\>\<sep\>\<value\>\<eol\>
+     *	  [\<key\>\<sub\>]\<key\>\<sep\>\<value\>\<eol\>
+     *
+     * in this, white spaces are omitted.
+     *
+     * \param  out               output stream
+     * \return                   output stream
+     */
+    std::ostream& write(std::ostream& out) const
+    {
+      using namespace std;
+
+      for (const_iterator i = begin(); i != end(); ++i) {
+
+	char c = ' ';
+
+	if (i->second->is_properties()) {
+	  c = getDefaultDivision ();
+	} else {
+	  c = getDefaultSeparator();
+	}
+
+	i->second->write(out, (i->first + c).c_str(), getDefaultEndOfLine());
+      }
+
+      out << flush;
+
+      return out;
+    }
+
+
+    /**
+     * Write to output stream according given format.
+     *
+     * For each key in the format specification,
+     * a corresponding value will be written to the output stream.
+     *
+     * \param  out               output stream
+     * \param  format            format
+     * \return                   output stream
+     */
+    std::ostream& write(std::ostream& out, const std::string& format) 
+    {
+      using namespace std;
+      
+      istringstream is(format);
+
+      vector<string> buffer;
+
+      for (string key; is >> key; ) {
+        buffer.push_back(key);
+      }
+
+      return write(out, buffer.begin(), buffer.end());
+    }
+
+
+    /**
+     * Write to output stream according given format.
+     *
+     * For each key in the format specification,
+     * a corresponding value will be written to the output stream.
+     *
+     * \param  out               output stream
+     * \param  __begin           begin of format
+     * \param  __end             end   of format
+     * \return                   output stream
+     */
+    template<class T>
+    std::ostream& write(std::ostream& out, T __begin, T __end)
+    {
+      using namespace std;
+      
+      for (T i = __begin; i != __end; ++i) {
+
+	iterator p = find(*i);
+	  
+	if (p != end()) {
+
+	  out << getDefaultWhiteSpace();
+
+	  p->second->write(out);
+	  
+	} else {
+	
+	  WARNING("JProperties::write(): unknown key <" << *i << ">" << endl);
+	}
+      }
+
+      return out;
+    }
+
+
+    /**
+     * Stream editing of input format.
+     *
+     * For each key in the format specification,
+     * a corresponding value will be written to the output stream.
+     *
+     * \param  format            format
+     * \param  prefix            prefix  key word
+     * \param  postfix           postfix key word
+     * \return                   output stream
+     */
+    std::string sed(const std::string& format,
+		    const std::string& prefix  = "", 
+		    const std::string& postfix = "")
+    {
+      using namespace std;
+      
+      string buffer = format;
+      
+      for (iterator i = begin(); i != end(); ++i) {
+
+	string::size_type ipos = 0;
+	
+	while ((ipos = buffer.find(prefix + i->first + postfix, ipos)) != string::npos) {
+
+	  ostringstream out;
+
+	  i->second->write(out);
+
+	  buffer.replace(ipos, prefix.length() + i->first.length() + postfix.length(), out.str());
+	}
+      }
+      
+      return buffer;
+    }
+
+    
+    /**
+     * Get value.
+     *
+     * \param  key               key
+     * \return                   value of this JPropertiesElement
+     */
+    template<class T>
+    const T& getValue(const std::string& key) const
+    {
+      const_iterator i = find(key);
+
+      if (i != end())
+	return i->second.getValue<T>();
+      else
+	THROW(JPropertiesException, "Key <" << key << "> not found at JPropertiesElement::getValue()");
+    }
+
+    
+    /**
+     * Get value.
+     *
+     * \param  key               key
+     * \return                   value of this JPropertiesElement
+     */
+    template<class T>
+    T& getValue(const std::string& key) 
+    {
+      iterator i = find(key);
+
+      if (i != end())
+	return i->second.getValue<T>();
+      else
+	THROW(JPropertiesException, "Key <" << key << "> not found at JPropertiesElement::getValue()");
+    }
+
+    
+    /**
+     * Set value.
+     *
+     * \param  key               key
+     * \param  value             value
+     */
+    template<class T>
+    void setValue(const std::string& key, const T& value)
+    {
+      iterator i = find(key);
+
+      if (i != end())
+	return i->second.setValue<T>(value);
+      else
+	THROW(JPropertiesException, "Key <" << key << "> not found at JPropertiesElement::setValue()");
+    }
+
+
+    /**
+     * Get string value.
+     *
+     * \param  key               key
+     * \return                   value
+     */
+    std::string getString(const std::string& key) const
+    {
+      const_iterator i = find(key);
+
+      if (i != end())
+	return i->second.toString();
+      else
+	THROW(JPropertiesException, "Key <" << key << "> not found at JPropertiesElement::getString()");
+    }
+
+ 
+    /** 
+     * Print the current parameter values.
+     *
+     * \param  out               output stream
+     * \return                   output stream
+     */
+    std::ostream& print(std::ostream& out) const
+    {
+      write(out);
+
+      return out;
+    }
+ 
+
+    /**
+     * Stream input.
+     *
+     * \param  in                input stream
+     * \param  properties        properties
+     * \return                   input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JProperties& properties)
+    {
+      return properties.read(in); 
+    }
+  
+  
+    /**
+     * Stream output.
+     *
+     * \param  out               output stream
+     * \param  properties        properties
+     * \return                   output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JProperties& properties)
+    { 
+      return properties.write(out); 
+    }
+  };
+
+
+  /**
+   * Template specialisation for JFileReader.
+   * This class will not produce ASCII output.
+   */
+  template<>
+  class JPropertiesTemplateElement<JProperties::JFileReader> : 
+    public JPropertiesElementInterface 
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  value             reference of template bject
+     */
+    JPropertiesTemplateElement(JProperties::JFileReader& value) : 
+      JPropertiesElementInterface(),
+      object(value)
+    {}
+
+ 
+    /**
+     * Stream input.
+     *
+     * \param  in                input stream
+     * \return                   input stream
+     */
+    virtual std::istream& read(std::istream& in) override 
+    {
+      return in >> object;
+    }
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out               output stream
+     * \param  prefix            prefix
+     * \param  postfix           postfix
+     * \return                   output stream
+     */
+    virtual std::ostream& write(std::ostream& out, 
+				const char*   prefix, 
+				const char    postfix) const override
+    { 
+      return out;
+    }
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out               output stream
+     * \return                   output stream
+     */
+    virtual std::ostream& write(std::ostream& out) const override 
+    {
+      return out;
+    }
+
+
+    /**
+     * Equality between property element interfaces.
+     *
+     * \param  element           properties element interface
+     * \return                   true if equal; else false
+     */
+    virtual bool equals(const JPropertiesElementInterface& element) const override 
+    { 
+      return false;
+    }
+
+  private:
+    JProperties::JFileReader& object;
+  };
+
+
+  /**
+   * Template specialisation for JProperties.
+   */
+  template<>
+  class JPropertiesTemplateElement<JProperties> : 
+    public JPropertiesElementInterface 
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  value             reference of template bject
+     */
+    JPropertiesTemplateElement(const JProperties& value) : 
+      JPropertiesElementInterface(),
+      object(value)
+    {}
+
+ 
+    /**
+     * Stream input.
+     *
+     * \param  in                input stream
+     * \return                   input stream
+     */
+    virtual std::istream& read(std::istream& in) override 
+    {
+      object.read(in);
+
+      return in;
+    }
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out               output stream
+     * \param  prefix            prefix
+     * \param  postfix           postfix
+     * \return                   output stream
+     */
+    virtual std::ostream& write(std::ostream& out, 
+				const char*   prefix, 
+				const char    postfix) const override
+    {
+      using namespace std;
+      
+      for (JProperties::const_iterator i = object.begin(); i != object.end(); ++i) {
+	
+	char c = ' ';
+
+	if (i->second->is_properties()) {
+	  c = object.getDefaultDivision ();
+	} else {
+	  c = object.getDefaultSeparator();
+	}
+
+	i->second->write(out, (prefix + i->first + c).c_str(), postfix);
+      }
+      
+      out << flush;
+      
+      return out;
+    }
+
+
+    /**
+     * Stream output.
+     *
+     * \param  out               output stream
+     * \return                   output stream
+     */
+    virtual std::ostream& write(std::ostream& out) const override 
+    {
+      return writeObject(out, object);
+    }
+
+
+    /**
+     * Get properties type.
+     *
+     * \return                   true
+     */
+    virtual bool is_properties() const override 
+    {
+      return true;
+    }
+
+
+  private:
+    JProperties object;
+  };
+
+
+  /**
+   * Get properties of a given object.
+   *
+   * This method transfers the making of the property object to the corresponding class 
+   * whilst preserving the constness of the argument.\n
+   * The corresponding class should implement the method:
+   * <pre>
+   *   template<bool is_constant>
+   *   static JProperties getProperties(typename JCategory<T, is_constant>::reference_type object,
+   *				        const JEquationParameters& equation,
+   *				        const int debug)
+   * </pre>
+   *
+   * \param  object            object
+   * \param  parameters        equation parameters
+   * \param  debug             debug level
+   */
+  template<class T>
+  inline JProperties& getProperties(T& object,
+				    const JEquationParameters& parameters = JEquationParameters(),
+				    const int debug = 1)
+  {
+    using namespace JPP;
+
+    static JProperties properties;
+
+    properties = T::template getProperties<JClass<T>::is_constant>(object, parameters, debug);
+    
+    return properties; 
+  }
+}
+
+
+using JLANG::JEquationParameters;
+using JLANG::JCategory;
+using JEEP::JProperties;
+using JEEP::getProperties;
+
+
+/**
+ * macro to convert (template) parameter to JPropertiesElement object
+ */
+#define gmake_property(A) JProperties::value_type(JProperties::getKey(#A,".>/:"), JEEP::JPropertiesElement(A))
+
+
+#endif
diff --git a/src/jpp/Jeep/JStreamToolkit.hh b/src/jpp/Jeep/JStreamToolkit.hh
new file mode 100644
index 0000000..03a7c17
--- /dev/null
+++ b/src/jpp/Jeep/JStreamToolkit.hh
@@ -0,0 +1,538 @@
+#ifndef __JEEP__JSTREAMTOOLKIT__
+#define __JEEP__JSTREAMTOOLKIT__
+
+#include <istream>
+#include <ostream>
+#include <iterator>
+
+#include "JLang/JSTDTypes.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JEEP {}
+namespace JPP { using namespace JEEP; }
+
+namespace JEEP {
+
+  /**
+   * Stream input of object.
+   *
+   * \param  in            input stream
+   * \param  object        object
+   * \return               input stream
+   */
+  template<class T>
+  inline std::istream& readObject(std::istream& in, T& object) 
+  {
+    return in >> object;
+  }
+  
+
+  /**
+   * Stream output of object.
+   *
+   * \param  out           output stream
+   * \param  object        object
+   * \return               output stream
+   */
+  template<class T>
+  inline std::ostream& writeObject(std::ostream& out, const T& object)
+  { 
+    return out << object;
+  }
+
+
+  /**
+   * Stream output of object.
+   *
+   * \param  out           output stream
+   * \param  prefix        prefix
+   * \param  object        object
+   * \param  postfix       postfix
+   * \return               output stream
+   */
+  template<class T>
+  inline std::ostream& writeObject(std::ostream& out,
+				   const char*   prefix, 
+				   const T&      object,
+				   const char    postfix)
+  { 
+    return out << prefix << object << postfix;
+  }
+
+
+  /**
+   * Template specialisation of method readObject() for std::pair.
+   *
+   * \param  in            input stream
+   * \param  object        object
+   * \return               input stream
+   */
+  template<class JFirst_t, class JSecond_t>
+  inline std::istream& readObject(std::istream& in, std::pair<JFirst_t, JSecond_t>& object)
+  {
+    readObject(in, object.first);
+    readObject(in, object.second);
+
+    return in;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::pair.
+   *
+   * \param  out           output stream
+   * \param  object        object
+   * \return               output stream
+   */
+  template<class JFirst_t, class JSecond_t>
+  inline std::ostream& writeObject(std::ostream& out, const std::pair<JFirst_t, JSecond_t>& object)
+  { 
+    writeObject(out, object.first);
+    writeObject(out, ' ');
+    writeObject(out, object.second);
+
+    return out;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::pair.
+   *
+   * \param  out           output stream
+   * \param  prefix        prefix
+   * \param  object        object
+   * \param  postfix       postfix
+   * \return               output stream
+   */
+  template<class JFirst_t, class JSecond_t>
+  inline std::ostream& writeObject(std::ostream& out,
+				   const char*   prefix, 
+				   const std::pair<JFirst_t, JSecond_t>& object,
+				   const char    postfix)
+  { 
+    writeObject(out, prefix);
+    writeObject(out, object.first);
+    writeObject(out, ' ');
+    writeObject(out, object.second);
+    writeObject(out, postfix);
+      
+    return out;
+  }
+
+
+  /**
+   * Template specialisation of method readObject() for std::vector.
+   *
+   * \param  in            input stream
+   * \param  object        object
+   * \return               input stream
+   */
+  template<class JElement_t, class JAllocator_t>
+  inline std::istream& readObject(std::istream& in, std::vector<JElement_t, JAllocator_t>& object)
+  {
+    for (JElement_t element; readObject(in, element); ) {
+      object.push_back(element);
+    }
+    
+    return in;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::vector.
+   *
+   * \param  out           output stream
+   * \param  object        object
+   * \return               output stream
+   */
+  template<class JElement_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out, const std::vector<JElement_t, JAllocator_t>& object)
+  { 
+    for (typename std::vector<JElement_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, ' ');
+      writeObject(out, *i);
+    }
+    
+    return out;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::vector.
+   *
+   * \param  out           output stream
+   * \param  prefix        prefix
+   * \param  object        object
+   * \param  postfix       postfix
+   * \return               output stream
+   */
+  template<class JElement_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out,
+				   const char*   prefix, 
+				   const std::vector<JElement_t, JAllocator_t>& object,
+				   const char    postfix)
+  { 
+    for (typename std::vector<JElement_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, prefix, *i, postfix);
+    }
+    
+    return out;
+  }
+
+
+  /**
+   * Template specialisation of method readObject() for std::list.
+   *
+   * \param  in            input stream
+   * \param  object        object
+   * \return               input stream
+   */
+  template<class JElement_t, class JAllocator_t>
+  inline std::istream& readObject(std::istream& in, std::list<JElement_t, JAllocator_t>& object)
+  {
+    for (JElement_t element; readObject(in, element); ) {
+      object.push_back(element);
+    }
+    
+    return in;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::list.
+   *
+   * \param  out           output stream
+   * \param  object        object
+   * \return               output stream
+   */
+  template<class JElement_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out, const std::list<JElement_t, JAllocator_t>& object)
+  { 
+    for (typename std::list<JElement_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, ' ');
+      writeObject(out, *i);
+    }
+    
+    return out;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::list.
+   *
+   * \param  out           output stream
+   * \param  prefix        prefix
+   * \param  object        object
+   * \param  postfix       postfix
+   * \return               output stream
+   */
+  template<class JElement_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out,
+				   const char*   prefix, 
+				   const std::list<JElement_t, JAllocator_t>& object,
+				   const char    postfix)
+  { 
+    for (typename std::list<JElement_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, prefix, *i, postfix);
+    }
+    
+    return out;
+  }
+
+
+  /**
+   * Template specialisation of method readObject() for std::set.
+   *
+   * \param  in            input stream
+   * \param  object        object
+   * \return               input stream
+   */
+  template<class JElement_t, class JComparator_t, class JAllocator_t>
+  inline std::istream& readObject(std::istream& in, std::set<JElement_t, JComparator_t, JAllocator_t>& object)
+  {
+    for (JElement_t element; readObject(in, element); ) {
+
+      const std::pair<typename std::set<JElement_t, JComparator_t, JAllocator_t>::iterator, bool> result = object.insert(element);
+
+      if (!result.second) {
+	object.erase (result.first);
+	object.insert(element);
+      }
+    }
+    
+    return in;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::set.
+   *
+   * \param  out           output stream
+   * \param  object        object
+   * \return               output stream
+   */
+  template<class JElement_t, class JComparator_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out, const std::set<JElement_t, JComparator_t, JAllocator_t>& object)
+  { 
+    for (typename std::set<JElement_t, JComparator_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, ' ');
+      writeObject(out, *i);
+    }
+    
+    return out;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::set.
+   *
+   * \param  out           output stream
+   * \param  prefix        prefix
+   * \param  object        object
+   * \param  postfix       postfix
+   * \return               output stream
+   */
+  template<class JElement_t, class JComparator_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out,
+				   const char*   prefix, 
+				   const std::set<JElement_t, JComparator_t, JAllocator_t>& object,
+				   const char    postfix)
+  { 
+    for (typename std::set<JElement_t, JComparator_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, prefix, *i, postfix);
+    }
+    
+    return out;
+  }
+
+
+  /**
+   * Template specialisation of method readObject() for std::multiset.
+   *
+   * \param  in            input stream
+   * \param  object        object
+   * \return               input stream
+   */
+  template<class JElement_t, class JComparator_t, class JAllocator_t>
+  inline std::istream& readObject(std::istream& in, std::multiset<JElement_t, JComparator_t, JAllocator_t>& object)
+  {
+    for (JElement_t element; readObject(in, element); ) {
+      object.insert(element);
+    }
+    
+    return in;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::multiset.
+   *
+   * \param  out           output stream
+   * \param  object        object
+   * \return               output stream
+   */
+  template<class JElement_t, class JComparator_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out, const std::multiset<JElement_t, JComparator_t, JAllocator_t>& object)
+  { 
+    for (typename std::multiset<JElement_t, JComparator_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, ' ');
+      writeObject(out, *i);
+    }
+    
+    return out;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::multiset.
+   *
+   * \param  out           output stream
+   * \param  prefix        prefix
+   * \param  object        object
+   * \param  postfix       postfix
+   * \return               output stream
+   */
+  template<class JElement_t, class JComparator_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out,
+				   const char*   prefix, 
+				   const std::multiset<JElement_t, JComparator_t, JAllocator_t>& object,
+				   const char    postfix)
+  { 
+    for (typename std::multiset<JElement_t, JComparator_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, prefix, *i, postfix);
+    }
+    
+    return out;
+  }
+
+
+  /**
+   * Template specialisation of method readObject() for std::map.
+   *
+   * \param  in            input stream
+   * \param  object        object
+   * \return               input stream
+   */
+  template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>
+  inline std::istream& readObject(std::istream& in, std::map<JKey_t, JValue_t, JComparator_t, JAllocator_t>& object)
+  {
+    for (std::pair<JKey_t, JValue_t> element; readObject(in, element); ) {
+
+      const std::pair<typename std::map<JKey_t, JValue_t, JComparator_t, JAllocator_t>::iterator, bool> result = object.insert(element);
+
+      if (!result.second) {
+	result.first->second = element.second;
+      }
+    }
+
+    return in;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::map.
+   *
+   * \param  out           output stream
+   * \param  object        object
+   * \return               output stream
+   */
+  template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out, const std::map<JKey_t, JValue_t, JComparator_t, JAllocator_t>& object)
+  { 
+    for (typename std::map<JKey_t, JValue_t, JComparator_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, ' ');
+      writeObject(out, *i);
+    }
+
+    return out;
+  }
+  
+
+  /**
+   * Template specialisation of method writeObject() for std::map.
+   *
+   * \param  out           output stream
+   * \param  prefix        prefix
+   * \param  object        object
+   * \param  postfix       postfix
+   * \return               output stream
+   */
+  template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out,
+				   const char*   prefix, 
+				   const std::map<JKey_t, JValue_t, JComparator_t, JAllocator_t>& object,
+				   const char    postfix)
+  { 
+    for (typename std::map<JKey_t, JValue_t, JComparator_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, prefix, *i, postfix);
+    }
+
+    return out;
+  }
+
+
+  /**
+   * Template specialisation of method readObject() for std::multimap.
+   *
+   * \param  in            input stream
+   * \param  object        object
+   * \return               input stream
+   */
+  template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>
+  inline std::istream& readObject(std::istream& in, std::multimap<JKey_t, JValue_t, JComparator_t, JAllocator_t>& object)
+  {
+    for (std::pair<JKey_t, JValue_t> element; readObject(in, element); ) {
+      object.insert(element);
+    }
+
+    return in;
+  }
+
+
+  /**
+   * Template specialisation of method writeObject() for std::multimap.
+   *
+   * \param  out           output stream
+   * \param  object        object
+   * \return               output stream
+   */
+  template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out, const std::multimap<JKey_t, JValue_t, JComparator_t, JAllocator_t>& object)
+  { 
+    for (typename std::multimap<JKey_t, JValue_t, JComparator_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, ' ');
+      writeObject(out, *i);
+    }
+
+    return out;
+  }
+  
+
+  /**
+   * Template specialisation of method writeObject() for std::multimap.
+   *
+   * \param  out           output stream
+   * \param  prefix        prefix
+   * \param  object        object
+   * \param  postfix       postfix
+   * \return               output stream
+   */
+  template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>
+  inline std::ostream& writeObject(std::ostream& out,
+				   const char*   prefix, 
+				   const std::multimap<JKey_t, JValue_t, JComparator_t, JAllocator_t>& object,
+				   const char    postfix)
+  { 
+    for (typename std::multimap<JKey_t, JValue_t, JComparator_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
+      writeObject(out, prefix, *i, postfix);
+    }
+
+    return out;
+  }
+  
+
+  /**
+   * Write array of objects. 
+   *
+   * \param  out           output stream
+   * \param  left          left  bracket
+   * \param  right         right bracket
+   * \param  sep           separator
+   * \param  __begin       begin of data
+   * \param  __end         end   of data
+   * \return               output stream
+   */
+  template<class T>
+  inline std::ostream& writeArray(std::ostream& out,
+				  const char*   left,
+				  const char*   right,
+				  const char*   sep,
+				  T             __begin,
+				  T             __end)
+  { 
+    if (std::distance(__begin, __end) != 0) {
+
+      out << left;
+
+      T i = __begin;
+      
+      writeObject(out, *i); 
+      
+      while (++i != __end) {
+	
+	out << sep;
+	
+	JEEP::writeObject(out, *i); 
+      }
+      
+      out << right;
+    }
+
+    return out;
+  }
+}
+#endif
diff --git a/src/jpp/Jeep/JeepToolkit.hh b/src/jpp/Jeep/JeepToolkit.hh
index 01e5412..35210fb 100644
--- a/src/jpp/Jeep/JeepToolkit.hh
+++ b/src/jpp/Jeep/JeepToolkit.hh
@@ -8,6 +8,7 @@
 #include <map>
 
 #include "JLang/gzstream.h"
+#include "JLang/JException.hh"
 
 
 /**
@@ -25,6 +26,8 @@ namespace JPP { using namespace JEEP; }
 
 namespace JEEP {
 
+  using JLANG::JNoValue;
+
   /**
    * Nick names of environment variables.
    */
@@ -38,6 +41,43 @@ namespace JEEP {
   static const char        FILENAME_SEPARATOR   = '.';                //!< file name separator
   static const char* const TYPENAME_SEPARATOR   = "::";               //!< type name separator
   static const char        PROTOCOL_SEPARATOR   = ':';                //!< protocol  separator
+  static const char        FILENAME_WILD_CARD   = '%';                //!< wild card character for file name substitution
+
+
+  /**
+   * Check presence of wild card.
+   *
+   * \param  file_name         file name
+   * \return                   true if wild card present; else false
+   */
+  inline bool hasWildCard(const std::string& file_name)
+  {
+    return (file_name.find(FILENAME_WILD_CARD) != std::string::npos);
+  }
+
+
+  /**
+   * Get file name by setting wild card to given value.
+   *
+   * \param  file_name          input  file name
+   * \param  value              value
+   * \return                    output file name
+   */
+  inline std::string setWildCard(const std::string& file_name, const std::string& value)
+  {
+    using namespace std;
+    using namespace JPP;
+
+    string buffer = file_name;
+
+    string::size_type pos = buffer.find(FILENAME_WILD_CARD);
+
+    if (pos == string::npos) {
+      THROW(JNoValue, "Method getFilename(): Missing wild card character \'" << FILENAME_WILD_CARD << "\'.");
+    }
+
+    return buffer.replace(pos, 1, value);
+  }
 
 
   /**
diff --git a/src/jpp/README.md b/src/jpp/README.md
index c051a03..5f6023d 100644
--- a/src/jpp/README.md
+++ b/src/jpp/README.md
@@ -1,6 +1,6 @@
 # Jpp
 
-The following source files were taken from Jpp version v14.1.0-40-ge37bef90a
+The following source files were taken from Jpp version v17.0.0-rc.1-172-g2b9d6e0cb
 and are used for testing and as fallback if no Jpp environment is loaded.
 
 See https://git.km3net.de/common/jpp
diff --git a/src/jppy/JppyOscProbInterpolator.hh b/src/jppy/JppyOscProbInterpolator.hh
new file mode 100644
index 0000000..c40373c
--- /dev/null
+++ b/src/jppy/JppyOscProbInterpolator.hh
@@ -0,0 +1,161 @@
+#ifndef __JOSCPROB__JPPYOSCPROBINTERPOLATOR__
+#define __JOSCPROB__JPPYOSCPROBINTERPOLATOR__
+
+
+#include <pybind11/pybind11.h>
+#include <pybind11/numpy.h>
+
+#include "JLang/JException.hh"
+
+#include "JTools/JPolint.hh"
+#include "JTools/JMapList.hh"
+#include "JTools/JCollection.hh"
+#include "JTools/JFunction1D_t.hh"
+#include "JTools/JMultiFunction.hh"
+#include "JTools/JFunctionalMap_t.hh"
+
+#include "JOscProb/JOscChannel.hh"
+#include "JOscProb/JOscParameters.hh"
+#include "JOscProb/JOscProbInterpolator.hh"
+
+
+/**
+ * \author bjung, jbootsma, mdejong
+ */
+
+namespace JOSCPROB {};
+namespace JPP { using namespace JOSCPROB; }
+
+namespace JOSCPROB {
+
+  namespace py = pybind11;
+
+  using JLANG::JValueOutOfRange;
+  
+
+  template<template<class, class> class JCollection_t = JTOOLS::JCollection,
+	   class JFunction1D_t                        = JTOOLS::JPolintFunction1D <1,
+										   JTOOLS::JElement2D<double, JTOOLS::JArray<NUMBER_OF_OSCCHANNELS, double> >,
+										   JCollection_t,
+										   JTOOLS::JArray<NUMBER_OF_OSCCHANNELS, double> >,
+	   class JFunctionalMaplist_t                 = JTOOLS::JMAPLIST          <JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint1FunctionalMap,
+										   JTOOLS::JPolint2FunctionalMap>::maplist >
+  struct JppyOscProbInterpolator :
+    public JOscProbInterpolator<JCollection_t, JFunction1D_t, JFunctionalMaplist_t>
+  {
+    typedef JOscProbInterpolator<JCollection_t, JFunction1D_t, JFunctionalMaplist_t>                interpolator_type;
+
+    typedef typename interpolator_type::multifunction_type                                         multifunction_type;
+
+    enum { NUMBER_OF_DIMENSIONS = multifunction_type::NUMBER_OF_DIMENSIONS };
+
+    typedef typename multifunction_type::abscissa_type                                                  abscissa_type;    
+    typedef typename multifunction_type::argument_type                                                  argument_type;
+    typedef typename multifunction_type::result_type                                                      result_type;
+    typedef typename multifunction_type::value_type                                                        value_type;
+
+    typedef typename multifunction_type::multimap_type                                                  multimap_type;
+
+    typedef typename multifunction_type::super_const_iterator                                    super_const_iterator;
+    typedef typename multifunction_type::super_iterator                                                super_iterator;
+    typedef typename multifunction_type::function_type                                                  function_type;
+
+    
+    /**
+     * Default constructor.
+     */
+    JppyOscProbInterpolator() :
+      interpolator_type()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  fileName           oscillation probability table filename
+     */
+    JppyOscProbInterpolator(const char* fileName) :
+      interpolator_type(fileName)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  fileName           oscillation probability table filename
+     */
+    JppyOscProbInterpolator(const char*           fileName,
+			    const JOscParameters& parameters) :
+      interpolator_type(fileName, parameters)
+    {}
+
+
+    /**
+     * Get oscillation probability for given oscillation channel.
+     *
+     * \param  channel            oscillation channel
+     * \param  E                  neutrino energies [GeV]
+     * \param  costh              cosine zenith angles
+     * \return                    oscillation probability
+     */
+    py::array_t<double> operator()(const JOscChannel&         channel,
+				   const py::array_t<double>& E,
+				   const py::array_t<double>& costh) const {
+
+      using JLANG::JValueOutOfRange;
+
+      py::buffer_info buffer1 = E.request();
+      py::buffer_info buffer2 = costh.request();
+
+      if (buffer1.ndim != 1 || buffer2.ndim != 1) {
+	THROW(JValueOutOfRange, "JppyOscProbInterpolator<>::operator(): Input arrays are not one-dimensional.");
+      }
+ 
+      if (buffer1.shape != buffer2.shape) {
+	THROW(JValueOutOfRange, "JppyOscProbInterpolator<>::operator(): Different input array shapes (" << buffer1.size << ", " << buffer2.size << ")");
+      }
+
+      py::array_t<double> result(buffer1.size);
+      
+      py::buffer_info buffer3 = result.request();
+
+      double* ptr1 = static_cast<double*>(buffer1.ptr);
+      double* ptr2 = static_cast<double*>(buffer2.ptr);
+      double* ptr3 = static_cast<double*>(buffer3.ptr);      
+
+      for (unsigned int i = 0; i < buffer1.size; ++i) {
+	ptr3[i] = static_cast<const interpolator_type&>(*this)(channel, ptr1[i], ptr2[i]);
+      }
+
+      return result;
+    }
+
+
+    /**
+     * Get oscillation probability for a given set of oscillation parameters\n
+     * and a given oscillation channel.
+     *
+     * \param  parameters         oscillation parameters
+     * \param  channel            oscillation channel
+     * \param  E                  neutrino energies [GeV]
+     * \param  costh              cosine zenith angles
+     * \return                    oscillation probability
+     */
+    py::array_t<double> operator()(const JOscParameters&      parameters,
+				   const JOscChannel&         channel,
+				   const py::array_t<double>& E,
+				   const py::array_t<double>& costh)
+    {
+      this->set(parameters);
+      
+      return (*this)(channel, E, costh);
+    }
+  };
+}
+
+#endif
diff --git a/src/jppy/__init__.py b/src/jppy/__init__.py
index 23f9374..5e2e477 100644
--- a/src/jppy/__init__.py
+++ b/src/jppy/__init__.py
@@ -7,6 +7,8 @@ except DistributionNotFound:
     
 from . import pdf_evaluator
 from . import constants
+from . import oscprob
 from . import geane
+from . import lang
 from . import pdf
 from . import npe
diff --git a/src/jppy/geane.cc b/src/jppy/geane.cc
index 626eb08..44e0669 100644
--- a/src/jppy/geane.cc
+++ b/src/jppy/geane.cc
@@ -10,26 +10,26 @@ PYBIND11_MODULE(geane, m) {
   py::class_<JPHYSICS::JGeane>(m, "JGeane");
   py::class_<JPHYSICS::JGeane_t, JPHYSICS::JGeane>(m, "JGeane_t")
     .def(py::init<const double, const double>(),
-	 py::arg("Energy loss due to ionisation [GeV/m]"),
-	 py::arg("Energy loss due to pair production and Bremsstrahlung [m^-1]"))
+	 py::arg("a"),
+	 py::arg("b"))
     .def("get_a", &JPHYSICS::JGeane_t::getA)
     .def("get_b", &JPHYSICS::JGeane_t::getB)
     .def("get_E", &JPHYSICS::JGeane_t::getE,
-	 py::arg("Energy of muon [GeV]"),
-	 py::arg("Distance traveled [m]"))
+	 py::arg("E"),
+	 py::arg("dx"))
     .def("get_X", &JPHYSICS::JGeane_t::getX,
-	 py::arg("Energy of muon at start [GeV]"),
-	 py::arg("Energy of mun at end [GeV]")
+	 py::arg("E0"),
+	 py::arg("E1")
 	 );
   py::class_<JPHYSICS::JGeaneWater, JPHYSICS::JGeane>(m, "JGeaneWater")
     .def(py::init<>())
     .def("get_a", &JPHYSICS::JGeaneWater::getA)
     .def("get_b", &JPHYSICS::JGeaneWater::getB)
     .def("get_E", &JPHYSICS::JGeaneWater::getE,
-	 py::arg("Energy of muon [GeV]"),
-	 py::arg("Distance traveled [m]"))
+	 py::arg("E"),
+	 py::arg("dx"))
     .def("get_X", &JPHYSICS::JGeaneWater::getX,
-	 py::arg("Energy of muon at start [GeV]"),
-	 py::arg("Energy of mun at end [GeV]")
+	 py::arg("E0"),
+	 py::arg("E1")
 	 );
 }
diff --git a/src/jppy/lang.cc b/src/jppy/lang.cc
new file mode 100644
index 0000000..5f86ea7
--- /dev/null
+++ b/src/jppy/lang.cc
@@ -0,0 +1,45 @@
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include <pybind11/pybind11.h>
+
+#include "JLang/JParameter.hh"
+
+#include "utils.hh"
+
+namespace py = pybind11;
+
+namespace {
+
+  template<class T>
+  void declare_jparameter(py::module &m, const std::string& class_name) {
+
+    using namespace JPP;
+    using namespace std;
+
+    py::class_<JParameter<T> >(m, class_name.c_str())
+      .def(py::init<>())
+      .def(py::init<const T&>(),
+	   py::arg("value"))
+      .def("get_value", static_cast<const T& (JParameter<T>::*)() const>(&JParameter<T>::getValue))
+      .def("get_value", static_cast<T& (JParameter<T>::*)()>(&JParameter<T>::getValue))
+      .def("set_value", &JParameter<T>::setValue,
+	   py::arg("value"),
+	   py::pos_only())
+      .def("is_defined", &JParameter<T>::isDefined)
+      .def("less", &JParameter<T>::less,
+	   py::arg("parameter"))
+      .def("__repr__", &UTILS::get_representation<JParameter<T> >);
+  }
+}
+
+
+PYBIND11_MODULE(lang, m) {
+  
+  m.doc() = "Language auxiliary classes, interfaces and methods specific to Jpp";
+
+  declare_jparameter<int>   (m, "JParameterI");  
+  declare_jparameter<float> (m, "JParameterF");
+  declare_jparameter<double>(m, "JParameterD");
+}
diff --git a/src/jppy/oscprob.cc b/src/jppy/oscprob.cc
new file mode 100644
index 0000000..0200392
--- /dev/null
+++ b/src/jppy/oscprob.cc
@@ -0,0 +1,403 @@
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include <pybind11/pybind11.h>
+#include <pybind11/operators.h>
+#include <pybind11/numpy.h>
+
+#include "JOscProb/JOscChannel.hh"
+#include "JOscProb/JOscParametersInterface.hh"
+#include "JOscProb/JOscParameters.hh"
+#include "JOscProb/JOscProbToolkit.hh"
+#include "JOscProb/JBaselineCalculator.hh"
+#include "JOscProb/JOscProbInterpolator.hh"
+
+#include "JppyOscProbInterpolator.hh"
+
+#include "utils.hh"
+
+namespace py = pybind11;
+
+namespace {
+
+  template<class T>
+  class JppyOscParametersInterface :
+    public JOSCPROB::JOscParametersInterface<T>
+  {
+    using JOSCPROB::JOscParametersInterface<T>::JOscParametersInterface; // Inherit constructors
+
+    bool is_valid() const override { // Trampoline (needed for virtual functions)
+      PYBIND11_OVERRIDE_PURE(
+			     bool,
+			     JOSCPROB::JOscParametersInterface<T>,
+			     is_valid
+			     );
+    }
+  };
+}
+
+
+PYBIND11_MODULE(oscprob, m) {
+  
+  m.doc() = "Oscillation probability interpolation utilities";
+
+  py::class_<JOSCPROB::JOscParametersInterface<double>, JppyOscParametersInterface<double> >(m, "JOscParametersInterfaceD")
+    .def(py::init<>())
+    .def(py::init<const double, const double, const double, const double, const double, const double>(),
+	 py::arg("dM21sq"),
+	 py::arg("dM31sq"),
+	 py::arg("deltaCP"),
+	 py::arg("sinsqTh12"),
+	 py::arg("sinsqTh13"),
+	 py::arg("sinsqTh23"))
+    .def(py::init<
+	 const std::string&, const double&>(),
+	 py::arg("name"),
+	 py::arg("value"),
+	 py::pos_only())	 
+    .def(py::init<
+	 const std::string&, const double&,
+	 const std::string&, const double&>(),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value2"),
+	 py::pos_only())	 
+    .def(py::init<
+	 const std::string&, const double&,
+	 const std::string&, const double&,	 
+	 const std::string&, const double&>(),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value2"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::pos_only())	 
+    .def(py::init<
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&,	 	 
+	 const std::string&, const double&>(),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value2"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::arg("name4"),
+	 py::arg("value4"),
+	 py::pos_only())	 
+    .def(py::init<
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&,	 
+	 const std::string&, const double&,	 	 
+	 const std::string&, const double&>(),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value2"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::arg("name4"),
+	 py::arg("value4"),
+	 py::arg("name5"),
+	 py::arg("value5"),
+	 py::pos_only())	 
+    .def(py::init<
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&>(),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value2"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::arg("name4"),
+	 py::arg("value4"),
+	 py::arg("name5"),
+	 py::arg("value5"),
+	 py::arg("name6"),
+	 py::arg("value6"),
+	 py::pos_only())	 
+    .def("set", static_cast<void (JOSCPROB::JOscParametersInterface<double>::*)(const std::string&, const double&)>(&JOSCPROB::JOscParametersInterface<double>::set),
+	 py::arg("name"),
+	 py::arg("value"),
+	 py::pos_only())	 
+    .def("set", static_cast<void (JOSCPROB::JOscParametersInterface<double>::*)(const std::string&, const double&,
+							       const std::string&, const double&)>(&JOSCPROB::JOscParametersInterface<double>::set),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value2"),
+	 py::pos_only())	 
+    .def("set", static_cast<void (JOSCPROB::JOscParametersInterface<double>::*)(const std::string&, const double&,
+							       const std::string&, const double&,
+							       const std::string&, const double&)>(&JOSCPROB::JOscParametersInterface<double>::set),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value3"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::pos_only())	 
+    .def("set", static_cast<void (JOSCPROB::JOscParametersInterface<double>::*)(const std::string&, const double&,
+							       const std::string&, const double&,
+							       const std::string&, const double&,							       
+							       const std::string&, const double&)>(&JOSCPROB::JOscParametersInterface<double>::set),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value3"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::arg("name4"),
+	 py::arg("value4"),
+	 py::pos_only())	 
+    .def("set", static_cast<void (JOSCPROB::JOscParametersInterface<double>::*)(const std::string&, const double&,
+							       const std::string&, const double&,
+							       const std::string&, const double&,							       
+							       const std::string&, const double&,							       
+							       const std::string&, const double&)>(&JOSCPROB::JOscParametersInterface<double>::set),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value3"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::arg("name4"),
+	 py::arg("value4"),
+	 py::arg("name5"),
+	 py::arg("value5"),
+	 py::pos_only())
+    .def("set", static_cast<void (JOSCPROB::JOscParametersInterface<double>::*)(const std::string&, const double&,
+							       const std::string&, const double&,
+							       const std::string&, const double&,
+							       const std::string&, const double&,					   
+							       const std::string&, const double&,							       
+							       const std::string&, const double&)>(&JOSCPROB::JOscParametersInterface<double>::set),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value3"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::arg("name4"),
+	 py::arg("value4"),
+	 py::arg("name5"),
+	 py::arg("value5"),
+	 py::arg("name6"),
+	 py::arg("value6"),
+	 py::pos_only())
+    .def("join", &JOSCPROB::JOscParametersInterface<double>::join)
+    .def("is_valid",&JOSCPROB::JOscParametersInterface<double>::is_valid)
+    .def("size", &JOSCPROB::JOscParametersInterface<double>::size)
+    .def("contains", &JOSCPROB::JOscParametersInterface<double>::contains,
+	 py::arg("parameters"))
+    .def("equals", &JOSCPROB::JOscParametersInterface<double>::equals,
+	 py::arg("parameters"))
+    .def("__eq__", [](const JOSCPROB::JOscParametersInterface<double>& first,
+		      const JOSCPROB::JOscParametersInterface<double>& second) { return first == second; } )
+    .def("__ne__", [](const JOSCPROB::JOscParametersInterface<double>& first,
+		      const JOSCPROB::JOscParametersInterface<double>& second) { return first != second; } )
+    .def("__repr__", &UTILS::get_representation<JOSCPROB::JOscParametersInterface<double>>)
+    .def_readwrite("dM21sq", &JOSCPROB::JOscParametersInterface<double>::dM21sq)
+    .def_readwrite("dM31sq", &JOSCPROB::JOscParametersInterface<double>::dM31sq)
+    .def_readwrite("deltaCP", &JOSCPROB::JOscParametersInterface<double>::deltaCP)
+    .def_readwrite("sinsqTh12", &JOSCPROB::JOscParametersInterface<double>::sinsqTh12)
+    .def_readwrite("sinsqTh13", &JOSCPROB::JOscParametersInterface<double>::sinsqTh13)
+    .def_readwrite("sinsqTh23", &JOSCPROB::JOscParametersInterface<double>::sinsqTh23);
+
+  py::class_<JOSCPROB::JOscParameters, JOSCPROB::JOscParametersInterface<double> >(m, "JOscParameters")
+    .def(py::init<const double, const double, const double, const double, const double, const double>(),
+	 py::arg("dM21sq"),
+	 py::arg("dM31sq"),
+	 py::arg("deltaCP"),
+	 py::arg("sinsqTh12"),
+	 py::arg("sinsqTh13"),
+	 py::arg("sinsqTh23"))
+    .def(py::init<const bool>(),
+	 py::arg("useIO"))
+    .def(py::init<
+	 const std::string&, const double&>(),
+	 py::arg("name"),
+	 py::arg("value"),
+	 py::pos_only())	 
+    .def(py::init<
+	 const std::string&, const double&,
+	 const std::string&, const double&>(),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value2"),
+	 py::pos_only())	 
+    .def(py::init<
+	 const std::string&, const double&,
+	 const std::string&, const double&,	 
+	 const std::string&, const double&>(),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value2"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::pos_only())	 
+    .def(py::init<
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&,	 	 
+	 const std::string&, const double&>(),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value2"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::arg("name4"),
+	 py::arg("value4"),
+	 py::pos_only())	 
+    .def(py::init<
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&,	 
+	 const std::string&, const double&,	 	 
+	 const std::string&, const double&>(),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value2"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::arg("name4"),
+	 py::arg("value4"),
+	 py::arg("name5"),
+	 py::arg("value5"),
+	 py::pos_only())	 
+    .def(py::init<
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&,
+	 const std::string&, const double&>(),
+	 py::arg("name1"),
+	 py::arg("value1"),
+	 py::arg("name2"),
+	 py::arg("value2"),
+	 py::arg("name3"),
+	 py::arg("value3"),
+	 py::arg("name4"),
+	 py::arg("value4"),
+	 py::arg("name5"),
+	 py::arg("value5"),
+	 py::arg("name6"),
+	 py::arg("value6"),
+	 py::pos_only())	 
+    .def("is_valid",&JOSCPROB::JOscParameters::is_valid);
+    
+  py::enum_<JOSCPROB::JFlavour_t>(m, "JFlavour_t")
+    .value("ELECTRON",JOSCPROB::JFlavour_t::ELECTRON)
+    .value("MUON",JOSCPROB::JFlavour_t::MUON)
+    .value("TAU",JOSCPROB::JFlavour_t::TAU)
+    .value("FLAVOUR_UNDEFINED",JOSCPROB::JFlavour_t::FLAVOUR_UNDEFINED);
+    
+  py::enum_<JOSCPROB::JChargeParity_t>(m, "JChargeParity_t")
+    .value("ANTIPARTICLE",JOSCPROB::JChargeParity_t::ANTIPARTICLE)
+    .value("PARTICLE",JOSCPROB::JChargeParity_t::PARTICLE)
+    .value("CPARITY_UNDEFINED",JOSCPROB::JChargeParity_t::CPARITY_UNDEFINED);
+
+  py::enum_<JOSCPROB::OscProbFlavour_t>(m, "OscProbFlavour_t")
+    .value("ELECTRON",JOSCPROB::OscProbFlavour_t::ELECTRON)
+    .value("MUON",JOSCPROB::OscProbFlavour_t::MUON)
+    .value("TAU",JOSCPROB::OscProbFlavour_t::TAU);
+
+  m.def("get_flavour", static_cast<JOSCPROB::JFlavour_t (*)(const int)>(&JOSCPROB::getFlavour));
+  m.def("get_charge_parity", static_cast<JOSCPROB::JChargeParity_t (*)(const int)>(&JOSCPROB::getChargeParity));
+  m.def("get_oscprob_flavour", static_cast<JOSCPROB::OscProbFlavour_t (*)(const int)>(&JOSCPROB::getOscProbFlavour));
+    
+  py::class_<JOSCPROB::JOscChannel>(m, "JOscChannel")
+    .def(py::init<const JOSCPROB::JFlavour_t,
+                  const JOSCPROB::JFlavour_t,
+                  const JOSCPROB::JChargeParity_t>(),
+	 py::arg("in"),
+	 py::arg("out"),
+	 py::arg("Cparity"))
+    .def(py::init<const int, const int, const int>(),
+	 py::arg("in"),
+	 py::arg("out"),
+	 py::arg("Cparity"))
+    .def(py::self <  py::self)
+    .def(py::self >  py::self)
+    .def(py::self <= py::self)
+    .def(py::self >= py::self)
+    .def(py::self == py::self)
+    .def(py::self != py::self)
+    .def("__repr__", &UTILS::get_representation<JOSCPROB::JOscChannel>)
+    .def_readwrite("in", &JOSCPROB::JOscChannel::in)
+    .def_readwrite("out", &JOSCPROB::JOscChannel::out)
+    .def_readwrite("Cparity", &JOSCPROB::JOscChannel::Cparity);
+
+  py::class_<JOSCPROB::JBaselineCalculator>(m, "JBaselineCalculator")
+    .def(py::init<const double, const double>(),
+	 py::arg("Lmin"),
+	 py::arg("Lmax"))
+    .def("__call__", &JOSCPROB::JBaselineCalculator::operator(),
+	 py::arg("costh"))
+    .def("__repr__", &UTILS::get_representation<JOSCPROB::JBaselineCalculator>);
+    
+  py::class_<JOSCPROB::JOscProbInterpolator<>>(m, "JOscProbInterpolator")
+    .def(py::init<>())
+    .def(py::init<const char*>(),
+	 py::arg("file_name"))
+    .def(py::init<const char*, const JOSCPROB::JOscParameters&>(),
+	 py::arg("file_name"),
+	 py::arg("parameters"))
+    .def("load", &JOSCPROB::JOscProbInterpolator<>::load,
+	 py::arg("file_name"))
+    .def("get_table_parameters", &JOSCPROB::JOscProbInterpolator<>::getTableParameters)
+    .def("get_baseline_calculator", &JOSCPROB::JOscProbInterpolator<>::getBaselineCalculator)
+    .def("__call__", static_cast<double (JOSCPROB::JOscProbInterpolator<>::*)(const JOSCPROB::JOscChannel&,
+    									      const double,
+    									      const double) const>(&JOSCPROB::JOscProbInterpolator<>::operator()),
+    	 py::arg("channel"),
+    	 py::arg("E"),
+    	 py::arg("costh"))
+    .def("__call__", static_cast<double (JOSCPROB::JOscProbInterpolator<>::*)(const JOSCPROB::JOscParameters&,
+									      const JOSCPROB::JOscChannel&,
+									      const double,
+									      const double)>(&JOSCPROB::JOscProbInterpolator<>::operator()),
+	 py::arg("parameters"),	 
+	 py::arg("channel"),
+	 py::arg("E"),
+	 py::arg("costh")
+	 );
+    
+    py::class_<JOSCPROB::JppyOscProbInterpolator<>, JOSCPROB::JOscProbInterpolator<> >(m, "JppyOscProbInterpolator")
+    .def(py::init<>())
+    .def(py::init<const char*>(),
+	 py::arg("file_name")) 
+    .def(py::init<const char*, const JOSCPROB::JOscParameters&>(),
+	 py::arg("file_name"),
+	 py::arg("parameters"))
+    .def("__call__", static_cast<py::array_t<double> (JOSCPROB::JppyOscProbInterpolator<>::*)(const JOSCPROB::JOscChannel&,
+    									                      const py::array_t<double>&,
+    									                      const py::array_t<double>&) const>(&JOSCPROB::JppyOscProbInterpolator<>::operator()),
+    	 py::arg("channel"),
+    	 py::arg("E"),
+    	 py::arg("costh"))
+    .def("__call__", static_cast<py::array_t<double> (JOSCPROB::JppyOscProbInterpolator<>::*)(const JOSCPROB::JOscParameters&,
+									                      const JOSCPROB::JOscChannel&,
+                                                                                              const py::array_t<double>&,
+									                      const py::array_t<double>&)>(&JOSCPROB::JppyOscProbInterpolator<>::operator()),
+	 py::arg("parameters"),	 
+	 py::arg("channel"),
+	 py::arg("E"),
+	 py::arg("costh")
+	 );
+}
diff --git a/src/jppy/pdf_evaluator.py b/src/jppy/pdf_evaluator.py
index 3ad447f..c76a0a0 100644
--- a/src/jppy/pdf_evaluator.py
+++ b/src/jppy/pdf_evaluator.py
@@ -47,7 +47,7 @@ class PDF(object, metaclass=ABCMeta):
 
     @t0.setter
     def t0(self, value):
-        self._t0 = float(t0)
+        self._t0 = float(value)
 
     @abstractmethod
     def evaluate(self, D, cd, theta, phi, t_obs):
diff --git a/src/jppy/utils.hh b/src/jppy/utils.hh
new file mode 100644
index 0000000..68d90de
--- /dev/null
+++ b/src/jppy/utils.hh
@@ -0,0 +1,28 @@
+#ifndef __JPPY_UTILS__
+#define __JPPY_UTILS__
+
+#include <iostream>
+#include <sstream>
+#include <string>
+
+namespace UTILS {
+
+  /**
+   * Auxiliary function for defining the representation of a class object.\n
+   * The stream output operator must be defined for the given class.
+   *
+   * \param  object           class object
+   */
+  template<class T>
+  std::string get_representation(const T& object) {
+
+    using namespace std;
+
+    stringstream stream;
+    stream << object;
+    
+    return stream.str();
+  }
+}
+
+#endif
diff --git a/tests/test_joscprob.py b/tests/test_joscprob.py
new file mode 100644
index 0000000..0a96062
--- /dev/null
+++ b/tests/test_joscprob.py
@@ -0,0 +1,78 @@
+import unittest
+import jppy
+
+class TestOscParameters(unittest.TestCase):
+    def test_oscparameters(self):
+        parameters1 = jppy.oscprob.JOscParameters("sinsqTh12", 0.304,
+                                                  "deltaCP",   1.544,
+                                                  "dM21sq",    7.42e-5)
+
+        print("parameters1:\n", parameters1)
+
+        assert(parameters1.is_valid() and parameters1.size() == 3)
+
+        parameters1.set("sinsqTh23", -0.5)
+
+        print("parameters1.sinsqTh23 = -0.5 -> parameters1:\n", parameters1)
+
+        assert(not parameters1.is_valid() and parameters1.size() == 4)
+
+        parameters2 = jppy.oscprob.JOscParameters("dM31sq",   -2.49e-3,
+                                                  "sinsqTh13", 0.02241,
+                                                  "sinsqTh23", 0.570)
+
+        print("parameters2:\n", parameters2)
+
+        assert(parameters2.is_valid() and parameters2.size() == 3)
+        assert(parameters1 != parameters2)
+        assert(not parameters1.contains(parameters2))
+
+        print("Joining parameters2 with parameters1")
+
+        parameters1.join(parameters2)
+
+        assert(parameters1.is_valid() and parameters1.size() == 6)
+        assert(parameters1.contains(parameters2))
+
+class TestOscChannel(unittest.TestCase):
+    def test_oscchannel(self):
+        # Test comparisons
+        channel1 = jppy.oscprob.JOscChannel(14,16,1)
+
+        print("channel1:\n", channel1)
+
+        channel2 = jppy.oscprob.JOscChannel(jppy.oscprob.JFlavour_t.ELECTRON,
+                                            jppy.oscprob.JFlavour_t.MUON,
+                                            jppy.oscprob.JChargeParity_t.ANTIPARTICLE)
+
+        print("channel2:\n", channel2)
+
+        channel3 = jppy.oscprob.JOscChannel(jppy.oscprob.JFlavour_t.MUON,
+                                            jppy.oscprob.JFlavour_t.TAU,
+                                            jppy.oscprob.JChargeParity_t.ANTIPARTICLE)
+
+        print("channel3:\n", channel3)
+
+        assert(channel1 > channel2)
+        assert(channel3 > channel2)
+
+        # Test auxiliary functions
+        assert(jppy.oscprob.get_flavour(-12) == jppy.oscprob.JFlavour_t.ELECTRON)
+        assert(jppy.oscprob.get_flavour(-14) == jppy.oscprob.JFlavour_t.MUON)
+        assert(jppy.oscprob.get_flavour(-16) == jppy.oscprob.JFlavour_t.TAU)
+        assert(jppy.oscprob.get_flavour(+12) == jppy.oscprob.JFlavour_t.ELECTRON)
+        assert(jppy.oscprob.get_flavour(+14) == jppy.oscprob.JFlavour_t.MUON)
+        assert(jppy.oscprob.get_flavour(+16) == jppy.oscprob.JFlavour_t.TAU)        
+
+        assert(jppy.oscprob.get_oscprob_flavour(jppy.oscprob.JFlavour_t.ELECTRON) == jppy.oscprob.OscProbFlavour_t.ELECTRON)
+        assert(jppy.oscprob.get_oscprob_flavour(jppy.oscprob.JFlavour_t.MUON) == jppy.oscprob.OscProbFlavour_t.MUON)
+        assert(jppy.oscprob.get_oscprob_flavour(jppy.oscprob.JFlavour_t.TAU) == jppy.oscprob.OscProbFlavour_t.TAU)
+
+        assert(jppy.oscprob.get_charge_parity(-12) == jppy.oscprob.JChargeParity_t.ANTIPARTICLE)
+        assert(jppy.oscprob.get_charge_parity(-14) == jppy.oscprob.JChargeParity_t.ANTIPARTICLE)
+        assert(jppy.oscprob.get_charge_parity(-16) == jppy.oscprob.JChargeParity_t.ANTIPARTICLE)
+        assert(jppy.oscprob.get_charge_parity(+12) == jppy.oscprob.JChargeParity_t.PARTICLE)
+        assert(jppy.oscprob.get_charge_parity(+14) == jppy.oscprob.JChargeParity_t.PARTICLE)
+        assert(jppy.oscprob.get_charge_parity(+16) == jppy.oscprob.JChargeParity_t.PARTICLE)        
+        
+                                            
-- 
GitLab