From 99c80e01b193c045c55b6a607f483285896e0c06 Mon Sep 17 00:00:00 2001
From: Tamas Gal <himself@tamasgal.com>
Date: Wed, 31 Mar 2021 12:37:27 +0200
Subject: [PATCH] Add fallback sources from Jpp

---
 jpp/JIO/JBufferedIO.hh                     |  231 +++
 jpp/JIO/JFileStreamIO.hh                   |  129 ++
 jpp/JIO/JObjectBinaryIO.hh                 |   47 +
 jpp/JIO/JSerialisable.hh                   |  193 +++
 jpp/JIO/JStreamIO.hh                       |  125 ++
 jpp/JLang/JAbstractObjectStatus.hh         |   51 +
 jpp/JLang/JAbstractPointer.hh              |  133 ++
 jpp/JLang/JAssert.hh                       |   31 +
 jpp/JLang/JBinaryIO.hh                     |   61 +
 jpp/JLang/JBool.hh                         |  348 ++++
 jpp/JLang/JCC.hh                           |   17 +
 jpp/JLang/JClass.hh                        |  220 +++
 jpp/JLang/JClonable.hh                     |   77 +
 jpp/JLang/JComparable.hh                   |  311 ++++
 jpp/JLang/JEquals.hh                       |  142 ++
 jpp/JLang/JException.hh                    |  673 ++++++++
 jpp/JLang/JForwardIterator.hh              |  116 ++
 jpp/JLang/JLangToolkit.hh                  |  333 ++++
 jpp/JLang/JManip.hh                        |  716 +++++++++
 jpp/JLang/JMemory.hh                       |  120 ++
 jpp/JLang/JNullType.hh                     |   22 +
 jpp/JLang/JObjectID.hh                     |  157 ++
 jpp/JLang/JObjectIO.hh                     |  141 ++
 jpp/JLang/JPointer.hh                      |  140 ++
 jpp/JLang/JSTDTypes.hh                     |   29 +
 jpp/JLang/JSharedCounter.hh                |   98 ++
 jpp/JLang/JSharedPointer.hh                |  211 +++
 jpp/JLang/JSinglePointer.hh                |  113 ++
 jpp/JLang/JStorage.hh                      |   98 ++
 jpp/JLang/JType.hh                         |   37 +
 jpp/JLang/JVectorize.hh                    |  193 +++
 jpp/JLang/JVoid.hh                         |   26 +
 jpp/JLang/gzstream.h                       |  229 +++
 jpp/JMath/JCalculator.hh                   |   93 ++
 jpp/JMath/JConstants.hh                    |   31 +
 jpp/JMath/JLimits.hh                       |  126 ++
 jpp/JMath/JMath.hh                         |  591 +++++++
 jpp/JMath/JMathSupportkit.hh               |  231 +++
 jpp/JMath/JZero.hh                         |  108 ++
 jpp/JPhysics/JConstants.hh                 |  188 +++
 jpp/JPhysics/JGeant_t.hh                   |  140 ++
 jpp/JPhysics/JGeanz.hh                     |  194 +++
 jpp/JPhysics/JNPETable.hh                  |  216 +++
 jpp/JPhysics/JNPE_t.hh                     |  288 ++++
 jpp/JPhysics/JPDFTable.hh                  |  308 ++++
 jpp/JPhysics/JPDFToolkit.hh                |  322 ++++
 jpp/JPhysics/JPDFTransformer.hh            | 1289 +++++++++++++++
 jpp/JPhysics/JPDFTypes.hh                  |  201 +++
 jpp/JPhysics/JPDF_t.hh                     |  383 +++++
 jpp/JTools/JAbstractCollection.hh          |   88 ++
 jpp/JTools/JAbstractMultiMap.hh            |   62 +
 jpp/JTools/JArray.hh                       | 1265 +++++++++++++++
 jpp/JTools/JAssembler.hh                   |   40 +
 jpp/JTools/JCollection.hh                  |  836 ++++++++++
 jpp/JTools/JConstantFunction1D.hh          |  206 +++
 jpp/JTools/JConstants.hh                   |   22 +
 jpp/JTools/JDistance.hh                    |   55 +
 jpp/JTools/JElement.hh                     |  611 +++++++
 jpp/JTools/JFunction1D_t.hh                |  380 +++++
 jpp/JTools/JFunctional.hh                  |  394 +++++
 jpp/JTools/JFunctionalMap.hh               |  220 +++
 jpp/JTools/JFunctionalMap_t.hh             |  204 +++
 jpp/JTools/JGarbageCollection.hh           |   68 +
 jpp/JTools/JGrid.hh                        |  185 +++
 jpp/JTools/JGridCollection.hh              |  111 ++
 jpp/JTools/JGridMap.hh                     |   70 +
 jpp/JTools/JHermiteSpline.hh               |  706 +++++++++
 jpp/JTools/JHistogram.hh                   |  234 +++
 jpp/JTools/JHistogramMap.hh                |  144 ++
 jpp/JTools/JMap.hh                         |  126 ++
 jpp/JTools/JMapCollection.hh               |   23 +
 jpp/JTools/JMapList.hh                     |  149 ++
 jpp/JTools/JMappableCollection.hh          |  118 ++
 jpp/JTools/JMultiFunction.hh               |  354 +++++
 jpp/JTools/JMultiHistogram.hh              |  135 ++
 jpp/JTools/JMultiKey.hh                    |  537 +++++++
 jpp/JTools/JMultiMap.hh                    | 1669 ++++++++++++++++++++
 jpp/JTools/JMultiMapTransformer.hh         |  341 ++++
 jpp/JTools/JMultiPair.hh                   |  328 ++++
 jpp/JTools/JPair.hh                        |  234 +++
 jpp/JTools/JPolint.hh                      | 1215 ++++++++++++++
 jpp/JTools/JQuadrature.hh                  |  546 +++++++
 jpp/JTools/JQuantiles.hh                   |  360 +++++
 jpp/JTools/JRange.hh                       |  718 +++++++++
 jpp/JTools/JResult.hh                      | 1043 ++++++++++++
 jpp/JTools/JResultTransformer.hh           |   87 +
 jpp/JTools/JSet.hh                         |  163 ++
 jpp/JTools/JSpline.hh                      |  865 ++++++++++
 jpp/JTools/JToolsToolkit.hh                |  352 +++++
 jpp/JTools/JTransformableMultiFunction.hh  |  294 ++++
 jpp/JTools/JTransformableMultiHistogram.hh |  176 +++
 jpp/JTools/JTransformer.hh                 |   36 +
 jpp/Jeep/JeepToolkit.hh                    |  371 +++++
 jpp/README.md                              |    4 +
 94 files changed, 26422 insertions(+)
 create mode 100644 jpp/JIO/JBufferedIO.hh
 create mode 100644 jpp/JIO/JFileStreamIO.hh
 create mode 100644 jpp/JIO/JObjectBinaryIO.hh
 create mode 100644 jpp/JIO/JSerialisable.hh
 create mode 100644 jpp/JIO/JStreamIO.hh
 create mode 100644 jpp/JLang/JAbstractObjectStatus.hh
 create mode 100644 jpp/JLang/JAbstractPointer.hh
 create mode 100644 jpp/JLang/JAssert.hh
 create mode 100644 jpp/JLang/JBinaryIO.hh
 create mode 100644 jpp/JLang/JBool.hh
 create mode 100644 jpp/JLang/JCC.hh
 create mode 100644 jpp/JLang/JClass.hh
 create mode 100644 jpp/JLang/JClonable.hh
 create mode 100644 jpp/JLang/JComparable.hh
 create mode 100644 jpp/JLang/JEquals.hh
 create mode 100644 jpp/JLang/JException.hh
 create mode 100644 jpp/JLang/JForwardIterator.hh
 create mode 100644 jpp/JLang/JLangToolkit.hh
 create mode 100644 jpp/JLang/JManip.hh
 create mode 100644 jpp/JLang/JMemory.hh
 create mode 100644 jpp/JLang/JNullType.hh
 create mode 100644 jpp/JLang/JObjectID.hh
 create mode 100644 jpp/JLang/JObjectIO.hh
 create mode 100644 jpp/JLang/JPointer.hh
 create mode 100644 jpp/JLang/JSTDTypes.hh
 create mode 100644 jpp/JLang/JSharedCounter.hh
 create mode 100644 jpp/JLang/JSharedPointer.hh
 create mode 100644 jpp/JLang/JSinglePointer.hh
 create mode 100644 jpp/JLang/JStorage.hh
 create mode 100644 jpp/JLang/JType.hh
 create mode 100644 jpp/JLang/JVectorize.hh
 create mode 100644 jpp/JLang/JVoid.hh
 create mode 100644 jpp/JLang/gzstream.h
 create mode 100644 jpp/JMath/JCalculator.hh
 create mode 100644 jpp/JMath/JConstants.hh
 create mode 100644 jpp/JMath/JLimits.hh
 create mode 100644 jpp/JMath/JMath.hh
 create mode 100644 jpp/JMath/JMathSupportkit.hh
 create mode 100644 jpp/JMath/JZero.hh
 create mode 100644 jpp/JPhysics/JConstants.hh
 create mode 100644 jpp/JPhysics/JGeant_t.hh
 create mode 100644 jpp/JPhysics/JGeanz.hh
 create mode 100644 jpp/JPhysics/JNPETable.hh
 create mode 100644 jpp/JPhysics/JNPE_t.hh
 create mode 100644 jpp/JPhysics/JPDFTable.hh
 create mode 100644 jpp/JPhysics/JPDFToolkit.hh
 create mode 100644 jpp/JPhysics/JPDFTransformer.hh
 create mode 100644 jpp/JPhysics/JPDFTypes.hh
 create mode 100644 jpp/JPhysics/JPDF_t.hh
 create mode 100644 jpp/JTools/JAbstractCollection.hh
 create mode 100644 jpp/JTools/JAbstractMultiMap.hh
 create mode 100644 jpp/JTools/JArray.hh
 create mode 100644 jpp/JTools/JAssembler.hh
 create mode 100644 jpp/JTools/JCollection.hh
 create mode 100644 jpp/JTools/JConstantFunction1D.hh
 create mode 100644 jpp/JTools/JConstants.hh
 create mode 100644 jpp/JTools/JDistance.hh
 create mode 100644 jpp/JTools/JElement.hh
 create mode 100644 jpp/JTools/JFunction1D_t.hh
 create mode 100644 jpp/JTools/JFunctional.hh
 create mode 100644 jpp/JTools/JFunctionalMap.hh
 create mode 100644 jpp/JTools/JFunctionalMap_t.hh
 create mode 100644 jpp/JTools/JGarbageCollection.hh
 create mode 100644 jpp/JTools/JGrid.hh
 create mode 100644 jpp/JTools/JGridCollection.hh
 create mode 100644 jpp/JTools/JGridMap.hh
 create mode 100644 jpp/JTools/JHermiteSpline.hh
 create mode 100644 jpp/JTools/JHistogram.hh
 create mode 100644 jpp/JTools/JHistogramMap.hh
 create mode 100644 jpp/JTools/JMap.hh
 create mode 100644 jpp/JTools/JMapCollection.hh
 create mode 100644 jpp/JTools/JMapList.hh
 create mode 100644 jpp/JTools/JMappableCollection.hh
 create mode 100644 jpp/JTools/JMultiFunction.hh
 create mode 100644 jpp/JTools/JMultiHistogram.hh
 create mode 100644 jpp/JTools/JMultiKey.hh
 create mode 100644 jpp/JTools/JMultiMap.hh
 create mode 100644 jpp/JTools/JMultiMapTransformer.hh
 create mode 100644 jpp/JTools/JMultiPair.hh
 create mode 100644 jpp/JTools/JPair.hh
 create mode 100644 jpp/JTools/JPolint.hh
 create mode 100644 jpp/JTools/JQuadrature.hh
 create mode 100644 jpp/JTools/JQuantiles.hh
 create mode 100644 jpp/JTools/JRange.hh
 create mode 100644 jpp/JTools/JResult.hh
 create mode 100644 jpp/JTools/JResultTransformer.hh
 create mode 100644 jpp/JTools/JSet.hh
 create mode 100644 jpp/JTools/JSpline.hh
 create mode 100644 jpp/JTools/JToolsToolkit.hh
 create mode 100644 jpp/JTools/JTransformableMultiFunction.hh
 create mode 100644 jpp/JTools/JTransformableMultiHistogram.hh
 create mode 100644 jpp/JTools/JTransformer.hh
 create mode 100644 jpp/Jeep/JeepToolkit.hh
 create mode 100644 jpp/README.md

diff --git a/jpp/JIO/JBufferedIO.hh b/jpp/JIO/JBufferedIO.hh
new file mode 100644
index 0000000..864c003
--- /dev/null
+++ b/jpp/JIO/JBufferedIO.hh
@@ -0,0 +1,231 @@
+#ifndef __JIO__JBUFFEREDIO__
+#define __JIO__JBUFFEREDIO__
+
+#include <algorithm>
+#include <cstring>
+
+#include "JLang/JSinglePointer.hh"
+#include "JIO/JSerialisable.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JIO {}
+namespace JPP { using namespace JIO; }
+
+namespace JIO {
+
+
+  /**
+   * Buffered binary input.
+   * This class implements the JReader interface.
+   */
+  class JBufferedReader : 
+    public JReader 
+  {
+  public:
+    /**
+     * Constructor.
+     * Note that this object owns the reader pointed to.
+     *
+     * \param  __in    pointer to reader
+     * \param  __size  size of internal buffer
+     */
+    JBufferedReader(JReader* __in, const int __size = 1048576) :
+      in(__in)
+    {
+      size   = std::max(__size, 1024);
+      buffer = new char[size];
+
+      pos = 0;
+      ls  = 0;
+      eof = true;
+    }
+
+
+    /**
+     * Destructor.
+     */
+    ~JBufferedReader()
+    {
+      delete [] buffer;
+    }
+
+
+    /**
+     * Status of reader.
+     *
+     * \return         status of this reader
+     */
+    virtual bool getStatus() const override 
+    { 
+      return in->getStatus() || !eof;
+    }
+
+
+    /**
+     * Clear status of reader.
+     */
+    virtual void clear() override 
+    {
+      in->clear();
+    }
+
+
+    /**
+     * Read byte array.
+     *
+     * \param  zbuf    pointer to byte array
+     * \param  n       number of bytes
+     * \return         number of bytes
+     */
+    virtual int read(char* zbuf, int n) override 
+    { 
+      for (int i = 0; i != n; ) {
+
+	int m = n - i;
+
+	if (m > ls - pos) {
+	  
+	  memmove(buffer, buffer + pos, ls - pos);
+	  
+	  ls  -= pos;
+	  pos  = 0;
+	  ls  += in->read(buffer + ls, size - ls); 
+
+	  if (m > ls) {
+
+	    if (ls == 0) {
+
+	      eof = true;
+
+	      return n - i;
+	    }
+
+	    m = ls;
+	  }
+	}
+
+	memcpy(zbuf + i, buffer + pos, m);
+	
+	i   += m;
+	pos += m;
+      }
+
+      eof = false;
+
+      return n;
+    }
+
+
+  protected:
+    JLANG::JSinglePointer<JReader> in;
+
+    char* buffer;  //!< internal buffer
+    int   size;    //!< size of internal buffer
+    int   pos;     //!< pointer to begin of available data
+    int   ls;      //!< pointer to end   of available data
+    bool  eof;     //!< end of file
+  };
+
+
+  /**
+   * Buffered binary output.
+   * This class implements the JWriter interface.
+   */
+  class JBufferedWriter : 
+    public JWriter 
+  {
+  public:
+    /**
+     * Constructor.
+     * Note that this object owns the writer pointed to.
+     *
+     * \param  __out   pointer to writer
+     * \param  __size  size of internal buffer
+     */
+    JBufferedWriter(JWriter* __out, const int __size = 1048576) :
+      out(__out)
+    {
+      size   = std::max(__size, 1024);
+      buffer = new char[size];
+
+      pos = 0;
+    }
+
+
+    /**
+     * Destructor.
+     */
+    ~JBufferedWriter()
+    {
+      flush();
+
+      delete [] buffer;
+    }
+
+
+    /**
+     * Status of writer.
+     *
+     * \return         status of this writer
+     */
+    virtual bool getStatus() const override 
+    { 
+      return (bool) *out;
+    }
+
+
+    /**
+     * Write byte array.
+     *
+     * \param  zbuf    pointer to byte array
+     * \param  n       number of bytes
+     * \return         number of bytes
+     */
+    virtual int write(const char* zbuf, int n) override 
+    { 
+      for (int i = 0; i != n; ) {
+
+	int m = n - i;
+
+	if (m > size - pos) {
+
+	  flush();
+	
+	  if (m > size - pos) {
+	    m = size - pos;
+	  }
+	}
+
+	memcpy(buffer + pos, zbuf + i, m);
+	
+	i   += m;
+	pos += m;
+      }
+
+      return n;
+    }
+
+    
+    /**
+     * Write internal data to output.
+     */
+    void flush()
+    {
+      pos -= out->write(buffer, pos); 
+    }
+
+
+  protected:
+    JLANG::JSinglePointer<JWriter> out;
+
+    char* buffer;  //!< internal buffer
+    int   size;    //!< size of internal buffer
+    int   pos;     //!< pointer to end of buffered data
+  };
+}
+
+#endif
diff --git a/jpp/JIO/JFileStreamIO.hh b/jpp/JIO/JFileStreamIO.hh
new file mode 100644
index 0000000..f6640de
--- /dev/null
+++ b/jpp/JIO/JFileStreamIO.hh
@@ -0,0 +1,129 @@
+#ifndef __JIO__JFILESTREAMIO__
+#define __JIO__JFILESTREAMIO__
+
+#include <fstream>
+
+#include "JIO/JStreamIO.hh"
+#include "JIO/JBufferedIO.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JIO {}
+namespace JPP { using namespace JIO; }
+
+namespace JIO {
+
+  /**
+   * Binary buffered file input.
+   */
+  class JFileStreamReader :
+    public std::ifstream,
+    public JBufferedReader
+  {
+  public:
+
+    using JAbstractObjectStatus::operator bool;
+    using JAbstractObjectStatus::operator!;
+    using JReader::operator>>;
+
+
+    /**
+     * Default constructor.
+     */
+    JFileStreamReader() :
+      std::ifstream(),
+      JBufferedReader(new JStreamReader(static_cast<std::ifstream&>(*this)))
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param file_name       file name
+     * \param size            size of internal buffer
+     */
+    JFileStreamReader(const char* file_name,
+		      const int   size = 1048576) :
+      std::ifstream  (),
+      JBufferedReader(new JStreamReader(static_cast<std::ifstream&>(*this)), size)
+    {
+      open(file_name);
+    }
+
+
+    /**
+     * Open file.
+     *
+     * \param file_name       file name
+     */
+    void open(const char* file_name)
+    {
+      static_cast<std::ifstream*>(this)->open(file_name, std::ios::binary);
+    }
+  };
+
+
+  /**
+   * Binary buffered file output.
+   */
+  class JFileStreamWriter :
+    public std::ofstream,
+    public JBufferedWriter
+  {
+  public:
+
+    using JAbstractObjectStatus::operator bool;
+    using JAbstractObjectStatus::operator!;
+    using JWriter::operator<<;
+
+
+    /**
+     * Default constructor.
+     */
+    JFileStreamWriter() :
+      std::ofstream(),
+      JBufferedWriter(new JStreamWriter(static_cast<std::ofstream&>(*this)))
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param file_name       file name
+     * \param size            size of internal buffer
+     */
+    JFileStreamWriter(const char* file_name,
+		      const int   size = 1048576) :
+      std::ofstream(),
+      JBufferedWriter(new JStreamWriter(static_cast<std::ofstream&>(*this)), size)
+    {
+      open(file_name);
+    }
+
+
+    /**
+     * Open file.
+     *
+     * \param file_name       file name
+     */
+    void open(const char* file_name)
+    {
+      static_cast<std::ofstream*>(this)->open(file_name, std::ios::binary);
+    }
+
+
+    /**
+     * Close file.
+     */
+    void close()
+    {
+      static_cast<JBufferedWriter*>(this)->flush();
+      static_cast<std::ofstream*>  (this)->close();
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JIO/JObjectBinaryIO.hh b/jpp/JIO/JObjectBinaryIO.hh
new file mode 100644
index 0000000..619492b
--- /dev/null
+++ b/jpp/JIO/JObjectBinaryIO.hh
@@ -0,0 +1,47 @@
+#ifndef __JIO__JOBJECTBINARYIO__
+#define __JIO__JOBJECTBINARYIO__
+
+#include "JLang/JObjectIO.hh"
+#include "JIO/JFileStreamIO.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JIO {}
+namespace JPP { using namespace JIO; }
+
+namespace JIO {
+  
+  /**
+   * Auxiliary base class for storing and loading a single object to and from a binary 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 JObjectBinaryIO {
+    /**
+     * Load from input file.
+     *
+     * \param  file_name               file name
+     */
+    void load(const char* file_name)
+    {
+      JLANG::load<JFileStreamReader>(file_name, static_cast<T&>(*this));
+    }
+
+
+    /**
+     * Store to output file.
+     *
+     * \param  file_name               file name
+     */
+    void store(const char* file_name) const
+    {
+      JLANG::store<JFileStreamWriter>(file_name, static_cast<const T&>(*this));
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JIO/JSerialisable.hh b/jpp/JIO/JSerialisable.hh
new file mode 100644
index 0000000..e72fa05
--- /dev/null
+++ b/jpp/JIO/JSerialisable.hh
@@ -0,0 +1,193 @@
+#ifndef __JIO__JSERIALISABLE__
+#define __JIO__JSERIALISABLE__
+
+#include "JLang/JBinaryIO.hh"
+#include "JLang/JObjectID.hh"
+#include "JLang/JAbstractObjectStatus.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+/**
+ * Auxiliary classes and methods for binary I/O.
+ */
+namespace JIO {}
+namespace JPP { using namespace JIO; }
+
+namespace JIO {
+
+  using JLANG::JBinaryInput;
+  using JLANG::JBinaryOutput;
+  using JLANG::JAbstractObjectStatus;
+
+  class JReader;      //!< Forward declaration of binary input.
+  class JWriter;      //!< Forward declaration of binary output.
+
+
+  /**
+   * Interface class for a data structure with binary I/O.
+   */
+  class JSerialisable {
+  public:
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JSerialisable()
+    {}
+
+
+    /**
+     * Read from input.
+     *
+     * \param  in    JReader
+     * \return       JReader
+     */
+    virtual JReader& read(JReader& in) = 0;
+
+
+    /**
+     * Write to output.
+     *
+     * \param  out   JWriter
+     * \return       JWriter
+     */
+    virtual JWriter& write(JWriter& out) const = 0;
+  };
+
+
+  /**
+   * Interface for binary input.
+   */
+  class JReader :
+    public JLANG::JBinaryInput,
+    public JLANG::JAbstractObjectStatus
+  {
+  public:
+    /**
+     * Clear status of reader.
+     */
+    virtual void clear()
+    {}
+
+
+    /**
+     * Read serialisable data object.
+     *
+     * \param  object  serialisable data object
+     * \return         JReader
+     */
+    JReader& operator>>(JSerialisable& object) 
+    { 
+      return object.read(*this); 
+    }
+
+
+    JReader& operator>>(bool&                   value) { read((char*) &value, sizeof(bool));                   return *this; }
+    JReader& operator>>(char&                   value) { read((char*) &value, sizeof(char));                   return *this; }
+    JReader& operator>>(unsigned char&          value) { read((char*) &value, sizeof(unsigned char));          return *this; }
+    JReader& operator>>(short&                  value) { read((char*) &value, sizeof(short));                  return *this; }
+    JReader& operator>>(unsigned short&         value) { read((char*) &value, sizeof(unsigned short));         return *this; }
+    JReader& operator>>(int&                    value) { read((char*) &value, sizeof(int));                    return *this; }
+    JReader& operator>>(unsigned int&           value) { read((char*) &value, sizeof(unsigned int));           return *this; }
+    JReader& operator>>(long int&               value) { read((char*) &value, sizeof(long int));               return *this; }
+    JReader& operator>>(unsigned long int&      value) { read((char*) &value, sizeof(unsigned long int));      return *this; }
+    JReader& operator>>(long long int&          value) { read((char*) &value, sizeof(long long int));          return *this; }
+    JReader& operator>>(unsigned long long int& value) { read((char*) &value, sizeof(unsigned long long int)); return *this; }
+    JReader& operator>>(float&                  value) { read((char*) &value, sizeof(float));                  return *this; }
+    JReader& operator>>(double&                 value) { read((char*) &value, sizeof(double));                 return *this; }
+    JReader& operator>>(long double&            value) { read((char*) &value, sizeof(long double));            return *this; }
+    JReader& operator>>(JLANG::JObjectID&       value) { return (*this) >> value.getID(); }
+
+
+    /**
+     * Read object.
+     *
+     * \param  object     object
+     * \return            this reader
+     */
+    inline JReader& load(JSerialisable& object)
+    {
+      return object.read(*this);
+    }
+
+
+    /**
+     * Read object.
+     *
+     * \param  object     object
+     * \return            this reader
+     */
+    template<class T>
+    inline JReader& load(T& object)
+    {
+      return *this >> object;
+    }
+  };  
+
+
+  /**
+   * Interface for binary output.
+   */
+  class JWriter :
+    public JLANG::JBinaryOutput,
+    public JLANG::JAbstractObjectStatus
+  {
+  public:
+    /**
+     * Write serialisable data object.
+     *
+     * \param  object  serialisable data object
+     * \return         JWriter
+     */
+    JWriter& operator<<(const JSerialisable& object) 
+    { 
+      return object.write(*this); 
+    }
+
+
+    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(); }
+
+
+    /**
+     * Write object.
+     *
+     * \param  object     object
+     * \return            this writer
+     */
+    inline JWriter& store(const JSerialisable& object)
+    {
+      return object.write(*this);
+    }
+
+
+    /**
+     * Write object.
+     *
+     * \param  object     object
+     * \return            this writer
+     */
+    template<class T>
+    inline JWriter& store(const T& object)
+    {
+      return *this << object;
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JIO/JStreamIO.hh b/jpp/JIO/JStreamIO.hh
new file mode 100644
index 0000000..afc7775
--- /dev/null
+++ b/jpp/JIO/JStreamIO.hh
@@ -0,0 +1,125 @@
+#ifndef __JIO__JSTREAMIO__
+#define __JIO__JSTREAMIO__
+
+#include <istream>
+#include <ostream>
+
+#include "JIO/JSerialisable.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JIO {}
+namespace JPP { using namespace JIO; }
+
+namespace JIO {
+
+
+  /**
+   * Binary input based on std::istream.
+   * This class implements the JReader interface.
+   */
+  class JStreamReader : 
+    public JReader 
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  __in    input stream
+     */
+    JStreamReader(std::istream& __in) :
+      in(__in)
+    {}
+
+
+    /**
+     * Status of reader.
+     *
+     * \return         status of this reader
+     */
+    virtual bool getStatus() const override 
+    { 
+      return (bool) in; 
+    }
+
+
+    /**
+     * Clear status of reader.
+     */
+    virtual void clear() override 
+    {
+      in.clear();
+    }
+
+
+    /**
+     * Read byte array.
+     *
+     * \param  buffer  pointer to byte array
+     * \param  length  number of bytes
+     * \return         number of bytes read
+     */
+    virtual int read(char* buffer, const int length) override 
+    { 
+      in.read(buffer, length); 
+
+      return in.gcount();
+    }
+
+  protected:
+    std::istream& in;
+  };
+
+
+  /**
+   * Binary output based on std::ostream.
+   * This class implements the JWriter interface.
+   */
+  class JStreamWriter : 
+    public JWriter
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  __out   output stream
+     */
+    JStreamWriter(std::ostream& __out) :
+      out(__out)
+    {}
+
+
+    /**
+     * Status of writer.
+     *
+     * \return         status of this writer
+     */
+    virtual bool getStatus() const override 
+    { 
+      return (bool) out; 
+    }
+
+
+    /**
+     * Write byte array.
+     *
+     * \param  buffer  pointer to byte array
+     * \param  length  number of bytes
+     * \return         number of bytes written
+     */
+    virtual int write(const char* buffer, const int length) override 
+    { 
+      out.write(buffer, length); 
+
+      return length;
+    }
+
+  protected:
+    std::ostream& out;
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JAbstractObjectStatus.hh b/jpp/JLang/JAbstractObjectStatus.hh
new file mode 100644
index 0000000..bc683ec
--- /dev/null
+++ b/jpp/JLang/JAbstractObjectStatus.hh
@@ -0,0 +1,51 @@
+#ifndef __JLANG__JABSTRACTOBJECTSTATUS__
+#define __JLANG__JABSTRACTOBJECTSTATUS__
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Interface for status of object.\n
+   * This interface implements:
+   *    - type conversion operator <tt>bool ()</tt>; and 
+   *    - negate operator <tt>!</tt>.
+   */
+  struct JAbstractObjectStatus {
+    /**
+     * Get status of object.
+     *
+     * \return                status of this object
+     */
+    virtual bool getStatus() const = 0;
+
+
+    /**
+     * Type conversion operator.
+     *
+     * \return                status of this object
+     */
+    operator bool() const
+    {
+      return this->getStatus();
+    }
+
+
+    /**
+     * Negated status of this object.
+     *
+     * \return                negated status of this object
+     */
+    bool operator!() const
+    {
+      return !(this->getStatus());
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JAbstractPointer.hh b/jpp/JLang/JAbstractPointer.hh
new file mode 100644
index 0000000..5fcda7b
--- /dev/null
+++ b/jpp/JLang/JAbstractPointer.hh
@@ -0,0 +1,133 @@
+#ifndef __JLANG__JABSTRACTPOINTER__
+#define __JLANG__JABSTRACTPOINTER__
+
+#include <cstdlib>
+
+#include "JLang/JException.hh"
+#include "JLang/JEquals.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Template interface for pointer to object(s).
+   */
+  template<class JClass_t>
+  class JAbstractPointer :
+    public JEquals< JAbstractPointer<JClass_t> >
+  {
+  protected:
+    /**
+     * Default constructor.
+     */
+    JAbstractPointer()
+    {}
+
+
+  public:
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JAbstractPointer()
+    {}
+
+
+    /**
+     * Equals.
+     * The equality is evaluated by comparison of the internal pointers.
+     *
+     * \param  object   abstract pointer
+     * \return          true if equals; else false
+     */
+    virtual bool equals(const JAbstractPointer& object) const
+    {
+      return this->get() == object.get();
+    }
+
+
+    /**
+     * Get pointer.
+     *
+     * \return          pointer to object
+     */
+    virtual JClass_t* get() const = 0;
+
+
+    /**
+     * Set pointer.
+     *
+     * \param  p        pointer to object
+     */
+    virtual void set(JClass_t* p) = 0;
+
+
+    /**
+     * Reset pointer.
+     */
+    virtual void reset() = 0;
+
+
+    /**
+     * Check validity of pointer.
+     *
+     * \return          true if pointer not null; else false
+     */
+    bool is_valid() const 
+    { 
+      return this->get() != NULL; 
+    }
+
+
+    /**
+     * Reset pointer.
+     *
+     * \param  p        pointer to object
+     */
+    void reset(JClass_t* p)
+    {
+      if (this->get() != p) {
+
+        this->reset();
+
+        if (p != NULL) {
+          this->set(p);
+	}
+      }
+    }
+
+
+    /**
+     * Smart pointer operator.
+     *
+     * \return          pointer to object
+     */
+    JClass_t* operator->() const 
+    { 
+      if (!is_valid())
+	throw JNullPointerException("JAbstractPointer::operator->()");
+      else
+	return this->get();
+    }
+
+    
+    /**
+     * Type conversion operator.
+     *
+     * \return          pointer to object
+     */
+    operator JClass_t*() const
+    {
+      return this->get();
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JAssert.hh b/jpp/JLang/JAssert.hh
new file mode 100644
index 0000000..78e69fd
--- /dev/null
+++ b/jpp/JLang/JAssert.hh
@@ -0,0 +1,31 @@
+#ifndef __JLANG__JASSERT__
+#define __JLANG__JASSERT__
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Generation of compiler error.
+   */
+  template<bool>
+  struct JAssert;
+
+  /**
+   * Implementation of valid assertion.
+   */
+  template<>
+  struct JAssert<true> 
+  {
+    static const bool value = true;
+  };
+}
+
+#define STATIC_CHECK(expr) { JLANG::JAssert<expr>(); } 
+
+#endif
diff --git a/jpp/JLang/JBinaryIO.hh b/jpp/JLang/JBinaryIO.hh
new file mode 100644
index 0000000..ab678dc
--- /dev/null
+++ b/jpp/JLang/JBinaryIO.hh
@@ -0,0 +1,61 @@
+#ifndef __JLANG__JBINARYIO__
+#define __JLANG__JBINARYIO__
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Interface for binary input.
+   */
+  class JBinaryInput {
+  public:
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JBinaryInput()
+    {}
+
+
+    /**
+     * Read byte array.
+     *
+     * \param  buffer  pointer to byte array
+     * \param  length  number of bytes
+     * \return         number of bytes read
+     */
+    virtual int read(char* buffer, const int length) = 0;
+  };
+
+
+  /**
+   * Interface for binary output.
+   */
+  class JBinaryOutput {
+  public:
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JBinaryOutput()
+    {}
+
+
+    /**
+     * Write byte array.
+     *
+     * \param  buffer  pointer to byte array
+     * \param  length  number of bytes
+     * \return         number of bytes written
+     */
+    virtual int write(const char* buffer, const int length) = 0;
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JBool.hh b/jpp/JLang/JBool.hh
new file mode 100644
index 0000000..d50ed8a
--- /dev/null
+++ b/jpp/JLang/JBool.hh
@@ -0,0 +1,348 @@
+#ifndef __JLANG__JBOOL__
+#define __JLANG__JBOOL__
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Auxiliary template class for type bool.
+   * This class can be used for boolean expressions at compile time.
+   */ 
+  template<bool __value__> 
+  struct JBool 
+  {
+    /**
+     * Type definition of bool value.
+     */
+    typedef JBool<__value__>  bool_type;
+
+
+    /**
+     * Default construcor.
+     */
+    JBool()
+    {}
+
+    
+    /**
+     * Value.
+     */
+    static const bool value = __value__;
+
+
+    /**
+     * Type conversion operator.
+     *
+     * \return             value
+     */
+    operator bool() const
+    {
+      return value;
+    }
+    
+
+    /**
+     * Make logical NOT.
+     *
+     * \return             logical NOT
+     */
+    static JBool<!value> c_not()
+    {
+      return JBool<!value>();
+    }
+
+
+    /**
+     * Make logical EQUALS.
+     *
+     * \return             logical EQUALS
+     */
+    template<bool option>
+    static JBool<value == option> c_equals()
+    {
+      return JBool<value == option>();
+    }
+
+
+    /**
+     * Make logical EQUALS.
+     *
+     * \param  object      value
+     * \return             logical EQUALS
+     */
+    template<bool option>
+    static JBool<value == option> c_equals(const JBool<option>& object)
+    {
+      return bool_type::c_equals<option>();
+    }
+
+
+    /**
+     * Make logical AND.
+     *
+     * \return             logical AND
+     */
+    template<bool option>
+    static JBool<value && option> c_and()
+    {
+      return JBool<value && option>();
+    }
+
+
+    /**
+     * Make logical AND.
+     *
+     * \param  object      value
+     * \return             logical AND
+     */
+    template<bool option>
+    static JBool<value && option> c_and(const JBool<option>& object)
+    {
+      return bool_type::c_and<option>();
+    }
+
+
+    /**
+     * Make logical OR.
+     *
+     * \return             logical OR
+     */
+    template<bool option>
+    static JBool<value || option> c_or()
+    {
+      return JBool<value || option>();
+    }
+
+
+    /**
+     * Make logical OR.
+     *
+     * \param  object      value
+     * \return             logical OR
+     */
+    template<bool option>
+    static JBool<value || option> c_or(const JBool<option>& object)
+    {
+      return bool_type::c_or<option>();
+    }
+
+
+    /**
+     * Make logical XOR.
+     *
+     * \return             logical XOR
+     */
+    template<bool option>
+    static JBool<value != option> c_xor()
+    {
+      return JBool<value != option>();
+    }
+
+
+    /**
+     * Make logical XOR.
+     *
+     * \param  object      value
+     * \return             logical XOR
+     */
+    template<bool option>
+    static JBool<value != option> c_xor(const JBool<option>& object)
+    {
+      return bool_type::c_xor<option>();
+    }
+
+
+    /**
+     * Make logical SWITCH.
+     * If value is true, select first, else select second.
+     *
+     * \return             logical SWITCH
+     */
+    template<bool __first__, bool __second__>
+    static JBool<(value && __first__) || (!value && __second__)> c_switch()
+    {
+      return JBool<(value && __first__) || (!value && __second__)>();
+    }
+
+
+    /**
+     * Make logical SWITCH.
+     * If value is true, select first, else select second.
+     *
+     * \param  first       first  value
+     * \param  second      second value
+     * \return             logical SWITCH
+     */
+    template<bool __first__, bool __second__>
+    static JBool<(value && __first__) || (!value && __second__)> c_switch(const JBool<__first__>&  first,
+									  const JBool<__second__>& second)
+    {
+      return bool_type::c_switch<__first__, __second__>();
+    }
+  };
+
+
+  /**
+   * Make logical NOT.
+   *
+   * \param  value       value
+   * \return             logical NOT
+   */
+  template<bool __value__>
+  static JBool<!__value__> c_not(const JBool<__value__>& value)
+  {
+    return value.c_not();
+  }
+  
+
+  /**
+   * Make logical EQUALS.
+   *
+   * \param  first       first  value
+   * \param  second      second value
+   * \return             logical EQUALS
+   */
+  template<bool __first__, bool __second__>
+  inline JBool<__first__ == __second__> c_equals(const JBool<__first__>&  first,
+						 const JBool<__second__>& second)
+  {
+    return first.c_equals(second);
+  }
+
+
+  /**
+   * Make logical AND.
+   *
+   * \param  first       first  value
+   * \param  second      second value
+   * \return             logical AND
+   */
+  template<bool __first__, bool __second__>
+  inline JBool<__first__ == __second__> c_and(const JBool<__first__>&  first,
+					      const JBool<__second__>& second)
+  {
+    return first.c_and(second);
+  }
+
+
+  /**
+   * Make logical OR.
+   *
+   * \param  first       first  value
+   * \param  second      second value
+   * \return             logical OR
+   */
+  template<bool __first__, bool __second__>
+  inline JBool<__first__ == __second__> c_or(const JBool<__first__>&  first,
+					     const JBool<__second__>& second)
+  {
+    return first.c_or(second);
+  }
+
+
+  /**
+   * Make logical XOR.
+   *
+   * \param  first       first  value
+   * \param  second      second value
+   * \return             logical XOR
+   */
+  template<bool __first__, bool __second__>
+  inline JBool<__first__ == __second__> c_xor(const JBool<__first__>&  first,
+					      const JBool<__second__>& second)
+  {
+    return first.c_xor(second);
+  }
+
+
+  typedef JBool<true>    JTRUE;         //!< True  type
+  typedef JBool<false>   JFALSE;        //!< False type
+  
+  static const JTRUE     JTrue_t;       //!< True  value
+  static const JFALSE    JFalse_t;      //!< False value
+
+  
+  /**
+   * Type definition of logical EQUALS.
+   */
+  template<class JFirst_t, class JSecond_t>
+  struct EQUALS;
+
+  /**
+   * Template specialisation for logical EQUALS.
+   */
+  template<bool first, bool second>
+  struct EQUALS< JBool<first>, JBool<second> > :
+    public JBool<first == second>
+  {};
+  
+
+  /**
+   * Type definition of logical NOT.
+   */
+  template<class T>
+  struct NOT;
+
+  /**
+   * Template specialisation for logical NOT.
+   */
+  template<bool __value__>
+  struct NOT< JBool<__value__> > :
+    public JBool<!__value__>
+  {};
+  
+  
+  /**
+   * Type definition of logical AND.
+   */
+  template<class JFirst_t, class JSecond_t>
+  struct AND;
+
+  /**
+   * Template specialisation for logical AND.
+   */
+  template<bool first, bool second>
+  struct AND< JBool<first>, JBool<second> > :
+    public JBool<first && second>
+  {};
+
+
+  /**
+   * Type definition of logical OR.
+   */
+  template<class JFirst_t, class JSecond_t>
+  struct OR;
+  
+  /**
+   * Template specialisation for logical OR.
+   */  
+  template<bool first, bool second>
+  struct OR< JBool<first>, JBool<second> > :
+    public JBool<first || second>
+  {};
+
+
+  /**
+   * Type definition of logical XOR.
+   */
+  template<class JFirst_t, class JSecond_t>
+  struct XOR;
+  
+  /**
+   * Template specialisation for logical XOR.
+   */  
+  template<bool first, bool second>
+  struct XOR< JBool<first>, JBool<second> > :
+    public JBool<first != second>
+  {};
+}
+
+#endif
diff --git a/jpp/JLang/JCC.hh b/jpp/JLang/JCC.hh
new file mode 100644
index 0000000..5e19830
--- /dev/null
+++ b/jpp/JLang/JCC.hh
@@ -0,0 +1,17 @@
+#ifndef __JLANG_JCC__
+#define __JLANG_JCC__
+
+//#include "RVersion.h"
+
+/**
+ * \file
+ * Compiler version dependent expressions, macros, etc.
+ * \author mdejong
+ */
+
+//#if __GNUC__ == 4 && __GNUC_MINOR__ < 6 
+//#endif
+//#if ROOT_VERSION_CODE < ROOT_VERSION(6,0,0)
+//#endif
+
+#endif
diff --git a/jpp/JLang/JClass.hh b/jpp/JLang/JClass.hh
new file mode 100644
index 0000000..67a4c8f
--- /dev/null
+++ b/jpp/JLang/JClass.hh
@@ -0,0 +1,220 @@
+#ifndef __JLANG__JCLASS__
+#define __JLANG__JCLASS__
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Data structure for primitive types.
+   */
+  template<class T>
+  struct JPrimitive {
+    
+    typedef const T      argument_type;
+    
+    enum { is_primitive  = true  };
+  };
+  
+  
+  /**
+   * Data structure for method argument types.
+   */
+  template<class T>
+  struct JArgument {
+    
+    typedef const T&     argument_type;
+    
+    enum { is_primitive  = false };
+  };
+  
+
+  /**
+   * Specialisations of JArgument for primitive types.
+   */
+  template<> struct JArgument<bool>                   : public JPrimitive<bool> {};
+  template<> struct JArgument<char>                   : public JPrimitive<char> {};
+  template<> struct JArgument<unsigned char>          : public JPrimitive<unsigned char> {};
+  template<> struct JArgument<short>                  : public JPrimitive<short> {};
+  template<> struct JArgument<unsigned short>         : public JPrimitive<unsigned short> {};
+  template<> struct JArgument<int>                    : public JPrimitive<int> {};
+  template<> struct JArgument<unsigned int>           : public JPrimitive<unsigned int> {};
+  template<> struct JArgument<long int>               : public JPrimitive<long int> {};
+  template<> struct JArgument<unsigned long int>      : public JPrimitive<unsigned long int> {};
+  template<> struct JArgument<long long int>          : public JPrimitive<long long int> {};
+  template<> struct JArgument<unsigned long long int> : public JPrimitive<unsigned long long int> {};
+  template<> struct JArgument<float>                  : public JPrimitive<float> {};
+  template<> struct JArgument<double>                 : public JPrimitive<double> {};
+  template<> struct JArgument<long double>            : public JPrimitive<long double> {};
+
+
+  /**
+   * Data structure to check whether given data type is an iterator.
+   */
+  template<class T>
+  struct is_iterator {
+
+    static T make();
+
+    typedef void*  buffer[2];
+
+    static buffer&                                          test(...);  //!< any type
+    template<class R> static typename R::iterator_category* test(R);    //!< iterator
+    template<class R> static void*                          test(R *);  //!< pointer
+
+    static const bool value = sizeof(test(make())) == sizeof(void *); 
+  };  
+  
+
+  /**
+   * Template for generic class types.
+   */
+  template<class T>
+  struct JClass {
+
+    typedef typename JArgument<T>::argument_type     argument_type;
+    typedef T                                        value_type;
+    typedef value_type&                              reference_type;
+    typedef value_type*                              pointer_type;
+
+    enum { is_primitive  = JArgument<T>::is_primitive };
+    enum { is_reference  = false };
+    enum { is_pointer    = false };
+    enum { is_constant   = false };
+  };
+
+  
+  /**
+   * Specialisation of JClass for const class types.
+   */
+  template<class T>
+  struct JClass<const T> {
+
+    typedef typename JArgument<T>::argument_type     argument_type;
+    typedef T                                        value_type;
+    typedef const value_type&                        reference_type;
+    typedef const value_type*                        pointer_type;
+
+    enum { is_primitive  = JArgument<T>::is_primitive };
+    enum { is_reference  = false };
+    enum { is_pointer    = false };
+    enum { is_constant   = true  };
+  };
+
+  
+  /**
+   * Specialisation of JClass for reference class types.
+   */
+  template<class T>
+  struct JClass<T&> {
+
+    typedef T&                                       argument_type;
+    typedef T                                        value_type;
+    typedef value_type&                              reference_type;
+    typedef value_type*                              pointer_type;
+
+    enum { is_primitive  = JArgument<T>::is_primitive };
+    enum { is_reference  = true  };
+    enum { is_pointer    = false };
+    enum { is_constant   = false };
+  };
+
+
+  /**
+   * Specialisation of JClass for const reference class types.
+   */
+  template<class T>
+  struct JClass<const T&> {
+
+    typedef const T&                                 argument_type;
+    typedef T                                        value_type;
+    typedef const value_type&                        reference_type;
+    typedef const value_type*                        pointer_type;
+
+    enum { is_primitive  = JArgument<T>::is_primitive };
+    enum { is_reference  = true  };
+    enum { is_pointer    = false };
+    enum { is_constant   = true  };
+  };
+
+  
+  /**
+   * Specialisation of JClass for pointer class types.
+   */
+  template<class T>
+  struct JClass<T*> {
+
+    typedef T*                                       argument_type;
+    typedef T                                        value_type;
+    typedef value_type*&                             reference_type;
+    typedef value_type*                              pointer_type;
+
+    enum { is_primitive  = JArgument<T>::is_primitive };
+    enum { is_reference  = false };
+    enum { is_pointer    = true  };
+    enum { is_constant   = false };
+  };
+
+
+  /**
+   * Specialisation of JClass for const pointer class types.
+   */
+  template<class T>
+  struct JClass<const T*> {
+
+    typedef const T*                                 argument_type;
+    typedef T                                        value_type;
+    typedef const value_type*&                       reference_type;
+    typedef const value_type*                        pointer_type;
+
+    enum { is_primitive  = JArgument<T>::is_primitive };
+    enum { is_reference  = false };
+    enum { is_pointer    = true  };
+    enum { is_constant   = true  };
+  };
+
+  
+  /**
+   * Specialisation of JClass for pointer class types.
+   */
+  template<class T>
+  struct JClass<T*&> {
+
+    typedef T*&                                      argument_type;
+    typedef T                                        value_type;
+    typedef value_type*&                             reference_type;
+    typedef value_type*                              pointer_type;
+
+    enum { is_primitive  = JArgument<T>::is_primitive };
+    enum { is_reference  = true };
+    enum { is_pointer    = true  };
+    enum { is_constant   = false };
+  };
+
+
+  /**
+   * Specialisation of JClass for const pointer class types.
+   */
+  template<class T>
+  struct JClass<const T*&> {
+
+    typedef const T*&                                argument_type;
+    typedef T                                        value_type;
+    typedef const value_type*&                       reference_type;
+    typedef const value_type*                        pointer_type;
+
+    enum { is_primitive  = JArgument<T>::is_primitive };
+    enum { is_reference  = true };
+    enum { is_pointer    = true  };
+    enum { is_constant   = true  };
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JClonable.hh b/jpp/JLang/JClonable.hh
new file mode 100644
index 0000000..681b381
--- /dev/null
+++ b/jpp/JLang/JClonable.hh
@@ -0,0 +1,77 @@
+#ifndef __JLANG__JCLONABLE__
+#define __JLANG__JCLONABLE__
+
+#include "JLang/JNullType.hh"
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Template class for object cloning.
+   */
+  template<class JClonable_t, class JDerived_t = JNullType>
+  struct JClonable;
+
+
+  /**
+   * Template specialisation to define base class for interface of object cloning.
+   */
+  template<class JClonable_t>
+  struct JClonable<JClonable_t, JNullType>
+  {
+    /**
+     * Type definition of return value of method clone().
+     */
+    typedef JClonable_t*                                      clone_type;
+
+
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JClonable() 
+    {}
+
+
+    /**
+     * Get clone of this object.
+     *
+     * \return              pointer to newly created object
+     */
+    virtual clone_type clone() const = 0;
+  };
+
+
+  /**
+   * Template specialisation to define base class for implementation of object cloning.
+   *
+   * This class derives from the specified clonable class and implements the method clone.
+   */
+  template<class JClonable_t, class JDerived_t>
+  struct JClonable :
+    public JClonable_t
+  {
+
+    typedef typename JClonable<JClonable_t>::clone_type       clone_type;
+    
+
+    /**
+     * Get clone of this object.
+     *
+     * \return              pointer to newly created object
+     */
+    virtual clone_type clone() const override 
+    {
+      return new JDerived_t(static_cast<const JDerived_t&>(*this));
+    }
+  };
+}
+
+
+#endif
diff --git a/jpp/JLang/JComparable.hh b/jpp/JLang/JComparable.hh
new file mode 100644
index 0000000..f2ee43d
--- /dev/null
+++ b/jpp/JLang/JComparable.hh
@@ -0,0 +1,311 @@
+#ifndef __JLANG__JCOMPARABLE__
+#define __JLANG__JCOMPARABLE__
+
+#include "JLang/JNullType.hh"
+#include "JLang/JClass.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  
+  /**
+   * Template definition of auxiliary base class for comparison of data structures.
+   *
+   * The various specialisations of this class implement the operators <tt> < > <= >= == != </tt>.
+   */
+  template<class JFirst_t, class JSecond_t = JNullType> 
+  struct JComparable;
+
+
+  /**
+   * General purpose specialisation of class JComparable for any data type.
+   *
+   * The template parameter should have the corresponding member method:
+   * <pre>
+   *       bool less(const JClass_t&) const;
+   * </pre>
+   *
+   * This class uses in-class friend operators (see Barton-Nackman trick).
+   */
+  template<class JClass_t>
+  struct JComparable<JClass_t, JNullType>
+  {
+    /**
+     * Less than operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is less than second object; else false
+     */
+    friend bool operator<(const JClass_t& first,
+			  const JClass_t& second)
+    { 
+      return first.less(second);
+    }
+
+ 
+    /**
+     * Greater than operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is greater than second object; else false
+     */
+    friend bool operator>(const JClass_t& first,
+			  const JClass_t& second)
+    { 
+      return second.less(first);
+    }
+    
+
+    /**
+     * Less than or equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is less than or equal to second object; else false
+     */
+    friend bool operator<=(const JClass_t& first,
+			   const JClass_t& second)
+    { 
+      return !second.less(first);
+    }
+    
+
+    /**
+     * Greater than or equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is greater than or equal to second object; else false
+     */
+    friend bool operator>=(const JClass_t& first,
+			   const JClass_t& second)
+    { 
+      return !first.less(second);
+    }
+    
+
+    /**
+     * Equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if two objects are equal; else false
+     */
+    friend bool operator==(const JClass_t& first,
+			   const JClass_t& second)
+    { 
+      return !first.less(second) && !second.less(first);
+    }
+
+
+    /**
+     * Not equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if two objects are not equal; else false
+     */
+    friend bool operator!=(const JClass_t& first,
+			   const JClass_t& second)
+    {
+      return first.less(second) || second.less(first);
+    }
+  };
+  
+
+  /**
+   * Specialisation of class JComparable for two data types.
+   *
+   * The first template parameter should have the corresponding member methods:
+   * <pre>
+   *       bool less(const JSecond_t&) const;
+   *       bool more(const JSecond_t&) const;
+   * </pre>
+   * where <tt>JFirst_t</tt> andd <tt>JSecond_t</tt> refers to the first and second template parameter, respectively.
+   * The second template parameter may be a primitive data type.
+   * This class uses in-class friend operators (see Barton-Nackman trick).
+   */
+  template<class JFirst_t, class JSecond_t>
+  struct JComparable
+  {
+    /**
+     * Less than operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is less than second object; else false
+     */
+    friend bool operator<(const JFirst_t& first,
+			  typename JClass<JSecond_t>::argument_type second)
+    { 
+      return first.less(second);
+    }
+
+
+    /**
+     * Less than operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is less than second object; else false
+     */
+    friend bool operator<(typename JClass<JSecond_t>::argument_type first,
+			  const JFirst_t& second)			  
+    { 
+      return second.more(first);
+    }
+
+
+    /**
+     * Greater than operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is greater than second object; else false
+     */
+    friend bool operator>(const JFirst_t& first,
+			  typename JClass<JSecond_t>::argument_type second)
+    { 
+      return first.more(second);
+    }
+
+
+    /**
+     * Greater than operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is greater than second object; else false
+     */
+    friend bool operator>(typename JClass<JSecond_t>::argument_type first,
+			  const JFirst_t& second)			  
+    { 
+      return second.less(first);
+    }
+
+
+    /**
+     * Less than or equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is less than or equal to second object; else false
+     */
+    friend bool operator<=(const JFirst_t& first,
+			   typename JClass<JSecond_t>::argument_type second)
+    { 
+      return !first.more(second);
+    }
+
+
+    /**
+     * Less than or equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is less than or equal to second object; else false
+     */
+    friend bool operator<=(typename JClass<JSecond_t>::argument_type first,
+			   const JFirst_t& second)
+    { 
+      return second.more(first);
+    }
+    
+
+    /**
+     * Greater than or equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is greater than or equal to second object; else false
+     */
+    friend bool operator>=(const JFirst_t& first,
+			   typename JClass<JSecond_t>::argument_type second)
+    { 
+      return !first.less(second);
+    }
+    
+
+    /**
+     * Greater than or equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if first object is greater than or equal to second object; else false
+     */
+    friend bool operator>=(typename JClass<JSecond_t>::argument_type first,
+			   const JFirst_t& second)
+			   
+    { 
+      return second.less(first);
+    }
+    
+
+    /**
+     * Equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if two objects are equal; else false
+     */
+    friend bool operator==(const JFirst_t& first,
+			   typename JClass<JSecond_t>::argument_type second)
+    { 
+      return !first.less(second) && !first.more(second);
+    }
+    
+
+    /**
+     * Equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if two objects are equal; else false
+     */
+    friend bool operator==(typename JClass<JSecond_t>::argument_type first,
+			   const JFirst_t& second)
+			   
+    { 
+      return !second.less(first) && !second.more(first);
+    }
+
+
+    /**
+     * Not equal operator.
+     *
+     * \param  first        first object
+     * \param  second       second object
+     * \return              true if two objects are not equal; else false
+     */
+    friend bool operator!=(const JFirst_t& first,
+			   typename JClass<JSecond_t>::argument_type second)
+    {
+      return first.less(second) || first.more(second);
+    }
+
+
+    /**
+     * Not equal operator.
+     *
+     * \param  first        first object
+     * \param  second       second object
+     * \return              true if two objects are not equal; else false
+     */
+    friend bool operator!=(typename JClass<JSecond_t>::argument_type first,
+			   const JFirst_t& second)
+    {
+      return second.less(first) || second.more(first);
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JEquals.hh b/jpp/JLang/JEquals.hh
new file mode 100644
index 0000000..67d9888
--- /dev/null
+++ b/jpp/JLang/JEquals.hh
@@ -0,0 +1,142 @@
+#ifndef __JLANG__JEQUALS__
+#define __JLANG__JEQUALS__
+
+#include "JLang/JNullType.hh"
+#include "JLang/JClass.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+   
+  /**
+   * Template definition of auxiliary base class for comparison of data structures.
+   *
+   * The various specialisations of this class implement the operators <tt> == != </tt>.
+   */
+  template<class JFirst_t, class JSecond_t = JNullType> 
+  struct JEquals;
+
+
+  /**
+   * General purpose specialisation of class JEquals for any data type.
+   *
+   * The template parameter should have the corresponding member method:
+   * <pre>
+   *       bool equals(const JClass_t&) const;
+   * </pre>
+   *
+   * This class uses in-class friend operators (see Barton-Nackman trick).
+   */
+  template<class JClass_t>
+  struct JEquals<JClass_t, JNullType> 
+  {
+    /**
+     * Equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if two objects are equal; else false
+     */
+    friend bool operator==(const JClass_t& first,
+			   const JClass_t& second)
+    { 
+      return first.equals(second);
+    }
+
+
+    /**
+     * Not equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if two objects are not equal; else false
+     */
+    friend bool operator!=(const JClass_t& first,
+			   const JClass_t& second)
+    {
+      return !first.equals(second);
+    }
+  };
+  
+
+  /**
+   * Specialisation of class JEquals for two data types.
+   *
+   * The first template parameter should have the corresponding member methods:
+   * <pre>
+   *       bool equals(const JFirst_t&) const;
+   *       bool equals(const JSecond_t&) const;
+   * </pre>
+   * where <tt>JFirst_t</tt> and <tt>JSecond_t</tt> refer to the first and second template parameter, respectively.
+   * The second template parameter may be a primitive data type.
+   * This class uses in-class friend operators (see Barton-Nackman trick).
+   */
+  template<class JFirst_t, class JSecond_t>
+  struct JEquals :
+    public JEquals<JFirst_t>
+  {
+    /**
+     * Equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if two objects are equal; else false
+     */
+    friend bool operator==(const JFirst_t& first,
+			   typename JClass<JSecond_t>::argument_type second)
+    { 
+      return first.equals(second);
+    }
+
+
+    /**
+     * Equal operator.
+     *
+     * \param  first        first  object
+     * \param  second       second object
+     * \return              true if two objects are equal; else false
+     */
+    friend bool operator==(typename JClass<JSecond_t>::argument_type first,
+			   const JFirst_t& second)
+    { 
+      return second.equals(first);
+    }
+
+
+    /**
+     * Not equal operator.
+     *
+     * \param  first        first object
+     * \param  second       second object
+     * \return              true if two objects are not equal; else false
+     */
+    friend bool operator!=(const JFirst_t& first,
+			   typename JClass<JSecond_t>::argument_type second)
+    {
+      return !first.equals(second);
+    }
+
+
+    /**
+     * Not equal operator.
+     *
+     * \param  first        first object
+     * \param  second       second object
+     * \return              true if two objects are not equal; else false
+     */
+    friend bool operator!=(typename JClass<JSecond_t>::argument_type first,
+			   const JFirst_t& second)
+    {
+      return !second.equals(first);
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JException.hh b/jpp/JLang/JException.hh
new file mode 100644
index 0000000..5892627
--- /dev/null
+++ b/jpp/JLang/JException.hh
@@ -0,0 +1,673 @@
+#ifndef __JLANG__JEXCEPTION__
+#define __JLANG__JEXCEPTION__
+
+#include <exception>
+#include <string>
+#include <ostream>
+#include <sstream>
+
+
+/**
+ * \file
+ * Exceptions.
+ * \author mdejong
+ */
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * General exception
+   */
+  class JException : public std::exception { 
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JException(const std::string& error) :
+      std::exception(),
+      buffer(error)
+    {}
+
+
+    /**
+     * Destructor.
+     */
+    ~JException() throw()
+    {}
+
+
+    /**
+     * Get error message.
+     *
+     * \return          error message
+     */
+    virtual const char* what() const throw() override 
+    { 
+      return buffer.c_str();
+    }
+
+
+    /**
+     * Print error message of JException.
+     *
+     * \param  out        output stream
+     * \param  exception  exception
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JException& exception)
+    {
+      return out << exception.what();
+    }
+
+
+    /**
+     * Get output stream for conversion of exception.
+     *
+     * Note that the ostream is emptied before use.
+     * 
+     * \return           ostream
+     */
+    static inline std::ostream& getOstream()
+    {
+      static std::ostringstream buffer;
+
+      buffer.str("");
+
+      return buffer;
+    }
+
+  private:
+    const std::string buffer;
+  };
+
+
+  /**
+   * Exception for accessing an index in a collection that is outside of its range.
+   */
+  class JIndexOutOfRange : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JIndexOutOfRange(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for accessing an invalid pointer.
+   */
+  class JPointerException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JPointerException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for a functional operation.
+   */
+  class JFunctionalException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JFunctionalException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for an empty collection.
+   */
+  class JEmptyCollection : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JEmptyCollection(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for accessing a value in a collection that is outside of its range.
+   */
+  class JValueOutOfRange : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JValueOutOfRange(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for parsing value.
+   */
+  class JParseError : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JParseError(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for missing value.
+   */
+  class JNoValue : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JNoValue(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for null pointer operation.
+   */
+  class JNullPointerException :
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JNullPointerException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for cast operation.
+   */
+  class JCastException :
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JCastException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for numerical precision error.
+   */
+  class JNumericalPrecision : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JNumericalPrecision(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for division by zero.
+   */
+  class JDivisionByZero : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JDivisionByZero(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for failure of memory allocation.
+   */
+  class JMallocException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JMallocException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for failure of memory allocation.
+   */
+  class JNewException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JNewException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for I/O.
+   */
+  class JIOException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JIOException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for opening of file.
+   */
+  class JFileOpenException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JFileOpenException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for reading of file.
+   */
+  class JFileReadException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JFileReadException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for end of file.
+   */
+  class JEndOfFile : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JEndOfFile(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for opening of pipe.
+   */
+  class JPipeOpenException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JPipeOpenException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for select call.
+   */
+  class JSelectException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JSelectException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for socket.
+   */
+  class JSocketException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JSocketException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for ControlHost.
+   */
+  class JControlHostException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JControlHostException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for socket channel.
+   */
+  class JSocketChannelException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JSocketChannelException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for creation of fork.
+   */
+  class JForkException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JForkException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for system call.
+   */
+  class JSystemException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JSystemException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception when parsing a value.
+   */
+  class JParserException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JParserException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception when parsing a value.
+   */
+  class JPropertiesException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JPropertiesException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for missing entry in dictionary.
+   */
+  class JDictionaryEntryNotFound : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JDictionaryEntryNotFound(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for duplicate entry in dictionary.
+   */
+  class JDictionaryDuplicateEntry : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JDictionaryDuplicateEntry(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Run time exception.
+   */
+  class JRunTimeException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JRunTimeException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Exception for absence of type information.
+   */
+  class JTypeInformationException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JTypeInformationException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Protocol exception.
+   */
+  class JProtocolException : 
+    public JException 
+  { 
+  public: 
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JProtocolException(const std::string& error) :
+      JException(error)
+    {}
+  };
+
+
+  /**
+   * Database exception.
+   */
+  class JDatabaseException :
+    public JException
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  error    error message
+     */
+    JDatabaseException(const std::string& error) :
+      JException(error)
+    {}
+  };
+}
+
+/**
+ * Marco for throwing exception with std::ostream compatible message.
+ *
+ * \param  JException_t    exception
+ * \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)
+#endif
+
+#endif
diff --git a/jpp/JLang/JForwardIterator.hh b/jpp/JLang/JForwardIterator.hh
new file mode 100644
index 0000000..642584e
--- /dev/null
+++ b/jpp/JLang/JForwardIterator.hh
@@ -0,0 +1,116 @@
+#ifndef __JLANG__JFORWARDITERATOR__
+#define __JLANG__JFORWARDITERATOR__
+
+#include <cstddef>
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Template interface for method bool increment().
+   * This interface implements the pre-fix and post-fix operators <tt>++</tt>.
+   */
+  template<class T> 
+  class JForwardIterator {
+  public:
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JForwardIterator()
+    {}
+
+    
+    /**
+     * Increment iterator.
+     *
+     * \return                 this iterator
+     */
+    T& operator++()
+    {
+      this->increment();
+      
+      return static_cast<T&>(*this);
+    }
+
+
+    /**
+     * Increment iterator.
+     *
+     * \return                 previous iterator
+     */
+    T operator++(int)
+    {
+      const T tmp(static_cast<const T&>(*this));
+
+      this->increment();
+
+      return tmp;
+    }
+
+
+    /**
+     * Advance iterator.
+     *
+     * \param  offset          offset
+     * \return                 iterator
+     */
+    T& operator+=(const size_t offset)
+    {
+      this->increment(offset);
+
+      return static_cast<T&>(*this);
+    }
+
+
+    /**
+     * Advance operator.
+     *
+     * \param  object          iterator
+     * \param  offset          offset
+     * \return                 iterator
+     */
+    friend inline T operator+(const T& object, const size_t offset)
+    {
+      T tmp(object);
+
+      tmp.increment(offset);
+
+      return tmp;
+    }
+    
+
+    /**
+     * Increment iterator.
+     *
+     * \return                 true if incremented; else false
+     */
+    virtual bool increment() = 0;
+
+
+    /**
+     * Increment iterator.
+     *
+     * \param  offset          offset
+     * \return                 true if incremented; else false
+     */
+    virtual bool increment(const size_t offset)
+    {
+      size_t i = 0;
+
+      while (i != offset && this->increment()) {
+	++i;
+      }
+
+      return i == offset;
+    }
+  };
+}
+
+#endif
+
diff --git a/jpp/JLang/JLangToolkit.hh b/jpp/JLang/JLangToolkit.hh
new file mode 100644
index 0000000..a9abcf2
--- /dev/null
+++ b/jpp/JLang/JLangToolkit.hh
@@ -0,0 +1,333 @@
+#ifndef __JLANG__JLANGTOOLKIT__
+#define __JLANG__JLANGTOOLKIT__
+
+#include <string>
+#include <sstream>
+#include <iterator>
+#include <ctype.h>
+
+
+/**
+ * \author mdejong
+ */
+
+/**
+ * Auxiliary classes and methods for language specific functionality.
+ */
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  using std::size_t;
+  
+  
+  /**
+   * Get size of c-array.
+   *
+   * \param  array          array
+   * \return                size
+   */
+  template<class T, size_t N>
+  inline size_t getSize(T (&array)[N])
+  {
+    return N;
+  }
+
+
+  /**
+   * Check if two objects are indentical.
+   *
+   * \param  first          first  object
+   * \param  second         second object
+   * \return                true if addresses are equal; else false
+   */
+  template<class JFirst_t, class JSecond_t>
+  inline bool is_identical(JFirst_t& first, JSecond_t& second)
+  {
+    return (void*) &first == (void*) &second;
+  }
+
+  
+  /**
+   * Check if string is an integer.\n
+   *
+   * \param  buffer         input string
+   * \return                true if integer; else false
+   */
+  inline bool is_integer(const std::string& buffer)
+  {
+    using namespace std;
+    
+    for (string::const_iterator i = buffer. begin(); i != buffer.end(); ++i) {
+      if (!isdigit(*i)) {
+	return false;
+      }
+    }
+    
+    return !buffer.empty();
+  }
+
+  
+  /**
+   * Trim string.\n
+   * Returns a copy of the string, with leading and trailing white spaces omitted.
+   *
+   * \param  buffer         input string
+   * \return                modified string
+   */
+  inline std::string trim(const std::string& buffer)
+  {
+    using namespace std;
+    
+    string::const_iterator         p = buffer. begin();
+    string::const_reverse_iterator q = buffer.rbegin();
+    
+    while (p != q.base() && isspace(*p)) { ++p; }
+    while (p != q.base() && isspace(*q)) { ++q; }
+    
+    return string(p,q.base());
+  }
+
+
+  /**
+   * Trim string.\n
+   * Returns a copy of the string, with leading and trailing target characters omitted.
+   *
+   * \param  buffer         input string
+   * \param  c              strip character
+   * \return                modified string
+   */
+  inline std::string trim(const std::string& buffer, const char c)
+  {
+    using namespace std;
+
+    string::const_iterator         p = buffer. begin();
+    string::const_reverse_iterator q = buffer.rbegin();
+    
+    while (p != q.base() && *p == c) { ++p; }
+    while (p != q.base() && *q == c) { ++q; }
+    
+    return string(p,q.base());
+  }
+
+
+  /**
+   * Replace tokens in string.\n
+   * Returns a copy of the string, with all occurences of <tt>target</tt> replaced by <tt>replacement</tt>.
+   *
+   * \param  input          input       string
+   * \param  target         target      string
+   * \param  replacement    replacement string
+   * \return                modified    string
+   */
+  inline std::string replace(const std::string& input, const std::string& target, const std::string& replacement)
+  {
+    using namespace std;
+
+    string buffer = input;
+
+    for (size_t i = buffer.find(target); i != string::npos; i = buffer.find(target,i)) {
+      buffer.replace(buffer.begin() + i, buffer.begin() + i + target.length(), replacement);
+    }
+
+    return buffer;
+  }
+
+
+  /**
+   * Replace characters in string.\n
+   * Returns a copy of the string, with all occurences of <tt>target</tt> replaced by <tt>replacement</tt>.
+   *
+   * \param  input          input       string
+   * \param  target         target      character
+   * \param  replacement    replacement character
+   * \return                modified    string
+   */
+  inline std::string replace(const std::string& input, const char target, const char replacement)
+  {
+    using namespace std;
+
+    string buffer = input;
+
+    for (string::iterator i = buffer.begin(); i != buffer.end(); ++i) {
+      if (*i == target) {
+	*i = replacement;
+      }
+    }
+
+    return buffer;
+  }
+
+
+  /**
+   * Trim string.\n
+   * Returns a copy of the string, with leading and trailing target characters omitted.
+   *
+   * \param  buffer         input string
+   * \param  target         strip character(s)
+   * \return                modified string
+   */
+  inline std::string trim(const std::string& buffer, const std::string& target)
+  {
+    using namespace std;
+    
+    string::const_iterator         p = buffer. begin();
+    string::const_reverse_iterator q = buffer.rbegin();
+      
+    while (p != q.base() && target.find(*p) != string::npos) { ++p; }
+    while (p != q.base() && target.find(*q) != string::npos) { ++q; }
+    
+    return string(p,q.base());
+  }
+
+  
+  /**
+   * Convert value to string.
+   *
+   * \param  value          value
+   * \return                string
+   */
+  template<class T>
+  inline std::string to_string(const T& value)
+  {
+    using namespace std;
+
+    ostringstream os;
+
+    os << value;
+
+    return os.str();
+  }
+
+
+  /**
+   * Convert string to value.
+   *
+   * \param  input          string
+   * \return                value
+   */
+  template<class T>
+  inline T to_value(const std::string& input)
+  {
+    using namespace std;
+
+    T value;
+
+    istringstream(input) >> value;
+
+    return value;
+  }
+
+
+  /**
+   * Convert all character to upper case.
+   *
+   * \param  value          value
+   * \return                string
+   */
+  inline std::string to_upper(const std::string& value)
+  {
+    using namespace std;
+    
+    string buffer(value);
+
+    for (string::iterator i = buffer.begin(); i != buffer.end(); ++i) {
+      *i = toupper(*i);
+    }
+
+    return buffer;
+  }
+
+
+  /**
+   * Convert all character to lower case.
+   *
+   * \param  value          value
+   * \return                string
+   */
+  inline std::string to_lower(const std::string& value)
+  {
+    using namespace std;
+    
+    string buffer(value);
+
+    for (string::iterator i = buffer.begin(); i != buffer.end(); ++i) {
+      *i = tolower(*i);
+    }
+
+    return buffer;
+  }
+
+
+  /**
+   * Count number of white space separated tokens.
+   *
+   * \param  buffer         input string
+   * \return                number of tokens
+   */
+  inline size_t get_number_of_tokens(const std::string& buffer)
+  {
+    using namespace std;
+
+    istringstream is(buffer);
+
+    return distance(istream_iterator<string>(is), istream_iterator<string>());
+  }
+
+
+  /**
+   * Check quotation.
+   *
+   * \param  value          value
+   * \return                true if quoted; else false
+   */
+  inline bool is_single_quoted(const std::string& value)
+  {
+    return (value.size() > 1  &&  *value.begin() == '\''  &&  *value.rbegin() == '\'');
+  }
+
+
+  /**
+   * Check quotation.
+   *
+   * \param  value          value
+   * \return                true if quoted; else false
+   */
+  inline bool is_double_quoted(const std::string& value)
+  {
+    return (value.size() > 1  &&  *value.begin() == '\"'  &&  *value.rbegin() == '\"');
+  }
+
+
+  /**
+   * Quote string.
+   *
+   * \param  value          value
+   * \return                string
+   */
+  inline std::string single_quote(const std::string& value)
+  {
+    if (!is_single_quoted(value))
+      return "\'" + value + "\'";
+    else
+      return value;
+  }
+
+
+  /**
+   * Quote string.
+   *
+   * \param  value          value
+   * \return                string
+   */
+  inline std::string double_quote(const std::string& value)
+  {
+    if (!is_double_quoted(value))
+      return "\"" + value + "\"";
+    else
+      return value;
+  }
+}
+
+#endif
diff --git a/jpp/JLang/JManip.hh b/jpp/JLang/JManip.hh
new file mode 100644
index 0000000..a4b2193
--- /dev/null
+++ b/jpp/JLang/JManip.hh
@@ -0,0 +1,716 @@
+#ifndef __JLANG_JMANIP__
+#define __JLANG_JMANIP__
+
+#include <string>
+#include <ostream>
+#include <sstream>
+#include <iomanip>
+
+
+/**
+ * \file
+ * I/O manipulators.
+ * \author mdejong
+ */
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Get index for user I/O manipulation.
+   *
+   * \return           index
+   */
+  inline int getIndex() 
+  {
+    static const int index = std::ios_base::xalloc();
+
+    return index;
+  }
+
+  
+  /**
+   * Print options.
+   */
+  enum JPrintOption_t {
+		       SHORT_PRINT  = 1,    //!< short  print
+		       MEDIUM_PRINT = 2,    //!< medium print
+		       LONG_PRINT   = 3     //!< long   print
+  };
+}
+
+
+/**
+ * Get print option.
+ *
+ * \param  out       output stream
+ * \return           print option
+ */
+inline int getPrintOption(std::ostream& out)
+{
+  return out.iword(JLANG::getIndex());
+}
+
+
+/**
+ * Set print option.
+ *
+ * \param  out       output stream
+ * \param  option    print option
+ */
+inline void setPrintOption(std::ostream& out, const int option)
+{
+  out.iword(JLANG::getIndex()) = option;
+}
+
+
+/**
+ * Get short print option.
+ *
+ * \param  out       output stream
+ * \return           true if short print option is on; else false
+ */
+inline bool getShortprint(std::ostream& out)
+{
+  return getPrintOption(out) == JLANG::SHORT_PRINT;
+}
+
+
+/**
+ * Set short print option.
+ *
+ * \param  out       output stream
+ */
+inline void setShortprint(std::ostream& out)
+{
+  return setPrintOption(out, JLANG::SHORT_PRINT);
+}
+
+
+/**
+ * Get medium print option.
+ *
+ * \param  out       output stream
+ * \return           true if medium print option is on; else false
+ */
+inline bool getMediumprint(std::ostream& out)
+{
+  return getPrintOption(out) == JLANG::MEDIUM_PRINT;
+}
+
+
+/**
+ * Set medium print option.
+ *
+ * \param  out       output stream
+ */
+inline void setMediumprint(std::ostream& out)
+{
+  return setPrintOption(out, JLANG::MEDIUM_PRINT);
+}
+
+
+/**
+ * Get long print option.
+ *
+ * \param  out       output stream
+ * \return           true if long print option is on; else false
+ */
+inline bool getLongprint(std::ostream& out)
+{
+  return getPrintOption(out) == JLANG::LONG_PRINT;
+}
+
+
+/**
+ * Set long print option.
+ *
+ * \param  out       output stream
+ */
+inline void setLongprint(std::ostream& out)
+{
+  return setPrintOption(out, JLANG::LONG_PRINT);
+}
+
+
+/**
+ * Set short printing.
+ *
+ * \param  out       output stream
+ * \return           output stream
+ */
+inline std::ostream& shortprint(std::ostream& out)
+{
+  setShortprint(out);
+
+  return out;
+}
+
+
+/**
+ * Set medium printing.
+ *
+ * \param  out       output stream
+ * \return           output stream
+ */
+inline std::ostream& mediumprint(std::ostream& out)
+{
+  setMediumprint(out);
+
+  return out;
+}
+
+
+/**
+ * Set long printing.
+ *
+ * \param  out       output stream
+ * \return           output stream
+ */
+inline std::ostream& longprint(std::ostream& out)
+{
+  setLongprint(out);
+
+  return out;
+}
+
+
+/**
+ * Print newline character.
+ *
+ * \param  out       output stream
+ * \return           output stream
+ */
+inline std::ostream& newline(std::ostream& out)
+{
+  return out << '\n';
+}
+
+
+/**
+ * Print white space character.
+ *
+ * \param  out       output stream
+ * \return           output stream
+ */
+inline std::ostream& whitespace(std::ostream& out)
+{
+  return out << ' ';
+}
+
+
+/**
+ * Print tab character.
+ *
+ * \param  out       output stream
+ * \return           output stream
+ */
+inline std::ostream& tab(std::ostream& out)
+{
+  return out << '\t';
+}
+
+
+/**
+ * Rewind character.
+ *
+ * \param  out       output stream
+ * \return           output stream
+ */
+inline std::ostream& rewind(std::ostream& out)
+{
+  return (out << '\r').flush();
+}
+
+
+/**
+ * Auxiliary data structure for alignment of data.
+ */
+struct WIDTH {
+  /**
+   * Constructor.
+   *
+   * \param  width         width
+   */
+  WIDTH(const int width)
+  {
+    this->width = width;
+  }
+
+
+  /**
+   * Format specifier.
+   *
+   * \param  out           output stream
+   * \param  format        format
+   * \return               output stream
+   */
+  friend inline std::ostream& operator<<(std::ostream& out, const WIDTH& format)
+  {
+    using namespace std;
+    
+    return out << setw(format.width);
+  }
+  
+  int  width;
+};
+
+
+/**
+ * Auxiliary data structure for alignment of data.
+ */
+struct LEFT :
+  public WIDTH
+{
+  /**
+   * Constructor.
+   *
+   * \param  width         width
+   */
+  LEFT(const int width) :
+    WIDTH(width)
+  {}
+
+
+  /**
+   * Format specifier.
+   *
+   * \param  out           output stream
+   * \param  format        format
+   * \return               output stream
+   */
+  friend inline std::ostream& operator<<(std::ostream& out, const LEFT& format)
+  {
+    using namespace std;
+    
+    return out << setw(format.width) << left;
+  }
+};
+
+
+/**
+ * Auxiliary data structure for alignment of data.
+ */
+struct RIGHT :
+  public WIDTH
+{
+  /**
+   * Constructor.
+   *
+   * \param  width         width
+   */
+  RIGHT(const int width) :
+    WIDTH(width)
+  {}
+
+
+  /**
+   * Format specifier.
+   *
+   * \param  out           output stream
+   * \param  format        format
+   * \return               output stream
+   */
+  friend inline std::ostream& operator<<(std::ostream& out, const RIGHT& format)
+  {
+    using namespace std;
+    
+    return out << setw(format.width) << right;
+  }
+};
+
+
+/**
+ * Auxiliary data structure for sequence of same character.
+ */
+struct FILL :
+  public WIDTH
+{
+  /**
+   * Constructor.
+   *
+   * \param  width         width
+   * \param  fill          fill character
+   */
+  FILL(const int  width = 0,
+       const char fill  = ' ') :
+    WIDTH(width)
+  {
+    this->fill = fill;
+  }
+
+  
+  /**
+   * Format specifier.
+   *
+   * \param  out           output stream
+   * \param  format        format
+   * \return               output stream
+   */
+  friend inline std::ostream& operator<<(std::ostream& out, const FILL& format)
+  {
+    using namespace std;
+
+    return out << setfill(format.fill) << setw(format.width); 
+  }
+
+  char fill;
+};
+
+
+/**
+ * Auxiliary data structure for alignment of data.
+ */
+struct CENTER :
+  public WIDTH
+{
+protected:
+  /**
+   * Auxiliary class for format center.
+   */
+  struct JCenter :
+    public WIDTH 
+  {
+    /**
+     * Constructor.
+     *
+     * \param  out         output stream
+     * \param  format      format center
+     */
+    JCenter(std::ostream& out, const WIDTH& format) :
+      WIDTH(format),
+      out   (out)
+    {}
+
+
+    /**
+     * Write value to output stream.
+     *
+     * \param  value       value
+     * \return             this JCenter
+     */
+    template<class T>
+    std::ostream& operator<<(const T& value)
+    {
+      using namespace std;
+
+      ostringstream os;
+
+      os.copyfmt(out);
+
+      os << value;
+
+      const int  w = this->width - os.str().size();
+      const char c = this->out.fill();
+
+      if (w > 0)
+	return this->out << FILL(w/2) << ' ' << os.str() << FILL((w+1)/2) << ' ' << setfill(c);
+      else
+	return this->out << os.str();
+    }
+
+  private:
+    std::ostream& out; 
+  };
+
+public:
+  /**
+   * Constructor.
+   *
+   * \param  width         width
+   */
+  CENTER(const int width) :
+    WIDTH(width)
+  {}
+
+
+  /**
+   * Format specifier.
+   *
+   * \param  out           output stream
+   * \param  format        format
+   * \return               output stream
+   */
+  friend inline JCenter operator<<(std::ostream& out, const CENTER& format)
+  {
+    return JCenter(out, format);
+  }
+};
+
+
+/**
+ * Auxiliary data structure for floating point format specification.
+ */
+struct FIXED :
+  public WIDTH
+{
+  /**
+   * Constructor.
+   *
+   * \param  width         width
+   * \param  precision     precision
+   */
+  FIXED(const int width,
+	const int precision) :
+    WIDTH(width)
+  {
+    this->precision = precision;
+  }
+
+
+  /**
+   * Format specifier.
+   *
+   * \param  out           output stream
+   * \param  format        format
+   * \return               output stream
+   */
+  friend inline std::ostream& operator<<(std::ostream& out, const FIXED& format)
+  {
+    using namespace std;
+    
+    return out << fixed << right << setw(format.width) << setprecision(format.precision);
+  }
+  
+  int precision;
+};
+
+
+/**
+ * Auxiliary data structure for floating point format specification.
+ */
+struct SCIENTIFIC :
+  public WIDTH
+{
+  /**
+   * Constructor.
+   *
+   * \param  width         width
+   * \param  precision     precision
+   */
+  SCIENTIFIC(const int width,
+	     const int precision) :
+    WIDTH(width)
+  {
+    this->precision = precision;
+  }
+
+
+  /**
+   * Format specifier.
+   *
+   * \param  out           output stream
+   * \param  format        format
+   * \return               output stream
+   */
+  friend inline std::ostream& operator<<(std::ostream& out, const SCIENTIFIC& format)
+  {
+    using namespace std;
+    
+    return out << scientific << right << setw(format.width) << setprecision(format.precision);
+  }
+  
+  int precision;
+};
+
+
+/**
+ * Data structure for format specifications.
+ */
+struct JFormat_t {
+
+  typedef std::ios_base::fmtflags  fmtflags;
+
+  /**
+   * Default constructor.
+   */
+  JFormat_t() :
+    width    (0),
+    precision(0),
+    flags    (),
+    fill     (' ') 
+  {}
+
+
+  /**
+   * Constructor.
+   *
+   * \param  width        width
+   * \param  precision    precision
+   * \param  flags        flags
+   * \param  fill         fill character
+   */
+  JFormat_t(const int      width,
+	    const int      precision  = 0,
+	    const fmtflags flags      = fmtflags(),
+	    const char     fill       = ' ') :
+    width    (width),
+    precision(precision),
+    flags    (flags),
+    fill     (fill)
+  {}
+  
+
+  /**
+   * Constructor.
+   *
+   * \param  out          output stream
+   */
+  JFormat_t(std::ostream& out)
+  {
+    get(out);
+  }
+
+
+  /**
+   * Check validity of this manipulator.
+   *
+   * \return              true if valid; else false
+   */
+  inline bool is_valid() const
+  {
+    return (width > 0);
+  }
+
+  
+  /**
+   * Get format specificaton from given output stream.
+   *
+   * \param  out          output stream
+   */
+  void get(std::ostream& out)
+  {
+    this->width     = out.width();
+    this->precision = out.precision();
+    this->flags     = out.flags();
+    this->fill      = out.fill();
+  }
+
+
+  /**
+   * Put format specificaton to given output stream.
+   *
+   * \param  out          output stream
+   */
+  void put(std::ostream& out) const
+  {
+    out.width    (this->width);
+    out.precision(this->precision);
+    out.flags    (this->flags);
+    out.fill     (this->fill);
+  }
+
+
+  /**
+   * Format specifier.
+   *
+   * \param  out           output stream
+   * \param  format        format
+   * \return               output stream
+   */
+  friend inline std::ostream& operator<<(std::ostream& out, const JFormat_t& format)
+  {
+    format.put(out);
+    
+    return out;
+  }
+  
+  int      width;
+  int      precision;
+  fmtflags flags;
+  char     fill;
+};
+
+
+/**
+ * Auxiliary class to temporarily define format specifications.
+ *
+ * The format specification of the output stream in use will be restored when this object is destroyed.
+ */
+struct JFormat :
+  public JFormat_t
+{
+  /**
+   * Constructor.
+   *
+   * \param  out       output stream
+   */
+  JFormat(std::ostream& out) :
+    JFormat_t(),
+    out      (out),
+    format   (out)
+  {}
+
+
+  /**
+   * Constructor.
+   *
+   * \param  out       output stream
+   * \param  format    format
+   */
+  JFormat(std::ostream& out, const JFormat_t& format) :
+    JFormat_t(format),
+    out      (out),
+    format   (out)
+  {}
+
+
+  /**
+   * Destructor.
+   */
+  ~JFormat()
+  {
+    format.put(out);
+  }
+
+private:
+  std::ostream&   out;
+  const JFormat_t format;
+};
+
+
+/**
+ * Get format for given type.
+ *
+ * \return           format
+ */
+template<class T>
+inline JFormat_t& getFormat()
+{
+  static JFormat_t manip;
+
+  return manip;
+}
+
+
+/**
+ * Get format for given type.
+ *
+ * \param  format    default format
+ * \return           actual  format
+ */
+template<class T>
+inline JFormat_t getFormat(const JFormat_t& format)
+{
+  const JFormat_t& buffer = getFormat<T>();
+
+  if (buffer.is_valid())
+    return buffer;
+  else
+    return format;
+}
+
+
+/**
+ * Set format for given type.
+ *
+ * \param  format    format
+ */
+template<class T>
+inline void setFormat(const JFormat_t& format)
+{
+  getFormat<T>() = format;
+}
+
+#endif
diff --git a/jpp/JLang/JMemory.hh b/jpp/JLang/JMemory.hh
new file mode 100644
index 0000000..8d9f622
--- /dev/null
+++ b/jpp/JLang/JMemory.hh
@@ -0,0 +1,120 @@
+#ifndef __JLANG__JMEMORY__
+#define __JLANG__JMEMORY__
+
+#include <stdlib.h>
+
+
+/**
+ * \file
+ *
+ * Base class for memory management.
+ * \author mdejong
+ */
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Memory management class for create/release policy based on new/delete.
+   */
+  template<class JClass_t>
+  class JNew {
+  public:
+    /**
+     * Create object in memory.
+     *
+     * \return           pointer to data
+     */
+    static inline JClass_t* create()
+    { 
+      return new JClass_t(); 
+    }
+    
+
+    /**
+     * Release memory.
+     *
+     * \param  p         pointer to data
+     */
+    static inline void release(JClass_t* p) 
+    {
+      delete p;
+    }
+  };
+  
+
+  /**
+   * Memory management class for create/release policy based on new []/delete [].
+   */
+  template<class JClass_t>
+  class JNewCArray {
+  public:
+    /**
+     * Create array of objects in memory.
+     *
+     * \param  size      number of elements
+     * \return           pointer to data
+     */
+    static inline JClass_t* create(const unsigned int size)
+    { 
+      return new JClass_t[size];
+    }
+
+
+    /**
+     * Release memory.
+     *
+     * \param  p         pointer to data
+     */
+    static inline void release(JClass_t* p)
+    { 
+      delete [] p;
+    }
+  };
+  
+
+  /**
+   * Memory management class for create/release policy based on malloc()/free().
+   */
+  template<class JClass_t>
+  class JMalloc {
+  public:
+    /**
+     * Create object in memory.
+     *
+     * \return           pointer to data
+     */
+    static inline JClass_t* create()
+    { 
+      return (JClass_t*) malloc(sizeof(JClass_t));
+    }
+
+
+    /**
+     * Create array of objects in memory.
+     *
+     * \param  size      number of elements
+     * \return           pointer to data
+     */
+    static inline JClass_t* create(const unsigned int size)
+    { 
+      return (JClass_t*) malloc(size * sizeof(JClass_t));
+    }
+
+
+    /**
+     * Release memory.
+     *
+     * \param  p         pointer to data
+     */
+    static inline void release(JClass_t* p)
+    { 
+      free((void*) p);
+    }
+  };
+}
+
+
+#endif
diff --git a/jpp/JLang/JNullType.hh b/jpp/JLang/JNullType.hh
new file mode 100644
index 0000000..05b1da9
--- /dev/null
+++ b/jpp/JLang/JNullType.hh
@@ -0,0 +1,22 @@
+#ifndef __JLANG__JNULLTYPE__
+#define __JLANG__JNULLTYPE__
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Auxiliary class for no type definition.
+   * This class can be used to terminate a type list, define a default template argument, etc.
+   */
+  struct JNullType {};
+}
+
+#endif
diff --git a/jpp/JLang/JObjectID.hh b/jpp/JLang/JObjectID.hh
new file mode 100644
index 0000000..2c77a87
--- /dev/null
+++ b/jpp/JLang/JObjectID.hh
@@ -0,0 +1,157 @@
+#ifndef __JLANG__JOBJECTID__
+#define __JLANG__JOBJECTID__
+
+#include <istream>
+#include <ostream>
+
+#include "JLang/JComparable.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Auxiliary class for object identification.
+   */
+  class JObjectID :
+    public JComparable<JObjectID>,
+    public JComparable<JObjectID, int>
+  {
+  public:
+    /**
+     * Default constructor.
+     */
+    JObjectID() :
+      __id(-1)
+    {}
+
+  
+    /**
+     * Constructor.
+     *
+     * \param  id         identifier
+     */
+    JObjectID(const int id) :
+      __id(id)
+    {}
+
+
+    /**
+     * Get identifier.
+     *
+     * \return            identifier
+     */
+    int getID() const
+    { 
+      return __id;
+    }
+
+
+    /**
+     * Get identifier.
+     *
+     * \return            identifier
+     */
+    int& getID()
+    { 
+      return __id;
+    }
+
+
+    /**
+     * Set identifier.
+     *
+     * \param  id         identifier
+     */
+    void setID(const int id)
+    { 
+      this->__id = id;
+    }
+
+
+    /**
+     * Less than method.
+     *
+     * \param  object     object identifier
+     * \return            true if this identifier less than given identifier; else false
+     */
+    inline bool less(const JObjectID& object) const
+    { 
+      return this->getID() < object.getID();
+    }
+
+
+    /**
+     * Less than method.
+     *
+     * \param  id         identifier
+     * \return            true if this identifier less than given identifier; else false
+     */
+    inline bool less(const int id) const
+    { 
+      return this->getID() < id;
+    }
+
+
+    /**
+     * More than method.
+     *
+     * \param  id         identifier
+     * \return            true if this identifier greater than given identifier; else false
+     */
+    inline bool more(const int id) const
+    { 
+      return this->getID() > id;
+    }
+
+    
+    /**
+     * Read object identifier from input.
+     *
+     * \param  in         input stream
+     * \param  object     object identifier
+     * \return            input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JObjectID& object)
+    {
+      return in >> object.__id;
+    }
+
+
+    /**
+     * Write object identifier to output.
+     *
+     * \param  out        output stream
+     * \param  object     object identifier
+     * \return            output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JObjectID& object)
+    {
+      return out << object.__id;
+    }
+           
+  protected:
+    int __id;
+  };
+
+
+  /**
+   * Get undefined object identifier.
+   *
+   * \return           undefined object identifier
+   */
+  inline const JObjectID& getUndefinedObjectID()
+  {
+    static JObjectID id;
+
+    return id;
+  }
+}
+
+#endif
diff --git a/jpp/JLang/JObjectIO.hh b/jpp/JLang/JObjectIO.hh
new file mode 100644
index 0000000..c10939a
--- /dev/null
+++ b/jpp/JLang/JObjectIO.hh
@@ -0,0 +1,141 @@
+#ifndef __JLANG__JOBJECTIO__
+#define __JLANG__JOBJECTIO__
+
+#include <fstream>
+
+#include "JLang/JType.hh"
+#include "JLang/JException.hh"
+
+
+/**
+ * \file
+ *
+ * General methods for loading and storing a single object from and to a file, respectively.
+ * \author mdejong
+ */
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+
+namespace JLANG {
+
+  /**
+   * Get error status of reader.
+   *
+   * \param  reader          reader
+   * \return                 true if error; else false
+   */
+  template<class JReader_t>
+  inline bool getError(const JReader_t& reader)
+  {
+    return !reader;
+  }
+
+
+  /**
+   * Get error status of reader.
+   *
+   * \param  reader          reader
+   * \return                 true if error; else false
+   */
+  inline bool getError(const std::ifstream& reader)
+  {
+    return reader.bad() || (reader.fail() && !reader.eof());
+  }
+
+
+  /**
+   * Load object from input file.
+   *
+   * \param  file_name       file name
+   * \param  object          object to be read
+   */
+  template<class JReader_t, class T>
+  inline void load(const char* file_name, T& object)
+  {
+    load(file_name, object, JType<JReader_t>());
+  }
+  
+
+  /**
+   * Store object to output file.
+   *
+   * \param  file_name       file name
+   * \param  object          object to be written
+   */
+  template<class JWriter_t, class T>
+  inline void store(const char* file_name, const T& object)
+  {
+    store(file_name, object, JType<JWriter_t>());
+  }
+    
+      
+  /**
+   * Load object from input file.
+   *
+   * This method makes use of the STD protocol for the given type reader, namely:
+   * <pre>
+   *   JReader_t in(file_name);
+   *
+   *   in >> object;
+   *
+   *   in.close();
+   * </pre>
+   * This method should be overloaded if the type reader requires a different protocol.
+   *
+   * \param  file_name       file name
+   * \param  object          object to be read
+   * \param  type            reader type
+   */
+  template<class JReader_t, class T>
+  inline void load(const char* file_name, T& object, JType<JReader_t> type)
+  {
+    JReader_t in(file_name);
+    
+    if (!in) {
+      THROW(JFileOpenException, "Error opening file: " << file_name);
+    }    
+    
+    in >> object;
+    
+    if (getError(in)) {
+      THROW(JFileReadException, "Error reading file: " << file_name);
+    }
+    
+    in.close();
+  }
+
+
+  /**
+   * Store object to output file.
+   *
+   * This method makes use of the STD protocol for the given type writer, namely:
+   * <pre>
+   *   JWriter_t out(file_name);
+   *
+   *   out << object;
+   *
+   *   out.close();
+   * </pre>
+   * This method should be overloaded if the type writer requires a different protocol.
+   *
+   * \param  file_name       file name
+   * \param  object          object to be written
+   * \param  type            writer type
+   */
+  template<class JWriter_t, class T>
+  inline void store(const char* file_name, const T& object, JType<JWriter_t> type)
+  {
+    JWriter_t out(file_name);
+
+    if (!out) {
+      THROW(JFileOpenException, "Error opening file: " << file_name);
+    }    
+
+    out << object;
+
+    out.close();
+  }
+}
+
+#endif
diff --git a/jpp/JLang/JPointer.hh b/jpp/JLang/JPointer.hh
new file mode 100644
index 0000000..3d05654
--- /dev/null
+++ b/jpp/JLang/JPointer.hh
@@ -0,0 +1,140 @@
+#ifndef __JLANG__JPOINTER__
+#define __JLANG__JPOINTER__
+
+#include "JLang/JAbstractPointer.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Template implementation of class that holds pointer to object(s).
+   *
+   * This class implements the JAbstractPointer interface.
+   */
+  template<class JClass_t>
+  class JPointer :
+    public JAbstractPointer<JClass_t>
+  {
+  public:
+
+    using JAbstractPointer<JClass_t>::set;
+    using JAbstractPointer<JClass_t>::reset;
+    
+    /**
+     * Default constructor.
+     */
+    JPointer() :
+      __p(NULL)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  p        pointer to object
+     */
+    JPointer(JClass_t* p) :
+      __p(p)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  pointer  pointer to object
+     */
+    template<class T>
+    JPointer(JPointer<T> pointer) :
+      __p(pointer.get())
+    {}
+
+
+    /**
+     * Get pointer.
+     *
+     * \return          pointer to object
+     */
+    virtual JClass_t* get() const override 
+    {
+      return this->__p;
+    }
+
+
+    /**
+     * Set pointer.
+     *
+     * \param  p        pointer to object
+     */
+    virtual void set(JClass_t* p) override 
+    {
+      this->__p = p;
+    }
+
+
+    /**
+     * Reset pointer.
+     */
+    virtual void reset() override 
+    { 
+      this->__p = NULL;
+    }
+
+
+    /**
+     * Set pointer.
+     *
+     * \param  pointer  pointer to object
+     */
+    template<class T>
+    void set(const JPointer<T>& pointer)
+    {
+      this->set(pointer.get());
+    }
+
+
+    /**
+     * Reset pointer.
+     *
+     * \param  pointer  pointer to object
+     */
+    template<class T>
+    void reset(const JPointer<T>& pointer)
+    {
+      this->reset(pointer.get());
+    }
+
+
+    /**
+     * Get rereference to internal pointer.
+     *
+     * \return          reference to internal pointer
+     */
+    JClass_t* const& getReference() const
+    {
+      return __p;
+    }
+
+
+    /**
+     * Get rereference to internal pointer.
+     *
+     * \return          reference to internal pointer
+     */
+    JClass_t* & getReference()
+    {
+      return __p;
+    }
+    
+  protected:
+    JClass_t* __p;      //!< pointer to object
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JSTDTypes.hh b/jpp/JLang/JSTDTypes.hh
new file mode 100644
index 0000000..9811aaa
--- /dev/null
+++ b/jpp/JLang/JSTDTypes.hh
@@ -0,0 +1,29 @@
+#ifndef __JLANG__JSTDTYPES__
+#define __JLANG__JSTDTYPES__
+
+/**
+ * \file
+ *
+ * Forward declarations of STD containers.
+ * \author mdejong
+ */
+
+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/jpp/JLang/JSharedCounter.hh b/jpp/JLang/JSharedCounter.hh
new file mode 100644
index 0000000..54bddba
--- /dev/null
+++ b/jpp/JLang/JSharedCounter.hh
@@ -0,0 +1,98 @@
+#ifndef __JLANG__JSHAREDCOUNTER__
+#define __JLANG__JSHAREDCOUNTER__
+
+#include <cstdlib>
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Shared counter.
+   */
+  class JSharedCounter 
+  {
+  public:
+    /**
+     * Default constructor.
+     */
+    JSharedCounter() :
+      counter(NULL)
+    {}
+
+
+    /**
+     * Initialise counter.
+     */
+    void initialise()
+    {
+      detach();
+
+      counter = new int(1);
+    }
+
+
+    /**
+     * Attach this counter to given shared counter object.
+     *
+     * \param  object   shared counter
+     */
+    void attach(const JSharedCounter& object)
+    {
+      detach();
+
+      counter = object.counter;
+
+      if (counter != NULL) {
+	++(*counter);
+      }
+    }
+
+
+    /**
+     * Detach.
+     *
+     * \return          true if counter at zero; else false
+     */
+    bool detach() 
+    {
+      if (counter != NULL) {
+
+	if (--(*counter) == 0) {
+
+	  delete counter;
+
+	  counter = NULL;
+
+	  return true;
+	}
+
+	counter = NULL;
+      }
+
+      return false;
+    }
+
+
+    /**
+     * Get count
+     * 
+     * \return          count
+     */
+    const int getCount()
+    {
+      return (counter != NULL ? *counter : 0);
+    }
+
+  protected:
+    int* counter;
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JSharedPointer.hh b/jpp/JLang/JSharedPointer.hh
new file mode 100644
index 0000000..f0d6fae
--- /dev/null
+++ b/jpp/JLang/JSharedPointer.hh
@@ -0,0 +1,211 @@
+#ifndef __JLANG__JSHAREDPOINTER__
+#define __JLANG__JSHAREDPOINTER__
+
+#include "JLang/JSharedCounter.hh"
+#include "JLang/JMemory.hh"
+#include "JLang/JStorage.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * The template JSharedPointer class can be used to share a pointer to an object. 
+   * The object pointed to is deleted when the shared counter is zero, 
+   * i.e.\ when no-one shares the object.
+   * It is possible to create a container with shared pointers. 
+   * The first template argument refers to the data type pointed to
+   * and the second to the memory management policy.
+   */
+  template<class JClass_t, template<class> class JMemory_t = JNew> 
+  class JSharedPointer :
+    public JSharedCounter,
+    public JStorage<JClass_t, JMemory_t>
+  {
+  public:
+
+    typedef JPointer<JClass_t>                    pointer_type;
+    typedef JStorage<JClass_t, JMemory_t>         storage_type;
+  
+    using   JAbstractPointer<JClass_t>::reset;
+
+
+    /**
+     * Default constructor.
+     */
+    JSharedPointer() 
+    {}
+
+
+    /**
+     * Copy constructor.
+     * The reference counter of the shared object is incremented by one.
+     *
+     * \param  object   shared pointer
+     */
+    JSharedPointer(const JSharedPointer& object)
+    {
+      if (object.is_valid()) {
+	this->set(object);
+      }
+    }
+
+  
+    /**
+     * Assignment constructor.
+     * If the pointer is valid, the reference counter of the shared object pointed to 
+     * is initialised to one.
+     *
+     * \param  p        pointer to derived class object
+     */
+    template<class JDerived_t>
+    JSharedPointer(JDerived_t* p)
+    {
+      if (p != NULL) {
+	this->set(p);
+      }
+    }
+
+
+    /**
+     * Destructor.
+     * The reference counter is decremented by one and 
+     * the object pointed to is deleted when the reference counter is zero.
+     */
+    ~JSharedPointer()
+    {
+      if (this->detach()) {
+	storage_type::reset();
+      }
+    }
+
+
+    /**
+     * Get shared pointer.
+     *
+     * \return          this shared pointer
+     */
+    const JSharedPointer& getSharedPointer() const
+    {
+      return static_cast<const JSharedPointer&>(*this);
+    }
+
+
+    /**
+     * Get shared pointer.
+     *
+     * \return          this shared pointer
+     */
+    JSharedPointer& getSharedPointer()
+    {
+      return static_cast<JSharedPointer&>(*this);
+    }
+
+
+    /**
+     * Set shared pointer.
+     *
+     * \param  object   shared pointer
+     */
+    void setSharedPointer(const JSharedPointer& object)
+    {
+      if (this->get() != object.get()) {
+
+	this->reset();
+
+	if (object.is_valid()) {
+	  this->set(object);
+	}
+      }
+    }
+
+
+    /**
+     * Assignment operator.
+     * The reference counter is decremented by one and 
+     * the object pointed to previously is deleted when its reference counter is zero.
+     * The reference counter of the shared object is incremented by one.
+     *
+     * \param  object   shared pointer 
+     * \return          this shared pointer
+     */
+    JSharedPointer& operator=(const JSharedPointer& object) 
+    {
+      this->setSharedPointer(object);
+
+      return *this;
+    }
+
+  
+    /**
+     * Assignment operator.
+     * The reference counter is decremented by one and 
+     * the object pointed to previously is deleted when its reference counter is zero.
+     * If the pointer is valid, the reference counter of the shared object pointed to 
+     * is initialised to one.
+     *
+     * \param  p        pointer to derived class object
+     * \return          this shared pointer
+     */
+    template<class JDerived_t>
+    JSharedPointer& operator=(JDerived_t* p)
+    {
+      this->reset(p);
+
+      return *this;
+    }
+
+
+    /**
+     * Reset pointer.
+     * The reference counter is decremented by one and 
+     * the object pointed to previously is deleted when its reference counter is zero.
+     */
+    virtual void reset() override 
+    {
+      if (this->detach()) {
+	storage_type::reset();
+      }
+
+      pointer_type::reset();
+    }
+
+
+  protected:
+    /**
+     * Set pointer.
+     * The reference counter of the shared object pointed to is incremented by one.
+     *
+     * \param  object   shared pointer 
+     */
+    void set(const JSharedPointer& object) 
+    {
+      pointer_type::set(object.get());
+
+      this->attach(object);
+    }
+
+
+    /**
+     * Set pointer.
+     * The reference counter of the shared object pointed to is initialised to one.
+     *
+     * \param  p        pointer to derived class object
+     */
+    virtual void set(JClass_t* p) override 
+    {
+      pointer_type::set(p);
+
+      this->initialise();
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JSinglePointer.hh b/jpp/JLang/JSinglePointer.hh
new file mode 100644
index 0000000..1832951
--- /dev/null
+++ b/jpp/JLang/JSinglePointer.hh
@@ -0,0 +1,113 @@
+#ifndef __JLANG__JSINGLEPOINTER__
+#define __JLANG__JSINGLEPOINTER__
+
+#include "JLang/JStorage.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * The template JSinglePointer class can be used to hold a pointer to an object.
+   * The object pointed to is deleted at destruction.
+   * It is possible to create a container with single pointers.
+   * The first template argument refers to the data type pointed to
+   * and the second to the memory management policy.
+   */
+  template<class JClass_t, template<class> class JMemory_t = JNew> 
+  class JSinglePointer :
+    public JStorage<JClass_t, JMemory_t>
+  {
+  public:
+
+    /**
+     * Default constructor.
+     */
+    JSinglePointer()
+    {}
+
+
+    /**
+     * Copy constructor.
+     * The ownership of the object pointed to is transferred to this single pointer.
+     *
+     * \param  object   single pointer
+     */
+    JSinglePointer(const JSinglePointer& object)
+    {
+      this->set(object.get());
+
+      const_cast<JSinglePointer&>(object).set(NULL);
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  p        pointer to object
+     */
+    JSinglePointer(JClass_t* p)
+    {
+      this->set(p);
+    }
+
+
+    /**
+     * Destructor.
+     */
+    ~JSinglePointer()
+    {
+      this->reset();
+    }
+
+
+    /**
+     * Assignment operator.
+     * The object pointed to previously is deleted.
+     * The ownership of the object pointed to is transferred to this single pointer.
+     *
+     * \param  object   single pointer
+     * \return          this single pointer
+     */
+    JSinglePointer& operator=(const JSinglePointer& object)
+    {
+      if (this->get() != object.get()) {
+
+	this->reset();
+
+	if (object.is_valid()) {
+
+	  this->set(object.get());
+
+	  const_cast<JSinglePointer&>(object).set(NULL);
+	}
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Assignment operator.
+     * The object pointed to previously is deleted.
+     *
+     * \param  p        pointer to derived class object
+     * \return          this single pointer
+     */
+    template<class JDerived_t>
+    JSinglePointer& operator=(JDerived_t* p)
+    {
+      this->reset(p);
+
+      return *this;
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JStorage.hh b/jpp/JLang/JStorage.hh
new file mode 100644
index 0000000..159996e
--- /dev/null
+++ b/jpp/JLang/JStorage.hh
@@ -0,0 +1,98 @@
+#ifndef __JLANG__JSTORAGE__
+#define __JLANG__JSTORAGE__
+
+#include "JLang/JPointer.hh"
+#include "JLang/JMemory.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Template storage class.
+   * This class extends the JPointer class with storage capabilities.
+   * The first template argument refers to the data type pointed to
+   * and the second (optional argument) to the memory management policy (see e.g.\ JMemory.hh).
+   * The method create() can be used to allocate memory;
+   * the method reset() releases the allocated memory.
+   */
+  template<class JClass_t, template<class> class JMemory_t = JNew>
+  class JStorage :
+    public JPointer <JClass_t>,
+    public JMemory_t<JClass_t>
+  {
+  public:
+
+    typedef JPointer <JClass_t>                   pointer_type;
+    typedef JMemory_t<JClass_t>                   memory_type;
+
+    using pointer_type::reset;
+
+
+    /**
+     * Reset pointer.
+     * The allocated memory is released.
+     */
+    virtual void reset() override 
+    { 
+      if (this->is_valid()) {
+	this->release();
+      }
+
+      pointer_type::reset();
+    }
+
+
+    /**
+     * Recreate object in memory.
+     * A new object is created if no memory is allocated yet, 
+     * else the previously created object is maintained.
+     */
+    void recreate()
+    {
+      if (!this->is_valid()) {
+	this->set(memory_type::create());
+      }
+    }
+
+
+    /**
+     * Create object in memory.
+     * The memory allocated by a previously created object will be released.
+     */
+    void create()
+    {
+      this->reset(memory_type::create());
+    }
+
+
+    /**
+     * Create array of objects in memory.
+     * The memory allocated by previously created objects will be released.
+     *
+     * \param  size      number of elements
+     */
+    void create(const unsigned int size)
+    {
+      this->reset(memory_type::create(size));
+    }
+
+
+  protected:
+    /**
+     * Release memory.
+     */
+    void release()
+    { 
+      memory_type::release(this->get());
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JLang/JType.hh b/jpp/JLang/JType.hh
new file mode 100644
index 0000000..6a547c4
--- /dev/null
+++ b/jpp/JLang/JType.hh
@@ -0,0 +1,37 @@
+#ifndef __JLANG__JTYPE__
+#define __JLANG__JTYPE__
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Auxiliary class for a type holder.
+   * This class can be used to transfer a template class to a method argument.
+   */
+  template<class T>
+  struct JType {
+
+    typedef T  data_type;
+  };
+
+
+  /**
+   * Get type.
+   *
+   * \return             type
+   */
+  template<class T>
+  inline JType<T> getType()
+  {
+    return JType<T>();
+  }
+}
+
+#endif
diff --git a/jpp/JLang/JVectorize.hh b/jpp/JLang/JVectorize.hh
new file mode 100644
index 0000000..f99038f
--- /dev/null
+++ b/jpp/JLang/JVectorize.hh
@@ -0,0 +1,193 @@
+#ifndef __JLANG__JVECTORIZE__
+#define __JLANG__JVECTORIZE__
+
+#include <vector>
+#include <iterator>
+
+#include "JLang/JSTDTypes.hh"
+#include "JLang/JClass.hh"
+
+
+/**
+ * \file
+ * Auxiliary methods to convert data members or return values of member methods of a set of objects to a single vector.
+ * \author mdejong
+ */
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+  /**
+   * Auxiliary data structure for return type of make methods.
+   */
+  template<class JElement_t, class JAllocator_t = std::allocator<JElement_t> >
+  struct array_type :
+    public std::vector<JElement_t, JAllocator_t>
+  {};
+
+
+  /**
+   * Method to create array of values.
+   *
+   * \param  array        c-array of values
+   * \return              data
+   */
+  template<class JValue_t, size_t N>
+  inline const array_type<JValue_t>& make_array(const JValue_t (&array)[N])
+  {
+    static array_type<JValue_t> buffer;
+
+    buffer.resize(N);
+
+    for (size_t i = 0; i != N; ++i) {
+      buffer[i] = array[i];
+    }
+
+    return buffer;
+  }
+
+
+  /**
+   * Method to create array of values.
+   *
+   * \param  __begin      begin of data
+   * \param  __end        end   of data
+   * \return              data
+   */
+  template<class T>
+  inline const array_type<typename std::iterator_traits<T>::value_type>& make_array(T __begin, T __end)
+  {
+    static array_type<typename std::iterator_traits<T>::value_type> buffer;
+
+    buffer.assign(__begin, __end);
+
+    return buffer;
+  }
+
+
+  /**
+   * Method to create array of values of data member.
+   *
+   * \param  __begin      begin of data
+   * \param  __end        end   of data
+   * \param  value        pointer to data member
+   * \return              data
+   */
+  template<class T, class JType_t, class JValue_t>
+  inline const array_type<typename JClass<JValue_t>::value_type>& make_array(T __begin, T __end, JValue_t const JType_t::*value)
+  {
+    static array_type<typename JClass<JValue_t>::value_type> buffer;
+
+    buffer.clear();
+
+    for (T __p = __begin; __p != __end; ++__p) {
+      buffer.push_back(*__p.*value);
+    }
+
+    return buffer;
+  }
+
+
+  /**
+   * Method to create array of return values of member method.
+   *
+   * \param  __begin      begin of data
+   * \param  __end        end   of data
+   * \param  function     pointer to member method
+   * \return              data
+   */
+  template<class T, class JType_t, class JValue_t>
+  inline const array_type<typename JClass<JValue_t>::value_type>& make_array(T __begin, T __end, JValue_t (JType_t::*function)() const)
+  {
+    static array_type<typename JClass<JValue_t>::value_type> buffer;
+
+    buffer.clear();
+
+    for (T __p = __begin; __p != __end; ++__p) {
+      buffer.push_back((*__p.*function)());
+    }
+
+    return buffer;
+  }
+
+
+  /**
+   * Method to create array of keys of map.
+   *
+   * \param  data         data
+   * \return              data
+   */
+  template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>
+  inline const array_type<JKey_t>& get_keys(const std::map<JKey_t, JValue_t, JComparator_t, JAllocator_t>& data)
+  {
+    return make_array(data.begin(), data.end(), &std::map<JKey_t, JValue_t, JComparator_t, JAllocator_t>::value_type::first);
+  }
+
+
+  /**
+   * Method to create array of values of map.
+   *
+   * \param  data         data
+   * \return              data
+   */
+  template<class JKey_t, class JValue_t, class JComparator_t, class JAllocator_t>
+  inline const array_type<JValue_t>& get_values(const std::map<JKey_t, JValue_t, JComparator_t, JAllocator_t>& data)
+  {
+    return make_array(data.begin(), data.end(), &std::map<JKey_t, JValue_t, JComparator_t, JAllocator_t>::value_type::second);
+  }
+
+
+  /**
+   * Method to exclude outliers from already sorted data.\n
+   * Note that the part after the returned iterator will be overwritten.
+   *
+   * \param  __begin      begin of data
+   * \param  __end        end   of data
+   * \param  value        pointer to data member,
+   * \param  comparator   comparison method
+   * \return              end   of sorted data
+   */
+  template<class T, class JResult_t, class JComparator_t>
+  T make_set(T __begin,
+	     T __end,
+	     JResult_t std::iterator_traits<T>::value_type::*value,
+	     const JComparator_t& comparator)
+
+  {
+    T p2 = __begin;
+    T p0 = p2++;
+    T p1 = p2++;
+
+    if (p0 == __end) { return p0; }
+    if (p1 == __end) { return p1; }
+
+    if (p2 == __end) {
+      if (comparator((*p0).*value, (*p1).*value))
+	return p2;
+      else
+	return p0;
+    }
+
+    for ( ; p2 != __end; ++p2) {
+
+      if (comparator((*p0).*value, (*p1).*value)) {
+	if (comparator((*p1).*value, (*p2).*value)) {
+	  *(++p0) = *p1;
+	  *(++p1) = *p2;
+	} else if (comparator((*p0).*value, (*p2).*value)) {
+	  *p1 = *p2;
+	}
+      } else {
+	if (comparator((*p2).*value, (*p0).*value)) {
+	  *p0 = *p1;
+	}
+	*p1 = *p2;
+      }
+    }
+
+    return ++p1;
+  }
+}
+
+#endif
diff --git a/jpp/JLang/JVoid.hh b/jpp/JLang/JVoid.hh
new file mode 100644
index 0000000..f9888ac
--- /dev/null
+++ b/jpp/JLang/JVoid.hh
@@ -0,0 +1,26 @@
+#ifndef __JLANG__JVOID__
+#define __JLANG__JVOID__
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JLANG {}
+namespace JPP { using namespace JLANG; }
+
+namespace JLANG {
+
+
+  /**
+   * Auxiliary class for void type definition.
+   * This class can be used to evaluate the validity of a type definition.
+   */
+  template<class T>
+  struct JVoid 
+  { 
+    typedef void type;
+  };
+}
+
+#endif
diff --git a/jpp/JLang/gzstream.h b/jpp/JLang/gzstream.h
new file mode 100644
index 0000000..4b40bbc
--- /dev/null
+++ b/jpp/JLang/gzstream.h
@@ -0,0 +1,229 @@
+/**
+ * \author mdejong
+ */
+
+// ============================================================================
+// gzstream, C++ iostream classes wrapping the zlib compression library.
+// Copyright (C) 2001  Deepak Bandyopadhyay, Lutz Kettner
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+// ============================================================================
+//
+// File          : gzstream.h
+// Revision      : $Revision: 1.5 $
+// Revision_date : $Date: 2002/04/26 23:30:15 $
+// Author(s)     : Deepak Bandyopadhyay, Lutz Kettner
+// 
+// Standard streambuf implementation following Nicolai Josuttis, "The 
+// Standard C++ Library".
+// ============================================================================
+
+#ifndef GZSTREAM_H
+#define GZSTREAM_H 1
+
+// standard C++ with new header file names and std:: namespace
+#include <iostream>
+#include <fstream>
+#include <zlib.h>
+#include <string>
+#include <string.h>
+
+#ifdef GZSTREAM_NAMESPACE
+namespace GZSTREAM_NAMESPACE {
+#endif
+
+// ----------------------------------------------------------------------------
+// Internal classes to implement gzstream. See below for user classes.
+// ----------------------------------------------------------------------------
+
+class gzstreambuf : public std::streambuf {
+private:
+    static const int bufferSize = 47+256;    // size of data buff
+    // totals 512 bytes under g++ for igzstream at the end.
+
+    gzFile           file;               // file handle for compressed file
+    char             buffer[bufferSize]; // data buffer
+    char             opened;             // open/close state of stream
+    int              mode;               // I/O mode
+
+    
+    int flush_buffer() {
+        // Separate the writing of the buffer from overflow() and
+        // sync() operation.
+        int w = pptr() - pbase();
+        if ( gzwrite( file, pbase(), w) != w)
+            return EOF;
+        pbump( -w);
+        return w;
+    }
+public:
+    gzstreambuf() : opened(0) {
+        setp( buffer, buffer + (bufferSize-1));
+        setg( buffer + 4,     // beginning of putback area
+              buffer + 4,     // read position
+              buffer + 4);    // end position      
+        // ASSERT: both input & output capabilities will not be used together
+    }
+    int is_open() const { return opened; }
+
+    ~gzstreambuf() { close(); }
+    gzstreambuf* open( const char* name, int open_mode) {
+        if ( is_open())
+            return (gzstreambuf*)0;
+        mode = open_mode;
+        // no append nor read/write mode
+        if ((mode & std::ios::ate) || (mode & std::ios::app)
+            || ((mode & std::ios::in) && (mode & std::ios::out)))
+            return (gzstreambuf*)0;
+        char  fmode[10];
+        char* fmodeptr = fmode;
+        if ( mode & std::ios::in)
+            *fmodeptr++ = 'r';
+        else if ( mode & std::ios::out)
+            *fmodeptr++ = 'w';
+        *fmodeptr++ = 'b';
+        *fmodeptr = '\0';
+        file = gzopen( name, fmode);
+        if (file == 0)
+            return (gzstreambuf*)0;
+        opened = 1;
+	setg( buffer + 4,     // beginning of putback area
+	      buffer + 4,     // read position
+	      buffer + 4);    // end position      
+        return this;
+    }
+    
+    gzstreambuf * close() {
+        if ( is_open()) {
+            sync();
+            opened = 0;
+            if ( gzclose( file) == Z_OK)
+                return this;
+        }
+        return (gzstreambuf*)0;
+    }
+    
+    virtual int underflow() { // used for input buffer only
+        if ( gptr() && ( gptr() < egptr()))
+            return * reinterpret_cast<unsigned char *>( gptr());
+        
+        if ( ! (mode & std::ios::in) || ! opened)
+            return EOF;
+        // Josuttis' implementation of inbuf
+        int n_putback = gptr() - eback();
+        if ( n_putback > 4)
+            n_putback = 4;
+        memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
+        
+        int num = gzread( file, buffer+4, bufferSize-4);
+        if (num <= 0) // ERROR or EOF
+            return EOF;
+        
+        // reset buffer pointers
+        setg( buffer + (4 - n_putback),   // beginning of putback area
+             buffer + 4,                 // read position
+             buffer + 4 + num);          // end of buffer
+        
+        // return next character
+        return * reinterpret_cast<unsigned char *>( gptr());    
+    }
+    
+    virtual int overflow( int c=EOF) { // used for output buffer only
+        if ( ! ( mode & std::ios::out) || ! opened)
+            return EOF;
+        if (c != EOF) {
+            *pptr() = c;
+            pbump(1);
+        }
+        if ( flush_buffer() == EOF)
+            return EOF;
+        return c;
+    }
+    
+    virtual int sync() {
+        // Changed to use flush_buffer() instead of overflow( EOF)
+        // which caused improper behavior with std::endl and flush(),
+        // bug reported by Vincent Ricard.
+        if ( pptr() && pptr() > pbase()) {
+            if ( flush_buffer() == EOF)
+                return -1;
+        }
+        return 0;
+    }    
+};
+
+class gzstreambase : virtual public std::ios {
+protected:
+    gzstreambuf buf;
+public:
+    
+    gzstreambase() { init(&buf); }
+    gzstreambase( const char* name, int mode) {
+        init( &buf);
+        open( name, mode);
+    }
+    ~gzstreambase() {
+        buf.close();
+    }
+    void open( const char* name, int open_mode) {
+        if ( ! buf.open( name, open_mode))
+            clear( rdstate() | std::ios::badbit);
+    }
+    
+    void close() {
+      if ( buf.is_open()) {
+	if ( ! buf.close())
+	  clear( rdstate() | std::ios::badbit );
+	else
+	  clear();
+      }
+    }
+    gzstreambuf* rdbuf() { return &buf; }
+    bool is_open() const { return buf.is_open(); }
+};
+
+// ----------------------------------------------------------------------------
+// User classes. Use igzstream and ogzstream analogously to ifstream and
+// ofstream respectively. They read and write files based on the gz* 
+// function interface of the zlib. Files are compatible with gzip compression.
+// ----------------------------------------------------------------------------
+
+class igzstream : public gzstreambase, public std::istream {
+public:
+    igzstream() : std::istream( &buf) {} 
+    igzstream( const char* name, int open_mode = std::ios::in)
+        : gzstreambase( name, open_mode), std::istream( &buf) {}  
+    void open( const char* name, int open_mode = std::ios::in) {
+        gzstreambase::open( name, open_mode);
+    }
+};
+
+class ogzstream : public gzstreambase, public std::ostream {
+public:
+    ogzstream() : std::ostream( &buf) {}
+    ogzstream( const char* name, int mode = std::ios::out)
+        : gzstreambase( name, mode), std::ostream( &buf) {}  
+    void open( const char* name, int open_mode = std::ios::out) {
+        gzstreambase::open( name, open_mode);
+    }
+};
+
+#ifdef GZSTREAM_NAMESPACE
+} // namespace GZSTREAM_NAMESPACE
+#endif
+
+#endif // GZSTREAM_H
+// ============================================================================
+// EOF //
diff --git a/jpp/JMath/JCalculator.hh b/jpp/JMath/JCalculator.hh
new file mode 100644
index 0000000..836eeb6
--- /dev/null
+++ b/jpp/JMath/JCalculator.hh
@@ -0,0 +1,93 @@
+#ifndef __JMATH__JCALCULATOR__
+#define __JMATH__JCALCULATOR__
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JMATH {}
+namespace JPP { using namespace JMATH; }
+
+namespace JMATH {
+
+  /**
+   * Auxiliary class for arithmetic operations on objects.
+   */  
+  template<class T, int N = 0>
+  struct JCalculator :
+    public T                         // object
+  {
+    /**
+     * Set calculator value.
+     *
+     * \param  value       value
+     * \return             this calculator
+     */
+    JCalculator& set(const T& value) 
+    {
+      static_cast<T&>(*this) = value;
+
+      return *this;
+    }
+
+    static JCalculator calculator;   // calculator
+  };
+
+  
+  /**
+   * Calculator.
+   */
+  template<class T, int N>
+  JCalculator<T,N> JCalculator<T,N>::calculator;
+  
+  
+  /** 
+   * Product evaluation of objects.
+   *
+   * \param  first       first  object
+   * \param  second      second object
+   * \return             calculator
+   */
+  template<class T>
+  inline const JCalculator<T, 1>& operator*(const T& first, const T& second)
+  {
+    JCalculator<T, 1>::calculator.mul(first, second);
+
+    return JCalculator<T, 1>::calculator;
+  }
+
+
+  /**
+   * Recursive product evaluation of objects.
+   *
+   * \param  first       first  object
+   * \param  second      second object
+   * \return             calculator
+   */
+  template<class T, int N>
+  inline const JCalculator<T, N+1>& operator*(const T& first, const JCalculator<T, N>& second)
+  {
+    JCalculator<T, N+1>::calculator.mul(first, second);
+
+    return JCalculator<T, N+1>::calculator;
+  }
+
+
+  /**
+   * Recursive product evaluation of objects.
+   *
+   * \param  first       first  object
+   * \param  second      second object
+   * \return             calculator
+   */
+  template<class T, int N>
+  inline const JCalculator<T, N+1>& operator*(const JCalculator<T, N>& first, const T& second)
+  {
+    JCalculator<T, N+1>::calculator.mul(first, second);
+
+    return JCalculator<T, N+1>::calculator;
+  }
+}
+
+#endif
diff --git a/jpp/JMath/JConstants.hh b/jpp/JMath/JConstants.hh
new file mode 100644
index 0000000..5ae6452
--- /dev/null
+++ b/jpp/JMath/JConstants.hh
@@ -0,0 +1,31 @@
+#ifndef __JMATH__JCONSTANTS__
+#define __JMATH__JCONSTANTS__
+
+#include <math.h>
+
+
+/**
+ * \file
+ * Mathematical constants. 
+ * \author mdejong
+ */
+namespace JMATH {}
+namespace JPP { using namespace JMATH; }
+
+namespace JMATH {
+
+  /**
+   * Mathematical constants.
+   */
+  static const double PI                        = acos(-1.0);           //!< pi
+  static const double EULER                     = 0.577215664901533;    //!< Euler number
+
+  /**
+   * Computing quantities.
+   */
+  static const long long int KILOBYTE   = 1024;                        //! Number of bytes in a kilo-byte
+  static const long long int MEGABYTE   = KILOBYTE*KILOBYTE;           //! Number of bytes in a mega-byte
+  static const long long int GIGABYTE   = MEGABYTE*KILOBYTE;           //! Number of bytes in a giga-byte
+}
+
+#endif
diff --git a/jpp/JMath/JLimits.hh b/jpp/JMath/JLimits.hh
new file mode 100644
index 0000000..cebfe3e
--- /dev/null
+++ b/jpp/JMath/JLimits.hh
@@ -0,0 +1,126 @@
+#ifndef __JMATH__JLIMITS__
+#define __JMATH__JLIMITS__
+
+#include <limits>
+
+/**
+ * \file
+ *
+ * Definition of minimum and maximum values for any class.
+ * \author mdejong
+ */
+namespace JMATH {}
+namespace JPP { using namespace JMATH; }
+
+namespace JMATH {
+
+  /**
+   * Auxiliary class for minimum and maximum values for any class.
+   */
+  template<class T, bool __is_specialized__ = std::numeric_limits<T>::is_specialized>
+  struct JLimits;
+
+
+  /**
+   * Template spacialisation of JMATH::JLimits for numerical values.
+   */
+  template<class T>
+  struct JLimits<T, true> {
+    /**
+     * Get minimum possible value.
+     *
+     * \return                  minimum possible value
+     */
+    static T min()
+    {
+      return std::numeric_limits<T>::min();
+    }
+
+
+    /**
+     * Get maximum possible value.
+     *
+     * \return                  maximum possible value
+     */
+    static T max()
+    {
+      return std::numeric_limits<T>::max();
+    }
+
+    static const bool is_specialized = true; 
+  };
+
+
+  /**
+   * Template spacialisation of JMATH::JRandom for other data types.
+   *
+   * The given template class should provide for the methods:
+   * <pre>
+   *      static T %min();
+   *      static T %max();
+   * </pre>
+   */
+  template<class T>
+  struct JLimits<T, false> {
+    /**
+     * Get minimum possible value.
+     *
+     * \return                  minimum possible value
+     */
+    static T min()
+    {
+      return T::min();
+    }
+
+
+    /**
+     * Get maximum possible value.
+     *
+     * \return                  maximum possible value
+     */
+    static T max()
+    {
+      return T::max();
+    }
+
+    static const bool is_specialized = false; 
+  };
+
+  
+  /**
+   * Get minimum possible value.
+   *
+   * \return                  minimum possible value
+   */
+  template<>
+  inline float JLimits<float, true>::min()
+  {
+    return std::numeric_limits<float>::lowest();
+  }
+
+  
+  /**
+   * Get minimum possible value.
+   *
+   * \return                  minimum possible value
+   */
+  template<>
+  inline double JLimits<double, true>::min()
+  {
+    return std::numeric_limits<double>::lowest();
+  }
+
+  
+  /**
+   * Get minimum possible value.
+   *
+   * \return                  minimum possible value
+   */
+  template<>
+  inline long double JLimits<long double, true>::min()
+  {
+    return std::numeric_limits<long double>::lowest();
+  }
+}
+
+#endif
diff --git a/jpp/JMath/JMath.hh b/jpp/JMath/JMath.hh
new file mode 100644
index 0000000..8c37cc9
--- /dev/null
+++ b/jpp/JMath/JMath.hh
@@ -0,0 +1,591 @@
+#ifndef __JMATH__
+#define __JMATH__
+
+#include <cmath>
+#include <iterator>
+
+#include "JLang/JNullType.hh"
+#include "JLang/JClass.hh"
+#include "JLang/JBool.hh"
+#include "JLang/JVectorize.hh"
+#include "JLang/JException.hh"
+#include "JMath/JZero.hh"
+#include "JMath/JCalculator.hh"
+
+
+/**
+ * \file
+ * 
+ * Base class for data structures with artithmetic capabilities.
+ * \author mdejong
+ */
+namespace JMATH {}
+namespace JPP { using namespace JMATH; }
+
+namespace JGEOMETRY3D { class JQuaternion3D; }
+
+namespace JMATH {
+
+  using JLANG::JNullType;
+  using JLANG::array_type;
+  using JLANG::JDivisionByZero;
+  
+  
+  /**
+   * Power \f$x^y\f$.
+   *
+   * \param  x              value
+   * \param  y              power
+   * \return                result
+   */
+  template<class T>
+  inline T pow(const T& x, const double y);
+
+
+  /**
+   * Auxiliary class to hide data type specific methods.
+   */
+  struct JMath_t {
+    /**
+     * Friend declaration of global method.
+     */
+    template<class T>
+    friend T JMATH::pow(const T&, const double y);
+
+  private:
+    /**
+     * Power \f$x^y\f$.
+     * This method corresponds to primitive data types.
+     *
+     * \param  x              value
+     * \param  y              power
+     * \param  option         true
+     * \return                result
+     */
+    template<class T>
+    static inline T pow(const T& x, const double y, const JLANG::JBool<true> option)
+    {
+      return std::pow(x, y);
+    }
+
+
+    /**
+     * Power \f$x^y\f$.
+     * Power.
+     * This method corresponds to non-primitive data types.
+     *
+     * \param  x              value
+     * \param  y              power
+     * \param  option         false
+     * \return                result
+     */
+    template<class T>
+    static inline T pow(const T& x, const double y, const JLANG::JBool<false> option)
+    {
+      return T(x).pow(y);
+    }
+  };
+
+
+  /**
+   * Power \f$x^y\f$.
+   *
+   * \param  x              value
+   * \param  y              power
+   * \return                result
+   */
+  template<class T>
+  inline T pow(const T& x, const double y)
+  {
+    using namespace JPP;
+
+    return JMath_t::pow(x, y, JBool<JClass<T>::is_primitive>());
+  }
+
+
+  /**
+   * Auxiliary base class for aritmetic operations of derived class types.
+   */
+  template<class JFirst_t, class JSecond_t = JNullType>
+  struct JMath;
+
+    
+  /**
+   * Template base class for data structures with arithmetic capabilities.
+   *
+   * This class provides for the operators <tt> - += -= *= /= + - * / </tt>.\n
+   * To this end, the template parameter should privide for the corresponding member methods:
+   * <pre>
+   *       T& negate();
+   *       T& add(const T& object);
+   *       T& sub(const T& object);
+   *       T& mul(const double factor);
+   *       T& div(const double factor);
+   * </pre>
+   *
+   * This class also provides for the object multiplication operators <tt>*= *</tt>.\n
+   * To this end, the template parameter should then also provide for the member method:
+   * <pre>
+   *       T& mul(const T&, const T&);
+   * </pre>
+   *
+   * This class adds interpolation functionality.\n
+   * This class uses in-class friend operators (see Barton-Nackman trick).
+   */
+  template<class T>
+  struct JMath<T, JNullType> {
+    /**
+     * Affirm operator.
+     *
+     * \param  object         this object
+     * \return                affirmed object
+     */
+    friend T operator+(const T& object) 
+    { 
+      return T(object);
+    }
+
+    
+    /**
+     * Negate operator.
+     *
+     * \param  object         this object
+     * \return                negated object
+     */
+    friend T operator-(const T& object) 
+    { 
+      return T(object).negate();
+    }
+
+    
+    /**
+     * Add object.
+     *
+     * \param  object         this object
+     * \param  value          value
+     * \return                this object
+     */
+    friend T& operator+=(T& object, const T& value)
+    { 
+      return object.add(value);
+    }
+
+    
+    /**
+     * Subtract object.
+     *
+     * \param  object         this object
+     * \param  value          value
+     * \return                this object
+     */
+    friend T& operator-=(T& object, const T& value)
+    { 
+      return object.sub(value);
+    }
+
+
+    /**
+     * Scale object.
+     *
+     * \param  object         this object
+     * \param  factor         factor
+     * \return                this object
+     */
+    friend T& operator*=(T& object, const double factor)
+    { 
+      return object.mul(factor);
+    }
+
+
+    /**
+     * Scale object.
+     *
+     * \param  object         this object
+     * \param  factor         factor
+     * \return                this object
+     */
+    friend T& operator/=(T& object, const double factor)
+    { 
+      return object.div(factor);
+    }
+
+    
+    /**
+     * Add objects.
+     *
+     * \param  first          first  object
+     * \param  second         second object
+     * \return                result object
+     */
+    friend T operator+(const T& first, const T& second)
+    { 
+      return JCalculator<T>::calculator.set(first).add(second);
+    }
+
+    
+    /**
+     * Subtract objects.
+     *
+     * \param  first          first  object
+     * \param  second         second object
+     * \return                result object
+     */
+    friend T operator-(const T& first, const T& second)
+    { 
+      return JCalculator<T>::calculator.set(first).sub(second);
+    }
+
+
+    /**
+     * Scale object.
+     *
+     * \param  object         object
+     * \param  factor         factor
+     * \return                object
+     */
+    friend T operator*(const T& object, const double factor)
+    { 
+      return JCalculator<T>::calculator.set(object).mul(factor);
+    }
+
+
+    /**
+     * Scale object.
+     *
+     * \param  factor         factor
+     * \param  object         object
+     * \return                object
+     */
+    friend T operator*(const double factor, const T& object)
+    { 
+      return JCalculator<T>::calculator.set(object).mul(factor);
+    }
+
+
+    /**
+     * Scale object.
+     *
+     * \param  object         object
+     * \param  factor         factor
+     * \return                object
+     */
+    friend T operator/(const T& object, const double factor)
+    { 
+      return JCalculator<T>::calculator.set(object).div(factor);
+    }
+
+
+    /**
+     * Multiply with object.
+     *
+     * \param  object         object
+     * \return                result object
+     */
+    T& mul(const T& object)
+    {
+      return static_cast<T&>(*this) = JCalculator<T>::calculator.mul(static_cast<const T&>(*this), object);
+    }
+
+
+    /**
+     * Multiply with object.
+     *
+     * \param  first          first  object
+     * \param  second         second object
+     * \return                result object
+     */
+    friend T& operator*=(T& first, const T& second)
+    {
+      return first.mul(second);
+    }
+
+    
+    /**
+     * Multiply objects.
+     *
+     * \param  first          first  object
+     * \param  second         second object
+     * \return                calculator
+     */
+    friend const JCalculator<T, 1>& operator*(const T& first, const T& second)
+    { 
+      JCalculator<T, 1>::calculator.mul(first, second);
+
+      return JCalculator<T, 1>::calculator;
+    }
+
+
+    /**
+     * Interpolation between objects.
+     * The result is equal to <tt>*this = (1 - alpha) * (*this) + (alpha) * (object)</tt>.
+     *
+     * \param  object         object
+     * \param  alpha          interpolation factor <tt>[0, 1]</tt>
+     * \return                this object
+     */
+    T& interpolate(const T& object, const double alpha)
+    {
+      static_cast<T*>(this)->mul(1.0 - alpha);
+      static_cast<T*>(this)->add(T(object).mul(alpha));
+
+      return static_cast<T&>(*this);
+    }
+  };
+
+  
+  /**
+   * Specialisation of JMath for two data types.
+   *
+   * This class provides for the object multiplication operators <tt>*= *</tt>.
+   * The template parameter should then have the member method:
+   * <pre>
+   *       JFirst_t& mul(const JFirst_t&, const JSecond_t&);
+   * </pre>
+   * where <tt>JFirst_t</tt> and <tt>JSecond_t</tt> refer to the first and second template parameter, respectively.
+   *
+   * This class uses in-class friend operators (see Barton-Nackman trick).
+   */
+  template<class JFirst_t, class JSecond_t>
+  struct JMath
+  {
+    /**
+     * Multiply with object.
+     *
+     * \param  object         object
+     * \return                result object
+     */
+    JFirst_t& mul(const JSecond_t& object)
+    {
+      return static_cast<JFirst_t&>(*this) = JCalculator<JFirst_t>::calculator.mul(static_cast<const JFirst_t&>(*this), object);
+    }
+
+
+    /**
+     * Multiply with object.
+     *
+     * \param  first          first  object
+     * \param  second         second object
+     * \return                result object
+     */
+    friend JFirst_t& operator*=(JFirst_t& first, const JSecond_t& second)
+    {
+      return first.mul(second);
+    }
+
+    
+    /**
+     * Multiply objects.
+     *
+     * \param  first          first  object
+     * \param  second         second object
+     * \return                result object
+     */
+    friend JFirst_t operator*(const JFirst_t& first, const JSecond_t& second)
+    { 
+      return JFirst_t(first).mul(second);
+    }
+  };
+
+
+  /**
+   * Interpolation between objects.
+   * The result is equal to <tt>result = (1 - alpha) * (first) + (alpha) * (second)</tt>.
+   *
+   * \param  first          first  object
+   * \param  second         second object
+   * \param  alpha          interpolation factor <tt>[0, 1]</tt>
+   * \return                result
+   */
+  template<class T>
+  inline T interpolate(const T&     first,
+		       const T&     second, 
+		       const double alpha)
+  {
+    return T(first).interpolate(second, alpha);
+  }
+
+
+  /**
+   * Auxiliary class to determine average of set of values.
+   */
+  template<class JValue_t>
+  struct JAverage {
+    /**
+     * Default constructor.
+     */
+    JAverage() :
+      value (getZero<JValue_t>()),
+      weight(0.0)
+    {}
+
+    
+    /**
+     * Constructor.
+     *
+     * \param  __begin        begin of data
+     * \param  __end          end   of data
+     */
+    template<class T>
+    JAverage(T __begin, T __end) :
+      value (getZero<JValue_t>()),
+      weight(0.0)
+    {
+      for (T i = __begin; i != __end; ++i) {
+	value  += (*i);
+	weight += 1.0;
+      }
+    }
+
+
+    /**
+     * Reset.
+     */
+    void reset()
+    {
+      this->value  = getZero<JValue_t>();
+      this->weight = 0.0;
+    }
+
+
+    /**
+     * Type conversion operator.
+     *
+     * \return                value
+     */
+    operator JValue_t () const
+    {
+      if (weight != 0.0)
+	return value * (1.0 / weight);
+      else
+	THROW(JDivisionByZero, "Invalid weight.");
+    }
+
+
+    /**
+     * Put value.
+     *
+     * \param  value         value
+     * \param  w             weight
+     */
+    void put(const JValue_t& value, const double w = 1.0)
+    {
+      this->value  += value;
+      this->weight += w;
+    }
+
+  private:
+    JValue_t value;
+    double   weight;
+  };
+
+
+  /**
+   * Template definition so that compiler error is generated if implementation is missing (see JEigen3D.hh).
+   */
+  template<>
+  class JAverage<JGEOMETRY3D::JQuaternion3D>;
+
+
+  /**
+   * Get average.
+   *
+   * \param  __begin        begin of data
+   * \param  __end          end   of data
+   * \return                average value
+   */
+  template<class T>
+  typename std::iterator_traits<T>::value_type getAverage(T __begin, T __end)
+  {
+    typedef typename std::iterator_traits<T>::value_type  value_type;
+
+    return JAverage<value_type>(__begin, __end);
+  }
+
+
+  /**
+   * Get average.
+   *
+   * \param  array          c-array of values
+   * \return                average value
+   */
+  template<class JValue_t, size_t N>
+  inline JValue_t getAverage(const JValue_t (&array)[N])
+  {
+    typedef JValue_t  value_type;
+    
+    return JAverage<value_type>((const value_type*) array, (const value_type*) array  +  N);
+  }
+
+
+  /**
+   * Get average.
+   *
+   * \param  buffer         input data
+   * \return                average value
+   */
+  template<class JElement_t, class JAllocator_t>
+  JElement_t getAverage(const array_type<JElement_t, JAllocator_t>& buffer)
+  {
+    return JAverage<JElement_t>(buffer.begin(), buffer.end());
+  }
+
+
+  /**
+   * Get average.
+   *
+   * \param  __begin        begin of data
+   * \param  __end          end   of data
+   * \param  value          default value
+   * \return                average value
+   */
+  template<class T>
+  typename std::iterator_traits<T>::value_type getAverage(T __begin, T __end, typename std::iterator_traits<T>::value_type value)
+  {
+    try {
+      return getAverage(__begin, __end);
+    }
+    catch(const std::exception&) {
+      return value;
+    }
+  }
+
+
+  /**
+   * Get average.
+   *
+   * \param  array          c-array of values
+   * \param  value          default value
+   * \return                average value
+   */
+  template<class JValue_t, size_t N>
+  inline JValue_t getAverage(const JValue_t (&array)[N], typename JLANG::JClass<JValue_t>::argument_type value)
+  {
+    try {
+      return getAverage(array);
+    }
+    catch(const std::exception&) {
+      return value;
+    }
+  }
+
+
+  /**
+   * Get average.
+   *
+   * \param  buffer         input data
+   * \param  value          default value
+   * \return                average value
+   */
+  template<class JElement_t, class JAllocator_t>
+  JElement_t getAverage(const array_type<JElement_t, JAllocator_t>& buffer, typename JLANG::JClass<JElement_t>::argument_type value)
+  {
+    try {
+      return getAverage(buffer);
+    }
+    catch(const std::exception&) {
+      return value;
+    }
+  }
+}
+
+#endif
diff --git a/jpp/JMath/JMathSupportkit.hh b/jpp/JMath/JMathSupportkit.hh
new file mode 100644
index 0000000..cfba6ad
--- /dev/null
+++ b/jpp/JMath/JMathSupportkit.hh
@@ -0,0 +1,231 @@
+#ifndef __JMATHSUPPORTKIT__
+#define __JMATHSUPPORTKIT__
+
+#include <limits>
+#include <cmath>
+
+#include "JMath/JConstants.hh"
+#include "JLang/JException.hh"
+
+
+/**
+ * \file
+ *
+ * Auxiliary methods for mathematics.
+ * \author mdejong
+ */
+
+namespace JMATH {}
+namespace JPP { using namespace JMATH; }
+
+namespace JMATH {
+
+  using JLANG::JValueOutOfRange;
+
+  
+  /**
+   * Gauss function (normalised to 1 at x = 0).
+   *
+   * \param  x                    x
+   * \param  sigma                sigma
+   * \return                      function value
+   */
+  inline 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;
+  }
+
+
+  /**
+   * Gauss function (normalised to 1 at x = x0).
+   *
+   * \param  x                    x
+   * \param  x0                   central value
+   * \param  sigma                sigma
+   * \return                      function value
+   */
+  inline double gauss(const double x, const double x0, const double sigma)
+  {
+    return gauss(x - x0, sigma);
+  }
+
+
+  /**
+   * Normalised Gauss function.
+   *
+   * \param  x                    x
+   * \param  sigma                sigma
+   * \return                      function value
+   */
+  inline double Gauss(const double x, const double sigma)
+  {
+    return gauss(x, sigma) / sqrt(2.0*PI) / sigma;
+  }
+
+
+  /**
+   * Normalised Gauss function.
+   *
+   * \param  x                    x
+   * \param  x0                   central value
+   * \param  sigma                sigma
+   * \return                      function value
+   */
+  inline double Gauss(const double x, const double x0, const double sigma)
+  {
+    return Gauss(x - x0, sigma);
+  }
+
+
+  /**
+   * Incomplete gamma function.
+   *
+   * \param  a                    a
+   * \param  x                    x
+   * \return                      function value
+   */
+  inline double Gamma(const double a, const double x)
+  {
+    using namespace std;
+
+    const int max = 100;
+
+    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 <= 0.0) { 
+	THROW(JValueOutOfRange, "x <= 0 " << x);
+      }
+
+      double ap  = a;
+      double sum = 1.0 /a;
+      double del = sum;
+
+      for (int i = 1; i != max; ++i) {
+
+	ap  += 1.0;
+	del *= x/ap;
+	sum += del;
+
+	if (fabs(del) < fabs(sum)*numeric_limits<double>::epsilon()) {
+	  return sum*exp(-x + a*log(x) - gln);
+	}
+      }
+
+    } else {
+
+      double b = x + 1.0 - a;
+      double c = numeric_limits<double>::epsilon() / numeric_limits<double>::min();
+      double d = 1.0 / b;
+      double h = d;
+
+      for (int i = 1; i != max; ++i) {
+
+	const double an = -i * (i-a);
+
+	b += 2.0;
+	d  = an*d + b;
+
+	if (fabs(d) < numeric_limits<double>::min()) {
+	  d = numeric_limits<double>::min();
+	}
+
+	c  = b + an/c;
+
+	if (fabs(c) < numeric_limits<double>::min()) {
+	  c = numeric_limits<double>::min();
+	}
+
+	d  = 1.0/d;
+
+	const double del = d*c;
+	
+	h *= del;
+	
+	if (fabs(del - 1.0) < numeric_limits<double>::epsilon()) {
+	  return 1.0 - exp(-x + a*log(x) - gln) * h;
+	}
+      }
+
+      THROW(JValueOutOfRange, "a " << a);
+    }
+
+    return 0.0;
+  }
+
+
+  /**
+   * Legendre polynome.
+   *
+   * \param  n                    degree 
+   * \param  x                    x
+   * \return                      function value
+   */
+  inline double legendre(const unsigned int n, const double x)
+  {
+    switch (n) {
+
+    case 0:
+      return 1.0;
+
+    case 1:
+      return x;
+
+    default:
+      {
+	double p0;
+	double p1 = 1.0;
+	double p2 = x;
+
+	for (unsigned int i = 2; i <= n; ++i) {
+	  p0 = p1;
+	  p1 = p2;
+	  p2 = ((2*i-1) * x*p1  -  (i-1) * p0) / i;
+	}
+
+	return p2;
+      }
+    }
+  }
+
+
+  /**
+   * Binomial function.
+   *
+   * \param  n                    n
+   * \param  k                    k
+   * \return                      function value
+   */
+  inline double binomial(const int n, const int k)
+  {
+    if (k == 0 || n == k) {
+      return 1.0;
+    }
+
+    if (n <= 0 || k < 0 || n < k) {
+      return 0.0;
+    }
+
+    const int k1 = std::min(k, n - k);
+    const int k2 = n - k1;
+
+    double value = k2 + 1;
+
+    for (int i = k1; i != 1; --i) {
+      value *= (double) (k2 + i) / (double) i;
+    }
+
+    return value;
+  }
+}
+
+#endif
diff --git a/jpp/JMath/JZero.hh b/jpp/JMath/JZero.hh
new file mode 100644
index 0000000..501348e
--- /dev/null
+++ b/jpp/JMath/JZero.hh
@@ -0,0 +1,108 @@
+#ifndef __JMATH__JZERO__
+#define __JMATH__JZERO__
+
+/**
+ * \file
+ *
+ * Definition of zero value for any class.
+ * \author mdejong
+ */
+namespace JMATH {}
+namespace JPP { using namespace JMATH; }
+
+namespace JMATH {
+
+  /**
+   * Get zero value for a given data type.
+   *
+   * The default implementation of this method returns an object which 
+   * is created with the default constructor.
+   * This method should be specialised if this value does not correspond
+   * to the equivalent of a zero result.
+   *
+   * \return                     zero
+   */
+  template<class T>
+  inline T getZero() 
+  {
+    return T();
+  }
+
+
+  /**
+   * Get zero value for <tt>bool</tt>.
+   *
+   * \return                     false
+   */
+  template<> inline bool getZero<bool>()
+  {
+    return false;
+  }
+
+
+  /**
+   * Get zero value for <tt>float</tt>.
+   *
+   * \return                     zero
+   */
+  template<> inline float getZero<float>()
+  { 
+    return float(0.0);
+  }
+
+
+  /**
+   * Get zero value for <tt>double</tt>.
+   *
+   * \return                     zero
+   */
+  template<>
+  inline double getZero<double>() 
+  {
+    return double(0.0);
+  }
+
+
+  /**
+   * Get zero value for <tt>long double</tt>.
+   *
+   * \return                     zero
+   */
+  template<>
+  inline long double getZero<long double>() 
+  {
+    return (long double)(0.0);
+  }
+
+
+  /**
+   * Auxiliary class to assign zero value.
+   */
+  struct JZero {
+    /** 
+     * Default constructor.
+     */
+    JZero()
+    {}
+
+
+    /**
+     * Type conversion operator.
+     *
+     * \return                     zero
+     */
+    template<class T>
+    operator T() const
+    {
+      return getZero<T>();
+    }
+  };
+
+
+  /**
+   * Function object to assign zero value.
+   */
+  static const JZero zero;
+}
+
+#endif
diff --git a/jpp/JPhysics/JConstants.hh b/jpp/JPhysics/JConstants.hh
new file mode 100644
index 0000000..1dbebf2
--- /dev/null
+++ b/jpp/JPhysics/JConstants.hh
@@ -0,0 +1,188 @@
+#ifndef __JPHYSICS__JCONSTANTS__
+#define __JPHYSICS__JCONSTANTS__
+
+#include <math.h>
+
+#include "JMath/JConstants.hh"
+
+
+/**
+ * \file
+ * Physics constants. 
+ * \author mdejong
+ */
+namespace JPHYSICS {}
+namespace JPP { using namespace JPHYSICS; }
+
+namespace JPHYSICS {
+
+  using JMATH::PI;
+  using JMATH::EULER;
+
+  /**
+   * Physics constants.
+   */
+  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 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]
+  static const double ALPHA_ELECTRO_MAGNETIC    = 1.0/137.036;          //!< Electro-Magnetic coupling constant
+  static const double THETA_MCS                 = 13.6e-3;              //!< Multiple Coulomb scattering constant [GeV]
+
+  /**
+   * Fixed environment values.
+   */
+  static const double DENSITY_SEA_WATER         = 1.038;                //!< Density  of sea water [g/cm^3]
+  static const double DENSITY_ROCK              = 2.65;                 //!< Density  of rock      [g/cm^3]
+  static const double SALINITY_SEA_WATER        = 0.035;                //!< Salinity of sea water
+  static const double INDEX_OF_REFRACTION_WATER = 1.3800851282;         //!< Average index of refraction of water corresponding to the group velocity 
+  static const double X0_WATER_M                = 0.36;                 //!< Radiation length pure water [m]
+
+  /**
+   * Derived quantities of optical medium.
+   */
+  static const double TAN_THETA_C_WATER         = sqrt((INDEX_OF_REFRACTION_WATER - 1.0) * (INDEX_OF_REFRACTION_WATER + 1.0)); //!< Average tangent corresponding to the group velocity 
+  static const double COS_THETA_C_WATER         = 1.0 / INDEX_OF_REFRACTION_WATER;                                             //!< Average cosine  corresponding to the group velocity 
+  static const double SIN_THETA_C_WATER         = TAN_THETA_C_WATER * COS_THETA_C_WATER;                                       //!< Average sine    corresponding to the group velocity 
+  static const double KAPPA_WATER               = 0.96;                                                                        //!< Average R-dependence of arrival time of Cherenkov light
+
+  /**
+   * Particle masses.
+   * Note that the neutrino masses are set to zero.
+   */
+  static const double MASS_PHOTON               = 0.0;                 //!< photon     mass [GeV]
+
+  static const double MASS_ELECTRON_NEUTRINO    = 0.0;                 //!< electron neutrino mass [GeV]
+  static const double MASS_MUON_NEUTRINO        = 0.0;                 //!< muon     neutrino mass [GeV]
+  static const double MASS_TAU_NEUTRINO         = 0.0;                 //!< tau      neutrino mass [GeV]
+  
+  static const double MASS_ELECTRON             = 0.510998946e-3;      //!< electron       mass [GeV]
+  static const double MASS_MUON                 = 0.1056583745;        //!< muon           mass [GeV]
+  static const double MASS_TAU                  = 1.77682;             //!< tau            mass [GeV]
+
+  static const double MASS_NEUTRAL_PION         = 0.1349766;           //!< pi_0           mass [GeV]
+  static const double MASS_CHARGED_PION         = 0.13957018;          //!< pi^+/-         mass [GeV]
+  static const double MASS_NEUTRAL_KAON         = 0.497614;            //!< K_0            mass [GeV]
+  static const double MASS_CHARGED_KAON         = 0.493677;            //!< K^+/-          mass [GeV]
+  static const double MASS_NEUTRAL_RHO          = 0.77526;             //!< rho_0          mass [GeV]
+  static const double MASS_CHARGED_RHO          = 0.77511;             //!< rho^+/-        mass [GeV]
+  static const double MASS_NEUTRAL_D            = 1.86483;             //!< D_0            mass [GeV]
+  static const double MASS_CHARGED_D            = 1.86965;             //!< D^+/-          mass [GeV]
+  static const double MASS_CHARGED_D_S          = 1.96834;             //!< D_s^+/-        mass [GeV]
+
+  static const double MASS_PROTON               = 0.9382720813;        //!< proton         mass [GeV]
+  static const double MASS_NEUTRON              = 0.9395654133;        //!< neutron        mass [GeV]
+  static const double MASS_DELTA_1232           = 1.232;               //!< Delta (1232)   mass [GeV]
+  static const double MASS_LAMBDA               = 1.115683;            //!< Lambda         mass [GeV]
+  static const double MASS_NEUTRAL_SIGMA        = 1.192642;            //!< Sigma_0        mass [GeV]
+  static const double MASS_CHARGED_SIGMA        = 1.18937;             //!< Sigma^+/-      mass [GeV]
+  static const double MASS_NEUTRAL_XI           = 1.31486;             //!< Xi_0           mass [GeV]
+  static const double MASS_CHARGED_XI           = 1.32171;             //!< Xi^+/-         mass [GeV]
+  static const double MASS_CHARGED_OMEGA        = 1.67245;             //!< Omega^+/-      mass [GeV]
+  static const double MASS_CHARGED_LAMBDA_C     = 2.28646;             //!< Lambda_c^+/-   mass [GeV]
+  static const double MASS_DOUBLYCHARGED_SIGMA_C = 2.45397;            //!< Sigma_c^++/--  mass [GeV]  
+  static const double MASS_CHARGED_SIGMA_C      = 2.4529;              //!< Sigma_c^+/-    mass [GeV]
+  static const double MASS_NEUTRAL_SIGMA_C      = 2.45375;             //!< Sigma_c_0      mass [GeV]
+  static const double MASS_CHARGED_XI_C         = 2.46793;             //!< Xi_c^+/-       mass [GeV]
+  static const double MASS_NEUTRAL_XI_C         = 2.47091;             //!< Xi_c_0         mass [GeV]
+  static const double MASS_NEUTRAL_OMEGA_C      = 2.6952;              //!< Omega_c_0      mass [GeV]
+  static const double MASS_NEUTRAL_B            = 5.27958;             //!< B_0            mass [GeV]
+  static const double MASS_CHARGED_B            = 5.27926;             //!< B^+/-          mass [GeV]
+  static const double MASS_NEUTRAL_B_S          = 5.36677;             //!< B_s^0          mass [GeV]
+  static const double MASS_NEUTRAL_LAMBDA_B     = 5.6194;              //!< Lambda_b^0     mass [GeV]
+  static const double MASS_NEUTRAL_XI_B         = 5.7878;              //!< Xi_b^0         mass [GeV]
+  static const double MASS_CHARGED_XI_B         = 5.7911;              //!< Xi_b^+/-       mass [GeV]
+  static const double MASS_CHARGED_OMEGA_B      = 6.071;               //!< Omega_b^+/-    mass [GeV]
+  static const double MASS_CHARGED_B_C          = 6.2756;              //!< B_c^+/-        mass [GeV]
+  
+  /** 
+   * Get speed of light.
+   * 
+   * return           speed of light [m/ns]
+   */
+  inline const double getSpeedOfLight()
+  {
+    return C;
+  }
+
+
+  /**
+   * Get inverse speed of light.
+   *
+   * return           inverse speed of light [ns/m]
+   */
+  inline const double getInverseSpeedOfLight()
+  { 
+    return C_INVERSE; 
+  }
+
+
+  /**
+   * Get average index of refraction of water corresponding to group velocity.
+   *
+   * \return          index of refraction
+   */
+  inline double getIndexOfRefraction() 
+  {
+    return INDEX_OF_REFRACTION_WATER;
+  }
+
+
+  /**
+   * Get average index of refraction of water corresponding to phase velocity.
+   *
+   * \return          index of refraction
+   */
+  inline double getIndexOfRefractionPhase() 
+  {
+    return 1.35;
+  }
+
+
+  /**
+   * Get average tangent of Cherenkov angle of water corresponding to group velocity.
+   *
+   * \return          tan(theta_C)
+   */
+  inline double getTanThetaC() 
+  {
+    return TAN_THETA_C_WATER;
+  }
+
+
+  /**
+   * Get average cosine of Cherenkov angle of water corresponding to group velocity.
+   *
+   * \return          cos(theta_C)
+   */
+  inline double getCosThetaC() 
+  {
+    return COS_THETA_C_WATER;
+  }
+
+
+  /**
+   * Get average sine of Cherenkov angle of water corresponding to group velocity.
+   *
+   * \return          sin(theta_C)
+   */
+  inline double getSinThetaC() 
+  {
+    return SIN_THETA_C_WATER;
+  }
+
+
+  /**
+   * Get average R-dependence of arrival time of Cherenkov light (a.k.a. kappa).
+   *
+   * \return          kappa
+   */
+  inline double getKappaC() 
+  {
+    return KAPPA_WATER;
+  }
+}
+
+#endif
diff --git a/jpp/JPhysics/JGeant_t.hh b/jpp/JPhysics/JGeant_t.hh
new file mode 100644
index 0000000..1f9db60
--- /dev/null
+++ b/jpp/JPhysics/JGeant_t.hh
@@ -0,0 +1,140 @@
+#ifndef __JPHYSICS__JGEANT_T__
+#define __JPHYSICS__JGEANT_T__
+
+#include "JTools/JFunction1D_t.hh"
+#include "JIO/JSerialisable.hh"
+
+/**
+ * \file
+ * Base class for photon emission profile EM-shower.
+ * \author mdejong
+ */
+
+namespace JPHYSICS {}
+namespace JPP { using namespace JPHYSICS; }
+
+namespace JPHYSICS {
+
+  using JIO::JReader;
+  using JIO::JWriter;
+
+  typedef JTOOLS::JGridPolint1Function1D_t  JGeantFunction1D_t;
+
+
+  /**
+   * Base class for the probability density function of photon emission from EM-shower 
+   * as a function of the index of refraction and the cosine of the emission angle.
+   *
+   * The implementation of this function is based on a linear interpolation of tabulated values.
+   * In this, a linear approximation of the dependence of the normalisation constant on 
+   * the index of refraction is assumed. This assumption is valid to within 10^-3.
+   */
+  class JGeant_t : 
+    public JGeantFunction1D_t
+  {
+  public:
+    /**
+     * Default constructor.
+     */
+    JGeant_t() 
+    {}
+ 
+
+    /**
+     * Number of photons from EM-shower as a function of emission angle.
+     * The integral over full solid angle is normalised to one.
+     *
+     * \param  n       index of refraction
+     * \param  ct      cosine angle of emmision
+     * \return         d^2P/dcos()dphi
+     */
+    double operator()(const double n,
+		      const double ct) const
+    {
+      const double y = JGeantFunction1D_t::operator()(ct - 1.0/n);
+
+      return y * (a0 - a1*n);
+    }
+
+
+    /**
+     * Integral number of photons from EM-shower between two emission angles.
+     * The integral over full solid angle is normalised to one.
+     *
+     * \param  n       index of refraction
+     * \param  xmin    minimal cosine angle of emmision
+     * \param  xmax    maximal cosine angle of emmision
+     * \return         dnpe/dphi 
+     */
+    double operator()(const double n, 
+		      const double xmin, 
+		      const double xmax) const
+    {
+      const double x_min = std::max(xmin - 1.0/n, buffer. begin()->getX());
+      const double x_max = std::min(xmax - 1.0/n, buffer.rbegin()->getX());
+
+      const double y = buffer(x_max) - buffer(x_min);
+
+      return y * (a0 - a1*n);
+    }
+
+
+    /**
+     * Read geant from input.
+     *
+     * \param  in       reader
+     * \param  geant    geant
+     * \return          reader
+     */
+    friend inline JReader& operator>>(JReader& in, JGeant_t& geant)
+    {
+      in >> geant.a0;
+      in >> geant.a1;
+      in >> static_cast<JGeantFunction1D_t&>(geant);
+
+      geant.compile();
+
+      return in;
+    }
+
+
+    /**
+     * Write geant to output.
+     *
+     * \param  out      writer
+     * \param  geant    geant
+     * \return          writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JGeant_t& geant)
+    {
+      out << geant.a0;
+      out << geant.a1;
+      out << static_cast<const JGeantFunction1D_t&>(geant);
+
+      return out;
+    }
+
+
+  protected:
+    /**
+     * Function compilation.
+     */
+    virtual void do_compile() override 
+    {
+      JGeantFunction1D_t::do_compile();
+
+      buffer.clear();
+
+      JTOOLS::integrate(*this, buffer);
+
+      buffer.compile();
+    }
+ 
+
+    double a0;     //!< offset of the normalisation dependence
+    double a1;     //!< slope  of the normalisation dependence
+    JGeantFunction1D_t buffer;
+  };
+}
+
+#endif
diff --git a/jpp/JPhysics/JGeanz.hh b/jpp/JPhysics/JGeanz.hh
new file mode 100644
index 0000000..8eb29d7
--- /dev/null
+++ b/jpp/JPhysics/JGeanz.hh
@@ -0,0 +1,194 @@
+#ifndef __JPHYSICS__JGEANZ__
+#define __JPHYSICS__JGEANZ__
+
+#include <cmath>
+
+#include "JMath/JMathSupportkit.hh"
+
+/**
+ * \file
+ * Longitudinal emission profile EM-shower.
+ * \author mdejong
+ */
+
+namespace JPHYSICS {}
+namespace JPP { using namespace JPHYSICS; }
+
+namespace JPHYSICS {
+
+  /**
+   * Function object for longitudinal profile of EM-shower.
+   *
+   *
+   *         \f[P(z)  \propto  z^{a-1} \times e^{-z/b}\f]
+   *
+   * where: \f[a = a_{0} + a_{1} \times \ln(E)\f]
+   *
+   * The parametrisation is taken from reference:
+   * C. Kopper, "Performance Studies for the KM3NeT Neutrino Telescope.",
+   * PhD thesis, University of Erlangen.
+   */
+  class JGeanz {
+  public:
+    /**
+     * constructor
+     * \param  __a0    power term (constant)
+     * \param  __a1    power term (E dependence)
+     * \param  __b     expontial slope
+     */ 
+    JGeanz(const double __a0,
+	   const double __a1,
+	   const double __b) :
+      a0(__a0),
+      a1(__a1),
+      b (__b),
+      Emin(exp(-a0/a1))
+    {}
+
+
+    /**
+     * Probability Density Function
+     *
+     * \param  E       EM-shower energy [GeV]
+     * \param  z       z position of light emission point relative to vertex location (z >= 0) [m]
+     * \return         dP/dz
+     */
+    double getProbability(const double E, 
+			  const double z) const
+    {
+      if (E > Emin) {
+
+	const double a = a0 + a1 * log(E);
+	const double y = pow(z,a-1.0) * exp(-z/b) / (pow(b,a) * std::tgamma(a));
+	
+	return y;
+      } 
+	  
+      if (z <= getMinimalShowerSize()) 
+	return 1.0 / getMinimalShowerSize();
+      else
+	return 0.0;
+    }
+    
+
+    /**
+     * Probability Density Function
+     *
+     * \param  E       EM-shower energy [GeV]
+     * \param  z       z position of light emission point relative to vertex location (z >= 0) [m]
+     * \return         dP/dz
+     */
+    double operator()(const double E, 
+		      const double z) const
+    {
+      return getProbability(E, z);
+    }
+   
+
+    /**
+     * Integral of PDF (starting from 0).
+     *
+     * \param  E       EM-shower energy [GeV]
+     * \param  z       z position [m] (>= 0)
+     * \return         dP
+     */
+    double getIntegral(const double E, 
+		       const double z) const
+    {
+      if (E > Emin) {
+
+	const double a = a0 + a1 * log(E);
+	const double x = z / b;
+	const double y = JMATH::Gamma(a,x);
+	
+	return y;
+      }
+      
+      if (z <= getMinimalShowerSize())
+	return z / getMinimalShowerSize();
+      else
+	return 1.0;
+    }
+    
+
+    /**
+     * Get shower length for a given integrated probability.
+     *
+     * \param  E       EM-shower energy [GeV]
+     * \param  P       integrated probability [0,1]
+     * \param  eps     relative precision
+     * \return         shower length [m]
+     */
+    double getLength(const double E, 
+		     const double P,
+		     const double eps = 1.0e-3) const
+    {
+      double zmin  =   0.0;     // [m]
+      double zmax  =  30.0;     // [m]
+
+      if (E > Emin) {
+
+	const double Q = P * (1.0 - eps);
+	
+	for (int i = 100; i != 0; --i) {
+	  
+	  const double z = 0.5 * (zmin + zmax);
+	  const double p = getIntegral(E, z);
+	  
+	  if (fabs(p-Q) < p*eps) {
+	    return z;
+	  }
+	  
+	  if (p > P)
+	    zmax = z;
+	  else
+	    zmin = z;
+	}
+	
+	return 0.5 * (zmin + zmax);
+
+      } else
+
+	return 0.0;
+    }
+
+    /**
+     * Get depth of shower maximum
+     *
+     * \param  E       EM-shower energy[GeV]
+     * \return         depth of maximum [m]
+     */
+    
+    double getMaximum(const double E) const
+    {
+      const double a = a0 + a1 * log(E); 
+
+      return (a-1)*b;
+    }
+
+
+    /**
+     * Get minimal shower size.
+     *
+     * \return         size [m]
+     */
+    static double getMinimalShowerSize()
+    {
+      return 1e-6;
+    }
+
+  protected:
+    const double a0;
+    const double a1;
+    const double b;
+    const double Emin;
+  };
+
+
+  /**
+   * Function object for longitudinal EM-shower profile
+   */
+  static const JGeanz geanz(1.85, 0.62, 0.54);
+}
+
+#endif
diff --git a/jpp/JPhysics/JNPETable.hh b/jpp/JPhysics/JNPETable.hh
new file mode 100644
index 0000000..59d57ae
--- /dev/null
+++ b/jpp/JPhysics/JNPETable.hh
@@ -0,0 +1,216 @@
+#ifndef __JPHYSICS__JNPETABLE__
+#define __JPHYSICS__JNPETABLE__
+
+#include "JLang/JSharedPointer.hh"
+#include "JLang/JException.hh"
+
+#include "JTools/JConstantFunction1D.hh"
+#include "JTools/JMultiFunction.hh"
+#include "JTools/JTransformableMultiFunction.hh"
+#include "JTools/JToolsToolkit.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JPHYSICS {}
+namespace JPP { using namespace JPHYSICS; }
+
+namespace JPHYSICS {
+
+  using JTOOLS::JConstantFunction1D;
+  using JTOOLS::JMapList;
+  using JTOOLS::JMultiFunction;
+  using JTOOLS::JMultiMapTransformer;
+  using JTOOLS::JTransformableMultiFunction;
+
+
+  /**
+   * Custom class for integrated values of the PDF of the arrival time of Cherenkov light.
+   *
+   * This class provides for the number of photo-electrons as a function
+   * of the leading <tt>(n - 1)</tt> parameter values. 
+   */
+  template<class JArgument_t, 
+	   class JResult_t,
+	   class JMaplist_t,
+	   class JDistance_t = JTOOLS::JDistance<JArgument_t> >
+  class JNPETable :
+    public JMultiFunction<JConstantFunction1D<JArgument_t, JResult_t>,
+			  JMaplist_t, 
+			  JDistance_t>
+  {
+  public:
+
+    typedef JMultiFunction<JConstantFunction1D<JArgument_t, JResult_t>,
+			   JMaplist_t, 
+			   JDistance_t>                                   multifunction_t;
+
+    using multifunction_t::NUMBER_OF_DIMENSIONS;
+
+    typedef JConstantFunction1D<JArgument_t, JResult_t>                   function_type;
+    typedef typename multifunction_t::map_type                            map_type;
+
+    typedef typename multifunction_t::value_type                          value_type;
+    typedef typename multifunction_t::argument_type                       argument_type;
+    typedef typename multifunction_t::supervisor_type                     supervisor_type;
+
+    typedef typename multifunction_t::abscissa_type                       abscissa_type;
+    typedef typename multifunction_t::ordinate_type                       ordinate_type;
+    typedef typename multifunction_t::result_type                         result_type;
+
+    typedef typename multifunction_t::const_iterator                      const_iterator;
+    typedef typename multifunction_t::const_reverse_iterator              const_reverse_iterator;
+    typedef typename multifunction_t::iterator                            iterator;
+    typedef typename multifunction_t::reverse_iterator                    reverse_iterator;
+
+    typedef typename multifunction_t::super_iterator                      super_iterator;
+    typedef typename multifunction_t::super_const_iterator                super_const_iterator;
+
+    typedef JMultiMapTransformer<NUMBER_OF_DIMENSIONS, argument_type>     transformer_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JNPETable() :
+      transformer(transformer_type::getClone())
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  input               multi-dimensional PDF
+     */
+    template<class JPDF_t, class JPDFMaplist_t, class JPDFDistance_t>
+    JNPETable(const JTransformableMultiFunction<JPDF_t, JPDFMaplist_t, JPDFDistance_t>& input) :
+      transformer(transformer_type::getClone())
+    {
+      using namespace JTOOLS;
+
+      typedef JTransformableMultiFunction<JPDF_t, JPDFMaplist_t, JPDFDistance_t>                       JTransformableMultiFunction_t;
+      typedef JMultiKey<JTransformableMultiFunction_t::NUMBER_OF_DIMENSIONS - 1, argument_type>        JMultiKey_t;
+      typedef typename JTransformableMultiFunction_t::transformer_type                                 transformer_type;
+
+
+      this->transformer.reset(input.transformer->clone());
+
+      for (typename JTransformableMultiFunction_t::super_const_iterator i = input.super_begin(); i != input.super_end(); ++i) {
+
+	const JMultiKey_t& key   = (*i).getKey();
+	const JPDF_t&      value = (*i).getValue();
+
+        const typename transformer_type::array_type array(key);
+
+        const double        V = getIntegral(value);
+        const argument_type z = input.transformer->getXn(array, 1.0) - input.transformer->getXn(array, 0.0);
+
+        this->insert(key, function_type(z*V));
+      }
+
+      this->compile();
+    }
+
+
+    /**
+     * Add NPE table.
+     *
+     * Note that the summation is made via iteration of the elements in this multidimensional table.
+     *
+     * \param  input               NPE table
+     */
+    void add(const JNPETable& input)
+    {
+      using namespace JTOOLS;
+
+      for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) {
+
+        map_type& f1 = (*i).getValue();
+
+	for (typename map_type::iterator j = f1.begin(); j != f1.end(); ++j) {
+
+	  try {
+
+	    const JArray<NUMBER_OF_DIMENSIONS, argument_type> buffer((*i).getKey(), j->getX());
+
+	    const double npe = get_value(input.evaluate(buffer.data()));
+	    const double W   = this->transformer->getWeight(buffer);
+	  
+	    j->getY() += npe/W;
+	  }
+	  catch(JLANG::JException& error) {}
+	}
+      }
+    }
+
+
+    /**
+     * Get number of photo-electrons.
+     *
+     * \param  args               comma separated argument list
+     * \return                    number of photo-electrons
+     */
+    template<class ...Args>
+    result_type operator()(const Args& ...args) const
+    {
+      this->buffer.set(args...);
+
+      return this->evaluate(this->buffer.data());
+    }
+
+
+    /**
+     * Recursive function value evaluation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const override 
+    {
+      for (int i = 0; i != NUMBER_OF_DIMENSIONS; ++i) {
+        this->buffer[i] = pX[i];
+      }
+
+      const double      W   = transformer->getWeight(buffer);
+      const result_type npe = multifunction_t::evaluate(buffer.data());
+
+      return W * npe;
+    }
+
+
+    /**
+     * Application of weight function.
+     *
+     * \param  transformer     function transformer
+     */
+    void transform(const transformer_type& transformer)
+    {
+      using namespace JTOOLS;
+
+      for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) {
+
+        map_type& f1 = (*i).getValue();
+
+	for (typename map_type::iterator j = f1.begin(); j != f1.end(); ++j) {
+
+	  const JArray<NUMBER_OF_DIMENSIONS, argument_type> array((*i).getKey(), j->getX());
+
+	  j->getY() *= this->transformer->getWeight(array) / transformer.getWeight(array);
+	}
+      }
+
+      this->transformer.reset(transformer.clone());
+      this->compile();
+    }
+
+
+    JLANG::JSharedPointer<transformer_type> transformer;
+
+  protected:
+    mutable JTOOLS::JArray<NUMBER_OF_DIMENSIONS, argument_type> buffer;
+  };
+}
+
+#endif
diff --git a/jpp/JPhysics/JNPE_t.hh b/jpp/JPhysics/JNPE_t.hh
new file mode 100644
index 0000000..6a3c9b8
--- /dev/null
+++ b/jpp/JPhysics/JNPE_t.hh
@@ -0,0 +1,288 @@
+
+#include "JLang/JException.hh"
+#include "JTools/JCollection.hh"
+#include "JTools/JMap.hh"
+#include "JTools/JGridMap.hh"
+#include "JTools/JMapList.hh"
+#include "JTools/JSpline.hh"
+#include "JTools/JPolint.hh"
+#include "JTools/JElement.hh"
+#include "JPhysics/JNPETable.hh"
+#include "JPhysics/JPDFTable.hh"
+#include "JPhysics/JPDFToolkit.hh"
+#include "JPhysics/JPDFTypes.hh"
+#include "JPhysics/JGeanz.hh"
+#include "JMath/JZero.hh"
+
+
+/**
+ * \file
+ *
+ * Auxiliary data structure for muon PDF.
+ * \author mdejong
+ */
+struct JMuonNPE_t {
+
+  typedef JPP::JMAPLIST<JPP::JPolint1FunctionalMap,
+			JPP::JPolint1FunctionalGridMap,
+			JPP::JPolint1FunctionalGridMap>::maplist   JNPEMaplist_t;
+  typedef JPP::JNPETable<double, double, JNPEMaplist_t>            JNPE_t;
+
+
+  /**
+   * Constructor.
+   *
+   * The PDF file descriptor should contain the wild card character JPHYSICS::WILD_CARD.\n
+   *
+   * \param  fileDescriptor     PDF file descriptor
+   */
+  JMuonNPE_t(const std::string& fileDescriptor)
+  {
+    using namespace std;
+    using namespace JPP;
+
+    const JPDFType_t pdf_t[] = { DIRECT_LIGHT_FROM_MUON,
+				 SCATTERED_LIGHT_FROM_MUON,
+				 DIRECT_LIGHT_FROM_EMSHOWERS,
+				 SCATTERED_LIGHT_FROM_EMSHOWERS };
+
+    const  int N = sizeof(pdf_t) / sizeof(pdf_t[0]);
+    
+    typedef JPP::JSplineFunction1D<JSplineElement2D<double, double>,
+                                   JCollection,
+                                   double>                          JFunction1D_t;
+    typedef JPDFTable<JFunction1D_t, JNPEMaplist_t>                 JPDF_t;
+
+
+    const JNPE_t::JSupervisor supervisor(new JNPE_t::JDefaultResult(zero));
+
+    for (int i = 0; i != N; ++i) {
+
+      JPDF_t pdf;
+
+      const string file_name = getFilename(fileDescriptor, pdf_t[i]);
+
+      cout << "loading PDF from file " << file_name << "... " << flush;
+
+      pdf.load(file_name.c_str());
+
+      cout << "OK" << endl;
+
+      pdf.setExceptionHandler(supervisor);
+
+      if (!is_bremsstrahlung(pdf_t[i]))
+	Y1.push_back(JNPE_t(pdf));
+      else
+	YB.push_back(JNPE_t(pdf));
+    }
+
+    // Add PDFs
+
+    cout << "adding PDFs... " << flush;
+
+    Y1[1].add(Y1[0]); Y1.erase(Y1.begin());
+    YB[1].add(YB[0]); YB.erase(YB.begin());
+
+    cout << "OK" << endl;
+  }
+
+
+  /**
+   * Get PDF.
+   *
+   * 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                  muon energy at minimum distance of approach [GeV]
+   * \param  R                  minimum distance of approach [m]
+   * \param  theta              PMT zenith  angle [rad]
+   * \param  phi                PMT azimuth angle [rad]
+   * \return                    number of photo-electrons
+   */
+  double calculate(const double E,
+		   const double R,
+		   const double theta,
+		   const double phi) const
+  {
+    using namespace JPP;
+
+    const double yA = getNPE(Y1, R, theta, phi);
+    const double yB = getNPE(YB, R, theta, phi);
+
+    if (E >= MASS_MUON * INDEX_OF_REFRACTION_WATER)
+      return yA + E * yB;
+    else
+      return 0.0;
+  }
+
+private:
+  std::vector<JNPE_t> Y1;     //!< light from muon
+  std::vector<JNPE_t> YB;     //!< light from EM showers
+
+  /**
+   * Get number of photo-electrons.
+   *
+   * \param  NPE                NPE tables
+   * \param  R                  distance between muon and PMT [m]
+   * \param  theta              zenith  angle orientation PMT [rad]
+   * \param  phi                azimuth angle orientation PMT [rad]
+   * \return                    number of photo-electrons
+   */
+  static inline double getNPE(const std::vector<JNPE_t>& NPE,
+			      const double R,
+			      const double theta,
+			      const double phi)
+  {
+    using namespace std;
+    using namespace JPP;
+
+    double npe = 0.0;
+
+    for (vector<JNPE_t>::const_iterator i = NPE.begin(); i != NPE.end(); ++i) {
+
+      if (R <= i->getXmax()) {
+
+	try {
+
+	  const double y = get_value((*i)(std::max(R, i->getXmin()), theta, phi));
+
+	  if (y > 0.0) {
+	    npe += y;
+	  }
+	}
+	catch(const exception& error) {
+	  cerr << error.what() << endl;
+	}
+      }
+    }
+
+    return npe;
+  }
+};
+
+
+/**
+ * Auxiliary data structure for shower PDF.
+ */
+struct JShowerNPE_t {
+
+  typedef JPP::JMAPLIST<JPP::JPolint1FunctionalMap,
+			JPP::JPolint1FunctionalMap,
+			JPP::JPolint1FunctionalGridMap,
+			JPP::JPolint1FunctionalGridMap>::maplist   JNPEMaplist_t;
+  typedef JPP::JNPETable<double, double, JNPEMaplist_t>            JNPE_t;
+
+
+  /**
+   * Constructor.
+   *
+   * The PDF file descriptor should contain the wild card character JPHYSICS::WILD_CARD.\n
+   *
+   * \param  fileDescriptor     PDF file descriptor
+   * \param  numberOfPoints     number of points for shower elongation
+   */
+  JShowerNPE_t(const std::string& fileDescriptor,
+	       const int          numberOfPoints = 0) :
+    numberOfPoints(numberOfPoints)
+  {
+    using namespace std;
+    using namespace JPP;
+    
+    const JPDFType_t pdf_t[] = { SCATTERED_LIGHT_FROM_EMSHOWER,
+				 DIRECT_LIGHT_FROM_EMSHOWER };
+
+    const  int N = sizeof(pdf_t) / sizeof(pdf_t[0]);
+
+    typedef JPP::JSplineFunction1D<JSplineElement2D<double, double>,
+                                   JCollection,
+                                   double>                          JFunction1D_t;
+    typedef JPDFTable<JFunction1D_t, JNPEMaplist_t>                 JPDF_t;
+
+
+    const JNPE_t::JSupervisor supervisor(new JNPE_t::JDefaultResult(zero));
+
+    for (int i = 0; i != N; ++i) {
+
+      const string file_name = getFilename(fileDescriptor, pdf_t[i]);
+
+      cout << "loading input from file " << file_name << "... " << flush;
+
+      JPDF_t pdf;
+
+      pdf.load(file_name.c_str());
+
+      pdf.setExceptionHandler(supervisor);
+
+      if (npe.empty())
+	npe = JNPE_t(pdf);
+      else
+	npe.add(JNPE_t(pdf));
+
+      F[i] = JNPE_t(pdf);
+
+      cout << "OK" << endl;
+    }
+  }
+
+
+  /**
+   * Get PDF.
+   *
+   * 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  D                  distance [m]
+   * \param  cd                 cosine emission angle
+   * \param  theta              PMT zenith  angle [rad]
+   * \param  phi                PMT azimuth angle [rad]
+   * \return                    hypothesis value
+   */
+  double calculate(const double E,
+		   const double D,
+		   const double cd,
+		   const double theta,
+		   const double phi) const
+  {
+    using namespace std;
+    using namespace JPP;
+
+    double Y = 0.0;
+  
+    if (numberOfPoints > 0) {
+
+      const double W = 1.0 / (double) numberOfPoints;
+
+      for (int i = 0; i != numberOfPoints; ++i) {
+
+	const double z = geanz.getLength(E, (i + 0.5) / (double) numberOfPoints);
+
+	const double __D  = sqrt(D*D - 2.0*(D*cd)*z + z*z);
+	const double __cd = (D * cd - z) / __D;
+
+	try {
+	  Y += W * npe (__D, __cd, theta, phi);
+	}
+	catch(const exception& error) {
+	  //cerr << error.what() << endl;
+	}
+      }
+
+    } else {
+
+      try {
+	Y = npe(D, cd, theta, phi);
+      }
+      catch(const exception& error) {
+	//cerr << error.what() << endl;
+      }
+    }
+
+    return E * Y;
+  }
+
+private:
+  int            numberOfPoints;
+  JNPE_t npe;    //!< PDF for shower
+  JNPE_t F[2];   //!< PDF for shower
+};
diff --git a/jpp/JPhysics/JPDFTable.hh b/jpp/JPhysics/JPDFTable.hh
new file mode 100644
index 0000000..73670e2
--- /dev/null
+++ b/jpp/JPhysics/JPDFTable.hh
@@ -0,0 +1,308 @@
+#ifndef __JPHYSICS__JPDFTABLE__
+#define __JPHYSICS__JPDFTABLE__
+
+#include <cmath>
+
+#include "JIO/JObjectBinaryIO.hh"
+#include "JTools/JTransformableMultiFunction.hh"
+#include "JTools/JQuantiles.hh"
+#include "JTools/JSet.hh"
+#include "JTools/JRange.hh"
+#include "JPhysics/JConstants.hh"
+#include "JPhysics/JPDFTransformer.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JPHYSICS {}
+namespace JPP { using namespace JPHYSICS; }
+
+namespace JPHYSICS {
+
+  using JIO::JSerialisable;
+  using JIO::JReader;
+  using JIO::JWriter;
+  using JIO::JObjectBinaryIO;
+  using JTOOLS::JTransformableMultiFunction;
+  using JTOOLS::JTransformableMultiHistogram;
+  using JTOOLS::JRange;
+  
+
+  /**
+   * Multi-dimensional PDF table for arrival time of Cherenkov light.
+   */
+  template<class JFunction1D_t,
+	   class JMaplist_t,
+           class JDistance_t = JTOOLS::JDistance<typename JFunction1D_t::argument_type> >
+  class JPDFTable :
+    public JTransformableMultiFunction<JFunction1D_t, JMaplist_t, JDistance_t>,
+    public JSerialisable,
+    public JObjectBinaryIO< JPDFTable<JFunction1D_t, JMaplist_t, JDistance_t> >
+  {
+  public:
+
+    typedef JTransformableMultiFunction<JFunction1D_t, JMaplist_t, JDistance_t>      transformablemultifunction_type;
+
+    typedef typename transformablemultifunction_type::argument_type                  argument_type;
+    typedef typename transformablemultifunction_type::result_type                    result_type;
+    typedef typename transformablemultifunction_type::value_type                     value_type;
+
+    typedef typename transformablemultifunction_type::multimap_type                  multimap_type;
+    typedef typename transformablemultifunction_type::transformer_type               transformer_type;
+
+    enum { NUMBER_OF_DIMENSIONS = transformablemultifunction_type::NUMBER_OF_DIMENSIONS };
+
+    typedef typename transformablemultifunction_type::super_const_iterator           super_const_iterator;
+    typedef typename transformablemultifunction_type::super_iterator                 super_iterator;
+    typedef typename transformablemultifunction_type::function_type                  function_type;
+
+    using transformablemultifunction_type::insert;
+
+
+    /**
+     * Default constructor.
+     */
+    JPDFTable() :
+      transformablemultifunction_type()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \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) :
+      transformablemultifunction_type(input)
+    {}
+
+    
+    /**
+     * Constructor.
+     *
+     * \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) :
+      transformablemultifunction_type(input)
+    {}
+
+
+    /**
+     * Blur PDF.
+     *
+     * The arrival times of Cherenkov light are smeared according to a Gaussian distribution
+     * with the specified width (i.e.\ TTS) using Gauss-Hermite integration.
+     * An exception is made when the time range according the specified quantile is 
+     * smaller than the specified width (TTS) of the Gaussian distribution.
+     * In that case, the resulting PDF is a Gaussian distribution with the specified width (TTS)
+     * and normalisation according to the integral value of the input PDF.
+     * A smooth transition is imposed between the normal regime and this exeption.
+     *
+     * \param  TTS                  TTS [ns]
+     * \param  numberOfPoints       number of points for Gauss-Hermite integration
+     * \param  epsilon              precision
+     * \param  quantile             quantile
+     */
+    void blur(const double TTS, 
+	      const int    numberOfPoints = 25,
+	      const double epsilon        = 1.0e-10,
+	      const double quantile       = 0.99)
+    {
+      using namespace std;
+      using namespace JTOOLS;
+
+      typedef typename transformer_type::array_type  array_type;
+
+      const JGaussHermite engine(numberOfPoints, epsilon);
+
+      for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) {
+	
+	const array_type array = (*i).getKey();
+	function_type&   f1    = (*i).getValue();
+
+	if (!f1.empty()) {
+
+	  const typename function_type::supervisor_type& supervisor = f1.getSupervisor();
+
+	  const JMultiMapGetTransformer<NUMBER_OF_DIMENSIONS - 1, value_type> get(*(this->transformer), array);
+	  const JMultiMapPutTransformer<NUMBER_OF_DIMENSIONS - 1, value_type> put(*(this->transformer), array);
+
+	  f1.transform(get);
+	  f1.compile();
+
+	  const JQuantiles Q(f1, quantile);
+
+	  // abscissa 
+
+	  JSet<double> X;
+
+	  for (JGaussHermite::const_iterator j = engine.begin(); j != engine.end(); ++j) {
+	    X.insert(Q.getX() + TTS*sqrt(2.0)*j->getX());
+	  }
+
+	  for (typename function_type::const_iterator j = f1.begin(); j != f1.end(); ++j) {
+
+	    if (j->getX() - TTS < X.getXmin()) {
+	      X.insert(j->getX() - TTS);
+	    }
+	    
+	    if (j->getX() + TTS > X.getXmax()) {
+	      X.insert(j->getX() + TTS);
+	    }
+	  }
+
+
+	  const double W = gauss(Q.getUpperLimit() - Q.getLowerLimit(), TTS);
+
+	  function_type buffer;
+
+	  for (JSet<double>::const_iterator x = X.begin(); x != X.end(); ++x) {
+
+	    double y = 0.0;
+
+	    for (JGaussHermite::const_iterator j = engine.begin(); j != engine.end(); ++j) {
+
+	      const double u = j->getX();
+	      const double v = j->getY() / sqrt(PI);
+	      const double w = get_value(f1(*x + u*TTS*sqrt(2.0)));
+	
+	      y += v * w;
+	    }
+
+	    buffer[*x]  =  W * Q.getIntegral() * Gauss(*x - Q.getX(), TTS)  +  (1.0 - W) * y;
+	  }
+
+	  buffer.transform(put);
+	  buffer.compile();
+
+	  f1 = buffer;
+
+	  f1.setExceptionHandler(supervisor);
+	}
+      }
+    }
+
+
+    /**
+     * Compresses PDF to given abscissa range.
+     *
+     * \param   range               abscissa range
+     */
+    void compress(const JRange<typename function_type::abscissa_type>& range)
+    {        
+      for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) {
+
+	function_type& f1 = i.getValue();
+	
+	typename function_type::iterator p = f1.lower_bound(range.getLowerLimit());
+
+	f1.function_type::container_type::erase(f1.begin(), p);
+
+	typename function_type::iterator q = f1.lower_bound(range.getUpperLimit());
+
+	f1.function_type::container_type::erase(++q, f1.end());
+      }
+
+      this->compile();
+    }
+
+
+    /**
+     * Read from input.
+     *
+     * \param  in                   reader
+     * \return                      reader
+     */
+    virtual JReader& read(JReader& in) override 
+    {
+      if (in >> static_cast<transformablemultifunction_type&>(*this)) {
+
+	// read optional transformer
+
+	JPDFTransformer<NUMBER_OF_DIMENSIONS - 1, argument_type> buffer;
+
+	if (buffer.read(in)) {
+
+	  this->transformer.reset(buffer.clone());
+
+	} else {
+
+	  in.clear();
+	  
+	  this->transformer.reset(transformer_type::getClone());
+	}
+      }
+      
+      this->compile();
+      
+      return in;
+    }
+    
+    
+    /**
+     * Write from input.
+     *
+     * \param  out                  writer
+     * \return                      writer
+     */
+    virtual JWriter& write(JWriter& out) const override 
+    {
+      out << static_cast<const transformablemultifunction_type&>(*this);
+
+      this->transformer->write(out);
+
+      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);
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JPhysics/JPDFToolkit.hh b/jpp/JPhysics/JPDFToolkit.hh
new file mode 100644
index 0000000..23a3586
--- /dev/null
+++ b/jpp/JPhysics/JPDFToolkit.hh
@@ -0,0 +1,322 @@
+#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
+ * Auxiliary methods for PDF calculations.
+ * \author mdejong
+ */
+
+namespace JPHYSICS {}
+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.
+   *
+   * \return            wavelength of light [nm]
+   */
+  inline double getMinimalWavelength()
+  {
+    return 300.0;
+  }
+
+
+  /**
+   * Get maximal wavelength for PDF evaluations.
+   *
+   * \return            wavelength of light [nm]
+   */
+  inline double getMaximalWavelength()
+  {
+    return 700.0;
+  }
+  
+
+  /**
+   * Number of Cherenkov photons per unit track length and per unit wavelength.
+   *
+   * \param  lambda     wavelength of light [nm]
+   * \param  n          index of refraction
+   * \return            number of photons per unit track length and per unit wavelength [m^-1 nm^-1]
+   */
+  inline double cherenkov(const double lambda,
+			  const double n)
+  {
+    const double x = n*lambda;
+    
+    return 1.0e9 * 2 * PI * ALPHA_ELECTRO_MAGNETIC * (n*n - 1.0) / (x*x);
+  }
+
+  
+  /**
+   * Equivalent EM-shower energy due to delta-rays per unit muon track length.
+   *
+   * Internal parameters are obtained with application [script] JDeltaRays[.sh].
+   * 
+   * \param  E      muon energy [GeV]
+   * \return        equivalent energy loss [GeV/m]
+   */  
+  inline double getDeltaRaysFromMuon(const double E)
+  {
+    static const double a =  3.186e-01;
+    static const double b =  3.384e-01;
+    static const double c = -2.759e-02;
+    static const double d =  1.630e-03;
+    static const double Emin = 0.13078; // [GeV]
+
+    if (E > Emin) {
+
+      const double x = log10(E);                      //
+      const double y = a + x*(b + x*(c + x*(d)));     // [MeV g^-1 cm^2]
+
+      return y * DENSITY_SEA_WATER * 1.0e-1;          // [GeV/m]
+    }
+
+    return 0.0;
+  }
+
+  
+  /**
+   * Equivalent EM-shower energy due to delta-rays per unit tau track length.
+   *
+   * Internal parameters are obtained with application [script] JDeltaRays[.sh].
+   * 
+   * \param  E      tau energy [GeV]
+   * \return        equivalent energy loss [GeV/m]
+   */  
+  inline double getDeltaRaysFromTau(const double E)
+  {
+    static const double a = -2.374e-01;
+    static const double b =  5.143e-01;
+    static const double c = -4.213e-02;
+    static const double d =  1.804e-03;
+    static const double Emin = 2.19500; // [GeV]
+    
+    if (E > Emin) {
+
+      const double x = log10(E);                      //
+      const double y = a + x*(b + x*(c + x*(d)));     // [MeV g^-1 cm^2]
+
+      return y * DENSITY_SEA_WATER * 1.0e-1;          // [GeV/m]
+    }
+
+    return 0.0;
+  }
+
+
+  /**
+   * Rayleigh cross section.
+   *
+   * \param  n          index of refraction
+   * \param  lambda     wavelength of light [nm]
+   * \return            cross section       [cm^2]
+   */
+  inline const double getRayleighCrossSection(const double n,
+					      const double lambda)
+  {
+    static const double d = 0.36;                    // size of H2O molecule [nm]
+    static const double U = PI*PI*PI*PI*PI*2.0/3.0;
+    static const double V = d*d*d*d*d*d;
+
+    const double W     = (n*n - 1.0) / (n*n + 2.0);
+    const double sigma = 1.0e-14 * U*V*W*W / (lambda*lambda*lambda*lambda);   // [cm^2]
+
+    return sigma;
+  }
+
+
+  /**
+   * Rayleigh scattering length.
+   *
+   * \param  n          index of refraction
+   * \param  lambda     wavelength of light [nm]
+   * \return            scattering length   [m]
+   */
+  inline const double getRayleighScatteringLength(const double n,
+						  const double lambda)
+  {
+    static const double amu = 18.01528; // H20 mass in Atomic mass units
+
+    const double sigma = getRayleighCrossSection(n, lambda);
+    const double ls    = 1.0e-2 / (DENSITY_SEA_WATER * AVOGADRO * sigma / amu);     // [m]
+
+    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/jpp/JPhysics/JPDFTransformer.hh b/jpp/JPhysics/JPDFTransformer.hh
new file mode 100644
index 0000000..59422f3
--- /dev/null
+++ b/jpp/JPhysics/JPDFTransformer.hh
@@ -0,0 +1,1289 @@
+#ifndef __JPHYSICS__JPDFTRANSFORMER__
+#define __JPHYSICS__JPDFTRANSFORMER__
+
+#include <cmath>
+
+#include "JLang/JCC.hh"
+#include "JIO/JSerialisable.hh"
+#include "JPhysics/JConstants.hh"
+#include "JTools/JMultiMapTransformer.hh"
+#include "JTools/JFunction1D_t.hh"
+#include "JTools/JGrid.hh"
+#include "JPhysics/JGeant_t.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JPHYSICS {}
+namespace JPP { using namespace JPHYSICS; }
+
+namespace JPHYSICS {
+
+  using JIO::JReader;
+  using JIO::JWriter;
+  using JTOOLS::JMultiMapTransformer;
+
+
+  /**
+   * Transformer for the 1D probability density function (PDF) of the time response of a PMT to a muon.
+   *
+   * PDFs are evaluated by interpolation for:
+   *   -# distance of closest approach of the muon to the PMT [m]
+   *   -# arrival time [ns]
+   *
+   * The evaluation of the weights is based on:
+   *   -# effective attenuation length
+   */
+  template<class JArgument_t>
+  class JPDFTransformer_t :
+    public JMultiMapTransformer<1, JArgument_t>
+  {
+  public:
+
+    typedef JMultiMapTransformer<1, JArgument_t>                     JMultiMapTransformer_t;
+
+    typedef typename JMultiMapTransformer_t::clone_type              clone_type;
+    typedef typename JMultiMapTransformer_t::argument_type           argument_type;
+    typedef typename JMultiMapTransformer_t::const_array_type        const_array_type;
+
+    using JMultiMapTransformer_t::getWeight;
+
+    /**
+     * Get shortest distance of approach.
+     *
+     * \return              distance [m]
+     */
+    static double getRmin()
+    {
+      return 0.01;
+    }
+
+
+    /**
+     * Default constructor.
+     */
+    JPDFTransformer_t() :
+      ln   (0.0),
+      alpha(0),
+      kmin (0.0),
+      kmax (0.0)
+    {}
+
+
+    /**
+     * Constructor.
+     *  
+     * \param  ln           Effective attenuation length [m]
+     * \param  alpha        Distance dependence (power term)
+     * \param  kmin         Minimal kappa
+     * \param  kmax         Maximal kappa
+     */
+    JPDFTransformer_t(const double ln,
+		      const int    alpha,
+		      const double kmin,
+		      const double kmax) :
+      ln   (ln),
+      alpha(alpha),
+      kmin (kmin),
+      kmax (kmax)
+    {}
+
+
+    /**
+     * Clone object.
+     * 
+     * \return            pointer to newly created transformer
+     */
+    virtual clone_type clone() const override 
+    {
+      return new JPDFTransformer_t(*this);
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {R_m}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type putXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      using namespace JTOOLS;
+
+      const double R = buffer[0];
+
+      double x = xn;
+
+      const double t0 =  R * getTanThetaC() * getInverseSpeedOfLight();
+      const double t1 =  R * kmin * getInverseSpeedOfLight();
+
+      x -= t1 - t0;
+      
+      if (kmax > kmin) {
+	x /= R * (kmax - kmin) * getInverseSpeedOfLight();
+      }
+
+      return x;
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {R_m}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type getXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      using namespace JTOOLS;
+
+      const double R = buffer[0];
+
+      double x = xn;
+
+      if (kmax > kmin) {
+	x *= R * (kmax - kmin) * getInverseSpeedOfLight();
+      }
+
+      const double t0 =  R * getTanThetaC() * getInverseSpeedOfLight();
+      const double t1 =  R * kmin * getInverseSpeedOfLight();
+      
+      x += t1 - t0;
+
+      return x;
+    }
+
+
+    /**
+     * Weight function.
+     *
+     * \param  buffer     {R_m}
+     * \return            weight
+     */
+    virtual double getWeight(const_array_type& buffer) const override 
+    {
+      using namespace JTOOLS;
+
+      const double R = buffer[0];
+
+      const double n   = getIndexOfRefraction();
+      const double ct0 = 1.0 / n;
+      const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
+    
+      const double d  = sqrt(getRmin()*getRmin() + R*R) / st0;
+    
+      return exp(-d/ln) / pow(d,alpha);
+    }
+
+
+    /**
+     * Read PDF transformer from input.
+     *
+     * \param  in         reader
+     * \return            reader
+     */
+    virtual JReader& read(JReader& in) override 
+    {
+      in >> ln;
+      in >> alpha;
+      in >> kmin;
+      in >> kmax;
+
+      return in;
+    }
+
+
+    /**
+     * Write PDF transformer to output.
+     *
+     * \param  out        writer
+     * \return            writer
+     */
+    virtual JWriter& write(JWriter& out) const override 
+    {
+      out << ln;
+      out << alpha;
+      out << kmin;
+      out << kmax;
+
+      return out;
+    }
+
+
+    /**
+     * Print PDF transformer to output stream.
+     *
+     * \param  out        output stream
+     * \return            output stream
+     */
+    std::ostream& print(std::ostream& out) const
+    {
+      using namespace std;
+
+      out << "Effective attenuation length [m]   " << ln    << endl;
+      out << "Distance dependence (power term)   " << alpha << endl;
+      out << "Minimal kappa                      " << kmin  << endl;
+      out << "Maximal kappa                      " << kmax  << endl;
+
+      return out;
+    }
+
+
+    double ln;                 //!< Effective attenuation length [m]
+    int    alpha;              //!< Distance dependence (power term)
+    double kmin;               //!< minimal kappa
+    double kmax;               //!< maximal kappa
+  };
+
+
+  /**
+   * Transformer for the 1D probability density function (PDF) of the time response of a PMT due to a point source.
+   *
+   * PDFs are evaluated by interpolation for:
+   *   -# distance between point source and PMT [m]
+   *   -# arrival time [ns]
+   *
+   * The evaluation of the weights is based on:
+   *   -# effective attenuation length
+   */
+  template<class JArgument_t>
+  class JPD0Transformer_t : 
+    public JMultiMapTransformer<1, JArgument_t>
+  {
+  public:
+
+    typedef JMultiMapTransformer<1, JArgument_t>                     JMultiMapTransformer_t;
+
+    typedef typename JMultiMapTransformer_t::clone_type              clone_type;
+    typedef typename JMultiMapTransformer_t::argument_type           argument_type;
+    typedef typename JMultiMapTransformer_t::const_array_type        const_array_type;
+
+    using JMultiMapTransformer_t::getWeight;
+
+    /**
+     * Get shortest distance.
+     *
+     * \return              distance [m]
+     */
+    static double getDmin()
+    {
+      return 0.01;
+    }
+
+
+    /**
+     * Default constructor.
+     */
+    JPD0Transformer_t() :
+      ln   (0.0),
+      alpha(0),
+      kmin (0.0),
+      kmax (0.0)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  ln         Effective attenuation length [m]
+     * \param  alpha      Distance dependence (power term)
+     * \param  kmin       Minimal kappa
+     * \param  kmax       Maximal kappa
+     */
+    JPD0Transformer_t(const double  ln,
+		      const int     alpha,
+		      const double  kmin,
+		      const double  kmax) :
+      ln   (ln),
+      alpha(alpha),
+      kmin (kmin),
+      kmax (kmax)
+    {}
+
+
+    /**
+     * Clone object.
+     * 
+     * \return            pointer to newly created transformer
+     */
+    virtual clone_type clone() const override 
+    {
+      return new JPD0Transformer_t(*this);
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {D_m}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type putXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      using namespace JTOOLS;
+
+      const double D  = buffer[0];
+
+      double x = xn;
+
+      const double t0 =  D * getIndexOfRefraction() * getInverseSpeedOfLight();
+      const double t1 =  D * kmin * getInverseSpeedOfLight();
+
+      x -= t1 - t0;
+
+      if (kmax > kmin) {
+        x /= D * (kmax - kmin) * getInverseSpeedOfLight();
+      }
+
+      return x;
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {D_m}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type getXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      using namespace JTOOLS;
+
+      const double D  = buffer[0];
+
+      double x = xn;
+
+      if (kmax > kmin) {
+        x *= D * (kmax - kmin) * getInverseSpeedOfLight();
+      }
+
+      const double t0 =  D * getIndexOfRefraction() * getInverseSpeedOfLight();
+      const double t1 =  D * kmin * getInverseSpeedOfLight();
+
+      x += t1 - t0;
+
+      return x;
+    }
+
+
+    /**
+     * Weight function.
+     *
+     * \param  buffer     {D_m}
+     * \return            weight
+     */
+    virtual double getWeight(const_array_type& buffer) const override 
+    {
+      using namespace JTOOLS;
+
+      const double D  = buffer[0];
+
+      const double d  = sqrt(getDmin()*getDmin() + D*D);
+
+      return exp(-d/ln) / pow(d,alpha);
+    }
+
+
+    /**
+     * Read PDF transformer from input.
+     *
+     * \param  in         reader
+     * \return            reader
+     */
+    virtual JReader& read(JReader& in) override 
+    {
+      in >> ln;
+      in >> alpha;
+      in >> kmin;
+      in >> kmax;
+
+      return in;
+    }
+
+
+    /**
+     * Write PDF transformer to output.
+     *
+     * \param  out        writer
+     * \return            writer
+     */
+    virtual JWriter& write(JWriter& out) const override 
+    {
+      out << ln;
+      out << alpha;
+      out << kmin;
+      out << kmax;
+
+      return out;
+    }
+
+
+    /**
+     * Print PDF transformer to output stream.
+     *
+     * \param  out        output stream
+     * \return            output stream
+     */
+    std::ostream& print(std::ostream& out) const
+    {
+      using namespace std;
+
+      out << "Effective attenuation length [m]   " << ln    << endl;
+      out << "Distance dependence (power term)   " << alpha << endl;
+      out << "Minimal kappa                      " << kmin  << endl;
+      out << "Maximal kappa                      " << kmax  << endl;
+
+      return out;
+    }
+
+
+    double ln;                 //!< Effective attenuation length [m]
+    int    alpha;              //!< Distance dependence (power term)
+    double kmin;               //!< minimal kappa
+    double kmax;               //!< maximal kappa
+  };
+
+
+  /**
+   * Transformer for the 2D probability density function (PDF) of the time response of a PMT due to an EM shower.
+   *
+   * PDFs are evaluated by interpolation for:
+   *   -# distance between EM shower and PMT [m]
+   *   -# cosine angle EM shower direction and EM shower - PMT position
+   *   -# arrival time [ns]
+   *
+   * The evaluation of the weights is based on:
+   *   -# effective attenuation length
+   *   -# emission profile of the photons
+   */
+  template<class JArgument_t>
+  class JPDGTransformer_t : 
+    public JMultiMapTransformer<2, JArgument_t>
+  {
+  public:
+
+    typedef JPD0Transformer_t      <JArgument_t>                     JFunction1DTransformer_t; 
+    typedef JMultiMapTransformer<2, JArgument_t>                     JMultiMapTransformer_t;
+
+    typedef typename JMultiMapTransformer_t::clone_type              clone_type;
+    typedef typename JMultiMapTransformer_t::argument_type           argument_type;
+    typedef typename JMultiMapTransformer_t::const_array_type        const_array_type;
+
+    using JMultiMapTransformer_t::getWeight;
+
+
+    /**
+     * Default constructor.
+     */
+    JPDGTransformer_t() :
+      transformer(),
+      getShowerProbability()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  ln         Effective attenuation length [m]
+     * \param  alpha      Distance dependence (power term)
+     * \param  kmin       Minimal kappa
+     * \param  kmax       Maximal kappa
+     * \param  geant      Function photon emission from EM-shower
+     * \param  bmin       Baseline photon emission from EM-shower
+     */
+    JPDGTransformer_t(const double    ln,
+		      const int       alpha,
+		      const double    kmin,
+		      const double    kmax,
+		      const JGeant_t& geant,
+		      const double    bmin) :
+      transformer(ln, alpha, kmin, kmax),
+      getShowerProbability(geant)
+    {
+      getShowerProbability.add(bmin);
+      getShowerProbability.compile();
+    }
+
+
+    /**
+     * Clone object.
+     * 
+     * \return            pointer to newly created transformer
+     */
+    virtual clone_type clone() const override 
+    {
+      return new JPDGTransformer_t(*this);
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {D_m, cd}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type putXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return transformer.putXn(buffer, xn);
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {D_m, cd}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type getXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return transformer.getXn(buffer, xn);
+    }
+
+
+    /**
+     * Weight function.
+     *
+     * \param  buffer     {D_m, cd}
+     * \return            weight
+     */
+    virtual double getWeight(const_array_type& buffer) const override 
+    {
+      using namespace JTOOLS;
+
+      //const double D  = buffer[0];
+      const double cd = buffer[1];
+
+      return transformer.getWeight(buffer) * getShowerProbability(getIndexOfRefractionPhase(), cd);
+    }
+
+
+    /**
+     * Read PDF transformer from input.
+     *
+     * \param  in         reader
+     * \return            reader
+     */
+    virtual JReader& read(JReader& in) override 
+    {
+      in >> transformer;
+      in >> getShowerProbability;
+
+      return in;
+    }
+
+
+    /**
+     * Write PDF transformer to output.
+     *
+     * \param  out        writer
+     * \return            writer
+     */
+    virtual JWriter& write(JWriter& out) const override 
+    {
+      out << transformer;
+      out << getShowerProbability;
+
+      return out;
+    }
+
+
+    /**
+     * Print PDF transformer to output stream.
+     *
+     * \param  out        output stream
+     * \return            output stream
+     */
+    std::ostream& print(std::ostream& out) const
+    {
+      return transformer.print(out);
+    }
+
+
+    JFunction1DTransformer_t transformer;
+    JGeant_t                 getShowerProbability;
+  };
+
+
+  /**
+   * Template definition of transformer of the probability density function (PDF) of the time response of a PMT.\n
+   * The actual implementation follows from the number of dimensions.
+   */
+  template<unsigned int N, class JArgument_t>
+  class JPDFTransformer;
+
+
+  /**
+   * Template specialisation of transformer of the 2D probability density function (PDF) of the time response of a PMT due to a bright point.
+   *
+   * PDFs are evaluated by interpolation for:
+   *   -# distance between bright point and PMT [m]
+   *   -# cosine PMT angle
+   *   -# arrival time [ns]
+   *
+   * The evaluation of the weights is based on:
+   *   -# effective attenuation length
+   */
+  template<class JArgument_t>
+  class JPDFTransformer<2, JArgument_t> : 
+    public JMultiMapTransformer<2, JArgument_t>
+  {
+  public:
+
+    typedef JPD0Transformer_t      <JArgument_t>                     JFunction1DTransformer_t;
+    typedef JMultiMapTransformer<2, JArgument_t>                     JMultiMapTransformer_t;
+
+    typedef typename JMultiMapTransformer_t::clone_type              clone_type;
+    typedef typename JMultiMapTransformer_t::argument_type           argument_type;
+    typedef typename JMultiMapTransformer_t::const_array_type        const_array_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JPDFTransformer() :
+      transformer()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  ln         Effective attenuation length [m]
+     * \param  alpha      Distance dependence (power term)
+     * \param  kmin       Minimal kappa
+     * \param  kmax       Maximal kappa
+     */
+    JPDFTransformer(const double ln,
+		    const int    alpha,
+		    const double kmin,
+		    const double kmax) :
+      transformer(ln, alpha, kmin, kmax)
+    {}
+
+
+    /**
+     * Clone object.
+     * 
+     * \return            pointer to newly created transformer
+     */
+    virtual clone_type clone() const override 
+    {
+      return new JPDFTransformer(*this);
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {D_m, ct}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type putXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return transformer.putXn(buffer, xn);
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {D_m, ct}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type getXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return transformer.getXn(buffer, xn);
+    }
+
+
+    /**
+     * Weight function.
+     *
+     * \param  buffer     {D_m, ct}
+     * \return            weight
+     */
+    virtual double getWeight(const_array_type& buffer) const override 
+    {
+      return transformer.getWeight(buffer);
+    }
+
+
+    /**
+     * Read PDF transformer from input.
+     *
+     * \param  in         reader
+     * \return            reader
+     */
+    virtual JReader& read(JReader& in) override 
+    {
+      in >> transformer;
+
+      return in;
+    }
+
+
+    /**
+     * Write PDF transformer to output.
+     *
+     * \param  out        writer
+     * \return            writer
+     */
+    virtual JWriter& write(JWriter& out) const override 
+    {
+      out << transformer;
+
+      return out;
+    }
+
+
+    /**
+     * Print PDF transfomer to output stream.
+     *
+     * \param  out        output stream
+     * \return            output stream
+     */
+    std::ostream& print(std::ostream& out) const
+    {
+      return transformer.print(out);
+    }
+
+
+    JFunction1DTransformer_t transformer;
+  };
+
+
+  /**
+   * Template specialisation of transformer of the 3D probability density function (PDF) of the time response of a PMT due to a muon.
+   *
+   * PDFs are evaluated by interpolation for:
+   *   -# distance of closest approach of the muon to the PMT [m]
+   *   -# zenith    angle of the PMT
+   *   -# azimuthal angle of the PMT
+   *   -# arrival time [ns]
+   *
+   * The evaluation of the weights is based on:
+   *   -# effective attenuation length
+   *   -# angular acceptance of PMT
+   */
+  template<class JArgument_t>
+  class JPDFTransformer<3, JArgument_t> : 
+    public JMultiMapTransformer<3, JArgument_t>
+  {
+  public:
+
+    typedef JPDFTransformer_t      <JArgument_t>                     JFunction1DTransformer_t; 
+    typedef JMultiMapTransformer<3, JArgument_t>                     JMultiMapTransformer_t;
+ 
+    typedef typename JMultiMapTransformer_t::clone_type              clone_type;
+    typedef typename JMultiMapTransformer_t::argument_type           argument_type;
+    typedef typename JMultiMapTransformer_t::const_array_type        const_array_type;
+
+    typedef JTOOLS::JGridPolint1Function1D_t                         JFunction1D_t;
+
+    using JMultiMapTransformer_t::getWeight;
+
+
+    /**
+     * Default constructor.
+     */
+    JPDFTransformer() :
+      transformer(),
+      getAngularAcceptance()
+    {}
+
+
+    /**
+     * Constructor.
+     *  
+     * \param  ln         Effective attenuation length [m]
+     * \param  alpha      Distance dependence (power term)
+     * \param  kmin       Minimal kappa
+     * \param  kmax       Maximal kappa
+     * \param  pmt        Function angular acceptance of PMT
+     * \param  amin       Baseline angular acceptance of PMT
+     */
+    template<class T>
+    JPDFTransformer(const double ln,
+		    const int    alpha,
+		    const double kmin,
+		    const double kmax,
+		    T            pmt,
+		    const double amin) :
+      transformer(ln, alpha, kmin, kmax),
+      getAngularAcceptance()
+    {
+      getAngularAcceptance.configure(JTOOLS::make_grid(1000, -1.0, +1.0), pmt);
+      getAngularAcceptance.add(amin);
+      getAngularAcceptance.compile();
+      getAngularAcceptance.setExceptionHandler(new JFunction1D_t::JDefaultResult(0.0));
+    }
+
+
+    /**
+     * Clone object.
+     * 
+     * \return            pointer to newly created transformer
+     */
+    virtual clone_type clone() const override 
+    {
+      return new JPDFTransformer(*this);
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {R_m, theta, phi}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type putXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return transformer.putXn(buffer, xn);
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {R_m, theta, phi}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type getXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return transformer.getXn(buffer, xn);
+    }
+
+
+    /**
+     * Weight function.
+     *
+     * \param  buffer     {R_m, theta, phi}
+     * \return            weight
+     */
+    virtual double getWeight(const_array_type& buffer) const override 
+    {
+      using namespace JTOOLS;
+
+      //const double R     = buffer[0];
+      const double theta = buffer[1];
+      const double phi   = buffer[2];
+
+      const double n   = getIndexOfRefraction();
+      const double ct0 = 1.0 / n;
+      const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
+    
+      const double px = sin(theta)*cos(phi);
+      //const double py = sin(theta)*sin(phi);
+      const double pz = cos(theta);
+    
+      const double ct = st0*px + ct0*pz;
+    
+      return transformer.getWeight(buffer) * getAngularAcceptance(ct);
+    }
+
+
+    /**
+     * Read PDF transformer from input.
+     *
+     * \param  in         reader
+     * \return            reader
+     */
+    virtual JReader& read(JReader& in) override 
+    {
+      in >> transformer;
+      in >> getAngularAcceptance;
+
+      getAngularAcceptance.compile();
+
+      return in;
+    }
+
+
+    /**
+     * Write PDF transformer to output.
+     *
+     * \param  out        writer
+     * \return            writer
+     */
+    virtual JWriter& write(JWriter& out) const override 
+    {
+      out << transformer;
+      out << getAngularAcceptance;
+
+      return out;
+    }
+
+
+    /**
+     * Print PDF transformer to output stream.
+     *
+     * \param  out        output stream
+     * \return            output stream
+     */
+    std::ostream& print(std::ostream& out) const
+    {
+      return transformer.print(out);
+    }
+
+
+    JFunction1DTransformer_t transformer;
+    JFunction1D_t            getAngularAcceptance;
+  };
+
+
+  /**
+   * Template specialisation of transformer of the 4D probability density function (PDF) of the time response of a PMT due to an EM shower.
+   *
+   * PDFs are evaluated by interpolation for:
+   *   -# distance between EM shower and PMT [m]
+   *   -# cosine angle EM shower direction and EM shower - PMT position
+   *   -# zenith    angle of the PMT
+   *   -# azimuthal angle of the PMT
+   *   -# arrival time [ns]
+   *
+   * The evaluation of the weights is based on:
+   *   -# effective attenuation length
+   *   -# emission profile of the photons
+   *   -# angular acceptance of PMT
+   */
+  template<class JArgument_t>
+  class JPDFTransformer<4, JArgument_t> : 
+    public JMultiMapTransformer<4, JArgument_t>
+  {
+  public:
+
+    typedef JPDGTransformer_t      <JArgument_t>                     JFunction2DTransformer_t;
+    typedef JMultiMapTransformer<4, JArgument_t>                     JMultiMapTransformer_t;
+
+    typedef typename JMultiMapTransformer_t::clone_type              clone_type;
+    typedef typename JMultiMapTransformer_t::argument_type           argument_type;
+    typedef typename JMultiMapTransformer_t::const_array_type        const_array_type;
+
+    typedef JTOOLS::JGridPolint1Function1D_t                         JFunction1D_t;
+
+    using JMultiMapTransformer_t::getWeight;
+
+
+    /**
+     * Default constructor.
+     */
+    JPDFTransformer() :
+      transformer(),
+      getAngularAcceptance()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  ln         Effective attenuation length [m]
+     * \param  alpha      Distance dependence (power term)
+     * \param  kmin       Minimal kappa
+     * \param  kmax       Maximal kappa
+     * \param  geant      Function photon emission from EM-shower
+     * \param  bmin       Baseline photon emission from EM-shower
+     * \param  pmt        Function angular acceptance of PMT
+     * \param  amin       Baseline angular acceptance of PMT
+     */
+    template<class T>
+    JPDFTransformer(const double    ln,
+		    const int       alpha,
+		    const double    kmin,
+		    const double    kmax,
+		    const JGeant_t& geant,
+		    const double    bmin,
+		    T               pmt,
+		    const double    amin) :
+      transformer(ln, alpha, kmin, kmax, geant, bmin),
+      getAngularAcceptance()
+    {
+      getAngularAcceptance.configure(JTOOLS::make_grid(1000, -1.0, +1.0), pmt);
+      getAngularAcceptance.add(amin);
+      getAngularAcceptance.compile();
+      getAngularAcceptance.setExceptionHandler(new JFunction1D_t::JDefaultResult(0.0));
+    }
+
+
+    /**
+     * Clone object.
+     * 
+     * \return            pointer to newly created transformer
+     */
+    virtual clone_type clone() const override 
+    {
+      return new JPDFTransformer(*this);
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {D_m, cd, theta, phi}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type putXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return transformer.putXn(buffer, xn);
+    }
+
+
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {D_m, cd, theta, phi}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type getXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return transformer.getXn(buffer, xn);
+    }
+
+
+    /**
+     * Weight function.
+     *
+     * \param  buffer     {D_m, cd, theta, phi}
+     * \return            weight
+     */
+    virtual double getWeight(const_array_type& buffer) const override 
+    {
+      const double cd    = buffer[1];
+      const double theta = buffer[2];
+      const double phi   = buffer[3];
+
+      const double ct0 = cd;
+      const double st0 = sqrt((1.0 + ct0)*(1.0 - ct0));
+    
+      const double px = sin(theta)*cos(phi);
+      //const double py = sin(theta)*sin(phi);
+      const double pz = cos(theta);
+    
+      const double ct = st0*px + ct0*pz;
+
+      return transformer.getWeight(buffer) * getAngularAcceptance(ct);
+    }
+
+
+    /**
+     * Read PDF transformer from input.
+     *
+     * \param  in         reader
+     * \return            reader
+     */
+    virtual JReader& read(JReader& in) override 
+    {
+      in >> transformer;
+      in >> getAngularAcceptance;
+
+      getAngularAcceptance.compile();
+
+      return in;
+    }
+
+
+    /**
+     * Write PDF transformer to output.
+     *
+     * \param  out        writer
+     * \return            writer
+     */
+    virtual JWriter& write(JWriter& out) const override 
+    {
+      out << transformer;
+      out << getAngularAcceptance;
+
+      return out;
+    }
+
+
+    /**
+     * Print PDF transfomer to output stream.
+     *
+     * \param  out        output stream
+     * \return            output stream
+     */
+    std::ostream& print(std::ostream& out) const
+    {
+      return transformer.print(out);
+    }
+
+
+    JFunction2DTransformer_t transformer;
+    JFunction1D_t            getAngularAcceptance;
+  };
+
+
+  /**
+   * Template specialisation of transformer of the 5D probability density function (PDF) of the time response of a PMT due to an EM shower.
+   *
+   * PDFs are evaluated by interpolation for:
+   *   -# energy of the EM shower
+   *   -# distance between EM shower and PMT [m]
+   *   -# cosine angle EM shower direction and EM shower - PMT position
+   *   -# zenith    angle of the PMT
+   *   -# azimuthal angle of the PMT
+   *   -# arrival time [ns]
+   *
+   * The evaluation of the weights is based on:
+   *   -# energy of the EM shower
+   *   -# effective attenuation length
+   *   -# emission profile of the photons
+   *   -# angular acceptance of PMT
+   */
+  template<class JArgument_t>
+  class JPDFTransformer<5, JArgument_t> : 
+    public JMultiMapTransformer<5, JArgument_t>
+  {
+  public:
+    
+    typedef JPDFTransformer     <4, JArgument_t>                     JFunction4DTransformer_t;
+    typedef JMultiMapTransformer<5, JArgument_t>                     JMultiMapTransformer_t;
+    
+    typedef typename JMultiMapTransformer_t::clone_type              clone_type;
+    typedef typename JMultiMapTransformer_t::argument_type           argument_type;
+    typedef typename JMultiMapTransformer_t::const_array_type        const_array_type;
+    
+    
+    /**
+     * Default constructor.
+     */
+    JPDFTransformer() :
+      transformer()
+    {}    
+
+    
+    /**
+     * Constructor.
+     *
+     * \param  ln         Effective attenuation length [m]
+     * \param  alpha      Distance dependence (power term)
+     * \param  kmin       Minimal kappa
+     * \param  kmax       Maximal kappa
+     * \param  geant      Function photon emission from EM-shower
+     * \param  bmin       Baseline photon emission from EM-shower
+     * \param  pmt        Function angular acceptance of PMT
+     * \param  amin       Baseline angular acceptance of PMT
+     */
+    
+    template<class T>
+    JPDFTransformer(const double    ln,
+		    const int       alpha,
+		    const double    kmin,
+		    const double    kmax,
+		    const JGeant_t& geant,
+		    const double    bmin,
+		    T               pmt,
+		    const double    amin) :
+      transformer(ln, alpha, kmin, kmax, geant, bmin, pmt, amin)
+    {}
+
+
+    /**
+     * Clone object.
+     * 
+     * \return            pointer to newly created transformer
+     */
+    virtual clone_type clone() const override 
+    {
+      return new JPDFTransformer(*this);
+    }
+    
+    
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {E_GeV, D_m, cd, theta, phi}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type putXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return transformer.putXn(buffer.pop_front(), xn);
+    }
+    
+    
+    /**
+     * Evaluate arrival time.
+     *
+     * \param  buffer     {E_GeV, D_m, cd, theta, phi}
+     * \param  xn         old t_ns
+     * \return            new t_ns
+     */
+    virtual argument_type getXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return transformer.getXn(buffer.pop_front(), xn);
+    }
+    
+    
+    /**
+     * Weight function.
+     *
+     * \param  buffer     {E_GeV, D_m, cd, theta, phi}
+     * \return            weight
+     */
+    virtual double getWeight(const_array_type& buffer) const override 
+    { 
+      const double E     = buffer[0];
+
+      return transformer.getWeight(buffer.pop_front()) / E;
+    }
+    
+    
+    /**
+     * Read PDF transformer from input.
+     *
+     * \param  in         reader
+     * \return            reader
+     */
+    virtual JReader& read(JReader& in) override 
+    {
+      in >> transformer;
+
+      return in;
+    }
+    
+  
+    /**
+     * Write PDF transformer to output.
+     *
+     * \param  out        writer
+     * \return            writer
+     */
+    virtual JWriter& write(JWriter& out) const override 
+    {
+      out << transformer;
+      
+      return out;
+    }
+    
+    
+    /**
+     * Print PDF transfomer to output stream.
+     *
+     * \param  out        output stream
+     * \return            output stream
+     */
+    std::ostream& print(std::ostream& out) const
+    {
+      return transformer.print(out);
+    }
+    
+    JFunction4DTransformer_t transformer;
+  };
+}
+
+#endif
diff --git a/jpp/JPhysics/JPDFTypes.hh b/jpp/JPhysics/JPDFTypes.hh
new file mode 100644
index 0000000..8c71d47
--- /dev/null
+++ b/jpp/JPhysics/JPDFTypes.hh
@@ -0,0 +1,201 @@
+#ifndef __JPHYSICS__JPDFTYPES__
+#define __JPHYSICS__JPDFTYPES__
+
+#include <string>
+#include <sstream>
+
+#include "JLang/JException.hh"
+#include "Jeep/JeepToolkit.hh"
+
+/**
+ * \file
+ *
+ * Numbering scheme for PDF types.
+ * \author mdejong
+ */
+namespace JPHYSICS {}
+namespace JPP { using namespace JPHYSICS; }
+
+namespace JPHYSICS {
+
+  using JLANG::JException;
+
+
+  /**
+   * PDF types
+   */
+  enum JPDFType_t {
+
+    DIRECT_LIGHT_FROM_MUON             =    1,      //!< direct    light from muon
+    SCATTERED_LIGHT_FROM_MUON          =    2,      //!< scattered light from muon
+
+    DIRECT_LIGHT_FROM_EMSHOWERS        =    3,      //!< direct    light from EM showers
+    SCATTERED_LIGHT_FROM_EMSHOWERS     =    4,      //!< scattered light from EM showers
+
+    DIRECT_LIGHT_FROM_DELTARAYS        =    5,      //!< direct    light from delta-rays
+    SCATTERED_LIGHT_FROM_DELTARAYS     =    6,      //!< scattered light from delta-rays
+
+    SCATTERED_LIGHT_FROM_MUON_5D       =   12,      //!< scattered light from muon
+
+    DIRECT_LIGHT_FROM_EMSHOWER         =   13,      //!< direct    light from EM shower
+    SCATTERED_LIGHT_FROM_EMSHOWER      =   14,      //!< scattered light from EM shower
+
+    //DIRECT_LIGHT_FROM_SHOWER           =   15,      //!< direct + scattered light from HADRONIC shower
+
+    DIRECT_LIGHT_FROM_BRIGHT_POINT     =   23,      //!< direct    light from bright point
+    SCATTERED_LIGHT_FROM_BRIGHT_POINT  =   24,      //!< scattered light from bright point
+
+    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
+    LIGHT_FROM_EMSHOWER                = 1013,      //!< direct and scattered light from EM shower
+    LIGHT_FROM_BRIGTH_POINT            = 1023       //!< direct and scattered light from brigth point
+  };
+
+
+  static const char WILD_CARD = '%';            //!< wild card character for file name substitution
+
+
+  /**
+   * Get PDF label.
+   *
+   * \param  pdf                PDF type
+   * \return                    PDF label
+   */
+  inline std::string getLabel(const JPDFType_t pdf)
+  {
+    std::ostringstream os;
+
+    os << pdf;
+
+    return os.str();
+  }
+
+
+  /**
+   * Get PDF type.
+   *
+   * \param  file_name          file name
+   * \return                    PDF type (-1 in case of error)
+   */
+  inline int getPDFType(const std::string& file_name)
+  {
+    using namespace std;
+
+    static const char* digits = "0123456789";
+    
+    int type = -1;
+    
+    string buffer = JEEP::getFilename(file_name);
+    
+    string::size_type pos = buffer.find_first_of(digits);
+
+    if (pos != string::npos) {
+
+      string::size_type len = buffer.substr(pos).find_first_not_of(digits);
+
+      istringstream(buffer.substr(pos, len)) >> type;
+    }
+
+    return type;
+  }
+
+
+  /**
+   * 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 
+   * which will be replaced by the label corresponding to the given PDF type.
+   * 
+   * \param  file_name          input  file name
+   * \param  pdf                PDF type
+   * \return                    output file name
+   */
+  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));
+  }
+
+
+  /**
+   * Test if given PDF type corresponds to Cherenkov light from muon.
+   *
+   * \param  pdf                PDF type
+   * \return                    true if PDF corresponds to muon; else false
+   */
+  inline bool is_muon(const int pdf)
+  {
+    return (pdf == DIRECT_LIGHT_FROM_MUON           ||
+	    pdf == SCATTERED_LIGHT_FROM_MUON        ||
+	    pdf == LIGHT_FROM_MUON);
+  }
+
+
+  /**
+   * Test if given PDF type corresponds to Cherenkov light from Bremsstrahlung.
+   *
+   * \param  pdf                PDF type
+   * \return                    true if PDF corresponds to Bremsstrahlung; else false
+   */
+  inline bool is_bremsstrahlung(const int pdf)
+  {
+    return (pdf == DIRECT_LIGHT_FROM_EMSHOWERS      ||
+	    pdf == SCATTERED_LIGHT_FROM_EMSHOWERS   ||
+	    pdf == LIGHT_FROM_EMSHOWERS);
+  }
+
+
+  /**
+   * Test if given PDF type corresponds to Cherenkov light from delta-rays.
+   *
+   * \param  pdf                PDF type
+   * \return                    true if PDF corresponds to delta-rays; else false
+   */
+  inline bool is_deltarays(const int pdf)
+  {
+    return (pdf == DIRECT_LIGHT_FROM_DELTARAYS      ||
+	    pdf == SCATTERED_LIGHT_FROM_DELTARAYS   ||
+	    pdf == LIGHT_FROM_DELTARAYS);
+  }
+
+
+  /**
+   * Test if given PDF type corresponds to scattered light.
+   *
+   * \param  pdf                PDF type
+   * \return                    true if PDF corresponds to scattered light; else false
+   */
+  inline bool is_scattered(const int pdf)
+  {
+    return (pdf == SCATTERED_LIGHT_FROM_MUON        ||
+	    pdf == SCATTERED_LIGHT_FROM_EMSHOWERS   ||
+	    pdf == SCATTERED_LIGHT_FROM_DELTARAYS   ||
+	    pdf == SCATTERED_LIGHT_FROM_MUON_5D     ||
+	    pdf == SCATTERED_LIGHT_FROM_EMSHOWER);
+  }
+}
+
+#endif
diff --git a/jpp/JPhysics/JPDF_t.hh b/jpp/JPhysics/JPDF_t.hh
new file mode 100644
index 0000000..bfc0ff2
--- /dev/null
+++ b/jpp/JPhysics/JPDF_t.hh
@@ -0,0 +1,383 @@
+#include "JLang/JException.hh"
+#include "JTools/JCollection.hh"
+#include "JTools/JMap.hh"
+#include "JTools/JGridMap.hh"
+#include "JTools/JMapList.hh"
+#include "JTools/JSpline.hh"
+#include "JTools/JPolint.hh"
+#include "JTools/JElement.hh"
+#include "JTools/JResult.hh"
+#include "JPhysics/JPDFTable.hh"
+#include "JPhysics/JPDFToolkit.hh"
+#include "JPhysics/JPDFTypes.hh"
+#include "JMath/JZero.hh"
+
+
+/**
+ * \file
+ *
+ * Auxiliary data structure for muon PDF.
+ * \author mdejong
+ */
+
+/**
+ * Auxiliary data structure for muon PDF.
+ */
+struct JPDF {
+
+  typedef JPP::JSplineFunction1D<JPP::JSplineElement2S<double, double>, 
+				 JPP::JCollection, 
+				 JPP::JResultPDF<double> >         JFunction1D_t;
+
+  typedef JPP::JMAPLIST<JPP::JPolint1FunctionalMap,
+			JPP::JPolint0FunctionalGridMap,
+			JPP::JPolint0FunctionalGridMap>::maplist   JPDFMaplist_t;
+  typedef JPP::JPDFTable<JFunction1D_t, JPDFMaplist_t>             JPDF_t;
+  typedef JFunction1D_t::result_type                               result_type;
+
+
+  /**
+   * Constructor.
+   *
+   * The <tt>TTS</tt> corresponds to the additional time smearing applied to the PDFs.
+   *
+   * \param  file_name          file name
+   * \param  TTS                TTS [ns]
+   * \param  numberOfPoints     number of points for Gauss-Hermite integration of TTS
+   * \param  epsilon            precision        for Gauss-Hermite integration of TTS
+   */
+  JPDF(const std::string& file_name,
+       const double       TTS,
+       const int          numberOfPoints = 25,
+       const double       epsilon        = 1.0e-10)
+  {
+    using namespace std;
+    using namespace JPP;
+
+    const JPDF_t::JSupervisor supervisor(new JPDF_t::JDefaultResult(zero));
+
+    cout << "loading input from file " << file_name << "... " << flush;
+
+    pdf.load(file_name.c_str());
+
+    pdf.setExceptionHandler(supervisor);
+
+    cout << "OK" << endl;
+
+    type = getPDFType(file_name);
+
+    if        (TTS > 0.0) {
+
+      cout << "bluring PDFs... " << flush;
+
+      pdf.blur(TTS, numberOfPoints, epsilon);
+
+      cout << "OK" << endl;
+
+    } else if (TTS < 0.0) {
+
+      THROW(JValueOutOfRange, "Illegal value of TTS [ns]: " << TTS); 
+    }
+  }
+
+
+  /**
+   * Get PDF.
+   *
+   * 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                  muon energy at minimum distance of approach [GeV]
+   * \param  R                  minimum distance of approach [m]
+   * \param  theta              PMT zenith  angle [rad]
+   * \param  phi                PMT azimuth angle [rad]
+   * \param  t1                 arrival time relative to Cherenkov hypothesis [ns]
+   * \return                    hypothesis value
+   */
+  result_type calculate(const double E,
+			const double R,
+			const double theta,
+			const double phi,
+			const double t1) const
+  {
+    using namespace JPP;
+
+    result_type h1 = pdf(R, theta, phi, t1);
+
+    if        (is_bremsstrahlung(type)) {
+      h1 *= E;
+    } else if (is_deltarays(type)) {
+      h1 *= getDeltaRaysFromMuon(E);
+    }
+
+    // safety measures
+
+    if (h1.f <= 0.0) {
+      h1.f  = 0.0;
+      h1.fp = 0.0;
+    }
+          
+    if (h1.v <= 0.0) {
+      h1.v  = 0.0;
+    }
+          
+    return h1;
+  }
+
+  JPDF_t pdf;    //!< PDF
+  int    type;   //!< PDF type
+};
+
+
+/**
+ * Auxiliary data structure for muon PDF.
+ */
+struct JMuonPDF_t {
+
+  typedef JPP::JSplineFunction1D<JPP::JSplineElement2S<double, double>, 
+				 JPP::JCollection, 
+				 JPP::JResultPDF<double> >         JFunction1D_t;
+
+  typedef JPP::JMAPLIST<JPP::JPolint1FunctionalMap,
+			JPP::JPolint0FunctionalGridMap,
+			JPP::JPolint0FunctionalGridMap>::maplist   JPDFMaplist_t;
+  typedef JPP::JPDFTable<JFunction1D_t, JPDFMaplist_t>             JPDF_t;
+  typedef JFunction1D_t::result_type                               result_type;
+
+
+  /**
+   * Constructor.
+   *
+   * The PDF file descriptor should contain the wild card character JPHYSICS::WILD_CARD.\n
+   * The <tt>TTS</tt> corresponds to the additional time smearing applied to the PDFs.
+   *
+   * \param  fileDescriptor     PDF file descriptor
+   * \param  TTS                TTS [ns]
+   * \param  numberOfPoints     number of points for Gauss-Hermite integration of TTS
+   * \param  epsilon            precision        for Gauss-Hermite integration of TTS
+   */
+  JMuonPDF_t(const std::string& fileDescriptor,
+	     const double       TTS,
+	     const int          numberOfPoints = 25,
+	     const double       epsilon        = 1.0e-10)
+  {
+    using namespace std;
+    using namespace JPP;
+
+    const JPDFType_t pdf_t[] = { DIRECT_LIGHT_FROM_MUON,
+				 SCATTERED_LIGHT_FROM_MUON,
+				 DIRECT_LIGHT_FROM_EMSHOWERS,
+				 SCATTERED_LIGHT_FROM_EMSHOWERS,
+				 DIRECT_LIGHT_FROM_DELTARAYS,
+				 SCATTERED_LIGHT_FROM_DELTARAYS };
+
+    const  int N = sizeof(pdf_t) / sizeof(pdf_t[0]);
+    
+    JPDF_t pdf[N];
+
+    const JPDF_t::JSupervisor supervisor(new JPDF_t::JDefaultResult(zero));
+
+    for (int i = 0; i != N; ++i) {
+
+      const string file_name = getFilename(fileDescriptor, pdf_t[i]);
+
+      cout << "loading input from file " << file_name << "... " << flush;
+
+      pdf[i].load(file_name.c_str());
+
+      pdf[i].setExceptionHandler(supervisor);
+
+      cout << "OK" << endl;
+    }
+
+    // Add PDFs
+
+    cout << "adding PDFs... " << flush;
+
+    pdfA = pdf[1];  pdfA.add(pdf[0]);
+    pdfB = pdf[3];  pdfB.add(pdf[2]);
+    pdfC = pdf[5];  pdfC.add(pdf[4]);
+
+    cout << "OK" << endl;
+
+    if        (TTS > 0.0) {
+
+      cout << "bluring PDFs... " << flush;
+
+      pdfA.blur(TTS, numberOfPoints, epsilon);
+      pdfB.blur(TTS, numberOfPoints, epsilon);
+      pdfC.blur(TTS, numberOfPoints, epsilon);
+
+      cout << "OK" << endl;
+
+    } else if (TTS < 0.0) {
+
+      THROW(JValueOutOfRange, "Illegal value of TTS [ns]: " << TTS); 
+    }
+  }
+
+
+  /**
+   * Get PDF.
+   *
+   * 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                  muon energy at minimum distance of approach [GeV]
+   * \param  R                  minimum distance of approach [m]
+   * \param  theta              PMT zenith  angle [rad]
+   * \param  phi                PMT azimuth angle [rad]
+   * \param  t1                 arrival time relative to Cherenkov hypothesis [ns]
+   * \return                    hypothesis value
+   */
+  result_type calculate(const double E,
+			const double R,
+			const double theta,
+			const double phi,
+			const double t1) const
+  {
+    using namespace JPP;
+
+    result_type h1 = (pdfA(R, theta, phi, t1)                               +
+		      pdfB(R, theta, phi, t1) * E                           +
+		      pdfC(R, theta, phi, t1) * getDeltaRaysFromMuon(E));
+
+    // safety measures
+
+    if (h1.f <= 0.0) {
+      h1.f  = 0.0;
+      h1.fp = 0.0;
+    }
+          
+    if (h1.v <= 0.0) {
+      h1.v  = 0.0;
+    }
+          
+    return h1;
+  }
+
+  JPDF_t pdfA;   //!< PDF for minimum ionisong particle
+  JPDF_t pdfB;   //!< PDF for average energy losses
+  JPDF_t pdfC;   //!< PDF for delta-rays
+};
+
+
+/**
+ * Auxiliary data structure for shower PDF.
+ */
+struct JShowerPDF_t {
+
+  typedef JPP::JSplineFunction1D<JPP::JSplineElement2S<double, double>,
+				 JPP::JCollection,
+				 JPP::JResultPDF<double> >         JFunction1D_t;
+
+  typedef JPP::JMAPLIST<JPP::JPolint1FunctionalMap,
+			JPP::JPolint1FunctionalMap,
+			JPP::JPolint0FunctionalGridMap,
+			JPP::JPolint0FunctionalGridMap>::maplist   JPDFMaplist_t;
+  typedef JPP::JPDFTable<JFunction1D_t, JPDFMaplist_t>             JPDF_t;
+  typedef JFunction1D_t::result_type                               result_type;
+
+
+  /**
+   * Constructor.
+   *
+   * The PDF file descriptor should contain the wild card character JPHYSICS::WILD_CARD.\n
+   * The <tt>TTS</tt> corresponds to the additional time smearing applied to the PDFs.
+   *
+   * \param  fileDescriptor     PDF file descriptor
+   * \param  TTS                TTS [ns]
+   * \param  numberOfPoints     number of points for Gauss-Hermite integration of TTS
+   * \param  epsilon            precision        for Gauss-Hermite integration of TTS
+   */
+  JShowerPDF_t(const std::string& fileDescriptor,
+	       const double       TTS,
+	       const int          numberOfPoints = 25,
+	       const double       epsilon        = 1.0e-10)
+  {
+    using namespace std;
+    using namespace JPP;
+
+    const JPDFType_t pdf_t[] = { SCATTERED_LIGHT_FROM_EMSHOWER,
+				 DIRECT_LIGHT_FROM_EMSHOWER };
+
+    const  int N = sizeof(pdf_t) / sizeof(pdf_t[0]);
+
+    const JPDF_t::JSupervisor supervisor(new JPDF_t::JDefaultResult(zero));
+
+    for (int i = 0; i != N; ++i) {
+
+      const string file_name = getFilename(fileDescriptor, pdf_t[i]);
+
+      cout << "loading input from file " << file_name << "... " << flush;
+
+      JPDF_t pdf;
+
+      pdf.load(file_name.c_str());
+
+      pdf.setExceptionHandler(supervisor);
+
+      if (pdfA.empty())
+	pdfA = pdf;
+      else
+	pdfA.add(pdf);
+
+      cout << "OK" << endl;
+    }
+
+    if        (TTS > 0.0) {
+
+      cout << "bluring PDFs... " << flush;
+
+      pdfA.blur(TTS, numberOfPoints, epsilon);
+
+      cout << "OK" << endl;
+
+    } else if (TTS < 0.0) {
+
+      THROW(JValueOutOfRange, "Illegal value of TTS [ns]: " << TTS);
+    }
+  }
+
+
+  /**
+   * Get PDF.
+   *
+   * 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  D                  distance [m]
+   * \param  cd                 cosine emission angle
+   * \param  theta              PMT zenith  angle [rad]
+   * \param  phi                PMT azimuth angle [rad]
+   * \param  t1                 arrival time relative to Cherenkov hypothesis [ns]
+   * \return                    hypothesis value
+   */
+  result_type calculate(const double E,
+			const double D,
+			const double cd,
+			const double theta,
+			const double phi,
+			const double t1) const
+  {
+    using namespace JPP;
+
+    result_type h1 = pdfA(D, cd, theta, phi, t1) * E;
+
+    // safety measures
+
+    if (h1.f <= 0.0) {
+      h1.f  = 0.0;
+      h1.fp = 0.0;
+    }
+
+    if (h1.v <= 0.0) {
+      h1.v  = 0.0;
+    }
+
+    return h1;
+  }
+
+  JPDF_t pdfA;   //!< PDF for shower
+};
diff --git a/jpp/JTools/JAbstractCollection.hh b/jpp/JTools/JAbstractCollection.hh
new file mode 100644
index 0000000..0145837
--- /dev/null
+++ b/jpp/JTools/JAbstractCollection.hh
@@ -0,0 +1,88 @@
+#ifndef __JTOOLS__JABSTRACTCOLLECTION__
+#define __JTOOLS__JABSTRACTCOLLECTION__
+
+
+/**
+ * \author mdejong
+ */
+
+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 {
+
+    typedef JAbscissa_t                                                   abscissa_type;
+
+
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JAbstractCollection()
+    {}
+    
+    
+    /**
+     * Get number of elements.
+     *
+     * \return                 number of elements
+     */
+    virtual int getSize() const = 0;
+    
+
+    /**
+     * Get abscissa value.
+     *
+     * \param  index           index
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getX(int index) const = 0;
+
+
+    /**
+     * Get minimal abscissa value.
+     *
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getXmin() const = 0;
+
+
+    /**
+     * Get maximal abscissa value.
+     *
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getXmax() const = 0;
+
+
+    /**
+     * Test whether abstract collections are equal.
+     *
+     * \param  collection      abstract collection
+     * \return                 true if collections are equals; else false
+     */
+    bool is_equal(const JAbstractCollection& collection) const
+    {
+      if (this->getSize() == collection.getSize()) {
+
+	for (int i = 0; i != this->getSize(); ++i) {
+
+	  if (this->getX(i) != collection.getX(i)) {
+	    return false;
+	  }
+	}
+
+	return true;
+      }
+
+      return false;
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JAbstractMultiMap.hh b/jpp/JTools/JAbstractMultiMap.hh
new file mode 100644
index 0000000..66d70f3
--- /dev/null
+++ b/jpp/JTools/JAbstractMultiMap.hh
@@ -0,0 +1,62 @@
+#ifndef __JTOOLS__JABSTRACTMULTIMAP__
+#define __JTOOLS__JABSTRACTMULTIMAP__
+
+#include "JTools/JAbstractCollection.hh"
+#include "JTools/JMultiKey.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  /**
+   * Abstract interface for abscissa values of a multidimensional map.
+   *
+   * The template parameters refer to the dimension of the multimap and
+   * the data type of the abscissa values, respectively.
+   */
+  template<unsigned int N, class JAbscissa_t> 
+  struct JAbstractMultiMap :
+    public virtual JAbstractMultiMap<N - 1, JAbscissa_t>
+  {
+    typedef JAbscissa_t                                          abscissa_type;
+    typedef JMultiKey<N - 1, abscissa_type>                      key_type;
+
+    using JAbstractMultiMap<N - 1, JAbscissa_t>::operator();
+
+
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JAbstractMultiMap()
+    {}
+
+
+    /**
+     * Get abscissa values as a function of given key.
+     * 
+     * \param  key           key
+     * \return               abscissa values
+     */
+    virtual const JAbstractCollection<abscissa_type>& operator()(const key_type& key) const = 0;
+  };
+
+
+  /**
+   * Terminator class of recursive class JAbstractMultiMap.
+   * This class provides for dummy implementations of interface methods.
+   */
+  template<class JAbscissa_t>
+  struct JAbstractMultiMap<0, JAbscissa_t>
+  {
+  protected:
+    void operator()() const {}
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JArray.hh b/jpp/JTools/JArray.hh
new file mode 100644
index 0000000..383b87a
--- /dev/null
+++ b/jpp/JTools/JArray.hh
@@ -0,0 +1,1265 @@
+#ifndef __JTOOLS__JARRAY__
+#define __JTOOLS__JARRAY__
+
+#include <istream>
+#include <ostream>
+#include <iterator>
+#include <algorithm>
+
+#include "JIO/JSerialisable.hh"
+#include "JTools/JMultiKey.hh"
+#include "JMath/JMath.hh"
+#include "JLang/JAssert.hh"
+#include "JLang/JClass.hh"
+#include "JLang/JException.hh"
+#include "JLang/JEquals.hh"
+#include "JLang/JManip.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JIO::JReader;
+  using JIO::JWriter;
+  using JMATH::JMath;
+  using JLANG::JEquals;
+  using JLANG::JIndexOutOfRange;
+
+
+  /**
+   * One dimensional array of template objects with fixed length.\n
+   * The internal data structure consists of a standard C-array.
+   */
+  template<unsigned int N, class T>
+  class JArray :
+    public JMath  < JArray<N,T> >,
+    public JEquals< JArray<N,T> >
+  {
+  public:
+
+    typedef  const T*                                      const_pointer;
+    typedef  T*                                            pointer;
+    typedef  const T*                                      const_iterator;
+    typedef  T*                                            iterator;
+    typedef  std::reverse_iterator<const_iterator>         const_reverse_iterator;
+    typedef  std::reverse_iterator<iterator>               reverse_iterator;
+    typedef  T&                                            reference;
+    typedef  const T&                                      const_reference;
+    typedef  unsigned int                                  size_type;
+    typedef  typename JLANG::JClass<T>::argument_type      argument_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JArray()
+    {}
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  array            array
+     */
+    template<unsigned int M>
+    JArray(const JArray<M, T>& array)
+    {
+      STATIC_CHECK(M >= N);
+
+      std::copy_n(array.data(), N, this->data());
+    }
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  array            array
+     */
+    template<unsigned int M>
+    JArray(const JArray<M, const T>& array)
+    {
+      STATIC_CHECK(M >= N);
+ 
+      std::copy_n(array.data(), N, this->data());
+    }
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  p                pointer to data
+     */
+    JArray(const T* p)
+    {
+      std::copy_n(p, N, this->data());
+    }
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  key              multi-dimensional key
+     */
+    JArray(const JMultiKey<N, T>& key)
+    {
+      assign(key);
+    }
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  key              multi-dimensional key
+     */
+    JArray(const JMultiKey<N, const T>& key)
+    {
+      assign(key);
+    }
+
+
+    /**
+     * Append constructor.
+     *
+     * \param  array            array
+     * \param  value            value
+     */
+    JArray(const JArray<N-1, T>& array, argument_type value)
+    {
+      std::copy_n(array.data(), N-1, this->data());
+
+      this->buffer[N-1] = value;
+    }
+
+
+    /**
+     * Append constructor.
+     *
+     * \param  array            array
+     * \param  value            value
+     */
+    JArray(const JArray<N-1, const T>& array, argument_type value)
+    {
+      std::copy_n(array.data(), N-1, this->data());
+
+      this->buffer[N-1] = value;
+    }
+
+
+    /**
+     * Append constructor.
+     *
+     * \param  key              multi-dimensional key
+     * \param  value            value
+     */
+    JArray(const JMultiKey<N-1, T>& key, argument_type value)
+    {
+      assign(key, value);
+    }
+
+
+    /**
+     * Append constructor.
+     *
+     * \param  key              multi-dimensional key
+     * \param  value            value
+     */
+    JArray(const JMultiKey<N-1, const T>& key, argument_type value)
+    {
+      assign(key, value);
+    }
+
+
+    /**
+     * Initialise constructor.
+     *
+     * \param  value            first value
+     * \param  args             remaining values
+     */
+    template<class ...Args>
+    JArray(argument_type value, const Args& ...args)
+    {
+      set(value, args...);
+    }
+
+
+    /**
+     * Set array.
+     *
+     * \param  args             values
+     */
+    template<class ...Args>
+    JArray& set(const Args& ...args)
+    {
+      STATIC_CHECK(N == sizeof...(Args));
+
+      __set__(0, args...);
+
+      return *this;
+    }
+
+
+    const_iterator begin() const { return buffer; }                                    //!< get iterator to begin of data
+    const_iterator end()   const { return buffer + N; }                                //!< get iterator to end   of data
+
+
+    iterator begin() { return buffer; }                                                //!< get iterator to begin of data
+    iterator end()   { return buffer + N; }                                            //!< get iterator to end   of data
+
+
+    const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }    //!< get reverse iterator to begin of data 
+    const_reverse_iterator rend()   const { return const_reverse_iterator(begin()); }  //!< get reverse iterator to begin of data 
+
+
+    reverse_iterator rbegin() { return reverse_iterator(end()); }                      //!< get reverse iterator to begin of data 
+    reverse_iterator rend()   { return reverse_iterator(begin()); }                    //!< get reverse iterator to end   of data 
+
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element
+     */
+    const_reference operator[](int index) const
+    { 
+      return buffer[index];
+    }
+
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element
+     */
+    reference operator[](int index)
+    {
+      return buffer[index];
+    }
+    
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element at index
+     */
+    const_reference at(int index) const 
+    { 
+      if (index >= 0 && index < N)
+	return buffer[index];
+      else
+	throw JIndexOutOfRange("JArray<>::at()");
+    }
+    
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element at index
+     */
+    reference at(int index)
+    { 
+      if (index >= 0 && index < N)
+	return buffer[index];
+      else
+	throw JIndexOutOfRange("JArray<>::at()");
+    }
+
+
+    /**
+     * Get pointer to data.
+     *
+     * \return                  pointer to data
+     */
+    const_pointer data() const 
+    { 
+      return buffer;
+    }
+
+
+    /**
+     * Get pointer to data.
+     *
+     * \return                  pointer to data
+     */
+    pointer data()
+    { 
+      return buffer;
+    }
+
+
+    /**
+     * Get size of data.
+     *
+     * \return                  size of data
+     */
+    static size_type size()
+    { 
+      return N;
+    }
+
+
+    /**
+     * Make a copy in which the first element is removed.
+     *
+     * \return                  array
+     */
+    JArray<N-1, T> pop_front() const
+    {
+      return JArray<N-1, T>(&buffer[1]);
+    }
+
+
+    /**
+     * Make a copy in which the last element is removed.
+     *
+     * \return                  array
+     */
+    JArray<N-1, T> pop_back() const
+    {
+      return JArray<N-1, T>(buffer);
+    }
+
+
+    /**
+     * Negate array.
+     *
+     * \return                  this array
+     */
+    JArray& negate()
+    {
+      for (int i = 0; i != N; ++i) {
+	buffer[i] = -buffer[i];
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Add array.
+     *
+     * \param  array            array
+     * \return                  this array
+     */
+    JArray& add(const JArray& array)
+    {
+      for (int i = 0; i != N; ++i) {
+	buffer[i] += array[i];
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Subtract array.
+     *
+     * \param  array            array
+     * \return                  this array
+     */
+    JArray& sub(const JArray& array)
+    {
+      for (int i = 0; i != N; ++i) {
+	buffer[i] -= array[i];
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Scale array.
+     *
+     * \param  factor           multiplication factor
+     * \return                  this array
+     */
+    JArray& mul(const double factor)
+    {
+      for (int i = 0; i != N; ++i) {
+	buffer[i] *= factor;
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Scale array.
+     *
+     * \param  factor           division factor
+     * \return                  this array
+     */
+    JArray& div(const double factor)
+    {
+      for (int i = 0; i != N; ++i) {
+	buffer[i] /= factor;
+      }
+
+      return *this;
+    }
+
+
+    /** 
+     * Check equality.
+     *
+     * \param  array            array
+     * \return                  true if arrays are equal; else false
+     */
+    bool equals(const JArray<N, T>& array) const
+    {
+      for (int i = 0; i != N; ++i) {
+	if (buffer[i] != array[i]) {
+	  return false;
+	}
+      }
+
+      return true;
+    }
+
+
+    /**
+     * Read array from input stream.
+     *
+     * \param  in               input stream
+     * \param  array            array
+     * \return                  input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JArray& array)
+    {
+      for (iterator i = array.begin(); i != array.end(); ++i) {
+	in >> *i;
+      }
+
+      return in;
+    }
+
+
+    /**
+     * Write array to output stream.
+     *
+     * \param  out              output stream
+     * \param  array            array
+     * \return                  output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JArray& array)
+    {
+      for (const_iterator i = array.begin(); i != array.end(); ++i) {
+	out << ' ' << SCIENTIFIC(12,5) << *i;
+      }
+
+      return out;
+    }
+
+
+    /**
+     * Read array from input.
+     *
+     * \param  in               reader
+     * \param  buffer           array
+     * \return                  reader
+     */
+    friend inline JReader& operator>>(JReader& in, JArray& buffer)
+    {
+      for (iterator i = buffer.begin(); i != buffer.end(); ++i) {
+        in >> *i;
+      }
+
+      return in;
+    }
+
+
+    /**
+     * Write array to output.
+     *
+     * \param  out              writer
+     * \param  buffer           array
+     * \return                  writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JArray& buffer)
+    {
+      for (const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
+        out << *i;
+      }
+
+      return out;
+    }
+
+  protected:
+
+    T buffer[N];
+
+
+    /**
+     * Recursive method for setting array.
+     *
+     * \param  i                index
+     * \param  x                value at given index
+     * \param  args             remaining values
+     */
+    template<class ...Args>
+    void __set__(const int i, const argument_type x, const Args& ...args)
+    {
+      this->buffer[i] = x;
+
+      __set__(i + 1, args...);
+    }
+
+
+    /**
+     * Termination method for setting array.
+     *
+     * \param  i                index
+     */
+    void __set__(const int i) const
+    {}
+
+
+    /**
+     * Recursive method for setting array.
+     *
+     * \param  key              multi-dimensional key
+     */
+    template<unsigned int M>
+    void assign(const JMultiKey<M, T>& key)
+    {
+      buffer[N-M] = key.first;
+
+      assign(key.second);
+    }
+
+
+    /**
+     * Recursive method for setting array.
+     *
+     * \param  key              multi-dimensional key
+     */
+    template<unsigned int M>
+    void assign(const JMultiKey<M, const T>& key)
+    {
+      buffer[N-M] = key.first;
+
+      assign(key.second);
+    }
+
+
+    /**
+     * Termination method for setting array.
+     *
+     * \param  key              one-dimensional key
+     */
+    void assign(const JMultiKey<1, T>& key)
+    {
+      buffer[N-1] = key.first;
+    }
+
+
+    /**
+     * Termination method for setting array.
+     *
+     * \param  key              one-dimensional key
+     */
+    void assign(const JMultiKey<1, const T>& key)
+    {
+      buffer[N-1] = key.first;
+    }
+
+
+    /**
+     * Recursive method for setting array.
+     *
+     * \param  key              multi-dimensional key
+     * \param  value            value
+     */
+    template<unsigned int M>
+    void assign(const JMultiKey<M, T>& key, argument_type value)
+    {
+      buffer[N-M-1] = key.first;
+
+      assign(key.second, value);
+    }
+
+
+    /**
+     * Recursive method for setting array.
+     *
+     * \param  key              multi-dimensional key
+     * \param  value            value
+     */
+    template<unsigned int M>
+    void assign(const JMultiKey<M, const T>& key, argument_type value)
+    {
+      buffer[N-M-1] = key.first;
+
+      assign(key.second, value);
+    }
+
+
+    /**
+     * Termination method for setting array.
+     *
+     * \param  key              one-dimensional key
+     * \param  value            value
+     */
+    void assign(const JMultiKey<1, T>& key, argument_type value)
+    {
+      buffer[N-2] = key.first;
+      buffer[N-1] = value;
+    }
+
+
+    /**
+     * Termination method for setting array.
+     *
+     * \param  key              one-dimensional key
+     * \param  value            value
+     */
+    void assign(const JMultiKey<1, const T>& key, argument_type value)
+    {
+      buffer[N-2] = key.first;
+      buffer[N-1] = value;
+    }
+  };
+
+
+  /**
+   * One dimensional array of template objects with fixed length.
+   * The internal data structure consists of a standard C-array.
+   */
+  template<class T>
+  class JArray<1, T> :
+    public JMath  < JArray<1,T> >,
+    public JEquals< JArray<1,T> >
+  {
+  public:
+
+    static const unsigned int N = 1;
+
+    typedef  const T*                                      const_pointer;
+    typedef  T*                                            pointer;
+    typedef  const T*                                      const_iterator;
+    typedef  T*                                            iterator;
+    typedef  std::reverse_iterator<const_iterator>         const_reverse_iterator;
+    typedef  std::reverse_iterator<iterator>               reverse_iterator;
+    typedef  T&                                            reference;
+    typedef  const T&                                      const_reference;
+    typedef  unsigned int                                  size_type;
+    typedef  typename JLANG::JClass<T>::argument_type      argument_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JArray()
+    {}
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  array            array
+     */
+    template<unsigned int M>
+    JArray(const JArray<M, T>& array)
+    {
+      buffer[0] = array[0];
+    }
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  array            array
+     */
+    template<unsigned int M>
+    JArray(const JArray<M, const T>& array)
+    {
+      buffer[0] = array[0];
+    }
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  p                pointer to data
+     */
+    JArray(const T* p)
+    {
+      buffer[0] = p[0];
+    }
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  key              multi-dimensional key
+     */
+    JArray(const JMultiKey<1, T>& key)
+    {
+      buffer[0] = key.first;
+    }
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  key              multi-dimensional key
+     */
+    JArray(const JMultiKey<1, const T>& key)
+    {
+      buffer[0] = key.first;
+    }
+
+
+    /**
+     * Initialise constructor.
+     *
+     * \param  x                value;
+     */
+    JArray(argument_type x)
+    {
+      buffer[0] = x;
+    }
+
+
+    const_iterator begin() const { return buffer; }                                    //!< get iterator to begin of data
+    const_iterator end()   const { return buffer + N; }                                //!< get iterator to end   of data
+
+
+    iterator begin() { return buffer; }                                                //!< get iterator to begin of data
+    iterator end()   { return buffer + N; }                                            //!< get iterator to end   of data
+
+
+    const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }    //!< get reverse iterator to begin of data 
+    const_reverse_iterator rend()   const { return const_reverse_iterator(begin()); }  //!< get reverse iterator to begin of data 
+
+
+    reverse_iterator rbegin() { return reverse_iterator(end()); }                      //!< get reverse iterator to begin of data 
+    reverse_iterator rend()   { return reverse_iterator(begin()); }                    //!< get reverse iterator to end   of data 
+
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element
+     */
+    const_reference operator[](int index) const
+    { 
+      return buffer[index];
+    }
+
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element
+     */
+    reference operator[](int index)
+    {
+      return buffer[index];
+    }
+    
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element at index
+     */
+    const_reference at(int index) const 
+    { 
+      if (index >= 0 && index < N)
+	return buffer[index];
+      else
+	throw JIndexOutOfRange("JArray<>::at()");
+    }
+    
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element at index
+     */
+    reference at(int index)
+    { 
+      if (index >= 0 && index < N)
+	return buffer[index];
+      else
+	throw JIndexOutOfRange("JArray<>::at()");
+    }
+
+
+    /**
+     * Get pointer to data.
+     *
+     * \return                  pointer to data
+     */
+    const_pointer data() const 
+    { 
+      return buffer;
+    }
+
+
+    /**
+     * Get pointer to data.
+     *
+     * \return                  pointer to data
+     */
+    pointer data()
+    { 
+      return buffer;
+    }
+
+
+    /**
+     * Get size of data.
+     *
+     * \return                  size of data
+     */
+    static size_type size()
+    { 
+      return N;
+    }
+
+
+    /**
+     * Negate array.
+     *
+     * \return                  this array
+     */
+    JArray& negate()
+    {
+      buffer[0] = -buffer[0];
+
+      return *this;
+    }
+
+
+    /**
+     * Add array.
+     *
+     * \param  array            array
+     * \return                  this array
+     */
+    JArray& add(const JArray& array)
+    {
+      buffer[0] += array[0];
+
+      return *this;
+    }
+
+
+    /**
+     * Subtract array.
+     *
+     * \param  array            array
+     * \return                  this array
+     */
+    JArray& sub(const JArray& array)
+    {
+      buffer[0] -= array[0];
+
+      return *this;
+    }
+
+
+    /**
+     * Scale array.
+     *
+     * \param  factor           multiplication factor
+     * \return                  this array
+     */
+    JArray& mul(const double factor)
+    {
+      buffer[0] *= factor;
+
+      return *this;
+    }
+
+
+    /**
+     * Scale array.
+     *
+     * \param  factor           division factor
+     * \return                  this array
+     */
+    JArray& div(const double factor)
+    {
+      buffer[0] /= factor;
+
+      return *this;
+    }
+
+
+    /** 
+     * Check equality.
+     *
+     * \param  array            array
+     * \return                  true if arrays are equal; else false
+     */
+    bool equals(const JArray<N, T>& array) const
+    {
+      return buffer[0] == array[0];
+    }
+
+
+    /**
+     * Read array from input stream.
+     *
+     * \param  in               input stream
+     * \param  array            array
+     * \return                  input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JArray& array)
+    {
+      for (iterator i = array.begin(); i != array.end(); ++i) {
+	in >> *i;
+      }
+
+      return in;
+    }
+
+
+    /**
+     * Write array to output stream.
+     *
+     * \param  out              output stream
+     * \param  array            array
+     * \return                  output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JArray& array)
+    {
+      for (const_iterator i = array.begin(); i != array.end(); ++i) {
+	out << ' ' << SCIENTIFIC(12,5) << *i;
+      }
+
+      return out;
+    }
+
+
+    /**
+     * Read array from input.
+     *
+     * \param  in               reader
+     * \param  buffer           array
+     * \return                  reader
+     */
+    friend inline JReader& operator>>(JReader& in, JArray& buffer)
+    {
+      return in >> buffer[0];
+    }
+
+
+    /**
+     * Write array to output.
+     *
+     * \param  out              writer
+     * \param  buffer           array
+     * \return                  writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JArray& buffer)
+    {
+      return out << buffer[0];
+    }
+
+  protected:
+    T buffer[1];
+  };
+
+
+  /**
+   * One dimensional read-only array of template objects with fixed length.
+   * The internal data structure consists of a simple C-pointer to the actual data.
+   * The user should ensure that the data are persistent.
+   */ 
+  template<unsigned int N, class T>
+  class JArray<N, const T> {
+  public:
+
+    friend class JArray<N + 1, const T>;
+
+    typedef  const T*                               const_pointer;
+    typedef  const T*                               const_iterator;
+    typedef  std::reverse_iterator<const_iterator>  const_reverse_iterator;
+    typedef  const T&                               const_reference;
+    typedef  unsigned int                           size_type;
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  array            array
+     */
+    template<unsigned int M>
+    JArray(const JArray<M, T>& array) :
+      p(array.data())
+    {
+      STATIC_CHECK(M >= N);
+    }
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  array            array
+     */
+    template<unsigned int M>
+    JArray(const JArray<M, const T>& array) :
+      p(array.data())
+    {
+      STATIC_CHECK(M >= N);
+    }
+
+
+    const_iterator begin() const { return p; }                                         //!< get iterator to begin of data
+    const_iterator end()   const { return p + N; }                                     //!< get iterator to end   of data
+
+
+    const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }    //!< get reverse iterator to begin of data 
+    const_reverse_iterator rend()   const { return const_reverse_iterator(begin()); }  //!< get reverse iterator to end   of data 
+
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element at index
+     */
+    const_reference operator[](int index) const
+    {
+      return p[index];
+    }
+    
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element at index
+     */
+    const_reference at(int index) const 
+    { 
+      if (index >= 0 && index < N)
+	return p[index];
+      else
+	throw JIndexOutOfRange("JArray<>::at()");
+    }
+
+
+    /**
+     * Get pointer to data.
+     *
+     * \return                  pointer to data
+     */
+    const_pointer data() const 
+    { 
+      return p;
+    }
+    
+
+    /**
+     * Get size of data.
+     *
+     * \return                  size of data
+     */
+    static size_type size()
+    { 
+      return N;
+    }
+
+
+    /**
+     * Make a copy in which the first element is removed.
+     *
+     * \return                  array
+     */
+    JArray<N-1, const T> pop_front() const
+    {
+      return JArray<N-1, const T>(p + 1);
+    }
+
+
+    /**
+     * Make a copy in which the last element is removed.
+     *
+     * \return                  array
+     */
+    JArray<N-1, const T> pop_back() const
+    {
+      return JArray<N-1, const T>(p);
+    }
+
+
+    /**
+     * Write array to output.
+     *
+     * \param  out              writer
+     * \param  buffer           array
+     * \return                  writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JArray& buffer)
+    {
+      for (const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
+        out << *i;
+      }
+
+      return out;
+    }
+
+  protected:
+
+    const_pointer p;
+
+    /**
+     * Constructor.
+     *
+     * \param  __p              pointer to data
+     */
+    JArray(const T* __p) :
+      p(__p)
+    {}
+  };
+
+
+  /**
+   * One dimensional read-only array of template objects with fixed length.
+   * The internal data structure consists of a simple C-pointer to the actual data.
+   * The user should ensure that the data are persistent.
+   */ 
+  template<class T>
+  class JArray<1, const T> {
+  public:
+
+    static const unsigned int N = 1;
+
+    friend class JArray<N + 1, const T>;
+
+    typedef  const T*                               const_pointer;
+    typedef  const T*                               const_iterator;
+    typedef  std::reverse_iterator<const_iterator>  const_reverse_iterator;
+    typedef  const T&                               const_reference;
+    typedef  unsigned int                           size_type;
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  array            array
+     */
+    template<unsigned int M>
+    JArray(const JArray<M, T>& array) :
+      p(array.data())
+    {
+      STATIC_CHECK(M >= N);
+    }
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param  array            array
+     */
+    template<unsigned int M>
+    JArray(const JArray<M, const T>& array) :
+      p(array.data())
+    {
+      STATIC_CHECK(M >= N);
+    }
+
+
+    const_iterator begin() const { return p; }                                         //!< get iterator to begin of data
+    const_iterator end()   const { return p + N; }                                     //!< get iterator to end   of data
+
+
+    const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }    //!< get reverse iterator to begin of data 
+    const_reverse_iterator rend()   const { return const_reverse_iterator(begin()); }  //!< get reverse iterator to end   of data 
+
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element at index
+     */
+    const_reference operator[](int index) const
+    {
+      return p[index];
+    }
+    
+
+    /**
+     * Get element at given index.
+     *
+     * \param  index            index
+     * \return                  element at index
+     */
+    const_reference at(int index) const 
+    { 
+      if (index >= 0 && index < N)
+	return p[index];
+      else
+	throw JIndexOutOfRange("JArray<>::at()");
+    }
+
+
+    /**
+     * Get pointer to data.
+     *
+     * \return                  pointer to data
+     */
+    const_pointer data() const 
+    { 
+      return p;
+    }
+    
+
+    /**
+     * Get size of data.
+     *
+     * \return                  size of data
+     */
+    static size_type size()
+    { 
+      return N;
+    }
+
+
+    /**
+     * Write array to output.
+     *
+     * \param  out              writer
+     * \param  buffer           array
+     * \return                  writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JArray& buffer)
+    {
+      return out << buffer[0];
+    }
+
+  protected:
+
+    const_pointer p;
+
+    /**
+     * Constructor.
+     *
+     * \param  __p              pointer to data
+     */
+    JArray(const T* __p) :
+      p(__p)
+    {}
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JAssembler.hh b/jpp/JTools/JAssembler.hh
new file mode 100644
index 0000000..25768e3
--- /dev/null
+++ b/jpp/JTools/JAssembler.hh
@@ -0,0 +1,40 @@
+#ifndef __JTOOLS__JASSEMBLER__
+#define __JTOOLS__JASSEMBLER__
+
+#include "JLang/JVoid.hh"
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JVoid;
+  
+  
+  /**
+   * Auxiliary class to check whether given template is a collection,
+   * i.e.\ has a defined type <tt>collection_type</tt>.
+   */
+  template<class T, class JType_t = void>
+  struct JAssembler
+  {
+    static const bool is_collection = false;
+  };
+
+  
+  /**
+   * Template specialisation of class JAssembler for classes
+   * with a defined type <tt>collection_type</tt>.
+   */
+  template<class T>
+  struct JAssembler<T, typename JVoid<typename T::collection_type>::type>
+  {
+    static const bool is_collection = true;
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JCollection.hh b/jpp/JTools/JCollection.hh
new file mode 100644
index 0000000..a366cc3
--- /dev/null
+++ b/jpp/JTools/JCollection.hh
@@ -0,0 +1,836 @@
+#ifndef __JTOOLS__JCOLLECTION__
+#define __JTOOLS__JCOLLECTION__
+
+#include <vector>
+#include <cmath>
+#include <limits>
+#include <algorithm>
+
+#include "JLang/JClass.hh"
+#include "JLang/JException.hh"
+#include "JLang/JLangToolkit.hh"
+#include "JMath/JZero.hh"
+#include "JMath/JMath.hh"
+#include "JIO/JSerialisable.hh"
+#include "JTools/JDistance.hh"
+#include "JTools/JTransformer.hh"
+#include "JTools/JMappableCollection.hh"
+#include "JTools/JAbstractCollection.hh"
+
+/**
+ * \file
+ *
+ * General purpose class for a collection of sorted elements.
+ * \author mdejong
+ */
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JMATH::JMath;
+  using JIO::JReader;
+  using JIO::JWriter;
+  using JLANG::JValueOutOfRange;
+  using JLANG::JClass;
+  using JLANG::JException;
+  
+
+  /**
+   * General purpose class for collection of elements, see:
+   \htmlonly
+   <a href="JTools.PDF";>Collection of elements.</a>
+   \endhtmlonly
+   *
+   * This class implements the JMappableCollection and JAbstractCollection interfaces.
+   *
+   * The data type of the elements of the collection should have the following policy
+   * type definition and member methods.
+   * <pre>
+   *    typedef \<abscissa type\>   abscissa_type;
+   *    typedef \<ordinate type\>   ordinate_type;
+   *
+   *    (constructor)(abscissa_type, ordinate_type);
+   *
+   *    abscissa_type  %getX() const;
+   *    ordinate_type  %getY() const;
+   *    ordinate_type& %getY();
+   * </pre>
+   *
+   * The elements in a collection are sorted according to their abscissa values and 
+   * the given distance operator.
+   * The distance operator constitues a binary method returning the distance between
+   * two abscissa values; The default distance operator is JDistance.
+   *
+   * For the binary I/O of a collection of elements, the data structure of the elements
+   * should provide for an implementation of the following operators:
+   * <pre>
+   *       JReader& operator>>(JReader& in);
+   *       JWriter& operator<<(JWriter& out);
+   * </pre>
+   */
+  template<class JElement_t, class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  class JCollection :
+    public std::vector<JElement_t>,
+    public JMappableCollection<typename JElement_t::abscissa_type, 
+			       typename JElement_t::ordinate_type>,
+    public JAbstractCollection<typename JElement_t::abscissa_type>,
+    public JMath< JCollection<JElement_t, JDistance_t> >
+  {
+  public:
+
+    typedef typename JElement_t::abscissa_type                   abscissa_type;
+    typedef typename JElement_t::ordinate_type                   ordinate_type;
+    typedef JElement_t                                           value_type;
+    typedef JDistance_t                                          distance_type;
+
+    typedef JCollection<JElement_t, JDistance_t>                 collection_type;
+    
+    typedef std::vector<value_type>                              container_type;
+
+    typedef typename container_type::const_iterator              const_iterator;
+    typedef typename container_type::const_reverse_iterator      const_reverse_iterator;
+    typedef typename container_type::iterator                    iterator;
+    typedef typename container_type::reverse_iterator            reverse_iterator;
+
+    typedef JCollectionElementTransformer<value_type>            transformer_type;
+    typedef std::pair<const_iterator, bool>                      pair_type;
+
+    using JMappableCollection<abscissa_type, ordinate_type>::operator[];
+
+
+    /**
+     * Auxiliary class for ordering of objects in the collection by their abscissa values.
+     */
+    struct JComparator {
+      /**
+       * Comparison of elements.
+       *
+       * \param  first           first  element
+       * \param  second          second element
+       * \return                 true if first element less than second element; else false
+       */
+      inline bool operator()(const JElement_t& first, 
+			     const JElement_t& second) const
+      {
+	return this->getDistance(first.getX(), second.getX()) > 0.0;
+      }
+      
+      
+      /**
+       * Comparison of element and abscissa value.
+       *
+       * \param  element         element
+       * \param  x               abscissa value
+       * \return                 true if element less than abscissa value; else false
+       */
+      inline bool operator()(const JElement_t& element, typename JClass<abscissa_type>::argument_type x) const
+      {
+	return this->getDistance(element.getX(), x) > 0.0;
+      }
+
+
+      /**
+       * Function object for distance evaluation.
+       */
+      JDistance_t getDistance;
+    };
+
+
+    /**
+     * Default constructor.
+     */
+    JCollection()
+    {}
+
+
+    /**
+     * Clear.
+     */
+    virtual void clear() override 
+    {
+      container_type::clear();
+    }
+
+
+    /**
+     * Get ordinate value.
+     *
+     * \param  x               abscissa value
+     * \return                 ordinate value
+     */
+    virtual const ordinate_type& get(typename JClass<abscissa_type>::argument_type x) const override 
+    {
+      const_iterator i = this->lower_bound(x);
+
+      if (i == this->end() || this->getDistance(x, i->getX()) > distance_type::precision) {
+	THROW(JValueOutOfRange, "Invalid abscissa value " << x);
+      }
+
+      return i->getY();
+    }
+
+
+    /**
+     * Get ordinate value.
+     *
+     * \param  x               abscissa value
+     * \return                 ordinate value
+     */
+    virtual ordinate_type& get(typename JClass<abscissa_type>::argument_type x) override 
+    {
+      iterator i = this->lower_bound(x);
+
+      if (i == this->end() || this->getDistance(x, i->getX()) > distance_type::precision) {
+        i = container_type::insert(i, value_type(x, ordinate_type()));
+      }
+
+      return i->getY();
+    }
+
+
+    /**
+     * Get number of elements.
+     *
+     * \return                 number of elements
+     */
+    virtual int getSize() const override 
+    {
+      return (int) this->size();
+    }
+
+
+    /**
+     * Get abscissa value.
+     *
+     * \param  index           index
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getX(int index) const override 
+    {
+      return this->at(index).getX();
+    }
+
+
+    /**
+     * Get minimal abscissa value.
+     *
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getXmin() const override 
+    {
+      return this->begin()->getX();
+    }
+
+
+    /**
+     * Get maximal abscissa value.
+     *
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getXmax() const override 
+    {
+      return this->rbegin()->getX();
+    }
+
+
+
+    /**
+     * Get ordinate value.
+     *
+     * \param  index           index
+     * \return                 ordinate value
+     */
+    const ordinate_type& getY(int index) const
+    {
+      return this->at(index).getY();
+    }
+
+
+    /**
+     * Get ordinate value.
+     *
+     * \param  index           index
+     * \return                 ordinate value
+     */
+    ordinate_type& getY(int index) 
+    {
+      return this->at(index).getY();
+    }
+
+
+    /**
+     * Transform collection.
+     *
+     * \param  transformer     element transformer
+     */
+    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));
+      }
+    }
+
+
+    /**
+     * Sort elements.
+     */
+    void sort()
+    {
+      std::sort(this->begin(), this->end(), compare);
+    }
+
+
+    /**
+     * Get first position of element <tt>i</tt>, where <tt>x >= i->getX()</tt>.
+     *
+     * \param  x               abscissa value
+     * \return                 position of corresponding element
+     */
+    const_iterator lower_bound(typename JClass<abscissa_type>::argument_type x) const
+    {
+      return std::lower_bound(this->begin(), this->end(), x, compare);
+    }
+
+
+    /**
+     * Get first position of element <tt>i</tt>, where <tt>x >= i->getX()</tt>.
+     *
+     * \param  x               abscissa value
+     * \return                 position of corresponding element
+     */
+    iterator lower_bound(typename JClass<abscissa_type>::argument_type x) 
+    {
+      return std::lower_bound(this->begin(), this->end(), x, compare);
+    }
+
+
+    /**
+     * Insert element.
+     *
+     * \param  element         element
+     * \return                 (iterator, status), where status is true if inserted; else false
+     */
+    pair_type insert(const value_type& element)
+    {
+      iterator i = this->lower_bound(element.getX());
+
+      if (i == this->end() || this->getDistance(element.getX(), i->getX()) > 0.0)
+        return pair_type(container_type::insert(i, element), true);
+      else
+        return pair_type(this->end(), false);
+    }
+
+    
+    /**
+     * Configure collection.
+     *
+     * \param  bounds          abscissa values
+     */
+    void configure(const JAbstractCollection<abscissa_type>& bounds)
+    {
+      configure(bounds, JMATH::getZero<ordinate_type>());
+    }
+
+
+    /**
+     * Configure collection.
+     *
+     * \param  bounds          abscissa values
+     * \param  value           ordinate value
+     */
+    void configure(const JAbstractCollection<abscissa_type>&     bounds,
+		   typename JClass<ordinate_type>::argument_type value)
+    {
+      this->resize(bounds.getSize());
+
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+
+	const abscissa_type x = bounds.getX(std::distance(this->begin(),i));
+
+	*i = value_type(x,value);
+      }
+    }
+
+
+    /**
+     * Configure collection.
+     *
+     * \param  bounds          abscissa values
+     * \param  function        function
+     */
+    template<class JFunction1D_t>
+    void configure(const JAbstractCollection<abscissa_type>& bounds, 
+		   const JFunction1D_t&                      function)
+    {
+      using namespace JLANG;
+
+      collection_type* out = (is_identical(*this, function) ? new collection_type() : this);
+
+      for (int i = 0; i != bounds.getSize(); ++i) {
+
+	const abscissa_type x = bounds.getX(i);
+
+	out->put(x, function(x));
+      }
+
+      if (is_identical(*this, function)) {
+	
+	this->swap(*out);
+
+	delete out;
+      }
+    }
+
+
+    /**
+     * Test whether collections are compatible.
+     *
+     * \param  collection      collection
+     * \return                 true if collections are compatible; else false
+     */
+    bool is_compatible(const JCollection& collection) const
+    {
+      if (this->empty() || collection.empty()) {
+
+	return true;
+
+      } else {
+
+	const double precision = JDistance<abscissa_type>::precision;
+	
+	const_iterator p = this->begin();
+	const_iterator q = collection.begin();
+	
+	if        (getDistance(p->getX(), q->getX()) > precision) { 
+
+	  do { 
+	    ++p; 
+	  } while (p != this->end()      && getDistance(p->getX(), q->getX()) > precision); 
+
+	} else if (getDistance(q->getX(), p->getX()) > precision) { 
+
+	  do { 
+	    ++q; 
+	  } while (q != collection.end() && getDistance(q->getX(), p->getX()) > precision); 
+	}
+
+	for ( ; p != this->end() && q != collection.end(); ++p, ++q) {
+	  if (fabs(getDistance(p->getX(), q->getX())) > precision) {
+	    return false;
+	  }
+	}
+
+	return true;
+      }
+    }
+
+
+    /**
+     * Negate collection.
+     *
+     * \return                 this collection
+     */
+    JCollection& negate()
+    {
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	i->getY() = -i->getY();
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Add collection.
+     *
+     * \param  collection      collection
+     * \return                 this collection
+     */
+    JCollection& add(const JCollection& collection)
+    {
+      if (!collection.empty()) {
+
+	if (this->empty()) {
+
+	  for (const_iterator i = collection.begin(); i != collection.end(); ++i) {
+	    this->put(i->getX(), +i->getY());
+	  }
+
+	} else if (this->is_compatible(collection)) {
+
+	  const double precision = JDistance<abscissa_type>::precision;
+
+	  iterator       p = this->begin();
+	  const_iterator q = collection.begin();
+
+	  if        (getDistance(p->getX(), q->getX()) > precision) { 
+
+	    do {
+	      ++p; 
+	    } while (p != this->end()      && getDistance(p->getX(), q->getX()) > precision); 
+
+	  } else if (getDistance(q->getX(), p->getX()) > precision) { 
+
+	    do { 
+	      ++q; 
+	    } while (q != collection.end() && getDistance(q->getX(), p->getX()) > precision); 
+	  }
+
+	  const_iterator i = q;
+
+	  for ( ; p != this->end() && i != collection.end(); ++p, ++i) {
+	    p->getY() += i->getY();
+	  }
+
+	  for ( ; i != collection.end(); ++i) {
+	    this->put(i->getX(), +i->getY());
+	  }
+
+	  for (i = collection.begin(); i != q; ++i) {
+	    this->put(i->getX(), +i->getY());
+	  }
+	}
+      }
+      
+      return *this;
+    }
+
+
+    /**
+     * Subtract collection.
+     *
+     * \param  collection      collection
+     * \return                 this collection
+     */
+    JCollection& sub(const JCollection& collection)
+    {
+      if (!collection.empty()) {
+
+	if (this->empty()) {
+
+	  for (const_iterator i = collection.begin(); i != collection.end(); ++i) {
+	    this->put(i->getX(), -i->getY());
+	  }
+
+	} else if (this->is_compatible(collection)) {
+
+	  const double precision = JDistance<abscissa_type>::precision;
+
+	  iterator       p = this->begin();
+	  const_iterator q = collection.begin();
+
+	  if        (getDistance(p->getX(), q->getX()) > precision) { 
+
+	    do {
+	      ++p; 
+	    } while (p != this->end()      && getDistance(p->getX(), q->getX()) > precision); 
+
+	  } else if (getDistance(q->getX(), p->getX()) > precision) { 
+
+	    do { 
+	      ++q; 
+	    } while (q != collection.end() && getDistance(q->getX(), p->getX()) > precision); 
+	  }
+
+	  const_iterator i = q;
+
+	  for ( ; p != this->end() && i != collection.end(); ++p, ++i) {
+	    p->getY() -= i->getY();
+	  }
+
+	  for ( ; i != collection.end(); ++i) {
+	    this->put(i->getX(), -i->getY());
+	  }
+
+	  for (i = collection.begin(); i != q; ++i) {
+	    this->put(i->getX(), -i->getY());
+	  }
+
+	} else {
+
+	  throw JException("JCollection::add() collections incompatible.");
+	}
+      }
+      
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           multiplication factor
+     * \return                 this collection
+     */
+    JCollection& mul(const double value)
+    {
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	i->getY() *= value;
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           division factor
+     * \return                 this collection
+     */
+    JCollection& div(const double value)
+    {
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	i->getY() /= value;
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Add offset.
+     *
+     * \param  value           offset
+     * \return                 this collection
+     */
+    JCollection& add(typename JClass<ordinate_type>::argument_type value)
+    {
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	i->getY() += value;
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Subtract offset.
+     *
+     * \param  value           offset
+     * \return                 this collection
+     */
+    JCollection& sub(typename JClass<ordinate_type>::argument_type value)
+    {
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	i->getY() -= value;
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Add function.
+     *
+     * \param  function        function
+     * \return                 this collection
+     */
+    template<class JFunction1D_t>
+    JCollection& add(const JFunction1D_t& function)
+    {
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	i->getY() += function(i->getX());
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Subtract function.
+     *
+     * \param  function        function
+     * \return                 this collection
+     */
+    template<class JFunction1D_t>
+    JCollection& sub(const JFunction1D_t& function)
+    {
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	i->getY() -= function(i->getX());
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Add offset to collaction.
+     *
+     * \param  collection      collection
+     * \param  value           offset
+     * \return                 collection
+     */
+    friend JCollection& operator+=(JCollection& collection, typename JClass<ordinate_type>::argument_type value)
+    {
+      return collection.add(value);
+    }
+
+
+    /**
+     * Subtract offset from collaction.
+     *
+     * \param  collection      collection
+     * \param  value           offset
+     * \return                 collection
+     */
+    friend JCollection& operator-=(JCollection& collection, typename JClass<ordinate_type>::argument_type value)
+    {
+      return collection.sub(value);
+    }
+ 
+
+    /**
+     * Add function.
+     *
+     * \param  collection      collection
+     * \param  function        function
+     * \return                 this collection
+     */
+    template<class JFunction1D_t>
+    friend JCollection& operator+=(JCollection& collection, const JFunction1D_t& function)
+    {
+      return collection.add(function);
+    }
+ 
+
+    /**
+     * Subtract function.
+     *
+     * \param  collection      collection
+     * \param  function        function
+     * \return                 this collection
+     */
+    template<class JFunction1D_t>
+    friend JCollection& operator-=(JCollection& collection, const JFunction1D_t& function)
+    {
+      return collection.sub(function);
+    }
+
+
+    /**
+     * Read collection from input.
+     *
+     * \param  in              reader
+     * \param  collection      collection
+     * \return                 reader
+     */
+    friend inline JReader& operator>>(JReader& in, JCollection& collection)
+    {
+      int n;
+
+      in >> n;
+
+      collection.resize(n);
+
+      for (typename JCollection::iterator i = collection.begin(); i != collection.end(); ++i) {
+        in >> *i;
+      }
+
+      return in;
+    }
+
+
+    /**
+     * Write collection to output.
+     *
+     * \param  out             writer
+     * \param  collection      collection
+     * \return                 writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JCollection& collection)
+    {
+      const int n = collection.size();
+
+      out << n;
+
+      for (typename JCollection::const_iterator i = collection.begin(); i != collection.end(); ++i) {
+        out << *i;
+      }
+
+      return out;
+    }
+
+
+    /**
+     * Get comparator.
+     *
+     * \return                 comparator
+     */
+    const JComparator& getComparator() const
+    {
+      return compare;
+    }
+
+
+    /**
+     * Function object for distance evaluation.
+     */
+    JDistance_t getDistance;
+
+
+  protected:
+    /**
+     * Function object for comparison.
+     */
+    JComparator compare;
+
+
+    /**
+     * Resize collection
+     *
+     * \param  size             size
+     */
+    void resize(typename container_type::size_type size)
+    {
+      container_type::resize(size);
+    }
+
+  private:
+    void erase();
+    void push_back();
+    void pop_back();
+  };
+
+
+  /**
+   * Conversion of data points to integral values.
+   *
+   * The integration is based on the trapezoidal rule applied to the input data points.
+   *
+   * \param  input             collection
+   * \param  output            mappable collection
+   * \return                   integral
+   */
+  template<class JElement_t,
+           class JDistance_t>
+  inline typename JElement_t::ordinate_type 
+  integrate(const JCollection<JElement_t, JDistance_t>& input, typename JMappable<JElement_t>::map_type& output)
+  {
+    typedef typename JElement_t::ordinate_type                             ordinate_type;
+    typedef typename JCollection<JElement_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 += 0.5 * input.getDistance(i->getX(), j->getX()) * (i->getY() + j->getY());
+
+        output.put(j->getX(), V);
+      }
+    }
+
+    return V;
+  }
+}
+
+#endif
diff --git a/jpp/JTools/JConstantFunction1D.hh b/jpp/JTools/JConstantFunction1D.hh
new file mode 100644
index 0000000..8ee9e14
--- /dev/null
+++ b/jpp/JTools/JConstantFunction1D.hh
@@ -0,0 +1,206 @@
+#ifndef __JCONSTANTFUNCTION1D__
+#define __JCONSTANTFUNCTION1D__
+
+#include "JIO/JSerialisable.hh"
+#include "JTools/JFunctional.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JIO::JReader;
+  using JIO::JWriter;
+
+  /**
+   * Template implementation of function object in one dimension returning a constant value.
+   *
+   * This class implements the JFunction1D interface.
+   */
+  template<class JArgument_t, class JResult_t>
+  class JConstantFunction1D : 
+    public JFunction1D<JArgument_t, JResult_t>
+  {
+  public:
+
+    typedef JFunction1D<JArgument_t, JResult_t>                         function_type;
+    typedef typename function_type::argument_type                       argument_type;
+    typedef typename function_type::result_type                         result_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JConstantFunction1D() :
+      function_type(),
+      __y()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  y               value
+     */
+    JConstantFunction1D(const result_type y) :
+      function_type(),
+      __y(y)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  y               zero
+     */
+    JConstantFunction1D(const JMATH::JZero& y) :
+      function_type(),
+      __y(y)
+    {}
+
+
+    /**
+     * Add offset.
+     *
+     * \param  value           offset
+     */
+    JConstantFunction1D& add(typename JLANG::JClass<result_type>::argument_type value)
+    {
+      __y += value;
+
+      return *this;
+    }
+
+
+    /**
+     * Subtract offset.
+     *
+     * \param  value            offset
+     */
+    JConstantFunction1D& sub(typename JLANG::JClass<result_type>::argument_type value)
+    {
+      __y -= value;
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           multiplication factor
+     */
+    JConstantFunction1D& mul(const double value)
+    {
+      __y *= value;
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           division factor
+     */
+    JConstantFunction1D& div(const double value)
+    {
+      __y /= value;
+
+      return *this;
+    }
+
+
+    /**
+     * Add function.
+     *
+     * \param  function        function
+     */
+    JConstantFunction1D& add(const JConstantFunction1D& function)
+    {
+      __y += function.getY();
+
+      return *this;
+    }
+
+
+    /**
+     * Subtract function.
+     *
+     * \param  function        function
+     */
+    JConstantFunction1D& sub(const JConstantFunction1D& function)
+    {
+      __y -= function.getY();
+
+      return *this;
+    }
+
+
+    /**
+     * Function value.
+     *
+     * \return                 function value
+     */
+    result_type getY() const 
+    {
+      return __y;
+    }
+
+
+    /**
+     * Function value evaluation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const override 
+    {
+      return __y;
+    }
+
+
+    /**
+     * Read function from input.
+     *
+     * \param  in              reader
+     * \param  function        function
+     * \return                 reader
+     */
+    friend inline JReader& operator>>(JReader& in, JConstantFunction1D& function)
+    {
+      return in >> function.__y;
+    }
+
+
+    /**
+     * Write function to output.
+     *
+     * \param  out             writer
+     * \param  function        function
+     * \return                 writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JConstantFunction1D& function)
+    {
+      return out << function.__y;
+    }
+
+
+  protected:
+    /**
+     * Function compilation.
+     */
+    virtual void do_compile() override 
+    {}
+
+  private:
+    result_type __y;
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JConstants.hh b/jpp/JTools/JConstants.hh
new file mode 100644
index 0000000..351227a
--- /dev/null
+++ b/jpp/JTools/JConstants.hh
@@ -0,0 +1,22 @@
+#ifndef __JTOOLS__JCONSTANTS__
+#define __JTOOLS__JCONSTANTS__
+
+#include <math.h>
+
+#include "JMath/JConstants.hh"
+
+/**
+ * \file
+ * Constants. 
+ * \author mdejong
+ */
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JMATH::PI;
+  using JMATH::EULER;
+}
+
+#endif
diff --git a/jpp/JTools/JDistance.hh b/jpp/JTools/JDistance.hh
new file mode 100644
index 0000000..8ba53f4
--- /dev/null
+++ b/jpp/JTools/JDistance.hh
@@ -0,0 +1,55 @@
+#ifndef __JTOOLS__JDISTANCE__
+#define __JTOOLS__JDISTANCE__
+
+#include <limits>
+
+#include "JLang/JClass.hh"
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  /**
+   * Template class for distance evaluation.
+   *
+   * This class should be specialised for data types when the distance
+   * between two values is not equal to the arithmetic minus operation.
+   */
+  template<class JAbscissa_t>
+  struct JDistance {
+
+    typedef typename JLANG::JClass<JAbscissa_t>::argument_type    argument_type;
+
+
+    /**
+     * Get distance between values.
+     *
+     * The distance should be negative, zero or positive if the first value
+     * is respectively larger, equal or smaller compared to the second value.
+     *
+     * \param  first           first  value
+     * \param  second          second value
+     * \return                 distance
+     */
+    inline double operator()(argument_type first, argument_type second) const
+    {
+      return second - first;
+    }
+
+    static double precision;
+  };
+
+
+  /**
+   * Default precision.
+   */
+  template<class JAbscissa_t>
+  double JDistance<JAbscissa_t>::precision = std::numeric_limits<double>::min();
+}
+
+#endif
diff --git a/jpp/JTools/JElement.hh b/jpp/JTools/JElement.hh
new file mode 100644
index 0000000..693a28d
--- /dev/null
+++ b/jpp/JTools/JElement.hh
@@ -0,0 +1,611 @@
+#ifndef __JTOOLS__JELEMENT__
+#define __JTOOLS__JELEMENT__
+
+#include <cmath>
+
+#include "JMath/JZero.hh"
+#include "JMath/JMath.hh"
+#include "JLang/JClass.hh"
+#include "JIO/JSerialisable.hh"
+
+
+/**
+ * \file
+ *
+ * The elements in a collection are sorted according to their abscissa values and a given distance operator.
+ * These elements should have the following type definitions and member methods:
+ * <pre>
+ *       typedef  \<abscissa type\>    abscissa_type;
+ *       typedef  \<ordinate type\>    ordinate_type;
+ *
+ *       constructor();
+ *       constructor(abscissa_type, ordinate_type);
+ *
+ *       abscissa_type        getX() const;
+ *       const ordinate_type& getY() const;
+ *       ordinate_type&       getY();
+ * </pre>
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JIO::JReader;
+  using JIO::JWriter;
+  using JMATH::JMath;
+  using JMATH::getZero;
+
+
+  /**
+   * 2D Element.
+   */
+  template<class JAbscissa_t, class JOrdinate_t>
+  struct JElement2D {
+
+    typedef JAbscissa_t                                          abscissa_type;
+    typedef JOrdinate_t                                          ordinate_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JElement2D() :
+      __x(getZero<abscissa_type>()),
+      __y(getZero<ordinate_type>())
+    {}
+    
+
+    /**
+     * Constructor.
+     *
+     * \param  x               abscissa value
+     * \param  y               ordinate value
+     */
+    JElement2D(typename JLANG::JClass<abscissa_type>::argument_type x,
+	       typename JLANG::JClass<ordinate_type>::argument_type y) :
+      __x(x),
+      __y(y)
+    {}
+    
+    
+    /**
+     * Get abscissa value.
+     *
+     * \return                 abscissa value
+     */
+    abscissa_type getX() const 
+    { 
+      return __x;
+    }
+    
+    
+    /**
+     * Get ordinate value.
+     *
+     * \return                 ordinate value
+     */
+    const ordinate_type& getY() const 
+    { 
+      return __y;
+    }
+    
+    
+    /**
+     * Get ordinate value.
+     *
+     * \return                 ordinate value
+     */
+    ordinate_type& getY()
+    { 
+      return __y;
+    }
+
+
+    /**
+     * Read element from input.
+     *
+     * \param  in              reader
+     * \param  element         element
+     * \return                 reader
+     */
+    friend inline JReader& operator>>(JReader& in, JElement2D& element)
+    {
+      in >> element.__x;
+      in >> element.__y;
+
+      return in;
+    }
+
+
+    /**
+     * Write element to output.
+     *
+     * \param  out             writer
+     * \param  element         element
+     * \return                 writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JElement2D& element)
+    {
+      out << element.__x;
+      out << element.__y;
+
+      return out;
+    }
+
+
+  protected:    
+    abscissa_type __x;
+    ordinate_type __y;
+  };
+
+
+  /**
+   * 2D Element for spline interpolations.
+   *
+   * Note that the internal data members needed for the calculation
+   * of the 2nd derivatives are not subject to I/O, i.e.\ the I/O of 
+   * this class is identical to that of the JElement2D class.
+   */
+  template<class JAbscissa_t, class JOrdinate_t>
+  struct JSplineElement2D :
+    public JElement2D<JAbscissa_t, JOrdinate_t>
+  {
+
+    typedef JElement2D<JAbscissa_t, JOrdinate_t>                 element_type;
+    typedef typename element_type::abscissa_type                 abscissa_type;
+    typedef typename element_type::ordinate_type                 ordinate_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JSplineElement2D() :
+      element_type(),
+      __u(getZero<ordinate_type>())
+    {}
+    
+
+    /**
+     * Constructor.
+     *
+     * \param  x               abscissa value
+     * \param  y               ordinate value
+     */
+    JSplineElement2D(typename JLANG::JClass<abscissa_type>::argument_type x,
+		     typename JLANG::JClass<ordinate_type>::argument_type y) :
+      element_type(x, y),
+      __u(getZero<ordinate_type>())
+    {}
+
+
+    /**
+     * Get derivative.
+     *
+     * \return                 derivative
+     */
+    ordinate_type getU() const
+    { 
+      return __u;
+    }
+
+
+    /**
+     * Set derivative.
+     *
+     * \param  u               derivative
+     */
+    void setU(typename JLANG::JClass<ordinate_type>::argument_type u)
+    { 
+      __u= u;
+    }
+
+
+  protected:    
+    ordinate_type __u;
+  };
+
+
+  /**
+   * 2D Element for spline interpolations.
+   *
+   * Note that the internal data members needed for the calculation
+   * of the integral values are not subject to I/O, i.e.\ the I/O of 
+   * this class is identical to that of the JElement2D class.
+   */
+  template<class JAbscissa_t, class JOrdinate_t>
+  struct JSplineElement2S :
+    public JSplineElement2D<JAbscissa_t, JOrdinate_t>
+  {
+
+    typedef JSplineElement2D<JAbscissa_t, JOrdinate_t>           element_type;
+    typedef typename element_type::abscissa_type                 abscissa_type;
+    typedef typename element_type::ordinate_type                 ordinate_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JSplineElement2S() :
+      element_type(),
+      __v(getZero<ordinate_type>())
+    {}
+    
+
+    /**
+     * Constructor.
+     *
+     * \param  x               abscissa value
+     * \param  y               ordinate value
+     */
+    JSplineElement2S(typename JLANG::JClass<abscissa_type>::argument_type x,
+		     typename JLANG::JClass<ordinate_type>::argument_type y) :
+      element_type(x, y),
+      __v(getZero<ordinate_type>())
+    {}
+
+
+    /**
+     * Get integral.
+     *
+     * \return                 integral
+     */
+    ordinate_type getIntegral() const
+    { 
+      return __v;
+    }
+
+
+    /**
+     * Set integral.
+     *
+     * \param  v               integral
+     */
+    void setIntegral(typename JLANG::JClass<ordinate_type>::argument_type v)
+    { 
+      __v = v;
+    }
+
+
+  protected:    
+    ordinate_type __v;
+  };
+
+
+  /**
+   * 2D Element for polynomial interpolations.
+   *
+   * Note that the internal data members needed for the calculation
+   * of the integral values are not subject to I/O, i.e.\ the I/O of 
+   * this class is identical to that of the JElement2D class.
+   */
+  template<class JAbscissa_t, class JOrdinate_t>
+  struct JPolintElement2S :
+    public JElement2D<JAbscissa_t, JOrdinate_t>
+  {
+
+    typedef JElement2D<JAbscissa_t, JOrdinate_t>                 element_type;
+    typedef typename element_type::abscissa_type                 abscissa_type;
+    typedef typename element_type::ordinate_type                 ordinate_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JPolintElement2S() :
+      element_type(),
+      __v(getZero<ordinate_type>())
+    {}
+    
+
+    /**
+     * Constructor.
+     *
+     * \param  x               abscissa value
+     * \param  y               ordinate value
+     */
+    JPolintElement2S(typename JLANG::JClass<abscissa_type>::argument_type x,
+		     typename JLANG::JClass<ordinate_type>::argument_type y) :
+      element_type(x, y),
+      __v(getZero<ordinate_type>())
+    {}
+
+
+    /**
+     * Get integral.
+     *
+     * \return                 integral
+     */
+    ordinate_type getIntegral() const
+    { 
+      return __v;
+    }
+
+
+    /**
+     * Set integral.
+     *
+     * \param  v               integral
+     */
+    void setIntegral(typename JLANG::JClass<ordinate_type>::argument_type v)
+    { 
+      __v = v;
+    }
+
+
+  protected:    
+    ordinate_type __v;
+  };
+
+
+  /**
+   * 2D Binned element.
+   *
+   * Note that the internal data members needed for the calculation
+   * of the bin center are not subject to I/O, i.e.\ the I/O of 
+   * this class is identical to that of the JElement2D class.
+   */
+  template<class JAbscissa_t, class JOrdinate_t>
+  struct JBin2D :
+    public JElement2D<JAbscissa_t, JOrdinate_t>,
+    public JMath< JBin2D<JAbscissa_t, JOrdinate_t> >
+  {
+
+    typedef JElement2D<JAbscissa_t, JOrdinate_t>                 element_type;
+    typedef typename element_type::abscissa_type                 abscissa_type;
+    typedef typename element_type::ordinate_type                 ordinate_type;
+    
+
+    /**
+     * Default constructor.
+     */
+    JBin2D() :
+      element_type(),
+      __z (getZero<ordinate_type>()),
+      __w2(getZero<ordinate_type>())
+    {}
+    
+
+    /**
+     * Constructor.
+     *
+     * \param  x               abscissa value
+     * \param  y               ordinate value
+     */
+    JBin2D(typename JLANG::JClass<abscissa_type>::argument_type x,
+	   typename JLANG::JClass<ordinate_type>::argument_type y) :
+      element_type(x,y),
+      __z (getZero<ordinate_type>()),
+      __w2(getZero<ordinate_type>())
+    {}
+
+    
+    /**
+     * Add abscissa value.
+     *
+     * \param  x               abscissa value
+     * \param  w               weight
+     */
+    void fill(typename JLANG::JClass<abscissa_type>::argument_type x,
+	      typename JLANG::JClass<ordinate_type>::argument_type w)
+    { 
+      this->__y  += w;
+      this->__z  += w * x;
+      this->__w2 += w * w;
+    }
+    
+
+    /**
+     * Get bin center.
+     *
+     * \return                 center
+     */
+    abscissa_type getBinCenter() const
+    { 
+      if (this->__y != 0) 
+	return this->__z / this->__y;
+      else
+	return this->__x;
+    }
+    
+
+    /**
+     * Get bin content.
+     *
+     * \return                 content
+     */
+    ordinate_type getBinContent() const
+    { 
+      return this->__y;
+    }
+    
+
+    /**
+     * Get bin error.
+     *
+     * \return                 error
+     */
+    ordinate_type getBinError() const
+    { 
+      return sqrt(this->__w2);
+    }
+
+
+    /**
+     * Add bin.
+     *
+     * \param  bin             bin
+     * \return                 this bin
+     */
+    JBin2D& add(const JBin2D& bin)
+    {
+      this->__y  += bin.__y;
+      this->__z  += bin.__zl;
+      this->__w2 += bin.__w2;
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           multiplication factor
+     * \return                 this bin
+     */
+    JBin2D& mul(const double value)
+    {
+      this->__y  *= value;
+      this->__z  *= value;
+      this->__w2 *= value*value;
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           division factor
+     * \return                 this bin
+     */
+    JBin2D& div(const double value)
+    {
+      this->__y  /= value;
+      this->__z  /= value;
+      this->__w2 /= value*value;
+
+      return *this;
+    }
+
+
+  protected:    
+    ordinate_type __z;
+    ordinate_type __w2;
+  };
+
+
+  /**
+   * 3D Element.
+   */
+  template<class JAbscissa_t, class JOrdinate_t>
+  struct JElement3D {
+
+    typedef JAbscissa_t                                          abscissa_type;
+    typedef JOrdinate_t                                          ordinate_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JElement3D() :
+      __x(getZero<abscissa_type>()),
+      __y(getZero<abscissa_type>()),
+      __z(getZero<ordinate_type>())
+    {}
+    
+
+    /**
+     * Constructor.
+     *
+     * \param  x               abscissa value
+     * \param  y               abscissa value
+     * \param  z               ordinate value
+     */
+    JElement3D(typename JLANG::JClass<abscissa_type>::argument_type x,
+	       typename JLANG::JClass<abscissa_type>::argument_type y,
+	       typename JLANG::JClass<ordinate_type>::argument_type z) :
+      __x(x),
+      __y(y),
+      __z(z)
+    {}
+    
+    
+    /**
+     * Get abscissa value.
+     *
+     * \return                 abscissa value
+     */
+    abscissa_type getX() const 
+    { 
+      return __x;
+    }
+    
+    
+    /**
+     * Get abscissa value.
+     *
+     * \return                 abscissa value
+     */
+    abscissa_type getY() const 
+    { 
+      return __y;
+    }
+    
+    
+    /**
+     * Get ordinate value.
+     *
+     * \return                 ordinate value
+     */
+    const ordinate_type& getZ() const 
+    { 
+      return __y;
+    }
+    
+    
+    /**
+     * Get ordinate value.
+     *
+     * \return                 ordinate value
+     */
+    ordinate_type& getZ()
+    { 
+      return __y;
+    }
+
+
+    /**
+     * Read element from input.
+     *
+     * \param  in              reader
+     * \param  element         element
+     * \return                 reader
+     */
+    friend inline JReader& operator>>(JReader& in, JElement3D& element)
+    {
+      in >> element.__x;
+      in >> element.__y;
+      in >> element.__z;
+
+      return in;
+    }
+
+
+    /**
+     * Write element to output.
+     *
+     * \param  out             writer
+     * \param  element         element
+     * \return                 writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JElement3D& element)
+    {
+      out << element.__x;
+      out << element.__y;
+      out << element.__z;
+
+      return out;
+    }
+
+
+  protected:    
+    abscissa_type __x;
+    abscissa_type __y;
+    ordinate_type __z;
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JFunction1D_t.hh b/jpp/JTools/JFunction1D_t.hh
new file mode 100644
index 0000000..07329eb
--- /dev/null
+++ b/jpp/JTools/JFunction1D_t.hh
@@ -0,0 +1,380 @@
+#ifndef __JFUNCTION1D_T__
+#define __JFUNCTION1D_T__
+
+#include "JTools/JElement.hh"
+#include "JTools/JCollection.hh"
+#include "JTools/JGridCollection.hh"
+#include "JTools/JSpline.hh"
+#include "JTools/JHermiteSpline.hh"
+#include "JTools/JPolint.hh"
+#include "JTools/JResult.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+
+  /**
+   * Type definition of a spline interpolation based on a JGridCollection.
+   */
+  template<class JElement_t, class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  struct JGridSplineFunction1D : 
+    public JSplineFunction1D<JElement_t, JGridCollection, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation method based on a JCollection with double result type.
+   */
+  struct JSplineFunction1D_t : 
+    public JSplineFunction1D<JSplineElement2D<double, double>, JCollection, double>
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation method based on a JCollection with JResultDerivative result type.
+   */
+  struct JSplineFunction1H_t : 
+    public JSplineFunction1D<JSplineElement2S<double, double>, JCollection, JResultDerivative<double> >
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation method based on a JCollection with JResultPDF result type.
+   */
+  struct JSplineFunction1S_t : 
+    public JSplineFunction1D<JSplineElement2S<double, double>, JCollection, JResultPDF<double> >
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation based on a JGridCollection with result type double.
+   */
+  struct JGridSplineFunction1D_t : 
+    public JSplineFunction1D<JSplineElement2D<double, double>, JGridCollection, double>
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation based on a JGridCollection with JResultDerivative result type.
+   */
+  struct JGridSplineFunction1H_t :
+    public JSplineFunction1D<JSplineElement2S<double, double>, JGridCollection, JResultDerivative<double> >
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation based on a JGridCollection with JResultPDF result type.
+   */
+  struct JGridSplineFunction1S_t :
+    public JSplineFunction1D<JSplineElement2S<double, double>, JGridCollection, JResultPDF<double> >
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation based on a JGridCollection.
+   */
+  template<class JElement_t, class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  struct JGridHermiteSplineFunction1D : 
+    public JHermiteSplineFunction1D<JElement_t, JGridCollection, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation method based on a JCollection with double result type.
+   */
+  struct JHermiteSplineFunction1D_t : 
+    public JHermiteSplineFunction1D<JSplineElement2D<double, double>, JCollection, double>
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation method based on a JCollection with JResultDerivative result type.
+   */
+  struct JHermiteSplineFunction1H_t : 
+    public JHermiteSplineFunction1D<JSplineElement2S<double, double>, JCollection, JResultDerivative<double> >
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation method based on a JCollection with JResultPDF result type.
+   */
+  struct JHermiteSplineFunction1S_t : 
+    public JHermiteSplineFunction1D<JSplineElement2S<double, double>, JCollection, JResultPDF<double> >
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation based on a JGridCollection with result type double.
+   */
+  struct JGridHermiteSplineFunction1D_t : 
+    public JHermiteSplineFunction1D<JSplineElement2D<double, double>, JGridCollection, double>
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation based on a JGridCollection with JResultDerivative result type.
+   */
+  struct JGridHermiteSplineFunction1H_t :
+    public JHermiteSplineFunction1D<JSplineElement2S<double, double>, JGridCollection, JResultDerivative<double> >
+  {};
+
+
+  /**
+   * Type definition of a zero degree polynomial interpolation.
+   */
+  template<class JElement_t, class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  struct JPolint0Function1D :
+    public JPolintFunction1D<0, JElement_t, JCollection, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 1st degree polynomial interpolation.
+   */
+  template<class JElement_t, class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  struct JPolint1Function1D :
+    public JPolintFunction1D<1, JElement_t, JCollection, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 2nd degree polynomial interpolation.
+   */
+  template<class JElement_t, class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  struct JPolint2Function1D :
+    public JPolintFunction1D<2, JElement_t, JCollection, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 3rd degree polynomial interpolation.
+   */
+  template<class JElement_t, class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  struct JPolint3Function1D :
+    public JPolintFunction1D<3, JElement_t, JCollection, JDistance_t>
+  {};
+
+
+  /**
+   * Polynomial interpolation method with result type double.
+   */
+  template<int N>
+  struct JPolintFunction1D_t :
+    public JPolintFunction1D<N, JElement2D<double, double>, JCollection, double>
+  {};
+
+
+  /**
+   * Type definition of a zero degree polynomial interpolation with result type double.
+   */
+  struct JPolint0Function1D_t :
+    public JPolintFunction1D_t<0>
+  {};
+
+
+  /**
+   * Type definition of a 1st degree polynomial interpolation with result type double.
+   */
+  struct JPolint1Function1D_t :
+    public JPolintFunction1D_t<1>
+  {};
+
+
+  /**
+   * Type definition of a 2nd degree polynomial interpolation with result type double.
+   */
+  struct JPolint2Function1D_t :
+    public JPolintFunction1D_t<2>
+  {};
+
+
+  /**
+   * Type definition of a 3rd degree polynomial interpolation with result type double.
+   */
+  struct JPolint3Function1D_t :
+    public JPolintFunction1D_t<3>
+  {};
+
+
+  /**
+   * Polynomial interpolation method with result type JResultDerivative.
+   */
+  template<int N>
+  struct JPolintFunction1H_t :
+    public JPolintFunction1D<N, JElement2D<double, double>, JCollection, JResultDerivative<double> >
+  {};
+
+
+  /**
+   * Type definition of a 1st degree polynomial interpolation with result type JResultDerivative.
+   */
+  struct JPolint1Function1H_t :
+    public JPolintFunction1H_t<1>
+  {};
+
+
+  /**
+   * Type definition of a 2nd degree polynomial interpolation with result type JResultDerivative.
+   */
+  struct JPolint2Function1H_t :
+    public JPolintFunction1H_t<2>
+  {};
+
+
+  /**
+   * Type definition of a 3rd degree polynomial interpolation with result type JResultDerivative.
+   */
+  struct JPolint3Function1H_t :
+    public JPolintFunction1H_t<3>
+  {};
+
+
+  /**
+   * Polynomial interpolation method with result type JResultPDF.
+   */
+  template<int N>
+  struct JPolintFunction1S_t :
+    public JPolintFunction1D<N, JPolintElement2S<double, double>, JCollection, JResultPDF<double> >
+  {};
+
+
+  /**
+   * Type definition of a 1st degree polynomial interpolation with result type JResultPDF.
+   */
+  struct JPolint1Function1S_t : 
+    public JPolintFunction1S_t<1>
+  {};
+
+
+  /**
+   * Type definition of a 2nd degree polynomial interpolation with result type JResultPDF.
+   */
+  struct JPolint2Function1S_t : 
+    public JPolintFunction1S_t<2>
+  {};
+
+
+  /**
+   * Type definition of a 3rd degree polynomial interpolation with result type JResultPDF.
+   */
+  struct JPolint3Function1S_t : 
+    public JPolintFunction1S_t<3>
+  {};
+
+
+  /**
+   * Polynomial interpolation method based on a JGridCollection with result type double.
+   */
+  template<int N>
+  struct JGridPolintFunction1D_t :
+    public JPolintFunction1D<N, JElement2D<double, double>, JGridCollection, double>
+  {};
+
+
+  /**
+   * Type definition of a zero degree polynomial interpolation based on a JGridCollection with result type double.
+   */
+  struct JGridPolint0Function1D_t :
+    public JGridPolintFunction1D_t<0>
+  {};
+
+
+  /**
+   * Type definition of a 1st degree polynomial interpolation based on a JGridCollection with result type double.
+   */
+  struct JGridPolint1Function1D_t :
+    public JGridPolintFunction1D_t<1>
+  {};
+
+
+  /**
+   * Type definition of a 2nd degree polynomial interpolation based on a JGridCollection with result type double.
+   */
+  struct JGridPolint2Function1D_t :
+    public JGridPolintFunction1D_t<2>
+  {};
+
+
+  /**
+   * Type definition of a 3rd degree polynomial interpolation based on a JGridCollection with result type double.
+   */
+  struct JGridPolint3Function1D_t :
+    public JGridPolintFunction1D_t<3>
+  {};
+
+
+  /**
+   * Polynomial interpolation method based on a JGridCollection with result type JResultDerivative.
+   */
+  template<int N>
+  struct JGridPolintFunction1H_t :
+    public JPolintFunction1D<N, JElement2D<double, double>, JGridCollection, JResultDerivative<double> >
+  {};
+
+
+  /**
+   * Type definition of a 1st degree polynomial interpolation with result type JResultDerivative.
+   */
+  struct JGridPolint1Function1H_t :
+    public JGridPolintFunction1H_t<2>
+  {};
+
+
+
+  /**
+   * Type definition of a 2nd degree polynomial interpolation with result type JResultDerivative.
+   */
+  struct JGridPolint2Function1H_t :
+    public JGridPolintFunction1H_t<2>
+  {};
+
+
+  /**
+   * Type definition of a 3rd degree polynomial interpolation with result type JResultDerivative.
+   */
+  struct JGridPolint3Function1H_t :
+    public JGridPolintFunction1H_t<3>
+  {};
+
+
+  /**
+   * Polynomial interpolation method with result type JResultPDF.
+   */
+  template<int N>
+  struct JGridPolintFunction1S_t :
+    public JPolintFunction1D<N, JPolintElement2S<double, double>, JGridCollection, JResultPDF<double> >
+  {};
+
+
+  /**
+   * Type definition of a 1st degree polynomial interpolation with result type JResulPDF.
+   */
+  struct JGridPolint1Function1S_t : 
+    public JGridPolintFunction1S_t<1>
+  {};
+
+
+  /**
+   * Type definition of a 2nd degree polynomial interpolation with result type JResulPDF.
+   */
+  struct JGridPolint2Function1S_t : 
+    public JGridPolintFunction1S_t<2>
+  {};
+
+
+  /**
+   * Type definition of a 3rd degree polynomial interpolation with result type JResulPDF.
+   */
+  struct JGridPolint3Function1S_t : 
+    public JGridPolintFunction1S_t<3>
+  {};
+}
+
+#endif
diff --git a/jpp/JTools/JFunctional.hh b/jpp/JTools/JFunctional.hh
new file mode 100644
index 0000000..5b0c005
--- /dev/null
+++ b/jpp/JTools/JFunctional.hh
@@ -0,0 +1,394 @@
+#ifndef __JTOOLS__JFUNCTIONAL__
+#define __JTOOLS__JFUNCTIONAL__
+
+#include "JLang/JSharedPointer.hh"
+#include "JLang/JNullType.hh"
+#include "JLang/JException.hh"
+#include "JLang/JVoid.hh"
+#include "JLang/JClass.hh"
+#include "JMath/JZero.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JClass;
+  using JLANG::JException;
+  using JLANG::JNullType;
+  using JLANG::JVoid;
+  using JLANG::JSharedPointer;
+
+
+  /**
+   * Template definition of function object interface.
+   */
+  template<class JArgument_t = JNullType, class JResult_t = JNullType>
+  class JFunctional;
+
+
+  /**
+   * Template specialisation of compilable function object.
+   */
+  template<>
+  class JFunctional<JNullType, JNullType> 
+  {
+  protected:
+    /**
+     * Function compilation.
+     */
+    virtual void do_compile() = 0;
+
+
+  public:
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JFunctional() 
+    {}
+
+
+    /**
+     * Function compilation.
+     */
+    void compile() 
+    {
+      do_compile();
+    }
+  };
+
+
+  /**
+   * Template definition of recursive function value evaluation.
+   */
+  template<class JArgument_t, class JResult_t>
+  class JFunctional : 
+    public virtual JFunctional<JNullType, JNullType>
+  {
+  protected:
+    /**
+     * Default constructor.
+     */
+    JFunctional() :
+      JFunctional<JNullType, JNullType>(),
+      supervisor(JSupervisor::getInstance())
+    {}
+
+  public:
+
+    class JSupervisor;
+
+    typedef JArgument_t                                   argument_type;
+    typedef JResult_t                                     result_type;
+    typedef JFunctional<argument_type, result_type>       functional_type;
+    typedef JSupervisor                                   supervisor_type;
+
+
+    /**
+     * Recursive function value evaluation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const = 0;
+
+    
+    /**
+     * Recursive function value evaluation.
+     *
+     * \param  function        function
+     * \param  pX              pointer to abscissa values
+     */
+    static result_type getValue(const JFunctional&   function,
+				const argument_type* pX)
+    {
+      return function.evaluate(pX);
+    }
+
+
+    /**
+     * Termination of recursive function value evaluation.
+     *
+     * \param  value           result
+     * \param  pX              pointer to abscissa values
+     */
+    static   typename JClass<result_type>::argument_type 
+    getValue(typename JClass<result_type>::argument_type value,
+	     const argument_type* pX)
+    {
+      return value;
+    }
+
+
+    /**
+     * Exception handler for functional object.
+     */
+    struct JExceptionHandler
+    {
+      /**
+       * Default constructor.
+       */
+      JExceptionHandler()
+      {}
+
+
+      /**
+       * Virtual destructor.
+       */
+      virtual ~JExceptionHandler()
+      {}
+      
+      
+      /**
+       * Implementation of exception handler.
+       * This implementation throws the exception.
+       *
+       * \param  error           error
+       */
+      virtual result_type action(const JException& error) const
+      {
+	throw error;
+      }
+    };
+
+
+    /**
+     * Exception handler for functional object using default result.
+     */
+    struct JDefaultResult :
+      public JExceptionHandler
+    {
+      /**
+       * Constructor.
+       * 
+       * \param  value             default result in case of exception
+       */
+      JDefaultResult(const result_type value) :
+	JExceptionHandler(),
+	defaultResult(value)
+      {}
+
+
+      /**
+       * Constructor.
+       * 
+       * \param  value             default result in case of exception
+       */
+      JDefaultResult(const JMATH::JZero& value) :
+	JExceptionHandler(),
+	defaultResult()
+      {}
+
+
+      /**
+       * Implementation of exception handler.
+       * This implementation returns the default value.
+       *
+       * \param  error             error
+       * \return                   default value
+       */
+      virtual result_type action(const JException& error) const override 
+      {
+	return defaultResult;
+      }
+      
+    private:
+      result_type defaultResult;    
+    };
+
+
+    /**
+     * Place holder for exception handler.
+     */
+    class JSupervisor :
+      public JSharedPointer<JExceptionHandler> 
+    {
+
+      typedef JSharedPointer<JExceptionHandler>  supervisor_type;
+
+    public:
+      /**
+       * Default constructor.
+       */
+      JSupervisor() :
+	supervisor_type(new JExceptionHandler())
+      {}
+
+      
+      /**
+       * Constructor
+       *
+       * \param  exception_handler  pointer to exception handler
+       */
+      JSupervisor(JExceptionHandler* exception_handler) :
+	supervisor_type(exception_handler)
+      {}
+
+
+      /**
+       * Get reference to unique instance of this class object.
+       *
+       * \return                   supervisor
+       */
+      static const JSupervisor& getInstance()
+      {
+	static const JSupervisor supervisor;
+	
+	return supervisor;
+      }
+
+
+      /**
+       * Set exception handler of given functional object.
+       *
+       * \param  function          function
+       * \return                   this supervisor
+       */
+      const JSupervisor& operator()(functional_type& function) const
+      {
+	function.setExceptionHandler(*this);
+
+	return *this;
+      }
+    };
+
+
+    /**
+     * Get supervisor.
+     *
+     * \return                   supervisor
+     */
+    JSupervisor getSupervisor() const
+    {
+      return supervisor;
+    }
+
+
+    /**
+     * Get exception handler.
+     *
+     * \return                   exception handler
+     */
+    const JExceptionHandler& getExceptionHandler() const
+    {
+      return *supervisor;
+    }
+
+
+    /**
+     * Set the supervisor for handling of exceptions.
+     *
+     * \param  supervisor        supervisor
+     */
+    void setExceptionHandler(const JSupervisor& supervisor)
+    {
+      this->supervisor = supervisor;
+    }
+
+
+  protected:
+    JSupervisor supervisor;
+  };
+
+
+  /**
+   * Template definition of function object interface in multidimensions.
+   */
+  template<class JArgument_t, class JResult_t>
+  struct JFunction : 
+    public virtual JFunctional<JArgument_t, JResult_t>
+  {
+    typedef JFunctional<JArgument_t, JResult_t>                         functional_type;
+    typedef typename functional_type::argument_type                     argument_type;
+    typedef typename functional_type::result_type                       result_type;
+  };
+
+
+  /**
+   * Template definition of function object interface in one dimension.
+   * This class provides for the standard function operator <tt>()</tt>.
+   */
+  template<class JArgument_t, class JResult_t>
+  struct JFunction1D : 
+    public JFunction<JArgument_t, JResult_t>
+  {
+    enum { NUMBER_OF_DIMENSIONS = 1 };
+
+    typedef JFunctional<JArgument_t, JResult_t>                         functional_type;
+    typedef typename functional_type::argument_type                     argument_type;
+    typedef typename functional_type::result_type                       result_type;
+
+
+    /**
+     * Function value evaluation.
+     *
+     * \param  x               argument value
+     * \return                 function value
+     */
+    result_type operator()(const argument_type x) const 
+    {
+      return this->evaluate(&x);
+    }
+  };
+
+
+  /**
+   * Functional object compiler.
+   */
+  struct JCompiler {
+    /**
+     * Default constructor.
+     */
+    JCompiler()
+    {}
+
+
+    /**    
+     * Compile function.
+     *
+     * \param  function          function
+     * \return                   this compiler
+     */
+    const JCompiler& operator()(JFunctional<>& function) const
+    {
+      function.compile();
+
+      return *this;
+    }
+  };
+
+  
+  /**
+   * Function object for functional object compilation.
+   */
+  static const JCompiler compiler;
+
+
+  /**
+   * Auxiliary class to evaluate result type.
+   * The result type is the actual data type.
+   */
+  template<class JClass_t, class JResultType_t = void>
+  struct JResultType {
+
+    typedef JClass_t                           result_type;
+  };
+
+
+  /**
+   * Auxiliary class to evaluate result type.
+   * The result type is the result type of the function object.
+   */
+  template<class JClass_t>
+  struct JResultType<JClass_t, typename JVoid<typename JClass_t::result_type>::type> {
+
+    typedef typename JClass_t::result_type     result_type;
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JFunctionalMap.hh b/jpp/JTools/JFunctionalMap.hh
new file mode 100644
index 0000000..52ae939
--- /dev/null
+++ b/jpp/JTools/JFunctionalMap.hh
@@ -0,0 +1,220 @@
+#ifndef __JTOOLS__JFUNCTIONALMAP__
+#define __JTOOLS__JFUNCTIONALMAP__
+
+#include "JTools/JFunctionalMap_t.hh"
+#include "JTools/JSpline.hh"
+#include "JTools/JPolint.hh"
+#include "JTools/JCollection.hh"
+#include "JTools/JGridCollection.hh"
+#include "JTools/JElement.hh"
+#include "JTools/JDistance.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+
+  /**
+   * Auxiliary class to define corresponding one-dimensional function interpolator <tt>function_type</tt>. 
+   */
+  template<template<class JKey_t, class JValue_t, class JDistance_t> class JFunctionalMap_t>
+  struct JFunctionalMap;
+
+
+  /**
+   * Specialisation of JFunctionalMap for JSplineFunctionalMap.
+   */
+  template<>
+  struct JFunctionalMap<JSplineFunctionalMap>
+  {
+    /**
+     * Corresponding one-dimensional function interpolator.
+     */
+    template<class JAbscissa_t, 
+	     class JOrdinate_t, 
+	     class JResult_t, 
+	     class JDistance_t = JDistance<JAbscissa_t> >
+    struct function_type : 
+      public JSplineFunction1D<JSplineElement2D<JAbscissa_t, JOrdinate_t>, JCollection, JResult_t, JDistance_t>
+    {}; 
+  };
+
+
+  /**
+   * Specialisation of JFunctionalMap for JSplineFunctionalGridMap.
+   */
+  template<>
+  struct JFunctionalMap<JSplineFunctionalGridMap>
+  {
+    /**
+     * Corresponding one-dimensional function interpolator.
+     */
+    template<class JAbscissa_t, 
+	     class JOrdinate_t, 
+	     class JResult_t, 
+	     class JDistance_t = JDistance<JAbscissa_t> >
+    struct function_type : 
+      public JSplineFunction1D<JSplineElement2D<JAbscissa_t, JOrdinate_t>, JGridCollection, JResult_t, JDistance_t>
+    {}; 
+  };
+
+
+  /**
+   * Specialisation of JFunctionalMap for JPolint0FunctionalMap.
+   */
+  template<>
+  struct JFunctionalMap<JPolint0FunctionalMap>
+  {
+    /**
+     * Corresponding one-dimensional function interpolator.
+     */
+    template<class JAbscissa_t, 
+	     class JOrdinate_t, 
+	     class JResult_t, 
+	     class JDistance_t = JDistance<JAbscissa_t> >
+    struct function_type : 
+      public JPolintFunction1D<0, JElement2D<JAbscissa_t, JOrdinate_t>, JCollection, JResult_t, JDistance_t>
+    {}; 
+  };
+
+
+  /**
+   * Specialisation of JFunctionalMap for JPolint1FunctionalMap.
+   */
+  template<>
+  struct JFunctionalMap<JPolint1FunctionalMap>
+  {
+    /**
+     * Corresponding one-dimensional function interpolator.
+     */
+    template<class JAbscissa_t, 
+	     class JOrdinate_t, 
+	     class JResult_t, 
+	     class JDistance_t = JDistance<JAbscissa_t> >
+    struct function_type : 
+      public JPolintFunction1D<1, JElement2D<JAbscissa_t, JOrdinate_t>, JCollection, JResult_t, JDistance_t>
+    {}; 
+  };
+
+
+  /**
+   * Specialisation of JFunctionalMap for JPolint2FunctionalMap.
+   */
+  template<>
+  struct JFunctionalMap<JPolint2FunctionalMap>
+  {
+    /**
+     * Corresponding one-dimensional function interpolator.
+     */
+    template<class JAbscissa_t, 
+	     class JOrdinate_t, 
+	     class JResult_t, 
+	     class JDistance_t = JDistance<JAbscissa_t> >
+    struct function_type : 
+      public JPolintFunction1D<2, JElement2D<JAbscissa_t, JOrdinate_t>, JCollection, JResult_t, JDistance_t>
+    {}; 
+  };
+
+
+  /**
+   * Specialisation of JFunctionalMap for JPolint3FunctionalMap.
+   */
+  template<>
+  struct JFunctionalMap<JPolint3FunctionalMap>
+  {
+    /**
+     * Corresponding one-dimensional function interpolator.
+     */
+    template<class JAbscissa_t, 
+	     class JOrdinate_t, 
+	     class JResult_t, 
+	     class JDistance_t = JDistance<JAbscissa_t> >
+    struct function_type : 
+      public JPolintFunction1D<3, JElement2D<JAbscissa_t, JOrdinate_t>, JCollection, JResult_t, JDistance_t>
+    {}; 
+  };
+
+
+  /**
+   * Specialisation of JFunctionalMap for JPolint0FunctionalGridMap.
+   */
+  template<>
+  struct JFunctionalMap<JPolint0FunctionalGridMap>
+  {
+    /**
+     * Corresponding one-dimensional function interpolator.
+     */
+    template<class JAbscissa_t, 
+	     class JOrdinate_t, 
+	     class JResult_t, 
+	     class JDistance_t = JDistance<JAbscissa_t> >
+    struct function_type : 
+      public JPolintFunction1D<0, JElement2D<JAbscissa_t, JOrdinate_t>, JGridCollection, JResult_t, JDistance_t>
+    {}; 
+  };
+
+
+  /**
+   * Specialisation of JFunctionalMap for JPolint1FunctionalGridMap.
+   */
+  template<>
+  struct JFunctionalMap<JPolint1FunctionalGridMap>
+  {
+    /**
+     * Corresponding one-dimensional function interpolator.
+     */
+    template<class JAbscissa_t, 
+	     class JOrdinate_t, 
+	     class JResult_t, 
+	     class JDistance_t = JDistance<JAbscissa_t> >
+    struct function_type : 
+      public JPolintFunction1D<1, JElement2D<JAbscissa_t, JOrdinate_t>, JGridCollection, JResult_t, JDistance_t>
+    {}; 
+  };
+
+
+  /**
+   * Specialisation of JFunctionalMap for JPolint2FunctionalGridMap.
+   */
+  template<>
+  struct JFunctionalMap<JPolint2FunctionalGridMap>
+  {
+    /**
+     * Corresponding one-dimensional function interpolator.
+     */
+    template<class JAbscissa_t, 
+	     class JOrdinate_t, 
+	     class JResult_t, 
+	     class JDistance_t = JDistance<JAbscissa_t> >
+    struct function_type : 
+      public JPolintFunction1D<2, JElement2D<JAbscissa_t, JOrdinate_t>, JGridCollection, JResult_t, JDistance_t>
+    {}; 
+  };
+
+
+  /**
+   * Specialisation of JFunctionalMap for JPolint3FunctionalGridMap.
+   */
+  template<>
+  struct JFunctionalMap<JPolint3FunctionalGridMap>
+  {
+    /**
+     * Corresponding one-dimensional function interpolator.
+     */
+    template<class JAbscissa_t, 
+	     class JOrdinate_t, 
+	     class JResult_t, 
+	     class JDistance_t = JDistance<JAbscissa_t> >
+    struct function_type : 
+      public JPolintFunction1D<3, JElement2D<JAbscissa_t, JOrdinate_t>, JGridCollection, JResult_t, JDistance_t>
+    {}; 
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JFunctionalMap_t.hh b/jpp/JTools/JFunctionalMap_t.hh
new file mode 100644
index 0000000..bf0ae84
--- /dev/null
+++ b/jpp/JTools/JFunctionalMap_t.hh
@@ -0,0 +1,204 @@
+#ifndef __JFUNCTIONALMAP_T__
+#define __JFUNCTIONALMAP_T__
+
+#include "JTools/JDistance.hh"
+#include "JTools/JMap.hh"
+#include "JTools/JGridMap.hh"
+#include "JTools/JPolint.hh"
+#include "JTools/JSpline.hh"
+#include "JTools/JResult.hh"
+
+
+/**
+ * \file
+ *
+ * Various implementations of functional maps.
+ * \author mdejong
+ */
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+
+  /**
+   * Type definition of a spline interpolation based on a JMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JSplineFunctionalMap :
+    public JSplineMap<JKey_t, JValue_t, JMap, typename JResultType<JValue_t>::result_type, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation based on a JGridMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JSplineFunctionalGridMap :
+    public JSplineMap<JKey_t, JValue_t, JGridMap, typename JResultType<JValue_t>::result_type, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a zero degree polynomial interpolation based on a JMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint0FunctionalMap : 
+    public JPolintMap<0, JKey_t, JValue_t, JMap, typename JResultType<JValue_t>::result_type, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 1st degree polynomial interpolation based on a JMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint1FunctionalMap :
+    public JPolintMap<1, JKey_t, JValue_t, JMap, typename JResultType<JValue_t>::result_type, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 2nd degree polynomial interpolation based on a JMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint2FunctionalMap :
+    public JPolintMap<2, JKey_t, JValue_t, JMap, typename JResultType<JValue_t>::result_type, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 3rd degree polynomial interpolation based on a JMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint3FunctionalMap :
+    public JPolintMap<3, JKey_t, JValue_t, JMap, typename JResultType<JValue_t>::result_type, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a zero degree polynomial interpolation based on a JGridMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint0FunctionalGridMap :
+    public JPolintMap<0, JKey_t, JValue_t, JGridMap, typename JResultType<JValue_t>::result_type, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 1st degree polynomial interpolation based on a JGridMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint1FunctionalGridMap :
+    public JPolintMap<1, JKey_t, JValue_t, JGridMap, typename JResultType<JValue_t>::result_type, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 2nd degree polynomial interpolation based on a JGridMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint2FunctionalGridMap :
+    public JPolintMap<2, JKey_t, JValue_t, JGridMap, typename JResultType<JValue_t>::result_type, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 3rd degree polynomial interpolation based on a JGridMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint3FunctionalGridMap :
+    public JPolintMap<3, JKey_t, JValue_t, JGridMap, typename JResultType<JValue_t>::result_type, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation based on a JMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JSplineFunctionalMapH :
+    public JSplineMap<JKey_t, JValue_t, JMap, JResultDerivative<typename JResultType<JValue_t>::result_type>, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a spline interpolation based on a JGridMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JSplineFunctionalGridMapH :
+    public JSplineMap<JKey_t, JValue_t, JGridMap, JResultDerivative<typename JResultType<JValue_t>::result_type>, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a zero degree polynomial interpolation based on a JMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint0FunctionalMapH : 
+    public JPolintMap<0, JKey_t, JValue_t, JMap, JResultDerivative<typename JResultType<JValue_t>::result_type>, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 1st degree polynomial interpolation based on a JMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint1FunctionalMapH :
+    public JPolintMap<1, JKey_t, JValue_t, JMap, JResultDerivative<typename JResultType<JValue_t>::result_type>, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 2nd degree polynomial interpolation based on a JMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint2FunctionalMapH :
+    public JPolintMap<2, JKey_t, JValue_t, JMap, JResultDerivative<typename JResultType<JValue_t>::result_type>, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 3rd degree polynomial interpolation based on a JMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint3FunctionalMapH :
+    public JPolintMap<3, JKey_t, JValue_t, JMap, JResultDerivative<typename JResultType<JValue_t>::result_type>, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a zero degree polynomial interpolation based on a JGridMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint0FunctionalGridMapH :
+    public JPolintMap<0, JKey_t, JValue_t, JGridMap, JResultDerivative<typename JResultType<JValue_t>::result_type>, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 1st degree polynomial interpolation based on a JGridMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint1FunctionalGridMapH :
+    public JPolintMap<1, JKey_t, JValue_t, JGridMap, JResultDerivative<typename JResultType<JValue_t>::result_type>, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 2nd degree polynomial interpolation based on a JGridMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint2FunctionalGridMapH :
+    public JPolintMap<2, JKey_t, JValue_t, JGridMap, JResultDerivative<typename JResultType<JValue_t>::result_type>, JDistance_t>
+  {};
+
+
+  /**
+   * Type definition of a 3rd degree polynomial interpolation based on a JGridMap implementation.
+   */
+  template<class JKey_t, class JValue_t, class JDistance_t = JDistance<JKey_t> >
+  struct JPolint3FunctionalGridMapH :
+    public JPolintMap<3, JKey_t, JValue_t, JGridMap, JResultDerivative<typename JResultType<JValue_t>::result_type>, JDistance_t>
+  {};
+}
+
+#endif
diff --git a/jpp/JTools/JGarbageCollection.hh b/jpp/JTools/JGarbageCollection.hh
new file mode 100644
index 0000000..3fe8ae1
--- /dev/null
+++ b/jpp/JTools/JGarbageCollection.hh
@@ -0,0 +1,68 @@
+#ifndef __JTOOLS__JGARBAGECOLLACTION__
+#define __JTOOLS__JGARBAGECOLLACTION__
+
+#include "JTools/JMappableCollection.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  /**
+   * Garbage collection.
+   *
+   * This class implements the JMappableCollection interface but does nothing.
+   */
+  template<class JKey_t, class JValue_t>
+  class JGarbageCollection :
+    public JMappableCollection<JKey_t, JValue_t>
+  {
+  public:
+
+    typedef JMappableCollection<JKey_t, JValue_t>                mappablecollection_type;
+
+    typedef typename mappablecollection_type::key_type           key_type;
+    typedef typename mappablecollection_type::mapped_type        mapped_type;
+
+
+    /**
+     * Clear.
+     */
+    virtual void clear() override 
+    {}
+
+
+    /**
+     * Get mapped value.
+     *
+     * \param  key             key
+     * \return                 value
+     */
+    virtual const mapped_type& get(typename JLANG::JClass<key_type>::argument_type key) const override 
+    {
+      return value;
+    }
+
+
+    /**
+     * Get mapped value.
+     *
+     * \param  key             key
+     * \return                 value
+     */
+    virtual mapped_type& get(typename JLANG::JClass<key_type>::argument_type key) override 
+    {
+      return value;
+    }
+
+  private:
+    mapped_type value;
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JGrid.hh b/jpp/JTools/JGrid.hh
new file mode 100644
index 0000000..aeb6b45
--- /dev/null
+++ b/jpp/JTools/JGrid.hh
@@ -0,0 +1,185 @@
+#ifndef __JTOOLS__JGRID__
+#define __JTOOLS__JGRID__
+
+#include <istream>
+#include <ostream>
+
+#include "JTools/JAbstractCollection.hh"
+#include "JLang/JClass.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JClass;
+
+  template<class JElement_t, class JDistance_t>
+  class JCollection;
+
+  
+  /**
+   * Simple data structure for an abstract collection of equidistant abscissa values.
+   *
+   * This class implements the JAbstractCollection interface.
+   */
+  template<class JAbscissa_t>
+  struct JGrid : 
+    public JAbstractCollection<JAbscissa_t>
+  {
+    typedef typename JAbstractCollection<JAbscissa_t>::abscissa_type      abscissa_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JGrid() :
+      size(0),
+      xmin(),
+      xmax()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  nx              number of elements
+     * \param  Xmin            lower limit
+     * \param  Xmax            upper limit
+     */
+    JGrid(const int           nx,
+	  const abscissa_type Xmin,
+	  const abscissa_type Xmax) :
+      size(nx),
+      xmin(Xmin),
+      xmax(Xmax)
+    {}
+
+
+    /**
+     * Get number of elements.
+     *
+     * \return                 number of elements
+     */
+    virtual int getSize() const override 
+    { 
+      return size;
+    }
+    
+
+    /**
+     * Get abscissa value.
+     *
+     * \param  index           index
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getX(int index) const override 
+    {
+      return xmin  +  index * ((xmax - xmin) / (size - 1));
+    }
+
+    
+    /**
+     * Get minimal abscissa value.
+     *
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getXmin() const override 
+    {
+      return xmin;
+    }
+
+
+    /**
+     * Get maximal abscissa value.
+     *
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getXmax() const override 
+    {
+      return xmax;
+    }    
+
+         
+    /**
+     * Get index of given abscissa value.
+     *
+     * \param  x               abscissa value
+     * \return                 index
+     */
+    int getIndex(typename JClass<abscissa_type>::argument_type x) const
+    {
+      return (int) ((size - 1) * (x - xmin) / (xmax - xmin));
+    }
+
+
+    /**    
+     * Configure collection.
+     *
+     * \param  collection        collection
+     * \return                   this grid
+     */
+    template<class JElement_t, class JDistance_t>
+    const JGrid& operator()(JCollection<JElement_t, JDistance_t>& collection) const
+    {
+      collection.configure(*this);
+
+      return *this;
+    }
+
+    
+    /**
+     * Read grid from input.
+     *
+     * \param  in       input stream
+     * \param  grid     grid
+     * \return          input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JGrid<JAbscissa_t>& grid)
+    {
+      return in >> grid.size >> grid.xmin >> grid.xmax;
+    }
+
+
+    /**
+     * Write grid to output.
+     *
+     * \param  out      output stream
+     * \param  grid     grid
+     * \return          output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JGrid<JAbscissa_t>& grid)
+    {
+      return out << grid.size << ' ' << grid.xmin << ' ' << grid.xmax;
+    }
+
+  protected:
+    int           size;
+    abscissa_type xmin;
+    abscissa_type xmax;
+  };
+
+
+  /**
+   * Helper method for JGrid.
+   *
+   * \param  nx              number of elements
+   * \param  Xmin            lower limit
+   * \param  Xmax            upper limit
+   * \return                 grid
+   */
+  template<class JAbscissa_t>
+  inline JGrid<JAbscissa_t> make_grid(const int         nx,
+				      const JAbscissa_t Xmin,
+				      const JAbscissa_t Xmax)
+  {
+    return JGrid<JAbscissa_t>(nx, Xmin, Xmax);
+  }
+}
+
+#endif
diff --git a/jpp/JTools/JGridCollection.hh b/jpp/JTools/JGridCollection.hh
new file mode 100644
index 0000000..1f702b2
--- /dev/null
+++ b/jpp/JTools/JGridCollection.hh
@@ -0,0 +1,111 @@
+#ifndef __JTOOLS__JGRIDCOLLECTION__
+#define __JTOOLS__JGRIDCOLLECTION__
+
+#include "JLang/JClass.hh"
+#include "JTools/JCollection.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JClass;
+
+  
+  /**
+   * General purpose class for collection of equidistant elements.
+   *
+   * For a collection with equidistant elements, the index of the nearest element can directly be computed
+   * based on the minimal abscissa value, the maximal abscissa value and the number of elements in the collection.
+   * The lower_bound methods are re-implemented in this class which otherwise simply derives from JCollection.
+   *
+   * For convenience, the implementation of the standard map operator <tt>[]</tt> of the JCollection class is maintained.
+   */
+  template<class JElement_t, class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  class JGridCollection :
+    public JCollection<JElement_t, JDistance_t>
+  {
+  public:
+
+    typedef JCollection<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 typename collection_type::pair_type                                  pair_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JGridCollection()
+    {}
+    
+     
+    /**
+     * Get index of given abscissa value.
+     *
+     * For values within the range of this collection, the index starts at zero and ends at number of elements minus one. 
+     * Note that the index could be less than zero or larger than (or equal to) the number of elements,
+     * if the given abscissa value is outside the range of this collection.
+     *
+     * \param  x               abscissa value
+     * \return                 index
+     */
+    int getIndex(typename JClass<abscissa_type>::argument_type x) const
+    {
+      return (int) ((this->size() - 1) * (x - this->begin()->getX()) / (this->rbegin()->getX() - this->begin()->getX()));
+    }
+
+
+    /**
+     * Get first position of element <tt>i</tt>, where <tt>x >= i->getX()</tt>.
+     *
+     * \param  x               abscissa value
+     * \return                 position of corresponding element
+     */
+    const_iterator lower_bound(typename JClass<abscissa_type>::argument_type x) const
+    {
+      const int index = getIndex(x) + 1;
+
+      if      (index <= 0)
+	return this->begin();
+      else if (index >= (int) this->size())
+        return this->end();
+      else
+	return this->begin() + index;
+    }
+
+
+    /**
+     * Get first position of element <tt>i</tt>, where <tt>x >= i->getX()</tt>.
+     *
+     * \param  x               abscissa value
+     * \return                 position of corresponding element
+     */
+    iterator lower_bound(typename JClass<abscissa_type>::argument_type x)
+    {
+      const int index = getIndex(x) + 1;
+
+      if      (index <= 0)
+	return this->begin();
+      else if (index >= (int) this->size())
+        return this->end();
+      else
+	return this->begin() + index;
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JGridMap.hh b/jpp/JTools/JGridMap.hh
new file mode 100644
index 0000000..61b04fe
--- /dev/null
+++ b/jpp/JTools/JGridMap.hh
@@ -0,0 +1,70 @@
+#ifndef __JTOOLS__JGRIDMAP__
+#define __JTOOLS__JGRIDMAP__
+
+#include "JTools/JGridCollection.hh"
+#include "JTools/JMapCollection.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  
+  /**
+   * Map of equidistant pair-wise elements.
+   *
+   * The key_type and mapped_type refer to the pair-wise element of this map, respectively.
+   */
+  template<class JKey_t, 
+	   class JValue_t, 
+	   class JDistance_t = JDistance<JKey_t> >
+  class JGridMap :
+    public JGridCollection<JElement2D<JKey_t, JValue_t>, JDistance_t>
+  {
+  public:
+
+    typedef JKey_t                                                               key_type;
+    typedef JValue_t                                                             mapped_type;
+
+    typedef JGridCollection<JElement2D<JKey_t, JValue_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;
+
+
+    /**
+     * Default constructor.
+     */
+    JGridMap()
+    {}
+  };
+
+
+  /**
+   * Specialisation of JMapCollection for JGridMap.
+   */
+  template<>
+  struct JMapCollection<JGridMap> {
+    /**
+     * Collection of elements.
+     */
+    template<class JElement_t, 
+	     class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+    struct collection_type :
+      public JGridCollection<JElement_t, JDistance_t>
+    {};
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JHermiteSpline.hh b/jpp/JTools/JHermiteSpline.hh
new file mode 100644
index 0000000..e908e0a
--- /dev/null
+++ b/jpp/JTools/JHermiteSpline.hh
@@ -0,0 +1,706 @@
+#ifndef __JTOOLS__JHERMITESPLINE__
+#define __JTOOLS__JHERMITESPLINE__
+
+#include <utility>
+#include <cmath>
+
+#include "JMath/JZero.hh"
+#include "JLang/JException.hh"
+#include "JLang/JClass.hh"
+#include "JTools/JFunctional.hh"
+#include "JTools/JDistance.hh"
+#include "JTools/JResult.hh"
+#include "JTools/JMapCollection.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JNoValue;
+  using JLANG::JDivisionByZero;
+  using JLANG::JFunctionalException;
+  using JLANG::JValueOutOfRange;
+
+
+  /**
+   * Template base class spline interpolations.
+   *
+   * This class implements the JFunctional interface.
+   *
+   * Note that the data structure of the elements in the collection should have the additional methods:
+   * <pre>
+   *     ordinate_type getU() const;
+   *     void setU(ordinate_type u);
+   * </pre>
+   * to get and set the derivatives, respectively.
+   *
+   * Note that -by default- the compilation is for a monotonous interpolation.
+   */
+  template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JHermiteSplineCollection :
+    public JCollection_t<JElement_t, JDistance_t>,
+    public virtual JFunctional<>
+  {
+  public:
+
+    typedef JCollection_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::distance_type                              distance_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;
+ 
+    using JFunctional<>::compile;
+
+
+    /**
+     * Determination of derivatives.
+     *
+     * \param  monotone        monotone
+     */
+    void compile(const bool monotone)
+    {
+      using namespace std;
+      
+      if (this->size() >= 2u) {
+
+	{
+	  iterator         j = this->begin(), i = j++;
+
+	  i->setU((j->getY() - i->getY()) / this->getDistance(i->getX(), j->getX()));
+	}		
+
+	{
+	  reverse_iterator j = this->rbegin(), i = j++;
+
+	  i->setU((j->getY() - i->getY()) / this->getDistance(i->getX(), j->getX()));
+	}	
+	
+	for (iterator k = this->begin(), i = k++, j = k++; k != this->end(); ++i, ++j, ++k) {
+	  j->setU(0.5 * ((j->getY() - i->getY()) / this->getDistance(i->getX(), j->getX()) +
+			 (k->getY() - j->getY()) / this->getDistance(j->getX(), k->getX())));
+	}
+
+	if (monotone) {
+	  
+	  for (iterator j = this->begin(), i = j++; j != this->end(); ++i, ++j) {
+	    if (i->getY() == j->getY()) {
+	      j->setU(JMATH::zero);
+	    }
+	  }
+
+	  for (iterator j = this->begin(), i = j++; j != this->end(); ++i, ++j) {
+
+	    const ordinate_type u = (j->getY() - i->getY()) / this->getDistance(i->getX(), j->getX());
+	    const ordinate_type w = (i->getU()*i->getU() + j->getU()*j->getU());
+	    
+	    if (w > 9.0*u*u) {
+
+	      const ordinate_type v = 3.0*u/sqrt(w);
+
+	      i->setU(v*i->getU());
+	      j->setU(v*j->getU());
+	    }
+	  }
+	}
+      }
+    }
+    
+
+  protected:
+    
+    static abscissa_type h00 (abscissa_type t)  { return (1.0 + 2*t) * (1.0 - t) * (1.0 - t); }
+    static abscissa_type h10 (abscissa_type t)  { return t * (1.0 - t) * (1.0 - t); }
+    static abscissa_type h01 (abscissa_type t)  { return t * t * (3.0 - 2*t); }
+    static abscissa_type h11 (abscissa_type t)  { return t * t * (t - 1.0); }
+
+    static abscissa_type h00p(abscissa_type t)  { return 6 * t * (t - 1.0); }
+    static abscissa_type h10p(abscissa_type t)  { return t * (3*t - 4.0) + 1.0; }
+    static abscissa_type h01p(abscissa_type t)  { return 6 * t * (1.0 -t); }
+    static abscissa_type h11p(abscissa_type t)  { return t * (3*t - 2.0); }
+    
+    static abscissa_type H00 (abscissa_type t)  { return t * (t * t * (0.5*t - 1.0) + 1.0); } 
+    static abscissa_type H10 (abscissa_type t)  { return t * t * (t * (0.25*t - 2.0/3.0) + 0.5); }
+    static abscissa_type H01 (abscissa_type t)  { return t * t * t * (1.0 - 0.5*t); }
+    static abscissa_type H11 (abscissa_type t)  { return t * t * t * (0.25*t - 1.0/3.0); }
+
+    
+    /**
+     * Default constructor.
+     */
+    JHermiteSplineCollection()
+    {}
+
+
+    /**
+     * Determination of derivatives.
+     */
+    virtual void do_compile() override 
+    {
+      compile(true);
+    }
+  };
+
+
+  /**
+   * Template definition for functional collection with spline interpolation.
+   */
+  template<class JElement_t, 
+	   template<class, class> class JCollection_t,
+	   class JResult_t,
+           class JDistance_t>
+  class JHermiteSplineFunction;
+
+
+  /**
+   * Template specialisation for functional collection with spline interpolation.
+   */
+  template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JHermiteSplineFunction<JElement_t, 
+			       JCollection_t, 
+			       typename JResultType<typename JElement_t::ordinate_type>::result_type,
+			       JDistance_t> :
+    public JHermiteSplineCollection<JElement_t, JCollection_t, JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type, 
+		     typename JResultType<typename JElement_t::ordinate_type>::result_type>
+  {
+  public:
+
+    typedef JHermiteSplineCollection<JElement_t, JCollection_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, data_type>                                  function_type;  
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+    
+
+    /**
+     * Default constructor.			
+     */
+    JHermiteSplineFunction()
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const override 
+    {
+      if (this->size() <= 1u) {
+        return this->getExceptionHandler().action(JFunctionalException("JHermiteSplineFunction<>::evaluate() not enough data."));
+      }
+
+      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("JHermiteSplineFunction::evaluate() x out of range."));
+      }
+
+      const_iterator q = p--;
+
+      const double dx = this->getDistance(p->getX(), q->getX());
+      const double t  = this->getDistance(p->getX(), x) / dx;
+
+      return h00(t)*p->getY() + h10(t)*p->getU()*dx + h01(t)*q->getY() + h11(t)*q->getU()*dx;
+    }
+
+  protected:
+    
+    using collection_type::h00;
+    using collection_type::h10;
+    using collection_type::h01;
+    using collection_type::h11;
+  };
+
+
+  /**
+   * Template specialisation for spline interpolation method with returning JResultDerivative data structure.
+   */
+  template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JHermiteSplineFunction<JElement_t,
+			       JCollection_t,
+			       JResultDerivative<typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			       JDistance_t> :
+    public JHermiteSplineCollection<JElement_t, JCollection_t, JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type, 
+		     JResultDerivative<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
+  {
+  public:
+
+    typedef JHermiteSplineCollection<JElement_t, JCollection_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, JResultDerivative<data_type> >              function_type;
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JHermiteSplineFunction() 
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const override 
+    {
+      if (this->size() <= 1u) {
+        return this->getExceptionHandler().action(JFunctionalException("JHermiteSplineFunction<>::evaluate() not enough data."));
+      }
+
+      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("JHermiteSplineFunction::evaluate() x out of range."));
+      }
+
+      const_iterator q = p--;
+
+      const double dx = this->getDistance(p->getX(), q->getX());
+      const double t  = this->getDistance(p->getX(), x) / dx;
+
+      result.f  = h00 (t)*p->getY()    + h10 (t)*p->getU()*dx + h01 (t)*q->getY()    + h11 (t)*q->getU()*dx;
+      result.fp = h00p(t)*p->getY()/dx + h10p(t)*p->getU()    + h01p(t)*q->getY()/dx + h11p(t)*q->getU();
+
+      return result;
+    }
+
+    
+  protected:
+    
+    using collection_type::h00;
+    using collection_type::h10;
+    using collection_type::h01;
+    using collection_type::h11;
+
+    using collection_type::h00p;
+    using collection_type::h10p;
+    using collection_type::h01p;
+    using collection_type::h11p;
+    
+  private:
+    mutable result_type result;
+  };
+
+
+  /**
+   * Template specialisation for spline interpolation method with returning JResultPDF data structure.
+   *
+   * Note that the data structure of the elements in the collection should have the additional methods:
+   * <pre>
+   *     ordinate_type getIntegral() const;
+   *     void setIntegral(ordinate_type v);
+   * </pre>
+   * to get and set the integral values, respectively.
+   */
+  template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JHermiteSplineFunction<JElement_t,
+			       JCollection_t,
+			       JResultPDF<typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			       JDistance_t> :
+    public JHermiteSplineCollection<JElement_t, JCollection_t, JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type, 
+		     JResultPDF<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
+  {
+  public:
+
+    typedef JHermiteSplineCollection<JElement_t, JCollection_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, JResultPDF<data_type> >                     function_type;
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+ 
+
+    /**
+     * Default constructor.			
+     */
+    JHermiteSplineFunction() 
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const override 
+    {
+      if (this->size() <= 1u) {
+        return this->getExceptionHandler().action(JFunctionalException("JHermiteSplineFunction<>::evaluate() not enough data."));
+      }
+      
+      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("JHermiteSplineFunction1D<>::operator() x < xmin."));
+
+	  // overwrite integral values
+
+	  result.v = 0;
+	  result.V = this->rbegin()->getIntegral();
+
+	} catch(const JValueOutOfRange& exception) {
+	  throw exception;
+	}
+
+	return result;
+
+      } else if (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision) {
+
+	try {
+
+	  result   = this->getExceptionHandler().action(JValueOutOfRange("JHermiteSplineFunction1D<>::operator() x > xmax."));
+
+	  // overwrite integral values
+
+	  result.v = this->rbegin()->getIntegral();
+	  result.V = this->rbegin()->getIntegral();
+
+	} catch(const JValueOutOfRange& exception) {
+	  throw exception;
+	}
+
+	return result;
+      }
+
+      const_iterator q = p--;
+
+      const double dx = this->getDistance(p->getX(), q->getX());
+      const double t  = this->getDistance(p->getX(), x) / dx;
+
+      result.f   =   h00 (t)*p->getY()    + h10 (t)*p->getU()*dx + h01 (t)*q->getY()    + h11 (t)*q->getU()*dx;
+      result.fp  =   h00p(t)*p->getY()/dx + h10p(t)*p->getU()    + h01p(t)*q->getY()/dx + h11p(t)*q->getU();
+      result.v   = (p->getIntegral() +
+		    (H00 (t)*p->getY()    + H10 (t)*p->getU()*dx + H01 (t)*q->getY()    + H11 (t)*q->getU()*dx)*dx);
+      result.V   =   this->rbegin()->getIntegral();
+
+      return result;
+    }
+
+
+  protected:
+
+    using collection_type::h00;
+    using collection_type::h10;
+    using collection_type::h01;
+    using collection_type::h11;
+
+    using collection_type::h00p;
+    using collection_type::h10p;
+    using collection_type::h01p;
+    using collection_type::h11p;
+
+    using collection_type::H00;
+    using collection_type::H10;
+    using collection_type::H01;
+    using collection_type::H11;
+
+    /**
+     * Determination of derivatives.
+     */
+    virtual void do_compile() override 
+    {
+      if (!this->empty()) {
+
+	collection_type::do_compile();
+ 
+	this->begin()->setIntegral(JMATH::zero);
+
+	for (iterator j = this->begin(), i = j++; j != this->end(); ++i, ++j) {
+	  
+	  const double        dx = this->getDistance(i->getX(), j->getX());
+	  const ordinate_type y  = i->getY() + j->getY();
+	  const ordinate_type z  = i->getU() - j->getU();
+	
+	  const ordinate_type v = dx * 0.50 * y;
+	  const ordinate_type w = dx * 1.00 * z*dx/12.0;
+
+	  j->setIntegral(i->getIntegral() + v + w);
+	}
+      }
+    }
+
+  private:
+    mutable result_type result;
+  };
+
+
+  /**
+   * Template class for spline interpolation in 1D
+   *
+   * This class implements the JFunction1D interface.
+   */
+  template<class JElement_t,
+	   template<class, class> class JCollection_t,
+	   class JResult_t   = typename JElement_t::ordinate_type,
+	   class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  class JHermiteSplineFunction1D :
+    public JHermiteSplineFunction<JElement_t, JCollection_t, JResult_t, JDistance_t>,
+    public JFunction1D<typename JElement_t::abscissa_type, JResult_t> 
+  {
+  public:
+
+    typedef JHermiteSplineCollection<JElement_t, JCollection_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::distance_type                              distance_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 JFunction1D<abscissa_type, JResult_t>                                function_type;           
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+
+    /**
+     * Default contructor.
+     */
+    JHermiteSplineFunction1D()
+    {}
+  };
+
+
+  /**
+   * Functional map with spline interpolation.
+   */
+  template<class JKey_t,
+           class JValue_t,
+           template<class, class, class> class JMap_t,
+           class JResult_t,
+           class JDistance_t = JDistance<JKey_t> >
+  class JHermiteSplineMap :
+    public JMap_t<JKey_t, JValue_t, JDistance_t>,
+    public JFunction<JKey_t, JResult_t>
+  {
+  public:
+
+    typedef JMap_t<JKey_t, JValue_t, JDistance_t>                                collection_type;
+    typedef JFunction<JKey_t, JResult_t>                                         function_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::distance_type                              distance_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 typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+    typedef typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JHermiteSplineFunction1D<JSplineElement2D<argument_type, data_type>, 
+				     JMapCollection<JMap_t>::template collection_type,
+				     result_type>                                JHermiteSplineFunction1D_t;
+
+
+    /**
+     * Default constructor.
+     */
+    JHermiteSplineMap() 
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const override 
+    {
+      const argument_type x = *pX;
+
+      ++pX;  // next argument value
+
+      const_iterator p = this->begin();
+
+      for (typename JHermiteSplineFunction1D_t::iterator q = buffer.begin(); q != buffer.end(); ++q, ++p) {
+	q->getY() = JFunction<argument_type, data_type>::getValue(p->getY(), pX);
+      }
+
+      buffer.compile();
+
+      return buffer(x);
+    }
+
+
+  private:
+    /**
+     * Function compilation.
+     */
+    virtual void do_compile() override 
+    {
+      buffer.clear();
+
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	buffer.put(i->getX(), data_type());
+      }
+    }
+
+
+    mutable JHermiteSplineFunction1D_t buffer;
+  };
+
+
+  /**
+   * Conversion of data points to integral values.
+   *
+   * The integration includes the use of 2nd derivatives of the data points of the input spline interpolating function.
+   *
+   * \param  input             collection   
+   * \param  output            mappable collection
+   * \return                   integral
+   */
+  template<class JElement_t,
+           template<class, class> class JCollection_t,
+           class JResult_t,
+           class JDistance_t>
+  inline typename JElement_t::ordinate_type 
+  integrate(const JHermiteSplineFunction1D<JElement_t, JCollection_t, JResult_t, JDistance_t>& input, 
+	    typename JMappable<JElement_t>::map_type&                                   output)
+  {
+    typedef typename JElement_t::ordinate_type                                                             ordinate_type;
+    typedef typename JHermiteSplineFunction1D<JElement_t, JCollection_t, JResult_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) {
+	
+	const double        dx = input.getDistance(i->getX(), j->getX());
+	const ordinate_type y  = i->getY() + j->getY();
+	const ordinate_type z  = i->getU() - j->getU();
+	
+	const ordinate_type v = dx * 0.50 * y;
+	const ordinate_type w = dx * 1.00 * z*dx/12.0;
+	
+	V += v + w;
+	
+	output.put(j->getX(), V);
+      }
+    }
+    
+    return V;
+  }
+  
+
+  /**
+   * Conversion of data points to integral values.
+   *
+   * The integration directly uses the integral values of the input spline interpolating function.
+   *
+   * \param  input             collection   
+   * \param  output            mappable collection
+   * \return                   integral
+   */
+  template<class JElement_t,
+           template<class, class> class JCollection_t,
+           class JDistance_t>
+  inline typename JElement_t::ordinate_type
+  integrate(const JHermiteSplineFunction1D<JElement_t, JCollection_t, JResultPDF<typename JElement_t::ordinate_type>, JDistance_t>& input,
+	    typename JMappable<JElement_t>::map_type&                                                                               output)
+  {
+    typedef typename JElement_t::ordinate_type                                                                      ordinate_type;
+    typedef JResultPDF<ordinate_type>                                                                               result_type;
+    typedef typename JHermiteSplineFunction1D<JElement_t, JCollection_t, result_type, JDistance_t>::const_iterator  const_iterator;
+    
+    if (input.getSize() > 1) {
+      
+      for (const_iterator i = input.begin(); i != input.end(); ++i) {
+        output.put(i->getX(), i->getIntegral());
+      }
+
+      return input.rbegin()->getIntegral();
+    }
+    
+    return JMATH::zero;
+  }
+}
+
+#endif
diff --git a/jpp/JTools/JHistogram.hh b/jpp/JTools/JHistogram.hh
new file mode 100644
index 0000000..224f5e6
--- /dev/null
+++ b/jpp/JTools/JHistogram.hh
@@ -0,0 +1,234 @@
+#ifndef __JTOOLS__JHISTOGRAM__
+#define __JTOOLS__JHISTOGRAM__
+
+#include "JLang/JClass.hh"
+#include "JMath/JZero.hh"
+#include "JIO/JSerialisable.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JIO::JReader;
+  using JIO::JWriter;
+
+
+  /**
+   * Template definition of histogram object interface.
+   * This class also comprises auxiliary data.
+   */
+  template<class JAbscissa_t, class JContents_t>
+  class JHistogram
+  {
+  protected:
+    /**
+     * Default constructor.
+     */
+    JHistogram() :
+      underflow(JMATH::zero),
+      overflow (JMATH::zero),
+      integral (JMATH::zero)
+    {}
+
+
+  public:
+
+    typedef JAbscissa_t                                   abscissa_type;
+    typedef JContents_t                                   contents_type;
+
+
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JHistogram()
+    {}
+
+
+    /**
+     * Histogram filling.
+     *
+     * \param  pX              pointer to abscissa values
+     * \param  w               weight
+     */
+    virtual void evaluate(const abscissa_type* pX,
+			  typename JLANG::JClass<contents_type>::argument_type w) = 0;
+
+
+    /**
+     * Add histogram.
+     *
+     * \param  histogram       histogram
+     * \return                 this histogram
+     */
+    JHistogram& add(const JHistogram& histogram)
+    {
+      this->underflow += histogram.underflow;
+      this->overflow  += histogram.overflow;
+      this->integral  += histogram.integral;
+
+      return *this;
+    }
+
+
+    /**
+     * Subtract histogram.
+     *
+     * \param  histogram       histogram
+     * \return                 this histogram
+     */
+    JHistogram& sub(const JHistogram& histogram)
+    {
+      this->underflow -= histogram.underflow;
+      this->overflow  -= histogram.overflow;
+      this->integral  -= histogram.integral;
+
+      return *this;
+    }
+
+
+    /**
+     * Scale histogram.
+     *
+     * \param  value           multiplication factor
+     * \return                 this histogram
+     */
+    JHistogram& mul(const double value)
+    {
+      this->underflow *= value;
+      this->overflow  *= value;
+      this->integral  *= value;
+
+      return *this;
+    }
+
+
+    /**
+     * Scale histogram.
+     *
+     * \param  value           division factor
+     * \return                 this histogram
+     */
+    JHistogram& div(double value)
+    {
+      this->underflow /= value;
+      this->overflow  /= value;
+      this->integral  /= value;
+
+      return *this;
+    }
+
+
+    /**
+     * Get contents below lower limit.
+     *
+     * \return                 contents
+     */
+    const contents_type& getUnderflow() const
+    {
+      return underflow;
+    }
+
+    
+    /**
+     * Get contents above upper limit.
+     *
+     * \return                 contents
+     */
+    const contents_type& getOverflow() const
+    {
+      return overflow;
+    }
+
+    
+    /**
+     * Get contents above upper limit.
+     *
+     * \return                 contents
+     */
+    const contents_type& getIntegral() const
+    {
+      return integral;
+    }
+
+
+    /**
+     * Read histogram from input.
+     *
+     * \param  in              reader
+     * \param  object          histogram
+     * \return                 reader
+     */
+    friend inline JReader& operator>>(JReader& in, JHistogram& object)
+    {
+      in >> object.underflow;
+      in >> object.overflow;
+      in >> object.integral;
+
+      return in;
+    }
+
+
+    /**
+     * Write histogram to output.
+     *
+     * \param  out             writer
+     * \param  object          histogram
+     * \return                 writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JHistogram& object)
+    {
+      out << object.underflow;
+      out << object.overflow;
+      out << object.integral;
+
+      return out;
+    }
+
+
+  protected:
+    contents_type underflow;
+    contents_type overflow;
+    contents_type integral;
+  };
+
+
+  /**
+   * Functional histogram cumulator.
+   */
+  struct JCumulator {
+    /**
+     * Default constructor.
+     */
+    JCumulator()
+    {}
+
+
+    /**    
+     * Compile function.
+     *
+     * \param  function          function
+     * \return                   this cumulator
+     */
+    template<class JHistogram_t>
+    const JCumulator& operator()(JHistogram_t& function) const
+    {
+      function.cumlative();
+
+      return *this;
+    }
+  };
+
+  
+  /**
+   * Function object for functional object compilation.
+   */
+  static const JCumulator cumulator;
+}
+
+#endif
diff --git a/jpp/JTools/JHistogramMap.hh b/jpp/JTools/JHistogramMap.hh
new file mode 100644
index 0000000..56efe4a
--- /dev/null
+++ b/jpp/JTools/JHistogramMap.hh
@@ -0,0 +1,144 @@
+#ifndef __JTOOLS__JHISTOGRAMMAP__
+#define __JTOOLS__JHISTOGRAMMAP__
+
+#include "JLang/JClass.hh"
+#include "JTools/JHistogram.hh"
+#include "JTools/JDistance.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+
+  /**
+   * Histogram map.
+   *
+   * This class implements the JHistogram interface.
+   */
+  template<class JAbscissa_t,
+	   class JContents_t,
+	   template<class, class, class> class JMap_t,
+	   class JDistance_t = JDistance<JAbscissa_t> >
+  class JHistogramMap :
+    public JMap_t<JAbscissa_t, JContents_t, JDistance_t>,
+    public JHistogram<JAbscissa_t, typename JContents_t::contents_type>
+  {
+  public:
+
+    typedef JMap_t<JAbscissa_t, JContents_t, JDistance_t>                        collection_type;
+    typedef JHistogram<JAbscissa_t, typename JContents_t::contents_type>         histogram_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 typename histogram_type::abscissa_type                               abscissa_type;
+    typedef typename histogram_type::contents_type                               contents_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JHistogramMap()
+    {}
+
+
+    /**
+     * Fill histogram.
+     *
+     * \param  pX              pointer to abscissa values
+     * \param  w               weight
+     */
+    virtual void evaluate(const abscissa_type* pX,
+			  typename JLANG::JClass<contents_type>::argument_type w)
+    {
+      const abscissa_type x = *pX;
+
+      iterator p = this->lower_bound(x);
+
+      this->integral  += w;
+
+      if      (p == this->begin()) 
+	this->underflow += w;
+      else if (p == this->end()) 
+	this->overflow  += w;
+      else 
+	(--p)->getY().evaluate(++pX, w);
+    }    
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  factor          multiplication factor
+     * \return                 this histogram
+     */
+    JHistogramMap& mul(typename JLANG::JClass<contents_type>::argument_type factor)
+    {
+      collection_type::mul(factor);
+      histogram_type ::mul(factor);
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  factor          division factor
+     * \return                 this histogram
+     */
+    JHistogramMap& div(typename JLANG::JClass<contents_type>::argument_type factor)
+    {
+      collection_type::div(factor);
+      histogram_type ::div(factor);
+
+      return *this;
+    }
+
+
+    /**
+     * Read histogram map from input.
+     *
+     * \param  in              reader
+     * \param  object          histogram map
+     * \return                 reader
+     */
+    friend inline JReader& operator>>(JReader& in, JHistogramMap& object)
+    {
+      in >> static_cast<histogram_type&> (object);
+      in >> static_cast<collection_type&>(object);
+
+      return in;
+    }
+
+
+    /**
+     * Write histogram map to output.
+     *
+     * \param  out             writer
+     * \param  object          histogram map
+     * \return                 writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JHistogramMap& object)
+    {
+      out << static_cast<const histogram_type&> (object);
+      out << static_cast<const collection_type&>(object);
+
+      return out;
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JMap.hh b/jpp/JTools/JMap.hh
new file mode 100644
index 0000000..72a077c
--- /dev/null
+++ b/jpp/JTools/JMap.hh
@@ -0,0 +1,126 @@
+#ifndef __JTOOLS__JMAP__
+#define __JTOOLS__JMAP__
+
+#include "JTools/JCollection.hh"
+#include "JTools/JMapCollection.hh"
+#include "JTools/JElement.hh"
+#include "JMath/JMath.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JMATH::JMath;
+
+
+  /**
+   * Map of pair-wise elements.
+   *
+   * The key_type and mapped_type refer to the pair-wise element of this map, respectively.
+   */
+  template<class JKey_t,
+	   class JValue_t,
+	   class JDistance_t = JDistance<JKey_t> >
+  class JMap :
+    public JCollection<JElement2D<JKey_t, JValue_t>, JDistance_t>,
+    public JMath< JMap<JKey_t, JValue_t, JDistance_t> >
+  {
+  public:
+
+    typedef JKey_t                                                               key_type;
+    typedef JValue_t                                                             mapped_type;
+    
+    typedef JCollection<JElement2D<JKey_t, JValue_t>, JDistance_t>               container_type;
+
+    typedef typename container_type::const_iterator                              const_iterator;
+    typedef typename container_type::const_reverse_iterator                      const_reverse_iterator;
+    typedef typename container_type::iterator                                    iterator;
+    typedef typename container_type::reverse_iterator                            reverse_iterator;
+
+
+    /**
+     * Default constructor.
+     */
+    JMap()
+    {}
+
+
+    /**
+     * Add map.
+     *
+     * \param  map             map
+     * \return                 this map
+     */
+    JMap& add(const JMap& map)
+    {
+      static_cast<container_type&>(*this).add(static_cast<const container_type&>(map));
+
+      return *this;
+    }
+ 
+
+    /**
+     * Subtract map.
+     *
+     * \param  map             map
+     * \return                 this map
+     */
+    JMap& sub(const JMap& map)
+    {
+      static_cast<container_type&>(*this).sub(static_cast<const container_type&>(map));
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           multiplication factor
+     * \return                 this map
+     */
+    JMap& mul(const double value)
+    {
+      static_cast<container_type&>(*this).mul(value);
+
+      return *this;
+    }
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           division factor
+     * \return                 this map
+     */
+    JMap& div(const double value)
+    {
+      static_cast<container_type&>(*this).div(value);
+
+      return *this;
+    }
+  };
+
+
+  /**
+   * Specialisation of JMapCollection for JMap.
+   */
+  template<>
+  struct JMapCollection<JMap> {
+    /**
+     * Collection of elements.
+     */
+    template<class JElement_t, 
+	     class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+    struct collection_type :
+      public JCollection<JElement_t, JDistance_t>
+    {};
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JMapCollection.hh b/jpp/JTools/JMapCollection.hh
new file mode 100644
index 0000000..cf55747
--- /dev/null
+++ b/jpp/JTools/JMapCollection.hh
@@ -0,0 +1,23 @@
+#ifndef __JTOOLS__JMAPCOLLECTION__
+#define __JTOOLS__JMAPCOLLECTION__
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  /**
+   * Template class to define the corresponding JCollection for a given template JMap.
+   *
+   * This class should be specialised for each map type so that the implementation
+   * of an interpolation method based on a collection can directly be transferred to a map.
+   */
+  template<template<class, class, class> class JMap_t>
+  struct JMapCollection;
+}
+
+#endif
diff --git a/jpp/JTools/JMapList.hh b/jpp/JTools/JMapList.hh
new file mode 100644
index 0000000..6559dab
--- /dev/null
+++ b/jpp/JTools/JMapList.hh
@@ -0,0 +1,149 @@
+#ifndef __JTOOLS__JMAPLIST__
+#define __JTOOLS__JMAPLIST__
+
+#include "JLang/JNullType.hh"
+#include "JTools/JDistance.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JNullType;
+  
+
+  /**
+   * Map list.
+   */
+  template<template<class, class, class> class JHead_t, class JTail_t = JNullType>
+  struct JMapList
+  {
+    typedef JMapList<JHead_t, typename JTail_t::head_list>   head_list;   //!< first N-1 maps
+    typedef typename JTail_t::tail_type                      tail_type;   //!< last  map
+  };
+
+
+  /**
+   * Terminator class of map list.
+   */
+  template<template<class, class, class> class JHead_t>
+  struct JMapList<JHead_t, JNullType>
+  {
+    typedef JNullType                                        head_list;   //!< first N-1 maps
+    typedef JMapList<JHead_t>                                tail_type;   //!< last  map
+  };
+
+
+  /**
+   * Length of map list.
+   */
+  template<class JMaplist_t> struct JMapLength {};
+
+
+  /**
+   * Recursive length of map list.
+   */
+  template<template<class, class, class> class JHead_t, class JTail_t>
+  struct JMapLength< JMapList<JHead_t, JTail_t> >
+  {
+    enum { value = 1 + JMapLength<JTail_t>::value };
+  };
+
+
+  /**
+   * Terminator class of length of map list.
+   */
+  template<template<class, class, class> class JHead_t>
+  struct JMapLength< JMapList<JHead_t, JNullType> >
+  {
+    enum { value = 1 };
+  };
+
+
+  /**
+   * Auxiliary class for no map definition.
+   * This class can be used to terminate a map list, define a default template argument, etc.
+   */
+  template<class JKey_t,
+	   class JValue_t,
+	   class JDistance_t = JDistance<JKey_t> >
+  struct JNullMap {};
+
+  
+  /**
+   * Auxiliary class for recursive map list generation.
+   * This class accepts up to 26 map types.
+   */
+  template<template<class, class, class> class A = JNullMap,
+	   template<class, class, class> class B = JNullMap,
+	   template<class, class, class> class C = JNullMap,
+	   template<class, class, class> class D = JNullMap,
+	   template<class, class, class> class E = JNullMap,
+	   template<class, class, class> class F = JNullMap,
+	   template<class, class, class> class G = JNullMap,
+	   template<class, class, class> class H = JNullMap,
+	   template<class, class, class> class I = JNullMap,
+	   template<class, class, class> class J = JNullMap,
+	   template<class, class, class> class K = JNullMap,
+	   template<class, class, class> class L = JNullMap,
+	   template<class, class, class> class M = JNullMap,
+	   template<class, class, class> class N = JNullMap,
+	   template<class, class, class> class O = JNullMap,
+	   template<class, class, class> class P = JNullMap,
+	   template<class, class, class> class Q = JNullMap,
+	   template<class, class, class> class R = JNullMap,
+	   template<class, class, class> class S = JNullMap,
+	   template<class, class, class> class T = JNullMap,
+	   template<class, class, class> class U = JNullMap,
+	   template<class, class, class> class V = JNullMap,
+	   template<class, class, class> class W = JNullMap,
+	   template<class, class, class> class X = JNullMap,
+	   template<class, class, class> class Y = JNullMap,
+	   template<class, class, class> class Z = JNullMap>
+  struct JMAPLIST
+  {
+    typedef JMapList<A, typename JMAPLIST<B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z>::maplist>  maplist;  //!< Map list
+  };
+
+  
+  /**
+   * Template specialisation to terminate recursive map list generation.
+   */
+  template<template<class, class, class> class A>
+  struct JMAPLIST<A,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap,
+		  JNullMap>
+  {
+    typedef JMapList<A>  maplist;  //!< Map list
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JMappableCollection.hh b/jpp/JTools/JMappableCollection.hh
new file mode 100644
index 0000000..3a67c49
--- /dev/null
+++ b/jpp/JTools/JMappableCollection.hh
@@ -0,0 +1,118 @@
+#ifndef __JTOOLS__JMAPPABLECOLLECTION__
+#define __JTOOLS__JMAPPABLECOLLECTION__
+
+#include "JLang/JClass.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JClass;
+
+
+  /**
+   * Template interface definition for associative collection of elements.
+   * The concrete associative collection should implement the following methods.
+   * <pre> 
+   *             void clear();
+   *
+   *             mapped_type& get(key_type key);
+   * </pre>
+   * This class implements the operator <tt>[key_type key]</tt> and method <tt>put(key_type key, mapped_type value)</tt>.
+   */
+  template<class JKey_t, class JValue_t>
+  struct JMappableCollection
+  {
+
+    typedef JKey_t                                               key_type;
+    typedef JValue_t                                             mapped_type;
+
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JMappableCollection()
+    {}
+
+
+    /**
+     * Clear.
+     */
+    virtual void clear() = 0;
+
+
+    /**
+     * Get mapped value.
+     *
+     * \param  key             key
+     * \return                 value
+     */
+    virtual const mapped_type& get(typename JClass<key_type>::argument_type key) const = 0;
+
+
+    /**
+     * Get mapped value.
+     *
+     * \param  key             key
+     * \return                 value
+     */
+    virtual mapped_type& get(typename JClass<key_type>::argument_type key) = 0;
+
+
+    /**
+     * Get mapped value.
+     *
+     * \param  key             key
+     * \return                 value
+     */
+    const mapped_type& operator[](typename JClass<key_type>::argument_type key) const
+    {
+      return get(key);
+    }
+
+
+    /**
+     * Get mapped value.
+     *
+     * \param  key             key
+     * \return                 value
+     */
+    mapped_type& operator[](typename JClass<key_type>::argument_type key) 
+    {
+      return get(key);
+    }
+
+
+    /**
+     * Put pair-wise element (key,value) into collection. 
+     *
+     * \param  key             key
+     * \param  value           value
+     */
+    void put(typename JClass<key_type>   ::argument_type key,
+	     typename JClass<mapped_type>::argument_type value)
+    {
+      get(key) = value;
+    }
+  };
+
+
+  /**
+   * Auxiliary class to define JMappableCollection for given template.
+   */
+  template<class T>
+  struct JMappable {
+    /**
+     * Type definition of JMappableCollection.
+     */
+    typedef JMappableCollection<typename T::abscissa_type, 
+				typename T::ordinate_type>   map_type;
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JMultiFunction.hh b/jpp/JTools/JMultiFunction.hh
new file mode 100644
index 0000000..715fed8
--- /dev/null
+++ b/jpp/JTools/JMultiFunction.hh
@@ -0,0 +1,354 @@
+#ifndef __JTOOLS__JMULTIFUNCTION__
+#define __JTOOLS__JMULTIFUNCTION__
+
+#include "JTools/JMultiMap.hh"
+#include "JTools/JFunctional.hh"
+#include "JTools/JConstantFunction1D.hh"
+#include "JTools/JArray.hh"
+#include "JTools/JMultiHistogram.hh"
+#include "JTools/JHistogramMap.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+ 
+  /**
+   * Multidimensional interpolation method.
+   *
+   * The template parameters respectively refer to:
+   * -# function object used for the lowest dimension(s);
+   * -# list of functional maps used for the higher dimension(s); and  
+   * -# distance operator.
+   *
+   * The number of dimensions of this function object is equal to the length of
+   * the given map list plus the extra dimensions of the first function object.
+   * When converting a multidimensional histogram to a multidimensional function for 
+   * subsequent interpolations, the function object used for the lowest dimension(s) 
+   * is treated as a probability density function.
+   */
+  template<class JFunction_t, 
+	   class JMaplist_t, 
+	   class JDistance_t = JDistance<typename JFunction_t::argument_type> >
+  class JMultiFunction :
+    public JMultiMap<typename JFunction_t::argument_type, JFunction_t, JMaplist_t, JDistance_t>
+  {
+  public:
+    
+    typedef JMultiMap<typename JFunction_t::argument_type, 
+		      JFunction_t, 
+		      JMaplist_t,
+		      JDistance_t>                                        multimap_type;
+
+    enum { NUMBER_OF_DIMENSIONS = JMapLength<JMaplist_t>::value + JFunction_t::NUMBER_OF_DIMENSIONS };
+
+    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 multimap_type::abscissa_type                         abscissa_type;
+    typedef typename multimap_type::ordinate_type                         ordinate_type;
+    typedef typename multimap_type::result_type                           result_type;
+
+    typedef typename multimap_type::const_iterator                        const_iterator;
+    typedef typename multimap_type::const_reverse_iterator                const_reverse_iterator;
+    typedef typename multimap_type::iterator                              iterator;
+    typedef typename multimap_type::reverse_iterator                      reverse_iterator;
+
+    typedef typename multimap_type::super_iterator                        super_iterator;
+    typedef typename multimap_type::super_const_iterator                  super_const_iterator;
+
+    using multimap_type::insert;
+
+
+    /**
+     * Default constructor.
+     */
+    JMultiFunction()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  input                multidimensional input
+     */
+    template<class T>
+    JMultiFunction(const T& input) 
+    {
+      insert(input);
+
+      this->compile();
+    }
+
+
+    /**
+     * Get multidimensional function.
+     *
+     * \return                      this multidimensional function
+     */
+    const JMultiFunction& getMultiFunction() const
+    {
+      return static_cast<const JMultiFunction&>(*this);
+    }
+
+
+    /**
+     * Get multidimensional function.
+     *
+     * \return                      this multidimensional function
+     */
+    JMultiFunction& getMultiFunction() 
+    {
+      return static_cast<JMultiFunction&>(*this);
+    }
+
+
+    /**
+     * Insert multidimensional input.
+     *
+     * \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) 
+    {
+      copy(input, *this);
+    }
+
+    
+    /**
+     * Insert multidimensional input.
+     *
+     * \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)
+    {
+      this->insert(JMultiKey<0, argument_type>(), input);
+    }
+
+
+    /**
+     * Compilation.
+     */
+    void compile() 
+    {
+      this->for_each(compiler);
+
+      for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) {
+	(*i).getValue().compile();
+      }
+    }
+
+
+    /**
+     * Set the supervisor for handling of exceptions.
+     *
+     * \param  supervisor      supervisor
+     */
+    void setExceptionHandler(const supervisor_type& supervisor)
+    {
+      this->for_each(supervisor);
+
+      for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) {
+	(*i).getValue().setExceptionHandler(supervisor);
+      }
+    }
+
+
+    /**
+     * Multi-dimensional interpolation method call.
+     *
+     * \param  args            comma seperated list of abscissa values
+     * \return                 function value
+     */
+    template<class ...Args>
+    result_type operator()(const Args& ...args) const
+    {
+      return this->evaluate(JArray<NUMBER_OF_DIMENSIONS, argument_type>(args...).data());
+    }
+
+
+  protected:
+    /**
+     * Insert multidimensional histogram at multidimensional key.
+     *
+     * \param  key                  multidimensional key
+     * \param  input                multidimensional histogram
+     */
+    template<unsigned int N,
+	     class __JAbscissa_t,
+	     class __JContents_t,
+	     template<class, class, class> class __JMap_t,
+	     class __JDistance_t>
+    void insert(const JMultiKey<N, argument_type>&                                          key, 
+		const JHistogramMap<__JAbscissa_t, __JContents_t, __JMap_t, __JDistance_t>& input)
+    {
+      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) {
+	  
+	  const argument_type x = 0.5 * (i->getX() + j->getX());
+
+	  insert(JMultiKey<N+1, argument_type>(key, x), i->getY());
+	}
+      }
+    }
+ 
+
+    /**
+     * Convert one-dimensional histogram to PDF and insert result at given multidimensional key.
+     *
+     * \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)
+    {
+      JFunction_t buffer;
+      
+      makePDF(input, buffer);
+      
+      multimap_type::insert(key, buffer);
+    }    
+  };
+
+  
+  /**
+   * Template specialisation of JMultiFunction for a JConstantFunction.
+   * The primary 2D function is reduced to a 1D function.
+   */
+  template<class JArgument_t,
+           class JResult_t,
+           template<class, class, class> class JMap_t,
+           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:
+
+    typedef JMap_t<JArgument_t, JResult_t, JDistance_t>                   multimap_type;
+
+    typedef typename multimap_type::abscissa_type                         abscissa_type;
+    typedef typename multimap_type::ordinate_type                         ordinate_type;
+
+    typedef typename multimap_type::argument_type                         argument_type;
+    typedef typename multimap_type::result_type                           result_type;
+
+    typedef typename multimap_type::const_iterator                        const_iterator;
+    typedef typename multimap_type::const_reverse_iterator                const_reverse_iterator;
+    typedef typename multimap_type::iterator                              iterator;
+    typedef typename multimap_type::reverse_iterator                      reverse_iterator;
+
+    typedef JConstantFunction1D<JArgument_t, JResult_t>                   function_type;
+    typedef JMap_t<JArgument_t, JResult_t, JDistance_t>                   map_type;
+    
+    enum { NUMBER_OF_DIMENSIONS = 1 };
+
+    using multimap_type::insert;
+
+
+    /**
+     * Insert element.
+     *
+     * \param  key             multidimensional key
+     * \param  function        function
+     */
+    void insert(const JMultiKey<1, abscissa_type>& key, const function_type& function)
+    {
+      this->insert(key.first, function.getY());
+    }
+  };
+
+ 
+  /**
+   * Template specialisation of JMultiFunction for a JConstantFunction.
+   * The number of dimensions of the primary function is reduced by one.
+   */
+  template<class JArgument_t,
+	   class JResult_t,
+	   class JMaplist_t, 
+	   class JDistance_t>
+  class JMultiFunction<JConstantFunction1D<JArgument_t, JResult_t>, JMaplist_t, JDistance_t> :
+    public JMultiFunction<JMultiFunction<JConstantFunction1D<JArgument_t, JResult_t>, 
+					 typename JMaplist_t::tail_type, 
+					 JDistance_t>,
+			  typename JMaplist_t::head_list,
+			  JDistance_t>
+  {
+  public:
+
+    typedef JMultiFunction<JMultiFunction<JConstantFunction1D<JArgument_t, JResult_t>, 
+					  typename JMaplist_t::tail_type, 
+					  JDistance_t>,
+			   typename JMaplist_t::head_list,
+			   JDistance_t>                                   multifunction_type;
+
+    typedef typename multifunction_type::multimap_type                    multimap_type;
+
+    typedef typename multimap_type::abscissa_type                         abscissa_type;
+    typedef typename multimap_type::ordinate_type                         ordinate_type;
+
+    typedef typename multimap_type::argument_type                         argument_type;
+    typedef typename multimap_type::result_type                           result_type;
+
+    typedef typename multimap_type::const_iterator                        const_iterator;
+    typedef typename multimap_type::const_reverse_iterator                const_reverse_iterator;
+    typedef typename multimap_type::iterator                              iterator;
+    typedef typename multimap_type::reverse_iterator                      reverse_iterator;
+
+    typedef typename multimap_type::super_iterator                        super_iterator;
+    typedef typename multimap_type::super_const_iterator                  super_const_iterator;
+
+    typedef JConstantFunction1D<JArgument_t, JResult_t>                   function_type;
+    typedef JMultiFunction<JConstantFunction1D<JArgument_t, JResult_t>, 
+			   typename JMaplist_t::tail_type, 
+			   JDistance_t>                                   map_type;
+
+    enum { NUMBER_OF_DIMENSIONS = JMapLength<JMaplist_t>::value };
+
+    using multimap_type::insert;
+
+
+    /**
+     * Insert element.
+     *
+     * \param  key             multidimensional key
+     * \param  function        function
+     */
+    void insert(const JMultiKey<NUMBER_OF_DIMENSIONS, abscissa_type>& key, const function_type& function)
+    {
+      this->get(key.front()).put(key.back(), function.getY());
+    }
+  };
+  
+
+  /**
+   * Conversion of multidimensional histogram to multidimensional function.
+   *
+   * \param  input             multidimensional histogram
+   * \param  output            multidimensional function
+   */
+  template<class JHistogram_t,
+	   class JHistogramMaplist_t,
+	   class JHistogramDistance_t,
+	   class JFunction_t,
+	   class JFunctionMaplist_t,
+	   class JFunctionDistance_t>
+  inline void makePDF(const JMultiHistogram<JHistogram_t, JHistogramMaplist_t, JHistogramDistance_t>& input, 
+		      JMultiFunction<JFunction_t, JFunctionMaplist_t, JFunctionDistance_t>&           output)
+  {
+    output.insert(input);
+  }
+}
+
+#endif
diff --git a/jpp/JTools/JMultiHistogram.hh b/jpp/JTools/JMultiHistogram.hh
new file mode 100644
index 0000000..f24c238
--- /dev/null
+++ b/jpp/JTools/JMultiHistogram.hh
@@ -0,0 +1,135 @@
+#ifndef __JTOOLS__JMULTIHISTOGRAM__
+#define __JTOOLS__JMULTIHISTOGRAM__
+
+#include "JTools/JMultiMap.hh"
+#include "JTools/JHistogram.hh"
+#include "JTools/JArray.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+
+  /**
+   * Multidimensional histogram.
+   *
+   * The template parameters respectively refer to:
+   * -# histogram object used for the lowest dimension(s);
+   * -# list of histogram maps used for the higher dimension(s); and
+   * -# distance operator.
+   *
+   * The number of dimensions of this histogram object is equal to the length of
+   * the given map list plus the extra dimensions of the first histogram object.
+   */
+  template<class JHistogram_t,
+	   class JMaplist_t,
+	   class JDistance_t = JDistance<typename JHistogram_t::abscissa_type> >
+  class JMultiHistogram :
+    public JMultiMap<typename JHistogram_t::abscissa_type, JHistogram_t, JMaplist_t, JDistance_t>
+  {
+  public:
+
+    typedef JMultiMap<typename JHistogram_t::abscissa_type,
+                      JHistogram_t,
+                      JMaplist_t,
+                      JDistance_t>                                        multimap_type;
+
+    enum { NUMBER_OF_DIMENSIONS = JMapLength<JMaplist_t>::value + JHistogram_t::NUMBER_OF_DIMENSIONS };
+
+    typedef typename multimap_type::abscissa_type                         abscissa_type;
+    typedef typename multimap_type::ordinate_type                         ordinate_type;
+
+    typedef typename multimap_type::const_iterator                        const_iterator;
+    typedef typename multimap_type::const_reverse_iterator                const_reverse_iterator;
+    typedef typename multimap_type::iterator                              iterator;
+    typedef typename multimap_type::reverse_iterator                      reverse_iterator;
+
+    typedef typename multimap_type::super_iterator                        super_iterator;
+    typedef typename multimap_type::super_const_iterator                  super_const_iterator;
+
+    typedef typename JHistogram_t::contents_type                          contents_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JMultiHistogram()
+    {}
+
+
+    /**
+     * Get multidimensional histogram.
+     *
+     * \return                 this multidimensional histogram
+     */
+    const JMultiHistogram& getMultiHistogram() const
+    {
+      return static_cast<const JMultiHistogram&>(*this);
+    }
+
+
+    /**
+     * Get multidimensional histogram.
+     *
+     * \return                 this multidimensional histogram
+     */
+    JMultiHistogram& getMultiHistogram()
+    {
+      return static_cast<JMultiHistogram&>(*this);
+    }
+
+
+    /**
+     * Multi-dimensional fill method call.
+     *
+     * \param  args            comma seperated list of abscissa values and weight
+     */
+    template<class ...Args>
+    void fill(const Args& ...args)
+    {
+      __fill__(0, args...);
+    }
+
+    
+  protected:
+    /**
+     * Recursive method for filling histogram.
+     *
+     * \param  i                index
+     * \param  x0               value at given index
+     * \param  x1               value at following index
+     * \param  args             remaining values and weight
+     */
+    template<class ...Args>
+    void __fill__(const int i, const abscissa_type x0, const abscissa_type x1, const Args& ...args)
+    {
+      this->buffer[i] = x0;
+
+      __fill__(i + 1, x1, args...);
+    }
+
+    /**
+     * Termination method for filling histogram.
+     *
+     * \param  i                index
+     * \param  x                value at given index
+     * \param  w                weight
+     */
+    virtual void __fill__(const int i, const abscissa_type x, const contents_type w)
+    {
+      this->buffer[i] = x;
+
+      this->evaluate(this->buffer.data(), w);
+    }
+
+    mutable JArray<NUMBER_OF_DIMENSIONS, abscissa_type> buffer;
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JMultiKey.hh b/jpp/JTools/JMultiKey.hh
new file mode 100644
index 0000000..419ad0a
--- /dev/null
+++ b/jpp/JTools/JMultiKey.hh
@@ -0,0 +1,537 @@
+#ifndef __JTOOLS__JMULTIKEY__
+#define __JTOOLS__JMULTIKEY__
+
+#include <istream>
+#include <ostream>
+#include <utility>
+#include <cmath>
+
+#include "JLang/JClass.hh"
+#include "JLang/JException.hh"
+#include "JLang/JComparable.hh"
+#include "JLang/JManip.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JComparable;
+  using JLANG::JClass;
+
+  
+  /**
+   * \cond NEVER
+   * Forward declaration of template JMultiKey class.
+   * \endcond
+   */
+  template<unsigned int N, class JKey_t>
+  class JMultiKey;
+    
+
+  namespace {
+    /**
+     * Auxiliary class for copying between const and non-const key types.
+     */
+    template<unsigned int N, class JKey_t>
+    struct JArgument {
+      typedef const JMultiKey<N, const JKey_t>&   argument_type;
+    };
+    
+    
+    template<unsigned int N, class JKey_t>
+    struct JArgument<N, const JKey_t> {
+      typedef const JMultiKey<N, JKey_t>&         argument_type;
+    };
+  }
+
+
+  /**
+   * Multidimensional key.
+   *
+   * This class reproduces the key of a multidimensional map.
+   * The individual data members can be accessed as, e.g:
+   * <pre>
+   *           JMultiKey<3, key_type>  key;
+   *
+   *           key[[.second].second].first;
+   * </pre>
+   */
+  template<unsigned int N, class JKey_t>
+  class JMultiKey :
+    public std::pair<JKey_t, JMultiKey<N-1, JKey_t> >,
+    public JComparable< JMultiKey<N, JKey_t> >
+  {
+  public:
+
+    typedef JKey_t                                               key_type;
+    typedef JMultiKey<N-1, JKey_t>                               mapped_type;
+    typedef std::pair<key_type, mapped_type>                     pair;
+
+
+    /**
+     * Default constructor.
+     */
+    JMultiKey() :
+      pair()
+    {}
+
+
+    /**
+     * Constructor.
+     * The secondary key is appended to the end of the primary keys.
+     *
+     * \param   __first      primary   keys
+     * \param   __second     secondary key
+     */
+    JMultiKey(typename JClass<mapped_type>::argument_type __first,
+	      typename JClass<key_type>   ::argument_type __second) :
+      pair(__first.first, mapped_type(__first.second, __second))
+    {}
+
+
+    /**
+     * Constructor.
+     * The primary key is inserted at the start of the secondary keys.
+     *
+     * \param   __first      primary   key
+     * \param   __second     secondary keys
+     */
+    JMultiKey(typename JClass<key_type>   ::argument_type __first,
+	      typename JClass<mapped_type>::argument_type __second) :	      
+      pair(__first, __second)
+    {}
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param   key          key
+     */
+    JMultiKey(typename JArgument<N, JKey_t>::argument_type key) :
+      pair(key.first, key.second)
+    {}
+
+
+    /**
+     * Less than method.
+     *
+     * \param   key          key
+     * \return               true if this key less than given key; else false
+     */
+    bool less(const JMultiKey<N, JKey_t>& key) const
+    {
+      if (this->first == key.first)
+	return this->second.less(key.second);
+      else
+	return this->first < key.first;
+    }
+
+
+    /**
+     * Get length squared.
+     *
+     * \return               square of length
+     */
+    double getLengthSquared() const
+    {
+      return this->first*this->first + this->second.getLengthSquared();
+    }
+
+
+    /**
+     * Get length.
+     *
+     * \return               length
+     */
+    double getLength() const
+    {
+      return sqrt(this->getLengthSquared());
+    }
+
+    
+    /**
+     * Get frontend key.
+     *
+     * \return               frontend key
+     */
+    JMultiKey<N-1, JKey_t> front() const
+    {
+      return JMultiKey<N-1, JKey_t>(this->first, this->second.front());
+    }
+
+
+    /**
+     * Get backend key.
+     *
+     * \return               backend key
+     */
+    key_type back() const
+    {
+      return this->second.back();
+    }
+
+
+    /**
+     * Read key from input.
+     *
+     * \param  in            input stream
+     * \param  key           key
+     * \return               input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JMultiKey<N, JKey_t>& key)
+    {
+      in >> key.first;
+      in >> key.second;
+
+      return in;
+    }
+
+
+    /**
+     * Write key to output.
+     *
+     * \param  out           output stream
+     * \param  key           key
+     * \return               output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JMultiKey<N, JKey_t>& key)
+    {
+      const JFormat format(out, getFormat< JMultiKey<N, JKey_t> >(JFormat_t(9, 3, std::ios::fixed | std::ios::showpos)));
+
+      out << format << key.first;
+      out << ' ';
+      out << key.second;
+
+      return out;
+    }
+  };
+
+
+  /**
+   * Two-dimensional key.
+   */
+  template<class JKey_t>
+  class JMultiKey<2, JKey_t> :
+    public std::pair<JKey_t, JMultiKey<1, JKey_t> >,
+    public JComparable< JMultiKey<2, JKey_t> >
+  {
+  public:
+
+    typedef JKey_t                                               key_type;
+    typedef JMultiKey<1, JKey_t>                                 mapped_type;
+    typedef std::pair<key_type, mapped_type>                     pair;
+
+
+    /**
+     * Default constructor.
+     */
+    JMultiKey() :
+      pair()
+    {}
+
+
+    /**
+     * Constructor.
+     * The secondary key is appended to the end of the primary key.
+     *
+     * \param   __first      primary   key
+     * \param   __second     secondary key
+     */
+    JMultiKey(typename JClass<mapped_type>::argument_type __first,
+	      typename JClass<key_type>   ::argument_type __second) :
+      pair(__first.first, __second)
+    {}
+
+
+    /**
+     * Constructor.
+     * The primary key is inserted at the start of the secondary key.
+     *
+     * \param   __first      primary   key
+     * \param   __second     secondary key
+     */
+    JMultiKey(typename JClass<key_type>   ::argument_type __first,
+	      typename JClass<mapped_type>::argument_type __second) :
+      pair(__first, __second.first)
+    {}
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param   key          key
+     */
+    JMultiKey(typename JArgument<2, JKey_t>::argument_type key) :
+      pair(key.first, key.second)
+    {}
+
+
+    /**
+     * Less than method.
+     *
+     * \param   key          key
+     * \return               true if this key less than given key; else false
+     */
+    bool less(const JMultiKey<2, JKey_t>& key) const
+    {
+      if (this->first == key.first)
+	return this->second.less(key.second);
+      else
+	return this->first < key.first;
+    }
+
+
+    /**
+     * Get length squared.
+     *
+     * \return               square of length
+     */
+    double getLengthSquared() const
+    {
+      return this->first*this->first + this->second.getLengthSquared();
+    }
+
+
+    /**
+     * Get length.
+     *
+     * \return               length
+     */
+    double getLength() const
+    {
+      return sqrt(this->getLengthSquared());
+    }
+
+
+    /**
+     * Get frontend key.
+     *
+     * \return               frontend key
+     */
+    JMultiKey<1, JKey_t> front() const
+    {
+      return JMultiKey<1, JKey_t>(this->first);
+    }
+
+
+    /**
+     * Get backend key.
+     *
+     * \return               backend key
+     */
+    key_type back() const
+    {
+      return this->second.back();
+    }
+
+
+    /**
+     * Read key from input.
+     *
+     * \param  in            input stream
+     * \param  key           key
+     * \return               input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JMultiKey<2, JKey_t>& key)
+    {
+      in >> key.first;
+      in >> key.second;
+
+      return in;
+    }
+
+
+    /**
+     * Write key to output.
+     *
+     * \param  out           output stream
+     * \param  key           key
+     * \return               output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JMultiKey<2, JKey_t>& key)
+    {
+      const JFormat format(out, getFormat< JMultiKey<2, JKey_t> >(JFormat_t(9, 3, std::ios::fixed | std::ios::showpos)));
+
+      out << format << key.first;
+      out << ' ';
+      out << key.second;
+
+      return out;
+    }
+  };
+
+
+  /**
+   * One-dimensional key.
+   */  
+  template<class JKey_t>
+  class JMultiKey<1, JKey_t> :
+    public JComparable< JMultiKey<1, JKey_t> >
+  {
+  public:
+
+    typedef JKey_t                                               key_type;
+    typedef JMultiKey<0, JKey_t>                                 mapped_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JMultiKey() :
+      first()
+    {}
+
+
+    /**
+     * Constructor.
+     * The secondary key is appended to the end of the primary key.
+     *
+     * \param   __first      primary   key
+     * \param   __second     secondary key
+     */
+    JMultiKey(typename JClass<mapped_type>::argument_type __first,
+	      typename JClass<key_type>   ::argument_type __second) :
+      first(__second)
+    {}
+
+
+    /**
+     * Constructor.
+     * The primary key is inserted at the start of the secondary key.
+     *
+     * \param   __first      primary   key
+     * \param   __second     secondary key
+     */
+    JMultiKey(typename JClass<key_type>   ::argument_type __first,
+	      typename JClass<mapped_type>::argument_type __second) :
+      first(__first)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param   __first      key
+     */
+    JMultiKey(typename JClass<key_type>::argument_type __first) :
+      first(__first)
+    {}
+
+
+    /**
+     * Copy constructor.
+     *
+     * \param   key          key
+     */
+    JMultiKey(typename JArgument<1, JKey_t>::argument_type key) :
+      first(key.first)
+    {}
+
+
+    /**
+     * Less than method.
+     *
+     * \param   key          key
+     * \return               true if this key less than given key; else false
+     */
+    bool less(const JMultiKey<1, JKey_t>& key) const
+    {
+      return this->first < key.first;
+    }
+    
+
+    /**
+     * Get length squared.
+     *
+     * \return               square of length
+     */
+    double getLengthSquared() const
+    {
+      return this->first*this->first;
+    }
+
+
+    /**
+     * Get length.
+     *
+     * \return               length
+     */
+    double getLength() const
+    {
+      return sqrt(this->getLengthSquared());
+    }
+
+
+    /**
+     * Get backend key.
+     *
+     * \return               backend key
+     */
+    key_type back() const
+    {
+      return this->first;
+    }
+
+
+    /**
+     * Read key from input.
+     *
+     * \param  in            input stream
+     * \param  key           key
+     * \return               input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JMultiKey<1, JKey_t>& key)
+    {
+      in >> key.first;
+
+      return in;
+    }
+
+
+    /**
+     * Write key to output.
+     *
+     * \param  out           output stream
+     * \param  key           key
+     * \return               output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JMultiKey<1, JKey_t>& key)
+    {
+      const JFormat format(out, getFormat< JMultiKey<1, JKey_t> >(JFormat_t(9, 3, std::ios::fixed | std::ios::showpos)));
+
+      out << format << key.first;
+
+      return out;
+    }
+
+
+    key_type first;
+  };
+
+
+  /**
+   * Empty key.
+   */
+  template<class JKey_t>
+  class JMultiKey<0, JKey_t>
+  {
+  public:
+
+    typedef JKey_t                                               key_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JMultiKey()
+    {}
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JMultiMap.hh b/jpp/JTools/JMultiMap.hh
new file mode 100644
index 0000000..d1ff254
--- /dev/null
+++ b/jpp/JTools/JMultiMap.hh
@@ -0,0 +1,1669 @@
+#ifndef __JTOOLS__JMULTIMAP__
+#define __JTOOLS__JMULTIMAP__
+
+#include "JLang/JSinglePointer.hh"
+#include "JLang/JEquals.hh"
+#include "JLang/JForwardIterator.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.
+ * \author mdejong
+ */
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JMATH::JMath;
+  using JLANG::JEquals;
+  using JLANG::JForwardIterator;
+
+
+  /**
+   * Multidimensional map.
+   *
+   * The first template parameter refers to the data type of the (multidimensional) key; 
+   * the second to the data type of the overall mapped value;
+   * 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.
+   */
+  template<class JAbscissa_t,
+	   class JOrdinate_t,
+	   class JMaplist_t,
+	   class JDistance_t = JDistance<JAbscissa_t> >
+  class JMultiMap;
+
+
+  /**
+   * Template specialisation of JMultiMap for map list with at least one map.
+   */
+  template<class JAbscissa_t, 
+	   class JOrdinate_t, 
+	   template<class, class, class> class JHead_t, 
+	   class JTail_t, 
+	   class JDistance_t>
+  class JMultiMap<JAbscissa_t, JOrdinate_t, JMapList<JHead_t, JTail_t>, JDistance_t> :
+    public JHead_t<JAbscissa_t, JMultiMap<JAbscissa_t, JOrdinate_t, JTail_t, JDistance_t>, JDistance_t>,
+    public JMath< JMultiMap<JAbscissa_t, JOrdinate_t, JMapList<JHead_t, JTail_t>, JDistance_t> >
+  {
+  public:
+
+    enum { NUMBER_OF_DIMENSIONS = JMapLength< JMapList<JHead_t, JTail_t> >::value };
+    
+    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;
+
+    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; 
+
+
+    /**
+     * Default constructor.
+     */
+    JMultiMap()
+    {}
+
+
+    /**
+     * Add map.
+     *
+     * \param  map             multimap
+     * \return                 this multimap
+     */
+    JMultiMap& add(const JMultiMap& map)
+    {
+      static_cast<map_type&>(*this).add(static_cast<const map_type&>(map));
+
+      return *this;
+    }
+ 
+
+    /**
+     * Subtract map.
+     *
+     * \param  map             multimap
+     * \return                 this multimap
+     */
+    JMultiMap& sub(const JMultiMap& map)
+    {
+      static_cast<map_type&>(*this).sub(static_cast<const map_type&>(map));
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           multiplication factor
+     * \return                 this multimap
+     */
+    JMultiMap& mul(const double value)
+    {
+      static_cast<map_type&>(*this).mul(value);
+
+      return *this;
+    }
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           division factor
+     * \return                 this multimap
+     */
+    JMultiMap& div(const double value)
+    {
+      static_cast<map_type&>(*this).div(value);
+
+      return *this;
+    }
+
+
+    /**
+     * Function application to each element of this multimap. 
+     *
+     * \param  function        function
+     * \return                 function
+     */
+    template<class JFunction_t>
+    void for_each(const JFunction_t& function)
+    {
+      function(*this);
+
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	i->getY().for_each(function);
+      }
+    }
+
+
+    /**
+     * Configure multidimensional map.
+     *
+     * \param  bounds          multidimensional bounds
+     */
+    void configure(const JAbstractMultiMap<NUMBER_OF_DIMENSIONS, abscissa_type>& bounds)
+    {
+      this->configure(JMultiKey<0, abscissa_type>(), bounds);
+    }
+    
+
+    /**
+     * Configure multidimensional map.
+     *
+     * \param  key             multidimensional key
+     * \param  bounds          multidimensional bounds
+     */
+    template<unsigned int N, unsigned int M>
+    void configure(const JMultiKey<M, abscissa_type>& key, const JAbstractMultiMap<N, abscissa_type>& bounds)
+    {
+      this->configure(bounds(key));
+
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+        i->getY().configure(JMultiKey<M+1, abscissa_type>(key,i->getX()), bounds);
+      }
+    }
+
+    
+    class super_const_iterator;  // forward declaration
+
+
+    /**
+     * Multidimensional iterator. 
+     */
+    class super_iterator :
+      public JEquals         <super_iterator>,
+      public JForwardIterator<super_iterator>
+    {
+
+      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.
+       */
+      super_iterator()
+      {}
+
+
+      /**
+       * Smart pointer operator.
+       *
+       * \return                 pointer to pair of iterators
+       */
+      pointer operator->()
+      { 
+	return pointer(new value_type(i->getX(), second));
+      }
+
+
+      /**
+       * Dereference operator.
+       *
+       * \return                 multidimensional pair
+       */
+      reference operator*()
+      {
+	return reference(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
+      {
+	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.
+       *
+       * \return                 key
+       */
+      multikey_type getKey() const
+      {
+	return multikey_type(i->getX(), second.getKey());
+      }
+
+      
+      /**
+       * Get value.
+       *
+       * \return                 value
+       */
+      JOrdinate_t& getValue() 
+      {
+	return 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;
+    };
+
+
+    /**
+     * Multidimensional const_iterator. 
+     */
+    class super_const_iterator :
+      public JEquals         <super_const_iterator>,
+      public JForwardIterator<super_const_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()
+      {}
+
+
+      /**
+       * Copy constructor.
+       *
+       * \param  cursor          super_iterator
+       */
+      super_const_iterator(super_iterator cursor) :
+	range (cursor.range),
+	i     (cursor.i),
+	second(cursor.second)
+      {}
+
+
+      /**
+       * Smart pointer operator.
+       *
+       * \return                 pointer to pair of iterators
+       */
+      pointer operator->()
+      { 
+	return pointer(new value_type(i->getX(), second));
+      }
+
+
+      /**
+       * Dereference operator.
+       *
+       * \return                 multidimensional pair
+       */
+      reference operator*()
+      { 
+	return reference(i->getX(), *second);
+      }
+
+
+      /**
+       * 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));
+      }
+
+
+      /**
+       * 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.
+       *
+       * \return                 key
+       */
+      multikey_type getKey() const
+      {
+	return multikey_type(i->getX(), second.getKey());
+      }
+
+      
+      /**
+       * 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)
+      {
+	for (i = range.first; i != range.second; ++i) {
+
+	  second = i->getY().super_begin();
+
+	  if (second != i->getY().super_end()) {
+	    break;
+	  }
+	}
+      }
+
+
+      std::pair<const_iterator, const_iterator> range;
+      const_iterator i;
+      typename mapped_type::super_const_iterator second;
+    };
+
+    
+    class super_const_reverse_iterator;  // forward declaration
+
+
+    /**
+     * Multidimensional reverse iterator. 
+     */
+    class super_reverse_iterator :
+      public JEquals         <super_reverse_iterator>,
+      public JForwardIterator<super_reverse_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;
+
+      
+      /**
+       * Default constructor.
+       */
+      super_reverse_iterator()
+      {}
+
+
+      /**
+       * Smart pointer operator.
+       *
+       * \return                 pointer to pair of iterators
+       */
+      pointer operator->()
+      { 
+	return pointer(new value_type(i->getX(), second));
+      }
+
+
+      /**
+       * Dereference operator.
+       *
+       * \return                 multidimensional pair
+       */
+      reference operator*()
+      {
+	return reference(i->getX(), *second);
+      }
+
+
+      /**
+       * 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 && (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_rbegin();
+	    
+	    if (!second.equals(i->getY().super_rend())) {
+	      break;
+	    }
+	  }
+	}
+
+	return i != range.second;
+      }
+
+      
+      /**
+       * Get multi-dimensional key.
+       *
+       * \return                 key
+       */
+      multikey_type getKey() const
+      {
+	return multikey_type(i->getX(), second.getKey());
+      }
+
+      
+      /**
+       * Get value.
+       *
+       * \return                 value
+       */
+      JOrdinate_t& getValue() 
+      {
+	return second.getValue();
+      }
+
+
+    private:
+      /**
+       * Constructor.
+       *
+       * \param  __begin         reverse begin of data
+       * \param  __end           reverse 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;
+    };
+
+
+    /**
+     * Multidimensional const_reverse_iterator. 
+     */
+    class super_const_reverse_iterator :
+      public JEquals         <super_const_reverse_iterator>,
+      public JForwardIterator<super_const_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;
+      
+
+      /**
+       * Default constructor.
+       */
+      super_const_reverse_iterator()
+      {}
+
+
+      /**
+       * Copy constructor.
+       *
+       * \param  cursor          super_iterator
+       */
+      super_const_reverse_iterator(super_reverse_iterator cursor) :
+	range (cursor.range),
+	i     (cursor.i),
+	second(cursor.second)
+      {}
+
+
+      /**
+       * Smart pointer operator.
+       *
+       * \return                 pointer to pair of iterators
+       */
+      pointer operator->()
+      { 
+	return pointer(new value_type(i->getX(), second));
+      }
+
+
+      /**
+       * Dereference operator.
+       *
+       * \return                 multidimensional pair
+       */
+      reference operator*()
+      { 
+	return reference(i->getX(), *second);
+      }
+
+
+      /**
+       * 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 && (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_rbegin();
+	    
+	    if (second != i->getY().super_rend()) {
+	      break;
+	    }
+	  }
+	}
+
+	return i != range.second;
+      }
+
+
+      /**
+       * Get multi-dimensional key.
+       *
+       * \return                 key
+       */
+      multikey_type getKey() const
+      {
+	return multikey_type(i->getX(), second.getKey());
+      }
+
+      
+      /**
+       * 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_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;
+    };
+
+
+    /**
+     * Get super_iterator to begin of data.
+     * 
+     * \return                 super iterator
+     */
+    super_const_iterator super_begin() const
+    {
+      return super_const_iterator(this->begin(), this->end());
+    }
+
+
+    /**
+     * Get super_reverse_iterator to reverse begin of data
+     *
+     * \return                  super reverse iterator
+     */
+    super_const_reverse_iterator super_rbegin() const
+    {
+      return super_const_reverse_iterator(this->rbegin(), this->rend());
+    }
+ 
+   
+    /**
+     * Get super_iterator to end of data.
+     *
+     * \return                 super iterator
+     */
+    super_const_iterator super_end() const
+    {
+      return super_const_iterator(this->end(), this->end());
+    }
+
+
+    /**
+     * Get super_reverse_iterator to end of data.
+     *
+     * \return                 super reverse iterator
+     */
+    super_const_reverse_iterator super_rend() const
+    {
+      return super_const_reverse_iterator(this->rend(), this->rend());
+    }
+
+
+    /**
+     * Get super_iterator to begin of data.
+     *
+     * \return                 super iterator
+     */
+    super_iterator super_begin()
+    {
+      return super_iterator(this->begin(), this->end());
+    }
+
+
+    /**
+     * Get super_reverse_iterator to begin of data.
+     *
+     * \return                 super iterator
+     */
+    super_reverse_iterator super_rbegin()
+    {
+      return super_reverse_iterator(this->rbegin(), this->rend());
+    }    
+ 
+   
+    /**
+     * Get super_iterator to end of data.
+     *
+     * \return                 super iterator
+     */
+    super_iterator super_end()
+    {
+      return super_iterator(this->end(), this->end());
+    }
+
+
+    /**
+     * Get super_reverse_iterator to end of data.
+     *
+     * \return                 super iterator
+     */
+    super_reverse_iterator super_rend()
+    {
+      return super_reverse_iterator(this->rend(), this->rend());
+    }    
+
+
+    /**
+     * Get value.
+     *
+     * \param  key             multidimensional key
+     * \return                 value
+     */
+    ordinate_type& get(const JMultiKey<NUMBER_OF_DIMENSIONS, abscissa_type>& key)
+    {
+      return this->get(key.first).get(key.second);
+    }
+
+
+    /**
+     * Insert element.
+     *
+     * \param  key             multidimensional key
+     * \param  value           value
+     */
+    void insert(const JMultiKey<NUMBER_OF_DIMENSIONS, abscissa_type>& key, const ordinate_type& value)
+    {
+      (*this)[key.first].insert(key.second, value);
+    }
+
+
+    /**
+     * Insert element.
+     *
+     * \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)
+    {
+      (*this)[value.first].insert(value.second);
+    }
+
+
+    /**
+     * Insert element.
+     *
+     * \param  value           multidimensional iterator value
+     */
+    void insert(const typename super_const_iterator::reference& value)
+    {
+      (*this)[value.first].insert(value.second);
+    }
+  };
+
+
+  /**
+   * Terminator class of recursive JMultiMap class.
+   */
+  template<class JAbscissa_t,
+	   class JOrdinate_t,
+	   template<class, class, class> class JHead_t,
+	   class JDistance_t>
+  class JMultiMap<JAbscissa_t, JOrdinate_t, JMapList<JHead_t, JLANG::JNullType>, JDistance_t> :
+    public JHead_t<JAbscissa_t, JOrdinate_t, JDistance_t>,
+    public JMath< JMultiMap<JAbscissa_t, JOrdinate_t, JMapList<JHead_t, JLANG::JNullType>, JDistance_t> >
+  {
+  public:
+
+    enum { NUMBER_OF_DIMENSIONS = 1 };
+
+    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;
+
+    using map_type::insert; 
+    using map_type::configure; 
+    using map_type::get; 
+
+
+    /**
+     * Default constructor.
+     */
+    JMultiMap() 
+    {}
+
+
+    /**
+     * Add map.
+     *
+     * \param  map             multimap
+     * \return                 this multimap
+     */
+    JMultiMap& add(const JMultiMap& map)
+    {
+      static_cast<map_type&>(*this).add(static_cast<const map_type&>(map));
+
+      return *this;
+    }
+ 
+
+    /**
+     * Subtract map.
+     *
+     * \param  map             multimap
+     * \return                 this multimap
+     */
+    JMultiMap& sub(const JMultiMap& map)
+    {
+      static_cast<map_type&>(*this).sub(static_cast<const map_type&>(map));
+
+      return *this;
+    }
+
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           multiplication factor
+     * \return                 this multimap
+     */
+    JMultiMap& mul(const double value)
+    {
+      static_cast<map_type&>(*this).mul(value);
+
+      return *this;
+    }
+
+    /**
+     * Scale contents.
+     *
+     * \param  value           division factor
+     * \return                 this multimap
+     */
+    JMultiMap& div(const double value)
+    {
+      static_cast<map_type&>(*this).div(value);
+
+      return *this;
+    }
+
+
+    /**
+     * Termination of function application.
+     *
+     * \param  function        function
+     * \return                 function
+     */
+    template<class JFunction_t>
+    void for_each(const JFunction_t& function)
+    {
+      function(*this);
+    }
+    
+
+    /**
+     * Configure multidimensional map.
+     *
+     * \param  bounds          multidimensional bounds
+     */
+    void configure(const JAbstractMultiMap<NUMBER_OF_DIMENSIONS, abscissa_type>& bounds)
+    {
+      this->configure(JMultiKey<0, abscissa_type>(), bounds);
+    }
+
+
+    /**
+     * Configure multidimensional map.
+     *
+     * \param  key             multidimensional key
+     * \param  bounds          multidimensional bounds
+     */
+    template<unsigned int N, unsigned int M>
+    void configure(const JMultiKey<M, abscissa_type>& key, const JAbstractMultiMap<N, abscissa_type>& bounds)
+    {
+      this->configure(bounds(key));
+    }
+
+
+    class super_const_iterator;  // forward declaration
+
+
+    /**
+     * Terminator class of multidimensional iterator. 
+     */
+    class super_iterator :
+      public JEquals         <super_iterator>,
+      public JForwardIterator<super_iterator>
+    {
+
+      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;
+
+
+      /**
+       * Default constructor.
+       */
+      super_iterator()
+      {}
+
+
+      /**
+       * Smart pointer operator.
+       *
+       * \return                 pointer to pair of 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 iterator.
+       *
+       * \param  cursor          super iterator
+       * \return                 true if equal; else false
+       */
+      virtual bool equals(const super_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
+      {
+	return multikey_type(i->getX());
+      }
+
+      
+      /**
+       * Get value.
+       *
+       * \return                 value
+       */
+      JOrdinate_t& getValue() 
+      {
+	return i->getY();
+      }
+
+    private:
+      /**
+       * Constructor.
+       *
+       * \param  __begin         begin of data
+       * \param  __end           end   of data
+       */
+      super_iterator(iterator __begin,
+		     iterator __end) :
+	range(__begin, __end),
+	i    (__begin)
+      {}
+
+
+      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>
+    {
+
+      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.
+       */
+      super_const_iterator()
+      {}
+
+
+      /**
+       * 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
+       */
+      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 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
+      {
+	return multikey_type(i->getX());
+      }
+
+      
+      /**
+       * Get value.
+       *
+       * \return                 value
+       */
+      const JOrdinate_t& getValue() 
+      {
+	return i->getY();
+      }
+
+    private:
+      /**
+       * Constructor.
+       *
+       * \param  __begin         begin of data
+       * \param  __end           end   of data
+       */
+      super_const_iterator(const_iterator __begin,
+			   const_iterator __end) :
+	range(__begin, __end),
+	i    (__begin)
+      {}
+
+
+      std::pair<const_iterator, const_iterator> range;
+      const_iterator i;
+    };
+
+
+    class super_const_reverse_iterator;  // forward declaration
+
+
+    /**
+     * Terminator class of multidimensional reverse iterator. 
+     */
+    class super_reverse_iterator :
+      public JEquals         <super_iterator>,
+      public JForwardIterator<super_iterator>
+    {
+
+      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.
+       *
+       * \param  __begin         begin of data
+       * \param  __end           end   of data
+       */
+      super_reverse_iterator(reverse_iterator __begin,
+			     reverse_iterator __end) :
+	range(__begin, __end),
+	i    (__begin)
+      {}
+
+
+      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>
+    {
+
+      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.
+       */
+      super_const_reverse_iterator()
+      {}
+
+
+      /**
+       * 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
+       */
+      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_const_reverse_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
+      {
+	return multikey_type(i->getX());
+      }
+
+      
+      /**
+       * Get value.
+       *
+       * \return                 value
+       */
+      const JOrdinate_t& getValue() 
+      {
+	return i->getY();
+      }
+
+    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),
+	i    (__begin)
+      {}
+
+
+      std::pair<const_reverse_iterator, const_reverse_iterator> range;
+      const_reverse_iterator i;
+    };
+
+
+     /**
+     * Get super_iterator to begin of data.
+     *
+     * \return             super_iterator
+     */
+    super_const_iterator super_begin() const
+    {
+      return super_const_iterator(this->begin(), this->end());
+    }
+
+
+    /**
+     * Get super_reverse_iterator to reverse begin of data.
+     *
+     * \return             super_reverse_iterator
+     */
+    super_const_reverse_iterator super_rbegin() const
+    {
+      return super_const_reverse_iterator(this->rbegin(), this->rend());
+    }
+ 
+   
+    /**
+     * Get super_iterator to end of data.
+     *
+     * \return             super_iterator
+     */
+    super_const_iterator super_end() const
+    {
+      return super_const_iterator(this->end(), this->end());
+    }
+
+    
+    /**
+     * Get super_reverse_iterator to reverse end of data.
+     *
+     * \return             super_reverse_iterator
+     */
+    super_const_reverse_iterator super_rend() const
+    {
+      return super_const_reverse_iterator(this->rend(), this->rend());
+    }
+
+
+    /**
+     * Get super_iterator to begin of data.
+     *
+     * \return             super_iterator
+     */
+    super_iterator super_begin()
+    {
+      return super_iterator(this->begin(), this->end());
+    }
+
+
+    /**
+     * Get super_reverse_iterator to reverse begin of data.
+     *
+     * \return             super_reverse_iterator
+     */
+    super_reverse_iterator super_rbegin()
+    {
+      return super_reverse_iterator(this->rbegin(), this->rend());
+    }
+ 
+   
+    /**
+     * Get super_iterator to end of data.
+     *
+     * \return             super_iterator
+     */
+    super_iterator super_end()
+    {
+      return super_iterator(this->end(), this->end());
+    }
+ 
+   
+    /**
+     * Get super_reverse_iterator to end of data.
+     *
+     * \return             super_reverse_iterator
+     */
+    super_reverse_iterator super_rend()
+    {
+      return super_reverse_iterator(this->rend(), this->rend());
+    }
+
+
+    /**
+     * Get value.
+     *
+     * \param  key             multidimensional key
+     * \return                 value
+     */
+    ordinate_type& get(const JMultiKey<1, abscissa_type>& key)
+    {
+      return get(key.first);
+    }
+
+
+    /**
+     * Insert element.
+     *
+     * \param  key          multidimensional key
+     * \param  value        value
+     */
+    void insert(const JMultiKey<1, JAbscissa_t>& key, const JOrdinate_t& value)
+    {
+      insert(value_type(key.first, value));
+    }
+
+
+    /**
+     * Insert element.
+     *
+     * \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)
+    {
+      insert(value_type(value.first, value.second));
+    }
+
+
+    /**
+     * Insert element.
+     *
+     * \param  value        multidimensional iterator value
+     */
+    void insert(const typename super_const_iterator::reference& value)
+    {
+      insert(value_type(value.first, value.second));
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JMultiMapTransformer.hh b/jpp/JTools/JMultiMapTransformer.hh
new file mode 100644
index 0000000..50dc1e1
--- /dev/null
+++ b/jpp/JTools/JMultiMapTransformer.hh
@@ -0,0 +1,341 @@
+#ifndef __JTOOLS__JMULTIMAPTRANSFORMER__
+#define __JTOOLS__JMULTIMAPTRANSFORMER__
+
+#include "JLang/JClonable.hh"
+#include "JIO/JSerialisable.hh"
+#include "JTools/JArray.hh"
+#include "JTools/JTransformer.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JClonable;
+  using JIO::JSerialisable;
+  using JIO::JReader;
+  using JIO::JWriter;
+
+
+  /**
+   * Interface for weight application and coordinate transformation of function.
+   *
+   * 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.
+   */
+  template<unsigned int N, class JArgument_t>
+  class JMultiMapTransformer :
+    public JClonable< JMultiMapTransformer<N, JArgument_t> >,
+    public JSerialisable 
+  {
+  public:
+
+    typedef JMultiMapTransformer<N, JArgument_t>                      multimaptransformer_type;
+
+    typedef typename JClonable<multimaptransformer_type>::clone_type  clone_type;
+    typedef JArgument_t                                               argument_type;
+    typedef JArray<N, argument_type>                                  array_type;
+    typedef const JArray<N, const argument_type>                      const_array_type;
+
+
+    /**
+     * Evaluate xn value as a function of {x0, ..., xn-1}
+     *
+     * \param  buffer               x0 - xn-1 values
+     * \param  xn                   xn value
+     * \return                      xn value
+     */
+    virtual argument_type putXn(const_array_type& buffer, const argument_type xn) const = 0;
+
+
+    /**
+     * Evaluate xn value as a function of {x0, ..., xn-1}
+     *
+     * \param  buffer               x0 - xn-1 values
+     * \param  xn                   xn value
+     * \return                      xn value
+     */
+    virtual argument_type getXn(const_array_type& buffer, const argument_type xn) const = 0;
+
+
+    /**
+     * Weight function.
+     *
+     * \param  buffer               x0 - xn-1 values
+     * \return                      weight
+     */
+    virtual double getWeight(const_array_type& buffer) const = 0;
+
+
+    /**
+     * Weight function.
+     *
+     * \param  x                    first abscissa values
+     * \param  args                 comma seperated list of remaining abscissa values
+     * \return                      weight
+     */
+    template<class ...Args>
+    double getWeight(const argument_type x, const Args& ...args) const
+    {
+      return getWeight(array_type(x, args...));
+    }
+
+
+    /**
+     * Default implementation of weight application and coordinate transformation of function.
+     */
+    class JMultiMapDefaultTransformer;
+
+
+    /**
+     * Get default transformer.
+     *
+     * \return                      default transformer
+     */
+    static const JMultiMapTransformer& getDefaultTransformer()
+    {
+      static const JMultiMapDefaultTransformer transformer;
+      
+      return transformer;
+    }
+
+
+    /**
+     * Get clone of default transformer.
+     *
+     * \return                      pointer to newly created transformer
+     */
+    static JMultiMapTransformer* getClone()
+    {
+      return new JMultiMapDefaultTransformer(); 
+    }
+  };
+
+    
+  /**
+   * Default implementation of weight application and coordinate transformation of function.
+   *
+   * The coordiniate transformation has no effect and the weight is equal to one.
+   * 
+   * This class implements the JMultiMapTransformer, JClonable and JSerialisable interfaces.
+   */
+  template<unsigned int N, class JArgument_t>
+  class JMultiMapTransformer<N, JArgument_t>::JMultiMapDefaultTransformer : 
+    public JMultiMapTransformer<N, JArgument_t>
+  {
+  public:
+
+    /**
+     * Default constructor.
+     */
+    JMultiMapDefaultTransformer()
+    {}
+
+
+    /**
+     * Clone object.
+     * 
+     * \return                      pointer to newly created transformer
+     */
+    virtual clone_type clone() const override 
+    {
+      return new JMultiMapDefaultTransformer(*this);
+    }
+
+
+    /**
+     * Evaluate xn value as a function of {x0, ..., xn-1}
+     *
+     * \param  buffer               x0 - xn-1 values
+     * \param  xn                   xn value
+     * \return                      xn value
+     */
+    virtual argument_type putXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return xn;
+    }
+
+
+    /**
+     * Evaluate xn value as a function of {x0, ..., xn-1}
+     *
+     * \param  buffer               x0 - xn-1 values
+     * \param  xn                   xn value
+     * \return                      xn value
+     */
+    virtual argument_type getXn(const_array_type& buffer, const argument_type xn) const override 
+    {
+      return xn;
+    }
+
+
+    /**
+     * Weight function.
+     *
+     * \param  buffer               x0 - xn-1 values
+     * \return                      weight
+     */
+    virtual double getWeight(const_array_type& buffer) const override 
+    {
+      return 1.0;
+    }
+
+
+    /**
+     * Read from input.
+     *
+     * This method reads nothing.
+     *
+     * \param  in              reader
+     * \return                 reader
+     */
+    virtual JReader& read(JReader& in) override 
+    { 
+      return in;
+    }
+
+
+    /**
+     * Write to output.
+     *
+     * This method writes nothing.
+     *
+     * \param  out             writer
+     * \return                 writer
+     */
+    virtual JWriter& write(JWriter& out) const override 
+    { 
+      return out; 
+    }
+  };
+
+  
+  /**
+   * Auxiliary class to convert JMultiMapTransformer to JCollectionElementTransformer.
+   *
+   * This class implements the JCollectionElementTransformer interface.
+   */
+  template<unsigned int N, class JElement_t>
+  class JMultiMapPutTransformer : 
+    public JCollectionElementTransformer<JElement_t> 
+  {
+  public:
+
+    typedef typename JElement_t::abscissa_type                     abscissa_type;
+    typedef typename JElement_t::ordinate_type                     ordinate_type;
+
+    typedef JMultiMapTransformer<N, abscissa_type>                 transformer_type;
+
+    typedef typename transformer_type::const_array_type            const_array_type;
+
+
+    /**
+     * Constructor.
+     *
+     * \param  __transformer        multidimensional map transformer
+     * \param  __buffer             x0 - xn-1 values
+     */
+    JMultiMapPutTransformer(const transformer_type& __transformer,
+			    const_array_type&       __buffer) :
+      transformer(__transformer),
+      buffer     (__buffer),
+      W(transformer.getWeight(buffer))
+    {}
+
+
+    /**
+     * Transform element.
+     *
+     * \param  element              input  element
+     * \return                      output element
+     */
+    virtual JElement_t operator()(const JElement_t& element) const override 
+    {
+      return JElement_t(transformer.putXn(buffer, element.getX()), element.getY() / W);
+    }
+    
+  private:    
+    const transformer_type& transformer;
+    const_array_type        buffer;
+    const double            W;
+  };
+
+
+  /**
+   * Auxiliary class to convert JMultiMapTransformer to JCollectionElementTransformer.
+   *
+   * This class implements the JCollectionElementTransformer interface.
+   */
+  template<unsigned int N, class JElement_t>
+  class JMultiMapGetTransformer : 
+    public JCollectionElementTransformer<JElement_t> 
+  {
+  public:
+
+    typedef typename JElement_t::abscissa_type                     abscissa_type;
+    typedef typename JElement_t::ordinate_type                     ordinate_type;
+
+    typedef JMultiMapTransformer<N, abscissa_type>                 transformer_type;
+
+    typedef typename transformer_type::const_array_type            const_array_type;
+
+
+    /**
+     * Constructor.
+     * 
+     * \param  __transformer        multidimensional map transformer
+     * \param  __buffer             x0 - xn-1 values
+     */
+    JMultiMapGetTransformer(const transformer_type& __transformer,
+			    const_array_type&       __buffer) :
+      transformer(__transformer),
+      buffer     (__buffer),
+      W(transformer.getWeight(buffer))
+    {}
+
+
+    /**
+     * Transform element.
+     *
+     * \param  element              input  element
+     * \return                      output element
+     */
+    virtual JElement_t operator()(const JElement_t& element) const override 
+    {
+      return JElement_t(transformer.getXn(buffer, element.getX()), element.getY() * W);
+    }
+    
+  private:
+    const transformer_type& transformer;
+    const_array_type        buffer;
+    const double            W;
+  };
+
+
+  /**
+   * Abstract interface for transformable multidimensional map.
+   *
+   * The template parameters refer to the dimension of the map and the data type of the argument, respectively.
+   */
+  template<unsigned int N, class JArgument_t>
+  struct JTransformable
+  {
+    typedef JArgument_t                                            argument_type;
+    typedef JMultiMapTransformer<N, argument_type>                 transformer_type;
+
+    /**
+     * Application of transformation.
+     *
+     * \param  transformer          function transformer
+     */
+    virtual void transform(const transformer_type& transformer) = 0;
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JMultiPair.hh b/jpp/JTools/JMultiPair.hh
new file mode 100644
index 0000000..87bf9bb
--- /dev/null
+++ b/jpp/JTools/JMultiPair.hh
@@ -0,0 +1,328 @@
+#ifndef __JTOOLS__JMULTIPAIR__
+#define __JTOOLS__JMULTIPAIR__
+
+#include "JTools/JMultiKey.hh"
+#include "JLang/JClass.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  /**
+   * Multidimensional pair.
+   *
+   * This class reproduces the element of a multidimensional map.
+   * The individual data members can be accessed as:
+   * <pre>
+   *           JMultiPair<3, key_type, mapped_type>  pair;
+   *
+   *           pair[[.second].second].first;
+   *           pair[[.second].second].second;
+   * </pre>
+   */
+  template<unsigned int N, class JKey_t, class JValue_t>
+  class JMultiPair 
+  {
+  public:
+
+    typedef JKey_t                                              key_type;
+    typedef JValue_t                                            value_type;
+    typedef JMultiPair<N-1, key_type, value_type>               mapped_type;
+    typedef typename JLANG::JClass<value_type>::reference_type  reference_type;
+    typedef JMultiKey<N, key_type>                              multikey_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JMultiPair() :
+      first (),
+      second()
+    {}
+
+    
+    /**
+     * Constructor.
+     * The primary key is inserted at the start of the secondary keys.
+     *
+     * \param   __first      primary   key
+     * \param   __second     secondary keys and value
+     */
+    JMultiPair(typename JClass<key_type>   ::argument_type __first,
+	       typename JClass<mapped_type>::argument_type __second) :
+      first (__first),
+      second(__second)
+    {}
+
+    
+    /**
+     * Constructor.
+     * The secondary key is appended to the end of the primary keys.
+     *
+     * \param   __first      primary   keys and value
+     * \param   __second     secondary key
+     */
+    JMultiPair(typename JClass<mapped_type>::argument_type __first,
+	       typename JClass<key_type>   ::argument_type __second) :
+      first (__first.first),
+      second(mapped_type(__first.second, __second))
+    {}
+
+    
+    /**
+     * Constructor.
+     *
+     * \param   key          multidimensional key
+     * \param   value        value
+     */
+    JMultiPair(typename JClass<multikey_type>::argument_type key,
+	       typename JClass<value_type>   ::argument_type value) :
+      first (key.first),
+      second(mapped_type(key.second, value))
+    {}
+
+
+    /**
+     * Get multidimensional key.
+     *
+     * \return               multidimensional key
+     */
+    multikey_type getKey() const
+    {
+      return multikey_type(this->first, this->second.getKey());
+    }
+
+
+    /**
+     * Get value.
+     *
+     * \return               value
+     */
+    reference_type getValue()
+    { 
+      return this->second.getValue();
+    }
+
+
+    /**
+     * Get value.
+     *
+     * \return               value
+     */
+    const reference_type getValue() const 
+    { 
+      return this->second.getValue();
+    }
+
+
+    key_type    first;
+    mapped_type second;
+  };
+
+
+  /**
+   * Two-dimensional pair.
+   */
+  template<class JKey_t, class JValue_t>
+  class JMultiPair<2, JKey_t, JValue_t> 
+  {
+  public:
+
+    typedef JKey_t                                       key_type;
+    typedef JValue_t                                     value_type;
+    typedef JMultiPair<1, key_type, value_type>          mapped_type;
+    typedef typename JClass<value_type>::reference_type  reference_type;
+    typedef JMultiKey<2, key_type>                       multikey_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JMultiPair() :
+      first (),
+      second()
+    {}
+
+
+    /**
+     * Constructor.
+     * The primary key is inserted at the start of the secondary key.
+     *
+     * \param   __first      primary   key
+     * \param   __second     secondary key and value
+     */
+    JMultiPair(typename JClass<key_type>   ::argument_type __first,
+	       typename JClass<mapped_type>::argument_type __second) :
+      first (__first),
+      second(__second)
+    {}
+
+
+    /**
+     * Constructor.
+     * The secondary key is appended to the end of the primary key.
+     *
+     * \param   __first      primary   keys and value
+     * \param   __second     secondary key
+     */
+    JMultiPair(typename JClass<mapped_type>::argument_type __first,
+	       typename JClass<key_type>   ::argument_type __second) :
+      first (__first.first),
+      second(mapped_type(__second, __first.second))
+    {}
+
+    
+    /**
+     * Constructor.
+     *
+     * \param   key          multidimensional key
+     * \param   value        value
+     */
+    JMultiPair(typename JClass<multikey_type>::argument_type key,
+	       typename JClass<value_type>   ::argument_type value) :
+      first (key.first), 
+      second(mapped_type(key.second, value))
+    {}
+
+
+    /**
+     * Get multidimensional key.
+     *
+     * \return               multidimensional key
+     */
+    multikey_type getKey() const
+    { 
+      return multikey_type(this->first, this->second.getKey());
+    }
+
+
+    /**
+     * Get value.
+     *
+     * \return               value
+     */
+    reference_type getValue()
+    {
+      return this->second.getValue();
+    }
+
+
+    /**
+     * Get value.
+     *
+     * \return               value
+     */
+    const reference_type getValue() const
+    { 
+      return this->second.getValue();
+    }
+
+
+    key_type    first;
+    mapped_type second;
+  };
+
+
+  /**
+   * One-dimensional pair.
+   */  
+  template<class JKey_t, class JValue_t>
+  class JMultiPair<1, JKey_t, JValue_t> 
+  {
+  public:
+
+    typedef JKey_t                                       key_type;
+    typedef JValue_t                                     value_type;
+    typedef JValue_t                                     mapped_type;
+    typedef typename JClass<value_type>::reference_type  reference_type;
+    typedef JMultiKey<1, key_type>                       multikey_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JMultiPair() :
+      first (),
+      second()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param   __first      key
+     * \param   __second     value
+     */
+    JMultiPair(typename JClass<key_type>  ::argument_type __first,
+	       typename JClass<value_type>::argument_type __second) :
+      first (__first),
+      second(__second)
+    {}
+
+    
+    /**
+     * Constructor.
+     *
+     * \param   key          multidimensional key
+     * \param   value        value
+     */
+    JMultiPair(typename JClass<multikey_type>::argument_type key,
+	       typename JClass<value_type>   ::argument_type value) :
+      first (key.first),
+      second(value)
+    {}
+
+    
+    /**
+     * Get multidimensional key.
+     *
+     * \return               multidimensional key
+     */
+    multikey_type getKey() const
+    { 
+      return JMultiKey<1, key_type>(this->first);
+    }
+
+
+    /**
+     * Get value.
+     *
+     * \return               value
+     */
+    reference_type getValue()
+    {
+      return this->second;
+    }
+
+
+    /**
+     * Get value.
+     *
+     * \return               value
+     */
+    const reference_type getValue() const
+    { 
+      return this->second;
+    }
+
+
+    key_type    first;
+    mapped_type second;
+  };
+
+
+  /**
+   * Empty pair.
+   */
+  template<class JKey_t, class JValue_t>
+  class JMultiPair<0, JKey_t, JValue_t>
+  {};
+}
+
+#endif
diff --git a/jpp/JTools/JPair.hh b/jpp/JTools/JPair.hh
new file mode 100644
index 0000000..af16632
--- /dev/null
+++ b/jpp/JTools/JPair.hh
@@ -0,0 +1,234 @@
+#ifndef __JTOOLS__JPAIR__
+#define __JTOOLS__JPAIR__
+
+#include <istream>
+#include <ostream>
+
+#include "JLang/JClass.hh"
+#include "JIO/JSerialisable.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JIO::JReader;
+  using JIO::JWriter;
+
+
+  /**
+   * Template specialisation for a pair of values.
+   */
+  template<class JKey_t, class JValue_t>
+  class JPair
+  {
+  public:
+
+    typedef JKey_t                                               key_type;
+    typedef JValue_t                                             mapped_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JPair() :
+      first (),
+      second()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  key          JKey_t
+     * \param  value        JValue_t
+     */
+    JPair(typename JLANG::JClass<key_type>   ::argument_type key,
+	  typename JLANG::JClass<mapped_type>::argument_type value) :
+      first (key),
+      second(value)
+    {}
+
+
+    /**
+     * Read pair from input.
+     *
+     * \param  in       input stream
+     * \param  pair     pair
+     * \return          input stream
+     */
+    friend inline std::istream& operator>>(std::istream& in, JPair<JKey_t, JValue_t>& pair)
+    {
+      in >> pair.first;
+      in >> pair.second;
+
+      return in;
+    }
+
+
+    /**
+     * Write pair to output.
+     *
+     * \param  out      output stream
+     * \param  pair     pair
+     * \return          output stream
+     */
+    friend inline std::ostream& operator<<(std::ostream& out, const JPair<JKey_t, JValue_t>& pair)
+    {
+      out << pair.first;
+      out << ' ';
+      out << pair.second;
+
+      return out;
+    }
+
+
+    /**
+     * Read pair from input.
+     *
+     * \param  in       reader
+     * \param  pair     pair
+     * \return          reader
+     */
+    friend inline JReader& operator>>(JReader& in, JPair<JKey_t, JValue_t>& pair)
+    {
+      in >> pair.first;
+      in >> pair.second;
+
+      return in;
+    }
+
+
+    /**
+     * Write pair to output.
+     *
+     * \param  out      writer
+     * \param  pair     pair
+     * \return          writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JPair<JKey_t, JValue_t>& pair)
+    {
+      out << pair.first;
+      out << pair.second;
+
+      return out;
+    }
+
+
+    const key_type&    getKey()   const { return this->first; }
+    const mapped_type& getValue() const { return this->second; }
+
+    mapped_type& getValue() { return this->second; }
+
+    JKey_t   first;
+    JValue_t second;
+  };
+
+
+  /**
+   * Template specialisation for a pair of references.
+   */
+  template<class JKey_t, class JValue_t>
+  class JPair<JKey_t&, JValue_t&>
+  {
+  public:
+
+    typedef JKey_t                                               key_type;
+    typedef JValue_t                                             mapped_type;
+
+
+    /**
+     * Constructor.
+     *
+     * \param  key          JKey_t
+     * \param  value        JValue_t
+     */
+    JPair(key_type&    key,
+	  mapped_type& value) :
+      first (key),
+      second(value)
+    {}
+
+    const key_type&    getKey()   const { return this->first; }
+    const mapped_type& getValue() const { return this->second; }
+
+    key_type&    getKey()   { return this->first; }
+    mapped_type& getValue() { return this->second; }
+
+    JKey_t&   first;
+    JValue_t& second;
+  };
+
+
+  /**
+   * Template specialisation for a mixed pair of const and non-const references.
+   */
+  template<class JKey_t, class JValue_t>
+  class JPair<const JKey_t&, JValue_t&>
+  {
+  public:
+
+    typedef JKey_t                                               key_type;
+    typedef JValue_t                                             mapped_type;
+
+
+    /**
+     * Constructor.
+     *
+     * \param  key          JKey_t
+     * \param  value        JValue_t
+     */
+    JPair(const key_type& key,
+	  mapped_type&    value) :
+      first (key),
+      second(value)
+    {}
+
+    const key_type&    getKey()   const { return this->first; }
+    const mapped_type& getValue() const { return this->second; }
+
+    mapped_type& getValue() { return this->second; }
+
+    const JKey_t& first;
+    JValue_t&     second;
+  };
+
+
+  /**
+   * Template specialisation for a pair of const references.
+   */
+  template<class JKey_t, class JValue_t>
+  class JPair<const JKey_t&, const JValue_t&>
+  {
+  public:
+
+    typedef JKey_t                                               key_type;
+    typedef JValue_t                                             mapped_type;
+
+
+    /**
+     * Constructor.
+     *
+     * \param  key          JKey_t
+     * \param  value        JValue_t
+     */
+    JPair(const key_type&    key,
+	  const mapped_type& value) :
+      first (key),
+      second(value)
+    {}
+
+    const key_type&    getKey()   const { return this->first; }
+    const mapped_type& getValue() const { return this->second; }
+
+    const JKey_t&   first;
+    const JValue_t& second;
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JPolint.hh b/jpp/JTools/JPolint.hh
new file mode 100644
index 0000000..d843fa3
--- /dev/null
+++ b/jpp/JTools/JPolint.hh
@@ -0,0 +1,1215 @@
+#ifndef __JTOOLS__JPOLINT__
+#define __JTOOLS__JPOLINT__
+
+#include <cmath>
+#include <iterator>
+#include <algorithm>
+
+#include "JLang/JException.hh"
+#include "JLang/JAssert.hh"
+#include "JLang/JBool.hh"
+#include "JTools/JFunctional.hh"
+#include "JTools/JDistance.hh"
+#include "JTools/JResult.hh"
+#include "JTools/JElement.hh"
+#include "JTools/JMapCollection.hh"
+#include "JTools/JQuadrature.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JException;
+  using JLANG::JFunctionalException;
+  using JLANG::JNumericalPrecision;
+  using JLANG::JValueOutOfRange;
+
+
+  /**
+   * Template definition for functional collection with polynomial interpolation.
+   */
+  template<unsigned int N, 
+	   class JElement_t,
+	   template<class, class> class JCollection_t,
+	   class JResult_t,
+	   class JDistance_t>
+  class JPolintFunction;
+
+
+  /**
+   * Template specialisation for functional collection with polynomial interpolation.
+   *
+   * Polynomial interpolation 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.
+   */
+  template<unsigned int N, class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JPolintFunction<N, 
+			JElement_t, 
+			JCollection_t, 
+			typename JResultType<typename JElement_t::ordinate_type>::result_type,
+			JDistance_t> :
+    public JCollection_t<JElement_t, JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type,
+		     typename JResultType<typename JElement_t::ordinate_type>::result_type>
+  {
+  public:
+
+    typedef JCollection_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, data_type>                                  function_type;           
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+
+    /**
+     * Default constructor.			
+     */
+    JPolintFunction()
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    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 ((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."));
+      }
+
+      ++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) {}
+
+
+      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];
+
+	if (fabs(u[i]) < fabs(u[j])) {
+	  j = i;
+	}
+      }
+
+      
+      result_type y = v[j];
+
+      --j;
+
+      for (int m = 1; m != n; ++m) {
+
+	for (int i = 0; i != n-m; ++i) {
+
+	  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] *= ho/dx;
+	  w[i] *= hp/dx;
+	}
+
+	if (2*(j+1) < n - m)
+	  y += v[j+1];
+	else
+	  y += w[j--];
+      }
+
+      return y;
+    }
+
+  protected: 
+    /**
+     * Function compilation.
+     */
+    virtual void do_compile() override 
+    {}
+
+
+  private: 
+    mutable double      u[N+1];
+    mutable result_type v[N+1];
+    mutable result_type w[N+1];
+  };
+
+
+  /**
+   * Template specialisation for zero-degree polynomial interpolation method.\n
+   * The interpolation is based on a simple lookup table.
+   */
+  template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JPolintFunction<0, 
+			JElement_t,
+			JCollection_t,
+			typename JResultType<typename JElement_t::ordinate_type>::result_type,
+			JDistance_t> :
+    public JCollection_t<JElement_t, JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type,
+		     typename JResultType<typename JElement_t::ordinate_type>::result_type>
+  {
+  public:
+
+    typedef JCollection_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, data_type>                                  function_type;           
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+
+    /**
+     * Default constructor.			
+     */
+    JPolintFunction()
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    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 ((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."));
+      }
+
+      ++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);
+    }
+
+  protected:
+    /**
+     * Function compilation.
+     */
+    virtual void do_compile() override 
+    {}
+  };
+
+
+  /**
+   * Template specialisation for first-degree polynomial interpolation method.\n
+   * The interpolation is based on a simple linear interpolation.
+   */
+  template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JPolintFunction<1, 
+			JElement_t,
+			JCollection_t,
+			typename JResultType<typename JElement_t::ordinate_type>::result_type,
+			JDistance_t> :
+    public JCollection_t<JElement_t, JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type,
+		     typename JResultType<typename JElement_t::ordinate_type>::result_type>
+  {
+  public:
+
+    typedef JCollection_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, data_type>                                  function_type;           
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+
+    /**
+     * Default constructor.			
+     */
+    JPolintFunction() 
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    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 ((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."));
+      }
+
+      ++pX;  // next argument value
+
+
+      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;
+
+      ya = function_type::getValue(p->getY(), pX);
+      yb = function_type::getValue(q->getY(), pX);
+
+      ya *= a;
+      yb *= b;
+
+      ya += yb;
+
+      return ya;
+    }
+
+  protected:
+    /**
+     * Function compilation.
+     */
+    virtual void do_compile() override 
+    {}
+
+
+  private:
+    mutable result_type ya;
+    mutable result_type yb;
+  };
+
+
+  /**
+   * Template specialisation for polynomial interpolation method with returning JResultPDF data structure.
+   *
+   * Note that the data structure of the elements in the collection should have the additional methods:
+   * <pre>
+   *     ordinate_type getIntegral() const;
+   *     void setIntegral(ordinate_type v);
+   * </pre>
+   * to get and set the integral values, respectively.
+   */
+  template<unsigned int N, class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JPolintFunction<N,
+			JElement_t,
+			JCollection_t,
+			JResultPDF<typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			JDistance_t> :
+    public JCollection_t<JElement_t, JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type, 
+		     JResultPDF<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
+  {
+  public:
+
+    typedef JCollection_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, JResultPDF<data_type> >                     function_type;
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+    using JFunctional<>::compile;
+
+
+    /**
+     * Default contructor.
+     */
+    JPolintFunction()
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    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        (p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) {
+
+        try {
+
+          result   = this->getExceptionHandler().action(JValueOutOfRange("JPolintFunction<>::operator() x < xmin."));
+
+          // overwrite integral values
+
+          result.v = 0;
+          result.V = this->rbegin()->getIntegral();
+
+        } catch(const JValueOutOfRange& exception) {
+          throw exception;
+        }
+
+        return result;
+
+      } else if (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision) {
+
+        try {
+
+          result   = this->getExceptionHandler().action(JValueOutOfRange("JPolintFunction<>::operator() x > xmax."));
+
+          // overwrite integral values
+
+          result.v = this->rbegin()->getIntegral();
+          result.V = this->rbegin()->getIntegral();
+
+        } catch(const JValueOutOfRange& exception) {
+          throw exception;
+        }
+
+        return result;
+      }
+
+      ++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) {}
+
+	
+	int j = 0;
+	
+	for (int i = 0; i != n; ++p, ++i) {
+
+	  u[i] = this->getDistance(x, p->getX());
+
+	  w[i][0] = v[i][0] = JFunctional<argument_type, data_type>::getValue(p->getY(), pX);
+	  w[i][1] = v[i][1] = JMATH::zero;
+	  w[i][2] = v[i][2] = p->getIntegral();
+	  
+	  if (fabs(u[i]) < fabs(u[j])) {
+	    j = i;
+	  }
+	}
+
+
+	result.f  = v[j][0];
+	result.fp = v[j][1];
+	result.v  = v[j][2];
+	result.V  = this->rbegin()->getIntegral();
+
+	--j;
+	
+	for (int m = 1; m != n; ++m) {
+	  
+	  for (int i = 0; i != n-m; ++i) {
+	    
+	    const double ho = u[ i ];
+	    const double hp = u[i+m];
+	    const double dx = ho - hp;
+	    
+	    for (int k = 0; k != 3; ++k) {
+	      r[k] = (v[i+1][k] - w[i][k]) / dx;
+	    }
+	    
+	    v[i][0] = ho * r[0];
+	    w[i][0] = hp * r[0];
+	    v[i][1] = ho * r[1] - r[0];
+	    w[i][1] = hp * r[1] - r[0];
+	    v[i][2] = ho * r[2];
+	    w[i][2] = hp * r[2];
+	  }
+
+	  if (2*(j+1) < n - m) {
+	    
+	    result.f  += v[j+1][0];
+	    result.fp += v[j+1][1];
+	    result.v  += v[j+1][2];
+	    
+	  } else {
+	    
+	    result.f  += w[j][0];
+	    result.fp += w[j][1];
+	    result.v  += w[j][2];
+	  
+	    --j;
+	  }
+	}
+      }
+      
+      return result;
+    }
+
+  protected: 
+    /**
+     * Function compilation.
+     */
+    virtual void do_compile() override 
+    {
+      ordinate_type V(JMATH::zero);
+
+      if (this->getSize() > 1) {
+
+	const JGaussLegendre engine(N);
+
+	this->begin()->setIntegral(V);
+
+	for (iterator j = this->begin(), i = j++; j != this->end(); ++i, ++j) {
+	  
+	  const abscissa_type xmin = i->getX();
+	  const abscissa_type xmax = j->getX();
+	  
+	  for (JGaussLegendre::const_iterator m = engine.begin(); m != engine.end(); ++m) {
+	    
+	    const abscissa_type x = 0.5 * (xmax + xmin  +  m->getX() * (xmax - xmin));
+	    const ordinate_type v = 0.5 * (xmax - xmin) *  m->getY() * get_value(this->evaluate(&x));
+	    
+	    V += v;
+	  }
+	  
+	  j->setIntegral(V);
+	}
+      }
+    }
+
+
+    mutable double    u[N+1];
+    mutable data_type v[N+1][3];
+    mutable data_type w[N+1][3];
+    mutable data_type r[3];
+
+    mutable result_type result;
+  };
+
+
+  /**
+   * Template definition of base class for polynomial interpolations with polynomial result.
+   */
+  template<unsigned int N,
+	   class JElement_t,
+	   template<class, class> class JCollection_t,
+	   class JResult_t,
+	   class JDistance_t>
+  class JPolintCollection;
+
+
+  /**
+   * Template base class for polynomial interpolations with polynomial result.
+   *
+   * This class partially implements the JFunctional interface.
+   */
+  template<unsigned int N, class JElement_t, template<class, class> class JCollection_t, class JDistance_t, unsigned int M>
+  class JPolintCollection<N,
+			  JElement_t,
+			  JCollection_t,
+			  JResultPolynome<M, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			  JDistance_t> :
+    public JCollection_t<JElement_t, JDistance_t>,
+    public virtual JFunctional<>,
+    private JLANG::JAssert<M <= N>
+  {
+  public:
+
+    typedef JCollection_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, JResultPolynome<M, data_type> >             function_type;
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+
+    using JFunctional<>::compile;
+
+
+    /**
+     * Default contructor.
+     */
+    JPolintCollection()
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    result_type evaluate(const argument_type* pX) const
+    {
+      if (this->size() <= N) {
+	THROW(JFunctionalException, "JPolintFunction<>::evaluate() not enough data.");
+      }
+
+      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.");
+      }
+
+      ++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) {}
+
+
+      int j = 0;
+
+      for (int i = 0; i != n; ++p, ++i) {
+	
+	u[i] = this->getDistance(x, p->getX());
+
+	w[i][0] = v[i][0] = JFunctional<argument_type, data_type>::getValue(p->getY(), pX);
+	  
+	for (unsigned int k = 1; k != M+1; ++k) {
+	  w[i][k] = v[i][k] = JMATH::zero;
+	}
+
+	if (fabs(u[i]) < fabs(u[j])) {
+	  j = i;
+	}
+      }
+
+
+      for (unsigned int k = 0; k != M+1; ++k) {
+	result.y[k] = v[j][k];
+      }
+
+      --j;
+
+      for (int m = 1; m != n; ++m) {
+
+	for (int i = 0; i != n-m; ++i) {
+
+	  const double ho = u[ i ];
+	  const double hp = u[i+m];
+	  const double dx = ho - hp;
+
+	  for (int k = 0; k != M+1; ++k) {
+	    r[k] = (v[i+1][k] - w[i][k]) / dx;
+	  }
+
+	  v[i][0] = ho * r[0];
+	  w[i][0] = hp * r[0];
+
+	  for (int k = 1; k != M+1; ++k) {
+	    v[i][k] = ho * r[k]  -  k * r[k-1];
+	    w[i][k] = hp * r[k]  -  k * r[k-1];
+	  }
+	}
+
+	if (2*(j+1) < n - m) {
+
+	  for (int k = 0; k != M+1; ++k) {
+	    result.y[k] += v[j+1][k];
+	  }
+
+	} else {
+
+	  for (int k = 0; k != M+1; ++k) {
+	    result.y[k] += w[j][k];
+	  }
+
+	  --j;
+	}
+      }
+
+      return result;
+    }
+
+  protected: 
+    /**
+     * Function compilation.
+     */
+    virtual void do_compile() override 
+    {}
+
+
+  private: 
+    mutable double    u[N+1];
+    mutable data_type v[N+1][M+1];
+    mutable data_type w[N+1][M+1];
+    mutable data_type r[M+1];
+
+    mutable result_type result;
+  };
+
+
+  /**
+   * Template specialisation for polynomial interpolation method with returning JResultPolynome data structure.
+   */
+  template<unsigned int N, class JElement_t, template<class, class> class JCollection_t, class JDistance_t, unsigned int M>
+  class JPolintFunction<N,
+			JElement_t,
+			JCollection_t,
+			JResultPolynome<M, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			JDistance_t> :
+    public JPolintCollection<N,
+			     JElement_t,
+			     JCollection_t,
+			     JResultPolynome<M, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			     JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type, 
+		     JResultPolynome<N, typename JResultType<typename JElement_t::ordinate_type>::result_type> >
+  {
+  public:
+
+    typedef JPolintCollection<N,
+			      JElement_t,
+			      JCollection_t,
+			      JResultPolynome<M, typename JResultType<typename JElement_t::ordinate_type>::result_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, JResultPolynome<M, data_type> >             function_type;
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+
+    /**
+     * Default contructor.
+     */
+    JPolintFunction()
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const override 
+    {
+      try {
+	return collection_type::evaluate(pX);
+      }
+      catch(const JException& error) {
+        return this->getExceptionHandler().action(error);
+      }
+    }
+  };
+
+
+  /**
+   * Template specialisation for polynomial interpolation method with returning JResultDerivative data structure.
+   */
+  template<unsigned int N, class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JPolintFunction<N,
+			JElement_t,
+			JCollection_t,
+			JResultDerivative<typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			JDistance_t> :
+    public JPolintCollection<N,
+			     JElement_t,
+			     JCollection_t,
+			     JResultPolynome<1, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			     JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type,
+		     JResultDerivative<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
+  {
+  public:
+
+    typedef JPolintCollection<N,
+			      JElement_t,
+			      JCollection_t,
+			      JResultPolynome<1, typename JResultType<typename JElement_t::ordinate_type>::result_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, JResultDerivative<data_type> >              function_type;
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+    using JFunctional<>::compile;
+
+
+    /**
+     * Default contructor.
+     */
+    JPolintFunction()
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const override 
+    {
+      try {
+	return collection_type::evaluate(pX);
+      }
+      catch(const JException& error) {
+        return this->getExceptionHandler().action(error);
+      }
+    }
+  };
+
+
+  /**
+   * Template specialisation for polynomial interpolation method with returning JResultHesse data structure.
+   */
+  template<unsigned int N, class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JPolintFunction<N,
+			JElement_t,
+			JCollection_t,
+			JResultHesse<typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			JDistance_t> :
+    public JPolintCollection<N,
+			     JElement_t,
+			     JCollection_t,
+			     JResultPolynome<2, typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			     JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type,
+		     JResultHesse<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
+  {
+  public:
+
+    typedef JPolintCollection<N,
+			      JElement_t,
+			      JCollection_t,
+			      JResultPolynome<2, typename JResultType<typename JElement_t::ordinate_type>::result_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, JResultHesse<data_type> >                   function_type;
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+    using JFunctional<>::compile;
+
+
+    /**
+     * Default contructor.
+     */
+    JPolintFunction()
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const override 
+    {
+      try {
+	return collection_type::evaluate(pX);
+      }
+      catch(const JException& error) {
+        return this->getExceptionHandler().action(error);
+      }
+    }
+  };
+
+
+  /**
+   * Template class for polynomial interpolation in 1D
+   *
+   * This class implements the JFunction1D interface.
+   */
+  template<unsigned int N,
+	   class JElement_t,
+	   template<class, class> class JCollection_t,
+	   class JResult_t   = typename JElement_t::ordinate_type,
+	   class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  class JPolintFunction1D :
+    public JPolintFunction<N, JElement_t, JCollection_t, JResult_t, JDistance_t>,
+    public JFunction1D<typename JElement_t::abscissa_type, JResult_t> 
+  {
+  public:
+
+    typedef JCollection_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::distance_type                              distance_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 JFunction1D<abscissa_type, JResult_t>                                function_type;           
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+
+    /**
+     * Default contructor.
+     */
+    JPolintFunction1D()
+    {}
+  };
+
+
+  /**
+   * \cond NEVER
+   * Forward declarations.
+   * \endcond
+   */
+  template<class JAbscissa_t, class JOrdinate_t>
+  struct JElement2D;
+
+  template<template<class, class, class> class JMap_t>
+  struct JMapCollection;
+
+
+  /**
+   * Functional map with polynomial interpolation.
+   */
+  template<unsigned int N,
+	   class JKey_t,
+	   class JValue_t,
+	   template<class, class, class> class JMap_t,
+	   class JResult_t,
+	   class JDistance_t = JDistance<JKey_t> >
+  class JPolintMap :
+    public JPolintFunction<N, 
+			   JElement2D<JKey_t, JValue_t>, 
+			   JMapCollection<JMap_t>::template collection_type, 
+			   JResult_t,
+			   JDistance_t>
+  {
+  public:
+
+    typedef JElement2D<JKey_t, JValue_t>                                         element_type;
+    typedef JPolintFunction<N, 
+			    element_type,
+			    JMapCollection<JMap_t>::template collection_type,
+			    JResult_t,
+			    JDistance_t>                                         JPolintFunction_t;
+
+    typedef typename JPolintFunction_t::abscissa_type                            abscissa_type;
+    typedef typename JPolintFunction_t::ordinate_type                            ordinate_type;
+    typedef typename JPolintFunction_t::value_type                               value_type;
+    typedef typename JPolintFunction_t::distance_type                            distance_type;
+
+    typedef typename JPolintFunction_t::const_iterator                           const_iterator;
+    typedef typename JPolintFunction_t::const_reverse_iterator                   const_reverse_iterator;
+    typedef typename JPolintFunction_t::iterator                                 iterator;
+    typedef typename JPolintFunction_t::reverse_iterator                         reverse_iterator;
+
+    typedef typename JPolintFunction_t::argument_type                            argument_type;
+    typedef typename JPolintFunction_t::result_type                              result_type;
+    typedef typename JPolintFunction_t::JExceptionHandler                        exceptionhandler_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JPolintMap()
+    {}
+  };
+
+                    
+  /**
+   * Conversion of data points to integral values.
+   *
+   * This method transfers the integration to the corresponding specialised function.
+   *
+   * \param  input             collection   
+   * \param  output            mappable collection
+   * \return                   integral
+   */
+  template<unsigned int N,
+           class JElement_t,
+           template<class, class> class JCollection_t,
+           class JResult_t,
+           class JDistance_t>
+  inline typename JElement_t::ordinate_type
+  integrate(const JPolintFunction1D<N, JElement_t, JCollection_t, JResult_t, JDistance_t>& input, 
+	    typename JMappable<JElement_t>::map_type&                                      output)
+  {
+    return integrate(input, output, JLANG::JBool<N == 0 || N == 1>());
+  }
+
+
+  /**
+   * Conversion of data points to integral values.
+   *
+   * The integration uses the Gauss-Legendre quadratures with the number of points set
+   * to the degree of the input polynomial interpolating function.
+   *
+   * \param  input             collection   
+   * \param  output            mappable collection
+   * \param  option            false
+   * \return                   integral
+   */
+  template<unsigned int N,
+           class JElement_t,
+           template<class, class> class JCollection_t,
+           class JResult_t,
+           class JDistance_t>
+  inline typename JElement_t::ordinate_type
+  integrate(const JPolintFunction1D<N, JElement_t, JCollection_t, JResult_t, JDistance_t>& input, 
+	    typename JMappable<JElement_t>::map_type&                                      output,
+	    const JLANG::JBool<false>&                                                     option)
+  {
+    typedef typename JElement_t::abscissa_type                                                                abscissa_type;
+    typedef typename JElement_t::ordinate_type                                                                ordinate_type;
+    typedef typename JPolintFunction1D<N, JElement_t, JCollection_t, JResult_t, JDistance_t>::const_iterator  const_iterator;
+    
+    ordinate_type V(JMATH::zero);
+
+    if (input.getSize() > 1) {
+      
+      output.put(input.begin()->getX(), V);
+      
+      const JGaussLegendre engine(N);
+      
+      for (const_iterator j = input.begin(), i = j++; j != input.end(); ++i, ++j) {
+        
+        const abscissa_type xmin = i->getX();
+        const abscissa_type xmax = j->getX();
+        
+        for (JGaussLegendre::const_iterator m = engine.begin(); m != engine.end(); ++m) {
+          
+          const abscissa_type x = 0.5 * (xmax + xmin  +  m->getX() * (xmax - xmin));
+          const ordinate_type v = 0.5 * (xmax - xmin) *  m->getY() * get_value(input(x));
+          
+          V += v;
+        }
+        
+        output.put(xmax, V);
+      }
+    }
+    
+    return V;
+  }
+  
+  
+  /**
+   * Conversion of data points to integral values.
+   *
+   * The integration is based on the sum of ordinates of the input data points.
+   *
+   * \param  input             collection   
+   * \param  output            mappable collection
+   * \param  option            true
+   * \return                   integral
+   */
+  template<class JElement_t,
+           template<class, class> class JCollection_t,
+           class JResult_t,
+           class JDistance_t>
+  inline typename JElement_t::ordinate_type
+  integrate(const JPolintFunction1D<0, JElement_t, JCollection_t, JResult_t, JDistance_t>& input, 
+	    typename JMappable<JElement_t>::map_type&                                      output,
+	    const JLANG::JBool<true>&                                                      option)
+  {
+    typedef typename JElement_t::ordinate_type                                                                ordinate_type;
+    typedef typename JPolintFunction1D<0, JElement_t, JCollection_t, JResult_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 += input.getDistance(i->getX(), j->getX()) * j->getY();
+        
+	output.put(j->getX(), V);
+      }
+    }
+    
+    return V;
+  }
+  
+
+  /**
+   * Conversion of data points to integral values.
+   *
+   * The integration is based on the trapezoidal rule applied to the input data points.
+   *
+   * \param  input             collection   
+   * \param  output            mappable collection
+   * \param  option            true
+   * \return                   integral
+   */
+  template<class JElement_t,
+           template<class, class> class JCollection_t,
+           class JResult_t,
+	   class JDistance_t>
+  inline typename JElement_t::ordinate_type
+  integrate(const JPolintFunction1D<1, JElement_t, JCollection_t, JResult_t, JDistance_t>& input, 
+	    typename JMappable<JElement_t>::map_type&                                      output,
+	    const JLANG::JBool<true>&                                                      option)
+  {
+    typedef typename JElement_t::ordinate_type                                                                ordinate_type;
+    typedef typename JPolintFunction1D<1, JElement_t, JCollection_t, JResult_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 += 0.5 * input.getDistance(i->getX(), j->getX()) * (i->getY() + j->getY());
+        
+	output.put(j->getX(), V);
+      }
+    }
+    
+    return V;
+  }
+}
+
+#endif
diff --git a/jpp/JTools/JQuadrature.hh b/jpp/JTools/JQuadrature.hh
new file mode 100644
index 0000000..c29f1c9
--- /dev/null
+++ b/jpp/JTools/JQuadrature.hh
@@ -0,0 +1,546 @@
+#ifndef __JTOOLS__JQUADRATURE__
+#define __JTOOLS__JQUADRATURE__
+
+#include <cmath>
+
+#include "JTools/JConstants.hh"
+#include "JTools/JElement.hh"
+#include "JTools/JCollection.hh"
+
+
+/**
+ * \file
+ *
+ * Auxiliary classes for numerical integration.
+ * \author mdejong
+ */
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  /**
+   * Type definition of basic element for quadratures.
+   */
+  typedef JElement2D<double, double>               JElement2D_t;
+  
+
+  /**
+   * 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$
+   *
+   * The abscissa and ordinate values of the collection can be used
+   * as abscissa and weight values of the summation to approximately
+   * determine the integral of the function.
+   */
+  class JQuadrature :
+    public JCollection<JElement2D_t> 
+  {
+  public:
+    /**
+     * Default constructor.
+     */
+    JQuadrature()
+    {}
+
+
+    /**
+     * 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 given function should return the value of the integral between the two integration limits. 
+     *
+     * \param  xmin       minimal x
+     * \param  xmax       maximal x
+     * \param  nx         number of points
+     * \param  integral   integral
+     * \param  eps        precision
+     */
+    template<class JFunction_t>
+    JQuadrature(const double xmin,
+		const double xmax,
+		const int    nx,
+		JFunction_t  integral,
+		const double eps = 1.0e-4)
+    {
+      double Xmin = xmin;
+      double Xmax = xmax;
+
+      const double Vmin = integral(Xmin, Xmax) / (double) nx;
+    
+      for (int i = 0; i != nx; ++i) {
+      
+	for (double xmin = Xmin, xmax = Xmax; ; ) {
+	  
+	  const double x = 0.5 * (xmin + xmax);
+	  const double v = integral(Xmin, x);
+	
+	  if (fabs(Vmin - v)    < eps *  Vmin ||
+	      fabs(xmax - xmin) < eps * (Xmax - Xmin)) {
+	    
+	    const double __x = 0.5 * (Xmin + x);
+	    const double __y = Vmin / integral(__x);
+	  
+	    insert(JElement2D_t(__x,__y));
+	  
+	    Xmin = x;
+	    xmax = Xmax;
+	    
+	    break;
+	  }
+	  
+	  if (v < Vmin)
+	    xmin = x;
+	  else
+	    xmax = x;
+	}
+      }
+    }
+  };
+
+
+  /**
+   * Numerical integrator for <tt>W(x) = 1</tt>.
+   * 
+   * 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, 
+   * Cambridge University Press.
+   */ 
+  class JGaussLegendre : 
+    public JQuadrature 
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  n          number of points
+     * \param  eps        precision
+     */
+    JGaussLegendre(const int    n,
+		   const double eps = 1.0e-12) :
+      JQuadrature()
+    {
+      resize(n);
+
+      const int M = (n + 1) / 2;
+      
+      double p0, p1, p2, pp;
+      
+      for (int i = 0; i < M; ++i) {
+	
+	double z  = cos(PI * (i+0.75) / (n+0.5));
+	double z1;
+	
+	do {
+	  
+	  p1 = 0.0;
+	  p2 = 1.0;
+	  
+	  // recurrence relation
+	  
+	  for (int j = 0; j < n; ++j) {
+	    p0 = p1;
+	    p1 = p2;
+	    p2 = ((2*j + 1) * z*p1  - j*p0) / (j+1);
+	  }
+	  
+	  pp = n * (z*p2 - p1) / (z*z - 1.0);
+	  
+	  z1 = z;
+	  z  = z1 - p2/pp;
+	  
+	} while (fabs(z-z1) > eps);
+
+	const double y = 2.0 / ((1.0-z*z)*pp*pp);
+
+	at(  i  ) = JElement2D_t(-z,y);
+	at(n-i-1) = JElement2D_t(+z,y);
+      }
+    }
+  };
+
+
+  /**
+   * Numerical integrator for <tt>W(x) = x^a e^(-x)</tt>.
+   *
+   * 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, 
+   * Cambridge University Press.
+   */ 
+  class JGaussLaguerre : 
+    public JQuadrature 
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  n          number of points
+     * \param  alf        power
+     * \param  eps        precision
+     */
+    JGaussLaguerre(const int    n,
+		   const double alf,
+		   const double eps = 1.0e-12) :
+      JQuadrature()
+    {
+      const int number_of_iterations = 100;
+
+      double z, z1;
+      double p0, p1, p2, pp;
+      
+      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:
+	  z += (15.0 + 6.25*alf) / (1.0 + 0.9*alf + 2.5*n); 
+	  break;
+
+	default:
+	  const double ai = i - 1;
+	  z += ((1.0+2.55*ai)/(1.9*ai) + (1.26*ai*alf)/(1.0+3.5*ai)) * (z - at(i-2).getX()) / (1.0 + 0.3*alf);
+	  break;
+	}
+
+
+	int k;
+
+	for (k = 0; k != number_of_iterations; ++k) {
+	  
+	  p1 = 0.0;
+	  p2 = 1.0;
+	  
+	  // recurrence relation
+	  
+	  for (int j = 0; j < n; ++j) {
+	    p0 = p1;
+	    p1 = p2;
+	    p2 = ((2*j + 1 + alf - z) * p1  - (j + alf)*p0) / (j+1);
+	  }
+	  
+	  pp = (n*p2 - (n+alf)*p1) / z;
+	  
+	  z1 = z;
+	  z  = z1 - p2/pp;
+
+	  if (fabs(z-z1) < eps)
+	    break;
+	}
+
+	const double y = -tgamma(alf+n) / tgamma((double) n) / (pp*n*p1);
+	
+	insert(JElement2D_t(z,y));
+      }
+    }
+  };
+
+
+  /**
+   * Numerical integrator for <tt>W(x) = e^-(x^2)</tt>.
+   *
+   * 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, 
+   * Cambridge University Press.
+   */ 
+  class JGaussHermite : 
+    public JQuadrature 
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  n          number of points
+     * \param  eps        precision
+     */
+    JGaussHermite(const int    n,
+		  const double eps = 1.0e-12) :
+      JQuadrature()
+    {
+      resize(n);
+
+      const double pii = 1.0 / pow(PI,0.25);
+
+      const int number_of_iterations = 100;
+
+      const int M = (n + 1) / 2;
+      
+      double p0, p1, p2, pp;
+      double z = 0.0;
+      double z1;
+      
+      for (int i = 0; i < M; ++i) {
+
+	switch (i) {
+
+	case 0:
+	  z  = sqrt((double) (2*n+1))  -  1.85575 * pow((double) (2*n+1),-0.16667);
+	  break;
+
+	case 1:
+	  z -= 1.14 * pow((double) n,0.426) / z;
+	  break;
+
+	case 2:
+	  z  = 1.86*z + 0.86*at( 0 ).getX();
+	  break;
+
+	case 3:
+	  z  = 1.91*z + 0.91*at( 1 ).getX();
+	  break;
+
+	default:
+	  z  = 2.00*z + 1.00*at(i-2).getX();
+	  break;
+	}
+
+	for (int k = 0; k != number_of_iterations; ++k) {
+	  
+	  p1 = 0.0;
+	  p2 = pii;
+	  
+	  // recurrence relation
+	  
+	  for (int j = 0; j < n; ++j) {
+	    p0 = p1;
+	    p1 = p2;
+	    p2 = z * sqrt(2.0/(double) (j+1)) * p1  -  sqrt((double) j / (double) (j+1)) * p0;
+	  }
+	  
+	  pp = sqrt((double) (2*n)) * p1;
+	  
+	  z1 = z;
+	  z  = z1 - p2/pp;
+
+	  if (fabs(z-z1) < eps)
+	    break;
+	} 
+
+	const double y = 2.0 / (pp*pp);
+
+	at(  i  ) = JElement2D_t(-z,y);
+	at(n-i-1) = JElement2D_t(+z,y);
+      }
+    }
+  };
+
+
+  /**
+   * Numerical integrator for <tt>W(x) = (1 + g^2 - 2gx)^a</tt>.
+   * For this, <tt>g > 0</tt>.
+   *
+   * Henyey-Greenstein integration points and weights.
+   */ 
+  class JHenyeyGreenstein : 
+    public JQuadrature 
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  n          number of points
+     * \param  g          angular dependence parameter
+     * \param  a          power
+     */
+    JHenyeyGreenstein(const int    n,
+		      const double g,
+		      const double a) :
+      JQuadrature()
+    {
+      const double b  = -2*g * (a + 1.0);
+      const double ai =  1.0 / (a + 1.0);
+
+      const double ymin = pow(1.0 + g, 2*(a + 1.0)) / b;
+      const double ymax = pow(1.0 - g, 2*(a + 1.0)) / b;
+
+      const double dy = (ymax - ymin) / (n + 1);
+      
+      for (double y = ymax - 0.5*dy; y > ymin; y -= dy) {
+	
+	const double v  = y*b;
+	const double w  = pow(v, ai);
+	const double x  = (1.0 + g*g - w) / (2*g);
+	const double dx = pow(v, -a*ai)*dy;
+	
+	insert(JElement2D_t(x,dx));
+      }
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  n          number of points
+     * \param  g          angular dependence parameter
+     * \param  a          power
+     * \param  xmin       minimal value
+     * \param  xmax       maximal value
+     */
+    JHenyeyGreenstein(const int    n,
+		      const double g,
+		      const double a,
+		      const double xmin,
+		      const double xmax) :
+      JQuadrature()
+    {
+      const double b  = -2*g * (a + 1.0);
+      const double ai =  1.0 / (a + 1.0);
+
+      const double ymin = pow(1.0 + g*g -2*g*xmin, a + 1.0) / b;
+      const double ymax = pow(1.0 + g*g -2*g*xmax, a + 1.0) / b;
+
+      const double dy = (ymax - ymin) / (n + 1);
+      
+      for (double y = ymax - 0.5*dy; y > ymin; y -= dy) {
+	
+	const double v  = y*b;
+	const double w  = pow(v, ai);
+	const double x  = (1.0 + g*g - w) / (2*g);
+	const double dx = pow(v, -a*ai)*dy;
+	
+	insert(JElement2D_t(x,dx));
+      }
+    }
+
+
+    /**
+     * Constructor for special case where a = -1.
+     *
+     * \param  n          number of points
+     * \param  g          angular dependence parameter
+     */
+    JHenyeyGreenstein(const int    n,
+		      const double g) :
+      JQuadrature()
+    {
+      const double dy = 1.0 / (n + 1);
+      const double gi = log((1.0 + g*g) / (1.0 - g*g)) / (2.0*g);
+      
+      for (double y = 1.0 - 0.5*dy; y > 0.0; y -= dy) {
+	
+	const double v  = -y*2.0*g*gi  +  log(1.0 + g*g);
+	const double w  = exp(v);
+	const double x  = (1.0 + g*g - w) / (2.0*g);
+	const double dx = w*gi*dy;
+	
+	insert(JElement2D_t(x,dx));
+      }
+    }
+  };
+
+
+  /**
+   * Numerical integrator for <tt>W(x) = (1 + g*x*x)</tt>.
+   * For this, <tt>g > 0</tt>.
+   *
+   * Rayleigh integration points and weights.
+   */ 
+  class JRayleigh : 
+    public JQuadrature 
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  n          number of points
+     * \param  g          angular dependence parameter
+     */
+    JRayleigh(const int    n,
+	      const double g) :
+      JQuadrature()
+    {
+      const double dy = 1.0 / (n + 1);
+      const double gi = 3.0/g  +  1.0;
+      
+      // t^3 + 3pt + 2q = 0
+      
+      const double p  = 1.0/g;
+      
+      for (double y = 0.5*dy; y < 1.0; y += dy) {
+	
+	const double q  = 0.5*gi - gi*y;
+	
+	const double b  = sqrt(q*q + p*p*p);
+	const double u  = pow(-q + b, 1.0/3.0);
+	const double v  = pow(+q + b, 1.0/3.0);
+	
+	const double x  =  u - v;
+	const double dx = (u + v) / (3.0*b);
+	
+	insert(JElement2D_t(x, dx*gi*dy)); 
+      }
+    }
+  };
+
+
+  /**
+   * Numerical integrator for <tt>W(x) = |x| / sqrt(1 - x*x)</tt>
+   *
+   * Co-tangent integration points and weights.
+   */ 
+  class JCotangent : 
+    public JQuadrature 
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  n          number of points
+     */
+    JCotangent(const int n) :
+      JQuadrature()
+    {
+      for (double ds = 1.0 / (n/2), sb = 0.5*ds; sb < 1.0; sb += ds) {
+
+	const double cb = sqrt((1.0 + sb)*(1.0 - sb));
+	const double dc = ds*sb/cb;
+	  
+	insert(JElement2D_t(+cb, dc));   
+	insert(JElement2D_t(-cb, dc));   
+      }
+    }
+  };
+
+
+  /**
+   * Numerical integrator for <tt>W(x) = |x| / sqrt(1 - x*x), x > 0 </tt> and <tt>W(x) =  1, x <= 0</tt>.
+   *
+   * Bi-tangent integration points and weights.
+   */ 
+  class JBitangent : 
+    public JQuadrature 
+  {
+  public:
+    /**
+     * Constructor.
+     *
+     * \param  n          number of points
+     */
+    JBitangent(const int n) :
+      JQuadrature()
+    {
+      double sb, ds;
+      double cb = 0.0;
+      double dc = 0.0;
+	  
+      for (ds = 1.0 / (n/2), sb = 0.5*ds; sb < 1.0; sb += ds) {
+
+	cb = sqrt((1.0 + sb)*(1.0 - sb));
+	dc = ds*sb/cb;
+	  
+	insert(JElement2D_t(cb, dc));   
+      }
+
+      for (dc = (cb + 1.0) / (n/2), cb -= 0.5*dc ; cb > -1.0; cb -= dc) {
+	insert(JElement2D_t(cb, dc));   
+      }
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JQuantiles.hh b/jpp/JTools/JQuantiles.hh
new file mode 100644
index 0000000..024ab4b
--- /dev/null
+++ b/jpp/JTools/JQuantiles.hh
@@ -0,0 +1,360 @@
+#ifndef __JTOOLS__JQUANTILES__
+#define __JTOOLS__JQUANTILES__
+
+#include <limits>
+#include <cmath>
+
+#include "JLang/JException.hh"
+#include "JTools/JRange.hh"
+#include "JTools/JElement.hh"
+#include "JTools/JResult.hh"
+#include "JTools/JAbstractCollection.hh"
+#include "JTools/JToolsToolkit.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JException;
+  using JLANG::JEmptyCollection;
+
+
+  /**
+   * Locate maximum or minimun of function.
+   * 
+   * Golden section search 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.
+   *
+   *             xa < xb < xc
+   *
+   *             is = +1  ->  There is a minimum, i.e:  f(xb) < min(f(xa),f(xc))
+   *             is = -1  ->  There is a maximum, i.e:  f(xb) > max(f(xa),f(xc))
+   *
+   * \param  xa       
+   * \param  xb       
+   * \param  xc       
+   * \param  f        function
+   * \param  is       sign (+1 -> minimim, -1 -> maximum)
+   * \param  eps      relative precision
+   */
+  template<class JFunction1D_t>
+  double search(const double xa,
+		const double xb,
+		const double xc,
+		const JFunction1D_t& f,
+		const int    is,
+		const double eps = 1.0e-6)
+  {
+    static const double R = 0.61803399;
+    static const double C = 1.0 - R;
+
+    double x0 = xa;
+    double x3 = xc;
+    double x1, x2;
+
+    if (fabs(xc-xb) > fabs(xb-xa)) {
+      x1 = xb;
+      x2 = xb + C*(xc-xb);
+    } else {
+      x2 = xb;
+      x1 = xb - C*(xb-xa);
+    }
+
+    double f1 = is * get_value(f(x1));
+    double f2 = is * get_value(f(x2));
+
+    while (fabs(x3-x0) > eps*(fabs(x1)+fabs(x2))) {
+
+      if (f2 < f1) {
+
+	x0 = x1;
+	x1 = x2;
+	x2 = R*x2 + C*x3;
+
+	f1 = f2;
+	f2 = is * get_value(f(x2));
+
+      } else {
+
+	x3 = x2;
+	x2 = x1;
+	x1 = R*x1 + C*x0;
+
+	f2 = f1;
+	f1 = is * get_value(f(x1));
+      }
+    }
+
+    if (f1 < f2)
+      return x1;
+    else
+      return x2;
+  }
+
+
+  /**
+   * Quantile calculator for a given function.
+   * It is assumed that the function has a single maximum.
+   */
+  class JQuantiles :
+    public JRange<double> 
+  {
+  public:
+
+    typedef JAbstractCollection<double>     JAbscissa_t;
+
+    /**
+     * Default constructor.
+     */
+    JQuantiles() :
+      Xmax(0.0),
+      Ymax(0.0),
+      fwhm(0.0),
+      sum (0.0)
+    {}
+   
+
+    /**
+     * Constructor.
+     *
+     * \param   f1        functional collection
+     * \param   Q         quantile
+     * \param   eps       relative precision
+     */
+    template<class JFunction1D_t>
+    JQuantiles(const JFunction1D_t& f1,
+	       const double         Q   = 1.0,
+	       const double         eps = 1.0e-6) :
+      Xmax(0.0),
+      Ymax(0.0),
+      fwhm(0.0),
+      sum (0.0)
+    {
+      set(f1, Q, eps);
+    }
+   
+
+    /**
+     * Constructor.
+     *
+     * \param   abscissa  abscissa
+     * \param   f1        function
+     * \param   Q         quantile
+     * \param   eps       relative precision
+     */
+    template<class JFunction1D_t>
+    JQuantiles(const JAbscissa_t&   abscissa,
+	       const JFunction1D_t& f1,
+	       const double         Q   = 1.0,
+	       const double         eps = 1.0e-6) :
+      Xmax(0.0),
+      Ymax(0.0),
+      fwhm(0.0),
+      sum (0.0)
+    {
+      set(abscissa, f1, Q, eps);
+    }
+
+
+    /**
+     * Set quantiles.
+     *
+     * \param   f1        functional collection
+     * \param   Q         quantile
+     * \param   eps       relative precision
+     */
+    template<class JFunction1D_t>
+    void set(const JFunction1D_t& f1,
+	     const double         Q   = 1.0,
+	     const double         eps = 1.0e-6) 
+    {
+      typedef typename JFunction1D_t::const_iterator  const_iterator;
+
+      if (f1.empty()) {
+	throw JEmptyCollection("JQuantiles() no data.");
+      }
+
+
+      // maximum
+
+      const_iterator p = f1.begin();
+
+      for (const_iterator i = f1.begin(); i != f1.end(); ++i) {
+	if (i->getY() > p->getY()) {
+	  p = i;
+	}
+      }
+      
+
+      // x at maximum
+      
+      Xmax = p->getX();
+	
+      if (p != f1.begin()) {
+	  
+	const double xa = (--p)->getX();
+	const double xb = (++p)->getX();
+	  
+	if (++p != f1.end()) {
+	    
+	  const double xc = p->getX();
+	    
+	  Xmax = search(xa, xb, xc, f1, -1, eps);
+	}
+      }
+	
+      Ymax = get_value(f1(Xmax));
+
+
+      // integral & quantile
+
+      if (Q > 0.0 && Q <= 1.0) {
+
+	JSplineFunction1D<JSplineElement2D<double, double>, JCollection, double> buffer;
+
+	try {
+
+	  sum = makeCDF(f1, buffer);
+
+	  setLowerLimit(buffer(0.5 * (1.0 - Q)));
+	  setUpperLimit(buffer(0.5 * (1.0 + Q)));
+	}
+	catch(const JException& error) {
+	  sum = 0.0;
+	}
+
+      } else {
+
+	sum = JTOOLS::getIntegral(f1);
+
+	if        (Q >  1.0) {
+	  setLowerLimit(f1. begin()->getX());
+	  setUpperLimit(f1.rbegin()->getX());
+	} else if (Q <= 0.0) {
+	  setLowerLimit(Xmax);
+	  setUpperLimit(Xmax);
+	}
+      }
+
+
+      // FWHM
+	
+      fwhm = 0.0;
+	
+      for (double xmin = f1.begin()->getX(), xmax = Xmax, v = 0.5*Ymax; ; ) {
+	
+	const double x = 0.5 * (xmin + xmax);
+	const double y = get_value(f1(x));
+	
+	if (fabs(y - v) < eps*v || xmax - xmin < eps) {
+	  fwhm -= x;
+	  break;
+	}
+	
+	if (y > v)
+	  xmax = x;
+	else
+	  xmin = x;
+      }
+      
+      for (double xmin = Xmax, xmax = f1.rbegin()->getX(), v = 0.5*Ymax; ; ) {
+	
+	const double x = 0.5 * (xmin + xmax);
+	const double y = get_value(f1(x));
+	  
+	if (fabs(y - v) < eps*v || xmax - xmin < eps) {
+	  fwhm += x;
+	  break;
+	}
+	
+	if (y > v)
+	  xmin = x;
+	else
+	  xmax = x;
+      }
+    }
+
+
+    /**
+     * Set quantiles.
+     *
+     * \param   abscissa  abscissa
+     * \param   f1        function
+     * \param   Q         quantile
+     * \param   eps       relative precision
+     */
+    template<class JFunction1D_t>
+    void set(const JAbscissa_t&   abscissa,
+	     const JFunction1D_t& f1,
+	     const double         Q   = 1.0,
+	     const double         eps = 1.0e-6) 
+    {
+      JSplineFunction1D<JSplineElement2D<double, double>, JCollection, double> buffer;
+
+      buffer.configure(abscissa, f1);
+      buffer.compile();
+
+      set(buffer, Q, eps);
+    }
+
+
+    /**
+     * Get position of maximum.
+     *
+     * \return     x value at maximum
+     */
+    double getX() const 
+    { 
+      return Xmax;
+    }
+
+ 
+    /**
+     * Get value of maximum.
+     *
+     * \return     y value at maximum
+     */
+    double getY() const 
+    {
+      return Ymax;
+    }
+
+
+    /**
+     * Get Full Width at Half Maximum.
+     *
+     * \return     FWHM
+     */
+    double getFWHM() const
+    {
+      return fwhm;
+    }
+    
+
+    /**
+     * Get integral of function.
+     *
+     * \return     integral
+     */
+    double getIntegral() const
+    {
+      return sum;
+    }
+
+
+  protected:
+    double Xmax;
+    double Ymax;
+    double fwhm;
+    double sum;
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JRange.hh b/jpp/JTools/JRange.hh
new file mode 100644
index 0000000..93ce131
--- /dev/null
+++ b/jpp/JTools/JRange.hh
@@ -0,0 +1,718 @@
+#ifndef __JTOOLS__JRANGE__
+#define __JTOOLS__JRANGE__
+
+#include <cmath>
+#include <utility>
+#include <functional>
+
+#include "JLang/JClass.hh"
+#include "JLang/JBool.hh"
+#include "JLang/JEquals.hh"
+#include "JLang/JVectorize.hh"
+#include "JTools/JPair.hh"
+#include "JMath/JMath.hh"
+#include "JMath/JLimits.hh"
+
+
+/**
+ * \file
+ *
+ * Auxiliary class to define a range between two values.
+ * \author mdejong
+ */
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JEquals;
+  using JLANG::array_type;
+  using JLANG::make_array;
+  using JMATH::JMath;
+
+
+  /**
+   * Range of values.
+   */
+  template<class T, class JComparator_t = std::less<T> >
+  class JRange :
+    public JPair<T,T>,
+    public JEquals< JRange<T> >,
+    public JMath  < JRange<T> >
+  {
+  public:
+
+    typedef std::pair<T,T>                             pair_type;
+    typedef JRange<T, JComparator_t>                   range_type;
+    typedef typename JLANG::JClass<T>::argument_type   argument_type;
+
+
+    /**
+     * Default constructor.\n
+     * This range corresponds to the maximal possible range.
+     */
+    JRange() :
+      JPair<T,T>(getMinimum(), getMaximum())
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  pair             pair
+     */
+    JRange(const pair_type& pair) :
+      JPair<T,T>(pair.first, pair.second)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  x                lower limit
+     * \param  y                upper limit
+     */
+    JRange(argument_type x,
+	   argument_type y) :
+      JPair<T,T>(x, y)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  x                lower and upper limit
+     */
+    JRange(argument_type x) :
+      JPair<T,T>(x, x)
+    {}
+
+
+    /**
+     * Constructor.\n
+     * The arguments could be values or iterators.
+     *
+     * \param  first            first
+     * \param  second           second
+     */
+    template<class R>
+    JRange(R first, R second) :
+      JPair<T,T>()
+    {
+      setRange(first, second);
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  buffer           input data
+     */
+    template<class JElement_t, class JAllocator_t>
+    JRange(const array_type<JElement_t, JAllocator_t>& buffer) :
+      JPair<T,T>()
+    {
+      setRange(buffer);
+    }
+
+
+    /**
+     * Type conversion operator.
+     *
+     * \return                  piar
+     */
+    operator pair_type() const
+    {
+      return pair_type(getLowerLimit(), getUpperLimit());
+    }
+
+
+    /**
+     * Get range.
+     *
+     * \return                  range
+     */
+    const range_type& getRange() const
+    {
+      return static_cast<const range_type&>(*this);
+    }
+
+
+    /**
+     * Set range.
+     *
+     * \param  range            range
+     */
+    void setRange(const range_type& range)
+    {
+      static_cast<range_type&>(*this) = range;
+    }
+
+
+    /**
+     * Set lower and upper limit.
+     *
+     * \param  x                lower limit
+     * \param  y                upper limit
+     */
+    void setRange(argument_type x, argument_type y)
+    {
+      this->first  = x;
+      this->second = y;
+    }
+
+
+    /**
+     * Set range.\n
+     * The arguments could be values or iterators.
+     *
+     * \param  first            first
+     * \param  second           second
+     */
+    template<class R>
+    void setRange(R first, R second)
+    {
+      using namespace JLANG;
+      
+      setRange(first, second, JBool<is_iterator<R>::value>());
+    }
+
+
+    /**
+     * Set lower and upper limit according to input data.
+     *
+     * \param  buffer           input data
+     */
+    template<class JElement_t, class JAllocator_t>
+    void setRange(const array_type<JElement_t, JAllocator_t>& buffer)
+    {
+      setRange(getMaximum(), getMinimum());
+
+      for (typename array_type<JElement_t, JAllocator_t>::const_iterator i = buffer.begin(); i != buffer.end(); ++i) {
+	include(*i);
+      }
+    }
+
+
+    /**
+     * Get lower limit.
+     *
+     * \return                  lower limit
+     */
+    T getLowerLimit() const
+    {
+      return this->first;
+    }
+
+
+    /**
+     * Get upper limit.
+     *
+     * \return                  upper limit
+     */
+    T getUpperLimit() const
+    {
+      return this->second;
+    }
+
+
+    /**
+     * Set lower limit.
+     *
+     * \param  x                lower limit
+     */
+    void setLowerLimit(argument_type x)
+    {
+      this->first  = x;
+    }
+
+
+    /**
+     * Set upper limit.
+     *
+     * \param  y                upper limit
+     */
+    void setUpperLimit(argument_type y)
+    {
+      this->second = y;
+    }
+
+
+    /**
+     * Fix lower limit.
+     *
+     * The range is shifted to the given lower limit.
+     *
+     * \param  x                lower limit
+     */
+    void fixLowerLimit(argument_type x)
+    {
+      this->second += x - this->first;
+      this->first   = x;
+    }
+
+
+    /**
+     * Fix upper limit.
+     *
+     * The range is shifted to the given upper limit.
+     *
+     * \param  y                upper limit
+     */
+    void fixUpperLimit(argument_type y)
+    {
+      this->first  += y - this->second;
+      this->second  = y;
+    }
+
+    
+    /**
+     * Equal method.
+     *
+     * \param  range            range
+     * \result                  true if this module range equal to given module range; else false
+     */
+    inline bool equals(const range_type& range) const
+    {
+      return (!this->compare(this->getLowerLimit(), range.getLowerLimit()) &&
+	      !this->compare(range.getLowerLimit(), this->getLowerLimit()) &&
+	      !this->compare(this->getUpperLimit(), range.getUpperLimit()) &&
+	      !this->compare(range.getUpperLimit(), this->getUpperLimit()));
+    }
+
+
+    /**
+     * Get length (difference between upper and lower limit).
+     *
+     * \return                  length
+     */
+    T getLength() const
+    {
+      return getUpperLimit() - getLowerLimit();
+    }
+
+
+    /**
+     * Set length (difference between upper and lower limit).
+     *
+     * \param  length           length
+     */
+    void setLength(argument_type length)
+    {
+      setUpperLimit(getLowerLimit() + length);
+    }
+
+
+    /**
+     * Check validity of range.
+     *
+     * \return                  true if lower limit less than or equal to upper limit; else false
+     */
+    bool is_valid() const
+    {
+      return !compare(getUpperLimit(), getLowerLimit());
+    }
+
+
+    /**
+     * Test whether value is inside range.
+     *
+     * \param  x                value
+     * \return                  true if lower limit <= value <= upper limit; else false
+     */
+    bool in_range(argument_type x) const
+    {
+      return (!compare(x, getLowerLimit()) && 
+	      !compare(getUpperLimit(), x));
+    }
+
+
+    /**
+     * Test whether value is inside range.
+     *
+     * \param  x                value
+     * \return                  true if lower limit <= value <= upper limit; else false
+     */
+    bool operator()(argument_type x) const
+    {
+      return in_range(x);
+    }
+
+
+    /**
+     * Constrain value to range.\n
+     * This method returns the original value if it is in this range, else
+     * lower limit if value < lower limit or upper limit if value > upper limit.
+     *
+     * \param  x                value
+     * \return                  lower limit <= x <= upper limit
+     */
+    T constrain(argument_type x) const
+    {
+      if (compare(x, getLowerLimit())) { return getLowerLimit(); }
+      if (compare(getUpperLimit(), x)) { return getUpperLimit(); }
+
+      return x;
+    }
+
+
+    /**
+     * Modulo value with respect to range.\n
+     *
+     * \param  x                value
+     * \return                  lower limit <= x <= upper limit
+     */
+    T mod(argument_type x) const
+    {
+      if      (compare(x, getLowerLimit()))
+	return x + getLength() * floor((getUpperLimit() - x) / getLength());
+      else if (compare(getUpperLimit(), x))
+	return x - getLength() * floor((x - getLowerLimit()) / getLength());
+      else
+	return x;
+    }
+
+
+    /**
+     * 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()));
+    }
+
+
+    /**
+     * Include given value to range.\n
+     * The new lower limit is the minimim of the original lower limit and given value and\n
+     * the new upper limit is the maximum of the original upper limit and given value;
+     *
+     * \param  x                value
+     * \return                  range
+     */
+    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
+     * the new upper limit is the minimum of the two upper limits.\n
+     * This operation results in an equal or smaller range and
+     * may result in an unphysical range (i.e.\ lower limit > upper limit).
+     *
+     * \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()); }
+
+      return *this;      
+    }
+
+
+    /**
+     * Combine ranges.\n
+     * The new lower limit is the minimim of the two lower limits and\n
+     * the new upper limit is the maximum of the two upper limits.\n
+     * This operation results in an equal or larger range.
+     *
+     * \param  range            range
+     */
+    range_type& combine(const range_type& range)
+    {  
+      if (compare(range.getLowerLimit(), getLowerLimit())) { setLowerLimit(range.getLowerLimit()); }
+      if (compare(getUpperLimit(), range.getUpperLimit())) { setUpperLimit(range.getUpperLimit()); }
+
+      return *this;
+    }
+
+
+    /**
+     * Add offset.
+     *
+     * \param  x                offset
+     */
+    range_type& add(argument_type x)
+    { 
+      this->first  += x;
+      this->second += x;
+
+      return *this;
+    }
+
+
+    /**
+     * Subtract offset.
+     *
+     * \param  x                offset
+     */
+    range_type& sub(argument_type x)
+    { 
+      this->first  -= x;
+      this->second -= x;
+
+      return *this;
+    }
+
+
+    /**
+     * Add offsets.\n
+     * The new lower limit is the sum of the two lower limits and\n
+     * the new upper limit is the sum of the two upper limits.
+     *
+     * \param  range            offset
+     */
+    range_type& add(const range_type& range)
+    { 
+      this->first  += range.getLowerLimit();
+      this->second += range.getUpperLimit();
+
+      return *this;
+    }
+
+
+    /**
+     * Subtract offsets.\n
+     * The new lower limit is the difference of the two lower limits and\n
+     * the new upper limit is the difference of the two upper limits.
+     *
+     * \param  range            offset
+     */
+    range_type& sub(const range_type& range)
+    { 
+      this->first  -= range.getLowerLimit();
+      this->second -= range.getUpperLimit();
+
+      return *this;
+    }
+
+    
+    /**
+     * Multiply range.
+     *
+     * \param  factor           factor
+     */
+    range_type& mul(const double factor)
+    { 
+      this->first  *= factor;
+      this->second *= factor;
+
+      return *this;
+    }
+
+    
+    /**
+     * Divide range.
+     *
+     * \param  factor           factor
+     */
+    range_type& div(const double factor)
+    { 
+      this->first  /= factor;
+      this->second /= factor;
+
+      return *this;
+    }
+
+
+    /**
+     * 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.
+     *
+     * \return                  minimum possible value
+     */
+    static T getMinimum() 
+    { 
+      return JMATH::JLimits<T>::min();
+    }
+
+
+    /**
+     * Get maximum possible value.
+     *
+     * \return                  maximum possible value
+     */
+    static T getMaximum() 
+    { 
+      return JMATH::JLimits<T>::max();
+    }
+
+    
+    /**
+     * Default range.
+     * This range corresponds to an unphysical range.
+     */
+    static const JRange<T, JComparator_t> DEFAULT_RANGE;
+
+
+    /**
+     * Function object.
+     *
+     * \param  first            first  argument
+     * \param  second           second argument
+     * \return                  true if first < second; else false
+     */
+    JComparator_t compare;
+
+  protected:
+    /**
+     * Set range.
+     *
+     * \param  first            first
+     * \param  second           second
+     * \param  option           false
+     */
+    template<class R>
+    void setRange(R first, R second, const JLANG::JBool<false>& option)
+    {
+      setRange((argument_type) first, (argument_type) second);
+    }
+
+
+    /**
+     * Set range.
+     *
+     * \param  first            first
+     * \param  second           second
+     * \param  option           true
+     */
+    template<class R>
+    void setRange(R first, R second, const JLANG::JBool<true>& option)
+    {
+      setRange(getMaximum(), getMinimum());
+
+      for (R i = first; i != second; ++i) {
+	include(*i);
+      }
+    }
+  };
+
+
+  /**
+   * Default range.
+   * This range corresponds to an unphysical range.
+   */
+  template<class T, class JComparator_t>
+  const JRange<T, JComparator_t> JRange<T, JComparator_t>::DEFAULT_RANGE(JRange<T, JComparator_t>::getMaximum(), 
+									 JRange<T, JComparator_t>::getMinimum()); 
+
+
+  /**
+   * Add ranges.\n
+   * The new lower limit is the sum of the two lower limits and\n
+   * the new upper limit is the sum of the two upper limits.
+   *
+   * \param  first               first  range
+   * \param  second              second range
+   * \result                     range
+   */
+  template<class T, class JComparator_t>
+  inline JRange<T, JComparator_t> operator+(const JRange<T, JComparator_t>& first, const JRange<T, JComparator_t>& second)
+  {
+    return JRange<T, JComparator_t>(first).add(second);
+  }
+
+
+  /**
+   * Subtract ranges.\n
+   * The new lower limit is the difference of the two lower limits and
+   * the new upper limit is the difference of the two upper limits.
+   *
+   * \param  first               first  range
+   * \param  second              second range
+   * \result                     range
+   */
+  template<class T, class JComparator_t>
+  inline JRange<T, JComparator_t> operator-(const JRange<T, JComparator_t>& first, const JRange<T, JComparator_t>& second)
+  {
+    return JRange<T, JComparator_t>(first).sub(second);
+  }
+
+
+  /**
+   * Test overlap between ranges.
+   *
+   * \param  first               first  range
+   * \param  second              second range
+   * \return                     true if there is a non-zero overlap; else false
+   */
+  template<class T, class JComparator_t>
+  inline bool overlap(const JRange<T, JComparator_t>& first, const JRange<T, JComparator_t>& second)
+  {
+    return first.overlap(second);
+  }
+
+
+  /**
+   * Join ranges.\n
+   * The new lower limit is the maximim of the two lower limits and\n
+   * the new upper limit is the minimum of the two upper limits.\n
+   * This operation results in an equal or smaller range and
+   * may result in an unphysical range (i.e.\ lower limit > upper limit).
+   *
+   * \param  first               first  range
+   * \param  second              second range
+   * \result                     range
+   */
+  template<class T, class JComparator_t>
+  inline JRange<T, JComparator_t> join(const JRange<T, JComparator_t>& first, const JRange<T, JComparator_t>& second)
+  {  
+    return JRange<T, JComparator_t>(first).join(second);
+  }
+
+
+  /**
+   * Combine ranges.\n
+   * The new lower limit is the minimim of the two lower limits and\n
+   * the new upper limit is the maximum of the two upper limits.\n
+   * This operation results in an equal or larger range.
+   *
+   * \param  first               first  range
+   * \param  second              second range
+   * \result                     range
+   */
+  template<class T, class JComparator_t>
+  inline JRange<T, JComparator_t> combine(const JRange<T, JComparator_t>& first, const JRange<T, JComparator_t>& second)
+  {  
+    return JRange<T, JComparator_t>(first).combine(second);
+  }
+
+
+  /**
+   * Auxiliary method to create range of values.
+   *
+   * \param  x                lower limit
+   * \param  y                upper limit
+   * \return                  range
+   */
+  template<class T>
+  inline JRange<T> make_range(T x, T y)
+  {
+    return JRange<T>(x,y);
+  } 
+}
+
+#endif
diff --git a/jpp/JTools/JResult.hh b/jpp/JTools/JResult.hh
new file mode 100644
index 0000000..bd3f3a1
--- /dev/null
+++ b/jpp/JTools/JResult.hh
@@ -0,0 +1,1043 @@
+#ifndef __JTOOLS__JRESULT__
+#define __JTOOLS__JRESULT__
+
+#include <cmath>
+
+#include "JTools/JRange.hh"
+#include "JLang/JClass.hh"
+#include "JLang/JAssert.hh"
+#include "JMath/JMath.hh"
+#include "JMath/JZero.hh"
+
+
+/**
+ * \file
+ *
+ * This include file containes various data structures that
+ * can be used as specific return types for the interpolating methods.
+ * These data structures have standard arithmetic capabilities and
+ * are templated so that they can be expanded in higher dimensions.
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JMATH::JMath;
+
+
+  /**
+   * Data structure for result including value and first derivative of function.
+   *
+   * This data structure contains the following data mambers:
+   * <pre>
+   *    JResultDerivative::f   = function value;
+   *    JResultDerivative::fp  = first  derivative;
+   * </pre>
+   *
+   * This class implements the JMATH::JMath interface.
+   */
+  template<class JResult_t>
+  struct JResultDerivative :
+    public JMath< JResultDerivative<JResult_t> >
+  {
+
+    typedef typename JLANG::JClass<JResult_t>::argument_type                     argument_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JResultDerivative() :
+      f  (JMATH::zero),
+      fp (JMATH::zero)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  f               function value
+     * \param  fp              first  derivative
+     */
+    JResultDerivative(argument_type f,
+		      argument_type fp) :
+      f  (f ),
+      fp (fp)
+    {}
+
+
+    /**
+     * Prefix unary minus for function value of PDF.
+     *
+     * \return                  function value of PDF
+     */
+    JResultDerivative& negate()
+    {
+      f   = -f;
+      fp  = -fp;
+
+      return *this;
+    }
+
+
+    /**
+     * Addition operator for function value of PDF.
+     *
+     * \param  value            function value of PDF
+     * \return                  function value of PDF
+     */
+    JResultDerivative& add(const JResultDerivative& value)
+    {
+      f   += value.f;
+      fp  += value.fp;
+
+      return *this;
+    }
+
+
+    /**
+     * Subtraction operator for function value of PDF.
+     *
+     * \param  value            function value of PDF
+     * \return                  function value of PDF
+     */
+    JResultDerivative& sub(const JResultDerivative& value)
+    {
+      f   -= value.f;
+      fp  -= value.fp;
+
+      return *this;
+    }
+
+
+    /**
+     * Multiplication operator for function value of PDF.
+     *
+     * \param  value            multiplication factor
+     * \return                  function value of PDF
+     */
+    JResultDerivative& mul(const double value)
+    {
+      f   *= value;
+      fp  *= value;
+
+      return *this;
+    }
+
+
+    /**
+     * Division operator for function value of PDF.
+     *
+     * \param  value            multiplication factor
+     * \return                  function value of PDF
+     */
+    JResultDerivative& div(const double value)
+    {
+      f   /= value;
+      fp  /= value;
+
+      return *this;
+    }
+
+
+    /**
+     * Get probability.\n
+     * If the given hit is false (true), the return value corresponds to the Poisson probability
+     * that zero (one or more) hits occur for the given expectation value JResultDerivative::f.
+     *
+     * \param  hit              hit (or not)
+     * \return                  probability
+     */
+    double getP(const bool hit) const
+    {
+      if (!hit)
+	return exp(-f);                  // probability of 0 hits
+      else
+	return 1.0 - getP(false);        // probability of 1 or more hits
+    }
+
+
+    /**
+     * Get chi2.
+     * The chi2 corresponds to <tt>-log(P)</tt>, where <tt>P</tt> is the probability JResultDerivative::f.
+     *
+     * \param  hit              hit (or not)
+     * \return                  chi2
+     */
+    double getChi2(const bool hit) const
+    {
+      if (!hit)
+	return  f;                       // = -log(getP(false))
+      else
+	return -log(getP(true));
+    }
+
+
+    /**
+     * Get derivative of chi2.
+     *
+     * \param  hit              hit (or not)
+     * \return                  derivative
+     */
+    double getDerivativeOfChi2(const bool hit) const
+    {
+      if (!hit)
+	return  fp;
+      else
+	return -fp * getP(false) / getP(true);
+    }
+
+
+    JResult_t f;      //!< function value
+    JResult_t fp;     //!< first  derivative
+  };
+
+
+  /**
+   * Data structure for result including value and first derivative of function.
+   *
+   * This data structure contains the following data mambers:
+   * <pre>
+   *    JResultHesse::f   = function value;
+   *    JResultHesse::fp  = first  derivative;
+   *    JResultHesse::fpp = second derivative;
+   * </pre>
+   *
+   * This class implements the JMATH::JMath interface.
+   */
+  template<class JResult_t>
+  struct JResultHesse :
+    public JResultDerivative<JResult_t>,
+    public JMath< JResultHesse<JResult_t> >
+  {
+
+    typedef typename JResultDerivative<JResult_t>::argument_type                 argument_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JResultHesse() :
+      JResultDerivative<JResult_t>(),
+      fpp(JMATH::zero)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  f               function value
+     * \param  fp              first  derivative
+     * \param  fpp             second derivative
+     */
+    JResultHesse(argument_type f,
+		 argument_type fp,
+		 argument_type fpp) :
+      JResultDerivative<JResult_t>(f, fp),
+      fpp(fpp)
+    {}
+
+
+    /**
+     * Prefix unary minus for function value of PDF.
+     *
+     * \return                  function value of PDF
+     */
+    JResultHesse& negate()
+    {
+      static_cast<JResultDerivative<JResult_t>&>(*this).negate();
+      fpp = -fpp;
+
+      return *this;
+    }
+
+
+    /**
+     * Addition operator for function value of PDF.
+     *
+     * \param  value            function value of PDF
+     * \return                  function value of PDF
+     */
+    JResultHesse& add(const JResultHesse& value)
+    {
+      static_cast<JResultDerivative<JResult_t>&>(*this).add(value);
+      fpp += value.fpp;
+
+      return *this;
+    }
+
+
+    /**
+     * Subtraction operator for function value of PDF.
+     *
+     * \param  value            function value of PDF
+     * \return                  function value of PDF
+     */
+    JResultHesse& sub(const JResultHesse& value)
+    {
+      static_cast<JResultDerivative<JResult_t>&>(*this).sub(value);
+      fpp -= value.fpp;
+
+      return *this;
+    }
+
+
+    /**
+     * Multiplication operator for function value of PDF.
+     *
+     * \param  value            multiplication factor
+     * \return                  function value of PDF
+     */
+    JResultHesse& mul(const double value)
+    {
+      static_cast<JResultDerivative<JResult_t>&>(*this).mul(value);
+      fpp *= value;
+
+      return *this;
+    }
+
+
+    /**
+     * Division operator for function value of PDF.
+     *
+     * \param  value            multiplication factor
+     * \return                  function value of PDF
+     */
+    JResultHesse& div(const double value)
+    {
+      static_cast<JResultDerivative<JResult_t>&>(*this).div(value);
+      fpp /= value;
+
+      return *this;
+    }
+
+
+    JResult_t fpp;    //!< second derivative
+  };
+
+
+  /**
+   * Data structure for result including value, first derivative and integrals of function.
+   *
+   * This data structure contains the following data mambers:
+   * <pre>
+   *    JResultPDF::f   = function value;
+   *    JResultPDF::fp  = first derivative;
+   *    JResultPDF::v   = partial  integral;
+   *    JResultPDF::V   = complete integral.
+   * </pre>
+   * The partial and complete integrals are used to evaluate the probability of the first hit. 
+   *
+   * This class implements the JMATH::JMath interface.
+   */
+  template<class JResult_t>
+  struct JResultPDF : 
+    public JMath< JResultPDF<JResult_t> >
+  {
+
+    typedef typename JLANG::JClass<JResult_t>::argument_type                     argument_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JResultPDF() :
+      f (JMATH::zero),
+      fp(JMATH::zero),
+      v (JMATH::zero),
+      V (JMATH::zero)
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  f               function value
+     * \param  fp              first derivative
+     * \param  v               integral <xmin,x]
+     * \param  V               integral <xmin,xmax>
+     */
+    JResultPDF(argument_type f,
+	       argument_type fp,
+	       argument_type v,
+	       argument_type V) :
+      f (f ),
+      fp(fp),
+      v (v),
+      V (V)
+    {}
+
+
+    /**
+     * 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>.
+     *
+     * \param  R               rate
+     * \param  x               abscissa value
+     * \param  X               abscissa range
+     */
+    JResultPDF(argument_type R,
+	       argument_type x,
+	       const JRange<JResult_t>& X) :
+      f (R),
+      fp(JMATH::zero),
+      v (R * (X.constrain(x)    - X.getLowerLimit())),
+      V (R * (X.getUpperLimit() - X.getLowerLimit()))
+    {}
+
+
+    /**
+     * Prefix unary minus for function value of PDF.
+     *
+     * \return                  function value of PDF
+     */
+    JResultPDF& negate()
+    {
+      f  = -f;
+      fp = -fp;
+      v  = -v;
+      V  = -V;
+
+      return *this;
+    }
+
+
+    /**
+     * Addition operator for function value of PDF.
+     *
+     * \param  value            function value of PDF
+     * \return                  function value of PDF
+     */
+    JResultPDF& add(const JResultPDF& value)
+    {
+      f  += value.f;
+      fp += value.fp;
+      v  += value.v;
+      V  += value.V;
+
+      return *this;
+    }
+
+
+    /**
+     * Subtraction operator for function value of PDF.
+     *
+     * \param  value            function value of PDF
+     * \return                  function value of PDF
+     */
+    JResultPDF& sub(const JResultPDF& value)
+    {
+      f  -= value.f;
+      fp -= value.fp;
+      v  -= value.v;
+      V  -= value.V;
+
+      return *this;
+    }
+
+
+    /**
+     * Multiplication operator for function value of PDF.
+     *
+     * \param  value            multiplication factor
+     * \return                  function value of PDF
+     */
+    JResultPDF& mul(const double value)
+    {
+      f  *= value;
+      fp *= value;
+      v  *= value;
+      V  *= value;
+
+      return *this;
+    }
+
+
+    /**
+     * Division operator for function value of PDF.
+     *
+     * \param  value            division factor
+     * \return                  function value of PDF
+     */
+    JResultPDF& div(const double value)
+    {
+      f  /= value;
+      fp /= value;
+      v  /= value;
+      V  /= value;
+
+      return *this;
+    }
+
+
+    /**
+     * Get probability of first hit.\n
+     * The probability is defined at the moment JResultPDF::f and JResultPDF::v have been evaluated
+     * and it is normalised to the total interval corresponding to JResultPDF::V.
+     *
+     * \return                  probability
+     */
+    double getP() const
+    {
+      return exp(-v) * f / (1.0 - exp(-V));
+    }
+
+
+    /**
+     * Get chi2 of first hit.\n
+     * The chi2 corresponds to <tt>-log(P)</tt>, where <tt>P</tt> is the probability JResultPDF::f.
+     *
+     * \return                  chi2
+     */
+    double getChi2() const
+    {
+      return -log(getP());
+    }
+
+
+    /**
+     * Get derivative of chi2 of first hit.
+     *
+     * \return                  derivative
+     */
+    double getDerivativeOfChi2() const
+    {
+      return fp/f - f;
+    }
+
+
+    JResult_t f;      //!< function value
+    JResult_t fp;     //!< first derivative
+    JResult_t v;      //!< integral <xmin,x]
+    JResult_t V;      //!< integral <xmin,xmax>
+  };
+
+
+  /**
+   * Data structure for result including value and <tt>N</tt> derivatives of function.
+   *
+   * This data structure contains the following data mambers:
+   * <pre>
+   *    JResultPolynome::y[0] = function value;
+   *    JResultPolynome::y[i] = ith derivative; 
+   *    JResultPolynome::y[N] = Nth derivative; 
+   * </pre>
+   *
+   * This class implements the JMATH::JMath interface.
+   */
+  template<unsigned int N, class JResult_t>
+  struct JResultPolynome :
+    public JMath< JResultPolynome<N, JResult_t> >
+  {
+
+    typedef typename JLANG::JClass<JResult_t>::argument_type                     argument_type;
+
+    static const int NUMBER_OF_POINTS = N + 1;        // number of points (starting at 0)
+
+
+    /**
+     * Default constructor.
+     */
+    JResultPolynome()
+    {
+      for (int i = 0; i != NUMBER_OF_POINTS; ++i) {
+	y[i] = JMATH::zero;
+      }
+    }
+
+
+    /**
+     * Type conversion operator.
+     *
+     * \return                 result
+     */
+    operator JResultDerivative<JResult_t>() const
+    {
+      STATIC_CHECK(NUMBER_OF_POINTS >= 2);
+      return JResultDerivative<JResult_t>(y[0], y[1]);
+    }
+
+
+    /**
+     * Type conversion operator.
+     *
+     * \return                 result
+     */
+    operator JResultHesse<JResult_t>() const
+    {
+      STATIC_CHECK(NUMBER_OF_POINTS >= 3);
+      return JResultHesse<JResult_t>(y[0], y[1], y[2]);
+    }
+
+
+    /**
+     * Prefix unary minus for function value of PDF.
+     *
+     * \return                  function value of PDF
+     */
+    JResultPolynome& negate()
+    {
+      for (int i = 0; i != NUMBER_OF_POINTS; ++i) {
+	y[i] = -y[i];
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Addition operator for function value of PDF.
+     *
+     * \param  value            function value of PDF
+     * \return                  function value of PDF
+     */
+    JResultPolynome& add(const JResultPolynome& value)
+    {
+      for (int i = 0; i != NUMBER_OF_POINTS; ++i) {
+	y[i] += value.y[i];
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Subtraction operator for function value of PDF.
+     *
+     * \param  value            function value of PDF
+     * \return                  function value of PDF
+     */
+    JResultPolynome& sub(const JResultPolynome& value)
+    {
+      for (int i = 0; i != NUMBER_OF_POINTS; ++i) {
+	y[i] -= value.y[i];
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Multiplication operator for function value of PDF.
+     *
+     * \param  value            multiplication factor
+     * \return                  function value of PDF
+     */
+    JResultPolynome& mul(const double value)
+    {
+      for (int i = 0; i != NUMBER_OF_POINTS; ++i) {
+	y[i] *= value;
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Division operator for function value of PDF.
+     *
+     * \param  value            multiplication factor
+     * \return                  function value of PDF
+     */
+    JResultPolynome& div(const double value)
+    {
+      for (int i = 0; i != NUMBER_OF_POINTS; ++i) {
+	y[i] /= value;
+      }
+
+      return *this;
+    }
+
+
+    /**
+     * Function value.
+     *
+     * \param  x          abscissa value
+     * \return            function value
+     */
+    double getValue(const double x) const
+    {
+      double w = 0.0;
+      double z = 1.0;
+
+      for (int i = 0; i != NUMBER_OF_POINTS; ++i, z *= x / i) {
+        w += y[i] * z;
+      }
+
+      return w;
+    }
+
+    
+    /**
+     * Function value.
+     *
+     * \param  x          abscissa value
+     * \return            function value
+     */
+    double operator()(const double x) const
+    {
+      return getValue(x);
+    }
+
+
+    JResult_t y[NUMBER_OF_POINTS];   //!< function and derivative values
+  };
+
+
+  /**
+   * Auxiliary class to recursively evaluate to a result.
+   */
+  template<class T>
+  struct JResultEvaluator
+  {
+    typedef T                                result_type;
+    
+    /**
+     * Get function value.
+     *
+     * \return                  result
+     */
+    static result_type get_value(typename JLANG::JClass<T>::argument_type value)
+    {
+      return value;
+    }
+    
+    /**
+     * Get derivative value.
+     *
+     * \return                  result
+     */
+    static result_type get_derivative(typename JLANG::JClass<T>::argument_type value)
+    {
+      return value;
+    }
+    
+    /**
+     * Get partial integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_integral(typename JLANG::JClass<T>::argument_type value)
+    {
+      return value;
+    }
+    
+    /**
+     * Get total integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_total_integral(typename JLANG::JClass<T>::argument_type value)
+    {
+      return value;
+    }
+  };
+
+
+  /**
+   * Template specialisation of JResultEvaluator for JResultDerivative.
+   */
+  template<class T>
+  struct JResultEvaluator< JResultDerivative<T> >
+  {
+    typedef typename JResultEvaluator<T>::result_type  result_type;
+
+    /**
+     * Get function value.
+     *
+     * \return                  result
+     */
+    static result_type get_value(const JResultDerivative<T>& value)
+    {
+      return JResultEvaluator<T>::get_value(value.f);
+    }
+
+    /**
+     * Get derivative value.
+     *
+     * \return                  result
+     */
+    static result_type get_derivative(const JResultDerivative<T>& value)
+    {
+      return JResultEvaluator<T>::get_value(value.fp);
+    }
+
+    /**
+     * Get partial integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_integral(const JResultDerivative<T>& value)
+    {
+      return JMATH::zero;
+    }
+    
+    /**
+     * Get total integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_total_integral(typename JLANG::JClass<T>::argument_type value)
+    {
+      return JMATH::zero;
+    }
+  };
+
+
+  /**
+   * Template specialisation of JResultEvaluator for JResultHesse.
+   */
+  template<class T>
+  struct JResultEvaluator< JResultHesse<T> >
+  {
+    typedef typename JResultEvaluator<T>::result_type  result_type;
+    
+    /**
+     * Get function value.
+     *
+     * \return                  result
+     */
+    static result_type get_value(const JResultHesse<T>& value)
+    {
+      return JResultEvaluator<T>::get_value(value.f);
+    }
+    
+    /**
+     * Get derivative value.
+     *
+     * \return                  result
+     */
+    static result_type get_derivative(const JResultHesse<T>& value)
+    {
+      return JResultEvaluator<T>::get_value(value.fp);
+    }
+
+    /**
+     * Get partial integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_integral(const JResultHesse<T>& value)
+    {
+      return JMATH::zero;
+    }
+    
+    /**
+     * Get total integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_total_integral(typename JLANG::JClass<T>::argument_type value)
+    {
+      return JMATH::zero;
+    }
+  };
+
+
+  /**
+   * Template specialisation of JResultEvaluator for JResultPDF.
+   */
+  template<class T>
+  struct JResultEvaluator< JResultPDF<T> >
+  {
+    typedef typename JResultEvaluator<T>::result_type  result_type;
+    
+    /**
+     * Get function value.
+     *
+     * \return                  result
+     */
+    static result_type get_value(const JResultPDF<T>& value)
+    {
+      return JResultEvaluator<T>::get_value(value.f);
+    }
+
+    /**
+     * Get derivative value.
+     *
+     * \return                  result
+     */
+    static result_type get_derivative(const JResultPDF<T>& value)
+    {
+      return JResultEvaluator<T>::get_value(value.fp);
+    }
+    
+    /**
+     * Get partial integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_integral(const JResultPDF<T>& value)
+    {
+      return JResultEvaluator<T>::get_value(value.v);
+    }
+    
+    /**
+     * Get total integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_total_integral(typename JLANG::JClass<T>::argument_type value)
+    {
+      return JResultEvaluator<T>::get_value(value.V);
+    }
+  };
+
+
+  /**
+   * Template specialisation of JResultEvaluator for JResultPolynome.
+   */
+  template<unsigned int N, class T>
+  struct JResultEvaluator< JResultPolynome<N, T> >
+  {
+    typedef typename JResultEvaluator<T>::result_type  result_type;
+    
+    /**
+     * Get function value.
+     *
+     * \return                  result
+     */
+    static result_type get_value(const JResultPolynome<N, T>& value)
+    {
+      return JResultEvaluator<T>::get_value(value.y[0]);
+    }
+
+    /**
+     * Get derivative value.
+     *
+     * \return                  result
+     */
+    static result_type get_derivative(const JResultPolynome<N, T>& value)
+    {
+      return JResultEvaluator<T>::get_value(value.y[1]);
+    }
+    
+    /**
+     * Get partial integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_integral(const JResultPolynome<N, T>& value)
+    {
+      return JMATH::zero;
+    }
+    
+    /**
+     * Get total integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_total_integral(typename JLANG::JClass<T>::argument_type value)
+    {
+      return JMATH::zero;
+    }
+  };
+
+
+  /**
+   * Template specialisation of JResultEvaluator for JResultPolynome.
+   */
+  template<class T>
+  struct JResultEvaluator< JResultPolynome<0, T> >
+  {
+    typedef typename JResultEvaluator<T>::result_type  result_type;
+    
+    /**
+     * Get function value.
+     *
+     * \return                  result
+     */
+    static result_type get_value(const JResultPolynome<0, T>& value)
+    {
+      return JResultEvaluator<T>::get_value(value.y[0]);
+    }
+
+    /**
+     * Get derivative value.
+     *
+     * \return                  result
+     */
+    static result_type get_derivative(const JResultPolynome<0, T>& value)
+    {
+      return JMATH::zero;
+    }
+    
+    /**
+     * Get partial integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_integral(const JResultPolynome<0, T>& value)
+    {
+      return JMATH::zero;
+    }
+    
+    /**
+     * Get total integral value.
+     *
+     * \return                  result
+     */
+    static result_type get_total_integral(typename JLANG::JClass<T>::argument_type value)
+    {
+      return JMATH::zero;
+    }
+  };
+
+  
+  /**
+   * Helper method to recursively evaluate a to function value.
+   *
+   * \param  value            result
+   * \return                  function value
+   */
+  template<class JResult_t>
+  inline typename JResultEvaluator<JResult_t>::result_type get_value(const JResult_t& value)
+  { 
+    return JResultEvaluator<JResult_t>::get_value(value);
+  }
+
+  
+  /**
+   * Helper method to convert function value to derivative value.
+   *
+   * \param  value            result
+   * \return                  derivative value
+   */
+  template<class JResult_t>
+  inline typename JResultEvaluator<JResult_t>::result_type get_derivative(const JResult_t& value)
+  { 
+    return JResultEvaluator<JResult_t>::get_derivative(value);
+  }
+
+  
+  /**
+   * Helper method to convert function value to partial integral value.
+   *
+   * \param  value            result
+   * \return                  partial integral value
+   */
+  template<class JResult_t>
+  inline typename JResultEvaluator<JResult_t>::result_type get_integral(const JResult_t& value)
+  { 
+    return JResultEvaluator<JResult_t>::get_integral(value);
+  }
+
+  
+  /**
+   * Helper method to convert function value to total integral value.
+   *
+   * \param  value            result
+   * \return                  total integral value
+   */
+  template<class JResult_t>
+  inline typename JResultEvaluator<JResult_t>::result_type get_total_integral(const JResult_t& value)
+  { 
+    return JResultEvaluator<JResult_t>::get_total_integral(value);
+  }
+}
+
+#endif
diff --git a/jpp/JTools/JResultTransformer.hh b/jpp/JTools/JResultTransformer.hh
new file mode 100644
index 0000000..ea8ac14
--- /dev/null
+++ b/jpp/JTools/JResultTransformer.hh
@@ -0,0 +1,87 @@
+#ifndef __JTOOLS__JRESULTTRANSFORMER__
+#define __JTOOLS__JRESULTTRANSFORMER__
+
+#include "JTools/JMultiMapTransformer.hh"
+#include "JTools/JResult.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  /**
+   * Auxiliary class to handle multidimensional map transformations for given result type.
+   */
+  template<class JResult_t>
+  struct JResultTransformer {
+
+    typedef JResult_t                    result_type;
+
+    template<unsigned int N, class JArgument_t>
+    static result_type transform(const JMultiMapTransformer<N, JArgument_t>&                     transformer,
+				 typename JMultiMapTransformer<N, JArgument_t>::const_array_type array,
+				 const result_type&                                              result) 
+    {
+      return result;
+    }
+  };
+
+
+  /**
+   * Auxiliary class to handle multidimensional map transformations for given result type.
+   */
+  template<class JResult_t>
+  struct JResultTransformer< JResultHesse<JResult_t> > {
+
+    typedef JResultHesse<JResult_t>      result_type;
+
+    template<unsigned int N, class JArgument_t>
+    static result_type transform(const JMultiMapTransformer<N, JArgument_t>&                     transformer,
+				 typename JMultiMapTransformer<N, JArgument_t>::const_array_type array,
+				 const result_type&                                              result) 
+    {
+      const JArgument_t z = transformer.getXn(array, 1.0) - transformer.getXn(array, 0.0);
+       
+      result_type value(result);
+
+      value.fp /= z;
+
+      return value;
+    }
+  };
+
+
+  /**
+   * Auxiliary class to handle multidimensional map transformations for given result type.
+   */
+  template<class JResult_t>
+  struct JResultTransformer< JResultPDF<JResult_t> > {
+
+    typedef JResultPDF<JResult_t>        result_type;
+
+    template<unsigned int N, class JArgument_t>
+    static result_type transform(const JMultiMapTransformer<N, JArgument_t>&                     transformer,
+				 typename JMultiMapTransformer<N, JArgument_t>::const_array_type array,
+				 const result_type&                                              result) 
+    {
+      typedef JArgument_t argument_type;
+
+      const argument_type z = transformer.getXn(array, 1.0) - transformer.getXn(array, 0.0);
+
+      result_type value(result);
+
+      value.fp /= z;
+      value.v  *= z;
+      value.V  *= z;
+
+      return value;
+    }
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JSet.hh b/jpp/JTools/JSet.hh
new file mode 100644
index 0000000..b5a90c9
--- /dev/null
+++ b/jpp/JTools/JSet.hh
@@ -0,0 +1,163 @@
+#ifndef __JTOOLS__JSET__
+#define __JTOOLS__JSET__
+
+#include <set>
+#include <iterator>
+
+#include "JTools/JAbstractCollection.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  template<class JElement_t, class JDistance_t>
+  class JCollection;
+
+  
+  /**
+   * Simple data structure for an abstract collection of non-equidistant abscissa values.
+   *
+   * This class implements the JAbstractCollection interface.
+   */
+  template<class JAbscissa_t>
+  struct JSet : 
+    public JAbstractCollection<JAbscissa_t>,
+    std::set                  <JAbscissa_t>
+  {
+    typedef typename JAbstractCollection<JAbscissa_t>::abscissa_type      abscissa_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JSet()
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  collection      abstract collection
+     */
+    JSet(const JAbstractCollection<abscissa_type>& collection)
+    {
+      for (int i = 0; i != collection.getSize(); ++i) {
+	this->insert(collection.getX(i));
+      }
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * \param  __begin         begin of abscissa values
+     * \param  __end           end   of abscissa values
+     */
+    template<class T>
+    JSet(T __begin, T __end)
+    {
+      for (T i = __begin; i != __end; ++i) {
+	this->insert(*i);
+      }
+    }
+
+
+    /**
+     * Get number of elements.
+     *
+     * \return                 number of elements
+     */
+    virtual int getSize() const override 
+    { 
+      return (int) this->size();
+    }
+    
+
+    /**
+     * Get abscissa value.
+     *
+     * \param  index           index
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getX(int index) const override 
+    {
+      typename std::set<abscissa_type>::const_iterator i = this->begin();
+
+      std::advance(i, index);
+
+      return *i;
+    }
+
+
+    /**
+     * Get minimal abscissa value.
+     *
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getXmin() const override 
+    {
+      return *(this->begin());
+    }
+
+
+    /**
+     * Get maximal abscissa value.
+     *
+     * \return                 abscissa value
+     */
+    virtual abscissa_type getXmax() const override 
+    {
+      return *(this->rbegin());
+    }
+    
+
+    /**
+     * Configure collection.
+     *
+     * \param  collection        collection
+     * \return                   this set
+     */
+    template<class JElement_t, class JDistance_t>
+    const JSet& operator()(JCollection<JElement_t, JDistance_t>& collection) const
+    {
+      collection.configure(*this);
+
+      return *this;
+    }
+  };
+
+
+  /**
+   * Helper method for JSet.
+   *
+   * \param  __begin         begin of abscissa values
+   * \param  __end           end   of abscissa values
+   * \return                 set
+   */
+  template<class T>
+  inline JSet<typename std::iterator_traits<T>::value_type> make_set(T __begin, T __end)
+  {
+    return JSet<typename std::iterator_traits<T>::value_type>(__begin, __end);
+  }
+
+
+  /**
+   * Helper method for JSet.
+   *
+   * \param  input           abstract collection
+   * \return                 set
+   */
+  template<class JAbscissa_t>
+  inline JSet<JAbscissa_t> make_set(const JAbstractCollection<JAbscissa_t>& input)
+  {
+    return JSet<JAbscissa_t>(input);
+  }
+}
+
+#endif
diff --git a/jpp/JTools/JSpline.hh b/jpp/JTools/JSpline.hh
new file mode 100644
index 0000000..cfd7843
--- /dev/null
+++ b/jpp/JTools/JSpline.hh
@@ -0,0 +1,865 @@
+#ifndef __JTOOLS__JSPLINE__
+#define __JTOOLS__JSPLINE__
+
+#include <utility>
+
+#include "JMath/JZero.hh"
+#include "JLang/JException.hh"
+#include "JLang/JClass.hh"
+#include "JTools/JFunctional.hh"
+#include "JTools/JDistance.hh"
+#include "JTools/JResult.hh"
+#include "JTools/JMapCollection.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JLANG::JNoValue;
+  using JLANG::JDivisionByZero;
+  using JLANG::JFunctionalException;
+  using JLANG::JValueOutOfRange;
+
+
+  /**
+   * Auxiliary class to define first derivates of the spline function at the two extrema.
+   */
+  template<class JOrdinate_t>
+  class JSplineBounds {
+  public:
+
+    typedef JOrdinate_t                                                          ordinate_type;
+    typedef typename JLANG::JClass<ordinate_type>::argument_type                 argument_type;
+
+
+    /** 
+     * Default constructor.
+     */
+    JSplineBounds() :
+      fp_at_xmin(false, ordinate_type()),
+      fp_at_xmax(false, ordinate_type())
+    {}
+
+
+    /** 
+     * Constructor.
+     *
+     * \param fpAtXmin          1st derivative at minimal abscissa value
+     * \param fpAtXmax          1st derivative at maximal abscissa value
+     */
+    JSplineBounds(argument_type fpAtXmin,
+		  argument_type fpAtXmax) :
+      fp_at_xmin(true, fpAtXmin),
+      fp_at_xmax(true, fpAtXmax)
+    {}
+
+
+    /**
+     * Set first derivative of function at minimal abscissa value.
+     * 
+     * \param fp                1st derivative
+     */
+    void setFirstDerivativeAtXmin(argument_type fp)
+    {
+      fp_at_xmin.first  = true;
+      fp_at_xmin.second = fp;
+    }
+
+
+    /**
+     * Set first derivative of function at maximal abscissa value.
+     * 
+     * \param fp                1st derivative
+     */
+    void setFirstDerivativeAtXmax(argument_type fp)
+    {
+      fp_at_xmax.first  = true;
+      fp_at_xmax.second = fp;
+    }
+
+
+    /**
+     * Has first derivative of function at minimal abscissa value.
+     * 
+     * \return                  true if 1st derivative is set; else false
+     */
+    const bool& hasFirstDerivativeAtXmin() const 
+    { 
+      return fp_at_xmin.first;
+    }
+
+
+    /**
+     * Has first derivative of function at maximal abscissa value.
+     * 
+     * \return                  true if 1st derivative is set; else false
+     */
+    const bool& hasFirstDerivativeAtXmax() const 
+    { 
+      return fp_at_xmax.first;
+    }
+
+
+    /**
+     * Get first derivative of function at minimal abscissa value.
+     * 
+     * \return                  1st derivative
+     */
+    ordinate_type getFirstDerivativeAtXmin() const 
+    { 
+      if (fp_at_xmin.first)
+	return fp_at_xmin.second;
+      else
+	throw JNoValue("JSplineBounds: missing 1st derivative.");
+    }
+
+
+    /**
+     * Get first derivative of function at maximal abscissa value.
+     * 
+     * \return                  1st derivative
+     */
+    ordinate_type getFirstDerivativeAtXmax() const 
+    { 
+      if (fp_at_xmax.first)
+	return fp_at_xmax.second;
+      else
+	throw JNoValue("JSplineBounds: missing 1st derivative.");
+    }
+
+  protected:
+    std::pair<bool, ordinate_type> fp_at_xmin;
+    std::pair<bool, ordinate_type> fp_at_xmax;
+  };
+
+
+  /**
+   * Helper method for JSplineBounds.
+   *
+   * \param fpAtXmin          1st derivative at minimal abscissa value
+   * \param fpAtXmax          1st derivative at maximal abscissa value
+   * \return                  spline bounds
+   */
+  template<class JOrdinate_t>
+  inline JSplineBounds<JOrdinate_t> make_spline_bounds(const JOrdinate_t fpAtXmin,
+						       const JOrdinate_t fpAtXmax)
+  {
+    return JSplineBounds<JOrdinate_t>(fpAtXmin, fpAtXmax);
+  }
+
+
+  /**
+   * Template base class for spline interpolations.
+   *
+   * This class partially implements the JFunctional interface.
+   *
+   * Note that the data structure of the elements in the collection should have the additional methods:
+   * <pre>
+   *     ordinate_type getU() const;
+   *     void setU(ordinate_type u);
+   * </pre>
+   * to get and set the second derivatives, respectively.
+   *
+   * Spline interpolation 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.
+   */
+  template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JSplineCollection :
+    public JCollection_t<JElement_t, JDistance_t>,
+    public virtual JFunctional<>
+  {
+  public:
+
+    typedef JCollection_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;
+ 
+    using JFunctional<>::compile;
+
+
+    /**
+     * Determination of second derivatives with specified bounds.
+     *
+     * \param bounds            1st derivatives at two extrema.
+     */
+    void compile(const JSplineBounds<ordinate_type>& bounds) 
+    {
+      const int numberOfElements = this->size();
+
+      using namespace std;
+
+      if (numberOfElements > 2) {
+	
+	std::vector<double> buffer(numberOfElements);
+
+	if (bounds.hasFirstDerivativeAtXmin()) {
+	  
+	  iterator j = this->begin();
+	  iterator i = j++;
+	   
+	  const double        dx = this->getDistance(i->getX(),  j->getX());
+	  const ordinate_type dy =                  (j->getY() - i->getY());
+	   
+	  buffer[0] = -0.5;
+
+	  i->setU((3.0/dx) * (dy/dx - bounds.getFirstDerivativeAtXmin()));
+
+	} else {
+
+	  buffer[0] = 0.0;
+
+	  this->begin()->setU(JMATH::zero);
+	}
+
+	int index = 1;
+       
+	for (iterator k = this->begin(), i = k++, j = k++; k != this->end(); ++i, ++j, ++k, ++index) {
+
+	  const abscissa_type  x1 = i->getX();
+	  const abscissa_type  x2 = j->getX();
+	  const abscissa_type  x3 = k->getX();
+
+	  const ordinate_type& y1 = i->getY();
+	  const ordinate_type& y2 = j->getY();
+	  const ordinate_type& y3 = k->getY();
+
+	  const double sig = this->getDistance(x1, x2) / this->getDistance(x1, x3);
+	  const double h   = sig * buffer[index-1] + 2.0;
+	 
+	  buffer[index]    = (sig - 1.0) / h;
+	 
+	  j->setU((y3 - y2) / this->getDistance(x2, x3)  -  
+		  (y2 - y1) / this->getDistance(x1, x2));
+
+	  j->setU((6.0 * j->getU() / this->getDistance(x1, x3)  -  sig * i->getU()) / h);
+	}
+       
+
+	if (bounds.hasFirstDerivativeAtXmax()) {
+
+	  reverse_iterator j = this->rbegin();
+	  reverse_iterator i = j++;
+
+	  index = numberOfElements - 2;
+	  
+	  const double        dx = this->getDistance(i->getX(),  j->getX());
+	  const ordinate_type dy =                  (j->getY() - i->getY());
+	   
+	  i->setU((3.0/dx) * (bounds.getFirstDerivativeAtXmax() - dy/dx));
+
+	  i->setU((i->getU() - 0.5*j->getU()) / (0.5*buffer[index] + 1.0));
+
+	} else {
+
+	  this->rbegin()->setU(JMATH::zero);
+	}
+
+
+	reverse_iterator j = this->rbegin();
+	reverse_iterator i = j++;
+	
+	index = numberOfElements - 2;
+	
+	for ( ; j != this->rend(); ++i, ++j, --index) {
+	  j->setU(j->getU() + i->getU() * buffer[index]);
+	}
+
+      } else {
+
+	for (iterator i = this->begin(); i != this->end(); ++i) {
+	  i->setU(JMATH::zero);
+	}
+      }
+    }
+
+
+  protected:
+    /**
+     * Default constructor.
+     */
+    JSplineCollection()
+    {}
+
+
+    /**
+     * Determination of second derivatives with no bounds.
+     */
+    virtual void do_compile() override 
+    {
+      compile(JSplineBounds<ordinate_type>());
+    }
+  };
+
+
+  /**
+   * Template definition for functional collection with spline interpolation.
+   */
+  template<class JElement_t, 
+	   template<class, class> class JCollection_t,
+	   class JResult_t,
+           class JDistance_t>
+  class JSplineFunction;
+
+
+  /**
+   * Template specialisation for functional collection with spline interpolation.
+   */
+  template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JSplineFunction<JElement_t, 
+			JCollection_t, 
+			typename JResultType<typename JElement_t::ordinate_type>::result_type,
+			JDistance_t> :
+    public JSplineCollection<JElement_t, JCollection_t, JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type, 
+		     typename JResultType<typename JElement_t::ordinate_type>::result_type>
+  {
+  public:
+
+    typedef JSplineCollection<JElement_t, JCollection_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, data_type>                                  function_type;  
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+
+    /**
+     * Default constructor.			
+     */
+    JSplineFunction()
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    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 ((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."));
+      }
+
+      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;
+
+      return a * p->getY() + b * q->getY()
+	- a*b * ((a + 1.0)*p->getU() + (b + 1.0)*q->getU()) * dx*dx/6;
+    }
+  };
+
+
+  /**
+   * Template specialisation for spline interpolation method with returning JResultDerivative data structure.
+   */
+  template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JSplineFunction<JElement_t,
+			JCollection_t,
+			JResultDerivative<typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			JDistance_t> :
+    public JSplineCollection<JElement_t, JCollection_t, JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type, 
+		     JResultDerivative<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
+  {
+  public:
+
+    typedef JSplineCollection<JElement_t, JCollection_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, JResultDerivative<data_type> >              function_type;
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+ 
+    using JFunctional<>::compile;
+
+
+    /**
+     * Default constructor.
+     */
+    JSplineFunction() 
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    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 ((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."));
+      }
+
+      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;
+
+      result.f   = a * p->getY() + b * q->getY()
+	- a*b * ((a + 1.0)*p->getU() + (b + 1.0)*q->getU()) * dx*dx/6;
+
+      result.fp  = (q->getY() - p->getY() + (p->getU()*(1.0 - 3*a*a) -
+					     q->getU()*(1.0 - 3*b*b)) * dx*dx/6) / dx;
+
+      return result;
+    }
+
+
+  private:
+    mutable result_type result;
+  };
+
+
+  /**
+   * Template specialisation for spline interpolation method with returning JResultPDF data structure.
+   *
+   * Note that the data structure of the elements in the collection should have the additional methods:
+   * <pre>
+   *     ordinate_type getIntegral() const;
+   *     void setIntegral(ordinate_type v);
+   * </pre>
+   * to get and set the integral values, respectively.
+   */
+  template<class JElement_t, template<class, class> class JCollection_t, class JDistance_t>
+  class JSplineFunction<JElement_t,
+			JCollection_t,
+			JResultPDF<typename JResultType<typename JElement_t::ordinate_type>::result_type>,
+			JDistance_t> :
+    public JSplineCollection<JElement_t, JCollection_t, JDistance_t>,
+    public JFunction<typename JElement_t::abscissa_type, 
+		     JResultPDF<typename JResultType<typename JElement_t::ordinate_type>::result_type> >
+  {
+  public:
+
+    typedef JSplineCollection<JElement_t, JCollection_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::distance_type                              distance_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 typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JFunction<abscissa_type, JResultPDF<data_type> >                     function_type;
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+ 
+    using JFunctional<>::compile;
+
+
+    /**
+     * Default constructor.			
+     */
+    JSplineFunction() 
+    {}
+
+
+    /**
+     * Determination of second derivatives with specified bounds.
+     *
+     * \param bounds            1st derivatives at two extrema.
+     */
+    void compile(const JSplineBounds<ordinate_type>& bounds) 
+    {
+      if (this->size() >= 2u) {
+
+	collection_type::compile(bounds);
+ 
+	this->begin()->setIntegral(JMATH::zero);
+
+	for (iterator j = this->begin(), i = j++; j != this->end(); ++i, ++j) {
+	  
+	  const double        dx = this->getDistance(i->getX(), j->getX());
+	  const ordinate_type y  = i->getY() + j->getY();
+	  const ordinate_type z  = i->getU() + j->getU();
+	
+	  const ordinate_type v = dx * 0.50 * y;
+	  const ordinate_type w = dx * 0.25 * z*dx*dx/6;
+
+	  j->setIntegral(i->getIntegral() + v - w);
+	}
+      }
+    }
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    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        (p == this->begin() && this->getDistance(x, (p++)->getX()) > distance_type::precision) {
+
+	try {
+
+	  result   = this->getExceptionHandler().action(JValueOutOfRange("JSplineFunction<>::operator() x < xmin."));
+
+	  // overwrite integral values
+
+	  result.v = 0;
+	  result.V = this->rbegin()->getIntegral();
+
+	} catch(const JValueOutOfRange& exception) {
+	  throw exception;
+	}
+
+	return result;
+
+      } else if (p == this->end()   && this->getDistance((--p)->getX(), x) > distance_type::precision) {
+
+	try {
+
+	  result   = this->getExceptionHandler().action(JValueOutOfRange("JSplineFunction<>::operator() x > xmax."));
+
+	  // overwrite integral values
+
+	  result.v = this->rbegin()->getIntegral();
+	  result.V = this->rbegin()->getIntegral();
+
+	} catch(const JValueOutOfRange& exception) {
+	  throw exception;
+	}
+
+	return result;
+      }
+
+      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;
+
+      result.f  = a * p->getY() + b * q->getY()
+	- a*b * ((a + 1.0)*p->getU() + (b + 1.0)*q->getU()) * dx*dx/6;
+
+      result.fp = (q->getY() - p->getY() + (p->getU()*(1.0 - 3*a*a) -
+					    q->getU()*(1.0 - 3*b*b)) * dx*dx/6) / dx;
+      
+      result.v  = p->getIntegral()
+	+ 0.5*dx * (p->getY() - 0.5*p->getU()*dx*dx/6)
+	- 0.5*dx * ((a*a*p->getY() - b*b*q->getY()) +
+		    (p->getU() * a*a*(0.5*a*a - 1.0) -
+		     q->getU() * b*b*(0.5*b*b - 1.0)) * dx*dx/6);
+      
+      result.V  = this->rbegin()->getIntegral();
+
+      return result;
+    }
+
+
+  protected:
+    /**
+     * Determination of second derivatives with no bounds.
+     */
+    virtual void do_compile() override 
+    {
+      compile(JSplineBounds<ordinate_type>());
+    }
+
+
+  private:
+    mutable result_type result;
+  };
+
+
+  /**
+   * Template class for spline interpolation in 1D
+   *
+   * This class implements the JFunction1D interface.
+   */
+  template<class JElement_t,
+	   template<class, class> class JCollection_t,
+	   class JResult_t   = typename JElement_t::ordinate_type,
+	   class JDistance_t = JDistance<typename JElement_t::abscissa_type> >
+  class JSplineFunction1D :
+    public JSplineFunction<JElement_t, JCollection_t, JResult_t, JDistance_t>,
+    public JFunction1D<typename JElement_t::abscissa_type, JResult_t> 
+  {
+  public:
+
+    typedef JSplineCollection<JElement_t, JCollection_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::distance_type                              distance_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 JFunction1D<abscissa_type, JResult_t>                                function_type;           
+
+    typedef typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+
+    /**
+     * Default contructor.
+     */
+    JSplineFunction1D()
+    {}
+  };
+
+
+  /**
+   * \cond NEVER
+   * Forward declarations.
+   * \endcond
+   */
+  template<class JAbscissa_t, class JOrdinate_t>
+  struct JSplineElement2D;
+
+  template<template<class, class, class> class JMap_t>
+  struct JMapCollection;
+
+
+  /**
+   * Functional map with spline interpolation.
+   */
+  template<class JKey_t,
+           class JValue_t,
+           template<class, class, class> class JMap_t,
+           class JResult_t,
+           class JDistance_t = JDistance<JKey_t> >
+  class JSplineMap :
+    public JMap_t<JKey_t, JValue_t, JDistance_t>,
+    public JFunction<JKey_t, JResult_t>
+  {
+  public:
+
+    typedef JMap_t<JKey_t, JValue_t, JDistance_t>                                collection_type;
+    typedef JFunction<JKey_t, JResult_t>                                         function_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::distance_type                              distance_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 typename function_type::argument_type                                argument_type;
+    typedef typename function_type::result_type                                  result_type;
+    typedef typename function_type::JExceptionHandler                            exceptionhandler_type;
+
+    typedef typename JResultType<ordinate_type>::result_type                     data_type;
+    typedef JSplineFunction1D<JSplineElement2D<argument_type, data_type>, 
+			      JMapCollection<JMap_t>::template collection_type,
+			      result_type>                                       JSplineFunction1D_t;
+
+
+    /**
+     * Default constructor.
+     */
+    JSplineMap()
+    {}
+
+
+    /**
+     * Recursive interpolation method implementation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const override 
+    {
+      const argument_type x = *pX;
+
+      ++pX;  // next argument value
+
+      const_iterator p = this->begin();
+
+      for (typename JSplineFunction1D_t::iterator q = buffer.begin(); q != buffer.end(); ++q, ++p) {
+	q->getY() = JFunction<argument_type, data_type>::getValue(p->getY(), pX);
+      }
+
+      buffer.compile();
+
+      return buffer(x);
+    }
+
+
+  private:
+    /**
+     * Function compilation.
+     */
+    virtual void do_compile() override 
+    {
+      buffer.clear();
+
+      for (iterator i = this->begin(); i != this->end(); ++i) {
+	buffer.put(i->getX(), data_type());
+      }
+    }
+
+
+    mutable JSplineFunction1D_t buffer;
+  };
+
+
+  /**
+   * Conversion of data points to integral values.
+   *
+   * The integration includes the use of 2nd derivatives of the data points of the input spline interpolating function.
+   *
+   * \param  input             collection   
+   * \param  output            mappable collection
+   * \return                   integral
+   */
+  template<class JElement_t,
+           template<class, class> class JCollection_t,
+           class JResult_t,
+           class JDistance_t>
+  inline typename JElement_t::ordinate_type 
+  integrate(const JSplineFunction1D<JElement_t, JCollection_t, JResult_t, JDistance_t>& input, 
+	    typename JMappable<JElement_t>::map_type&                                   output)
+  {
+    typedef typename JElement_t::ordinate_type                                                             ordinate_type;
+    typedef typename JSplineFunction1D<JElement_t, JCollection_t, JResult_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) {
+	
+	const double        dx = input.getDistance(i->getX(), j->getX());
+	const ordinate_type y  = i->getY()  +  j->getY();
+	const ordinate_type z  = i->getU()  +  j->getU();             
+	const ordinate_type v  = dx * 0.50 * y;
+	const ordinate_type w  = dx * 0.25 * z*dx*dx/6;
+	
+	V += v - w;
+	
+	output.put(j->getX(), V);
+      }
+    }
+    
+    return V;
+  }
+  
+
+  /**
+   * Conversion of data points to integral values.
+   *
+   * The integration directly uses the integral values of the input spline interpolating function.
+   *
+   * \param  input             collection   
+   * \param  output            mappable collection
+   * \return                   integral
+   */
+  template<class JElement_t,
+           template<class, class> class JCollection_t,
+           class JDistance_t>
+  inline typename JElement_t::ordinate_type
+  integrate(const JSplineFunction1D<JElement_t, JCollection_t, JResultPDF<typename JElement_t::ordinate_type>, JDistance_t>& input,
+	    typename JMappable<JElement_t>::map_type&                                                                        output)
+  {
+    typedef typename JElement_t::ordinate_type                                                               ordinate_type;
+    typedef JResultPDF<ordinate_type>                                                                        result_type;
+    typedef typename JSplineFunction1D<JElement_t, JCollection_t, result_type, JDistance_t>::const_iterator  const_iterator;
+    
+    if (input.getSize() > 1) {
+      
+      for (const_iterator i = input.begin(); i != input.end(); ++i) {
+        output.put(i->getX(), i->getIntegral());
+      }
+
+      return input.rbegin()->getIntegral();
+    }
+    
+    return JMATH::zero;
+  }
+}
+
+#endif
diff --git a/jpp/JTools/JToolsToolkit.hh b/jpp/JTools/JToolsToolkit.hh
new file mode 100644
index 0000000..6b81ae5
--- /dev/null
+++ b/jpp/JTools/JToolsToolkit.hh
@@ -0,0 +1,352 @@
+#ifndef __JTOOLS__JTOOLSTOOLKIT__
+#define __JTOOLS__JTOOLSTOOLKIT__
+
+#include "JLang/JException.hh"
+#include "JLang/JBool.hh"
+#include "JMath/JZero.hh"
+#include "JTools/JAssembler.hh"
+#include "JTools/JElement.hh"
+#include "JTools/JCollection.hh"
+#include "JTools/JGarbageCollection.hh"
+#include "JTools/JMultiFunction.hh"
+#include "JTools/JMultiHistogram.hh"
+#include "JTools/JFunctionalMap.hh"
+
+
+/**
+ * \file
+ *
+ * This include file contains various recursive methods to operate on multi-dimensional collections.
+ * \author mdejong
+ */
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+/**
+ * Auxiliary classes and methods for multi-dimensional interpolations and histograms.
+ */
+namespace JTOOLS {
+
+  using JLANG::JException;
+  using JLANG::JEmptyCollection;
+  using JLANG::JDivisionByZero;
+  using JLANG::JBool;
+
+  
+  /**
+   * Conversion of data points to cumulative probability distribition (CDF).
+   *
+   * Note that the data type of the input container should be preserved 
+   * so that the corresponding method <tt>integrate()</tt> is used.
+   *
+   * \param  input             collection   
+   * \param  output            mappable collection
+   * \param  eps               minimal step size
+   * \return                   integral value
+   */
+  template<class JContainer_t,
+	   class JKey_t,
+	   class JValue_t>
+  inline typename JContainer_t::ordinate_type
+  makeCDF(const JContainer_t&                        input,
+	  JMappableCollection<JKey_t, JValue_t>&     output, 
+	  const typename JContainer_t::ordinate_type eps = JMATH::zero)
+  {
+    typedef typename JContainer_t::ordinate_type       ordinate_type;
+    typedef typename JContainer_t::abscissa_type       abscissa_type;
+    typedef JElement2D<abscissa_type, ordinate_type>   element_type;
+    typedef JCollection<element_type>                  buffer_type;
+
+
+    if (input.getSize() > 1) {
+      
+      buffer_type buffer;
+
+      const ordinate_type V = integrate(input, buffer);
+      
+      if (V == ordinate_type(JMATH::zero)) {
+	THROW(JDivisionByZero, "Method makeCDF(): integral equals zero.");
+      }
+      
+      output.clear();
+      
+      typename buffer_type::const_iterator i = buffer.begin();
+	    
+      for ( ; i != buffer.end() && i->getY() <= 0.5 * eps * V; ++i) {}
+      
+      if (i != buffer.end()) {
+	
+	// force first point at (0, ymin)
+      
+	JKey_t   x = 0.0;
+	JValue_t y = i->getX();
+	
+	output.put(x, y);
+      
+	JKey_t   xmax = x;
+	JValue_t ymax = y;
+      
+	for (++i; i != buffer.end(); ++i) {
+	  
+	  x = i->getY() / V;
+	  y = i->getX();
+	  
+	  if (x > xmax) {
+	  
+	    ymax = y;
+	    
+	    if (x > xmax + eps) {
+	      
+	      output.put(x, y);
+	      
+	      xmax = x;
+	    }
+	  }
+	}
+	
+	// force last point at (1, ymax)
+	
+	x = 1.0;
+	y = ymax;
+	
+	output.put(x,y);
+	
+      } else {
+	THROW(JDivisionByZero, "Method makeCDF(): no remaining data.");
+      }
+
+      return V;
+
+    } else {
+      THROW(JEmptyCollection, "Method makeCDF(): not sufficient input data.");
+    }
+  }
+
+  
+  /**
+   * Get integral of input data points.
+   *
+   * \param  input           input data
+   * \return                 integral value
+   */
+  template<class JContainer_t>
+  inline typename JContainer_t::ordinate_type getIntegral(const JContainer_t& input)
+  { 
+    JGarbageCollection<typename JContainer_t::abscissa_type, typename JContainer_t::ordinate_type> garbage;
+    
+    return integrate(input, garbage);
+  }
+
+
+  /**
+   * Auxiliary method to get integral of input data points.
+   *
+   * \param  input           input data
+   * \return                 integral value
+   */
+  template<class JFunction_t,
+	   template<class, class, class> class JMap_t,
+	   class JTail_t>
+  inline typename JFunction_t::ordinate_type
+  getIntegral(const JMultiMap<typename JFunction_t::abscissa_type, JFunction_t, JMapList<JMap_t, JTail_t>, typename JFunction_t::distance_type>& input)
+  { 
+    typedef typename JFunction_t::abscissa_type                                               abscissa_type;
+    typedef typename JFunction_t::ordinate_type                                               ordinate_type;
+    typedef typename JFunction_t::distance_type                                               distance_type;
+    typedef typename JFunctionalMap<JMap_t>::template function_type<abscissa_type,
+								    ordinate_type,
+								    ordinate_type,
+								    distance_type>            buffer_type;
+    typedef JMultiMap<abscissa_type, JFunction_t, JMapList<JMap_t, JTail_t>, distance_type>   multimap_type;
+    
+    static buffer_type buffer;
+    
+    buffer.configure(input);
+    
+    typename buffer_type::iterator out = buffer.begin();
+    
+    for (typename multimap_type::const_iterator in = input.begin(); in != input.end(); ++in, ++out) {
+      out->getY() = getIntegral(in->getY());
+    }
+    
+    buffer.compile();
+    
+    return getIntegral(buffer);
+  }
+  
+
+  /**
+   * Get integral of input data points.
+   *
+   * \param  input           input data
+   * \return                 integral value
+   */
+  template<class JFunction_t,
+	   template<class, class, class> class JMap_t,
+	   class JTail_t>
+  inline typename JFunction_t::ordinate_type
+  getIntegral(const JMultiFunction<JFunction_t, JMapList<JMap_t, JTail_t>, typename JFunction_t::distance_type>& input)
+  { 
+    typedef typename JFunction_t::abscissa_type                                      abscissa_type;
+    typedef typename JFunction_t::ordinate_type                                      ordinate_type;
+    typedef typename JFunction_t::distance_type                                      distance_type;
+    typedef typename JFunctionalMap<JMap_t>::template function_type<abscissa_type,
+								    ordinate_type,
+								    ordinate_type,
+								    distance_type>   buffer_type;
+    typedef JMultiFunction<JFunction_t, JMapList<JMap_t, JTail_t>, distance_type>    multifunction_type;
+    
+    buffer_type buffer;
+    
+    for (typename multifunction_type::const_iterator i = input.begin(); i != input.end(); ++i) {      
+      buffer.put(i->getX(), getIntegral(i->getY()));
+    }
+    
+    buffer.compile();
+    
+    return getIntegral(buffer);
+  }
+
+
+  /**
+   * Reset value.
+   *
+   * The value is set to (the equivalent of) zero, see method JMATH::getZero.
+   *
+   * \param  value           value
+   */
+  template<class T>
+  inline void reset(T& value)
+  {
+    value = JMATH::getZero<T>();
+  }
+  
+
+  /**
+   * Recursive reset of collection.
+   *
+   * \param  collection      collection
+   */
+  template<class JElement_t, class JDistance_t>
+  inline void reset(JCollection<JElement_t, JDistance_t>& collection)
+  {
+    typedef typename JCollection<JElement_t, JDistance_t>::iterator  iterator;
+
+    for (iterator i = collection.begin(); i != collection.end(); ++i) {
+      reset(i->getY());
+    }
+  }
+
+  
+  /**
+   * Copy of input to output.
+   *
+   * The output value is set to the input value.
+   *
+   * \param  input           input
+   * \param  output          output
+   */
+  template<class T>
+  inline void copy(const T& input, T& output)
+  {
+    output = input;
+  }
+
+
+  /**
+   * Recursive copy of input collection to output collection.
+   *
+   * \param  input           input
+   * \param  output          output
+   */
+  template<class JElement_t, class JDistance_t, class JKey_t, class JValue_t>
+  inline void copy(const JCollection<JElement_t, JDistance_t>& input, JMappableCollection<JKey_t, JValue_t>& output)
+  {
+    typedef typename JCollection<JElement_t, JDistance_t>::const_iterator  const_iterator;
+
+    output.clear();
+
+    for (const_iterator i = input.begin(); i != input.end(); ++i) {
+      copy(i->getY(), output.get(i->getX()));
+    }
+  }
+
+
+  /**
+   * Configuration of value.
+   *
+   * This is a fall-back method; it does nothing.
+   *
+   * \param  value           value
+   * \param  bounds          bounds
+   * \param  option          false
+   */
+  template<class T, class JAbscissa_t>
+  inline void configure(const T& value, const JAbstractCollection<JAbscissa_t>& bounds, JBool<false> option)
+  {}
+
+
+  /**
+   * Recursive configuration of collection.
+   *
+   * \param  collection      collection
+   * \param  bounds          bounds
+   * \param  option          true
+   */
+  template<class JElement_t, class JDistance_t>
+  inline void configure(JCollection<JElement_t, JDistance_t>&                          collection,
+			const JAbstractCollection<typename JElement_t::abscissa_type>& bounds,
+			JBool<true>                                                    option = JBool<true>())
+  {
+    typedef typename JCollection<JElement_t, JDistance_t>::iterator       iterator;
+    typedef typename JCollection<JElement_t, JDistance_t>::ordinate_type  ordinate_type;
+
+    collection.configure(bounds);
+
+    for (iterator i = collection.begin(); i != collection.end(); ++i) {
+      configure(i->getY(), bounds, JBool<JAssembler<ordinate_type>::is_collection>());
+    }
+  }
+
+
+  /**
+   * Accumulation of value.
+   *
+   * This is a fall-back method; it does nothing.
+   *
+   * \param  value           value
+   * \param  option          false
+   */
+  template<class T>
+  inline void accumulate(T& value, JBool<false> option)
+  {}
+
+
+  /**
+   * Recursive accumulation of collection.
+   *
+   * \param  collection      collection
+   * \param  option          true
+   */
+  template<class JElement_t, class JDistance_t>
+  inline void accumulate(JCollection<JElement_t, JDistance_t>& collection, JBool<true> option = JBool<true>())
+  {
+    typedef typename JCollection<JElement_t, JDistance_t>::iterator       iterator;
+    typedef typename JCollection<JElement_t, JDistance_t>::ordinate_type  ordinate_type;
+
+    for (iterator i = collection.begin(); i != collection.end(); ++i) {
+      accumulate(i->getY(), JBool<JAssembler<ordinate_type>::is_collection>());
+    }
+
+    if (collection.getSize() > 1) {
+
+      for (iterator j = collection.begin(), i = j++; j != collection.end(); ++i, ++j) {
+	j->getY() += i->getY();
+      }
+
+      reset(collection.begin()->getY());
+    }
+  }
+}
+
+#endif
diff --git a/jpp/JTools/JTransformableMultiFunction.hh b/jpp/JTools/JTransformableMultiFunction.hh
new file mode 100644
index 0000000..125547e
--- /dev/null
+++ b/jpp/JTools/JTransformableMultiFunction.hh
@@ -0,0 +1,294 @@
+#ifndef __JTOOLS__JTRANSFORMABLEMULTIFUNCTION__
+#define __JTOOLS__JTRANSFORMABLEMULTIFUNCTION__
+
+#include "JIO/JSerialisable.hh"
+#include "JLang/JSharedPointer.hh"
+
+#include "JTools/JMultiFunction.hh"
+#include "JTools/JMultiMapTransformer.hh"
+#include "JTools/JFunctional.hh"
+#include "JTools/JArray.hh"
+#include "JTools/JResultTransformer.hh"
+#include "JTools/JTransformableMultiHistogram.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JIO::JReader;
+  using JIO::JWriter;
+
+
+  /**
+   * Transformable multidimensional function.
+   *
+   * This class implements the JTransformable interface.
+   */
+  template<class JFunction_t, 
+	   class JMaplist_t, 
+	   class JDistance_t = JDistance<typename JFunction_t::argument_type> >
+  class JTransformableMultiFunction :
+    public JMultiFunction<JFunction_t, JMaplist_t, JDistance_t>,
+    public JTransformable<JMapLength<JMaplist_t>::value, typename JFunction_t::argument_type>
+  {
+  public:
+
+    typedef JMultiFunction<JFunction_t, 
+			   JMaplist_t,
+			   JDistance_t>                                         multifunction_type;
+
+    enum { NUMBER_OF_DIMENSIONS = multifunction_type::NUMBER_OF_DIMENSIONS };
+
+    typedef JFunction_t                                                         function_type;
+    
+    typedef typename multifunction_type::value_type                             value_type;
+    typedef typename multifunction_type::argument_type                          argument_type;
+    typedef typename multifunction_type::supervisor_type                        supervisor_type;
+
+    typedef typename multifunction_type::abscissa_type                          abscissa_type;
+    typedef typename multifunction_type::ordinate_type                          ordinate_type;
+    typedef typename multifunction_type::result_type                            result_type;
+    
+    typedef typename multifunction_type::const_iterator                         const_iterator;
+    typedef typename multifunction_type::const_reverse_iterator                 const_reverse_iterator;
+    typedef typename multifunction_type::iterator                               iterator;
+    typedef typename multifunction_type::reverse_iterator                       reverse_iterator;
+
+    typedef typename multifunction_type::super_iterator                         super_iterator;
+    typedef typename multifunction_type::super_const_iterator                   super_const_iterator;
+
+    typedef JMultiMapTransformer<JMapLength<JMaplist_t>::value, argument_type>  transformer_type;
+    typedef typename transformer_type::array_type                               array_type;
+
+    using multifunction_type::insert;
+    
+
+    /**
+     * Default constructor.
+     */
+    JTransformableMultiFunction() :
+      transformer(transformer_type::getClone())
+    {}
+
+
+    /**
+     * Constructor.
+     *
+     * \param  input                multidimensional input
+     */
+    template<class T>
+    JTransformableMultiFunction(const T& input) 
+    {
+      insert(input);
+
+      this->compile();
+    }
+
+
+    /**
+     * Get transformable multidimensional function.
+     *
+     * \return                      this transformable multidimensional function
+     */
+    const JTransformableMultiFunction& getTransformableMultiFunction() const
+    {
+      return static_cast<const JTransformableMultiFunction&>(*this);
+    }
+
+
+    /**
+     * Get transformable multidimensional function.
+     *
+     * \return                      this transformable multidimensional function
+     */
+    JTransformableMultiFunction& getTransformableMultiFunction()
+    {
+      return static_cast<JTransformableMultiFunction&>(*this);
+    }
+
+
+    /**
+     * Insert multidimensional input.
+     *
+     * \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) 
+    {
+      this->transformer.reset(input.transformer->clone());
+
+      multifunction_type::insert(input);
+    }
+
+    
+    /**
+     * Insert multidimensional input.
+     *
+     * \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)
+    {
+      this->transformer.reset(input.transformer->clone());
+
+      multifunction_type::insert(input);
+    }
+
+    
+    /**
+     * Add function.
+     *
+     * Note that the summation is made via iteration of the elements in this multidimensional function.
+     *
+     * \param  input           multidimensional function
+     */
+    template<class JMultiFunction_t>
+    void add(const JMultiFunction_t& input)
+    {
+      for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) {
+	
+	const array_type array = (*i).getKey();
+	function_type&   f1    = (*i).getValue();
+
+	if (!f1.empty()) {
+
+	  const JMultiMapGetTransformer<NUMBER_OF_DIMENSIONS - 1, value_type> get(*(this->transformer), array);
+	  const JMultiMapPutTransformer<NUMBER_OF_DIMENSIONS - 1, value_type> put(*(this->transformer), array);
+
+	  f1.transform(get);
+
+	  for (typename function_type::iterator j = f1.begin(); j != f1.end(); ++j) {
+
+	    const JArray<NUMBER_OF_DIMENSIONS, argument_type> buffer(array, j->getX());
+
+	    j->getY() += get_value(input.evaluate(buffer.data()));
+	  }
+
+	  f1.transform(put);
+	  f1.compile();
+	}
+      }
+    }
+
+
+    /**
+     * Multidimensional interpolation method call.
+     *
+     * \param  args            comma seperated list of abscissa values
+     * \return                 function value
+     */
+    template<class ...Args>
+    result_type operator()(const Args& ...args) const
+    {
+      return this->evaluate(this->buffer.set(args...).data());
+    }
+
+
+    /**
+     * Recursive function value evaluation.
+     *
+     * \param  pX              pointer to abscissa values
+     * \return                 function value
+     */
+    virtual result_type evaluate(const argument_type* pX) const override 
+    {
+      for (int i = 0; i != NUMBER_OF_DIMENSIONS; ++i) {
+        this->buffer[i] = pX[i];
+      }
+
+      this->buffer[NUMBER_OF_DIMENSIONS - 1] = transformer->putXn(this->buffer, this->buffer[NUMBER_OF_DIMENSIONS - 1]);
+
+      const result_type y = multifunction_type::evaluate(this->buffer.data());
+      const double      W = transformer->getWeight(this->buffer);
+
+      return JResultTransformer<result_type>::transform(*transformer, this->buffer, y) * W;      
+    }
+
+
+    /**
+     * Application of weight function and coordinate transformation.
+     *
+     * \param  transformer     function transformer
+     */
+    virtual void transform(const transformer_type& transformer) override 
+    {
+      for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) {
+
+	const array_type  array    = (*i).getKey();
+	function_type&    function = (*i).getValue();
+
+	const JMultiMapGetTransformer<NUMBER_OF_DIMENSIONS - 1, value_type> get(*(this->transformer), array);
+	const JMultiMapPutTransformer<NUMBER_OF_DIMENSIONS - 1, value_type> put(        transformer,  array);
+	
+	function.transform(get);
+	function.transform(put);
+      }
+
+      this->transformer.reset(transformer.clone());
+      this->compile();
+    }
+
+
+    /**
+     * Read transformable multidimensional function.
+     *
+     * \param  in              reader
+     * \param  object          transformable multidimensional function.
+     * \return                 reader
+     */
+    friend inline JReader& operator>>(JReader& in, JTransformableMultiFunction& object)
+    {
+      in >> static_cast<multifunction_type&>(object);
+
+      return object.transformer->read(in);
+    }
+
+
+    /**
+     * Write transformable multidimensional function.
+     *
+     * \param  out             writer
+     * \param  object          transformable multidimensional function
+     * \return                 writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JTransformableMultiFunction& object)
+    {
+      out << static_cast<const multifunction_type&>(object);
+
+      return object.transformer->write(out);
+    }
+
+
+    JLANG::JSharedPointer<transformer_type> transformer;
+
+  private:
+    mutable JArray<NUMBER_OF_DIMENSIONS, argument_type> buffer;
+  };
+  
+
+  /**
+   * Conversion of multidimensional histogram to multidimensional function.
+   *
+   * \param  input             multidimensional histogram
+   * \param  output            multidimensional function
+   */
+  template<class JHistogram_t,
+	   class JHistogramMaplist_t,
+	   class JHistogramDistance_t,
+	   class JFunction_t,
+	   class JFunctionMaplist_t,
+	   class JFunctionDistance_t>
+  inline void makePDF(const JTransformableMultiHistogram<JHistogram_t, JHistogramMaplist_t, JHistogramDistance_t>& input, 
+			   JTransformableMultiFunction<JFunction_t, JFunctionMaplist_t, JFunctionDistance_t>&           output)
+  {
+    output.insert(input);
+  }
+}
+
+#endif
diff --git a/jpp/JTools/JTransformableMultiHistogram.hh b/jpp/JTools/JTransformableMultiHistogram.hh
new file mode 100644
index 0000000..5f3a32c
--- /dev/null
+++ b/jpp/JTools/JTransformableMultiHistogram.hh
@@ -0,0 +1,176 @@
+#ifndef __JTOOLS__JTRANSFORMABLEMULTIHISTOGRAM__
+#define __JTOOLS__JTRANSFORMABLEMULTIHISTOGRAM__
+
+#include "JIO/JSerialisable.hh"
+#include "JLang/JSharedPointer.hh"
+
+#include "JTools/JMultiMap.hh"
+#include "JTools/JMultiHistogram.hh"
+#include "JTools/JMultiMapTransformer.hh"
+#include "JTools/JArray.hh"
+#include "JIO/JSerialisable.hh"
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  using JIO::JReader;
+  using JIO::JWriter;
+
+
+  /**
+   * Transformable multidimensional histogram.
+   *
+   * This class implements the JTransformable interface.
+   */
+  template<class JHistogram_t,
+	   class JMaplist_t,
+	   class JDistance_t = JDistance<typename JHistogram_t::abscissa_type> >
+  class JTransformableMultiHistogram :
+    public JMultiHistogram<JHistogram_t, JMaplist_t, JDistance_t>,
+    public JTransformable<JMapLength<JMaplist_t>::value, typename JHistogram_t::abscissa_type>
+  {
+  public:
+
+    typedef JMultiHistogram<JHistogram_t,
+			    JMaplist_t,
+			    JDistance_t>                                        JMultiHistogram_t;
+
+    enum { NUMBER_OF_DIMENSIONS = JMultiHistogram_t::NUMBER_OF_DIMENSIONS };
+
+    typedef JHistogram_t                                                        histogram_type;
+
+    typedef typename histogram_type::contents_type                              contents_type;
+    typedef typename histogram_type::value_type                                 value_type;
+
+    typedef typename JMultiHistogram_t::abscissa_type                           abscissa_type;
+    typedef typename JMultiHistogram_t::ordinate_type                           ordinate_type;
+
+    typedef typename JMultiHistogram_t::const_iterator                          const_iterator;
+    typedef typename JMultiHistogram_t::const_reverse_iterator                  const_reverse_iterator;
+    typedef typename JMultiHistogram_t::iterator                                iterator;
+    typedef typename JMultiHistogram_t::reverse_iterator                        reverse_iterator;
+
+    typedef typename JMultiHistogram_t::super_iterator                          super_iterator;
+    typedef typename JMultiHistogram_t::super_const_iterator                    super_const_iterator;
+
+    typedef JMultiMapTransformer<JMapLength<JMaplist_t>::value, abscissa_type>  transformer_type;
+    typedef typename transformer_type::array_type                               array_type;
+
+
+    /**
+     * Default constructor.
+     */
+    JTransformableMultiHistogram() :
+      transformer(transformer_type::getClone())
+    {}
+
+
+    /**
+     * Get transformable multidimensional histogram.
+     *
+     * \return                 this transformable multidimensional histogram
+     */
+    const JTransformableMultiHistogram& getTransformableMultiHistogram() const
+    {
+      return static_cast<const JTransformableMultiHistogram&>(*this);
+    }
+
+
+    /**
+     * Get transformable multidimensional histogram.
+     *
+     * \return                 this transformable multidimensional histogram
+     */
+    JTransformableMultiHistogram& getTransformableMultiHistogram()
+    {
+      return static_cast<JTransformableMultiHistogram&>(*this);
+    }
+
+
+    /**
+     * Application of weight function and coordinate transformation.
+     *
+     * \param  transformer     function transformer
+     */
+    virtual void transform(const transformer_type& transformer) override 
+    {
+      typedef typename transformer_type::array_type array_type;
+
+      for (super_iterator i = this->super_begin(); i != this->super_end(); ++i) {
+
+	const array_type  array     = (*i).getKey();
+	histogram_type&   histogram = (*i).getValue();
+
+	const JMultiMapGetTransformer<NUMBER_OF_DIMENSIONS - 1, value_type> get(*(this->transformer), array);
+	const JMultiMapPutTransformer<NUMBER_OF_DIMENSIONS - 1, value_type> put(        transformer,  array);
+	
+	histogram.transform(get);
+	histogram.transform(put);
+      }
+
+      this->transformer.reset(transformer.clone());
+    }
+
+
+    /**
+     * Read transformable multidimensional histogram.
+     *
+     * \param  in              reader
+     * \param  object          transformable multidimensional histogram.
+     * \return                 reader
+     */
+    friend inline JReader& operator>>(JReader& in, JTransformableMultiHistogram& object)
+    {
+      in >> static_cast<JMultiHistogram_t&>(object);
+
+      return object.transformer->read(in);
+    }
+
+
+    /**
+     * Write transformable multidimensional histogram.
+     *
+     * \param  out             writer
+     * \param  object          transformable multidimensional histogram
+     * \return                 writer
+     */
+    friend inline JWriter& operator<<(JWriter& out, const JTransformableMultiHistogram& object)
+    {
+      out << static_cast<const JMultiHistogram_t&>(object);
+
+      return object.transformer->write(out);
+    }
+
+
+    JLANG::JSharedPointer<transformer_type> transformer;
+
+  protected:
+    /**
+     * Termination method for filling histogram.
+     *
+     * \param  i                index
+     * \param  x                abscissa value
+     * \param  w                weight
+     */
+    virtual void __fill__(const int i, const abscissa_type x, const contents_type w) override 
+    {
+      this->buffer[NUMBER_OF_DIMENSIONS - 1] = transformer->putXn(this->buffer, this->buffer[NUMBER_OF_DIMENSIONS - 1]);
+
+      const double z = transformer->putXn(this->buffer, 1.0) - transformer->putXn(this->buffer, 0.0);
+      const double W = transformer->getWeight(this->buffer);
+
+      this->evaluate(this->buffer.begin(), w * z / W);
+
+      this->evaluate(this->buffer.begin(), w);
+    }    
+  };
+}
+
+#endif
diff --git a/jpp/JTools/JTransformer.hh b/jpp/JTools/JTransformer.hh
new file mode 100644
index 0000000..37b29e5
--- /dev/null
+++ b/jpp/JTools/JTransformer.hh
@@ -0,0 +1,36 @@
+#ifndef __JTOOLS__JTRANSFORMER__
+#define __JTOOLS__JTRANSFORMER__
+
+
+/**
+ * \author mdejong
+ */
+
+namespace JTOOLS {}
+namespace JPP { using namespace JTOOLS; }
+
+namespace JTOOLS {
+
+  /**
+   * Interface for transformation of collection of elements.
+   */
+  template<class JElement_t>
+  struct JCollectionElementTransformer {
+    /**
+     * Virtual destructor.
+     */
+    virtual ~JCollectionElementTransformer()
+    {}
+
+
+    /**
+     * Transform element.
+     *
+     * \param  element         input  element
+     * \return                 output element
+     */
+    virtual JElement_t operator()(const JElement_t& element) const = 0;
+  };
+}
+
+#endif
diff --git a/jpp/Jeep/JeepToolkit.hh b/jpp/Jeep/JeepToolkit.hh
new file mode 100644
index 0000000..01e5412
--- /dev/null
+++ b/jpp/Jeep/JeepToolkit.hh
@@ -0,0 +1,371 @@
+#ifndef __JEEP__JEEPTOOLKIT__
+#define __JEEP__JEEPTOOLKIT__
+
+#include <string>
+#include <fstream>
+#include <sstream>
+#include <cstdlib>
+#include <map>
+
+#include "JLang/gzstream.h"
+
+
+/**
+ * \file
+ *
+ * Auxiliary methods for handling file names, type names and environment.
+ * \author mdejong
+ */
+
+/**
+ * General puprpose classes and methods.
+ */
+namespace JEEP {}
+namespace JPP { using namespace JEEP; }
+
+namespace JEEP {
+
+  /**
+   * Nick names of environment variables.
+   */
+  static const char* const LD_LIBRARY_PATH      = "LD_LIBRARY_PATH";  //!< library file paths
+  static const char* const PATH                 = "PATH";             //!< binary  file paths
+  static const char* const SHELL                = "SHELL";            //!< SHELL
+  static const char* const JPP_PAGES            = "JPP_PAGES";        //!< Jpp document pages
+
+  static const char        PATHNAME_SEPARATOR   = '/';                //!< path name separator
+  static const char        PATHLIST_SEPARATOR   = ':';                //!< path list separator
+  static const char        FILENAME_SEPARATOR   = '.';                //!< file name separator
+  static const char* const TYPENAME_SEPARATOR   = "::";               //!< type name separator
+  static const char        PROTOCOL_SEPARATOR   = ':';                //!< protocol  separator
+
+
+  /**
+   * Strip leading and trailing white spaces from file name.
+   *
+   * \param  file_name         file name
+   * \return                   file name
+   */
+  inline std::string strip(const std::string& file_name)
+  {
+    using namespace std;
+
+    string::const_iterator         p = file_name. begin();
+    string::const_reverse_iterator q = file_name.rbegin();
+    
+    for ( ; p != file_name.end() && q != file_name.rend() && isspace(*p); ++p) {}
+    for ( ; p != file_name.end() && q != file_name.rend() && isspace(*q); ++q) {}
+    
+    return string(p,q.base());
+  }
+
+
+  /**
+   * Get file name extension, i.e.\ part after last JEEP::FILENAME_SEPARATOR if any.
+   *
+   * \param  file_name         file name
+   * \return                   extension (excluding separator)
+   */
+  inline std::string getFilenameExtension(const std::string& file_name)
+  {
+    using namespace std;
+
+    const size_t pos = file_name.rfind(FILENAME_SEPARATOR);
+
+    if (pos != string::npos)
+      return file_name.substr(pos + 1);
+    else
+      return "";
+  }
+
+
+  /**
+   * Get file name part, i.e.\ part after last JEEP::PATHNAME_SEPARATOR if any.
+   *
+   * \param  file_name          file name
+   * \return                    file name part (excluding separator)
+   */
+  inline std::string getFilename(const std::string& file_name)
+  {
+    using namespace std;
+
+    const string buffer = strip(file_name);
+    const size_t pos    = buffer.rfind(PATHNAME_SEPARATOR);
+
+    if (pos != string::npos)
+      return buffer.substr(pos + 1);
+    else
+      return buffer;
+  }
+
+
+  /**
+   * Get path, i.e.\ part before last JEEP::PATHNAME_SEPARATOR if any.
+   *
+   * \param  file_name          file name
+   * \return                    path (including separator)
+   */
+  inline std::string getPath(const std::string& file_name)
+  {
+    using namespace std;
+
+    const string buffer = strip(file_name);
+    const size_t pos    = buffer.rfind(PATHNAME_SEPARATOR);
+
+    if (pos != string::npos)
+      return buffer.substr(0, pos + 1);
+    else
+      return "";
+  }
+
+
+  /**
+   * Get full path, i.e.\ add JEEP::PATHNAME_SEPARATOR if necessary.
+   *
+   * \param  path               path
+   * \return                    path (including separator)
+   */
+  inline std::string getFullPath(const std::string& path)
+  {
+    using namespace std;
+
+    const string buffer = strip(path);
+
+    if (buffer.empty() || *buffer.rbegin() == PATHNAME_SEPARATOR) {
+
+      return buffer;
+
+    } else {
+
+      return buffer + PATHNAME_SEPARATOR;
+    }
+  }
+
+  
+  /**
+   * Compose full file name and introduce JEEP::PATHNAME_SEPARATOR if needed.
+   *
+   * \param  path               path
+   * \param  file_name          file name
+   * \return                    file name
+   */
+  inline std::string getFilename(const std::string& path, const std::string& file_name)
+  {
+    using namespace std;
+
+    const string buffer = getFullPath(path);
+
+    if (buffer.empty())
+      return strip(file_name);
+    else
+      return buffer + strip(file_name);
+  }
+
+
+  /**
+   * Get selected path from environment variable for given file name.
+   *
+   * The environment variable is parsed according character JEEP::PATHLIST_SEPARATOR.
+   * The first path in which a file exists with the given file name is returned.
+   * If no existing file is found, an empty path is returned.
+   *
+   * \param  variable           environment variable
+   * \param  file_name          file name
+   * \return                    path
+   */
+  inline std::string getPath(const std::string& variable, const std::string& file_name)
+  {
+    using namespace std;
+
+    string path = "";
+
+    if (!file_name.empty() && file_name[0] != PATHNAME_SEPARATOR) {
+
+      const string buffer(getenv(variable.c_str()));
+	
+      if (!buffer.empty()) {
+	  
+	size_t pos = 0, len;
+	  
+	do { 
+	  
+	  len  = buffer.substr(pos).find(PATHLIST_SEPARATOR);
+	  path = buffer.substr(pos,len);
+
+	} while (!ifstream(getFilename(path, file_name).c_str()).good() && len != string::npos && (pos += len + 1) != buffer.length());
+      }
+    }
+
+    if (ifstream(getFilename(path, file_name).c_str()).good())
+      return path;
+    else
+      return "";
+  }  
+
+
+  /**
+   * Get full file name (see JEEP::getPath).
+   *
+   * \param  variable           environment variable
+   * \param  file_name          file name
+   * \return                    file name
+   */
+  inline std::string getFullFilename(const std::string& variable, const std::string& file_name)
+  {
+    return getFilename(getPath(variable, file_name), file_name);
+  }
+
+
+  /**
+   * Get name space, i.e.\ part before JEEP::TYPENAME_SEPARATOR.
+   *
+   * \param  type_name         type name
+   * \return                   name space (possibly empty)
+   */
+  inline std::string getNamespace(const std::string& type_name)
+  {
+    using namespace std;
+
+    const size_t pos = type_name.rfind(TYPENAME_SEPARATOR);
+
+    if (pos != string::npos)
+      return type_name.substr(0, pos);
+    else
+      return "";
+  }
+
+
+  /**
+   * Get type name, i.e.\ part after JEEP::TYPENAME_SEPARATOR.
+   *
+   * \param  type_name         type name
+   * \return                   class name
+   */
+  inline std::string getClassname(const std::string& type_name)
+  {
+    using namespace std;
+
+    const size_t pos = type_name.rfind(TYPENAME_SEPARATOR);
+
+    if (pos != string::npos)
+      return type_name.substr(pos + 2);
+    else
+      return type_name;
+  }
+
+
+  /**
+   * Get protocol, i.e.\ part before first JEEP::PROTOCOL_SEPARATOR if any.
+   *
+   * \param  file_name         file name
+   * \return                   protocol (excluding separator)
+   */
+  inline std::string getProtocol(const std::string& file_name)
+  {
+    using namespace std;
+
+    const size_t pos = file_name.find(PROTOCOL_SEPARATOR);
+
+    if (pos != string::npos)
+      return file_name.substr(0, pos);
+    else
+      return "";
+  }
+
+
+  /**
+   * Get URL of document pages.
+   *
+   * \return                   URL
+   */
+  inline std::string getURL()
+  {
+    const char* const url = getenv(JPP_PAGES);
+
+    return std::string(url != NULL ? url : "");
+  }
+
+
+  /**
+   * Open file.
+   *
+   * \param  file_name           file name
+   * \return                     pointer to input stream
+   */
+  template<class T>
+  inline T* open(const std::string& file_name);
+
+
+  /**
+   * Open file.
+   *
+   * \param  file_name           file name
+   * \return                     pointer to input stream
+   */
+  template<>
+  inline std::istream* open(const std::string& file_name)
+  {
+    using namespace std;
+    using namespace JPP;
+
+    if      (getFilenameExtension(file_name) == "gz") 
+      return new igzstream(file_name.c_str());
+    else if (getFilenameExtension(file_name) == "txt") 
+      return new ifstream (file_name.c_str());
+    else
+      return NULL;
+  }
+
+
+  /**
+   * Open file.
+   *
+   * \param  file_name           file name
+   * \return                     pointer to output stream
+   */
+  template<>
+  inline std::ostream* open(const std::string& file_name)
+  {
+    using namespace std;
+    using namespace JPP;
+
+    if      (getFilenameExtension(file_name) == "gz") 
+      return new ogzstream(file_name.c_str());
+    else if (getFilenameExtension(file_name) == "txt") 
+      return new ofstream (file_name.c_str());
+    else
+      return NULL;
+  }
+
+
+  /**
+   * Close file.
+   *
+   * \param  pf                  pointer to file stream
+   */
+  inline void close(std::istream* pf)
+  {
+    using namespace std;
+    using namespace JPP;
+
+    if (dynamic_cast<ifstream*> (pf) != NULL) { dynamic_cast<ifstream*> (pf)->close(); return; }
+    if (dynamic_cast<igzstream*>(pf) != NULL) { dynamic_cast<igzstream*>(pf)->close(); return; }
+  }
+
+
+  /**
+   * Close file.
+   *
+   * \param  pf                  pointer to file stream
+   */
+  inline void close(std::ostream* pf)
+  {
+    using namespace std;
+    using namespace JPP;
+
+    if (dynamic_cast<ofstream*> (pf) != NULL) { dynamic_cast<ofstream*> (pf)->close(); return; }
+    if (dynamic_cast<ogzstream*>(pf) != NULL) { dynamic_cast<ogzstream*>(pf)->close(); return; }
+  }
+}
+
+#endif
diff --git a/jpp/README.md b/jpp/README.md
new file mode 100644
index 0000000..36b6d2c
--- /dev/null
+++ b/jpp/README.md
@@ -0,0 +1,4 @@
+# Jpp
+
+The following source files were taken from Jpp version v14.1.0-40-ge37bef90a
+and are used for testing and as fallback if no Jpp environment is loaded.
-- 
GitLab