[med-svn] [libbpp-core] 01/04: Imported Upstream version 2.1.0

Andreas Tille tille at debian.org
Thu Apr 7 08:04:39 UTC 2016


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

tille pushed a commit to branch master
in repository libbpp-core.

commit 8a8f217998ce893ada7f2fa023d799a0d6a03a34
Author: Andreas Tille <tille at debian.org>
Date:   Wed Apr 6 21:56:12 2016 +0200

    Imported Upstream version 2.1.0
---
 AUTHORS.txt                                        |   22 +
 CMakeLists.txt                                     |  149 ++
 COPYING.txt                                        |  505 +++++
 ChangeLog                                          |   54 +
 Doxyfile                                           | 1773 ++++++++++++++++++
 INSTALL.txt                                        |   12 +
 bpp-core.spec                                      |  183 ++
 debian/changelog                                   |   37 +
 debian/compat                                      |    1 +
 debian/control                                     |   22 +
 debian/copyright                                   |   74 +
 debian/docs                                        |    0
 debian/libbpp-core-dev.install                     |    3 +
 debian/libbpp-core2.install                        |    1 +
 debian/postinst                                    |   43 +
 debian/postrm                                      |   45 +
 debian/prerm                                       |   27 +
 debian/rules                                       |  120 ++
 debian/source/format                               |    1 +
 src/Bpp/App/ApplicationTools.cpp                   |  329 ++++
 src/Bpp/App/ApplicationTools.h                     |  514 ++++++
 src/Bpp/App/BppApplication.cpp                     |   70 +
 src/Bpp/App/BppApplication.h                       |   80 +
 src/Bpp/App/NumCalcApplicationTools.cpp            |  140 ++
 src/Bpp/App/NumCalcApplicationTools.h              |  134 ++
 src/Bpp/BppBoolean.h                               |   94 +
 src/Bpp/BppString.cpp                              |   50 +
 src/Bpp/BppString.h                                |   95 +
 src/Bpp/BppVector.h                                |  105 ++
 src/Bpp/Clonable.h                                 |  120 ++
 src/Bpp/Exceptions.cpp                             |  110 ++
 src/Bpp/Exceptions.h                               |  419 +++++
 src/Bpp/Graph/BasicONode.cpp                       |   43 +
 src/Bpp/Graph/BasicONode.h                         |   59 +
 src/Bpp/Graph/BasicTNode.cpp                       |  204 ++
 src/Bpp/Graph/BasicTNode.h                         |  160 ++
 src/Bpp/Graph/ONode.h                              |  170 ++
 src/Bpp/Graph/TNode.h                              |  129 ++
 src/Bpp/Graph/UNode.h                              |  123 ++
 src/Bpp/Graphics/AbstractGraphicDevice.h           |  112 ++
 src/Bpp/Graphics/ColorManager.h                    |  191 ++
 src/Bpp/Graphics/ColorSet.h                        |  132 ++
 src/Bpp/Graphics/ColorTools.cpp                    |   86 +
 src/Bpp/Graphics/ColorTools.h                      |  133 ++
 src/Bpp/Graphics/DefaultColorSet.h                 |   74 +
 src/Bpp/Graphics/Fig/XFigGraphicDevice.cpp         |  194 ++
 src/Bpp/Graphics/Fig/XFigGraphicDevice.h           |  133 ++
 src/Bpp/Graphics/Fig/XFigLaTeXFontManager.cpp      |   55 +
 src/Bpp/Graphics/Fig/XFigLaTeXFontManager.h        |   66 +
 src/Bpp/Graphics/Fig/XFigPostscriptFontManager.cpp |   85 +
 src/Bpp/Graphics/Fig/XFigPostscriptFontManager.h   |   66 +
 src/Bpp/Graphics/Font/Font.cpp                     |   56 +
 src/Bpp/Graphics/Font/Font.h                       |  179 ++
 src/Bpp/Graphics/Font/FontManager.h                |  149 ++
 src/Bpp/Graphics/GraphicDevice.cpp                 |   58 +
 src/Bpp/Graphics/GraphicDevice.h                   |  199 ++
 src/Bpp/Graphics/Latex/DvipsColorSet.cpp           |  115 ++
 src/Bpp/Graphics/Latex/DvipsColorSet.h             |   65 +
 src/Bpp/Graphics/Latex/PgfGraphicDevice.cpp        |  299 +++
 src/Bpp/Graphics/Latex/PgfGraphicDevice.h          |  117 ++
 src/Bpp/Graphics/Molscript/MolscriptColorSet.cpp   |  210 +++
 src/Bpp/Graphics/Molscript/MolscriptColorSet.h     |   63 +
 src/Bpp/Graphics/Point2D.h                         |  146 ++
 src/Bpp/Graphics/Point2DTools.h                    |   79 +
 src/Bpp/Graphics/R/RColorSet.cpp                   |  704 +++++++
 src/Bpp/Graphics/R/RColorSet.h                     |   78 +
 src/Bpp/Graphics/RgbColor.h                        |  157 ++
 src/Bpp/Graphics/Svg/SvgGraphicDevice.cpp          |  171 ++
 src/Bpp/Graphics/Svg/SvgGraphicDevice.h            |  107 ++
 src/Bpp/Io/BppODiscreteDistributionFormat.cpp      |  440 +++++
 src/Bpp/Io/BppODiscreteDistributionFormat.h        |   96 +
 src/Bpp/Io/BppOParametrizableFormat.cpp            |  118 ++
 src/Bpp/Io/BppOParametrizableFormat.h              |  110 ++
 src/Bpp/Io/FileTools.cpp                           |  153 ++
 src/Bpp/Io/FileTools.h                             |  162 ++
 src/Bpp/Io/IoDiscreteDistribution.h                |  125 ++
 src/Bpp/Io/IoDiscreteDistributionFactory.cpp       |   57 +
 src/Bpp/Io/IoDiscreteDistributionFactory.h         |   99 +
 src/Bpp/Io/IoFormat.h                              |   89 +
 src/Bpp/Io/IoParametrizable.h                      |  117 ++
 src/Bpp/Io/OutputStream.h                          |  354 ++++
 src/Bpp/Numeric/AbstractParameterAliasable.cpp     |  207 +++
 src/Bpp/Numeric/AbstractParameterAliasable.h       |  208 +++
 src/Bpp/Numeric/AbstractParametrizable.cpp         |   70 +
 src/Bpp/Numeric/AbstractParametrizable.h           |  207 +++
 .../Numeric/AdaptiveKernelDensityEstimation.cpp    |  141 ++
 src/Bpp/Numeric/AdaptiveKernelDensityEstimation.h  |  122 ++
 src/Bpp/Numeric/AutoParameter.cpp                  |  120 ++
 src/Bpp/Numeric/AutoParameter.h                    |  146 ++
 src/Bpp/Numeric/Constraints.h                      |  384 ++++
 src/Bpp/Numeric/DataTable.cpp                      |  594 ++++++
 src/Bpp/Numeric/DataTable.h                        |  443 +++++
 src/Bpp/Numeric/DataTableExceptions.h              |  175 ++
 .../Numeric/Function/AbstractNumericalDerivative.h |  285 +++
 src/Bpp/Numeric/Function/AbstractOptimizer.cpp     |  344 ++++
 src/Bpp/Numeric/Function/AbstractOptimizer.h       |  391 ++++
 src/Bpp/Numeric/Function/BfgsMultiDimensions.cpp   |  300 +++
 src/Bpp/Numeric/Function/BfgsMultiDimensions.h     |  123 ++
 src/Bpp/Numeric/Function/BrentOneDimension.cpp     |  214 +++
 src/Bpp/Numeric/Function/BrentOneDimension.h       |  150 ++
 .../Function/ConjugateGradientMultiDimensions.cpp  |  124 ++
 .../Function/ConjugateGradientMultiDimensions.h    |  110 ++
 src/Bpp/Numeric/Function/DirectionFunction.cpp     |  109 ++
 src/Bpp/Numeric/Function/DirectionFunction.h       |  116 ++
 src/Bpp/Numeric/Function/DownhillSimplexMethod.cpp |  243 +++
 src/Bpp/Numeric/Function/DownhillSimplexMethod.h   |  171 ++
 .../Function/FivePointsNumericalDerivative.cpp     |  140 ++
 .../Function/FivePointsNumericalDerivative.h       |  125 ++
 src/Bpp/Numeric/Function/FunctionTools.cpp         |  140 ++
 src/Bpp/Numeric/Function/FunctionTools.h           |  122 ++
 src/Bpp/Numeric/Function/Functions.h               |  659 +++++++
 src/Bpp/Numeric/Function/GoldenSectionSearch.cpp   |  178 ++
 src/Bpp/Numeric/Function/GoldenSectionSearch.h     |  145 ++
 src/Bpp/Numeric/Function/MetaOptimizer.cpp         |  208 +++
 src/Bpp/Numeric/Function/MetaOptimizer.h           |  250 +++
 .../Function/NewtonBacktrackOneDimension.cpp       |  124 ++
 .../Numeric/Function/NewtonBacktrackOneDimension.h |  124 ++
 src/Bpp/Numeric/Function/NewtonOneDimension.cpp    |  122 ++
 src/Bpp/Numeric/Function/NewtonOneDimension.h      |   92 +
 .../Function/OneDimensionOptimizationTools.cpp     |  259 +++
 .../Function/OneDimensionOptimizationTools.h       |  138 ++
 .../Numeric/Function/OptimizationStopCondition.cpp |  241 +++
 .../Numeric/Function/OptimizationStopCondition.h   |  313 ++++
 src/Bpp/Numeric/Function/Optimizer.h               |  402 ++++
 src/Bpp/Numeric/Function/PowellMultiDimensions.cpp |  170 ++
 src/Bpp/Numeric/Function/PowellMultiDimensions.h   |  115 ++
 .../Function/ReparametrizationFunctionWrapper.cpp  |  194 ++
 .../Function/ReparametrizationFunctionWrapper.h    |  274 +++
 src/Bpp/Numeric/Function/SimpleMultiDimensions.cpp |  114 ++
 src/Bpp/Numeric/Function/SimpleMultiDimensions.h   |   99 +
 .../Function/SimpleNewtonMultiDimensions.cpp       |  110 ++
 .../Numeric/Function/SimpleNewtonMultiDimensions.h |   98 +
 .../Function/ThreePointsNumericalDerivative.cpp    |  249 +++
 .../Function/ThreePointsNumericalDerivative.h      |  118 ++
 .../Function/TwoPointsNumericalDerivative.cpp      |  121 ++
 .../Function/TwoPointsNumericalDerivative.h        |  121 ++
 src/Bpp/Numeric/Hmm/HmmEmissionProbabilities.h     |  154 ++
 src/Bpp/Numeric/Hmm/HmmExceptions.h                |   83 +
 src/Bpp/Numeric/Hmm/HmmLikelihood.h                |  104 ++
 src/Bpp/Numeric/Hmm/HmmStateAlphabet.h             |  128 ++
 src/Bpp/Numeric/Hmm/HmmTransitionMatrix.h          |  107 ++
 src/Bpp/Numeric/Hmm/LogsumHmmLikelihood.cpp        |  291 +++
 src/Bpp/Numeric/Hmm/LogsumHmmLikelihood.h          |  190 ++
 .../Numeric/Hmm/LowMemoryRescaledHmmLikelihood.cpp |  246 +++
 .../Numeric/Hmm/LowMemoryRescaledHmmLikelihood.h   |  198 ++
 src/Bpp/Numeric/Hmm/RescaledHmmLikelihood.cpp      |  317 ++++
 src/Bpp/Numeric/Hmm/RescaledHmmLikelihood.h        |  184 ++
 src/Bpp/Numeric/Matrix/EigenValue.h                | 1244 +++++++++++++
 src/Bpp/Numeric/Matrix/LUDecomposition.h           |  465 +++++
 src/Bpp/Numeric/Matrix/Matrix.h                    |  430 +++++
 src/Bpp/Numeric/Matrix/MatrixTools.h               | 1280 +++++++++++++
 src/Bpp/Numeric/NumConstants.h                     |  102 +
 src/Bpp/Numeric/NumTools.cpp                       |   95 +
 src/Bpp/Numeric/NumTools.h                         |  205 +++
 src/Bpp/Numeric/Number.h                           |  100 +
 src/Bpp/Numeric/Parameter.cpp                      |  210 +++
 src/Bpp/Numeric/Parameter.h                        |  344 ++++
 src/Bpp/Numeric/ParameterAliasable.h               |  172 ++
 src/Bpp/Numeric/ParameterExceptions.cpp            |   75 +
 src/Bpp/Numeric/ParameterExceptions.h              |  164 ++
 src/Bpp/Numeric/ParameterList.cpp                  |  489 +++++
 src/Bpp/Numeric/ParameterList.h                    |  374 ++++
 src/Bpp/Numeric/Parametrizable.h                   |  230 +++
 .../Numeric/Prob/AbstractDiscreteDistribution.cpp  |  466 +++++
 .../Numeric/Prob/AbstractDiscreteDistribution.h    |  246 +++
 src/Bpp/Numeric/Prob/BetaDiscreteDistribution.cpp  |  122 ++
 src/Bpp/Numeric/Prob/BetaDiscreteDistribution.h    |  117 ++
 src/Bpp/Numeric/Prob/ConstantDistribution.cpp      |  105 ++
 src/Bpp/Numeric/Prob/ConstantDistribution.h        |  107 ++
 .../Numeric/Prob/DirichletDiscreteDistribution.cpp |  282 +++
 .../Numeric/Prob/DirichletDiscreteDistribution.h   |  178 ++
 src/Bpp/Numeric/Prob/DiscreteDistribution.h        |  322 ++++
 .../Prob/ExponentialDiscreteDistribution.cpp       |   74 +
 .../Numeric/Prob/ExponentialDiscreteDistribution.h |  122 ++
 src/Bpp/Numeric/Prob/GammaDiscreteDistribution.cpp |  127 ++
 src/Bpp/Numeric/Prob/GammaDiscreteDistribution.h   |  116 ++
 .../Numeric/Prob/GaussianDiscreteDistribution.cpp  |  109 ++
 .../Numeric/Prob/GaussianDiscreteDistribution.h    |  104 ++
 .../Prob/InvariantMixedDiscreteDistribution.cpp    |  157 ++
 .../Prob/InvariantMixedDiscreteDistribution.h      |  162 ++
 .../Prob/MixtureOfDiscreteDistributions.cpp        |  319 ++++
 .../Numeric/Prob/MixtureOfDiscreteDistributions.h  |  167 ++
 .../Numeric/Prob/MultipleDiscreteDistribution.h    |  151 ++
 .../Numeric/Prob/SimpleDiscreteDistribution.cpp    |  350 ++++
 src/Bpp/Numeric/Prob/SimpleDiscreteDistribution.h  |  158 ++
 src/Bpp/Numeric/Prob/Simplex.cpp                   |  190 ++
 src/Bpp/Numeric/Prob/Simplex.h                     |  162 ++
 .../TruncatedExponentialDiscreteDistribution.cpp   |   90 +
 .../TruncatedExponentialDiscreteDistribution.h     |  154 ++
 .../Numeric/Prob/UniformDiscreteDistribution.cpp   |   94 +
 src/Bpp/Numeric/Prob/UniformDiscreteDistribution.h |  113 ++
 .../Numeric/Random/ContingencyTableGenerator.cpp   |  199 ++
 src/Bpp/Numeric/Random/ContingencyTableGenerator.h |   93 +
 src/Bpp/Numeric/Random/RandomFactory.h             |   72 +
 src/Bpp/Numeric/Random/RandomTools.cpp             | 1060 +++++++++++
 src/Bpp/Numeric/Random/RandomTools.h               |  548 ++++++
 src/Bpp/Numeric/Random/Uniform01K.cpp              |  106 ++
 src/Bpp/Numeric/Random/Uniform01K.h                |   97 +
 src/Bpp/Numeric/Random/Uniform01QD.cpp             |   54 +
 src/Bpp/Numeric/Random/Uniform01QD.h               |   91 +
 src/Bpp/Numeric/Random/Uniform01WH.cpp             |   56 +
 src/Bpp/Numeric/Random/Uniform01WH.h               |   97 +
 src/Bpp/Numeric/Range.h                            |  519 ++++++
 src/Bpp/Numeric/Stat/ContingencyTableTest.cpp      |  129 ++
 src/Bpp/Numeric/Stat/ContingencyTableTest.h        |   98 +
 .../Numeric/Stat/Mva/CorrespondenceAnalysis.cpp    |  114 ++
 src/Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.h  |   95 +
 src/Bpp/Numeric/Stat/Mva/DualityDiagram.cpp        |  291 +++
 src/Bpp/Numeric/Stat/Mva/DualityDiagram.h          |  160 ++
 .../Stat/Mva/PrincipalComponentAnalysis.cpp        |  182 ++
 .../Numeric/Stat/Mva/PrincipalComponentAnalysis.h  |  138 ++
 src/Bpp/Numeric/Stat/StatTest.h                    |   73 +
 src/Bpp/Numeric/Stat/StatTools.cpp                 |   60 +
 src/Bpp/Numeric/Stat/StatTools.h                   |   89 +
 src/Bpp/Numeric/TransformedParameter.h             |  312 ++++
 src/Bpp/Numeric/VectorExceptions.h                 |  155 ++
 src/Bpp/Numeric/VectorTools.cpp                    |  101 +
 src/Bpp/Numeric/VectorTools.h                      | 1939 ++++++++++++++++++++
 src/Bpp/Text/KeyvalTools.cpp                       |  118 ++
 src/Bpp/Text/KeyvalTools.h                         |  117 ++
 src/Bpp/Text/NestedStringTokenizer.cpp             |  153 ++
 src/Bpp/Text/NestedStringTokenizer.h               |   99 +
 src/Bpp/Text/StringTokenizer.cpp                   |  122 ++
 src/Bpp/Text/StringTokenizer.h                     |  142 ++
 src/Bpp/Text/TextTools.cpp                         |  525 ++++++
 src/Bpp/Text/TextTools.h                           |  411 +++++
 src/Bpp/Utils/AttributesTools.cpp                  |  266 +++
 src/Bpp/Utils/AttributesTools.h                    |  251 +++
 src/Bpp/Utils/MapTools.h                           |  129 ++
 src/CMakeLists.txt                                 |  248 +++
 test/CMakeLists.txt                                |   94 +
 test/PolynomialFunction.h                          |  127 ++
 test/test_bfgs.cpp                                 |   65 +
 test/test_derivative1.cpp                          |  117 ++
 test/test_distributions.cpp                        |  155 ++
 test/test_downhill.cpp                             |   65 +
 test/test_eigen.cpp                                |   73 +
 test/test_gradient.cpp                             |   65 +
 test/test_matrices.cpp                             |   67 +
 test/test_mva.cpp                                  |  175 ++
 test/test_numconstants.cpp                         |   62 +
 test/test_powell.cpp                               |   65 +
 test/test_range.cpp                                |  198 ++
 test/test_sample.cpp                               |  131 ++
 test/test_stats.cpp                                |   87 +
 test/test_text_tools.cpp                           |  112 ++
 246 files changed, 47493 insertions(+)

diff --git a/AUTHORS.txt b/AUTHORS.txt
new file mode 100644
index 0000000..b59d246
--- /dev/null
+++ b/AUTHORS.txt
@@ -0,0 +1,22 @@
+Julien Dutheil <julien.dutheil at univ-montp2.fr>
+Sylvain Gaillard <sylvain.gaillard at angers.inra.fr>
+Nicolas Galtier <galtier at univ-montp2.fr>
+Céline Scornavacca <scornava at lirmm.fr>
+Laurent Guéguen <gueguen at biomserv.univ-lyon1.fr>
+Ania Pawelczyk <ania.pawelczyk at gmail.com>
+
+Contributed code to Bio++ was enabled thanks to the following institutions and resources:
+
+2002 - 2006 Laboratoire GPIA - UMR CNRS 5171 Université Montpellier 2 (Eric Bazin, Khalid Belkhir, Guillaume Deuchst, Julien Dutheil, Sylvain Gaillard, Nicolas Galtier, Sylvain Glémin)
+2005 -      ISE-M UMR CNRS 5554 Université Montpellier 2 (Vincent Ranwez, Céline Scornavacca)
+2006 -      ISE-M UMR CNRS 5554 Université Montpellier 2 (Khalid Belkhir, Nicolas Galtier, Sylvain Glémin)
+2006 - 2007 ISE-M UMR CNRS 5554 Université Montpellier 2 (Julien Dutheil)
+2007 - 2010 Bioinformatics Research Center, University of Aarhus (Julien Dutheil).
+            Funded by European research Area on Plant Genomics (ERA-PG) ARelatives.
+2010 -      ISE-M UMR CNRS 5554 Université Montpellier 2 (Julien Dutheil)
+2011 -      Max Planck Institute for Terrestrial Microbiology (Julien Dutheil)
+2007 -      Genetics and Horticulture UMR INRA 1259 Angers-Nantes INRA Center (Sylvain Gaillard)
+2008 - 2009 Laboratoire BBE - UMR CNRS 5558 Université Lyon 1 (Bastien Boussau)
+2009 - 2010 Berkeley University (Bastien Boussau)
+2010 -      Laboratoire BBE - UMR CNRS 5558 Université Lyon 1 (Bastien Boussau)   
+2008 -      Laboratoire BBE - UMR CNRS 5558 Université Lyon 1 (Laurent Guéguen)
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..fb9b712
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,149 @@
+# CMake script for Bio++ Core
+# Author: Sylvain Gaillard and Julien Dutheil
+# Created: 17/09/2010
+
+# Global parameters
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(bpp-core CXX)
+IF(NOT CMAKE_BUILD_TYPE)
+  SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
+      "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
+      FORCE)
+ENDIF(NOT CMAKE_BUILD_TYPE)
+
+SET(CMAKE_CXX_FLAGS "-Wall -Weffc++ -Wshadow -Wconversion")
+IF(NOT NO_VIRTUAL_COV)
+  SET(NO_VIRTUAL_COV FALSE CACHE BOOL
+      "Disable covariant return type with virtual inheritance, for compilers that do not support it."
+      FORCE)
+ENDIF(NOT NO_VIRTUAL_COV)
+
+IF(NO_VIRTUAL_COV)
+  MESSAGE("-- Covariant return with virtual inheritance disabled.")
+  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNO_VIRTUAL_COV=1")
+ENDIF(NO_VIRTUAL_COV)
+
+# Libtool-like version number
+# CURRENT:REVISION:AGE => file.so.(C-A).A.R
+# current:  The most recent interface number that this library implements.
+# revision: The implementation number of the current interface.
+# age:      The difference between the newest and oldest interfaces that this
+#           library implements.
+# In other words, the library implements all the interface numbers in the
+# range from number current - age to current.
+SET(BPPCORE_VERSION_CURRENT "2")
+SET(BPPCORE_VERSION_REVISION "3")
+SET(BPPCORE_VERSION_AGE "0")
+
+# Effective version number computation
+MATH(EXPR BPPCORE_VERSION_MAJOR "${BPPCORE_VERSION_CURRENT} - ${BPPCORE_VERSION_AGE}")
+SET(BPPCORE_VERSION_MINOR ${BPPCORE_VERSION_AGE})
+SET(BPPCORE_VERSION_PATCH ${BPPCORE_VERSION_REVISION})
+SET(BPPCORE_VERSION "${BPPCORE_VERSION_MAJOR}.${BPPCORE_VERSION_MINOR}.${BPPCORE_VERSION_PATCH}")
+
+# Set the CMAKE_PREFIX_PATH for the find_library fonction when using non
+# standard install location
+IF(CMAKE_INSTALL_PREFIX)
+  SET(CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}" ${CMAKE_PREFIX_PATH})
+ENDIF(CMAKE_INSTALL_PREFIX)
+
+# Subdirectories
+ADD_SUBDIRECTORY(src)
+
+# Doxygen
+FIND_PACKAGE(Doxygen)
+IF (DOXYGEN_FOUND)
+  ADD_CUSTOM_TARGET (apidoc cp Doxyfile ${CMAKE_BINARY_DIR}/Doxyfile-build
+    COMMAND echo "OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}" >> ${CMAKE_BINARY_DIR}/Doxyfile-build
+    COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile-build
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+  ADD_CUSTOM_TARGET (apidoc-stable cp Doxyfile ${CMAKE_BINARY_DIR}/Doxyfile-stable
+    COMMAND echo "OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}" >> ${CMAKE_BINARY_DIR}/Doxyfile-stable
+    COMMAND echo "HTML_HEADER=header.html" >> ${CMAKE_BINARY_DIR}/Doxyfile-stable
+    COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/Doxyfile-stable
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+ENDIF (DOXYGEN_FOUND)
+
+# Packager
+SET(CPACK_PACKAGE_NAME "libbpp-core")
+SET(CPACK_PACKAGE_VENDOR "Bio++ Development Team")
+SET(CPACK_PACKAGE_VERSION "2.1.0")
+SET(CPACK_PACKAGE_VERSION_MAJOR "2")
+SET(CPACK_PACKAGE_VERSION_MINOR "1")
+SET(CPACK_PACKAGE_VERSION_PATCH "0")
+SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The Bio++ Core library")
+SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING.txt")
+SET(CPACK_RESOURCE_FILE_AUTHORS "${CMAKE_SOURCE_DIR}/AUTHORS.txt")
+SET(CPACK_RESOURCE_FILE_INSTALL "${CMAKE_SOURCE_DIR}/INSTALL.txt")
+SET(CPACK_SOURCE_GENERATOR "TGZ")
+SET(CPACK_SOURCE_IGNORE_FILES
+ "CMakeFiles"
+ "Makefile"
+ "_CPack_Packages"
+ "CMakeCache.txt"
+ ".*\\\\.cmake"
+ ".*\\\\.git"
+ ".*\\\\.gz"
+ ".*\\\\.deb"
+ ".*\\\\.rpm"
+ ".*\\\\.dmg"
+ ".*\\\\.sh"
+ ".*\\\\..*\\\\.swp"
+ "src/\\\\..*"
+ "src/libbpp*"
+ "debian/tmp"
+ "debian/libbpp.*/"
+ "debian/libbpp.*\\\\.so.*"
+ "debian/libbpp.*\\\\.a"
+ "debian/libbpp.*\\\\.substvars"
+ "debian/libbpp.*\\\\.debhelper"
+ "debian/debhelper\\\\.log"
+ "html"
+ "Core.tag"
+ "Testing"
+ "build-stamp"
+ "install_manifest.txt"
+ "DartConfiguration.tcl"
+ ${CPACK_SOURCE_IGNORE_FILES}
+)
+IF (MACOS)
+  SET(CPACK_GENERATOR "Bundle")
+ENDIF()
+
+SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
+SET(CPACK_DEBSOURCE_PACKAGE_FILE_NAME "lib${CMAKE_PROJECT_NAME}_${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}.orig")
+INCLUDE(CPack)
+
+#This adds the 'dist' target
+ADD_CUSTOM_TARGET(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source)
+# 'clean' is not (yet) a first class target. However, we need to clean the directories before building the sources:
+IF("${CMAKE_GENERATOR}" MATCHES "Make")
+  ADD_CUSTOM_TARGET(make_clean
+  COMMAND ${CMAKE_MAKE_PROGRAM} clean
+  WORKING_DIRECTORY ${CMAKE_CURRENT_DIR}
+  )
+  ADD_DEPENDENCIES(dist make_clean)
+ENDIF()
+
+IF (UNIX)
+#This creates deb packages:
+ADD_CUSTOM_TARGET(origdist COMMAND cp ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.gz ../${CPACK_DEBSOURCE_PACKAGE_FILE_NAME}.tar.gz)
+ADD_DEPENDENCIES(origdist dist)
+ADD_CUSTOM_TARGET(deb dpkg-buildpackage -uc -us -i${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.gz)
+ADD_DEPENDENCIES(deb origdist)
+
+#This creates rpm packages:
+ADD_CUSTOM_TARGET(rpm rpmbuild -ta ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.gz)
+ADD_DEPENDENCIES(rpm dist)
+
+ENDIF()
+
+SET(CTEST_UPDATE_TYPE git)
+SET(UPDATE_COMMAND "git")
+SET(UPDATE_OPTIONS "")
+
+ENABLE_TESTING()
+INCLUDE(CTest)
+IF (BUILD_TESTING)
+  ADD_SUBDIRECTORY(test)
+ENDIF(BUILD_TESTING)
diff --git a/COPYING.txt b/COPYING.txt
new file mode 100644
index 0000000..7e84b53
--- /dev/null
+++ b/COPYING.txt
@@ -0,0 +1,505 @@
+
+               CeCILL FREE SOFTWARE LICENSE AGREEMENT
+
+
+    Notice
+
+This Agreement is a Free Software license agreement that is the result
+of discussions between its authors in order to ensure compliance with
+the two main principles guiding its drafting:
+
+    * firstly, compliance with the principles governing the distribution
+      of Free Software: access to source code, broad rights granted to
+      users,
+    * secondly, the election of a governing law, French law, with which
+      it is conformant, both as regards the law of torts and
+      intellectual property law, and the protection that it offers to
+      both authors and holders of the economic rights over software.
+
+The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[logiciel] L[ibre])
+license are:
+
+Commissariat à l'Energie Atomique - CEA, a public scientific, technical
+and industrial establishment, having its principal place of business at
+31-33 rue de la Fédération, 75752 Paris cedex 15, France.
+
+Centre National de la Recherche Scientifique - CNRS, a public scientific
+and technological establishment, having its principal place of business
+at 3 rue Michel-Ange 75794 Paris cedex 16, France.
+
+Institut National de Recherche en Informatique et en Automatique -
+INRIA, a public scientific and technological establishment, having its
+principal place of business at Domaine de Voluceau, Rocquencourt, BP
+105, 78153 Le Chesnay cedex, France.
+
+
+    Preamble
+
+The purpose of this Free Software license agreement is to grant users
+the right to modify and redistribute the software governed by this
+license within the framework of an open source distribution model.
+
+The exercising of these rights is conditional upon certain obligations
+for users so as to preserve this status for all subsequent redistributions.
+
+In consideration of access to the source code and the rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty and the software's author, the holder of the
+economic rights, and the successive licensors only have limited liability.
+
+In this respect, the risks associated with loading, using, modifying
+and/or developing or reproducing the software by the user are brought to
+the user's attention, given its Free Software status, which may make it
+complicated to use, with the result that its use is reserved for
+developers and experienced professionals having in-depth computer
+knowledge. Users are therefore encouraged to load and test the
+Software's suitability as regards their requirements in conditions
+enabling the security of their systems and/or data to be ensured and,
+more generally, to use and operate it in the same conditions of
+security. This Agreement may be freely reproduced and published,
+provided it is not altered, and that no provisions are either added or
+removed herefrom.
+
+This Agreement may apply to any or all software for which the holder of
+the economic rights decides to submit the use thereof to its provisions.
+
+
+    Article 1 - DEFINITIONS
+
+For the purpose of this Agreement, when the following expressions
+commence with a capital letter, they shall have the following meaning:
+
+Agreement: means this license agreement, and its possible subsequent
+versions and annexes.
+
+Software: means the software in its Object Code and/or Source Code form
+and, where applicable, its documentation, "as is" when the Licensee
+accepts the Agreement.
+
+Initial Software: means the Software in its Source Code and possibly its
+Object Code form and, where applicable, its documentation, "as is" when
+it is first distributed under the terms and conditions of the Agreement.
+
+Modified Software: means the Software modified by at least one
+Contribution.
+
+Source Code: means all the Software's instructions and program lines to
+which access is required so as to modify the Software.
+
+Object Code: means the binary files originating from the compilation of
+the Source Code.
+
+Holder: means the holder(s) of the economic rights over the Initial
+Software.
+
+Licensee: means the Software user(s) having accepted the Agreement.
+
+Contributor: means a Licensee having made at least one Contribution.
+
+Licensor: means the Holder, or any other individual or legal entity, who
+distributes the Software under the Agreement.
+
+Contribution: means any or all modifications, corrections, translations,
+adaptations and/or new functions integrated into the Software by any or
+all Contributors, as well as any or all Internal Modules.
+
+Module: means a set of sources files including their documentation that
+enables supplementary functions or services in addition to those offered
+by the Software.
+
+External Module: means any or all Modules, not derived from the
+Software, so that this Module and the Software run in separate address
+spaces, with one calling the other when they are run.
+
+Internal Module: means any or all Module, connected to the Software so
+that they both execute in the same address space.
+
+GNU GPL: means the GNU General Public License version 2 or any
+subsequent version, as published by the Free Software Foundation Inc.
+
+Parties: mean both the Licensee and the Licensor.
+
+These expressions may be used both in singular and plural form.
+
+
+    Article 2 - PURPOSE
+
+The purpose of the Agreement is the grant by the Licensor to the
+Licensee of a non-exclusive, transferable and worldwide license for the
+Software as set forth in Article 5 hereinafter for the whole term of the 
+protection granted by the rights over said Software.
+
+
+    Article 3 - ACCEPTANCE
+
+3.1 The Licensee shall be deemed as having accepted the terms and
+conditions of this Agreement upon the occurrence of the first of the
+following events:
+
+    * (i) loading the Software by any or all means, notably, by
+      downloading from a remote server, or by loading from a physical
+      medium;
+    * (ii) the first time the Licensee exercises any of the rights
+      granted hereunder.
+
+3.2 One copy of the Agreement, containing a notice relating to the
+characteristics of the Software, to the limited warranty, and to the
+fact that its use is restricted to experienced users has been provided
+to the Licensee prior to its acceptance as set forth in Article 3.1
+hereinabove, and the Licensee hereby acknowledges that it has read and 
+understood it.
+
+
+    Article 4 - EFFECTIVE DATE AND TERM
+
+
+      4.1 EFFECTIVE DATE
+
+The Agreement shall become effective on the date when it is accepted by
+the Licensee as set forth in Article 3.1.
+
+
+      4.2 TERM
+
+The Agreement shall remain in force for the entire legal term of
+protection of the economic rights over the Software.
+
+
+    Article 5 - SCOPE OF RIGHTS GRANTED
+
+The Licensor hereby grants to the Licensee, who accepts, the following
+rights over the Software for any or all use, and for the term of the
+Agreement, on the basis of the terms and conditions set forth hereinafter.
+
+Besides, if the Licensor owns or comes to own one or more patents
+protecting all or part of the functions of the Software or of its
+components, the Licensor undertakes not to enforce the rights granted by
+these patents against successive Licensees using, exploiting or
+modifying the Software. If these patents are transferred, the Licensor
+undertakes to have the transferees subscribe to the obligations set
+forth in this paragraph.
+
+
+      5.1 RIGHT OF USE
+
+The Licensee is authorized to use the Software, without any limitation
+as to its fields of application, with it being hereinafter specified
+that this comprises:
+
+   1. permanent or temporary reproduction of all or part of the Software
+      by any or all means and in any or all form.
+
+   2. loading, displaying, running, or storing the Software on any or
+      all medium.
+
+   3. entitlement to observe, study or test its operation so as to
+      determine the ideas and principles behind any or all constituent
+      elements of said Software. This shall apply when the Licensee
+      carries out any or all loading, displaying, running, transmission
+      or storage operation as regards the Software, that it is entitled
+      to carry out hereunder.
+
+
+      5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS
+
+The right to make Contributions includes the right to translate, adapt,
+arrange, or make any or all modifications to the Software, and the right
+to reproduce the resulting Software.
+
+The Licensee is authorized to make any or all Contributions to the
+Software provided that it includes an explicit notice that it is the
+author of said Contribution and indicates the date of the creation thereof.
+
+
+      5.3 RIGHT OF DISTRIBUTION
+
+In particular, the right of distribution includes the right to publish,
+transmit and communicate the Software to the general public on any or
+all medium, and by any or all means, and the right to market, either in
+consideration of a fee, or free of charge, one or more copies of the
+Software by any means.
+
+The Licensee is further authorized to distribute copies of the modified
+or unmodified Software to third parties according to the terms and
+conditions set forth hereinafter.
+
+
+        5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION
+
+The Licensee is authorized to distribute true copies of the Software in
+Source Code or Object Code form, provided that said distribution
+complies with all the provisions of the Agreement and is accompanied by:
+
+   1. a copy of the Agreement,
+
+   2. a notice relating to the limitation of both the Licensor's
+      warranty and liability as set forth in Articles 8 and 9,
+
+and that, in the event that only the Object Code of the Software is
+redistributed, the Licensee allows future Licensees unhindered access to
+the full Source Code of the Software by indicating how to access it, it
+being understood that the additional cost of acquiring the Source Code
+shall not exceed the cost of transferring the data.
+
+
+        5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE
+
+When the Licensee makes a Contribution to the Software, the terms and
+conditions for the distribution of the Modified Software become subject
+to all the provisions of this Agreement.
+
+The Licensee is authorized to distribute the Modified Software, in
+Source Code or Object Code form, provided that said distribution
+complies with all the provisions of the Agreement and is accompanied by:
+
+   1. a copy of the Agreement,
+
+   2. a notice relating to the limitation of both the Licensor's
+      warranty and liability as set forth in Articles 8 and 9,
+
+and that, in the event that only the Object Code of the Modified
+Software is redistributed, the Licensee allows future Licensees
+unhindered access to the full Source Code of the Modified Software by
+indicating how to access it, it being understood that the additional
+cost of acquiring the Source Code shall not exceed the cost of
+transferring the data.
+
+
+        5.3.3 DISTRIBUTION OF EXTERNAL MODULES
+
+When the Licensee has developed an External Module, the terms and
+conditions of this Agreement do not apply to said External Module, that
+may be distributed under a separate license agreement.
+
+
+        5.3.4 COMPATIBILITY WITH THE GNU GPL
+
+The Licensee can include a code that is subject to the provisions of one
+of the versions of the GNU GPL in the Modified or unmodified Software,
+and distribute that entire code under the terms of the same version of
+the GNU GPL.
+
+The Licensee can include the Modified or unmodified Software in a code
+that is subject to the provisions of one of the versions of the GNU GPL,
+and distribute that entire code under the terms of the same version of
+the GNU GPL.
+
+
+    Article 6 - INTELLECTUAL PROPERTY
+
+
+      6.1 OVER THE INITIAL SOFTWARE
+
+The Holder owns the economic rights over the Initial Software. Any or
+all use of the Initial Software is subject to compliance with the terms
+and conditions under which the Holder has elected to distribute its work
+and no one shall be entitled to modify the terms and conditions for the
+distribution of said Initial Software.
+
+The Holder undertakes that the Initial Software will remain ruled at
+least by the current license, for the duration set forth in article 4.2.
+
+
+      6.2 OVER THE CONTRIBUTIONS
+
+A Licensee who develops a Contribution is the owner of the intellectual
+property rights over this Contribution as defined by applicable law.
+
+
+      6.3 OVER THE EXTERNAL MODULES
+
+A Licensee who develops an External Module is the owner of the
+intellectual property rights over this External Module as defined by
+applicable law and is free to choose the type of agreement that shall
+govern its distribution.
+
+
+      6.4 JOINT PROVISIONS
+
+The Licensee expressly undertakes:
+
+   1. not to remove, or modify, in any manner, the intellectual property
+      notices attached to the Software;
+
+   2. to reproduce said notices, in an identical manner, in the copies
+      of the Software modified or not.
+
+The Licensee undertakes not to directly or indirectly infringe the
+intellectual property rights of the Holder and/or Contributors on the
+Software and to take, where applicable, vis-à-vis its staff, any and all
+measures required to ensure respect of said intellectual property rights
+of the Holder and/or Contributors.
+
+
+    Article 7 - RELATED SERVICES
+
+7.1 Under no circumstances shall the Agreement oblige the Licensor to
+provide technical assistance or maintenance services for the Software.
+
+However, the Licensor is entitled to offer this type of services. The
+terms and conditions of such technical assistance, and/or such
+maintenance, shall be set forth in a separate instrument. Only the
+Licensor offering said maintenance and/or technical assistance services
+shall incur liability therefor.
+
+7.2 Similarly, any Licensor is entitled to offer to its licensees, under
+its sole responsibility, a warranty, that shall only be binding upon
+itself, for the redistribution of the Software and/or the Modified
+Software, under terms and conditions that it is free to decide. Said
+warranty, and the financial terms and conditions of its application,
+shall be subject of a separate instrument executed between the Licensor
+and the Licensee.
+
+
+    Article 8 - LIABILITY
+
+8.1 Subject to the provisions of Article 8.2, the Licensee shall be
+entitled to claim compensation for any direct loss it may have suffered
+from the Software as a result of a fault on the part of the relevant
+Licensor, subject to providing evidence thereof.
+
+8.2 The Licensor's liability is limited to the commitments made under
+this Agreement and shall not be incurred as a result of in particular:
+(i) loss due the Licensee's total or partial failure to fulfill its
+obligations, (ii) direct or consequential loss that is suffered by the
+Licensee due to the use or performance of the Software, and (iii) more
+generally, any consequential loss. In particular the Parties expressly
+agree that any or all pecuniary or business loss (i.e. loss of data,
+loss of profits, operating loss, loss of customers or orders,
+opportunity cost, any disturbance to business activities) or any or all
+legal proceedings instituted against the Licensee by a third party,
+shall constitute consequential loss and shall not provide entitlement to
+any or all compensation from the Licensor.
+
+
+    Article 9 - WARRANTY
+
+9.1 The Licensee acknowledges that the scientific and technical
+state-of-the-art when the Software was distributed did not enable all
+possible uses to be tested and verified, nor for the presence of
+possible defects to be detected. In this respect, the Licensee's
+attention has been drawn to the risks associated with loading, using,
+modifying and/or developing and reproducing the Software which are
+reserved for experienced users.
+
+The Licensee shall be responsible for verifying, by any or all means,
+the product's suitability for its requirements, its good working order,
+and for ensuring that it shall not cause damage to either persons or
+properties.
+
+9.2 The Licensor hereby represents, in good faith, that it is entitled
+to grant all the rights over the Software (including in particular the
+rights set forth in Article 5).
+
+9.3 The Licensee acknowledges that the Software is supplied "as is" by
+the Licensor without any other express or tacit warranty, other than
+that provided for in Article 9.2 and, in particular, without any warranty
+as to its commercial value, its secured, safe, innovative or relevant 
+nature.
+
+Specifically, the Licensor does not warrant that the Software is free
+from any error, that it will operate without interruption, that it will
+be compatible with the Licensee's own equipment and software
+configuration, nor that it will meet the Licensee's requirements.
+
+9.4 The Licensor does not either expressly or tacitly warrant that the
+Software does not infringe any third party intellectual property right
+relating to a patent, software or any other property right. Therefore,
+the Licensor disclaims any and all liability towards the Licensee
+arising out of any or all proceedings for infringement that may be
+instituted in respect of the use, modification and redistribution of the
+Software. Nevertheless, should such proceedings be instituted against
+the Licensee, the Licensor shall provide it with technical and legal
+assistance for its defense. Such technical and legal assistance shall be
+decided on a case-by-case basis between the relevant Licensor and the
+Licensee pursuant to a memorandum of understanding. The Licensor
+disclaims any and all liability as regards the Licensee's use of the
+name of the Software. No warranty is given as regards the existence of
+prior rights over the name of the Software or as regards the existence
+of a trademark.
+
+
+    Article 10 - TERMINATION
+
+10.1 In the event of a breach by the Licensee of its obligations
+hereunder, the Licensor may automatically terminate this Agreement
+thirty (30) days after notice has been sent to the Licensee and has
+remained ineffective.
+
+10.2 A Licensee whose Agreement is terminated shall no longer be
+authorized to use, modify or distribute the Software. However, any
+licenses that it may have granted prior to termination of the Agreement
+shall remain valid subject to their having been granted in compliance
+with the terms and conditions hereof.
+
+
+    Article 11 - MISCELLANEOUS
+
+
+      11.1 EXCUSABLE EVENTS
+
+Neither Party shall be liable for any or all delay, or failure to
+perform the Agreement, that may be attributable to an event of force
+majeure, an act of God or an outside cause, such as defective
+functioning or interruptions of the electricity or telecommunications
+networks, network paralysis following a virus attack, intervention by
+government authorities, natural disasters, water damage, earthquakes,
+fire, explosions, strikes and labor unrest, war, etc.
+
+11.2 Any Failure by either Party, on one or more occasions, to invoke
+one or more of the provisions hereof, shall under no circumstances be
+interpreted as being a waiver by the interested Party of its right to
+invoke said provision(s) subsequently.
+
+11.3 The Agreement cancels and replaces any or all previous agreements,
+whether written or oral, between the Parties and having the same
+purpose, and constitutes the entirety of the agreement between said
+Parties concerning said purpose. No supplement or modification to the
+terms and conditions hereof shall be effective as between the Parties
+unless it is made in writing and signed by their duly authorized
+representatives.
+
+11.4 In the event that one or more of the provisions hereof were to
+conflict with a current or future applicable act or legislative text,
+said act or legislative text shall prevail, and the Parties shall make
+the necessary amendments so as to comply with said act or legislative
+text. All other provisions shall remain effective. Similarly, invalidity
+of a provision of the Agreement, for any reason whatsoever, shall not
+cause the Agreement as a whole to be invalid.
+
+
+      11.5 LANGUAGE
+
+The Agreement is drafted in both French and English and both versions
+are deemed authentic.
+
+
+    Article 12 - NEW VERSIONS OF THE AGREEMENT
+
+12.1 Any person is authorized to duplicate and distribute copies of this
+Agreement.
+
+12.2 So as to ensure coherence, the wording of this Agreement is
+protected and may only be modified by the authors of the License, who
+reserve the right to periodically publish updates or new versions of the
+Agreement, each with a separate number. These subsequent versions may
+address new issues encountered by Free Software.
+
+12.3 Any Software distributed under a given version of the Agreement may
+only be subsequently distributed under the same version of the Agreement
+or a subsequent version, subject to the provisions of Article 5.3.4.
+
+
+    Article 13 - GOVERNING LAW AND JURISDICTION
+
+13.1 The Agreement is governed by French law. The Parties agree to
+endeavor to seek an amicable solution to any disagreements or disputes
+that may arise during the performance of the Agreement.
+
+13.2 Failing an amicable solution within two (2) months as from their
+occurrence, and unless emergency proceedings are necessary, the
+disagreements or disputes shall be referred to the Paris Courts having
+jurisdiction, by the more diligent Party.
+
+
+Version 2.0 dated 2005-05-21.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..8c8ed8d
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,54 @@
+04/03/13 -*- Version 2.1.0 -*-
+
+06/02/13 Julien Dutheil
+* Fixed bug #60
+* Fixed bug #63
+
+18/01/13 Julien Dutheil
+* Now compiles with -Wconversion
+* Several code formating update
+
+09/01/13 Julien Dutheil
+* Bug 59 fixed.
+
+09/02/12 -*- Version 2.0.3 -*-
+
+24/01/12 Julien Dutheil and Ania Pawelczyk
+* Added Linear Assignment Problem function in MatrixTools.
+
+24/11/11 Julien Dutheil
+* NestedStringTokenizer now inherits from StringTokenizer.
+
+22/11/11 Julien Dutheil
+* Added unit testing for matrices
+* Added new Range and MultiRange classes + unit test.
+
+09/06/11 -*- Version 2.0.2 -*-
+
+22/03/11 Mathieu Groussin
+* Added classes for mutivariate analysis.
+
+18/03/11 Mathieu Groussin
+* Added Hadamard product function in MatrixTools.
+
+28/02/11 -*- Version 2.0.1 -*-
+
+25/02/11 Julien Dutheil
+* Fixed CMakeLists.txt: added RColorSet.cpp file to compilation chain!
+
+07/02/11 -*- Version 2.0.0 -*-
+
+09/11/10 Julien Dutheil
+* Added chisq test on contingency table.
+* Removed NumTools::pow which was incorrect. Use std::pow instead.
+
+05/11/10 Julien Dutheil
+* In VectorTools: posmin -> whichMin, whichmax -> whichMax. Also recoded a bit more efficiently.
+
+27/10/10 Julien Dutheil
+* Added unit testing
+* [0000003] Fixed downhill simplex method! Did not work when initial point was 0!
+
+17/09/10 Julien Dutheil
+* Initial draft of bpp-core from old bpp-utils and bpp-numcalc.
+
diff --git a/Doxyfile b/Doxyfile
new file mode 100644
index 0000000..338c654
--- /dev/null
+++ b/Doxyfile
@@ -0,0 +1,1773 @@
+# Doxyfile 1.7.6.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should 
+# identify the project. Note that if you do not use Doxywizard you need 
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME           = bpp-core
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 2.1.0
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description 
+# for a project that appears at the top of each page and should give viewer 
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is 
+# included in the documentation. The maximum height of the logo should not 
+# exceed 55 pixels and the maximum width should not exceed 200 pixels. 
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = 
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, 
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English 
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, 
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = ./src/
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = ./src/
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful if your file system 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 2
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only). 
+# A mapping has the form "name=value". For example adding 
+# "class=itcl::class" will allow you to use the command class in the 
+# itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it 
+# parses. With this tag you can assign which parser to use for a given extension. 
+# Doxygen has a built-in mapping, but you can override or extend it using this 
+# tag. The format is ext=language, where ext is a file extension, and language 
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, 
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make 
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C 
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions 
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also makes the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to 
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter 
+# and setter methods for a property. Setting this option to YES (the default) 
+# will make doxygen replace the get and set methods by a property in the 
+# documentation. This will only work if the methods are indeed getting or 
+# setting a simple type. If this is not the case, or you want to show the 
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and 
+# unions are shown inside the group in which they are included (e.g. using 
+# @ingroup) instead of on a separate page (for HTML and Man pages) or 
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and 
+# unions with only public data fields will be shown inline in the documentation 
+# of the scope in which they are defined (i.e. file, namespace, or group 
+# documentation), provided this scope is documented. If set to NO (the default), 
+# structs, classes, and unions are shown on a separate page (for HTML and Man 
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to 
+# determine which symbols to keep in memory and which to flush to disk. 
+# When the cache is full, less often used symbols will be written to disk. 
+# For small to medium size projects (<1000 input files) the default value is 
+# probably good enough. For larger projects a too small cache size can cause 
+# doxygen to be busy swapping symbols to and from disk most of the time 
+# causing a significant performance penalty. 
+# If the system has enough physical memory increasing the cache will improve the 
+# performance by keeping more symbols in memory. Note that the value works on 
+# a logarithmic scale so increasing the size by one will roughly double the 
+# memory usage. The cache size is given by this formula: 
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+SYMBOL_CACHE_SIZE      = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be 
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given 
+# their name and scope. Since this can be an expensive process and often the 
+# same symbol appear multiple times in the code, doxygen keeps a cache of 
+# pre-resolved symbols. If the cache is too small doxygen will become slower. 
+# If the cache is too large, memory is wasted. The cache size is given by this 
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, 
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen 
+# will list include files with double quotes in the documentation 
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen 
+# will sort the (brief and detailed) documentation of class members so that 
+# constructors and destructors are listed first. If set to NO (the default) 
+# the constructors will appear in the respective orders defined by 
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. 
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO 
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. 
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to 
+# do proper type resolution of all parameters of a function it will reject a 
+# match between the prototype and the implementation of a member function even 
+# if there is only one candidate or it is obvious which candidate to choose 
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen 
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or macro consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and macros in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. 
+# This will remove the Files entry from the Quick Index and from the 
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the 
+# Namespaces page.  This will remove the Namespaces entry from the Quick Index 
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed 
+# by doxygen. The layout file controls the global structure of the generated 
+# output files in an output format independent way. The create the layout file 
+# that represents doxygen's defaults, run doxygen with the -l option. 
+# You can optionally specify a file name after the option, if omitted 
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files 
+# containing the references data. This must be a list of .bib files. The 
+# .bib extension is automatically appended if omitted. Using this command 
+# requires the bibtex tool to be installed. See also 
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style 
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this 
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = src
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh 
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py 
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS          = *.h \
+                         *.cpp
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag. 
+# Note that relative paths are relative to the directory from which doxygen is 
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or 
+# directories that are symbolic links (a Unix file system feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty or if 
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file 
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) 
+# and it is also possible to disable source filtering for a specific pattern 
+# using *.ext= (so without naming a filter). This option only has effect when 
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS = 
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) 
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from 
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will 
+# link to the source code.  Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header. Note that when using a custom header you are responsible  
+# for the proper inclusion of any scripts and style sheets that doxygen 
+# needs, which is dependent on the configuration options used. 
+# It is advised to generate a default header using "doxygen -w html 
+# header.html footer.html stylesheet.css YourConfigFile" and then modify 
+# that header. Note that the header is subject to change so you typically 
+# have to redo this when upgrading to a newer version of doxygen or when 
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# style sheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or 
+# other source files which should be copied to the HTML output directory. Note 
+# that these files will be copied to the base HTML output directory. Use the 
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these 
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that 
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. 
+# Doxygen will adjust the colors in the style sheet and background images 
+# according to this color. Hue is specified as an angle on a colorwheel, 
+# see http://en.wikipedia.org/wiki/Hue for more information. 
+# For instance the value 0 represents red, 60 is yellow, 120 is green, 
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. 
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of 
+# the colors in the HTML output. For a value of 0 the output will use 
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to 
+# the luminance component of the colors in the HTML output. Values below 
+# 100 gradually make the output lighter, whereas values above 100 make 
+# the output darker. The value divided by 100 is the actual gamma applied, 
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, 
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML 
+# page will contain the date and time when the page was generated. Setting 
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = YES
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup. 
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html 
+# for more information.
+
+GENERATE_DOCSET        = YES
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Bio++ Core Library"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = bpp.core
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify 
+# the documentation publisher. This should be a reverse domain-name style 
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING 
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file 
+# content.
+
+CHM_INDEX_ENCODING     = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and 
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated 
+# that can be used as input for Qt's qhelpgenerator to generate a 
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can 
+# be used to specify the file name of the resulting .qch file. 
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating 
+# Qt Help Project output. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to 
+# add. For more information please see 
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the 
+# custom filter to add. For more information please see 
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> 
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this 
+# project's 
+# filter section matches. 
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> 
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can 
+# be used to specify the location of Qt's qhelpgenerator. 
+# If non-empty doxygen will try to run qhelpgenerator on the generated 
+# .qhp file.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files  
+# will be generated, which together with the HTML files, form an Eclipse help 
+# plugin. To install this plugin and make it available under the help contents 
+# menu in Eclipse, the contents of the directory containing the HTML and XML 
+# files needs to be copied into the plugins directory of eclipse. The name of 
+# the directory within the plugins directory should be the same as 
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before 
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin 
+# the directory name containing the HTML and XML files should also have 
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) 
+# at top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it. Since the tabs have the same information as the 
+# navigation tree you can set this option to NO if you already set 
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index 
+# structure should be generated to display hierarchical information. 
+# If the tag value is set to YES, a side panel will be generated 
+# containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). 
+# Windows users are probably better off using the HTML help feature. 
+# Since the tree basically has the same information as the tab index you 
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW      = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values 
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML 
+# documentation. Note that a value of 0 will completely suppress the enum 
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, 
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open 
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included 
+# as images in the HTML documentation. The default is 10. Note that 
+# when you change the font size after a successful doxygen run you need 
+# to manually remove any form_*.png images from the HTML output directory 
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images 
+# generated for formulas are transparent PNGs. Transparent PNGs are 
+# not supported properly for IE 6.0, but are supported on all modern browsers. 
+# Note that when changing this option you need to delete any form_*.png files 
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax 
+# (see http://www.mathjax.org) which uses client side Javascript for the 
+# rendering instead of using prerendered bitmaps. Use this if you do not 
+# have LaTeX installed or if you want to formulas look prettier in the HTML 
+# output. When enabled you also need to install MathJax separately and 
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you need to specify the location relative to the 
+# HTML output directory using the MATHJAX_RELPATH option. The destination 
+# directory should contain the MathJax.js script. For instance, if the mathjax 
+# directory is located at the same level as the HTML output directory, then 
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the 
+# mathjax.org site, so you can quickly see the result without installing 
+# MathJax, but it is strongly recommended to install a local copy of MathJax 
+# before deployment.
+
+MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension 
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS     = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box 
+# for the HTML output. The underlying search engine uses javascript 
+# and DHTML and should work on any modern browser. Note that when using 
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets 
+# (GENERATE_DOCSET) there is already a search function so this one should 
+# typically be disabled. For large projects the javascript based search engine 
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be 
+# implemented using a PHP enabled web server instead of at the web client 
+# using Javascript. Doxygen will generate the search PHP script and index 
+# file to put on the web server. The advantage of the server 
+# based approach is that it scales better to large projects and allows 
+# full text search. The disadvantages are that it is more difficult to setup 
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name. 
+# Note that when enabling USE_PDFLATEX this option is only used for 
+# generating bitmaps for formulas in the HTML output, but not in the 
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = amsmath
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for 
+# the generated latex document. The footer should contain everything after 
+# the last chapter. If it is left blank doxygen will generate a 
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include 
+# source code with syntax highlighting in the LaTeX output. 
+# Note that which sources are shown also depends on other settings 
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the 
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See 
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition that 
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all references to function-like macros 
+# that are alone on a line, have an all uppercase name, and do not end with a 
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links. 
+# Note that each tag file must have a unique name 
+# (where the name does NOT include the path) 
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = BppCore.tag
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option also works with HAVE_DOT disabled, but it is recommended to 
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is 
+# allowed to run in parallel. When set to 0 (the default) doxygen will 
+# base this on the number of processors available in the system. You can set it 
+# explicitly to a value larger than 0 to get control over the balance 
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will use the Helvetica font for all dot files that 
+# doxygen generates. When you want a differently looking font you can specify 
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find 
+# the font, which can be done by putting it in a standard location or by setting 
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the 
+# directory containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. 
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the Helvetica font. 
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to 
+# set the path where dot can find it.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include 
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are svg, png, jpg, or gif. 
+# If left blank png will be used. If you choose svg you need to set 
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to 
+# enable generation of interactive SVG images that allow zooming and panning. 
+# Note that this requires a modern browser other than Internet Explorer. 
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you 
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files 
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG        = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that 
+# contain msc files that are included in the documentation (see the 
+# \mscfile command).
+
+MSCFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, because dot on Windows does not 
+# seem to support this out of the box. Warning: Depending on the platform used, 
+# enabling this option may lead to badly anti-aliased labels on the edges of 
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = YES
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
diff --git a/INSTALL.txt b/INSTALL.txt
new file mode 100644
index 0000000..c8859da
--- /dev/null
+++ b/INSTALL.txt
@@ -0,0 +1,12 @@
+This software needs cmake >= 2.6 to build.
+
+After installing cmake, run it with the following command:
+cmake -DCMAKE_INSTALL_PREFIX=[where to install, for instance /usr/local or $HOME/.local] .
+
+If available, you can also use ccmake instead of cmake for a more user-friendly interface.
+
+Then compile and install the software with
+make install
+
+You may also consider installing and using the software checkinstall for easier system administration.
+
diff --git a/bpp-core.spec b/bpp-core.spec
new file mode 100644
index 0000000..06e8efd
--- /dev/null
+++ b/bpp-core.spec
@@ -0,0 +1,183 @@
+%define _basename bpp-core
+%define _version 2.1.0
+%define _release 1
+%define _prefix /usr
+
+URL: http://biopp.univ-montp2.fr/
+
+Name: %{_basename}
+Version: %{_version}
+Release: %{_release}
+License: CECILL-2.0
+Vendor: The Bio++ Project
+Source: http://biopp.univ-montp2.fr/repos/sources/%{_basename}-%{_version}.tar.gz
+Summary: Bio++ Core library
+Group: Development/Libraries/C and C++
+
+BuildRoot: %{_builddir}/%{_basename}-root
+BuildRequires: cmake >= 2.6.0
+BuildRequires: gcc-c++ >= 4.0.0
+AutoReq: yes
+AutoProv: yes
+
+%description
+This library contains the core classes and utilitary functions of the Bio++ project.
+
+%package -n libbpp-core2
+Summary: Bio++ Core library
+Group: Development/Libraries/C and C++
+
+%description -n libbpp-core2
+This library contains the core classes and utilitary functions of the Bio++ project.
+
+%package -n libbpp-core-devel
+Summary: Libraries, includes to develop applications with %{_basename}
+Group: Development/Libraries/C and C++
+Requires: libbpp-core2 = %{_version}
+
+%description -n libbpp-core-devel
+The libbpp-core-devel package contains the header files and static libraries for
+building applications which use %{_basename}.
+
+%prep
+%setup -q
+
+%build
+CFLAGS="$RPM_OPT_FLAGS"
+CMAKE_FLAGS="-DCMAKE_INSTALL_PREFIX=%{_prefix} -DBUILD_TESTING=OFF"
+if [ %{_lib} == 'lib64' ] ; then
+  CMAKE_FLAGS="$CMAKE_FLAGS -DLIB_SUFFIX=64"
+fi
+cmake $CMAKE_FLAGS .
+make
+
+%install
+make DESTDIR=$RPM_BUILD_ROOT install
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post -n libbpp-core2 -p /sbin/ldconfig
+
+%post -n libbpp-core-devel
+createGeneric() {
+  echo "-- Creating generic include file: $1.all"
+  #Make sure we run into subdirectories first:
+  dirs=()
+  for file in "$1"/*
+  do
+    if [ -d "$file" ]
+    then
+      # Recursion:
+      dirs+=( "$file" )
+    fi
+  done
+  for dir in ${dirs[@]}
+  do
+    createGeneric $dir
+  done
+  #Now list all files, including newly created .all files:
+  if [ -f $1.all ]
+  then
+    rm $1.all
+  fi
+  dir=`basename $1`
+  for file in "$1"/*
+  do
+    if [ -f "$file" ] && ( [ "${file##*.}" == "h" ] || [ "${file##*.}" == "all" ] )
+    then
+      file=`basename $file`
+      echo "#include \"$dir/$file\"" >> $1.all
+    fi
+  done;
+}
+# Actualize .all files
+createGeneric %{_prefix}/include/Bpp
+exit 0
+
+%preun -n libbpp-core-devel
+removeGeneric() {
+  if [ -f $1.all ]
+  then
+    echo "-- Remove generic include file: $1.all"
+    rm $1.all
+  fi
+  for file in "$1"/*
+  do
+    if [ -d "$file" ]
+    then
+      # Recursion:
+      removeGeneric $file
+    fi
+  done
+}
+# Actualize .all files
+removeGeneric %{_prefix}/include/Bpp
+exit 0
+
+%postun -n libbpp-core2 -p /sbin/ldconfig
+
+%postun -n libbpp-core-devel
+createGeneric() {
+  echo "-- Creating generic include file: $1.all"
+  #Make sure we run into subdirectories first:
+  dirs=()
+  for file in "$1"/*
+  do
+    if [ -d "$file" ]
+    then
+      # Recursion:
+      dirs+=( "$file" )
+    fi
+  done
+  for dir in ${dirs[@]}
+  do
+    createGeneric $dir
+  done
+  #Now list all files, including newly created .all files:
+  if [ -f $1.all ]
+  then
+    rm $1.all
+  fi
+  dir=`basename $1`
+  for file in "$1"/*
+  do
+    if [ -f "$file" ] && ( [ "${file##*.}" == "h" ] || [ "${file##*.}" == "all" ] )
+    then
+      file=`basename $file`
+      echo "#include \"$dir/$file\"" >> $1.all
+    fi
+  done;
+}
+# Actualize .all files
+createGeneric %{_prefix}/include/Bpp
+exit 0
+
+%files -n libbpp-core2
+%defattr(-,root,root)
+%doc AUTHORS.txt COPYING.txt INSTALL.txt ChangeLog
+%{_prefix}/%{_lib}/lib*.so.*
+
+%files -n libbpp-core-devel
+%defattr(-,root,root)
+%doc AUTHORS.txt COPYING.txt INSTALL.txt ChangeLog
+%{_prefix}/%{_lib}/lib*.so
+%{_prefix}/%{_lib}/lib*.a
+%{_prefix}/include/*
+
+%changelog
+* Mon Mar 04 2013 Julien Dutheil <julien.dutheil at univ-montp2.fr> 2.1.0-1
+- Extended range classes
+- Improved initialization of static members
+- Extended support for BppO.
+* Thu Feb 09 2012 Julien Dutheil <julien.dutheil at univ-montp2.fr> 2.0.3-1
+- New range classes
+- Linear assigment method
+- Improved string tokenizer and text tools.
+* Thu Jun 09 2011 Julien Dutheil <julien.dutheil at univ-montp2.fr> 2.0.2-1
+- New MVA classes + more numerical tools.
+* Mon Feb 28 2011 Julien Dutheil <julien.dutheil at univ-montp2.fr> 2.0.1-1
+- Fixed missing RColorSet file.
+* Mon Feb 07 2011 Julien Dutheil <julien.dutheil at univ-montp2.fr> 2.0.0-1
+- Initial package.
+
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..fb0eee0
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,37 @@
+libbpp-core (2.1.0-1) unstable; urgency=low
+
+  * Extended range classes
+  * Improved initialization of static members
+  * Extended support for BppO.
+
+ -- Julien Dutheil <julien.dutheil at univ-montp2.fr>  Mon, 04 Mar 2013 10:15:00 +0100
+
+libbpp-core (2.0.3-1) unstable; urgency=low
+
+  * New range classes
+  * Linear assigment method
+  * Improved string tokenizer and text tools.
+
+ -- Julien Dutheil <julien.dutheil at univ-montp2.fr>  Thu, 09 Feb 2012 13:00:00 +0100
+
+libbpp-core (2.0.2-1) unstable; urgency=low
+
+  * RFP: Bio++ -- The Bio++ bioinformatics libraries. (Closes: #616373).
+  * Packages are now non-native.
+  * More MatrixTools, multivariate analysis classes and several bugs fixed.
+
+ -- Julien Dutheil <julien.dutheil at univ-montp2.fr>  Thu, 09 Jun 2011 11:00:00 +0100
+
+libbpp-core (2.0.1) unstable; urgency=low
+
+  * Fixed missing RColorSet.cpp source file.
+
+ -- Julien Dutheil <julien.dutheil at univ-montp2.fr>  Mon, 28 Feb 2011 09:00:00 +0100
+
+libbpp-core (2.0.0) unstable; urgency=low
+
+  * New package merging old bpp-utils and bpp-numcalc.
+  * New source tree.
+
+ -- Julien Dutheil <julien.dutheil at univ-montp2.fr>  Mon, 07 Feb 2011 09:00:00 +0100
+
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..7ed6ff8
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..bc0ed01
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,22 @@
+Source: libbpp-core
+Section: libs
+Priority: optional
+Maintainer: Loic Dachary <loic at dachary.org>
+Uploaders: Julien Dutheil <julien.dutheil at univ-montp2.fr>
+Build-Depends: debhelper (>= 5), cmake (>= 2.6)
+Standards-Version: 3.9.1
+
+Package: libbpp-core-dev
+Section: libdevel
+Architecture: any
+Depends: libbpp-core2 (= ${binary:Version}), ${misc:Depends}
+Description: Bio++ Core library development files.
+ Contains the Bio++ core classes.
+
+Package: libbpp-core2
+Section: libs
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Bio++ Core library.
+ Contains the Bio++ core classes.
+
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..597cf01
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,74 @@
+This package was debianized by Julien Dutheil <julien.dutheil at univ-montp2.fr> on
+Mon, 04 Mar 2013 14:30:00 +0100.
+
+It was downloaded from <http://biopp.univ-montp2.fr/Repositories/sources>
+
+Upstream Author: 
+
+    Julien Dutheil <julien.dutheil at univ-montp2.fr>
+
+Copyright: 
+
+    Copyright (C) 2013 Bio++ Development Team
+
+License:
+
+    This package is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+ 
+    This package is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+ 
+    You should have received a copy of the GNU General Public License
+    along with this package; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.
+
+The Debian packaging is (C) 2013, Julien Dutheil <julien.dutheil at univ-montp2.fr> and
+is licensed under the GPL, see above.
+
+The provided software is distributed under the CeCILL license:
+
+    This software is governed by the CeCILL license under French law and
+    abiding by the rules of distribution of free software.  You can  use, 
+    modify and/ or redistribute the software under the terms of the CeCILL
+    license as circulated by CEA, CNRS and INRIA at the following URL
+    "http://www.cecill.info". 
+
+    As a counterpart to the access to the source code and  rights to copy,
+    modify and redistribute granted by the license, users are provided only
+    with a limited warranty  and the software's author,  the holder of the
+    economic rights,  and the successive licensors  have only  limited
+    liability. 
+
+    In this respect, the user's attention is drawn to the risks associated
+    with loading,  using,  modifying and/or developing or reproducing the
+    software by the user in light of its specific status of free software,
+    that may mean  that it is complicated to manipulate,  and  that  also
+    therefore means  that it is reserved for developers  and  experienced
+    professionals having in-depth computer knowledge. Users are therefore
+    encouraged to load and test the software's suitability as regards their
+    requirements in conditions enabling the security of their systems and/or 
+    data to be ensured and,  more generally, to use and operate it in the 
+    same conditions as regards security. 
+
+    The fact that you are presently reading this means that you have had
+    knowledge of the CeCILL license and that you accept its terms.
+    
+The complete text of the license may be found here:
+http://www.cecill.info/licences/Licence_CeCILL_V2-en.html
+
+It contains some code parts from JAMA, a Java Matrix Library,
+   developed by jointly by the Mathworks and NIST;
+   see  http://math.nist.gov/javanumerics/jama,
+   and release under the GPL (files Eigenvalue.hand LUDecomposition.h).
+
+Files ContingencyTableGenerator.h (.cpp) are adpated from file rcont.c
+   edited by Martin Maechler, Dec 2003, and belonging to the R software,
+   distributed under the GPL.
diff --git a/debian/docs b/debian/docs
new file mode 100644
index 0000000..e69de29
diff --git a/debian/libbpp-core-dev.install b/debian/libbpp-core-dev.install
new file mode 100644
index 0000000..0f5727e
--- /dev/null
+++ b/debian/libbpp-core-dev.install
@@ -0,0 +1,3 @@
+debian/tmp/usr/include/*
+debian/tmp/usr/lib/*.a
+debian/tmp/usr/lib/*.so
diff --git a/debian/libbpp-core2.install b/debian/libbpp-core2.install
new file mode 100644
index 0000000..c45ebcf
--- /dev/null
+++ b/debian/libbpp-core2.install
@@ -0,0 +1 @@
+debian/tmp/usr/lib/lib*.so.*
diff --git a/debian/postinst b/debian/postinst
new file mode 100755
index 0000000..cf9e925
--- /dev/null
+++ b/debian/postinst
@@ -0,0 +1,43 @@
+#! /bin/bash
+
+# Abort if any command returns an error value
+set -e
+
+createGeneric() {
+  echo "-- Creating generic include file: $1.all"
+  #Make sure we run into subdirectories first:
+  dirs=()
+  for file in "$1"/*
+  do
+    if [ -d "$file" ]
+    then
+      # Recursion:
+      dirs+=( "$file" )
+    fi
+  done
+  for dir in ${dirs[@]}
+  do
+    createGeneric $dir
+  done
+  #Now list all files, including newly created .all files:
+  if [ -f $1.all ]
+  then
+    rm $1.all
+  fi
+  dir=`basename $1`
+  for file in "$1"/*
+  do
+    if [ -f "$file" ] && ( [ "${file##*.}" == "h" ] || [ "${file##*.}" == "all" ] )
+    then
+      file=`basename $file`
+      echo "#include \"$dir/$file\"" >> $1.all
+    fi
+  done;
+}
+
+if [ "$1" = "configure" ]; then
+  # Actualize .all files
+  createGeneric /usr/include/Bpp
+fi
+
+exit 0
diff --git a/debian/postrm b/debian/postrm
new file mode 100755
index 0000000..3931669
--- /dev/null
+++ b/debian/postrm
@@ -0,0 +1,45 @@
+#! /bin/bash
+
+# Abort if any command returns an error value
+set -e
+
+createGeneric() {
+  echo "-- Creating generic include file: $1.all"
+  #Make sure we run into subdirectories first:
+  dirs=()
+  for file in "$1"/*
+  do
+    if [ -d "$file" ]
+    then
+      # Recursion:
+      dirs+=( "$file" )
+    fi
+  done
+  for dir in ${dirs[@]}
+  do
+    createGeneric $dir
+  done
+  #Now list all files, including newly created .all files:
+  if [ -f $1.all ]
+  then
+    rm $1.all
+  fi
+  dir=`basename $1`
+  for file in "$1"/*
+  do
+    if [ -f "$file" ] && ( [ "${file##*.}" == "h" ] || [ "${file##*.}" == "all" ] )
+    then
+      file=`basename $file`
+      echo "#include \"$dir/$file\"" >> $1.all
+    fi
+  done;
+}
+
+if [ "$1" = "remove" ]; then
+  # Automatically added by dh_makeshlibs
+  ldconfig
+  # Actualize .all files
+  createGeneric /usr/include/Bpp
+fi
+
+exit 0
diff --git a/debian/prerm b/debian/prerm
new file mode 100755
index 0000000..5aefd24
--- /dev/null
+++ b/debian/prerm
@@ -0,0 +1,27 @@
+#! /bin/bash
+
+# Abort if any command returns an error value
+set -e
+
+removeGeneric() {
+  if [ -f $1.all ]
+  then
+    echo "-- Remove generic include file: $1.all"
+    rm $1.all
+  fi
+  for file in "$1"/*
+  do
+    if [ -d "$file" ]
+    then
+      # Recursion:
+      removeGeneric $file
+    fi
+  done
+}
+
+if [ "$1" = "remove" ]; then
+  # Actualize .all files
+  removeGeneric /usr/include/Bpp
+fi
+
+exit 0
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..92c389e
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,120 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# 24/01/10 Modification for use with CMake by Julien Dutheil.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+	CFLAGS += -O0
+else
+	CFLAGS += -O2
+endif
+
+# shared library versions
+version=`ls src/lib*.so.* | \
+ awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
+major=`ls src/lib*.so.* | \
+ awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
+
+configure:
+	cmake -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_TESTING=OFF .
+
+config.status: configure
+	dh_testdir
+
+build: build-stamp
+build-stamp:  config.status
+	dh_testdir
+
+	# Add here commands to compile the package.
+	$(MAKE)
+
+	touch $@
+
+clean:
+	dh_testdir
+	dh_testroot
+
+	# Add here commands to clean up after the build process.
+	[ ! -f Makefile ] || $(MAKE) clean;
+	[ ! -f Makefile ] || rm Makefile;
+	[ ! -f src/Makefile ] || rm src/Makefile;
+	[ ! -f test/Makefile ] || rm test/Makefile;
+	rm -f config.sub config.guess
+	rm -f build-stamp
+	rm -f CMakeCache.txt
+	rm -f *.cmake
+	rm -f src/*.cmake
+	rm -f test/*.cmake
+	rm -rf CMakeFiles
+	rm -rf src/CMakeFiles
+	rm -rf test/CMakeFiles
+	rm -rf _CPack_Packages
+	rm -rf Testing
+	rm -f DartConfiguration.tcl
+
+	dh_clean 
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_prep 
+	dh_installdirs
+
+	# Add here commands to install the package into debian/tmp
+	$(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+	dh_testdir
+	dh_testroot
+	dh_installchangelogs ChangeLog
+	dh_installdocs
+	dh_installexamples
+	dh_install
+#	dh_installmenu
+#	dh_installdebconf	
+#	dh_installlogrotate
+#	dh_installemacsen
+#	dh_installpam
+#	dh_installmime
+#	dh_installinit
+#	dh_installcron
+#	dh_installinfo
+	dh_installman
+	dh_link
+	dh_strip
+	dh_compress
+	dh_fixperms
+#	dh_perl
+#	dh_python
+	dh_makeshlibs
+	dh_installdeb
+	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install 
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/src/Bpp/App/ApplicationTools.cpp b/src/Bpp/App/ApplicationTools.cpp
new file mode 100644
index 0000000..d449a53
--- /dev/null
+++ b/src/Bpp/App/ApplicationTools.cpp
@@ -0,0 +1,329 @@
+//
+// File: ApplicationTools.cpp
+// Created by: Julien Dutheil
+// Created on: Fri Oct 21 16:19 2005
+// From old file created on: Sun Dec 14 09:36:26 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+This software is a computer program whose purpose is to provide basal and 
+utilitary classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "ApplicationTools.h"
+
+using namespace bpp;
+
+// From the STL:
+#include <cmath>
+
+using namespace std;
+
+/******************************************************************************/
+
+OutputStream* ApplicationTools::error   = new StdErr();
+OutputStream* ApplicationTools::message = new StdOut();
+OutputStream* ApplicationTools::warning = new StdOut();
+time_t ApplicationTools::startTime;
+size_t ApplicationTools::terminalWidth = 80;
+float ApplicationTools::terminalSplit = 0.5;
+bool ApplicationTools::interactive = true;
+
+/******************************************************************************/
+
+bool ApplicationTools::parameterExists(
+  const std::string & parameterName,
+  std::map<std::string, std::string>& params)
+{
+  return (params.find(parameterName) != params.end() && !TextTools::isEmpty(params[parameterName]));
+}
+  
+/******************************************************************************/
+
+std::string ApplicationTools::getAFilePath(
+  const std::string& parameter,
+  std::map<std::string, std::string>& params,
+  bool isRequired,
+  bool mustExist,
+  const std::string& suffix,
+  bool suffixIsOptional) throw (Exception)
+{
+  string filePath = getStringParameter(parameter, params, "none", suffix, suffixIsOptional, false);
+  if (filePath == "") filePath = "none";
+  if (filePath == "none" && isRequired)
+  {
+    throw Exception("You must specify a file for this parameter: " + parameter + (suffixIsOptional ? "" : suffix));
+  }
+  if(filePath == "none") return filePath;
+  if(mustExist && !FileTools::fileExists(filePath))
+  {
+    throw Exception("File does not exists: " + filePath);
+  }
+  return filePath;
+}
+
+/******************************************************************************/
+
+double ApplicationTools::getDoubleParameter(
+  const std::string & parameterName,
+  std::map<std::string, std::string> & params,
+  double defaultValue,
+  const std::string & suffix,
+  bool suffixIsOptional,
+  bool warn)
+{
+  double dParam = defaultValue;
+  if (parameterExists(parameterName + suffix, params))
+  {
+    dParam = TextTools::toDouble(params[parameterName + suffix]);
+  }
+  else if (suffixIsOptional && parameterExists(parameterName, params))
+  {
+    dParam = TextTools::toDouble(params[parameterName]);
+  }
+  else if(warn)
+  {
+    displayWarning("Parameter " + parameterName + suffix + " not specified. Default used instead: " + TextTools::toString(defaultValue));
+  }
+  return dParam;
+}
+
+/******************************************************************************/
+
+int ApplicationTools::getIntParameter(
+  const std::string & parameterName,
+  std::map<std::string, std::string> & params,
+  int defaultValue,
+  const std::string & suffix,
+  bool suffixIsOptional,
+  bool warn)
+{
+  int iParam = defaultValue;
+  if (parameterExists(parameterName + suffix, params)) {
+    iParam = TextTools::toInt(params[parameterName + suffix]);
+  } else if(suffixIsOptional && parameterExists(parameterName, params)) {
+    iParam = TextTools::toInt(params[parameterName]);
+  } else if (warn) {
+    displayWarning("Parameter " + parameterName + suffix + " not specified. Default used instead: " + TextTools::toString(defaultValue));
+  }
+  return iParam;
+}
+
+/******************************************************************************/
+
+std::string ApplicationTools::getStringParameter(
+  const std::string& parameterName,
+  std::map<std::string, std::string>& params,
+  const std::string& defaultValue,
+  const std::string& suffix,
+  bool suffixIsOptional,
+  bool warn)
+{
+  string sParam = defaultValue;
+  if (parameterExists(parameterName + suffix, params)) {
+    sParam = params[parameterName + suffix];
+  } else if (suffixIsOptional && parameterExists(parameterName, params)) {
+    sParam = params[parameterName];
+  } else if (warn) {
+    displayWarning("Parameter " + parameterName + " not specified. Default used instead: " + defaultValue);
+  }
+  return sParam;
+}
+
+/******************************************************************************/
+
+bool ApplicationTools::getBooleanParameter(
+  const std::string& parameterName,
+  std::map<std::string, std::string>& params,
+  bool defaultValue,
+  const std::string& suffix,
+  bool suffixIsOptional,
+  bool warn)
+{
+  string sParam;
+  bool bParam = defaultValue;
+  if (parameterExists(parameterName + suffix, params))
+  {
+    sParam = params[parameterName + suffix];
+  }
+  else if (suffixIsOptional && parameterExists(parameterName, params))
+  {
+    sParam = params[parameterName];
+  }
+  else {
+    if (warn)
+    {
+      displayWarning("Parameter " + parameterName + " not specified. Default used instead: " + TextTools::toString(defaultValue));
+    }
+    return bParam;
+  }
+  if ((sParam == "true") 
+   || (sParam == "TRUE")
+   || (sParam == "t")
+   || (sParam == "T")
+   || (sParam == "yes")
+   || (sParam == "YES")
+   || (sParam == "y")
+   || (sParam == "Y")
+   || (sParam == "1"))
+    bParam = true;
+  else if ((sParam == "false") 
+        || (sParam == "FALSE")
+        || (sParam == "f")
+        || (sParam == "F")
+        || (sParam == "no")
+        || (sParam == "NO")
+        || (sParam == "n")
+        || (sParam == "N")
+        || (sParam == "0"))
+    bParam = false;
+  else throw Exception("ApplicationTools::getBooleanParameter. Wrong description:" + sParam);
+ 
+  return bParam;
+}
+
+/******************************************************************************/
+
+void ApplicationTools::displayMessage(const std::string& text) { if(message) (*message << text).endLine(); }
+    
+void ApplicationTools::displayError(const std::string& text) { if(error) (*error << "ERROR!!! " << text).endLine(); }
+    
+void ApplicationTools::displayWarning(const std::string& text) { if(warning) (*warning << "WARNING!!! " << text).endLine(); }
+
+void ApplicationTools::displayTask(const std::string& text, bool eof)
+{
+  if (message)
+  {
+    *message << TextTools::resizeRight(text, static_cast<size_t>(static_cast<float>(terminalWidth) * terminalSplit - 1), '.') << ": ";
+    if (eof) message->endLine();
+    else     message->flush();
+  }
+}
+    
+void ApplicationTools::displayTaskDone() { if(message) (*message << "Done.").endLine(); }
+
+/******************************************************************************/
+
+void ApplicationTools::displayGauge(size_t iter, size_t total, char symbol, const std::string& mes)
+{
+  if (!message) return;
+  if (total == 0) return;//We do not display anything in that case.
+  size_t width = static_cast<size_t>(static_cast<float>(terminalWidth) * terminalSplit - 2);
+  string gauge = string(static_cast<size_t>((1. * static_cast<double>(iter) / static_cast<double>(total)) * static_cast<double>(width)), symbol);
+  string info = mes;
+  if (interactive)
+  {
+    string fill = string(width - gauge.length(), ' ');
+    gauge = "[" + gauge + fill + "] " + TextTools::resizeLeft(TextTools::toString(100 * iter / total), 3) + "%";
+    if (mes.size() > terminalWidth - gauge.size())
+      info = TextTools::resizeRight(mes, terminalWidth - gauge.size());
+    *message << '\r' + info + gauge;
+    message->flush();
+  }
+  else
+  {
+    if (iter == 0)
+    {
+      *message << "[";
+      message->flush();
+      return;
+    }
+    size_t step = static_cast<size_t>(ceil(1. * static_cast<double>(total) / static_cast<double>(width)));
+    if (iter >= total)
+    {
+      size_t fill = static_cast<size_t>(static_cast<float>(terminalWidth) * terminalSplit) - (total - 1) / step - 1;
+      *message << TextTools::resizeLeft("]", fill, symbol);
+      message->flush();
+      return;
+    }
+    size_t x = iter % step;
+    if (x == 0) { *message << symbol; message->flush(); }
+  }
+}
+
+/******************************************************************************/
+
+void ApplicationTools::displayUnlimitedGauge(size_t iter, const std::string& mes)
+{
+  if (!message) return;
+  string chars = "-/-\\";
+  string info = mes;
+  if (interactive)
+  {
+    unsigned int i = iter % 4;
+    *message << '\r' << info << chars[i] << " " << TextTools::toString(iter);
+    message->flush();
+  }
+  else
+  {
+    if (iter == 0)
+      *message << info;
+    *message << "*";
+    message->flush();
+    return;
+  }
+}
+
+/******************************************************************************/
+  
+void ApplicationTools::displayTime(const std::string& msg)
+{
+  time_t endTime;
+  time(&endTime);
+  if (message)
+  {
+    double nsec = difftime(endTime, startTime);
+    double nmin = floor(nsec/60.);
+    double nhou = floor(nmin/60.);
+    double nday = floor(nhou/24.);
+    nhou = nhou - nday * 24;
+    nmin = nmin - (nday * 24 + nhou) * 60;
+    nsec = nsec - ((nday * 24 + nhou) * 60 + nmin) * 60;
+    *message << msg << " ";
+    *message << nday << "d, ";
+    *message << nhou << "h, ";
+    *message << nmin << "m, ";
+    *message << nsec << "s.";
+    message->endLine();
+  }
+}
+
+/******************************************************************************/
+  
+double ApplicationTools::getTime()
+{
+  time_t endTime;
+  time(&endTime);
+  return difftime(endTime, startTime);
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/App/ApplicationTools.h b/src/Bpp/App/ApplicationTools.h
new file mode 100644
index 0000000..272ca85
--- /dev/null
+++ b/src/Bpp/App/ApplicationTools.h
@@ -0,0 +1,514 @@
+//
+// File: ApplicationTools.h
+// Created by: Julien Dutheil
+// Created on: Fri Oct 21 16:19 2005
+// From old file created on: Sun Dec 14 09:36:26 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide basal and 
+utilitary classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _APPLICATIONTOOLS_H_
+#define _APPLICATIONTOOLS_H_
+
+#include "../Io/FileTools.h"
+#include "../Io/OutputStream.h"
+#include "../Text/TextTools.h"
+#include "../Text/StringTokenizer.h"
+#include "../Text/NestedStringTokenizer.h"
+
+// From the STL:
+#include <map>
+#include <vector>
+#include <iostream>
+#include <ctime>
+
+namespace bpp
+{
+
+/**
+ * @brief This class provides some common tools for developping applications.
+ *
+ * These functions are designed for helping to parse an option file.
+ * 
+ * The option files are supposed to follow this simple format:<br>
+ * @code
+ * parameterName = parameterContent
+ * @endcode
+ * with one parameter per line.
+ *
+ * In files, shell comments:
+ * @code
+ * # my comment line here
+ * @endcode
+ * C comments:
+ * @code
+ * / * my comment block here * /
+ * @endcode
+ * and C++ comments:
+ * @code
+ * // my comment line here
+ * @endcode
+ * are allowed, and ignored while parsing.
+ *
+ * Some methods for displaying information (messages, errors, warnings...) are also provided.
+ *
+ * Methods dealing with parameters takes as argument a map<string, string> object
+ * containing the parameters (names are the keys of the map, and values are... the values of the map!).
+ * These map objects may be obtained from the AttributesTools utilitary class.
+ */
+class ApplicationTools
+{
+  public:
+    
+    /**
+     * @brief The output stream where errors have to be displayed.
+     */
+    static OutputStream* error;
+    /**
+     * @brief The output stream where messages have to be displayed.
+     */
+    static OutputStream* message;
+    /**
+     * @brief The output stream where warnings have to be displayed.
+     */
+    static OutputStream* warning;
+
+    /**
+     * @brief Timer variable.
+     */
+    static time_t startTime;
+
+    /**
+     * @brief The width of the output terminal (in character).
+     */
+    static size_t terminalWidth;
+
+    /**
+     * @brief The fraction of terminal width dedicated to messages.
+     */
+    static float terminalSplit;
+
+    /**
+     * @brief Tell if the program is interactive (typically run in foreground). Default to yes.
+     */
+    static bool interactive;
+  
+  public:
+    ApplicationTools() {}
+    virtual ~ApplicationTools() {}
+  
+  public:
+
+    /**
+     * @brief Tells if a parameter have been specified.
+     *
+     * @param parameterName The name of the parameter.
+     * @param params        The parameter list.
+     * @return True is the parameter of specified name is in the list.
+     */
+    static bool parameterExists(const std::string& parameterName, std::map<std::string, std::string>& params);
+  
+    /**
+     * @brief Get a double parameter.
+     *
+     * @param parameterName    The name of the corresponding parameter.
+     * @param params           The attribute map where options may be found.
+     * @param defaultValue     The default value to use if the parameter is not found.
+     * @param suffix           A suffix to be applied to the parameter name.
+     * @param suffixIsOptional Tell if the suffix is absolutely required.
+     * @param warn             Tell if a warning must be sent in case the parameter is not found.
+     * @return The corresponding value.
+     */
+    static double getDoubleParameter(
+      const std::string& parameterName,
+      std::map<std::string, std::string>& params,
+      double defaultValue,
+      const std::string& suffix = "",
+      bool suffixIsOptional = true,
+      bool warn = true);
+  
+    /**
+     * @brief Get an integer parameter.
+     *
+     * @param parameterName    The name of the corresponding parameter.
+     * @param params           The attribute map where options may be found.
+     * @param defaultValue     The default value to use if the parameter is not found.
+     * @param suffix           A suffix to be applied to the parameter name.
+     * @param suffixIsOptional Tell if the suffix is absolutely required.
+     * @param warn             Tell if a warning must be sent in case the parameter is not found.
+     * @return The corresponding value.
+     */
+    static int getIntParameter(
+      const std::string& parameterName,
+      std::map<std::string, std::string>& params,
+      int defaultValue,
+      const std::string& suffix = "",
+      bool suffixIsOptional = true,
+      bool warn = true);
+  
+    /**
+     * @brief Get a string parameter.
+     *
+     * @param parameterName    The name of the corresponding parameter.
+     * @param params           The attribute map where options may be found.
+     * @param defaultValue     The default value to use if the parameter is not found.
+     * @param suffix           A suffix to be applied to the parameter name.
+     * @param suffixIsOptional Tell if the suffix is absolutely required.
+     * @param warn             Tell if a warning must be sent in case the parameter is not found.
+     * @return The corresponding value.
+     */
+    static std::string getStringParameter(
+      const std::string& parameterName,
+      std::map<std::string, std::string>& params,
+      const std::string& defaultValue,
+      const std::string& suffix = "",
+      bool suffixIsOptional = true,
+      bool warn = true);
+
+    /**
+     * @brief Get a boolean parameter.
+     *
+     * @param parameterName    The name of the corresponding parameter.
+     * @param params           The attribute map where options may be found.
+     * @param defaultValue     The default value to use if the parameter is not found.
+     * @param suffix           A suffix to be applied to the parameter name.
+     * @param suffixIsOptional Tell if the suffix is absolutely required.
+     * @param warn             Tell if a warning must be sent in case the parameter is not found.
+     * @return The corresponding value.
+     */
+    static bool getBooleanParameter(
+      const std::string& parameterName,
+      std::map<std::string, std::string>& params,
+      bool defaultValue,
+      const std::string& suffix = "",
+      bool suffixIsOptional = true,
+      bool warn = true);
+
+    /**
+     * @brief Get a parameter.
+     *
+     * @param parameterName    The name of the corresponding parameter.
+     * @param params           The attribute map where options may be found.
+     * @param defaultValue     The default value to use if the parameter is not found.
+     * @param suffix           A suffix to be applied to the parameter name.
+     * @param suffixIsOptional Tell if the suffix is absolutely required.
+     * @param warn             Tell if a warning must be sent in case the parameter is not found.
+     * @return The corresponding value.
+     */
+    template<class T> static T getParameter(
+      const std::string& parameterName,
+      std::map<std::string, std::string>& params,
+      T defaultValue,
+      const std::string& suffix = "",
+      bool suffixIsOptional = true,
+      bool warn = true)
+    {
+      T tParam = defaultValue;
+      if(parameterExists(parameterName + suffix, params))
+      {
+        tParam = TextTools::to<T>(params[parameterName + suffix]);
+      }
+      else if(suffixIsOptional && parameterExists(parameterName, params))
+      {
+        tParam = TextTools::to<T>(params[parameterName]);
+      } else if(warn)
+      {
+        displayWarning("Parameter " + parameterName + suffix + " not specified. Default used instead: " + TextTools::toString(defaultValue));
+      }
+      return tParam;
+    }
+  
+
+    /**
+     * @brief Get a file path.
+     *
+     * @param parameter        The name of the corresponding parameter.
+     * @param params           The attribute map where options may be found.
+     * @param isRequired       Tell if this path is strictly required or is optional
+     * (in the first case, if the parameter is not found, the programm will
+     * send an error and exit).
+     * @param mustExist        Tell if the corresponding file must already exist.
+     * @param suffix           A suffix to be applied to the parameter name.
+     * @param suffixIsOptional Tell if the suffix is absolutely required.
+     * @throw Exception        If no file path is specified and isRequired is
+     *                         true, or the file does not exist and mustExist
+     *                         is set to true.
+     */
+    static std::string getAFilePath(
+      const std::string& parameter,
+      std::map<std::string, std::string>& params,
+      bool isRequired = true,
+      bool mustExist = true,
+      const std::string& suffix = "",
+      bool suffixIsOptional = false) throw (Exception);
+
+    /**
+     * @brief Get a vector.
+     *
+     * @param parameterName    The name of the corresponding parameter.
+     * @param params           The attribute map where options may be found.
+     * @param separator        The character used to delimit values.
+     * @param defaultValue     The default value to use if the parameter is not found.
+     * @param suffix           A suffix to be applied to the parameter name.
+     * @param suffixIsOptional Tell if the suffix is absolutely required.
+     * @param warn             Tell if a warning must be sent in case the parameter is not found.
+     * @return The corresponding value.
+     */
+    template<class T> static std::vector<T> getVectorParameter(
+      const std::string& parameterName,
+      std::map<std::string, std::string>& params,
+      char separator,
+      const std::string& defaultValue,
+      const std::string& suffix = "",
+      bool suffixIsOptional = true,
+      bool warn = true)
+    {
+      std::string s = getStringParameter(parameterName, params, defaultValue, suffix, suffixIsOptional, warn);
+      if (TextTools::isEmpty(s)) return std::vector<T>(0);
+      if (s[0] == '(' && s[s.size() - 1] == ')') {
+        //This is a delimited vector:
+        s = s.substr(1, s.size() - 2);
+        if (TextTools::isEmpty(s)) return std::vector<T>(0);
+      }
+      NestedStringTokenizer st(s, "(", ")", TextTools::toString(separator));
+      size_t n = st.numberOfRemainingTokens();
+      std::vector<T> v(n);
+      for (size_t i = 0; i < n; i++)
+      {
+        v[i] = TextTools::fromString<T>(st.nextToken());
+      }
+      return v;
+    }
+
+    /**
+     * @brief Get a vector.
+     *
+     * Similar to getVectorParameter, but dedicated to numerical values.
+     * It allows the possibility to set range of values, which will be incremented by 1 (like the : operator in R).
+     *
+     * @param parameterName    The name of the corresponding parameter.
+     * @param params           The attribute map where options may be found.
+     * @param separator        The character used to delimit values.
+     * @param rangeOperator    The character used to delimit ranges (the + 1 operator must be available for T).
+     * @param defaultValue     The default value to use if the parameter is not found.
+     * @param suffix           A suffix to be applied to the parameter name.
+     * @param suffixIsOptional Tell if the suffix is absolutely required.
+     * @param warn             Tell if a warning must be sent in case the parameter is not found.
+     * @return The corresponding value.
+     */
+    template<class T> static std::vector<T> getVectorParameter(
+      const std::string& parameterName,
+      std::map<std::string, std::string>& params,
+      char separator,
+      char rangeOperator,
+      const std::string& defaultValue,
+      const std::string& suffix = "",
+      bool suffixIsOptional = true,
+      bool warn = true)
+    {
+      std::string s = getStringParameter(parameterName, params, defaultValue, suffix, suffixIsOptional, warn);
+      StringTokenizer st(s, TextTools::toString(separator));
+      size_t n = st.numberOfRemainingTokens();
+      std::vector<T> v;
+      for (size_t i = 0; i < n; i++)
+      {
+        std::string token = st.nextToken();
+        std::string::size_type pos = token.find(rangeOperator);
+        if (pos == std::string::npos)
+          v.push_back(TextTools::fromString<T>(token));
+        else
+        {
+          T d1 = TextTools::fromString<T>(token.substr(0, pos));
+          T d2 = TextTools::fromString<T>(token.substr(pos + 1));
+          for (T j = d1; j < d2; j++)
+          {
+            v.push_back(j);
+          }
+          v.push_back(d2);
+        }
+      }
+      return v;
+    }
+   
+    /**
+     * @name Output methods.
+     *
+     * @{
+     */
+    
+    /**
+     * @brief Print a message.
+     *
+     * @param text The text of the message.
+     */
+    static void displayMessage(const std::string& text);
+    
+    /**
+     * @brief Print an error message.
+     *
+     * @param text The text of the message.
+     */
+    static void displayError(const std::string& text);
+    
+    /**
+     * @brief Print a warning message.
+     *
+     * @param text The text of the message.
+     */
+    static void displayWarning(const std::string& text);
+    
+    /**
+     * @brief Print a task message.
+     *
+     * Display the message and flush the buffer, but do not end the current line.
+     *
+     * @param text The text of the message.
+     * @param eof  Insert a carriage return after displaying the message.
+     */
+    static void displayTask(const std::string& text, bool eof = false);
+    
+    /**
+     * @brief Print a task ended message.
+     *
+     * Print "Done." and go to next line.
+     */
+    static void displayTaskDone();
+    
+    /**
+     * @brief Print a result message.
+     *
+     * Result will be aligned to 30 character from the begining of the message.
+     * ex: text = "Here is what you get:" and result = "THAT" gives
+     * "Here is what you get:          THAT".
+     *    
+     * @param text   The text of the message.
+     * @param result The result.
+     */
+    template<class T>
+    static void displayResult(const std::string& text, const T& result)
+    {
+      displayMessage(TextTools::resizeRight(text, static_cast<size_t>(static_cast<float>(terminalWidth) * terminalSplit - 1), '.') + ": " + TextTools::toString<T>(result));
+    }
+
+    /**
+     * @brief Print a boolean result message ("yes" or "no").
+     *
+     * Result will be aligned to 30 character from the begining of the message.
+     * @param text   The text of the message.
+     * @param result The result.
+     */
+    static void displayBooleanResult(const std::string& text, bool result)
+    {
+      displayResult(text, result ? std::string("yes") : std::string("no"));
+    }
+
+    /**
+     * @brief Display a gauge.
+     *
+     * Show progress status.
+     * @code
+     * for(size_t i = 0; i < 1000; i++)
+     * {
+     *   ApplicationTools::displayGauge(i, 999, '*');
+     *   //Perform time consuming task...
+     * }
+     * @endcode
+     * will result in something like:
+     * @verbatim
+     * [************************************]
+     * @endverbatim
+     * 
+     * @param iter   The current iteration number.
+     * @param total  The total number of iteration.
+     * @param symbol The character to display in the gauge.
+     * @param mes    A message to print before the gauge.
+     */
+    static void displayGauge(size_t iter, size_t total, char symbol='>', const std::string& mes="");
+
+    /**
+     * @brief Display a gauge for unefined amount of iterations.
+     *
+     * Show progress status.
+     * @code
+     * for(size_t i = 0; i < 1000; i++)
+     * {
+     *   ApplicationTools::displayUnlimitedGauge(i);
+     *   //Perform time consuming task...
+     * }
+     * @endcode
+     * will result in something like:
+     * @verbatim
+     * - 1
+     * / 2
+     * - 3
+     * \ 4
+     * - 5
+     * etc
+     * @endverbatim
+     * 
+     * @param iter   The current iteration number.
+     * @param mes    A message to print before the gauge.
+     */
+    static void displayUnlimitedGauge(size_t iter, const std::string& mes="");
+
+
+    /** @} */
+
+    /**
+     * @brief Starts the timer.
+     */
+    static void startTimer()
+    {
+      time(&startTime);
+    }
+
+    /**
+     * @brief Display the current timer value to the 'message' stream.
+     *
+     * @param msg Message to display before time.
+     */
+    static void displayTime(const std::string& msg);
+ 
+    /**
+     * @brief Get the current timer value.
+     *
+     * @return The number of seconds from when timer was started.
+     */
+    static double getTime();
+};
+
+} //end of namespace bpp.
+
+#endif  //_APPLICATIONTOOLS_H_
+
diff --git a/src/Bpp/App/BppApplication.cpp b/src/Bpp/App/BppApplication.cpp
new file mode 100644
index 0000000..5d10750
--- /dev/null
+++ b/src/Bpp/App/BppApplication.cpp
@@ -0,0 +1,70 @@
+//
+// File: BppApplication.cpp
+// Created by: Julien Dutheil
+// Created on: Sat Aug 08 08:21 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide basal and 
+utilitary classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "BppApplication.h"
+#include "../Utils/AttributesTools.h"
+#include "ApplicationTools.h"
+
+// From the STL:
+#include <iostream>
+
+using namespace bpp;
+using namespace std;
+
+BppApplication::BppApplication(int argc, char* argv[], const std::string& name): appName_(name), params_(), timerStarted_(false)
+{
+  cout << "Parsing options:" << endl;  
+  params_ = AttributesTools::parseOptions(argc, argv);
+  bool noint = ApplicationTools::getBooleanParameter("--noninteractive", params_, false, "", true, false);
+  ApplicationTools::interactive = !noint;
+}
+
+void BppApplication::startTimer()
+{
+  ApplicationTools::startTimer();
+  timerStarted_ = true;
+}
+
+void BppApplication::done()
+{
+  cout << appName_ << "'s done. Bye." << endl;
+  if (timerStarted_)
+    ApplicationTools::displayTime("Total execution time:");
+}
+
diff --git a/src/Bpp/App/BppApplication.h b/src/Bpp/App/BppApplication.h
new file mode 100644
index 0000000..8798f17
--- /dev/null
+++ b/src/Bpp/App/BppApplication.h
@@ -0,0 +1,80 @@
+//
+// File: BppApplication.h
+// Created by: Julien Dutheil
+// Created on: Sat Aug 08 08:21 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide basal and 
+utilitary classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BPPAPPLICATION_H_
+#define _BPPAPPLICATION_H_
+
+#include "../Exceptions.h"
+
+// From the STL:
+#include <string>
+#include <map>
+
+namespace bpp
+{
+
+  class BppApplication
+  {
+    private:
+      std::string appName_;
+      mutable std::map<std::string, std::string> params_;
+      bool timerStarted_;
+
+    public:
+      BppApplication(int argc, char* argv[], const std::string& name);
+
+    public:
+      void startTimer();
+      void done();
+
+      std::map<std::string, std::string>& getParams() { return params_; }
+
+      const std::string& getParam(const std::string& name) const throw (Exception)
+      {
+        if (params_.find(name) == params_.end()) throw Exception("BppApplication::getParam(). Parameter '" + name + "' not found.");
+        return params_[name];
+      }
+      
+      std::string& getParam(const std::string& name) { return params_[name]; }
+  };
+
+} //end of namespace bpp;
+
+#endif // _BPPAPPLICATION_H_
+
diff --git a/src/Bpp/App/NumCalcApplicationTools.cpp b/src/Bpp/App/NumCalcApplicationTools.cpp
new file mode 100644
index 0000000..7c2dcf9
--- /dev/null
+++ b/src/Bpp/App/NumCalcApplicationTools.cpp
@@ -0,0 +1,140 @@
+//
+// File: NumCalcApplicationTools.cpp
+// Created by: Julien Dutheil
+// Created on: Sun Mar 29 15:13 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (January 13, 2009)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "NumCalcApplicationTools.h"
+#include "../Numeric/NumConstants.h"
+#include "ApplicationTools.h"
+#include "../Text/KeyvalTools.h"
+
+using namespace bpp;
+using namespace std;
+
+vector<int> NumCalcApplicationTools::seqFromString(const std::string& s, const std::string& delim, const std::string& seqdelim)
+{
+  vector<int> seq;
+  StringTokenizer * st = new StringTokenizer(s, delim, true);
+  while (st->hasMoreToken())
+  {
+    StringTokenizer * st2 = new StringTokenizer(st->nextToken(), seqdelim, true);
+    if (st2->numberOfRemainingTokens() > 1)
+    {
+      vector<int> tmp = VectorTools::seq(TextTools::toInt(st2->getToken(0)), TextTools::toInt(st2->getToken(1)), 1);
+      VectorTools::append(seq, tmp);
+    }
+    else
+    {
+      seq.push_back(TextTools::toInt(st2->getToken(0)));
+    }  
+  }  
+  return seq;
+}
+
+
+
+vector<double> NumCalcApplicationTools::getVector(const std::string& desc) throw (Exception)
+{
+  vector<double> values;
+  string key, val;
+
+  if(desc.substr(0,3) == "seq") // Bounds specified as sequence
+  {
+    map<string, string> keyvals;
+    KeyvalTools::multipleKeyvals(desc.substr(4, desc.size() - 5), keyvals);
+    if(keyvals.find("from") == keyvals.end()) throw Exception("Unvalid sequence specification, missing 'from' key: " + desc.substr(3, desc.size() - 5));
+    if(keyvals.find("to") == keyvals.end()) throw Exception("Unvalid sequence specification, missing 'to' key: " + desc.substr(3, desc.size() - 5));
+    if(keyvals.find("step") == keyvals.end() && keyvals.find("size") == keyvals.end())
+      throw Exception("Unvalid sequence specification, missing 'step' or 'size' key: " + desc.substr(3, desc.size() - 5));
+    double start = TextTools::toDouble(keyvals["from"]);
+    double end   = TextTools::toDouble(keyvals["to"]);
+    if(keyvals.find("step") != keyvals.end())
+    {
+      double step = TextTools::toDouble(keyvals["step"]);
+      for(double x = start; x <= end+NumConstants::TINY(); x += step)
+        values.push_back(x);
+    }
+    else
+    {
+      int size = TextTools::toInt(keyvals["size"]);
+      double step = (end - start) / (double)size;
+      for(int i = 0; i < size - 1; i++)
+        values.push_back(start + i * step);
+      values.push_back(end); // for rounding purpose.
+    }
+  }
+  else // Direct enumaration of values
+  {
+    StringTokenizer st(desc, ",");
+    while(st.hasMoreToken()) values.push_back(TextTools::toDouble(st.nextToken()));
+  }
+  return values;
+}
+
+
+
+double NumCalcApplicationTools::getDefaultValue(const ParameterList& pl, const std::string& name, double x)
+{
+  for(unsigned int i = 0; i < pl.size(); i++)
+  {
+    const Parameter& p = pl[i];
+    if(p.getName() == name)
+      return p.getValue();
+  }
+  return x;
+}
+
+
+
+ParameterGrid* NumCalcApplicationTools::getParameterGrid(
+    map<string, string>& params,
+    const string& suffix,
+    bool suffixIsOptional,
+    bool warn) throw (Exception)
+{
+  unsigned int nbParams = ApplicationTools::getParameter<unsigned int>("grid.number_of_parameters", params, 1, suffix, suffixIsOptional, warn);
+  ParameterGrid* grid = new ParameterGrid();
+  for(unsigned int i = 0; i < nbParams; i++)
+  {
+    string name = ApplicationTools::getStringParameter("grid.parameter" + TextTools::toString(i+1) + ".name", params, "", suffix, suffixIsOptional, warn);
+    vector<double> values = getVector(ApplicationTools::getStringParameter("grid.parameter" + TextTools::toString(i+1) + ".values", params, "", suffix, suffixIsOptional, warn));
+    grid->addDimension(name, values);
+  }
+  return grid;
+}
+
+
diff --git a/src/Bpp/App/NumCalcApplicationTools.h b/src/Bpp/App/NumCalcApplicationTools.h
new file mode 100644
index 0000000..b250940
--- /dev/null
+++ b/src/Bpp/App/NumCalcApplicationTools.h
@@ -0,0 +1,134 @@
+//
+// File: NumCalcApplicationTools.h
+// Created by: Sylvain Gaillard
+// Created on: Tue Jan 14:58:50 CET 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (January 13, 2009)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _NUMCALCAPPLICATIONTOOLS_H_
+#define _NUMCALCAPPLICATIONTOOLS_H_
+
+#include "../Text/StringTokenizer.h"
+#include "ApplicationTools.h"
+#include "../Numeric/VectorTools.h"
+#include "../Numeric/Function/FunctionTools.h"
+
+namespace bpp
+{
+
+class NumCalcApplicationTools
+{
+  public:
+    NumCalcApplicationTools();
+    virtual ~NumCalcApplicationTools();
+
+  public:
+    /**
+     * @brief Build a vector of integers as described by a string
+     *
+     * Build a vector of integers following a description like:
+     * "2, 5, 7-10, 4" => [2, 5, 7, 8, 9, 10, 4]
+     *
+     * @author Sylvain Gaillard
+     * @param s The string to parse.
+     * @param delim Delimiter between elements.
+     * @param seqdelim Delimiter between min and max for a sequence.
+     * @return A vector containing the integers
+     */
+    static std::vector<int> seqFromString(const std::string& s, const std::string& delim = ",", const std::string& seqdelim = "-");
+
+    /**
+     * @brief Build a vector of double from a structured text description.
+     *
+     * The syntax may be one of the following:
+     * - Specified values: 1.23, 2.34, 3.45, 4.56
+     * - Sequence macro: seq(from=1.23,to=2.45,step=0.1)
+     *   or              seq(from=1.23,to=2.45,size=5)
+     *   The meaning of these to form is equivalent as the R function:
+     *   The first one start from 1.23 and increment 0.1 until it reaches
+     *   the 2.45 value, wheras the seocnd one will compute 3 values at
+     *   equal distance from 1.23 and 2.45. the 'from' and 'to' values are
+     *   included, except for the first syntax when the interval is not an
+     *   exact multiple of the 'step' argument.
+     *
+     * @author Julien Dutheil
+     * @param desc The string to parse.
+     * @return A vector containing the corresponding values as double.
+     * @throw Exception If the syntax describing the set is not correct.
+     */
+    static std::vector<double> getVector(const std::string& desc) throw (Exception);
+
+    /**
+     * @brief Returns the value of the Parameter of the given name
+     *  if it exists; otherwise returns the default value.
+     *
+     * @author Laurent Gueguen
+     * @param pl A parameter list to look in.
+     * @param name A string name
+     * @param x A double value
+     */
+    static double getDefaultValue(const ParameterList& pl, const std::string& name, double x);
+
+    /**
+     * @brief Design a parameter grid from input options.
+     *
+     * Example:
+     * @code
+     * grid.number_of_parameters=3
+     * grid.parameter1.name=x
+     * grid.parameter1.values=0.1,0.2,0.3,0.4,0.5
+     * grid.parameter2.name=y
+     * grid.parameter2.values=seq(from=0.1,to=0.5,step=0.1)
+     * grid.parameter3.name=z
+     * grid.parameter3.values=seq(from=0.1,to=0.5,size=5)
+     * @endcode
+     *
+     * @param params           The attribute map where options may be found.
+     * @param suffix           A suffix to be applied to the parameter name.
+     * @param suffixIsOptional Tell if the suffix is absolutely required.
+     * @param warn             Tell if a warning must be sent in case the parameter is not found.
+     * @return a parameter grid object.
+     */
+    static ParameterGrid* getParameterGrid(
+        std::map<std::string, std::string>& params,
+        const std::string& suffix = "",
+        bool suffixIsOptional = true,
+        bool warn = true) throw (Exception);
+
+};
+
+} //End of namespace bpp.
+
+#endif  //_NUMCALCAPPLICATIONTOOLS_H_
diff --git a/src/Bpp/BppBoolean.h b/src/Bpp/BppBoolean.h
new file mode 100644
index 0000000..25041ea
--- /dev/null
+++ b/src/Bpp/BppBoolean.h
@@ -0,0 +1,94 @@
+//
+// File: BppBoolean.h
+// Created by: Julien Dutheil
+// Created on: Fri 31 10:44 2010
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BPP_BOOLEAN_H_
+#define _BPP_BOOLEAN_H_
+
+#include "Clonable.h"
+
+// From the STL:
+#include <string>
+#include <ostream>
+
+namespace bpp
+{
+
+/**
+ * @brief The BppBoolean object class.
+ *
+ * This class extends the bool type to support the Clonable interface.
+ */
+class BppBoolean: public virtual Clonable
+{
+  private:
+    bool value_;
+
+	public:
+		
+		BppBoolean(): value_(false) {}
+		BppBoolean(bool value): value_(value) {}
+		virtual ~BppBoolean() {}
+	
+	public:
+	
+		/**
+		 * @name The Clonable interface.
+		 *
+		 * @{
+		 */
+#ifdef NO_VIRTUAL_COV
+    Clonable*
+#else
+		BppBoolean*
+#endif
+    clone() const { return new BppBoolean(*this); }
+		/** @} */
+
+    const bool getValue() const { return value_; }
+    
+};
+
+std::ostream& operator<<(std::ostream& out, const BppBoolean& s) {
+  return out << s.getValue();
+}
+
+} //end of namespace bpp.
+
+#endif	//_BPP_BOOLEAN_H_
+
diff --git a/src/Bpp/BppString.cpp b/src/Bpp/BppString.cpp
new file mode 100644
index 0000000..5df0fcb
--- /dev/null
+++ b/src/Bpp/BppString.cpp
@@ -0,0 +1,50 @@
+//
+// File: BppString.cpp
+// Created by: Julien Dutheil
+// Created on: Thu May 04 10:21 2006
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "BppString.h"
+
+using namespace bpp;
+
+std::ostream& bpp::operator<<(std::ostream& out, const BppString& s)
+{
+  out << s.toSTL();
+  return out;
+}
+
+
diff --git a/src/Bpp/BppString.h b/src/Bpp/BppString.h
new file mode 100644
index 0000000..ef6c176
--- /dev/null
+++ b/src/Bpp/BppString.h
@@ -0,0 +1,95 @@
+//
+// File: BppString.h
+// Created by: Julien Dutheil
+// Created on: Thu May 04 10:21 2006
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BPP_STRING_H_
+#define _BPP_STRING_H_
+
+#include "Clonable.h"
+
+// From the STL:
+#include <string>
+#include <ostream>
+
+namespace bpp
+{
+
+/**
+ * @brief The BppString object class.
+ *
+ * This class extends the stl::string class to support the Clonable interface.
+ */
+class BppString: public virtual Clonable
+{
+  private:
+    std::string text_;
+
+	public:
+		
+		BppString(): text_() {}
+		BppString(const char* value): text_(value) {}
+		BppString(const std::string& value): text_(value) {}
+		BppString& operator=(const char* value) { text_ = value; return *this; }
+		BppString& operator=(const std::string& value) { text_ = value; return *this; }
+		virtual ~BppString() {}
+	
+	public:
+	
+		/**
+		 * @name The Clonable interface.
+		 *
+		 * @{
+		 */
+#ifdef NO_VIRTUAL_COV
+    Clonable*
+#else
+		BppString*
+#endif
+    clone() const { return new BppString(*this); }
+		/** @} */
+
+    const std::string& toSTL() const { return text_; }
+    
+};
+
+std::ostream& operator<<(std::ostream& out, const BppString& s);
+
+} //end of namespace bpp.
+
+#endif	//_BPP_STRING_H_
+
diff --git a/src/Bpp/BppVector.h b/src/Bpp/BppVector.h
new file mode 100644
index 0000000..8981a43
--- /dev/null
+++ b/src/Bpp/BppVector.h
@@ -0,0 +1,105 @@
+//
+// File: BppVector.h
+// Created by: Julien Dutheil
+// Created on: Mon Apr 07 15:14 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BPPVECTOR_H_
+#define _BPPVECTOR_H_
+
+#include "Clonable.h"
+
+// From the STL:
+#include <vector>
+
+namespace bpp
+{
+
+/**
+ * @brief The BppVector object class.
+ *
+ * This class extends the std::vector class to support the Clonable interface.
+ */
+template<class TYPE>
+class BppVector: public Clonable
+{
+  private:
+    std::vector<TYPE> vector_;
+
+  public:
+
+    BppVector():
+      vector_() {}
+    
+    BppVector(typename std::vector<TYPE>::size_type num, const TYPE& val = TYPE() ):
+      vector_(num, val) {}
+
+    BppVector(typename std::vector<TYPE>::iterator start, typename std::vector<TYPE>::iterator end):
+      vector_(start, end) {}
+
+    virtual ~BppVector() {}
+  
+  public:
+  
+    /**
+     * @name The Clonable interface.
+     *
+     * @{
+     */
+#ifdef NO_VIRTUAL_COV
+    Clonable*
+#else
+    BppVector<TYPE>*
+#endif
+    clone() const { return new BppVector<TYPE>(*this); }
+    /** @} */
+
+    const std::vector<TYPE>& toSTL() const { return vector_; }
+    
+    std::vector<TYPE>& toSTL() { return vector_; }
+
+    unsigned int size() const { return vector_.size(); }
+
+    TYPE& operator[] (unsigned int i) { return vector_[i]; }
+    
+    const TYPE& operator[] (unsigned int i) const { return vector_[i]; }
+  
+};
+
+} //end of namespace bpp.
+
+#endif  //_BPPVECTOR_H_
+
diff --git a/src/Bpp/Clonable.h b/src/Bpp/Clonable.h
new file mode 100644
index 0000000..4b803f7
--- /dev/null
+++ b/src/Bpp/Clonable.h
@@ -0,0 +1,120 @@
+//
+// File: Clonable.h
+// Created by: Julien Dutheil
+// Created on: Wed Nov 12 15:55:03 2003
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _CLONABLE_H_
+#define _CLONABLE_H_
+
+/**
+ * @mainpage
+ *
+ * @par
+ * This library contains Bio++ core interfaces, classes and functions.
+ * It provides a general interface called bpp::Clonable, which allows dynamic copy of objects.
+ * Wrapper classes for numbers, strings and vectors that implement this interface are provided, and called
+ * respectively bpp::Number, bpp::BppString and bpp::BppVector.
+ *
+ * @par
+ * The bpp::Exception class is the most general exception class used in Bio++, and provides only a single text information.
+ * Several more specialized exception classes are also provided, like
+ * - bpp::IOException for input/output errors, usually when reading from or writing to files,
+ * - bpp::NullPointerException when a NULL pointer is unexpectedly provided,
+ * - bpp::BadNumberException and bpp::BadIntegerException, dealing with number problems (bounds, format, etc),
+ * - and more...
+ *
+ * @par
+ * This library also includes several submodules:
+ * - The Text module contains: functions to deal with character strings (bpp::StringTokenizer and the bpp::TextTools static class),
+ * like pattern matching, concatenation, number conversion, etc.
+ * - The Graphics module provides support for graphical output. This includes the general bpp::GraphicDevice interface, with currently three implementations for XFig (bpp::XFigGraphicDevice), SVG (bpp::SVGGraphicDevice) and PGF (bpp::PGFGraphicDevice) formats.
+ * Classes to deal with colors and fonts were created (see bpp::RGBColor, bpp::ColorSet, bpp::ColorTools and bpp::Font).
+ * - The App module contains classes and tools that provide powerful methods to parse command-line options and more.
+ * - The Numeric module is quite large and provides interfaces, classes and functions for numerical calculus.
+ *   The tools included are general enough to be useful beyond biology.
+ *   The originality of this module, unless many existing libraries, is to be fully object-oriented.
+ *   Available methods include:
+ *   - Vector operations, based on the stl::vector class, see bpp::VectorTools,
+ *   - Matrix data and operations, see the bpp::Matrix interface and bpp::MatrixTools class,
+ *   - Functions are implemented using several general classes:
+ *     - the bpp::Function interface and its derivatives,
+ *     - the bpp::Parameter, bpp::Constraint and bpp::ParameterList classes, and the bpp::Parametrizable interface
+ *       provide a very general way to deal with parameters
+ *     - Function operations, see the bpp::Optimizer interface, and the bpp::AbstractNumericalDerivative class for
+ *       numerical differenciation,
+ *     - Discrete probability distributions are implemented via the bpp::DiscreteDistribution interface
+ *     - Several random numbers generators are available through the bpp::RandomNumberFactory interface, and the
+ *       bpp::RandomTools static class provides useful methods to deal with random numbers.
+ *     .
+ *   .
+ * .
+ */
+
+namespace bpp
+{
+
+/**
+ * @brief The Clonable interface (allow an object to be cloned).
+ *
+ * A clone is a deep (or hard) copy of an object.
+ * This interface provides a method that dynamically creates a copy of itself
+ * and send a pointer toward it.
+ *
+ * This method allows an object to be copied when you do not now its class.
+ */
+class Clonable
+{
+	public:
+		
+		Clonable() {}
+	
+		virtual ~Clonable() {}
+	
+	public:
+		
+		/**
+		 * @brief Create a copy of this object and send a pointer to it.
+		 *
+		 * @return A pointer toward the copy object.
+		 */
+		virtual Clonable * clone() const = 0;
+};
+
+} //end of namespace bpp.
+
+#endif	//_CLONABLE_H_
+
diff --git a/src/Bpp/Exceptions.cpp b/src/Bpp/Exceptions.cpp
new file mode 100644
index 0000000..7b00a5d
--- /dev/null
+++ b/src/Bpp/Exceptions.cpp
@@ -0,0 +1,110 @@
+//
+// File Exceptions.cpp
+// Created by: Guillaume Deuchst
+//              Julien Dutheil
+//              Sylvain Gaillard
+// Last modification : Thu Jul 22 2004
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "Exceptions.h"
+#include "Text/TextTools.h"
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+  
+BadIntegerException::BadIntegerException(const char* text, int badInt):
+  Exception(string(text) + "(" + TextTools::toString(badInt) + ")"),
+  badInt_(badInt) {}
+
+BadIntegerException::BadIntegerException(const std::string& text, int badInt):
+  Exception(text + "(" + TextTools::toString(badInt) + ")"),
+  badInt_(badInt) {}
+
+/******************************************************************************/
+
+BadNumberException::BadNumberException(const char* text, double badNumber):
+  Exception(string(text) + "(" + TextTools::toString(badNumber) + ")"),
+  badNumber_(badNumber) {}
+
+BadNumberException::BadNumberException(const std::string& text, double badNumber):
+  Exception(text + "(" + TextTools::toString(badNumber) + ")"),
+  badNumber_(badNumber) {}
+
+/******************************************************************************/
+
+NumberFormatException::NumberFormatException(const char* text, const std::string& badNumber):
+  Exception(string(text) + "(" + badNumber + ")"),
+  badNumber_(badNumber) {}
+
+NumberFormatException::NumberFormatException(const std::string& text, const std::string& badNumber):
+  Exception(text + "(" + badNumber + ")"),
+  badNumber_(badNumber) {}
+
+/******************************************************************************/
+  
+IndexOutOfBoundsException::IndexOutOfBoundsException(const std::string& text, size_t badInt, size_t lowerBound, size_t upperBound):
+  Exception("out of [" + TextTools::toString(lowerBound) + ", " + TextTools::toString(upperBound) +  "])" + text),
+  badIndex_(badInt),
+  lowerBound_(lowerBound),
+  upperBound_(upperBound) {}
+
+vector<size_t> IndexOutOfBoundsException::getBounds() const
+{
+  vector<size_t> bounds(2);
+  bounds[0] = lowerBound_;
+  bounds[1] = upperBound_;
+  return bounds;
+}
+
+/******************************************************************************/
+  
+BadSizeException::BadSizeException(const std::string& text, size_t badSize, size_t correctSize):
+  Exception("Incorrect size " + TextTools::toString(badSize) + ", expected " + TextTools::toString(correctSize) + ". " + text),
+  badSize_(badSize),
+  correctSize_(correctSize) {}
+
+/******************************************************************************/
+
+OutOfRangeException::OutOfRangeException(const std::string& text, double badValue, double lowerBound, double upperBound):
+  Exception(TextTools::toString(badValue) + " out of [" + TextTools::toString(lowerBound) + ", " + TextTools::toString(upperBound) +  "])" + text),
+  lowerBound_(lowerBound),
+  upperBound_(upperBound)
+{}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Exceptions.h b/src/Bpp/Exceptions.h
new file mode 100644
index 0000000..2ac2c53
--- /dev/null
+++ b/src/Bpp/Exceptions.h
@@ -0,0 +1,419 @@
+//
+// File Exceptions.h
+// Created by: Guillaume Deuchst
+//              Julien Dutheil
+//              Sylvain Gaillard
+// Last modification : Thu Jul 22 2004
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _EXCEPTIONS_H_
+#define _EXCEPTIONS_H_
+
+#include <stdexcept>
+#include <vector>
+
+namespace bpp
+{
+
+/**
+ * @brief Exception base class.
+ *
+ * Overload exception constructor (to control the exceptions mechanism).</p>
+ */
+class Exception:
+  public std::exception
+{
+  protected:
+    std::string message_;
+  
+  public:
+    /**
+     * @brief Build a new Exception.
+     *
+     * @param text A message to be passed to the exception hierarchy.
+     */
+    Exception(const char* text): message_(std::string(text)) {}
+
+    /**
+     * @brief Build a new Exception.
+     *
+     * @param text A message to be passed to the exception hierarchy.
+     */
+    Exception(const std::string& text): message_(text) {}
+  
+    virtual ~Exception() throw() {}
+
+  public:
+    
+    /**
+     * @brief Method to get the message of the exception (STL method redefinition).
+     *
+     * @return The message passed to the exception hierarchy.
+     */
+    const char* what() const throw() { return message_.c_str(); }
+};
+
+
+/**
+ * @brief The base class exception for IO error.
+ */
+class IOException:
+  public Exception
+{
+  public: // Class constructors and destructor:
+    
+    /**
+     * @brief Build a new IOException.
+     *
+     * @param text A message to be passed to the exception hierarchy.
+     */
+    IOException(const char* text): Exception(text) {}
+
+    /**
+     * @brief Build a new IOException.
+     *
+     * @param text A message to be passed to the exception hierarchy.
+     */
+    IOException(const std::string& text): Exception(text) {} 
+  
+    virtual ~IOException() throw() {}
+
+};
+
+
+/**
+ * @brief The base class exception for NULL pointer error.
+ *
+ * This exception may be thrown when an unexpected NULL pointer is found.
+ */
+class NullPointerException:
+  public Exception
+{
+  public:
+
+    /**
+     * @brief Build a new NullPointerException.
+     *
+     * @param text A message to be passed to the exception hierarchy.
+     */
+    NullPointerException(const char* text): Exception(text) {}
+
+    /**
+     * @brief Build a new NullPointerException.
+     *
+     * @param text A message to be passed to the exception hierarchy.
+     */
+    NullPointerException(const std::string& text): Exception(text) {}
+
+    virtual ~NullPointerException() throw() {}
+};
+
+
+/**
+ * @brief The base class exception for zero division error.
+ */
+class ZeroDivisionException:
+  public Exception
+{
+  public:
+
+    /**
+     * @brief Build a new ZeroDivisionException.
+     *
+     * @param text A message to be passed to the exception hierarchy.
+     */
+    ZeroDivisionException(const char* text): Exception(text) {}
+
+    /**
+     * @brief Build a new ZeroDivisionException.
+     *
+     * @param text A message to be passed to the exception hierarchy.
+     */
+    ZeroDivisionException(const std::string& text): Exception(text) {}
+
+    virtual ~ZeroDivisionException() throw() {}
+};
+
+  
+/**
+ * @brief Number exception: integers.
+ */
+class BadIntegerException:
+  public Exception
+{
+  protected:
+    int badInt_;
+  
+  public:
+    
+    /**
+     * @brief Build a new BadIntegerException.
+     *
+     * @param text   A message to be passed to the exception hierarchy.
+     * @param badInt The faulty integer.
+     */
+    BadIntegerException(const char* text, int badInt);
+
+    /**
+     * @brief Build a new BadIntegerException.
+     *
+     * @param text   A message to be passed to the exception hierarchy.
+     * @param badInt The faulty integer.
+     */
+    BadIntegerException(const std::string& text, int badInt);
+  
+    virtual ~BadIntegerException() throw() {}
+
+  public:
+    
+    /**
+     * @brief Get the integer that threw this exception.
+     *
+     * @return The faulty integer.
+     */
+    int getBadInteger() const { return badInt_; }
+  
+};
+
+
+/**
+ * @brief Number exception: doubles.
+ */
+class BadNumberException:
+  public Exception
+{
+  protected:
+    double badNumber_;
+  
+  public:
+    
+    /**
+     * @brief Build a new BadNumberException.
+     *
+     * @param text      A message to be passed to the exception hierarchy.
+     * @param badNumber The faulty number.
+     */
+    BadNumberException(const char* text, double badNumber);
+
+    /**
+     * @brief Build a new BadNumberException.
+     *
+     * @param text      A message to be passed to the exception hierarchy.
+     * @param badNumber The faulty number.
+     */
+    BadNumberException(const std::string& text, double badNumber);
+  
+    virtual ~BadNumberException() throw() {}
+
+  public:
+    
+    /**
+     * @brief Get the number that threw this exception.
+     *
+     * @return The faulty number.
+     */
+    double getBadNumber() const { return badNumber_; }
+  
+};
+
+
+/**
+ * @brief Number format exception.
+ */
+class NumberFormatException:
+  public Exception
+{
+  protected:
+    std::string badNumber_;
+  
+  public:
+    
+    /**
+     * @brief Build a new NumberFormatException.
+     *
+     * @param text      A message to be passed to the exception hierarchy.
+     * @param badNumber The faulty number.
+     */
+    NumberFormatException(const char* text, const std::string& badNumber);
+
+    /**
+     * @brief Build a new NumberFormatException.
+     *
+     * @param text      A message to be passed to the exception hierarchy.
+     * @param badNumber The faulty number.
+     */
+    NumberFormatException(const std::string& text, const std::string& badNumber);
+  
+    virtual ~NumberFormatException() throw() {}
+
+  public:
+    
+    /**
+     * @brief Get the number that threw this exception.
+     *
+     * @return The faulty number.
+     */
+    std::string getBadNumber() const { return badNumber_; }
+  
+};
+
+
+/**
+ * @brief Index out of bounds exception class.
+ */
+class IndexOutOfBoundsException:
+  public virtual Exception
+{
+  protected:
+    size_t badIndex_, lowerBound_, upperBound_;
+  
+  public:
+
+    /**
+     * @brief Build a new IndexOutOfBoundsException.
+     *
+     * @param text   A message to be passed to the exception hierarchy.
+     * @param badInt The faulty integer.
+     * @param lowerBound Lower limit.
+     * @param upperBound Upper limit.
+     */
+    IndexOutOfBoundsException(const std::string& text, size_t badInt, size_t lowerBound, size_t upperBound);
+  
+    virtual ~IndexOutOfBoundsException() throw() {}
+
+  public:
+    
+    /**
+     * @brief Get the bounds.
+     *
+     * @return The bounds.
+     */
+    std::vector<size_t> getBounds() const;
+
+    size_t getBadIndex() const { return badIndex_; }
+};
+
+
+/**
+ * @brief Wrong size exception class.
+ */
+class BadSizeException:
+  public virtual Exception
+{
+  protected:
+    size_t badSize_, correctSize_;
+  
+  public:
+    
+    /**
+     * @brief Build a new BadSizeException.
+     *
+     * @param text   A message to be passed to the exception hierarchy.
+     * @param badSize The faulty size.
+     * @param correctSize The expected size.
+     */
+    BadSizeException(const std::string& text, size_t badSize, size_t correctSize);
+  
+    virtual ~BadSizeException() throw() {}
+
+  public:
+    
+    size_t getBadSize() const { return badSize_; }
+    size_t getCorrectSize() const { return correctSize_; }
+};
+
+
+/**
+ * @brief Out of range exception class.
+ */
+class OutOfRangeException:
+  public Exception
+{
+  protected:
+    double lowerBound_, upperBound_;
+  
+  public:
+    
+    /**
+     * @brief Build a new OutOfRangeException.
+     *
+     * @param text   A message to be passed to the exception hierarchy.
+     * @param badValue The faulty value.
+     * @param lowerBound Lower limit.
+     * @param upperBound Upper limit.
+     */
+    OutOfRangeException(const std::string& text, double badValue, double lowerBound, double upperBound);
+  
+    virtual ~OutOfRangeException() throw() {}
+
+  public:
+    
+    /**
+     * @return The lower bound.
+     */
+    double getLowerBound() const { return lowerBound_; }
+
+    /**
+     * @return The upper bound.
+     */
+    double getUpperBound() const { return upperBound_; }
+};
+
+
+/**
+ * @brief This expeption is sent when a given method is not implemented.
+ */
+class NotImplementedException:
+  public Exception
+{
+  public:
+
+    /**
+     * @brief Build a new NotImplementedException.
+     *
+     * @param text A message to be passed to the exception hierarchy.
+     */
+    NotImplementedException(const std::string& text): Exception(text) {}
+
+    virtual ~NotImplementedException() throw() {}
+};
+
+
+
+} //end of namespace bpp.
+
+#endif // _EXCEPTIONS_H_
+
diff --git a/src/Bpp/Graph/BasicONode.cpp b/src/Bpp/Graph/BasicONode.cpp
new file mode 100644
index 0000000..97e0ec9
--- /dev/null
+++ b/src/Bpp/Graph/BasicONode.cpp
@@ -0,0 +1,43 @@
+// 
+// File:    BasicONode.cpp
+// Author:  Sylvain Gaillard
+// Created: 14/01/2011 14:59:07
+// 
+
+/*
+Copyright or © or Copr. CNRS, (January 12, 2011)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "BasicONode.h"
+
+using namespace bpp;
+
diff --git a/src/Bpp/Graph/BasicONode.h b/src/Bpp/Graph/BasicONode.h
new file mode 100644
index 0000000..535fd6a
--- /dev/null
+++ b/src/Bpp/Graph/BasicONode.h
@@ -0,0 +1,59 @@
+// 
+// File:    BasicONode.h
+// Author:  Sylvain Gaillard
+// Created: 13/01/2011 16:34:44
+// 
+
+/*
+Copyright or © or Copr. CNRS, (January 12, 2011)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BPP_GRAPH_BASICONODE_H_
+#define _BPP_GRAPH_BASICONODE_H_
+
+#include "ONode.h"
+
+namespace bpp {
+  /**
+   * @brief Simple implementation of ONode
+   *
+   * Contains only methods for node manipulation.
+   *
+   * @warning Class not implemented yet!
+   *
+   * @author Sylvain Gaillard
+   */
+  class BasicONode: public ONode {
+  };
+}
+
+#endif //_BPP_GRAPH_BASICONODE_H_
diff --git a/src/Bpp/Graph/BasicTNode.cpp b/src/Bpp/Graph/BasicTNode.cpp
new file mode 100644
index 0000000..7033b40
--- /dev/null
+++ b/src/Bpp/Graph/BasicTNode.cpp
@@ -0,0 +1,204 @@
+// 
+// File:    BasicTNode.cpp
+// Author:  Sylvain Gaillard
+// Created: 14/01/2011 14:59:07
+// 
+
+/*
+Copyright or © or Copr. CNRS, (January 12, 2011)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "BasicTNode.h"
+
+using namespace bpp;
+
+BasicTNode::~BasicTNode() {
+  if (father_) {
+    father_->removeSon(this);
+  }
+  for (size_t i = 0 ; i < sons_.size() ; i++) {
+    sons_[i]->removeFather();
+  }
+}
+
+BasicTNode::BasicTNode(const BasicTNode& node):
+  sons_(node.sons_),
+  father_(node.father_)
+{};
+
+BasicTNode& BasicTNode::operator=(const BasicTNode& node) {
+  sons_ = node.sons_;
+  father_ = node.father_;
+  return * this;
+}
+
+// Neighbors
+
+const BasicTNode* BasicTNode::getNeighbor(int pos) const {
+  if (pos < 0 || pos > static_cast<int>(sons_.size())) {
+    throw IndexOutOfBoundsException("BasicTNode::getNeighbor() pos is out of bounds", pos, 0, static_cast<int>(sons_.size()));
+  }
+  if (pos == 0)
+    return father_;
+  else
+    return sons_[static_cast<size_t>(pos - 1)];
+}
+
+BasicTNode* BasicTNode::getNeighbor(int pos) {
+  if (pos < 0 || pos > static_cast<int>(sons_.size())) {
+    throw IndexOutOfBoundsException("BasicTNode::getNeighbor() pos is out of bounds", pos, 0, static_cast<int>(sons_.size()));
+  }
+  if (pos == 0)
+    return father_;
+  else
+    return sons_[static_cast<size_t>(pos - 1)];
+}
+
+const BasicTNode* BasicTNode::operator[](int i) const {
+  if (i < 0) {
+    return father_;
+  } else {
+    return sons_[static_cast<size_t>(i)];
+  }
+}
+
+BasicTNode* BasicTNode::operator[](int i) {
+  if (i < 0) {
+    return father_;
+  } else {
+    return sons_[static_cast<size_t>(i)];
+  }
+}
+
+// Fathers
+
+const BasicTNode* BasicTNode::getFather(int pos) const {
+  if (pos != 0) {
+    throw IndexOutOfBoundsException("BasicTNode::getFather() pos must be 0 for TNode", pos, 0, 0);
+  }
+  return getFather();
+}
+
+BasicTNode* BasicTNode::getFather(int pos) {
+  if (pos != 0) {
+    throw IndexOutOfBoundsException("BasicTNode::getFather() pos must be 0 for TNode", pos, 0, 0);
+  }
+  return getFather();
+}
+
+const BasicTNode* BasicTNode::getFather() const {
+  return father_;
+}
+
+BasicTNode* BasicTNode::getFather() {
+  return father_;
+}
+
+bool BasicTNode::isFather(const BasicTNode* node) const {
+  if (father_ == node)
+    return true;
+  return false;
+}
+
+void BasicTNode::addFather(BasicTNode* node) {
+  if (!node)
+    throw NullPointerException("BasicTNode::addFather() Empty node given as input");
+  if (father_)
+    throw Exception("BasicTNode::addFather() This node already has a father.");
+  if (!isFather(node))
+    father_ = node;
+  if (!node->isSon(this))
+    node->addSon(this);
+}
+
+BasicTNode* BasicTNode::removeFather() {
+  if (hasFathers()) {
+    BasicTNode* father = father_;
+    father_ = 0;
+    father->removeSon(this);
+    return father;
+  }
+  return 0;
+}
+
+// Sons
+
+const BasicTNode* BasicTNode::getSon(int pos) const {
+  if (pos < 0 || pos > static_cast<int>(sons_.size()) - 1) {
+    throw IndexOutOfBoundsException("BasicTNode::getSon() pos out of range", pos, 0, sons_.size() - 1);
+  }
+  return sons_[static_cast<size_t>(pos)];
+}
+
+BasicTNode* BasicTNode::getSon(int pos) {
+  if (pos < 0 || pos > static_cast<int>(sons_.size()) - 1) {
+    throw IndexOutOfBoundsException("BasicTNode::getSon() pos out of range", pos, 0, sons_.size() - 1);
+  }
+  return sons_[static_cast<size_t>(pos)];
+}
+
+bool BasicTNode::isSon(const BasicTNode* node) const {
+  for (size_t i = 0 ; i < sons_.size() ; i++) {
+    if (sons_[i] == node)
+      return true;
+  }
+  return false;
+}
+
+void BasicTNode::addSon(BasicTNode* node) {
+  if (!node)
+    throw NullPointerException("BasicTNode::addSon() Empty node given as input.");
+  if (!isSon(node))
+    sons_.push_back(node);
+  if (!node->isFather(this))
+    node->addFather(this);
+}
+
+void BasicTNode::removeSon(BasicTNode* node) {
+  if (!node)
+    throw NullPointerException("BasicTNode::removeSon() Empty node given as input.");
+  for (size_t i = 0 ; i < sons_.size() ; i++) {
+    if (sons_[i] == node) {
+      sons_.erase(sons_.begin() + i);
+      node->removeFather();
+    }
+  }
+}
+
+BasicTNode* BasicTNode::removeSon(int pos) {
+  if (pos < 0 || pos > static_cast<int>(sons_.size() - 1))
+    throw IndexOutOfBoundsException("BasicTNode::removeSon() pos out of bound", pos, 0, sons_.size() - 1);
+  BasicTNode* node = sons_[static_cast<size_t>(pos)];
+  sons_.erase(sons_.begin() + pos);
+  node->removeFather();
+  return node;
+}
diff --git a/src/Bpp/Graph/BasicTNode.h b/src/Bpp/Graph/BasicTNode.h
new file mode 100644
index 0000000..585bddf
--- /dev/null
+++ b/src/Bpp/Graph/BasicTNode.h
@@ -0,0 +1,160 @@
+// 
+// File:    BasicTNode.h
+// Author:  Sylvain Gaillard
+// Created: 13/01/2011 16:39:23
+// 
+
+/*
+Copyright or © or Copr. CNRS, (January 12, 2011)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BPP_GRAPH_BASICTNODE_H_
+#define _BPP_GRAPH_BASICTNODE_H_
+
+#include "TNode.h"
+#include "../Exceptions.h"
+
+namespace bpp {
+  /**
+   * @brief Simple implementation of TNode
+   *
+   * Contains only methods for node manipulation.
+   *
+   * @author Sylvain Gaillard
+   */
+  class BasicTNode: public TNode {
+    private:
+      std::vector< BasicTNode * > sons_;
+      BasicTNode * father_;
+
+    public:
+      /**
+       * @brief Simple constructor.
+       */
+      BasicTNode(): sons_(), father_(0) {};
+
+      /**
+       * @brief Destructor.
+       *
+       * When destroyed, the node remove himself as son of its father and as
+       * father of its sons.
+       */
+      virtual ~BasicTNode();
+
+      /**
+       * @brief Copy constructor.
+       */
+      BasicTNode(const BasicTNode& node);
+
+      /**
+       * @brief Assignation operator.
+       */
+      BasicTNode& operator=(const BasicTNode& node);
+
+      BasicTNode* clone() const {
+        return new BasicTNode(* this);
+      }
+
+      // Neighbors
+
+      const BasicTNode* getNeighbor(int pos) const;
+      BasicTNode* getNeighbor(int pos);
+
+      int degree() const { return sons_.size() - 1 + father_ ? 1 : 0; }
+
+      const BasicTNode* operator[](int i) const;
+      BasicTNode* operator[](int i);
+
+      // Fathers
+
+      /**
+       * @brief Tell if the node has a father.
+       */
+      bool hasFather() const { return father_ ? true : false; }
+      bool hasFathers() const { return father_ ? true : false; }
+      int getNumberOfFathers() const { return father_ ? 1 : 0; }
+
+      const BasicTNode* getFather(int pos) const;
+      BasicTNode* getFather(int pos);
+      const BasicTNode* getFather() const;
+      BasicTNode* getFather();
+
+      /**
+       * @brief Tell if the node is a father of this node.
+       */
+      virtual bool isFather(const BasicTNode* node) const;
+
+      /**
+       * @brief Add a father to this node.
+       */
+      virtual void addFather(BasicTNode* node);
+
+      /**
+       * @brief Remove the father of this node.
+       *
+       * @return A pointer to the removed father node.
+       */
+      virtual BasicTNode* removeFather();
+
+      // Sons
+
+      bool hasSons() const { return !sons_.empty(); }
+      int getNumberOfSons() const { return static_cast<int>(sons_.size()); }
+      const BasicTNode* getSon(int pos) const;
+      BasicTNode* getSon(int pos);
+
+      /**
+       * @brief Tell if a node is son of this node.
+       */
+      virtual bool isSon(const BasicTNode* node) const;
+
+      /**
+       * @brief Add a son to this node.
+       */
+      virtual void addSon(BasicTNode* node);
+
+      /**
+       * @brief Remove a son of this node.
+       */
+      virtual void removeSon(BasicTNode* son);
+
+      /**
+       * @brief Remove a son of this node.
+       *
+       * @return A pointer to the removed son node or a Null pointer if son is
+       * not found.
+       */
+      virtual BasicTNode* removeSon(int pos);
+  };
+}
+
+#endif //_BPP_GRAPH_BASICTNODE_H_
diff --git a/src/Bpp/Graph/ONode.h b/src/Bpp/Graph/ONode.h
new file mode 100644
index 0000000..c7ec781
--- /dev/null
+++ b/src/Bpp/Graph/ONode.h
@@ -0,0 +1,170 @@
+// 
+// File:    ONode.h
+// Author:  Sylvain Gaillard
+// Created: 12/01/2011 08:36:47
+// 
+
+/*
+Copyright or © or Copr. CNRS, (January 12, 2011)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BPP_GRAPH_ONODE_H_
+#define _BPP_GRAPH_ONODE_H_
+
+#include "UNode.h"
+
+namespace bpp {
+  /**
+   * @brief Oriented Node interface
+   *
+   * ONode is an interface for oriented nodes aimed to build oriented graphs.
+   *
+   * @author Sylvain Gaillard
+   */
+  class ONode: public virtual UNode {
+    public:
+      /**
+       * @name Neighbors
+       *
+       * @{
+       */
+
+      virtual const ONode * getNeighbor(int pos) const = 0;
+      virtual ONode * getNeighbor(int pos) = 0;
+
+      /** @} */
+
+      /**
+       * @name The Clonable interface.
+       *
+       * @{
+       */
+#ifndef NO_VIRTUAL_COV      
+      ONode * clone() const = 0;
+#endif
+      /** @} */
+
+      /**
+       * @name Fathers
+       *
+       * @{
+       */
+
+      /**
+       * @brief Get a particular father in const environment.
+       */
+      virtual const ONode * getFather(int pos) const = 0;
+
+      /**
+       * @brief Get a particular father.
+       */
+      virtual ONode * getFather(int pos) = 0;
+
+      /**
+       * @brief Tell if this node has one or more father nodes.
+       */
+      virtual bool hasFathers() const = 0;
+
+      /**
+       * @brief Give the number of father nodes for this node.
+       */
+      virtual int getNumberOfFathers() const = 0;
+
+      /** @} */
+
+      /**
+       * @name Sons
+       *
+       * @{
+       */
+
+      /**
+       * @brief Get a particular son in const environment.
+       */
+      virtual const ONode * getSon(int pos) const = 0;
+
+      /**
+       * @brief Get a particular son.
+       */
+      virtual ONode * getSon(int pos) = 0;
+
+      /**
+       * @brief Tell if this node has one or more son nodes.
+       */
+      virtual bool hasSons() const = 0;
+
+      /**
+       * @brief Give the number of son nodes for this node.
+       */
+      virtual int getNumberOfSons() const = 0;
+
+      /** @} */
+
+      /**
+       * @name Operators
+       *
+       * @{
+       */
+
+      /**
+       * @brief Direct access to a neighbor in const context.
+       *
+       * - a positive i gives access to sons (from 0 to n - 1)
+       * - a negative i gives access to fathers (from 1 to m)
+       *
+       * No check is done, you have to ensure that you query an existing
+       * neighbor.
+       *
+       * @param i the position of the neighbor
+       * @return A pointer toward the neighbor
+       */
+      virtual const ONode * operator[] (int i) const = 0;
+
+      /**
+       * @brief Direct access to a neighbor.
+       *
+       * - a positive i gives access to sons (from 0 to n - 1)
+       * - a negative i gives access to fathers (from 1 to m)
+       *
+       * No check is done, you have to ensure that you query an existing
+       * neighbor.
+       *
+       * @param i the position of the neighbor
+       * @return A pointer toward the neighbor
+       */
+      virtual ONode * operator[] (int i) = 0;
+
+      /** @} */
+  };
+}
+
+#endif //_BPP_GRAPH_ONODE_H_
diff --git a/src/Bpp/Graph/TNode.h b/src/Bpp/Graph/TNode.h
new file mode 100644
index 0000000..71eecf5
--- /dev/null
+++ b/src/Bpp/Graph/TNode.h
@@ -0,0 +1,129 @@
+// 
+// File:    TNode.h
+// Author:  Sylvain Gaillard
+// Created: 12/01/2011 08:43:15
+// 
+
+/*
+Copyright or © or Copr. CNRS, (January 12, 2011)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BPP_GRAPH_TNODE_H_
+#define _BPP_GRAPH_TNODE_H_
+
+#include "ONode.h"
+
+namespace bpp {
+  /**
+   * @brief Tree Node interface
+   *
+   * TNode is an interface for tree nodes (i.e. oriented nodes with only one
+   * father). It is aimed to build trees.
+   *
+   * @author Sylvain Gaillard
+   */
+  class TNode: public virtual ONode {
+    public:
+      /**
+       * @name Neighbors
+       *
+       * @{
+       */
+
+      /**
+       * @copydoc bpp::ONode::getNeighbor(int) const
+       */
+      virtual const TNode * getNeighbor(int pos) const = 0;
+
+      /**
+       * @copydoc bpp::ONode::getNeighbor(int)
+       */
+      virtual TNode * getNeighbor(int pos) = 0;
+
+      /** @} */
+
+      /**
+       * @name The Clonable interface.
+       *
+       * @{
+       */
+#ifndef NO_VIRTUAL_COV      
+      TNode * clone() const = 0;
+#endif
+      /** @} */
+
+      /**
+       * @name Fathers
+       *
+       * @{
+       */
+
+      virtual const TNode * getFather(int pos) const = 0;
+      virtual TNode * getFather(int pos) = 0;
+
+      /**
+       * @brief Get the father in const environment.
+       */
+      virtual const TNode * getFather() const = 0;
+
+      /**
+       * @brief Get the father.
+       */
+      virtual TNode * getFather() = 0;
+
+      /** @} */
+
+      /**
+       * @name Sons
+       *
+       * @{
+       */
+
+      virtual const TNode * getSon(int pos) const = 0;
+      virtual TNode * getSon(int pos) = 0;
+
+      /** @} */
+
+      /**
+       * @name Operators
+       *
+       * @{
+       */
+
+      virtual const TNode * operator[] (int i) const = 0;
+      virtual TNode * operator[] (int i) = 0;
+
+      /** @} */
+  };
+}
+
+#endif //_BPP_GRAPH_TNODE_H_
diff --git a/src/Bpp/Graph/UNode.h b/src/Bpp/Graph/UNode.h
new file mode 100644
index 0000000..86053a5
--- /dev/null
+++ b/src/Bpp/Graph/UNode.h
@@ -0,0 +1,123 @@
+// 
+// File:    UNode.h
+// Author:  Sylvain Gaillard
+// Created: 12/01/2011 08:33:55
+// 
+
+/*
+Copyright or © or Copr. CNRS, (January 12, 2011)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BPP_GRAPH_UNODE_H_
+#define _BPP_GRAPH_UNODE_H_
+
+#include "../Clonable.h"
+
+// From the STL
+#include <vector>
+
+namespace bpp {
+  /**
+   * @brief Unoriented node interface
+   *
+   * UNode is an interface for unoriented nodes aimed to build unoriented
+   * graphs.
+   *
+   * In these classes we choose to use int for positions rathed than size_t
+   * because negative positions are used in some implementations to distinguish
+   * between two types of neighbors in operator[]. @see bpp::ONode
+   *
+   * @author Sylvain Gaillard
+   */
+  class UNode: public virtual Clonable {
+    public:
+      /**
+       * @name Neighbors
+       *
+       * @{
+       */
+
+      /**
+       * @brief Get a neighbor of this node in const context.
+       *
+       * @param pos the position of the neighbor to get.
+       * @return A pointer toward the neighbor node.
+       */
+      virtual const UNode * getNeighbor(int pos) const = 0;
+
+      /**
+       * @brief Get a neighbor of this node.
+       *
+       * @param pos the position of the neighbor to get.
+       * @return A pointer toward the neighbor node.
+       */
+      virtual UNode * getNeighbor(int pos) = 0;
+
+      /**
+       * @brief Get the degree i.e. the number of neighbors of this node.
+       */
+      virtual int degree() const = 0;
+
+      /** @} */
+
+      /**
+       * @name The Clonable interface.
+       *
+       * @{
+       */
+#ifndef NO_VIRTUAL_COV      
+      UNode * clone() const = 0;
+#endif
+      /** @} */
+
+      /**
+       * @name Operators
+       *
+       * @{
+       */
+
+      /**
+       * @brief Direct access to a neighbor in const context.
+       */
+      virtual const UNode * operator[] (int i) const = 0;
+
+      /**
+       * @brief Direct access to a neighbor.
+       */
+      virtual UNode * operator[] (int i) = 0;
+
+      /** @} */
+
+  };
+}
+
+#endif //_BPP_GRAPH_UNODE_H_
diff --git a/src/Bpp/Graphics/AbstractGraphicDevice.h b/src/Bpp/Graphics/AbstractGraphicDevice.h
new file mode 100644
index 0000000..961945f
--- /dev/null
+++ b/src/Bpp/Graphics/AbstractGraphicDevice.h
@@ -0,0 +1,112 @@
+//
+// File: AbstractGraphicDevice.h
+// Created by: Julien Dutheil
+// Created on: Fri Jul 24 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 16, 2006)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _ABSTRACTGRAPHICDEVICE_H_
+#define _ABSTRACTGRAPHICDEVICE_H_
+
+#include "GraphicDevice.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Partial implementation of the GraphicDevice interface.
+ *
+ * Implement this interface to support new formats.
+ */
+class AbstractGraphicDevice:
+  public virtual GraphicDevice
+{
+  private:
+    double xUnit_;
+    double yUnit_;
+    RGBColor fgColor_;
+    RGBColor bgColor_;
+    Font font_;
+    unsigned int pointSize_;
+    short lineType_;
+    int currentLayer_;
+
+  public:
+    AbstractGraphicDevice(): xUnit_(1.), yUnit_(1.),
+        fgColor_(0, 0, 0), bgColor_(0, 0, 0), font_(), pointSize_(1), lineType_(LINE_SOLID), currentLayer_(-1) 
+    {}
+
+    virtual ~AbstractGraphicDevice() {}
+
+  public:
+    void setXUnit(double xu) { xUnit_ = xu; }
+    void setYUnit(double yu) { yUnit_ = yu; }
+    double getXUnit() const { return xUnit_; }
+    double getYUnit() const { return yUnit_; }
+
+    void setCurrentForegroundColor(const RGBColor& color) { fgColor_ = color; }
+    void setCurrentBackgroundColor(const RGBColor& color) { bgColor_ = color; }
+    void setCurrentFont(const Font& font) { font_ = font; }
+    void setCurrentPointSize(unsigned int size) { pointSize_ = size; }
+    void setCurrentLineType(short type) throw (Exception)
+    { 
+      if       (type == LINE_SOLID) lineType_ = type;
+      else if (type == LINE_DASHED) lineType_ = type;
+      else if (type == LINE_DOTTED) lineType_ = type;
+      else throw Exception("AbstractGraphicDevice::setCurrentLineType. Unknown line type: " + TextTools::toString(type));
+    }
+    void setCurrentLayer(int layerIndex) { currentLayer_ = layerIndex; }
+
+    const RGBColor& getCurrentForegroundColor() const { return fgColor_; }
+    const RGBColor& getCurrentBackgroundColor() const { return bgColor_; }
+    const Font& getCurrentFont() const { return font_; }
+    unsigned int getCurrentPointSize() const { return pointSize_; }
+    short getCurrentLineType() const { return lineType_; }
+    int getCurrentLayer() const { return currentLayer_; }
+ 
+
+  protected:
+    double x_(double x) const { return x * xUnit_; }
+    double y_(double y) const { return y * yUnit_; }
+
+    double revx_(double x) const { return x / xUnit_; }
+    double revy_(double y) const { return y / yUnit_; }
+
+};
+
+} //end of namespace bpp;
+
+#endif //_ABSTRACTGRAPHICDEVICE_H_
+
diff --git a/src/Bpp/Graphics/ColorManager.h b/src/Bpp/Graphics/ColorManager.h
new file mode 100644
index 0000000..7666026
--- /dev/null
+++ b/src/Bpp/Graphics/ColorManager.h
@@ -0,0 +1,191 @@
+//
+// File: ColorManager.h
+// Created by: Julien Dutheil
+// Created on: Mon May 08 2006
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _COLORMANAGER_H_
+#define _COLORMANAGER_H_
+
+#include "RgbColor.h"
+#include "ColorTools.h"
+#include "../Text/TextTools.h"
+
+// From the STL:
+#include <vector>
+
+namespace bpp
+{
+
+  /**
+   * @brief Associate special colors to a code.
+   *
+   * Instances of this interface are used in some vector format.
+   */
+  template<class CodeType>
+    class ColorManager
+    {
+      public:
+        ColorManager() {}
+        virtual ~ColorManager() {}
+
+      public:
+
+        /**
+         * @param color The color to look for.
+         * @return The code associated to a given color.
+         */
+        virtual CodeType getCode(const RGBColor& color) = 0;
+
+        /**
+         * @param code The code to look for.
+         * @return The color associated to a given code.
+         * @throw exception if the code is not valid.
+         */
+        virtual const RGBColor& getColor(CodeType& code) const throw (Exception) = 0;
+
+        /**
+         * @return All valid codes.
+         */
+        virtual const std::vector<CodeType>& getCodes() const = 0;
+
+        /**
+         * @return All available colors.
+         */
+        virtual const std::vector<RGBColor>& getColors() const = 0;
+
+        /**
+         * @return The total number of colors available.
+         */
+        virtual size_t getNumberOfColors() const = 0;
+    };
+
+
+
+
+
+  /**
+   * @brief Color manager for the XFig format.
+   *
+   * Default colors are coded from 0 to 31.
+   * New colors may be added from code 32.
+   */
+  class XFigColorManager:
+    public ColorManager<unsigned int>
+  {
+    protected:
+      unsigned int currentCode_;
+      std::vector<RGBColor> colors_;
+      std::vector<unsigned int> codes_;
+
+    public:
+      XFigColorManager():
+        currentCode_(31),
+        colors_(),
+        codes_()
+    {
+      // Add "official" color codes, from 0 to 31:
+      codes_.push_back(0); colors_.push_back(ColorTools::BLACK);
+      codes_.push_back(1); colors_.push_back(ColorTools::BLUE);
+      codes_.push_back(2); colors_.push_back(ColorTools::GREEN);
+      codes_.push_back(3); colors_.push_back(ColorTools::CYAN);
+      codes_.push_back(4); colors_.push_back(ColorTools::RED);
+      codes_.push_back(5); colors_.push_back(ColorTools::MAGENTA);
+      codes_.push_back(6); colors_.push_back(ColorTools::YELLOW);
+      codes_.push_back(7); colors_.push_back(ColorTools::WHITE);
+      codes_.push_back(8); colors_.push_back(RGBColor(0,0,140));
+      codes_.push_back(9); colors_.push_back(RGBColor(0,0,173));
+      codes_.push_back(10); colors_.push_back(RGBColor(0,0,206));
+      codes_.push_back(11); colors_.push_back(RGBColor(132,207,205));
+      codes_.push_back(12); colors_.push_back(RGBColor(0,142,0));
+      codes_.push_back(13); colors_.push_back(RGBColor(0,174,0));
+      codes_.push_back(14); colors_.push_back(RGBColor(0,207,0));
+      codes_.push_back(15); colors_.push_back(RGBColor(0,142,140));
+      codes_.push_back(16); colors_.push_back(RGBColor(0,174,173));
+      codes_.push_back(17); colors_.push_back(RGBColor(0,207,206));
+      codes_.push_back(18); colors_.push_back(RGBColor(140,0,0));
+      codes_.push_back(19); colors_.push_back(RGBColor(173,0,0));
+      codes_.push_back(20); colors_.push_back(RGBColor(206,0,0));
+      codes_.push_back(21); colors_.push_back(RGBColor(140,0,140));
+      codes_.push_back(22); colors_.push_back(RGBColor(173,0,173));
+      codes_.push_back(23); colors_.push_back(RGBColor(206,0,206));
+      codes_.push_back(24); colors_.push_back(RGBColor(132,48,0));
+      codes_.push_back(25); colors_.push_back(RGBColor(156,65,0));
+      codes_.push_back(26); colors_.push_back(RGBColor(189,97,0));
+      codes_.push_back(27); colors_.push_back(RGBColor(255,130,132));
+      codes_.push_back(28); colors_.push_back(RGBColor(255,158,156));
+      codes_.push_back(29); colors_.push_back(RGBColor(255,190,189));
+      codes_.push_back(30); colors_.push_back(RGBColor(255,223,222));
+      codes_.push_back(31); colors_.push_back(RGBColor(255,215,0));
+    }
+      virtual ~XFigColorManager() {}
+
+    public:
+      unsigned int getCode(const RGBColor & color)
+      {
+        for (unsigned int i = 0; i < colors_.size(); i++)
+        {
+          if (colors_[i] == color)
+          {
+            return codes_[i];
+          }
+        }
+        currentCode_++;
+        colors_.push_back(color);
+        codes_.push_back(currentCode_);
+        return currentCode_;
+      }
+      const RGBColor& getColor(unsigned int &code) const throw (Exception)
+      {
+        for(unsigned int i = 0; i < codes_.size(); i++)
+        {
+          if(codes_[i] == code)
+          {
+            return colors_[i];
+          }
+        }
+        throw Exception("XFigColorManager::getColor. No color associated to this code: " + TextTools::toString(code));
+      }
+      const std::vector<unsigned int>& getCodes() const { return codes_; }
+      const std::vector<RGBColor>& getColors() const { return colors_; }
+      size_t getNumberOfColors() const { return colors_.size(); }
+
+  };
+
+} // end of namespace bpp;
+
+#endif //_COLORMANAGER_H_
+
diff --git a/src/Bpp/Graphics/ColorSet.h b/src/Bpp/Graphics/ColorSet.h
new file mode 100644
index 0000000..df880c1
--- /dev/null
+++ b/src/Bpp/Graphics/ColorSet.h
@@ -0,0 +1,132 @@
+//
+// File: ColorSet.h
+// Created by: Julien Dutheil
+// Created on: Mon Apr 14 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2008)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _COLORSET_H_
+#define _COLORSET_H_
+
+#include "RgbColor.h"
+#include "../Utils/MapTools.h"
+
+// From the STL:
+#include <vector>
+
+namespace bpp
+{
+
+/**
+ * @brief Specify a set of color definitions.
+ */
+class ColorSet
+{
+  public:
+    ColorSet() {}
+    virtual ~ColorSet() {}
+
+  public:
+
+    /**
+     * @brief Get the color object corresponding to a given name.
+     *
+     * @param name The name of the color to look for.
+     * @return The color associated to the given name.
+     * @throw Exception if the name is not assigned to any color.
+     */
+    virtual const RGBColor& getColor(const std::string& name) const throw (Exception) = 0;
+
+    /**
+     * @brief Get the ith color object in the set.
+     *
+     * @param index The index of the color to look for.
+     * @return The color associated to the given index.
+     * @throw IndexOutOfBoundsException if the index is not assigned to any color.
+     */
+    virtual const RGBColor& getColor(unsigned int index) const throw (IndexOutOfBoundsException) = 0;
+
+    /**
+     * @return All valid color names.
+     */
+    virtual std::vector<std::string> getColorNames() const = 0;
+  
+    /**
+     * @return The total number of colors available.
+     */
+    virtual size_t getNumberOfColors() const = 0;
+};
+
+
+/**
+ * @brief Partial implementation of the ColorSet interface.
+ *
+ * Derivative classes just have to fill the colors_ map in the constructor of the class.
+ */
+class AbstractColorSet:
+  public ColorSet
+{
+  protected:
+    std::map<std::string, RGBColor> colors_;
+
+  public:
+    AbstractColorSet(): colors_() {}
+    virtual ~AbstractColorSet() {}
+
+  public:
+    const RGBColor& getColor(const std::string& name) const throw (Exception)
+    {
+      std::map<std::string, RGBColor>::const_iterator it = colors_.find(name);
+      if (it != colors_.end()) return it->second;
+      else throw Exception("AbstractColorSet::getColor(name): no color with name " + name);
+    }
+
+    const RGBColor& getColor(unsigned int index) const throw (IndexOutOfBoundsException)
+    {
+      if (index >= colors_.size()) throw IndexOutOfBoundsException("AbstractColorSet::getColor(index): invalid index.", index, 0, colors_.size() - 1);
+      std::map<std::string, RGBColor>::const_iterator it = colors_.begin();
+      for (unsigned int i = 0; i < index; i++) it++;
+      return it->second;
+    }
+    
+    std::vector<std::string> getColorNames() const { return MapTools::getKeys(colors_); }
+    
+    size_t getNumberOfColors() const { return colors_.size(); }
+};
+
+} // end of namespace bpp;
+
+#endif //_COLORSET_H_
+
diff --git a/src/Bpp/Graphics/ColorTools.cpp b/src/Bpp/Graphics/ColorTools.cpp
new file mode 100644
index 0000000..19ef7b7
--- /dev/null
+++ b/src/Bpp/Graphics/ColorTools.cpp
@@ -0,0 +1,86 @@
+//
+// File: ColorTools.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Mar 16 2006
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "ColorTools.h"
+
+using namespace std;
+using namespace bpp;
+
+const RGBColor ColorTools::RED    = RGBColor(255,0,0);
+const RGBColor ColorTools::GREEN  = RGBColor(0,255,0);
+const RGBColor ColorTools::BLUE   = RGBColor(0,0,255);
+const RGBColor ColorTools::BLACK  = RGBColor(0,0,0);
+const RGBColor ColorTools::WHITE  = RGBColor(255,255,255);
+const RGBColor ColorTools::YELLOW = RGBColor(255,255,0);
+const RGBColor ColorTools::CYAN   = RGBColor(0,255,255);
+const RGBColor ColorTools::MAGENTA = RGBColor(255,0,255);
+const RGBColor ColorTools::ORANGE = RGBColor(255,127,0);
+
+/******************************************************************************/
+
+std::vector<RGBColor> ColorTools::gradient(unsigned int n, const RGBColor & low, const RGBColor & high) 
+{
+  vector<RGBColor> colors(n);
+  for(unsigned int i = 0; i < n-1; i++)
+  {
+    colors[i][0] = low[0] + (int)floor((double)i*(double)((int)high[0] - (int)low[0])/(double)(n-1));
+    colors[i][1] = low[1] + (int)floor((double)i*(double)((int)high[1] - (int)low[1])/(double)(n-1));
+    colors[i][2] = low[2] + (int)floor((double)i*(double)((int)high[2] - (int)low[2])/(double)(n-1));
+  }
+  colors[n-1] = high;
+  return colors;
+}
+
+/******************************************************************************/
+
+std::vector<RGBColor> ColorTools::gradient(unsigned int n, const RGBColor & low, const RGBColor & mid, const RGBColor & high)
+{
+  unsigned int lower = n/2;
+  unsigned int upper = n - lower;
+  vector<RGBColor> colors1 = gradient(lower, low, mid);
+  vector<RGBColor> colors2 = gradient(upper+1, mid, high);
+  for(unsigned int i = 1; i < colors2.size(); i++)
+  {
+    colors1.push_back(colors2[i]);
+  }
+  return colors1;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Graphics/ColorTools.h b/src/Bpp/Graphics/ColorTools.h
new file mode 100644
index 0000000..79c8c30
--- /dev/null
+++ b/src/Bpp/Graphics/ColorTools.h
@@ -0,0 +1,133 @@
+//
+// File: ColorTools.h
+// Created by: Julien Dutheil
+// Created on: Thu Mar 16 2006
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _COLORTOOLS_H_
+#define _COLORTOOLS_H_
+
+#include "../Text/TextTools.h"
+#include "../Exceptions.h"
+#include "RgbColor.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Provide tools to deal with color objects.
+ */
+class ColorTools
+{
+  public:
+    ColorTools() {}
+    virtual ~ColorTools() {}
+
+  public:
+    /**
+     * @brief Create a set of colors according to a gradient defined by two extrema.
+     *
+     * @param n Number of colors to output.
+     * @param low First color in gradient.
+     * @param high Last color in gradient.
+     * @return A set of ordered colors defining a gradient.
+     */
+    static std::vector<RGBColor> gradient(unsigned int n, const RGBColor & low, const RGBColor & high);
+ 
+    /**
+     * @brief Create a set of colors according to a gradient defined by two extrema and a midpoint.
+     *
+     * @param n Number of colors to output.
+     * @param low First color in gradient.
+     * @param mid Midpoint color.
+     * @param high Last color in gradient.
+     * @return A set of ordered colors defining a gradient.
+     */
+    static std::vector<RGBColor> gradient(unsigned int n, const RGBColor & low, const RGBColor & mid, const RGBColor & high);
+    
+    /**
+     * @return A gray color.
+     * @param level Gray intensity ([0,1]).
+     */
+    static RGBColor gray(double level)
+    { 
+      unsigned int i = (unsigned int)round(255*level);
+      return RGBColor(i, i, i);
+    }
+
+    /**
+     * @brief Get a RGBColor from a cyan-magenta-yellow-key description.
+     *
+     * The following formula are used for the transformation:
+     * @f[
+     * \begin{array}{rcl}
+     * r &=& 255 * (1 - c)(1 - k)\\
+     * g &=& 255 * (1 - m)(1 - k)\\
+     * b &=& 255 * (1 - y)(1 - k)
+     * \end{array}
+     * @f]
+     *
+     * @param c Cyan proportion.
+     * @param m Magenta proportion.
+     * @param y Yellow proportion.
+     * @param k Black proportion.
+     * @return A RGBColor object.
+     */
+    static RGBColor cmyk2rgb(double c, double m, double y, double k)
+    {
+      unsigned int r = static_cast<unsigned int>(round(255 * (1. - c) * (1. - k)));
+      unsigned int g = static_cast<unsigned int>(round(255 * (1. - m) * (1. - k)));
+      unsigned int b = static_cast<unsigned int>(round(255 * (1. - y) * (1. - k)));
+      return RGBColor(r, g, b);
+    }
+ 
+  public:
+    static const RGBColor RED;
+    static const RGBColor GREEN;
+    static const RGBColor BLUE;
+    static const RGBColor BLACK;
+    static const RGBColor WHITE;
+    static const RGBColor YELLOW;
+    static const RGBColor CYAN;
+    static const RGBColor MAGENTA;
+    static const RGBColor ORANGE;
+    
+};
+
+} // end of namespace bpp.
+
+#endif //_COLORTOOLS_H_
+
diff --git a/src/Bpp/Graphics/DefaultColorSet.h b/src/Bpp/Graphics/DefaultColorSet.h
new file mode 100644
index 0000000..f7a60d3
--- /dev/null
+++ b/src/Bpp/Graphics/DefaultColorSet.h
@@ -0,0 +1,74 @@
+//
+// File: DefaultColorSet.h
+// Created by: Julien Dutheil
+// Created on: Mon Apr 14 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2008)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _DEFAULTCOLORSET_H_
+#define _DEFAULTCOLORSET_H_
+
+#include "ColorSet.h"
+#include "ColorTools.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Default color definitions.
+ */
+class DefaultColorSet:
+  public AbstractColorSet
+{
+  public:
+    DefaultColorSet()
+    {
+      colors_["black"]   = ColorTools::BLACK;
+      colors_["red"]     = ColorTools::RED;
+      colors_["green"]   = ColorTools::GREEN;
+      colors_["blue"]    = ColorTools::BLUE;
+      colors_["yellow"]  = ColorTools::YELLOW;
+      colors_["magenta"] = ColorTools::MAGENTA;
+      colors_["cyan"]    = ColorTools::CYAN;
+      colors_["white"]   = ColorTools::WHITE;
+    }
+    virtual ~DefaultColorSet() {}
+
+};
+
+} // end of namespace bpp;
+
+#endif //_DEFAULTCOLORSET_H_
+
diff --git a/src/Bpp/Graphics/Fig/XFigGraphicDevice.cpp b/src/Bpp/Graphics/Fig/XFigGraphicDevice.cpp
new file mode 100644
index 0000000..c1c062c
--- /dev/null
+++ b/src/Bpp/Graphics/Fig/XFigGraphicDevice.cpp
@@ -0,0 +1,194 @@
+//
+// File: XFigGraphicDevice.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Mar 03 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "XFigGraphicDevice.h"
+
+using namespace bpp;
+using namespace std;
+
+const unsigned int XFigGraphicDevice::FONTFLAG_LATEX = 0;
+const unsigned int XFigGraphicDevice::FONTFLAG_POSTSCRIPT = 4;
+
+void XFigGraphicDevice::begin()
+{
+  content_.clear();
+}
+
+void XFigGraphicDevice::end()
+{
+  //Print to file:
+  //Header:
+  out_ << "#FIG 3.2 Produced by the Bio++ Graphic Device System" << endl;
+  out_ << "Portrait" << endl;
+  out_ << "Flush left" << endl;
+  out_ << "Metric" << endl;
+  out_ << "A4" << endl;
+  out_ << "100" << endl;
+  out_ << "Single" << endl;
+  out_ << "0" << endl;
+  //out << "254 2" << endl; // 1fig unit = 0.1mm
+  out_ << "72 2" << endl; // 1fig unit = 1pt
+
+  // Color definitions:
+  out_ << "#Color definitions:" << endl; 
+  vector<unsigned int> codes = colorManager_.getCodes();
+  vector<RGBColor> colors    = colorManager_.getColors();
+  for(unsigned int i = 32; i < colorManager_.getNumberOfColors(); i++)
+  {
+    string hexCode = colors[i].toHex();
+    out_ << "0 " << codes[i] << " " << hexCode << endl;
+  }
+
+  // Print content:
+  out_ << "#Drawing content:" << endl; 
+  for(unsigned int i = 0; i < content_.size(); i++)
+  {
+    out_ << content_[i] << endl;
+  }
+}
+
+void XFigGraphicDevice::setCurrentForegroundColor(const RGBColor& color)
+{
+  fgColorCode_ = colorManager_.getCode(color);
+  AbstractGraphicDevice::setCurrentForegroundColor(color);
+}
+
+void XFigGraphicDevice::setCurrentBackgroundColor(const RGBColor& color)
+{
+  bgColorCode_ = colorManager_.getCode(color);
+  AbstractGraphicDevice::setCurrentBackgroundColor(color);
+}
+
+void XFigGraphicDevice::setCurrentFont(const Font& font)
+{
+  if (fontFlag_ == FONTFLAG_LATEX)
+    fontCode_ = latexFontManager_.getCode(font);
+  else if (fontFlag_ == FONTFLAG_POSTSCRIPT)
+    fontCode_ = postscriptFontManager_.getCode(font);
+  else
+    fontCode_ = 0;
+  fontSize_ = font.getSize();
+  AbstractGraphicDevice::setCurrentFont(font); 
+}
+
+void XFigGraphicDevice::drawLine(double x1, double y1, double x2, double y2)
+{
+  ostringstream oss;
+  oss << "2 1 " << lineTypeCode_ << " " << getCurrentPointSize()
+      << " " << fgColorCode_
+      << " " << bgColorCode_
+      << " " << getCurrentLayer()
+      << " " << "-1 -1 -1 0 0 0 0 0 2" << endl;
+  oss << round(x_(x1)) << " " << round(y_(y1)) << endl;
+  oss << round(x_(x2)) << " " << round(y_(y2));
+  content_.push_back(oss.str());
+}
+ 
+void XFigGraphicDevice::drawRect(double x, double y, double width, double height, short fill)
+{
+  ostringstream oss;
+  oss << "2 2 0 " << getCurrentPointSize()
+      << " " << fgColorCode_
+      << " " << bgColorCode_
+      << " " << getCurrentLayer()
+      << " " << "-1"
+      << " " << getFillCode(fill) << " -1 0 0 0 0 0 5" << endl;
+  oss << round(x) << " " << round(y) << endl;
+  oss << round(x_(x + width)) << " " << round(y_(y)) << endl;
+  oss << round(x_(x + width)) << " " << round(y_(y + height)) << endl;
+  oss << round(x_(x)) << " " << round(y_(y + height)) << endl;
+  oss << round(x_(x)) << " " << round(y_(y));
+  content_.push_back(oss.str());
+}
+
+void XFigGraphicDevice::drawCircle(double x, double y, double radius, short fill)
+{
+  ostringstream oss;
+  oss << "1 3 0 " << getCurrentPointSize()
+      << " " << fgColorCode_
+      << " " << bgColorCode_
+      << " " << getCurrentLayer()
+      << " " << "-1"
+      << " " << getFillCode(fill) << " -1 1 0 "
+      << round(x_(x)) << " " << round(y_(y)) << " "
+      << round(x_(radius)) << " " << round(y_(radius)) << " "
+      << round(x_(x + radius)) << " " << round(y_(y)) << " "
+      << round(x_(x + radius)) << " " << round(y_(y)) << endl;
+  content_.push_back(oss.str());
+}
+
+void XFigGraphicDevice::drawText(double x, double y, const std::string& text, short hpos, short vpos, double angle) throw (UnvalidFlagException)
+{
+  int xrel = static_cast<int>(round(x_(x)));
+  short sub = 0;
+  if (hpos == TEXT_HORIZONTAL_LEFT)
+    sub = 0;
+  else if (hpos == TEXT_HORIZONTAL_CENTER) 
+    sub = 1;
+  else if (hpos == TEXT_HORIZONTAL_RIGHT)
+    sub = 2;
+  else throw UnvalidFlagException("XFigGraphicDevice::drawText(). Bad horizontal text alignment flag: " + TextTools::toString(hpos));
+  
+  int yrel = 0;
+  if (vpos == TEXT_VERTICAL_BOTTOM)
+    yrel = static_cast<int>(round(y_(y - 1.)));
+  else if (vpos == TEXT_VERTICAL_CENTER)
+    yrel = static_cast<int>(round(y + fontSize_ / 2 - 1)); 
+  else if (vpos == TEXT_VERTICAL_TOP)
+    yrel = static_cast<int>(round(y - fontSize_)); 
+  else throw UnvalidFlagException("XFigGraphicDevice::drawText(). Bad vertical text alignment flag: " + TextTools::toString(vpos));
+
+  ostringstream oss;
+  oss << "4 " << sub << " " << fgColorCode_ << " " << 50 << " " << -1 << " " << fontCode_ << " " << fontSize_ << " " 
+      << angle << " " << fontFlag_ << " " << -1 << " " << -1 << " " << xrel << " " << yrel << " " << text << "\\001";
+  content_.push_back(oss.str());
+}
+
+int XFigGraphicDevice::getFillCode(short fill)
+{
+  if (fill == FILL_EMPTY) return -1;
+  if (fill == FILL_FILLED) return 20;
+  if (fill == FILL_PATTERN)
+  {
+    //TODO: define a field names currentPattern_, etc.
+  }
+  //Temp:
+  return 20;
+}
+
diff --git a/src/Bpp/Graphics/Fig/XFigGraphicDevice.h b/src/Bpp/Graphics/Fig/XFigGraphicDevice.h
new file mode 100644
index 0000000..dd70748
--- /dev/null
+++ b/src/Bpp/Graphics/Fig/XFigGraphicDevice.h
@@ -0,0 +1,133 @@
+//
+// File: XFigGraphicDevice.h
+// Created by: Julien Dutheil
+// Created on: Mon Mar 03 2008
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _XFIGGRAPHICDEVICE_H_
+#define _XFIGGRAPHICDEVICE_H_
+
+#include "../AbstractGraphicDevice.h"
+#include "../ColorManager.h"
+#include "XFigLaTeXFontManager.h"
+#include "XFigPostscriptFontManager.h"
+
+// From the STL:
+#include <map>
+#include <iostream>
+
+namespace bpp
+{
+
+/**
+ * @brief XFig plotting format.
+ */
+class XFigGraphicDevice:
+  public AbstractGraphicDevice
+{
+  private:
+    std::ostream& out_;
+    std::vector<std::string> content_;
+    XFigColorManager colorManager_;
+    XFigLaTeXFontManager latexFontManager_;
+    XFigPostscriptFontManager postscriptFontManager_;
+    unsigned int fgColorCode_;
+    unsigned int bgColorCode_;
+    int fontCode_; 
+    unsigned int fontSize_;
+    unsigned int fontFlag_;
+    unsigned int lineTypeCode_;
+
+  public:
+    XFigGraphicDevice(std::ostream& out):
+      out_(out),
+      content_(),
+      colorManager_(),
+      latexFontManager_(),
+      postscriptFontManager_(),
+      fgColorCode_(0),
+      bgColorCode_(0),
+      fontCode_(-1),
+      fontSize_(12),
+      fontFlag_(FONTFLAG_POSTSCRIPT),
+      lineTypeCode_(LINE_SOLID)
+    {
+      setCurrentLayer(0);
+    }
+
+    virtual ~XFigGraphicDevice() {}
+
+  public:
+    void begin();
+    void end();
+
+    void setCurrentForegroundColor(const RGBColor& color);
+    void setCurrentBackgroundColor(const RGBColor& color);
+    void setCurrentFont(const Font& font);
+    void setCurrentLineType(short type) throw (Exception)
+    { 
+      if(type == LINE_SOLID) lineTypeCode_ = 0;
+      else if(type == LINE_DASHED) lineTypeCode_ = 1;
+      else if(type == LINE_DOTTED) lineTypeCode_ = 2;
+      else throw Exception("XFigGraphicDevice::setCurrentLineType. Unknown line type: " + TextTools::toString(type));
+      AbstractGraphicDevice::setCurrentLineType(type);
+    }
+    void drawLine(double x1, double y1, double x2, double y2);
+    void drawRect(double x, double y, double width, double height, short fill = FILL_EMPTY);
+    void drawCircle(double x, double y, double radius, short fill = FILL_EMPTY);
+    void drawText(double x, double y, const std::string& text, short hpos = TEXT_HORIZONTAL_LEFT, short vpos = TEXT_VERTICAL_BOTTOM, double angle = 0) throw (UnvalidFlagException);
+    void comment(const std::string& text)
+    {
+      content_.push_back("#" + text);
+    }
+
+    //Specific:
+    void setFontFlag(unsigned int flag) { fontFlag_ = flag; }
+
+  protected:
+    int getFillCode(short fill);
+
+  public:
+    static const unsigned int FONTFLAG_LATEX;
+    static const unsigned int FONTFLAG_POSTSCRIPT;
+
+};
+
+} // end of namespace bpp;
+
+#endif //_XFIGGRAPHICDEVICE_H_
+
+
diff --git a/src/Bpp/Graphics/Fig/XFigLaTeXFontManager.cpp b/src/Bpp/Graphics/Fig/XFigLaTeXFontManager.cpp
new file mode 100644
index 0000000..05c7c53
--- /dev/null
+++ b/src/Bpp/Graphics/Fig/XFigLaTeXFontManager.cpp
@@ -0,0 +1,55 @@
+//
+// File: XFigLaTeXFontManager.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Dec 30 2009
+// From file: FontManager.h
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "XFigLaTeXFontManager.h"
+
+using namespace bpp;
+
+XFigLaTeXFontManager::XFigLaTeXFontManager()
+{
+  // Add "official" font codes, from 0 to 5:
+  registerFont_(Font("Default", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 0);
+  registerFont_(Font("Roman", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 1);
+  registerFont_(Font("Bold", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 2);
+  registerFont_(Font("Italic", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 3);
+  registerFont_(Font("Sans Serif", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 4);
+  registerFont_(Font("Typewriter", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 5);
+}
+
diff --git a/src/Bpp/Graphics/Fig/XFigLaTeXFontManager.h b/src/Bpp/Graphics/Fig/XFigLaTeXFontManager.h
new file mode 100644
index 0000000..be73ba8
--- /dev/null
+++ b/src/Bpp/Graphics/Fig/XFigLaTeXFontManager.h
@@ -0,0 +1,66 @@
+//
+// File: XFigLaTeXFontManager.h
+// Created by: Julien Dutheil
+// Created on: Wed Dec 30 2009
+// From file: FontManager.h
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _XFIGLATEXFONTMANAGER_H_
+#define _XFIGLATEXFONTMANAGER_H_
+
+#include "../Font/FontManager.h"
+
+namespace bpp
+{
+
+/**
+ * @brief LaTeX font manager for the XFig format.
+ */
+class XFigLaTeXFontManager:
+  public AbstractFontManager<int>
+{
+
+public:
+  XFigLaTeXFontManager();
+
+  virtual ~XFigLaTeXFontManager() {}
+
+};
+
+} //end of namespace bpp;
+
+#endif //_XFIGLATEXFONTMANAGER_H_
+
diff --git a/src/Bpp/Graphics/Fig/XFigPostscriptFontManager.cpp b/src/Bpp/Graphics/Fig/XFigPostscriptFontManager.cpp
new file mode 100644
index 0000000..2bf11de
--- /dev/null
+++ b/src/Bpp/Graphics/Fig/XFigPostscriptFontManager.cpp
@@ -0,0 +1,85 @@
+//
+// File: XFigPostscriptFontManager.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Dec 30 2009
+// From file: FontManager.h
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "XFigPostscriptFontManager.h"
+
+using namespace bpp;
+
+XFigPostscriptFontManager::XFigPostscriptFontManager()
+{
+  // Add "official" font codes, from 0 to 34:
+  registerFont_(Font("Default", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), -1);
+  registerFont_(Font("Times", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 0); //Roman
+  registerFont_(Font("Times", Font::STYLE_ITALIC, Font::WEIGHT_NORMAL, 12), 1);
+  registerFont_(Font("Times", Font::STYLE_NORMAL, Font::WEIGHT_BOLD, 12), 2);
+  registerFont_(Font("Times", Font::STYLE_ITALIC, Font::WEIGHT_BOLD, 12), 3);
+  registerFont_(Font("AvantGarde", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 4); //Book
+  registerFont_(Font("AvantGarde", Font::STYLE_ITALIC, Font::WEIGHT_NORMAL, 12), 5); //Book Oblique
+  registerFont_(Font("AvantGarde", Font::STYLE_NORMAL, Font::WEIGHT_BOLD, 12), 6); //Demi
+  registerFont_(Font("AvantGarde", Font::STYLE_ITALIC, Font::WEIGHT_BOLD, 12), 7); //Demi Oblique
+  registerFont_(Font("Bookman", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 8); //Light
+  registerFont_(Font("Bookman", Font::STYLE_ITALIC, Font::WEIGHT_NORMAL, 12), 9); //Light Italic
+  registerFont_(Font("Bookman", Font::STYLE_NORMAL, Font::WEIGHT_BOLD, 12), 10); //Demi
+  registerFont_(Font("Bookman", Font::STYLE_ITALIC, Font::WEIGHT_BOLD, 12), 11); //Demi Italic
+  registerFont_(Font("Courier", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 12);
+  registerFont_(Font("Courier", Font::STYLE_ITALIC, Font::WEIGHT_NORMAL, 12), 13); //Oblique
+  registerFont_(Font("Courier", Font::STYLE_NORMAL, Font::WEIGHT_BOLD, 12), 14); //Bold
+  registerFont_(Font("Courier", Font::STYLE_ITALIC, Font::WEIGHT_BOLD, 12), 15); //Bold Oblique
+  registerFont_(Font("Helvetica", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 16);
+  registerFont_(Font("Helvetica", Font::STYLE_ITALIC, Font::WEIGHT_NORMAL, 12), 17); //Oblique
+  registerFont_(Font("Helvetica", Font::STYLE_NORMAL, Font::WEIGHT_BOLD, 12), 18); //Bold
+  registerFont_(Font("Helvetica", Font::STYLE_ITALIC, Font::WEIGHT_BOLD, 12), 19); //Bold Oblique
+  registerFont_(Font("Helvetica", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 20); //Narrow
+  registerFont_(Font("Helvetica", Font::STYLE_ITALIC, Font::WEIGHT_NORMAL, 12), 21); //Narrow Oblique
+  registerFont_(Font("Helvetica", Font::STYLE_NORMAL, Font::WEIGHT_BOLD, 12), 22); //Narrow Bold
+  registerFont_(Font("Helvetica", Font::STYLE_ITALIC, Font::WEIGHT_BOLD, 12), 23); //Narrow Bold Oblique
+  registerFont_(Font("New Century Schoolbook", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 24); //Roman
+  registerFont_(Font("New Century Schoolbook", Font::STYLE_ITALIC, Font::WEIGHT_NORMAL, 12), 25); //Italic
+  registerFont_(Font("New Century Schoolbook", Font::STYLE_NORMAL, Font::WEIGHT_BOLD, 12), 26); //Bold
+  registerFont_(Font("New Century Schoolbook", Font::STYLE_ITALIC, Font::WEIGHT_BOLD, 12), 27); //Bold Italic
+  registerFont_(Font("Palatino", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 28); //Roman
+  registerFont_(Font("Palatino", Font::STYLE_ITALIC, Font::WEIGHT_NORMAL, 12), 29); //Italic
+  registerFont_(Font("Palatino", Font::STYLE_NORMAL, Font::WEIGHT_BOLD, 12), 30); //Bold
+  registerFont_(Font("Palatino", Font::STYLE_ITALIC, Font::WEIGHT_BOLD, 12), 31); //Bold Italic
+  registerFont_(Font("Symbol", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 32);
+  registerFont_(Font("Zapf Chancery Medium", Font::STYLE_ITALIC, Font::WEIGHT_NORMAL, 12), 33); //Italic
+  registerFont_(Font("Zapf Dingbats", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12), 34);
+}
+
diff --git a/src/Bpp/Graphics/Fig/XFigPostscriptFontManager.h b/src/Bpp/Graphics/Fig/XFigPostscriptFontManager.h
new file mode 100644
index 0000000..d0ee0db
--- /dev/null
+++ b/src/Bpp/Graphics/Fig/XFigPostscriptFontManager.h
@@ -0,0 +1,66 @@
+//
+// File: XFigPostscriptFontManager.h
+// Created by: Julien Dutheil
+// Created on: Wed Dec 30 2009
+// From file: FontManager.h
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _XFIGPOSTSCRIPTFONTMANAGER_H_
+#define _XFIGPOSTSCRIPTFONTMANAGER_H_
+
+#include "../Font/FontManager.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Postscript font manager for the XFig format.
+ */
+class XFigPostscriptFontManager:
+  public AbstractFontManager<int>
+{
+
+public:
+  XFigPostscriptFontManager();
+  
+  virtual ~XFigPostscriptFontManager() {}
+
+};
+
+} //end of namespace bpp;
+
+#endif //_XFIGPOSTSCRIPTFONTMANAGER_H_
+
diff --git a/src/Bpp/Graphics/Font/Font.cpp b/src/Bpp/Graphics/Font/Font.cpp
new file mode 100644
index 0000000..3cfa410
--- /dev/null
+++ b/src/Bpp/Graphics/Font/Font.cpp
@@ -0,0 +1,56 @@
+//
+// File: Font.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Dec 30 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "Font.h"
+
+using namespace bpp;
+
+const short int Font::STYLE_NORMAL  = 0;
+const short int Font::STYLE_ITALIC  = 1;
+    
+const short int Font::WEIGHT_NORMAL = 0;
+const short int Font::WEIGHT_BOLD   = 1;
+
+void Font::init_()
+{
+  styleDesc_[STYLE_NORMAL] = "normal";
+  styleDesc_[STYLE_ITALIC] = "italic";
+  weightDesc_[WEIGHT_NORMAL] = "normal";
+  weightDesc_[WEIGHT_BOLD] = "bold";
+}
diff --git a/src/Bpp/Graphics/Font/Font.h b/src/Bpp/Graphics/Font/Font.h
new file mode 100644
index 0000000..1a3b36c
--- /dev/null
+++ b/src/Bpp/Graphics/Font/Font.h
@@ -0,0 +1,179 @@
+//
+// File: Font.h
+// Created by: Julien Dutheil
+// Created on: Mon Mar 03 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _FONT_H_
+#define _FONT_H_
+
+#include "../../Clonable.h"
+#include "../../Text/TextTools.h"
+
+//From the STL:
+#include <map>
+#include <string>
+
+namespace bpp
+{
+
+/**
+ * @brief Data structure for fonts.
+ */
+class Font:
+  public virtual Clonable
+{
+  private:
+    std::string family_;
+    short int style_;
+    short int weight_;
+    unsigned int size_;
+    mutable std::map<short int, std::string> styleDesc_;
+    mutable std::map<short int, std::string> weightDesc_;
+
+  public:
+    Font(const std::string& family = "Default", short int style = STYLE_NORMAL, short int weight = WEIGHT_NORMAL, unsigned int size = 12):
+      family_(family), style_(style), weight_(weight), size_(size), styleDesc_(), weightDesc_()
+    {
+      init_();
+    }
+
+    virtual ~Font() {}
+
+#ifdef NO_VIRTUAL_COV
+    Clonable*
+#else
+    Font*
+#endif
+    clone() const { return new Font(*this); }
+
+  private:
+    void init_();
+
+  public:
+    bool operator==(const Font& font) const
+    {
+      return family_ == font.family_
+          &&  style_ == font.style_
+          && weight_ == font.weight_;
+    }
+
+    /**
+     * @return The family component of this font.
+     */
+    const std::string& getFamily() const { return family_; }
+
+    /**
+     * @return The style component of this font.
+     */
+    const short int getStyle() const { return style_; }
+
+    /**
+     * @brief Alias function for getStyle.
+     * @return The shape component of this font.
+     */
+    const short int getShape() const { return style_; }
+
+    /**
+     * @return The weight component of this font.
+     */
+    const short int getWeight() const { return weight_; }
+
+    /**
+     * @brief Alias function for getWeight
+     * @return The series component of this font.
+     */
+    const short int getSeries() const { return weight_; }
+
+    /**
+     * @return The size component of this font.
+     */
+    const unsigned int& getSize() const { return size_; }
+
+    /**
+     * @param family The family component of this font.
+     */
+    void setFamily(const std::string& family) { family_ = family; }
+
+    /**
+     * @param style The style component of this font.
+     */
+    void setStyle(short int style) { style_ = style; }
+
+    /**
+     * @brief Alias function for setStyle.
+     * @param shape The shape component of this font.
+     */
+    void setShape(short int shape) { style_ = shape; }
+
+
+    /**
+     * @param weight The weight component of this font.
+     */
+    void setWeight(short int weight) { weight_ = weight; }
+
+    /**
+     * @brief Alias function for setWeight.
+     * @param series The series component of this font.
+     */
+    void setSeries(short int series) { weight_ = series; }
+
+    /**
+     * @param size The size component of this font.
+     */
+    void setSize(unsigned int size) { size_ = size; }
+
+    /**
+     * @return A text description of this font (family type size).
+     */
+    std::string toString() const
+    {
+      return family_ + "/" + styleDesc_[style_] + "/" + weightDesc_[weight_] + "/" + TextTools::toString(size_);
+    }
+
+  public:
+    static const short int STYLE_NORMAL;
+    static const short int STYLE_ITALIC;
+    
+    static const short int WEIGHT_NORMAL;
+    static const short int WEIGHT_BOLD;
+};
+
+} // end of namespace bpp.
+
+#endif //_FONT_H_
+
+
diff --git a/src/Bpp/Graphics/Font/FontManager.h b/src/Bpp/Graphics/Font/FontManager.h
new file mode 100644
index 0000000..541f530
--- /dev/null
+++ b/src/Bpp/Graphics/Font/FontManager.h
@@ -0,0 +1,149 @@
+//
+// File: FontManager.h
+// Created by: Julien Dutheil
+// Created on: Sat Mar 08 2008
+//
+
+/*
+Copyright or © or Copr. Bio++ Developement Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _FONTMANAGER_H_
+#define _FONTMANAGER_H_
+
+#include "Font.h"
+
+// From the STL:
+#include <vector>
+
+#include "../../Text/TextTools.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Associate special fonts to a code.
+ *
+ * Instances of this interface are used in some vector format.
+ */
+template<class CodeType>
+class FontManager
+{
+public:
+  FontManager() {}
+  virtual ~FontManager() {}
+
+public:
+
+  /**
+   * @param font The font to look for.
+   * @return The code associated to a given font.
+   */
+  virtual CodeType getCode(const Font& font) const throw (Exception) = 0;
+
+  /**
+   * @param code The code to look for.
+   * @return The font associated to a given code.
+   * @throw exception if the code is not valid.
+   */
+  virtual const Font& getFont(CodeType& code) const throw (Exception) = 0;
+
+  /**
+   * @return All valid codes.
+   */
+  virtual std::vector<CodeType> getCodes() const = 0;
+
+  /**
+   * @return All available fonts.
+   */
+  virtual std::vector<Font> getFonts() const = 0;
+
+  /**
+   * @return The total number of fonts available.
+   */
+  virtual size_t getNumberOfFonts() const = 0;
+};
+
+
+
+template<class CodeType>
+class AbstractFontManager :
+  public virtual FontManager<CodeType>
+{
+private:
+  std::vector<Font> fonts_;
+  std::vector<CodeType> codes_;
+
+public:
+  AbstractFontManager() : fonts_(), codes_() {}
+
+public:
+  CodeType getCode(const Font& font) const throw (Exception)
+  {
+    for (unsigned int i = 0; i < fonts_.size(); i++)
+    {
+      if (fonts_[i] == font)
+      {
+        return codes_[i];
+      }
+    }
+    throw Exception("AbstractFontManager::getCode. Unknown font: " + font.toString());
+  }
+
+  const Font& getFont(int &code) const throw (Exception)
+  {
+    for (unsigned int i = 0; i < codes_.size(); i++)
+    {
+      if (codes_[i] == code)
+      {
+        return fonts_[i];
+      }
+    }
+    throw Exception("AbstractFontManager::getColor. No font associated to this code: " + TextTools::toString(code));
+  }
+  std::vector<CodeType> getCodes() const { return codes_; }
+  std::vector<Font> getFonts() const { return fonts_; }
+  size_t getNumberOfFonts() const { return fonts_.size(); }
+
+protected:
+  void registerFont_(const Font& font, int code)
+  {
+    codes_.push_back(code);
+    fonts_.push_back(font);
+  }
+
+};
+
+} // end of namespace.
+
+#endif //_FONTMANAGER_H_
+
diff --git a/src/Bpp/Graphics/GraphicDevice.cpp b/src/Bpp/Graphics/GraphicDevice.cpp
new file mode 100644
index 0000000..455d744
--- /dev/null
+++ b/src/Bpp/Graphics/GraphicDevice.cpp
@@ -0,0 +1,58 @@
+//
+// File: GraphicDevice.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Mar 03 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to map data onto
+a sequence or a phylogenetic tree.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "GraphicDevice.h"
+
+using namespace bpp;
+
+short GraphicDevice::TEXT_HORIZONTAL_CENTER = 0;
+short GraphicDevice::TEXT_HORIZONTAL_LEFT   = 1;
+short GraphicDevice::TEXT_HORIZONTAL_RIGHT  = 2;
+short GraphicDevice::TEXT_VERTICAL_CENTER   = 3;
+short GraphicDevice::TEXT_VERTICAL_BOTTOM   = 4;
+short GraphicDevice::TEXT_VERTICAL_TOP      = 5;
+
+short GraphicDevice::FILL_EMPTY             = 10;
+short GraphicDevice::FILL_FILLED            = 11;
+short GraphicDevice::FILL_PATTERN           = 12;
+
+short GraphicDevice::LINE_SOLID             = 20;
+short GraphicDevice::LINE_DASHED            = 21;
+short GraphicDevice::LINE_DOTTED            = 22;
+
diff --git a/src/Bpp/Graphics/GraphicDevice.h b/src/Bpp/Graphics/GraphicDevice.h
new file mode 100644
index 0000000..6715cda
--- /dev/null
+++ b/src/Bpp/Graphics/GraphicDevice.h
@@ -0,0 +1,199 @@
+//
+// File: GraphicDevice.h
+// Created by: Julien Dutheil
+// Created on: Mon Mar 03 2008
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 16, 2006)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _GRAPHICDEVICE_H_
+#define _GRAPHICDEVICE_H_
+
+#include "RgbColor.h"
+#include "Font/Font.h"
+
+namespace bpp
+{
+
+  class UnvalidFlagException: public virtual Exception
+  {
+    public:
+      UnvalidFlagException(const std::string& message): Exception(message) {}
+  };
+
+
+
+  /**
+   * @brief Interface for all plotting devices.
+   *
+   * Implement this interface to support new formats.
+   */
+  class GraphicDevice
+  {
+    public:
+      GraphicDevice() {}
+      virtual ~GraphicDevice() {}
+
+    public:
+      /**
+       * @brief Start the painting.
+       */
+      virtual void begin() = 0;
+
+      /**
+       * @brief End the painting.
+       *
+       * Depending on the implementation of the device,
+       * the call of this method might be required before
+       * the plotting commands become visible.
+       */
+      virtual void end() = 0;
+
+      /**
+       * @param xu The x expansion factor. The actual unit actually depends on the implementation.
+       */
+      virtual void setXUnit(double xu) = 0;
+
+      /**
+       * @param yu The y expansion factor. The actual unit actually depends on the implementation.
+       */
+      virtual void setYUnit(double yu) = 0;
+
+      /**
+       * @return The x expansion factor. The actual unit actually depends on the implementation.
+       */
+      virtual double getXUnit() const = 0;
+
+      /**
+       * @return The y expansion factor. The actual unit actually depends on the implementation.
+       */
+      virtual double getYUnit() const = 0;
+
+      virtual void setCurrentForegroundColor(const RGBColor& color) = 0;
+      virtual void setCurrentBackgroundColor(const RGBColor& color) = 0;
+      virtual void setCurrentFont(const Font& font) = 0;
+      virtual void setCurrentPointSize(unsigned int size) = 0;
+      virtual void setCurrentLineType(short type) = 0;
+      virtual void setCurrentLayer(int layerIndex) = 0;
+
+      virtual const RGBColor& getCurrentForegroundColor() const = 0;
+      virtual const RGBColor& getCurrentBackgroundColor() const = 0;
+      virtual const Font& getCurrentFont() const = 0;
+      virtual unsigned int getCurrentPointSize() const = 0;
+      virtual short getCurrentLineType() const = 0;
+      virtual int getCurrentLayer() const = 0;
+
+
+      /**
+       * @brief Draw a line between two points.
+       *
+       * This method uses the current foreground color and the current line type.
+       *
+       * @param x1 x coordinate 1
+       * @param y1 y coordinate 1
+       * @param x2 x coordinate 2
+       * @param y2 y coordinate 2
+       */
+      virtual void drawLine(double x1, double y1, double x2, double y2) = 0;
+
+      /**
+       * @brief Draw a rectangle.
+       *
+       * This method uses the current foreground color and the current line type for drawing the stroke of the rectangle,
+       * and the current background color for filling the rectangle.
+       *
+       * @param x x coordinate
+       * @param y y coordinate
+       * @param width The rectangle width
+       * @param height The rectangle height
+       * @param fill Filling type (one of FILL_EMPTY, FILL_FILLED or FILL_PATTERN).
+       */
+      virtual void drawRect(double x, double y, double width, double height, short fill = FILL_EMPTY) = 0;
+
+      /**
+       * @brief Draw a circle.
+       *
+       * This method uses the current foreground color and the current line type for drawing the stroke of the circle,
+       * and the current background color for filling the circle.
+       *
+       * @param x x coordinate of the center
+       * @param y y coordinate of the center
+       * @param radius The circle radius
+       * @param fill Filling type (one of FILL_EMPTY, FILL_FILLED or FILL_PATTERN).
+       */
+      virtual void drawCircle(double x, double y, double radius, short fill = FILL_EMPTY) = 0;
+
+      /**
+       * @brief Draw some characters.
+       *
+       * This method uses the current foreground color.
+       *
+       * @param x x coordinate
+       * @param y y coordinate
+       * @param text The characters to draw
+       * @param hpos Horizontal adjustment, one of TEXT_HORIZONTAL_LEFT, TEXT_HORIZONTAL_CENTER or TEXT_HORIZONTAL_RIGHT.
+       * @param vpos Vertical adjustment, one of TEXT_VERTICAL_LEFT, TEXT_VERTICAL_CENTER or TEXT_VERTICAL_RIGHT.
+       * @param angle Angle i radian to rotate the text.
+       */
+      virtual void drawText(double x, double y, const std::string& text, short hpos = TEXT_HORIZONTAL_LEFT, short vpos = TEXT_VERTICAL_BOTTOM, double angle = 0) throw (UnvalidFlagException) = 0;
+
+      /**
+       * @brief Add a comment in the output.
+       *
+       * @param comment Comment text.
+       */
+      virtual void comment(const std::string & comment) = 0;
+
+    public:
+      static short TEXT_HORIZONTAL_CENTER;
+      static short TEXT_HORIZONTAL_LEFT;
+      static short TEXT_HORIZONTAL_RIGHT;
+      static short TEXT_VERTICAL_CENTER;
+      static short TEXT_VERTICAL_BOTTOM;
+      static short TEXT_VERTICAL_TOP;
+
+      static short FILL_EMPTY;
+      static short FILL_FILLED;
+      static short FILL_PATTERN;
+
+      static short LINE_SOLID;
+      static short LINE_DASHED;
+      static short LINE_DOTTED;
+  };
+
+} // end of namespace bpp.
+
+#endif //_GRAPHICDEVICE_H_
+
+
diff --git a/src/Bpp/Graphics/Latex/DvipsColorSet.cpp b/src/Bpp/Graphics/Latex/DvipsColorSet.cpp
new file mode 100644
index 0000000..5327cc7
--- /dev/null
+++ b/src/Bpp/Graphics/Latex/DvipsColorSet.cpp
@@ -0,0 +1,115 @@
+//
+// File: DvipsColorSet.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Apr 14 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2008)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "DvipsColorSet.h"
+
+using namespace bpp;
+
+DvipsColorSet::DvipsColorSet()
+{
+  colors_["GreenYellow"] = RGBColor(217, 255, 79);
+  colors_["Yellow"] = RGBColor(255, 255, 0);
+  colors_["Goldenrod"] = RGBColor(255, 230, 41);
+  colors_["Dandelion"] = RGBColor(255, 181, 41);
+  colors_["Apricot"] = RGBColor(255, 173, 122);
+  colors_["Peach"] = RGBColor(255, 128, 77);
+  colors_["Melon"] = RGBColor(255, 138, 128);
+  colors_["YellowOrange"] = RGBColor(255, 148, 0);
+  colors_["Orange"] = RGBColor(255, 99, 33);
+  colors_["BurntOrange"] = RGBColor(255, 125, 0);
+  colors_["Bittersweet"] = RGBColor(194, 48, 0);
+  colors_["RedOrange"] = RGBColor(255, 59, 33);
+  colors_["Mahogany"] = RGBColor(166, 25, 22);
+  colors_["Maroon"] = RGBColor(173, 23, 55);
+  colors_["BrickRed"] = RGBColor(184, 20, 11);
+  colors_["Red"] = RGBColor(255, 0, 0);
+  colors_["OrangeRed"] = RGBColor(255, 0, 128);
+  colors_["RubineRed"] = RGBColor(255, 0, 222);
+  colors_["WildStrawberry"] = RGBColor(255, 10, 156);
+  colors_["Salmon"] = RGBColor(255, 120, 158);
+  colors_["CarnationPink"] = RGBColor(255, 94, 255);
+  colors_["Magenta"] = RGBColor(255, 0, 255);
+  colors_["VioletRed"] = RGBColor(255, 48, 255);
+  colors_["Rhodamine"] = RGBColor(255, 46, 255);
+  colors_["Mulberry"] = RGBColor(165, 25, 250);
+  colors_["RedViolet"] = RGBColor(157, 17, 168);
+  colors_["Fuchsia"] = RGBColor(124, 21, 235);
+  colors_["Lavender"] = RGBColor(255, 133, 255);
+  colors_["Thistle"] = RGBColor(224, 105, 255);
+  colors_["Orchid"] = RGBColor(173, 92, 255);
+  colors_["DarkOrchid"] = RGBColor(153, 51, 204);
+  colors_["Purple"] = RGBColor(140, 36, 255);
+  colors_["Plum"] = RGBColor(128, 0, 255);
+  colors_["Violet"] = RGBColor(54, 31, 255);
+  colors_["RoyalPurple"] = RGBColor(64, 25, 255);
+  colors_["BlueViolet"] = RGBColor(34, 22, 245);
+  colors_["Periwinkle"] = RGBColor(110, 115, 255);
+  colors_["CadetBlue"] = RGBColor(97, 110, 196);
+  colors_["CornflowerBlue"] = RGBColor(89, 222, 255);
+  colors_["MidnightBlue"] = RGBColor(3, 126, 145);
+  colors_["NavyBlue"] = RGBColor(15, 117, 255);
+  colors_["RoyalBlue"] = RGBColor(0, 128, 255);
+  colors_["Blue"] = RGBColor(0, 0, 255);
+  colors_["Cerulean"] = RGBColor(15, 227, 255);
+  colors_["Cyan"] = RGBColor(0, 255, 255);
+  colors_["ProcessBlue"] = RGBColor(10, 255, 255);
+  colors_["SkyBlue"] = RGBColor(97, 255, 224);
+  colors_["Turquoise"] = RGBColor(38, 255, 204);
+  colors_["TealBlue"] = RGBColor(35, 250, 165);
+  colors_["Aquamarine"] = RGBColor(46, 255, 178);
+  colors_["BlueGreen"] = RGBColor(38, 255, 171);
+  colors_["Emerald"] = RGBColor(0, 255, 128);
+  colors_["JungleGreen"] = RGBColor(3, 255, 122);
+  colors_["SeaGreen"] = RGBColor(79, 255, 128);
+  colors_["Green"] = RGBColor(0, 255, 0);
+  colors_["ForestGreen"] = RGBColor(20, 224, 27);
+  colors_["PineGreen"] = RGBColor(15, 191, 78);
+  colors_["LimeGreen"] = RGBColor(128, 255, 0);
+  colors_["YellowGreen"] = RGBColor(143, 255, 66);
+  colors_["SpringGreen"] = RGBColor(189, 255, 61);
+  colors_["OliveGreen"] = RGBColor(55, 153, 8);
+  colors_["RawSienna"] = RGBColor(140, 39, 0);
+  colors_["Sepia"] = RGBColor(77, 13, 0);
+  colors_["Brown"] = RGBColor(102, 19, 0);
+  colors_["Tan"] = RGBColor(219, 148, 112);
+  colors_["Gray"] = RGBColor(128, 128, 128);
+  colors_["Black"] = RGBColor(0, 0, 0);
+  colors_["White"] = RGBColor(255, 255, 255);
+}
+
diff --git a/src/Bpp/Graphics/Latex/DvipsColorSet.h b/src/Bpp/Graphics/Latex/DvipsColorSet.h
new file mode 100644
index 0000000..73a4fd7
--- /dev/null
+++ b/src/Bpp/Graphics/Latex/DvipsColorSet.h
@@ -0,0 +1,65 @@
+//
+// File: DvipsColorSet.h
+// Created by: Julien Dutheil
+// Created on: Mon Apr 14 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2008)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _DVIPSCOLORSET_H_
+#define _DVIPSCOLORSET_H_
+
+#include "../ColorSet.h"
+
+namespace bpp
+{
+
+/**
+ * @brief The dvips color definitions.
+ *
+ * Source: dvipsnam.def, from the TeXlive LaTeX distribution. 
+ */
+class DvipsColorSet:
+  public AbstractColorSet
+{
+  public:
+    DvipsColorSet();
+    virtual ~DvipsColorSet() {}
+
+};
+
+} // end of namespace bpp;
+
+#endif //_MOLSCRIPTCOLORSET_H_
+
diff --git a/src/Bpp/Graphics/Latex/PgfGraphicDevice.cpp b/src/Bpp/Graphics/Latex/PgfGraphicDevice.cpp
new file mode 100644
index 0000000..0b72269
--- /dev/null
+++ b/src/Bpp/Graphics/Latex/PgfGraphicDevice.cpp
@@ -0,0 +1,299 @@
+//
+// File: PgfGraphicDevice.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Jun 19 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "PgfGraphicDevice.h"
+using namespace bpp;
+
+#include<algorithm>
+using namespace std;
+
+
+PgfGraphicDevice::PgfGraphicDevice(std::ostream& out, double unit) :
+  out_(out),
+  fgColorStr_("black"),
+  bgColorStr_("white"),
+  content_(),
+  layers_(),
+  colorIndex_(),
+  colorCount_(0),
+  useLayers_(false),
+  contentStarted_(false),
+  fontShapes_(),
+  fontSeries_()
+{
+  colorIndex_[ColorTools::BLACK]   = "black";
+  colorIndex_[ColorTools::WHITE]   = "white";
+  colorIndex_[ColorTools::BLUE]    = "blue";
+  colorIndex_[ColorTools::RED]     = "red";
+  colorIndex_[ColorTools::GREEN]   = "green";
+  colorIndex_[ColorTools::YELLOW]  = "yellow";
+  colorIndex_[ColorTools::CYAN]    = "cyan";
+  colorIndex_[ColorTools::MAGENTA] = "magenta";
+
+  fontShapes_[Font::STYLE_NORMAL]  = "n";
+  fontShapes_[Font::STYLE_ITALIC]  = "it";
+  fontSeries_[Font::WEIGHT_NORMAL] = "m";
+  fontSeries_[Font::WEIGHT_BOLD]   = "bx";
+
+  setCurrentFont(Font("cmtt", Font::STYLE_NORMAL, Font::WEIGHT_NORMAL, 12));
+  setXUnit(unit);
+  setYUnit(unit);
+}
+
+void PgfGraphicDevice::begin()
+{
+  content_.clear();
+  layers_.clear();
+  colorIndex_.clear();
+  colorCount_ = 0;
+  useLayers_ = false;
+  contentStarted_ = false;
+}
+
+bool comp( int a, int b ) { return a > b; } ;
+void PgfGraphicDevice::end()
+{
+  ostringstream oss;
+  if (useLayers_)
+    oss << "\\end{pgfonlayer}{" << TextTools::toString(getCurrentLayer()) << "}" << endl;
+  content_.push_back(oss.str());
+
+  //Header:
+  out_ << "\\documentclass{article}" << endl;
+  out_ << "% This figure was generated by the Bio++ Pgf Graphic Device." << endl;
+  out_ << "% Althought this file can be compiled 'as is' it may not be displayed correctly, depending on the size of the picture." << endl;
+  out_ << "% You may consider copying the pgfpicture environment to your own LaTeX file and play with pgf settings (e.g. the pgfpages module)." << endl;
+  out_ << "% You can also use the geometry package, for instance:" << endl;
+  out_ << "% \\usepackage[a3paper]{geometry}" << endl;
+  out_ << "\\usepackage{pgf}" << endl;
+  for(map<const RGBColor, string>::iterator it = colorIndex_.begin(); it != colorIndex_.end(); it++)
+  {
+    if(it->second.substr(0,3) == "use")
+      out_ << "\\definecolor{" << it->second << "}{rgb}{" << it->first[0]/255. << "," << it->first[1]/255. << "," << it->first[2]/255. << "}" << endl;    
+  }
+  out_ << "\\begin{document}" << endl;
+
+  //Declare and set layers:
+  if (useLayers_)
+  {
+    string tmp;
+    sort(layers_.begin(), layers_.end(), comp);
+    for(unsigned int i = 0; i < layers_.size(); i++)
+    {
+      if(i > 0) tmp += ",";
+      tmp += TextTools::toString(layers_[i]);
+      out_ << "\\pgfdeclarelayer{" << layers_[i] << "}" << endl;
+    }
+    out_ << "\\pgfsetlayers{" << tmp << "}" << endl;
+  }
+
+  //Start picture:
+  out_ << "\\begin{pgfpicture}" << endl;
+  out_ << "\\pgfsetxvec{\\pgfpoint{" << getXUnit() << "cm}{0cm}}" << endl;
+  out_ << "\\pgfsetyvec{\\pgfpoint{0cm}{-" << getYUnit() << "cm}}" << endl;
+  
+  for(unsigned int i = 0; i < content_.size(); i++)
+  {
+    out_ << content_[i] << endl;
+  }
+  
+  out_ << "\\end{pgfpicture}" << endl;
+  out_ << "\\end{document}" << endl;
+}
+
+void PgfGraphicDevice::setCurrentForegroundColor(const RGBColor& color)
+{
+  map<const RGBColor, string>::iterator it = colorIndex_.find(color);
+  if(it != colorIndex_.end())
+  {
+    fgColorStr_ = it->second;
+  }
+  else
+  {
+    colorCount_++;
+    fgColorStr_ = "usercolor" + TextTools::toString(colorCount_);
+    colorIndex_[color] = fgColorStr_;
+  }
+  AbstractGraphicDevice::setCurrentForegroundColor(color);
+  ostringstream oss;
+  oss << "\\pgfsetstrokecolor{" << fgColorStr_ << "}" << endl;
+  content_.push_back(oss.str());
+}
+
+void PgfGraphicDevice::setCurrentBackgroundColor(const RGBColor& color)
+{
+  map<const RGBColor, string>::iterator it = colorIndex_.find(color);
+  if (it != colorIndex_.end())
+  {
+    bgColorStr_ = it->second;
+  }
+  else
+  {
+    colorCount_++;
+    bgColorStr_ = "usercolor" + TextTools::toString(colorCount_);
+    colorIndex_[color] = bgColorStr_;
+  }
+  AbstractGraphicDevice::setCurrentBackgroundColor(color);
+  ostringstream oss;
+  oss << "\\pgfsetfillcolor{" << bgColorStr_ << "}" << endl;
+  content_.push_back(oss.str());
+}
+
+void PgfGraphicDevice::setCurrentFont(const Font& font)
+{
+  AbstractGraphicDevice::setCurrentFont(font);
+  ostringstream oss;
+  oss << "\\fontfamily{" << font.getFamily() << "}" << endl;
+  oss << "\\fontseries{" << fontSeries_[font.getSeries()] << "}" << endl;
+  oss << "\\fontshape{"  << fontShapes_[font.getShape()] << "}"  << endl;
+  oss << "\\fontsize{"   << font.getSize() << "}{" << font.getSize() << "}" << endl;
+  oss << "\\selectfont"  << endl;
+  content_.push_back(oss.str());
+}
+
+void PgfGraphicDevice::setCurrentPointSize(unsigned int size)
+{
+  AbstractGraphicDevice::setCurrentPointSize(size);
+  ostringstream oss;
+  oss << "\\pgfsetlinewidth{" << x_(size) << "}" << endl;
+  content_.push_back(oss.str());
+}
+
+void PgfGraphicDevice::setCurrentLineType(short type) throw (Exception)
+{ 
+  AbstractGraphicDevice::setCurrentLineType(type);
+  if(type == LINE_SOLID)
+  {
+    ostringstream oss;
+    oss << "\\pgfsetdash{}{0pt}" << endl;
+    content_.push_back(oss.str());
+  }
+  else if(type == LINE_DASHED)
+  {
+    ostringstream oss;
+    oss << "\\pgfsetdash{{3mm}{2mm}}{0pt}" << endl;
+    content_.push_back(oss.str());
+  }
+  else if(type == LINE_DOTTED)
+  {
+    ostringstream oss;
+    oss << "\\pgfsetdash{{" << (x_(getCurrentPointSize())) << "}{" << (x_(getCurrentPointSize())) << "}}{0pt}" << endl;
+    content_.push_back(oss.str());
+  }
+  else throw Exception("PgfGraphicDevice::setCurrentLineType. Unknown line type: " + TextTools::toString(type));
+}
+
+void PgfGraphicDevice::setCurrentLayer(int layerIndex)
+{
+  if (!useLayers_ && contentStarted_)
+    throw Exception("PgfGraphicDevice::setCurrentLayer. A layer is specified after some content has been already added, this would result in a corrupted display.");
+  ostringstream oss;
+  if (useLayers_)
+    oss << "\\end{pgfonlayer}{" << TextTools::toString(getCurrentLayer()) << "}" << endl;
+  oss << "\\begin{pgfonlayer}{" << TextTools::toString(layerIndex) << "}" << endl;
+  //We have to recall the current color values for this layer:
+  oss << "\\pgfsetstrokecolor{" << fgColorStr_ << "}" << endl;
+  oss << "\\pgfsetfillcolor{" << bgColorStr_ << "}" << endl;
+  content_.push_back(oss.str());
+  AbstractGraphicDevice::setCurrentLayer(layerIndex);
+  if (find(layers_.begin(), layers_.end(), layerIndex) == layers_.end())
+    layers_.push_back(layerIndex);
+  useLayers_ = true;
+}
+
+void PgfGraphicDevice::drawLine(double x1, double y1, double x2, double y2)
+{
+  ostringstream oss;
+  oss << "\\pgfpathmoveto{\\pgfpointxy{" << x1 << "}{" << y1 << "}}" << endl;
+  oss << "\\pgfpathlineto{\\pgfpointxy{" << x2 << "}{" << y2 << "}}" << endl;
+  oss << "\\pgfpathclose" << endl;
+  oss << "\\pgfusepath{stroke}" << endl;
+  content_.push_back(oss.str());
+  contentStarted_ = true;
+}
+ 
+void PgfGraphicDevice::drawRect(double x, double y, double width, double height, short fill)
+{
+  ostringstream oss;
+  oss << "\\pgfpathrectangle{\\pgfpointxy{" << x << "}{" << y << "}}{\\pgfpointxy{" << width << "}{" << height << "}}" << endl;
+  if(fill == FILL_FILLED)
+    oss << "\\pgfusepath{stroke,fill}" << endl;
+  else
+    oss << "\\pgfusepath{stroke}" << endl;
+  content_.push_back(oss.str());
+  contentStarted_ = true;
+}
+
+void PgfGraphicDevice::drawCircle(double x, double y, double radius, short fill)
+{
+  ostringstream oss;
+  oss << "\\pgfpathcircle{\\pgfpointxy{" << x << "}{" << y << "}}{" << radius << "}" << endl;
+  if(fill == FILL_FILLED)
+    oss << "\\pgfusepath{stroke,fill}" << endl;
+  else
+    oss << "\\pgfusepath{stroke}" << endl;
+  content_.push_back(oss.str());
+  contentStarted_ = true;
+}
+
+void PgfGraphicDevice::drawText(double x, double y, const std::string& text, short hpos, short vpos, double angle) throw (UnvalidFlagException)
+{
+  string anchor;
+  if(vpos == TEXT_VERTICAL_BOTTOM)
+    anchor = "bottom";
+  else if(vpos == TEXT_VERTICAL_TOP)
+    anchor = "top";
+  else if(vpos == TEXT_VERTICAL_CENTER)
+    anchor = "base";
+  else throw UnvalidFlagException("PgfGraphicDevice::drawText. Invalid vertical alignment option.");
+  if(hpos == TEXT_HORIZONTAL_LEFT)
+    anchor += ",left";
+  else if(hpos == TEXT_HORIZONTAL_RIGHT)
+    anchor += ",right";
+  else if(hpos == TEXT_HORIZONTAL_CENTER)
+    anchor += "";
+  else throw UnvalidFlagException("PgfGraphicDevice::drawText. Invalid horizontal alignment option.");
+
+  ostringstream oss;
+  oss << "\\pgftransformrotate{" << angle << "}" << endl;
+  oss << "\\pgftext[" << anchor << ",at=\\pgfpointxy{" << x << "}{" << y << "}]{\\textcolor{" << fgColorStr_ << "}" << text << "}" << endl;
+  content_.push_back(oss.str());
+  contentStarted_ = true;
+}
+
diff --git a/src/Bpp/Graphics/Latex/PgfGraphicDevice.h b/src/Bpp/Graphics/Latex/PgfGraphicDevice.h
new file mode 100644
index 0000000..aecb9ed
--- /dev/null
+++ b/src/Bpp/Graphics/Latex/PgfGraphicDevice.h
@@ -0,0 +1,117 @@
+//
+// File: PgfGraphicDevice.h
+// Created by: Julien Dutheil
+// Created on: Thu Jun 19 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 16, 2006)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _PGFGRAPHICDEVICE_H_
+#define _PGFGRAPHICDEVICE_H_
+
+#include "../AbstractGraphicDevice.h"
+#include "../ColorTools.h"
+
+// From the STL:
+#include <map>
+#include <vector>
+#include <string>
+
+namespace bpp
+{
+
+/**
+ * @brief LaTeX Portable Graphic Format (Pgf) plotting format.
+ */
+class PgfGraphicDevice:
+  public AbstractGraphicDevice
+{
+  private:
+    std::ostream& out_;
+    std::string fgColorStr_;
+    std::string bgColorStr_;
+    std::vector<std::string> content_;
+    std::vector<int> layers_;
+    std::map<const RGBColor, std::string> colorIndex_;
+    unsigned int colorCount_;
+    bool useLayers_;
+    bool contentStarted_;
+    mutable std::map<short int, std::string> fontShapes_;
+    mutable std::map<short int, std::string> fontSeries_;
+
+  public:
+    /**
+     * @brief Build a new Pgf device object.
+     *
+     * Coordinates in Pgf are the same as in LaTeX, so it can be any of cm, mm, in, pt, px, etc.
+     * For compatibility with other devices, the constructor takes as input the scale of the drawing, as cm per points.
+     * All coordinates and widths will be multiplied by the factor in the output file.
+     *
+     * @param out The output stream.
+     * @param unit The unit length.
+     */
+    PgfGraphicDevice(std::ostream& out, double unit);
+
+    virtual ~PgfGraphicDevice() {}
+
+  public:
+    void begin();
+    void end();
+
+    void setCurrentForegroundColor(const RGBColor& color);
+    void setCurrentBackgroundColor(const RGBColor& color);
+    void setCurrentFont(const Font& font);
+    void setCurrentPointSize(unsigned int size);
+    void setCurrentLineType(short type) throw (Exception);
+    void setCurrentLayer(int layerIndex);
+   
+    void drawLine(double x1, double y1, double x2, double y2);
+    void drawRect(double x, double y, double width, double height, short fill = FILL_EMPTY);
+    void drawCircle(double x, double y, double radius, short fill = FILL_EMPTY);
+    void drawText(double x, double y, const std::string & text, short hpos = TEXT_HORIZONTAL_LEFT, short vpos = TEXT_VERTICAL_BOTTOM, double angle = 0) throw (UnvalidFlagException);
+    void comment(const std::string& text)
+    {
+      content_.push_back("%" + text);
+    }
+
+  public:
+    const std::string& getFontShape(const Font& font);
+
+};
+
+} // end of namespace bpp.
+
+#endif //_PGFGRAPHICDEVICE_H_
+
+
diff --git a/src/Bpp/Graphics/Molscript/MolscriptColorSet.cpp b/src/Bpp/Graphics/Molscript/MolscriptColorSet.cpp
new file mode 100644
index 0000000..b5331e2
--- /dev/null
+++ b/src/Bpp/Graphics/Molscript/MolscriptColorSet.cpp
@@ -0,0 +1,210 @@
+//
+// File: MolscriptColorSet.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Apr 14 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2008)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "MolscriptColorSet.h"
+
+using namespace bpp;
+
+MolscriptColorSet::MolscriptColorSet()
+{
+  colors_["aliceblue"] = RGBColor(240, 248, 255);
+  colors_["antiquewhite"] = RGBColor(250, 235, 215);
+  colors_["aquamarine"] = RGBColor(127, 255, 212);
+  colors_["azure"] = RGBColor(240, 255, 255);
+  colors_["beige"] = RGBColor(245, 245, 220);
+  colors_["bisque"] = RGBColor(255, 228, 196);
+  colors_["black"] = RGBColor(0, 0, 0);
+  colors_["blanchedalmond"] = RGBColor(255, 235, 205);
+  colors_["blue"] = RGBColor(0, 0, 255);
+  colors_["blueviolet"] = RGBColor(138, 43, 226);
+  colors_["brown"] = RGBColor(165, 42, 42);
+  colors_["burlywood"] = RGBColor(222, 184, 135);
+  colors_["cadetblue"] = RGBColor(95, 158, 160);
+  colors_["chartreuse"] = RGBColor(127, 255, 0);
+  colors_["chocolate"] = RGBColor(210, 105, 30);
+  colors_["coral"] = RGBColor(255, 127, 80);
+  colors_["cornflowerblue"] = RGBColor(100, 149, 237);
+  colors_["cornsilk"] = RGBColor(255, 248, 220);
+  colors_["crimson"] = RGBColor(220, 20, 60);
+  colors_["cyan"] = RGBColor(0, 255, 255);
+  colors_["darkblue"] = RGBColor(0, 0, 139);
+  colors_["darkcyan"] = RGBColor(0, 139, 139);
+  colors_["darkgoldenrod"] = RGBColor(184, 134, 11);
+  colors_["darkgray"] = RGBColor(169, 169, 169);
+  colors_["darkgreen"] = RGBColor(0, 100, 0);
+  colors_["darkgrey"] = RGBColor(169, 169, 169);
+  colors_["darkkhaki"] = RGBColor(189, 183, 107);
+  colors_["darkmagenta"] = RGBColor(139, 0, 139);
+  colors_["darkolivegreen"] = RGBColor(85, 107, 47);
+  colors_["darkorange"] = RGBColor(255, 140, 0);
+  colors_["darkorchid"] = RGBColor(153, 50, 204);
+  colors_["darkred"] = RGBColor(139, 0, 0);
+  colors_["darksalmon"] = RGBColor(233, 150, 122);
+  colors_["darkseagreen"] = RGBColor(143, 188, 143);
+  colors_["darkslateblue"] = RGBColor(72, 61, 139);
+  colors_["darkslategray"] = RGBColor(47, 79, 79);
+  colors_["darkslategrey"] = RGBColor(47, 79, 79);
+  colors_["darkturquoise"] = RGBColor(0, 206, 209);
+  colors_["darkviolet"] = RGBColor(148, 0, 211);
+  colors_["deeppink"] = RGBColor(255, 20, 147);
+  colors_["deepskyblue"] = RGBColor(0, 191, 255);
+  colors_["dimgray"] = RGBColor(105, 105, 105);
+  colors_["dimgrey"] = RGBColor(105, 105, 105);
+  colors_["dodgerblue"] = RGBColor(30, 144, 255);
+  colors_["firebrick"] = RGBColor(178, 34, 34);
+  colors_["floralwhite"] = RGBColor(255, 250, 240);
+  colors_["forestgreen"] = RGBColor(34, 139, 34);
+  colors_["gainsboro"] = RGBColor(220, 220, 220);
+  colors_["ghostwhite"] = RGBColor(248, 248, 255);
+  colors_["gold"] = RGBColor(255, 215, 0);
+  colors_["goldenrod"] = RGBColor(218, 165, 32);
+  colors_["gray"] = RGBColor(190, 190, 190);
+  colors_["green"] = RGBColor(0, 255, 0);
+  colors_["greenyellow"] = RGBColor(173, 255, 47);
+  colors_["grey"] = RGBColor(190, 190, 190);
+  colors_["honeydew"] = RGBColor(240, 255, 240);
+  colors_["hotpink"] = RGBColor(255, 105, 180);
+  colors_["indianred"] = RGBColor(205, 92, 92);
+  colors_["indigo"] = RGBColor(75, 0, 130);
+  colors_["ivory"] = RGBColor(255, 255, 240);
+  colors_["khaki"] = RGBColor(240, 230, 140);
+  colors_["lavender"] = RGBColor(230, 230, 250);
+  colors_["lavenderblush"] = RGBColor(255, 240, 245);
+  colors_["lawngreen"] = RGBColor(124, 252, 0);
+  colors_["lemonchiffon"] = RGBColor(255, 250, 205);
+  colors_["lightblue"] = RGBColor(173, 216, 230);
+  colors_["lightcoral"] = RGBColor(240, 128, 128);
+  colors_["lightcyan"] = RGBColor(224, 255, 255);
+  colors_["lightgoldenrod"] = RGBColor(238, 221, 130);
+  colors_["lightgoldenrodyellow"] = RGBColor(250, 250, 210);
+  colors_["lightgray"] = RGBColor(211, 211, 211);
+  colors_["lightgreen"] = RGBColor(144, 238, 144);
+  colors_["lightgrey"] = RGBColor(211, 211, 211);
+  colors_["lightpink"] = RGBColor(255, 182, 193);
+  colors_["lightsalmon"] = RGBColor(255, 160, 122);
+  colors_["lightseagreen"] = RGBColor(32, 178, 170);
+  colors_["lightskyblue"] = RGBColor(135, 206, 250);
+  colors_["lightslateblue"] = RGBColor(132, 112, 255);
+  colors_["lightslategray"] = RGBColor(119, 136, 153);
+  colors_["lightslategrey"] = RGBColor(119, 136, 153);
+  colors_["lightsteelblue"] = RGBColor(176, 196, 222);
+  colors_["lightyellow"] = RGBColor(255, 255, 224);
+  colors_["limegreen"] = RGBColor(50, 205, 50);
+  colors_["linen"] = RGBColor(250, 240, 230);
+  colors_["magenta"] = RGBColor(255, 0, 255);
+  colors_["maroon"] = RGBColor(176, 48, 96);
+  colors_["mediumaquamarine"] = RGBColor(102, 205, 170);
+  colors_["mediumblue"] = RGBColor(0, 0, 205);
+  colors_["mediumorchid"] = RGBColor(186, 85, 211);
+  colors_["mediumpurple"] = RGBColor(147, 112, 219);
+  colors_["mediumseagreen"] = RGBColor(60, 179, 113);
+  colors_["mediumslateblue"] = RGBColor(123, 104, 238);
+  colors_["mediumspringgreen"] = RGBColor(0, 250, 154);
+  colors_["mediumturquoise"] = RGBColor(72, 209, 204);
+  colors_["mediumvioletred"] = RGBColor(199, 21, 133);
+  colors_["midnightblue"] = RGBColor(25, 25, 112);
+  colors_["mintcream"] = RGBColor(245, 255, 250);
+  colors_["mistyrose"] = RGBColor(255, 228, 225);
+  colors_["moccasin"] = RGBColor(255, 228, 181);
+  colors_["navajowhite"] = RGBColor(255, 222, 173);
+  colors_["navy"] = RGBColor(0, 0, 128);
+  colors_["navyblue"] = RGBColor(0, 0, 128);
+  colors_["oldlace"] = RGBColor(253, 245, 230);
+  colors_["olivedrab"] = RGBColor(107, 142, 35);
+  colors_["orange"] = RGBColor(255, 165, 0);
+  colors_["orangered"] = RGBColor(255, 69, 0);
+  colors_["orchid"] = RGBColor(218, 112, 214);
+  colors_["palegoldenrod"] = RGBColor(238, 232, 170);
+  colors_["palegreen"] = RGBColor(152, 251, 152);
+  colors_["paleturquoise"] = RGBColor(175, 238, 238);
+  colors_["palevioletred"] = RGBColor(219, 112, 147);
+  colors_["papayawhip"] = RGBColor(255, 239, 213);
+  colors_["peachpuff"] = RGBColor(255, 218, 185);
+  colors_["peru"] = RGBColor(205, 133, 63);
+  colors_["pink"] = RGBColor(255, 192, 203);
+  colors_["plum"] = RGBColor(221, 160, 221);
+  colors_["powderblue"] = RGBColor(176, 224, 230);
+  colors_["purple"] = RGBColor(160, 32, 240);
+  colors_["red"] = RGBColor(255, 0, 0);
+  colors_["rosybrown"] = RGBColor(188, 143, 143);
+  colors_["royalblue"] = RGBColor(65, 105, 225);
+  colors_["saddlebrown"] = RGBColor(139, 69, 19);
+  colors_["salmon"] = RGBColor(250, 128, 114);
+  colors_["sandybrown"] = RGBColor(244, 164, 96);
+  colors_["seagreen"] = RGBColor(46, 139, 87);
+  colors_["seashell"] = RGBColor(255, 245, 238);
+  colors_["sgibeet"] = RGBColor(142, 56, 142);
+  colors_["sgibrightgray"] = RGBColor(197, 193, 170);
+  colors_["sgibrightgrey"] = RGBColor(197, 193, 170);
+  colors_["sgichartreuse"] = RGBColor(113, 198, 113);
+  colors_["sgidarkgray"] = RGBColor(85, 85, 85);
+  colors_["sgidarkgrey"] = RGBColor(85, 85, 85);
+  colors_["sgilightblue"] = RGBColor(125, 158, 192);
+  colors_["sgilightgray"] = RGBColor(170, 170, 170);
+  colors_["sgilightgrey"] = RGBColor(170, 170, 170);
+  colors_["sgimediumgray"] = RGBColor(132, 132, 132);
+  colors_["sgimediumgrey"] = RGBColor(132, 132, 132);
+  colors_["sgiolivedrab"] = RGBColor(142, 142, 56);
+  colors_["sgisalmon"] = RGBColor(198, 113, 113);
+  colors_["sgislateblue"] = RGBColor(113, 113, 198);
+  colors_["sgiteal"] = RGBColor(56, 142, 142);
+  colors_["sgiverydarkgray"] = RGBColor(40, 40, 40);
+  colors_["sgiverydarkgrey"] = RGBColor(40, 40, 40);
+  colors_["sgiverylightgray"] = RGBColor(214, 214, 214);
+  colors_["sgiverylightgrey"] = RGBColor(214, 214, 214);
+  colors_["sienna"] = RGBColor(160, 82, 45);
+  colors_["skyblue"] = RGBColor(135, 206, 235);
+  colors_["slateblue"] = RGBColor(106, 90, 205);
+  colors_["slategray"] = RGBColor(112, 128, 144);
+  colors_["slategrey"] = RGBColor(112, 128, 144);
+  colors_["snow"] = RGBColor(255, 250, 250);
+  colors_["springgreen"] = RGBColor(0, 255, 127);
+  colors_["steelblue"] = RGBColor(70, 130, 180);
+  colors_["tan"] = RGBColor(210, 180, 140);
+  colors_["thistle"] = RGBColor(216, 191, 216);
+  colors_["tomato"] = RGBColor(255, 99, 71);
+  colors_["turquoise"] = RGBColor(64, 224, 208);
+  colors_["violet"] = RGBColor(238, 130, 238);
+  colors_["violetred"] = RGBColor(208, 32, 144);
+  colors_["wheat"] = RGBColor(245, 222, 179);
+  colors_["white"] = RGBColor(255, 255, 255);
+  colors_["whitesmoke"] = RGBColor(245, 245, 245);
+  colors_["yellow"] = RGBColor(255, 255, 0);
+  colors_["yellowgreen"] = RGBColor(154, 205, 50);
+}
diff --git a/src/Bpp/Graphics/Molscript/MolscriptColorSet.h b/src/Bpp/Graphics/Molscript/MolscriptColorSet.h
new file mode 100644
index 0000000..f34aba0
--- /dev/null
+++ b/src/Bpp/Graphics/Molscript/MolscriptColorSet.h
@@ -0,0 +1,63 @@
+//
+// File: MolscriptColorSet.h
+// Created by: Julien Dutheil
+// Created on: Mon Apr 14 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2008)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _MOLSCRIPTCOLORSET_H_
+#define _MOLSCRIPTCOLORSET_H_
+
+#include "../ColorSet.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Molscript color definitions.
+ */
+class MolscriptColorSet:
+  public AbstractColorSet
+{
+  public:
+    MolscriptColorSet();
+    virtual ~MolscriptColorSet() {}
+
+};
+
+} // end of namespace bpp;
+
+#endif //_MOLSCRIPTCOLORSET_H_
+
diff --git a/src/Bpp/Graphics/Point2D.h b/src/Bpp/Graphics/Point2D.h
new file mode 100644
index 0000000..5def49d
--- /dev/null
+++ b/src/Bpp/Graphics/Point2D.h
@@ -0,0 +1,146 @@
+//
+// File Point2D.h (from file Coord.h)
+// Author : Sylvain Gaillard
+//          Julien Dutheil
+//
+
+/*
+   Copyright or © or Copr. CNRS, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for population genetics analysis.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use, 
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info". 
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability. 
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or 
+   data to be ensured and,  more generally, to use and operate it in the 
+   same conditions as regards security. 
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+   */
+
+#ifndef _POINT2D_H_
+#define _POINT2D_H_
+
+#include "../Clonable.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief The Point2D class.
+   *
+   * This is a simple class designed to store the coordinates of a point.
+   * The type of the two coordinates is defined as a template.
+   *
+   * @author Sylvain Gaillard, Julien Dutheil
+   */
+  template<class T> class Point2D:
+    public virtual Clonable
+  {
+    private:
+      T x_;
+      T y_;
+
+    public: // Constructors and destructor :
+
+      /**
+       * @brief Build a new Point2D from two values.
+       * 
+       * The two values are set to 0 if no parametre is given to the constructor.
+       *
+       * @param x The longitude or abscissa.
+       * @param y The latitude or ordinate.
+       */
+      Point2D<T>(const T x = 0, const T y = 0): x_(x), y_(y) {}
+
+      /**
+       * @brief Destroy the Point2D object.
+       */
+      virtual ~Point2D() {}
+
+    public: // Methodes
+
+      /**
+       * @brief Implement the Clonable interface.
+       */
+      Point2D<T>* clone() const { return new Point2D(*this); }
+
+      /**
+       * @brief Set the two values.
+       */
+      void setCoord(const T x, const T y);
+
+      /**
+       * @brief Set only the longitude.
+       */
+      void setX(const T x) { x_ = x; }
+
+      /**
+       * @brief Set only the latitude.
+       */
+      void setY(const T y) { y_ = y; }
+
+      /**
+       * @brief Get the longitude.
+       */
+      const T& getX() const { return x_; }
+
+      /**
+       * @brief Get the latitude.
+       */
+      const T& getY() const { return y_; }
+
+      /**
+       * @brief Compares two Point2D objets.
+       *
+       * Return true if the coordinates of the 2 Point2D are equals.
+       */
+      bool hasSameCoordsAs(const Point2D<T>& coord) const
+      {
+        return x_ == coord.x_ && y_ == coord.y_;
+      }
+
+      /**
+       * @brief The == operator.
+       *
+       * Return true if the coordinates of the 2 Point2Ds are equals.
+       * Does the same as the asSameCoords() methode.
+       */
+      virtual bool operator== (const Point2D<T>& coord) const
+      {
+        return hasSameCoordsAs(coord);
+      }
+
+      /**
+       * @brief The != operator.
+       */
+      virtual bool operator!= (const Point2D<T>& coord) const
+      {
+        return !hasSameCoordsAs(coord);
+      }
+
+  };
+
+} //end of namespace bpp;
+
+#endif // _POINT2D_H_
+
diff --git a/src/Bpp/Graphics/Point2DTools.h b/src/Bpp/Graphics/Point2DTools.h
new file mode 100644
index 0000000..bda32b0
--- /dev/null
+++ b/src/Bpp/Graphics/Point2DTools.h
@@ -0,0 +1,79 @@
+//
+// File Point2DTools.h (from CoordsTools.h)
+// Author : Sylvain Gaillard
+//
+
+/*
+   Copyright or © or Copr. CNRS, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for population genetics analysis.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use, 
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info". 
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability. 
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or 
+   data to be ensured and,  more generally, to use and operate it in the 
+   same conditions as regards security. 
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+   */
+
+#ifndef _POINT2DTOOLS_H_
+#define _POINT2DTOOLS_H_
+
+// From local
+#include "Point2D.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Some functions to deal with Point2D.
+   *
+   * @author Sylvain Gaillard
+   */
+
+  class CoordsTools
+  {
+    public:
+      /**
+       * @brief Get the distance between two Coord objects.
+       *
+       * @param co1 A Point2D object.
+       * @param co2 An other Point2D object.
+       * @return the distance between the 2 points as a double
+       */
+      template<class T> static double getDistanceBetween(const Point2D<T>& co1, const Point2D<T>& co2)
+      {
+        T base, height;
+        base = co1.getX() - co2.getX();
+        height = co1.getY() - co2.getY();
+        base = base * base;
+        height = height * height;
+        return sqrt((double)base + (double)height);
+      }
+
+  };
+
+} //end of namespace bpp;
+
+#endif // _POINT2DTOOLS_H_
+
diff --git a/src/Bpp/Graphics/R/RColorSet.cpp b/src/Bpp/Graphics/R/RColorSet.cpp
new file mode 100644
index 0000000..96c2ba1
--- /dev/null
+++ b/src/Bpp/Graphics/R/RColorSet.cpp
@@ -0,0 +1,704 @@
+//
+// File: RColorSet.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Apr 14 2008
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2008)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "RColorSet.h"
+
+using namespace bpp;
+
+RColorSet::RColorSet()
+{
+  colors_["white"] = RGBColor(255, 255, 255);
+  colors_["aliceblue"] = RGBColor(240, 248, 255);
+  colors_["antiquewhite"] = RGBColor(250, 235, 215);
+  colors_["antiquewhite1"] = RGBColor(255, 239, 219);
+  colors_["antiquewhite2"] = RGBColor(238, 223, 204);
+  colors_["antiquewhite3"] = RGBColor(205, 192, 176);
+  colors_["antiquewhite4"] = RGBColor(139, 131, 120);
+  colors_["aquamarine"] = RGBColor(127, 255, 212);
+  colors_["aquamarine1"] = RGBColor(127, 255, 212);
+  colors_["aquamarine2"] = RGBColor(118, 238, 198);
+  colors_["aquamarine3"] = RGBColor(102, 205, 170);
+  colors_["aquamarine4"] = RGBColor(69, 139, 116);
+  colors_["azure"] = RGBColor(240, 255, 255);
+  colors_["azure1"] = RGBColor(240, 255, 255);
+  colors_["azure2"] = RGBColor(224, 238, 238);
+  colors_["azure3"] = RGBColor(193, 205, 205);
+  colors_["azure4"] = RGBColor(131, 139, 139);
+  colors_["beige"] = RGBColor(245, 245, 220);
+  colors_["bisque"] = RGBColor(255, 228, 196);
+  colors_["bisque1"] = RGBColor(255, 228, 196);
+  colors_["bisque2"] = RGBColor(238, 213, 183);
+  colors_["bisque3"] = RGBColor(205, 183, 158);
+  colors_["bisque4"] = RGBColor(139, 125, 107);
+  colors_["black"] = RGBColor(0, 0, 0);
+  colors_["blanchedalmond"] = RGBColor(255, 235, 205);
+  colors_["blue"] = RGBColor(0, 0, 255);
+  colors_["blue1"] = RGBColor(0, 0, 255);
+  colors_["blue2"] = RGBColor(0, 0, 238);
+  colors_["blue3"] = RGBColor(0, 0, 205);
+  colors_["blue4"] = RGBColor(0, 0, 139);
+  colors_["blueviolet"] = RGBColor(138, 43, 226);
+  colors_["brown"] = RGBColor(165, 42, 42);
+  colors_["brown1"] = RGBColor(255, 64, 64);
+  colors_["brown2"] = RGBColor(238, 59, 59);
+  colors_["brown3"] = RGBColor(205, 51, 51);
+  colors_["brown4"] = RGBColor(139, 35, 35);
+  colors_["burlywood"] = RGBColor(222, 184, 135);
+  colors_["burlywood1"] = RGBColor(255, 211, 155);
+  colors_["burlywood2"] = RGBColor(238, 197, 145);
+  colors_["burlywood3"] = RGBColor(205, 170, 125);
+  colors_["burlywood4"] = RGBColor(139, 115, 85);
+  colors_["cadetblue"] = RGBColor(95, 158, 160);
+  colors_["cadetblue1"] = RGBColor(152, 245, 255);
+  colors_["cadetblue2"] = RGBColor(142, 229, 238);
+  colors_["cadetblue3"] = RGBColor(122, 197, 205);
+  colors_["cadetblue4"] = RGBColor(83, 134, 139);
+  colors_["chartreuse"] = RGBColor(127, 255, 0);
+  colors_["chartreuse1"] = RGBColor(127, 255, 0);
+  colors_["chartreuse2"] = RGBColor(118, 238, 0);
+  colors_["chartreuse3"] = RGBColor(102, 205, 0);
+  colors_["chartreuse4"] = RGBColor(69, 139, 0);
+  colors_["chocolate"] = RGBColor(210, 105, 30);
+  colors_["chocolate1"] = RGBColor(255, 127, 36);
+  colors_["chocolate2"] = RGBColor(238, 118, 33);
+  colors_["chocolate3"] = RGBColor(205, 102, 29);
+  colors_["chocolate4"] = RGBColor(139, 69, 19);
+  colors_["coral"] = RGBColor(255, 127, 80);
+  colors_["coral1"] = RGBColor(255, 114, 86);
+  colors_["coral2"] = RGBColor(238, 106, 80);
+  colors_["coral3"] = RGBColor(205, 91, 69);
+  colors_["coral4"] = RGBColor(139, 62, 47);
+  colors_["cornflowerblue"] = RGBColor(100, 149, 237);
+  colors_["cornsilk"] = RGBColor(255, 248, 220);
+  colors_["cornsilk1"] = RGBColor(255, 248, 220);
+  colors_["cornsilk2"] = RGBColor(238, 232, 205);
+  colors_["cornsilk3"] = RGBColor(205, 200, 177);
+  colors_["cornsilk4"] = RGBColor(139, 136, 120);
+  colors_["cyan"] = RGBColor(0, 255, 255);
+  colors_["cyan1"] = RGBColor(0, 255, 255);
+  colors_["cyan2"] = RGBColor(0, 238, 238);
+  colors_["cyan3"] = RGBColor(0, 205, 205);
+  colors_["cyan4"] = RGBColor(0, 139, 139);
+  colors_["darkblue"] = RGBColor(0, 0, 139);
+  colors_["darkcyan"] = RGBColor(0, 139, 139);
+  colors_["darkgoldenrod"] = RGBColor(184, 134, 11);
+  colors_["darkgoldenrod1"] = RGBColor(255, 185, 15);
+  colors_["darkgoldenrod2"] = RGBColor(238, 173, 14);
+  colors_["darkgoldenrod3"] = RGBColor(205, 149, 12);
+  colors_["darkgoldenrod4"] = RGBColor(139, 101, 8);
+  colors_["darkgray"] = RGBColor(169, 169, 169);
+  colors_["darkgreen"] = RGBColor(0, 100, 0);
+  colors_["darkgrey"] = RGBColor(169, 169, 169);
+  colors_["darkkhaki"] = RGBColor(189, 183, 107);
+  colors_["darkmagenta"] = RGBColor(139, 0, 139);
+  colors_["darkolivegreen"] = RGBColor(85, 107, 47);
+  colors_["darkolivegreen1"] = RGBColor(202, 255, 112);
+  colors_["darkolivegreen2"] = RGBColor(188, 238, 104);
+  colors_["darkolivegreen3"] = RGBColor(162, 205, 90);
+  colors_["darkolivegreen4"] = RGBColor(110, 139, 61);
+  colors_["darkorange"] = RGBColor(255, 140, 0);
+  colors_["darkorange1"] = RGBColor(255, 127, 0);
+  colors_["darkorange2"] = RGBColor(238, 118, 0);
+  colors_["darkorange3"] = RGBColor(205, 102, 0);
+  colors_["darkorange4"] = RGBColor(139, 69, 0);
+  colors_["darkorchid"] = RGBColor(153, 50, 204);
+  colors_["darkorchid1"] = RGBColor(191, 62, 255);
+  colors_["darkorchid2"] = RGBColor(178, 58, 238);
+  colors_["darkorchid3"] = RGBColor(154, 50, 205);
+  colors_["darkorchid4"] = RGBColor(104, 34, 139);
+  colors_["darkred"] = RGBColor(139, 0, 0);
+  colors_["darksalmon"] = RGBColor(233, 150, 122);
+  colors_["darkseagreen"] = RGBColor(143, 188, 143);
+  colors_["darkseagreen1"] = RGBColor(193, 255, 193);
+  colors_["darkseagreen2"] = RGBColor(180, 238, 180);
+  colors_["darkseagreen3"] = RGBColor(155, 205, 155);
+  colors_["darkseagreen4"] = RGBColor(105, 139, 105);
+  colors_["darkslateblue"] = RGBColor(72, 61, 139);
+  colors_["darkslategray"] = RGBColor(47, 79, 79);
+  colors_["darkslategray1"] = RGBColor(151, 255, 255);
+  colors_["darkslategray2"] = RGBColor(141, 238, 238);
+  colors_["darkslategray3"] = RGBColor(121, 205, 205);
+  colors_["darkslategray4"] = RGBColor(82, 139, 139);
+  colors_["darkslategrey"] = RGBColor(47, 79, 79);
+  colors_["darkturquoise"] = RGBColor(0, 206, 209);
+  colors_["darkviolet"] = RGBColor(148, 0, 211);
+  colors_["deeppink"] = RGBColor(255, 20, 147);
+  colors_["deeppink1"] = RGBColor(255, 20, 147);
+  colors_["deeppink2"] = RGBColor(238, 18, 137);
+  colors_["deeppink3"] = RGBColor(205, 16, 118);
+  colors_["deeppink4"] = RGBColor(139, 10, 80);
+  colors_["deepskyblue"] = RGBColor(0, 191, 255);
+  colors_["deepskyblue1"] = RGBColor(0, 191, 255);
+  colors_["deepskyblue2"] = RGBColor(0, 178, 238);
+  colors_["deepskyblue3"] = RGBColor(0, 154, 205);
+  colors_["deepskyblue4"] = RGBColor(0, 104, 139);
+  colors_["dimgray"] = RGBColor(105, 105, 105);
+  colors_["dimgrey"] = RGBColor(105, 105, 105);
+  colors_["dodgerblue"] = RGBColor(30, 144, 255);
+  colors_["dodgerblue1"] = RGBColor(30, 144, 255);
+  colors_["dodgerblue2"] = RGBColor(28, 134, 238);
+  colors_["dodgerblue3"] = RGBColor(24, 116, 205);
+  colors_["dodgerblue4"] = RGBColor(16, 78, 139);
+  colors_["firebrick"] = RGBColor(178, 34, 34);
+  colors_["firebrick1"] = RGBColor(255, 48, 48);
+  colors_["firebrick2"] = RGBColor(238, 44, 44);
+  colors_["firebrick3"] = RGBColor(205, 38, 38);
+  colors_["firebrick4"] = RGBColor(139, 26, 26);
+  colors_["floralwhite"] = RGBColor(255, 250, 240);
+  colors_["forestgreen"] = RGBColor(34, 139, 34);
+  colors_["gainsboro"] = RGBColor(220, 220, 220);
+  colors_["ghostwhite"] = RGBColor(248, 248, 255);
+  colors_["gold"] = RGBColor(255, 215, 0);
+  colors_["gold1"] = RGBColor(255, 215, 0);
+  colors_["gold2"] = RGBColor(238, 201, 0);
+  colors_["gold3"] = RGBColor(205, 173, 0);
+  colors_["gold4"] = RGBColor(139, 117, 0);
+  colors_["goldenrod"] = RGBColor(218, 165, 32);
+  colors_["goldenrod1"] = RGBColor(255, 193, 37);
+  colors_["goldenrod2"] = RGBColor(238, 180, 34);
+  colors_["goldenrod3"] = RGBColor(205, 155, 29);
+  colors_["goldenrod4"] = RGBColor(139, 105, 20);
+  colors_["gray"] = RGBColor(190, 190, 190);
+  colors_["gray0"] = RGBColor(0, 0, 0);
+  colors_["gray1"] = RGBColor(3, 3, 3);
+  colors_["gray2"] = RGBColor(5, 5, 5);
+  colors_["gray3"] = RGBColor(8, 8, 8);
+  colors_["gray4"] = RGBColor(10, 10, 10);
+  colors_["gray5"] = RGBColor(13, 13, 13);
+  colors_["gray6"] = RGBColor(15, 15, 15);
+  colors_["gray7"] = RGBColor(18, 18, 18);
+  colors_["gray8"] = RGBColor(20, 20, 20);
+  colors_["gray9"] = RGBColor(23, 23, 23);
+  colors_["gray10"] = RGBColor(26, 26, 26);
+  colors_["gray11"] = RGBColor(28, 28, 28);
+  colors_["gray12"] = RGBColor(31, 31, 31);
+  colors_["gray13"] = RGBColor(33, 33, 33);
+  colors_["gray14"] = RGBColor(36, 36, 36);
+  colors_["gray15"] = RGBColor(38, 38, 38);
+  colors_["gray16"] = RGBColor(41, 41, 41);
+  colors_["gray17"] = RGBColor(43, 43, 43);
+  colors_["gray18"] = RGBColor(46, 46, 46);
+  colors_["gray19"] = RGBColor(48, 48, 48);
+  colors_["gray20"] = RGBColor(51, 51, 51);
+  colors_["gray21"] = RGBColor(54, 54, 54);
+  colors_["gray22"] = RGBColor(56, 56, 56);
+  colors_["gray23"] = RGBColor(59, 59, 59);
+  colors_["gray24"] = RGBColor(61, 61, 61);
+  colors_["gray25"] = RGBColor(64, 64, 64);
+  colors_["gray26"] = RGBColor(66, 66, 66);
+  colors_["gray27"] = RGBColor(69, 69, 69);
+  colors_["gray28"] = RGBColor(71, 71, 71);
+  colors_["gray29"] = RGBColor(74, 74, 74);
+  colors_["gray30"] = RGBColor(77, 77, 77);
+  colors_["gray31"] = RGBColor(79, 79, 79);
+  colors_["gray32"] = RGBColor(82, 82, 82);
+  colors_["gray33"] = RGBColor(84, 84, 84);
+  colors_["gray34"] = RGBColor(87, 87, 87);
+  colors_["gray35"] = RGBColor(89, 89, 89);
+  colors_["gray36"] = RGBColor(92, 92, 92);
+  colors_["gray37"] = RGBColor(94, 94, 94);
+  colors_["gray38"] = RGBColor(97, 97, 97);
+  colors_["gray39"] = RGBColor(99, 99, 99);
+  colors_["gray40"] = RGBColor(102, 102, 102);
+  colors_["gray41"] = RGBColor(105, 105, 105);
+  colors_["gray42"] = RGBColor(107, 107, 107);
+  colors_["gray43"] = RGBColor(110, 110, 110);
+  colors_["gray44"] = RGBColor(112, 112, 112);
+  colors_["gray45"] = RGBColor(115, 115, 115);
+  colors_["gray46"] = RGBColor(117, 117, 117);
+  colors_["gray47"] = RGBColor(120, 120, 120);
+  colors_["gray48"] = RGBColor(122, 122, 122);
+  colors_["gray49"] = RGBColor(125, 125, 125);
+  colors_["gray50"] = RGBColor(127, 127, 127);
+  colors_["gray51"] = RGBColor(130, 130, 130);
+  colors_["gray52"] = RGBColor(133, 133, 133);
+  colors_["gray53"] = RGBColor(135, 135, 135);
+  colors_["gray54"] = RGBColor(138, 138, 138);
+  colors_["gray55"] = RGBColor(140, 140, 140);
+  colors_["gray56"] = RGBColor(143, 143, 143);
+  colors_["gray57"] = RGBColor(145, 145, 145);
+  colors_["gray58"] = RGBColor(148, 148, 148);
+  colors_["gray59"] = RGBColor(150, 150, 150);
+  colors_["gray60"] = RGBColor(153, 153, 153);
+  colors_["gray61"] = RGBColor(156, 156, 156);
+  colors_["gray62"] = RGBColor(158, 158, 158);
+  colors_["gray63"] = RGBColor(161, 161, 161);
+  colors_["gray64"] = RGBColor(163, 163, 163);
+  colors_["gray65"] = RGBColor(166, 166, 166);
+  colors_["gray66"] = RGBColor(168, 168, 168);
+  colors_["gray67"] = RGBColor(171, 171, 171);
+  colors_["gray68"] = RGBColor(173, 173, 173);
+  colors_["gray69"] = RGBColor(176, 176, 176);
+  colors_["gray70"] = RGBColor(179, 179, 179);
+  colors_["gray71"] = RGBColor(181, 181, 181);
+  colors_["gray72"] = RGBColor(184, 184, 184);
+  colors_["gray73"] = RGBColor(186, 186, 186);
+  colors_["gray74"] = RGBColor(189, 189, 189);
+  colors_["gray75"] = RGBColor(191, 191, 191);
+  colors_["gray76"] = RGBColor(194, 194, 194);
+  colors_["gray77"] = RGBColor(196, 196, 196);
+  colors_["gray78"] = RGBColor(199, 199, 199);
+  colors_["gray79"] = RGBColor(201, 201, 201);
+  colors_["gray80"] = RGBColor(204, 204, 204);
+  colors_["gray81"] = RGBColor(207, 207, 207);
+  colors_["gray82"] = RGBColor(209, 209, 209);
+  colors_["gray83"] = RGBColor(212, 212, 212);
+  colors_["gray84"] = RGBColor(214, 214, 214);
+  colors_["gray85"] = RGBColor(217, 217, 217);
+  colors_["gray86"] = RGBColor(219, 219, 219);
+  colors_["gray87"] = RGBColor(222, 222, 222);
+  colors_["gray88"] = RGBColor(224, 224, 224);
+  colors_["gray89"] = RGBColor(227, 227, 227);
+  colors_["gray90"] = RGBColor(229, 229, 229);
+  colors_["gray91"] = RGBColor(232, 232, 232);
+  colors_["gray92"] = RGBColor(235, 235, 235);
+  colors_["gray93"] = RGBColor(237, 237, 237);
+  colors_["gray94"] = RGBColor(240, 240, 240);
+  colors_["gray95"] = RGBColor(242, 242, 242);
+  colors_["gray96"] = RGBColor(245, 245, 245);
+  colors_["gray97"] = RGBColor(247, 247, 247);
+  colors_["gray98"] = RGBColor(250, 250, 250);
+  colors_["gray99"] = RGBColor(252, 252, 252);
+  colors_["gray100"] = RGBColor(255, 255, 255);
+  colors_["green"] = RGBColor(0, 255, 0);
+  colors_["green1"] = RGBColor(0, 255, 0);
+  colors_["green2"] = RGBColor(0, 238, 0);
+  colors_["green3"] = RGBColor(0, 205, 0);
+  colors_["green4"] = RGBColor(0, 139, 0);
+  colors_["greenyellow"] = RGBColor(173, 255, 47);
+  colors_["grey"] = RGBColor(190, 190, 190);
+  colors_["grey0"] = RGBColor(0, 0, 0);
+  colors_["grey1"] = RGBColor(3, 3, 3);
+  colors_["grey2"] = RGBColor(5, 5, 5);
+  colors_["grey3"] = RGBColor(8, 8, 8);
+  colors_["grey4"] = RGBColor(10, 10, 10);
+  colors_["grey5"] = RGBColor(13, 13, 13);
+  colors_["grey6"] = RGBColor(15, 15, 15);
+  colors_["grey7"] = RGBColor(18, 18, 18);
+  colors_["grey8"] = RGBColor(20, 20, 20);
+  colors_["grey9"] = RGBColor(23, 23, 23);
+  colors_["grey10"] = RGBColor(26, 26, 26);
+  colors_["grey11"] = RGBColor(28, 28, 28);
+  colors_["grey12"] = RGBColor(31, 31, 31);
+  colors_["grey13"] = RGBColor(33, 33, 33);
+  colors_["grey14"] = RGBColor(36, 36, 36);
+  colors_["grey15"] = RGBColor(38, 38, 38);
+  colors_["grey16"] = RGBColor(41, 41, 41);
+  colors_["grey17"] = RGBColor(43, 43, 43);
+  colors_["grey18"] = RGBColor(46, 46, 46);
+  colors_["grey19"] = RGBColor(48, 48, 48);
+  colors_["grey20"] = RGBColor(51, 51, 51);
+  colors_["grey21"] = RGBColor(54, 54, 54);
+  colors_["grey22"] = RGBColor(56, 56, 56);
+  colors_["grey23"] = RGBColor(59, 59, 59);
+  colors_["grey24"] = RGBColor(61, 61, 61);
+  colors_["grey25"] = RGBColor(64, 64, 64);
+  colors_["grey26"] = RGBColor(66, 66, 66);
+  colors_["grey27"] = RGBColor(69, 69, 69);
+  colors_["grey28"] = RGBColor(71, 71, 71);
+  colors_["grey29"] = RGBColor(74, 74, 74);
+  colors_["grey30"] = RGBColor(77, 77, 77);
+  colors_["grey31"] = RGBColor(79, 79, 79);
+  colors_["grey32"] = RGBColor(82, 82, 82);
+  colors_["grey33"] = RGBColor(84, 84, 84);
+  colors_["grey34"] = RGBColor(87, 87, 87);
+  colors_["grey35"] = RGBColor(89, 89, 89);
+  colors_["grey36"] = RGBColor(92, 92, 92);
+  colors_["grey37"] = RGBColor(94, 94, 94);
+  colors_["grey38"] = RGBColor(97, 97, 97);
+  colors_["grey39"] = RGBColor(99, 99, 99);
+  colors_["grey40"] = RGBColor(102, 102, 102);
+  colors_["grey41"] = RGBColor(105, 105, 105);
+  colors_["grey42"] = RGBColor(107, 107, 107);
+  colors_["grey43"] = RGBColor(110, 110, 110);
+  colors_["grey44"] = RGBColor(112, 112, 112);
+  colors_["grey45"] = RGBColor(115, 115, 115);
+  colors_["grey46"] = RGBColor(117, 117, 117);
+  colors_["grey47"] = RGBColor(120, 120, 120);
+  colors_["grey48"] = RGBColor(122, 122, 122);
+  colors_["grey49"] = RGBColor(125, 125, 125);
+  colors_["grey50"] = RGBColor(127, 127, 127);
+  colors_["grey51"] = RGBColor(130, 130, 130);
+  colors_["grey52"] = RGBColor(133, 133, 133);
+  colors_["grey53"] = RGBColor(135, 135, 135);
+  colors_["grey54"] = RGBColor(138, 138, 138);
+  colors_["grey55"] = RGBColor(140, 140, 140);
+  colors_["grey56"] = RGBColor(143, 143, 143);
+  colors_["grey57"] = RGBColor(145, 145, 145);
+  colors_["grey58"] = RGBColor(148, 148, 148);
+  colors_["grey59"] = RGBColor(150, 150, 150);
+  colors_["grey60"] = RGBColor(153, 153, 153);
+  colors_["grey61"] = RGBColor(156, 156, 156);
+  colors_["grey62"] = RGBColor(158, 158, 158);
+  colors_["grey63"] = RGBColor(161, 161, 161);
+  colors_["grey64"] = RGBColor(163, 163, 163);
+  colors_["grey65"] = RGBColor(166, 166, 166);
+  colors_["grey66"] = RGBColor(168, 168, 168);
+  colors_["grey67"] = RGBColor(171, 171, 171);
+  colors_["grey68"] = RGBColor(173, 173, 173);
+  colors_["grey69"] = RGBColor(176, 176, 176);
+  colors_["grey70"] = RGBColor(179, 179, 179);
+  colors_["grey71"] = RGBColor(181, 181, 181);
+  colors_["grey72"] = RGBColor(184, 184, 184);
+  colors_["grey73"] = RGBColor(186, 186, 186);
+  colors_["grey74"] = RGBColor(189, 189, 189);
+  colors_["grey75"] = RGBColor(191, 191, 191);
+  colors_["grey76"] = RGBColor(194, 194, 194);
+  colors_["grey77"] = RGBColor(196, 196, 196);
+  colors_["grey78"] = RGBColor(199, 199, 199);
+  colors_["grey79"] = RGBColor(201, 201, 201);
+  colors_["grey80"] = RGBColor(204, 204, 204);
+  colors_["grey81"] = RGBColor(207, 207, 207);
+  colors_["grey82"] = RGBColor(209, 209, 209);
+  colors_["grey83"] = RGBColor(212, 212, 212);
+  colors_["grey84"] = RGBColor(214, 214, 214);
+  colors_["grey85"] = RGBColor(217, 217, 217);
+  colors_["grey86"] = RGBColor(219, 219, 219);
+  colors_["grey87"] = RGBColor(222, 222, 222);
+  colors_["grey88"] = RGBColor(224, 224, 224);
+  colors_["grey89"] = RGBColor(227, 227, 227);
+  colors_["grey90"] = RGBColor(229, 229, 229);
+  colors_["grey91"] = RGBColor(232, 232, 232);
+  colors_["grey92"] = RGBColor(235, 235, 235);
+  colors_["grey93"] = RGBColor(237, 237, 237);
+  colors_["grey94"] = RGBColor(240, 240, 240);
+  colors_["grey95"] = RGBColor(242, 242, 242);
+  colors_["grey96"] = RGBColor(245, 245, 245);
+  colors_["grey97"] = RGBColor(247, 247, 247);
+  colors_["grey98"] = RGBColor(250, 250, 250);
+  colors_["grey99"] = RGBColor(252, 252, 252);
+  colors_["grey100"] = RGBColor(255, 255, 255);
+  colors_["honeydew"] = RGBColor(240, 255, 240);
+  colors_["honeydew1"] = RGBColor(240, 255, 240);
+  colors_["honeydew2"] = RGBColor(224, 238, 224);
+  colors_["honeydew3"] = RGBColor(193, 205, 193);
+  colors_["honeydew4"] = RGBColor(131, 139, 131);
+  colors_["hotpink"] = RGBColor(255, 105, 180);
+  colors_["hotpink1"] = RGBColor(255, 110, 180);
+  colors_["hotpink2"] = RGBColor(238, 106, 167);
+  colors_["hotpink3"] = RGBColor(205, 96, 144);
+  colors_["hotpink4"] = RGBColor(139, 58, 98);
+  colors_["indianred"] = RGBColor(205, 92, 92);
+  colors_["indianred1"] = RGBColor(255, 106, 106);
+  colors_["indianred2"] = RGBColor(238, 99, 99);
+  colors_["indianred3"] = RGBColor(205, 85, 85);
+  colors_["indianred4"] = RGBColor(139, 58, 58);
+  colors_["ivory"] = RGBColor(255, 255, 240);
+  colors_["ivory1"] = RGBColor(255, 255, 240);
+  colors_["ivory2"] = RGBColor(238, 238, 224);
+  colors_["ivory3"] = RGBColor(205, 205, 193);
+  colors_["ivory4"] = RGBColor(139, 139, 131);
+  colors_["khaki"] = RGBColor(240, 230, 140);
+  colors_["khaki1"] = RGBColor(255, 246, 143);
+  colors_["khaki2"] = RGBColor(238, 230, 133);
+  colors_["khaki3"] = RGBColor(205, 198, 115);
+  colors_["khaki4"] = RGBColor(139, 134, 78);
+  colors_["lavender"] = RGBColor(230, 230, 250);
+  colors_["lavenderblush"] = RGBColor(255, 240, 245);
+  colors_["lavenderblush1"] = RGBColor(255, 240, 245);
+  colors_["lavenderblush2"] = RGBColor(238, 224, 229);
+  colors_["lavenderblush3"] = RGBColor(205, 193, 197);
+  colors_["lavenderblush4"] = RGBColor(139, 131, 134);
+  colors_["lawngreen"] = RGBColor(124, 252, 0);
+  colors_["lemonchiffon"] = RGBColor(255, 250, 205);
+  colors_["lemonchiffon1"] = RGBColor(255, 250, 205);
+  colors_["lemonchiffon2"] = RGBColor(238, 233, 191);
+  colors_["lemonchiffon3"] = RGBColor(205, 201, 165);
+  colors_["lemonchiffon4"] = RGBColor(139, 137, 112);
+  colors_["lightblue"] = RGBColor(173, 216, 230);
+  colors_["lightblue1"] = RGBColor(191, 239, 255);
+  colors_["lightblue2"] = RGBColor(178, 223, 238);
+  colors_["lightblue3"] = RGBColor(154, 192, 205);
+  colors_["lightblue4"] = RGBColor(104, 131, 139);
+  colors_["lightcoral"] = RGBColor(240, 128, 128);
+  colors_["lightcyan"] = RGBColor(224, 255, 255);
+  colors_["lightcyan1"] = RGBColor(224, 255, 255);
+  colors_["lightcyan2"] = RGBColor(209, 238, 238);
+  colors_["lightcyan3"] = RGBColor(180, 205, 205);
+  colors_["lightcyan4"] = RGBColor(122, 139, 139);
+  colors_["lightgoldenrod"] = RGBColor(238, 221, 130);
+  colors_["lightgoldenrod1"] = RGBColor(255, 236, 139);
+  colors_["lightgoldenrod2"] = RGBColor(238, 220, 130);
+  colors_["lightgoldenrod3"] = RGBColor(205, 190, 112);
+  colors_["lightgoldenrod4"] = RGBColor(139, 129, 76);
+  colors_["lightgoldenrodyellow"] = RGBColor(250, 250, 210);
+  colors_["lightgray"] = RGBColor(211, 211, 211);
+  colors_["lightgreen"] = RGBColor(144, 238, 144);
+  colors_["lightgrey"] = RGBColor(211, 211, 211);
+  colors_["lightpink"] = RGBColor(255, 182, 193);
+  colors_["lightpink1"] = RGBColor(255, 174, 185);
+  colors_["lightpink2"] = RGBColor(238, 162, 173);
+  colors_["lightpink3"] = RGBColor(205, 140, 149);
+  colors_["lightpink4"] = RGBColor(139, 95, 101);
+  colors_["lightsalmon"] = RGBColor(255, 160, 122);
+  colors_["lightsalmon1"] = RGBColor(255, 160, 122);
+  colors_["lightsalmon2"] = RGBColor(238, 149, 114);
+  colors_["lightsalmon3"] = RGBColor(205, 129, 98);
+  colors_["lightsalmon4"] = RGBColor(139, 87, 66);
+  colors_["lightseagreen"] = RGBColor(32, 178, 170);
+  colors_["lightskyblue"] = RGBColor(135, 206, 250);
+  colors_["lightskyblue1"] = RGBColor(176, 226, 255);
+  colors_["lightskyblue2"] = RGBColor(164, 211, 238);
+  colors_["lightskyblue3"] = RGBColor(141, 182, 205);
+  colors_["lightskyblue4"] = RGBColor(96, 123, 139);
+  colors_["lightslateblue"] = RGBColor(132, 112, 255);
+  colors_["lightslategray"] = RGBColor(119, 136, 153);
+  colors_["lightslategrey"] = RGBColor(119, 136, 153);
+  colors_["lightsteelblue"] = RGBColor(176, 196, 222);
+  colors_["lightsteelblue1"] = RGBColor(202, 225, 255);
+  colors_["lightsteelblue2"] = RGBColor(188, 210, 238);
+  colors_["lightsteelblue3"] = RGBColor(162, 181, 205);
+  colors_["lightsteelblue4"] = RGBColor(110, 123, 139);
+  colors_["lightyellow"] = RGBColor(255, 255, 224);
+  colors_["lightyellow1"] = RGBColor(255, 255, 224);
+  colors_["lightyellow2"] = RGBColor(238, 238, 209);
+  colors_["lightyellow3"] = RGBColor(205, 205, 180);
+  colors_["lightyellow4"] = RGBColor(139, 139, 122);
+  colors_["limegreen"] = RGBColor(50, 205, 50);
+  colors_["linen"] = RGBColor(250, 240, 230);
+  colors_["magenta"] = RGBColor(255, 0, 255);
+  colors_["magenta1"] = RGBColor(255, 0, 255);
+  colors_["magenta2"] = RGBColor(238, 0, 238);
+  colors_["magenta3"] = RGBColor(205, 0, 205);
+  colors_["magenta4"] = RGBColor(139, 0, 139);
+  colors_["maroon"] = RGBColor(176, 48, 96);
+  colors_["maroon1"] = RGBColor(255, 52, 179);
+  colors_["maroon2"] = RGBColor(238, 48, 167);
+  colors_["maroon3"] = RGBColor(205, 41, 144);
+  colors_["maroon4"] = RGBColor(139, 28, 98);
+  colors_["mediumaquamarine"] = RGBColor(102, 205, 170);
+  colors_["mediumblue"] = RGBColor(0, 0, 205);
+  colors_["mediumorchid"] = RGBColor(186, 85, 211);
+  colors_["mediumorchid1"] = RGBColor(224, 102, 255);
+  colors_["mediumorchid2"] = RGBColor(209, 95, 238);
+  colors_["mediumorchid3"] = RGBColor(180, 82, 205);
+  colors_["mediumorchid4"] = RGBColor(122, 55, 139);
+  colors_["mediumpurple"] = RGBColor(147, 112, 219);
+  colors_["mediumpurple1"] = RGBColor(171, 130, 255);
+  colors_["mediumpurple2"] = RGBColor(159, 121, 238);
+  colors_["mediumpurple3"] = RGBColor(137, 104, 205);
+  colors_["mediumpurple4"] = RGBColor(93, 71, 139);
+  colors_["mediumseagreen"] = RGBColor(60, 179, 113);
+  colors_["mediumslateblue"] = RGBColor(123, 104, 238);
+  colors_["mediumspringgreen"] = RGBColor(0, 250, 154);
+  colors_["mediumturquoise"] = RGBColor(72, 209, 204);
+  colors_["mediumvioletred"] = RGBColor(199, 21, 133);
+  colors_["midnightblue"] = RGBColor(25, 25, 112);
+  colors_["mintcream"] = RGBColor(245, 255, 250);
+  colors_["mistyrose"] = RGBColor(255, 228, 225);
+  colors_["mistyrose1"] = RGBColor(255, 228, 225);
+  colors_["mistyrose2"] = RGBColor(238, 213, 210);
+  colors_["mistyrose3"] = RGBColor(205, 183, 181);
+  colors_["mistyrose4"] = RGBColor(139, 125, 123);
+  colors_["moccasin"] = RGBColor(255, 228, 181);
+  colors_["navajowhite"] = RGBColor(255, 222, 173);
+  colors_["navajowhite1"] = RGBColor(255, 222, 173);
+  colors_["navajowhite2"] = RGBColor(238, 207, 161);
+  colors_["navajowhite3"] = RGBColor(205, 179, 139);
+  colors_["navajowhite4"] = RGBColor(139, 121, 94);
+  colors_["navy"] = RGBColor(0, 0, 128);
+  colors_["navyblue"] = RGBColor(0, 0, 128);
+  colors_["oldlace"] = RGBColor(253, 245, 230);
+  colors_["olivedrab"] = RGBColor(107, 142, 35);
+  colors_["olivedrab1"] = RGBColor(192, 255, 62);
+  colors_["olivedrab2"] = RGBColor(179, 238, 58);
+  colors_["olivedrab3"] = RGBColor(154, 205, 50);
+  colors_["olivedrab4"] = RGBColor(105, 139, 34);
+  colors_["orange"] = RGBColor(255, 165, 0);
+  colors_["orange1"] = RGBColor(255, 165, 0);
+  colors_["orange2"] = RGBColor(238, 154, 0);
+  colors_["orange3"] = RGBColor(205, 133, 0);
+  colors_["orange4"] = RGBColor(139, 90, 0);
+  colors_["orangered"] = RGBColor(255, 69, 0);
+  colors_["orangered1"] = RGBColor(255, 69, 0);
+  colors_["orangered2"] = RGBColor(238, 64, 0);
+  colors_["orangered3"] = RGBColor(205, 55, 0);
+  colors_["orangered4"] = RGBColor(139, 37, 0);
+  colors_["orchid"] = RGBColor(218, 112, 214);
+  colors_["orchid1"] = RGBColor(255, 131, 250);
+  colors_["orchid2"] = RGBColor(238, 122, 233);
+  colors_["orchid3"] = RGBColor(205, 105, 201);
+  colors_["orchid4"] = RGBColor(139, 71, 137);
+  colors_["palegoldenrod"] = RGBColor(238, 232, 170);
+  colors_["palegreen"] = RGBColor(152, 251, 152);
+  colors_["palegreen1"] = RGBColor(154, 255, 154);
+  colors_["palegreen2"] = RGBColor(144, 238, 144);
+  colors_["palegreen3"] = RGBColor(124, 205, 124);
+  colors_["palegreen4"] = RGBColor(84, 139, 84);
+  colors_["paleturquoise"] = RGBColor(175, 238, 238);
+  colors_["paleturquoise1"] = RGBColor(187, 255, 255);
+  colors_["paleturquoise2"] = RGBColor(174, 238, 238);
+  colors_["paleturquoise3"] = RGBColor(150, 205, 205);
+  colors_["paleturquoise4"] = RGBColor(102, 139, 139);
+  colors_["palevioletred"] = RGBColor(219, 112, 147);
+  colors_["palevioletred1"] = RGBColor(255, 130, 171);
+  colors_["palevioletred2"] = RGBColor(238, 121, 159);
+  colors_["palevioletred3"] = RGBColor(205, 104, 137);
+  colors_["palevioletred4"] = RGBColor(139, 71, 93);
+  colors_["papayawhip"] = RGBColor(255, 239, 213);
+  colors_["peachpuff"] = RGBColor(255, 218, 185);
+  colors_["peachpuff1"] = RGBColor(255, 218, 185);
+  colors_["peachpuff2"] = RGBColor(238, 203, 173);
+  colors_["peachpuff3"] = RGBColor(205, 175, 149);
+  colors_["peachpuff4"] = RGBColor(139, 119, 101);
+  colors_["peru"] = RGBColor(205, 133, 63);
+  colors_["pink"] = RGBColor(255, 192, 203);
+  colors_["pink1"] = RGBColor(255, 181, 197);
+  colors_["pink2"] = RGBColor(238, 169, 184);
+  colors_["pink3"] = RGBColor(205, 145, 158);
+  colors_["pink4"] = RGBColor(139, 99, 108);
+  colors_["plum"] = RGBColor(221, 160, 221);
+  colors_["plum1"] = RGBColor(255, 187, 255);
+  colors_["plum2"] = RGBColor(238, 174, 238);
+  colors_["plum3"] = RGBColor(205, 150, 205);
+  colors_["plum4"] = RGBColor(139, 102, 139);
+  colors_["powderblue"] = RGBColor(176, 224, 230);
+  colors_["purple"] = RGBColor(160, 32, 240);
+  colors_["purple1"] = RGBColor(155, 48, 255);
+  colors_["purple2"] = RGBColor(145, 44, 238);
+  colors_["purple3"] = RGBColor(125, 38, 205);
+  colors_["purple4"] = RGBColor(85, 26, 139);
+  colors_["red"] = RGBColor(255, 0, 0);
+  colors_["red1"] = RGBColor(255, 0, 0);
+  colors_["red2"] = RGBColor(238, 0, 0);
+  colors_["red3"] = RGBColor(205, 0, 0);
+  colors_["red4"] = RGBColor(139, 0, 0);
+  colors_["rosybrown"] = RGBColor(188, 143, 143);
+  colors_["rosybrown1"] = RGBColor(255, 193, 193);
+  colors_["rosybrown2"] = RGBColor(238, 180, 180);
+  colors_["rosybrown3"] = RGBColor(205, 155, 155);
+  colors_["rosybrown4"] = RGBColor(139, 105, 105);
+  colors_["royalblue"] = RGBColor(65, 105, 225);
+  colors_["royalblue1"] = RGBColor(72, 118, 255);
+  colors_["royalblue2"] = RGBColor(67, 110, 238);
+  colors_["royalblue3"] = RGBColor(58, 95, 205);
+  colors_["royalblue4"] = RGBColor(39, 64, 139);
+  colors_["saddlebrown"] = RGBColor(139, 69, 19);
+  colors_["salmon"] = RGBColor(250, 128, 114);
+  colors_["salmon1"] = RGBColor(255, 140, 105);
+  colors_["salmon2"] = RGBColor(238, 130, 98);
+  colors_["salmon3"] = RGBColor(205, 112, 84);
+  colors_["salmon4"] = RGBColor(139, 76, 57);
+  colors_["sandybrown"] = RGBColor(244, 164, 96);
+  colors_["seagreen"] = RGBColor(46, 139, 87);
+  colors_["seagreen1"] = RGBColor(84, 255, 159);
+  colors_["seagreen2"] = RGBColor(78, 238, 148);
+  colors_["seagreen3"] = RGBColor(67, 205, 128);
+  colors_["seagreen4"] = RGBColor(46, 139, 87);
+  colors_["seashell"] = RGBColor(255, 245, 238);
+  colors_["seashell1"] = RGBColor(255, 245, 238);
+  colors_["seashell2"] = RGBColor(238, 229, 222);
+  colors_["seashell3"] = RGBColor(205, 197, 191);
+  colors_["seashell4"] = RGBColor(139, 134, 130);
+  colors_["sienna"] = RGBColor(160, 82, 45);
+  colors_["sienna1"] = RGBColor(255, 130, 71);
+  colors_["sienna2"] = RGBColor(238, 121, 66);
+  colors_["sienna3"] = RGBColor(205, 104, 57);
+  colors_["sienna4"] = RGBColor(139, 71, 38);
+  colors_["skyblue"] = RGBColor(135, 206, 235);
+  colors_["skyblue1"] = RGBColor(135, 206, 255);
+  colors_["skyblue2"] = RGBColor(126, 192, 238);
+  colors_["skyblue3"] = RGBColor(108, 166, 205);
+  colors_["skyblue4"] = RGBColor(74, 112, 139);
+  colors_["slateblue"] = RGBColor(106, 90, 205);
+  colors_["slateblue1"] = RGBColor(131, 111, 255);
+  colors_["slateblue2"] = RGBColor(122, 103, 238);
+  colors_["slateblue3"] = RGBColor(105, 89, 205);
+  colors_["slateblue4"] = RGBColor(71, 60, 139);
+  colors_["slategray"] = RGBColor(112, 128, 144);
+  colors_["slategray1"] = RGBColor(198, 226, 255);
+  colors_["slategray2"] = RGBColor(185, 211, 238);
+  colors_["slategray3"] = RGBColor(159, 182, 205);
+  colors_["slategray4"] = RGBColor(108, 123, 139);
+  colors_["slategrey"] = RGBColor(112, 128, 144);
+  colors_["snow"] = RGBColor(255, 250, 250);
+  colors_["snow1"] = RGBColor(255, 250, 250);
+  colors_["snow2"] = RGBColor(238, 233, 233);
+  colors_["snow3"] = RGBColor(205, 201, 201);
+  colors_["snow4"] = RGBColor(139, 137, 137);
+  colors_["springgreen"] = RGBColor(0, 255, 127);
+  colors_["springgreen1"] = RGBColor(0, 255, 127);
+  colors_["springgreen2"] = RGBColor(0, 238, 118);
+  colors_["springgreen3"] = RGBColor(0, 205, 102);
+  colors_["springgreen4"] = RGBColor(0, 139, 69);
+  colors_["steelblue"] = RGBColor(70, 130, 180);
+  colors_["steelblue1"] = RGBColor(99, 184, 255);
+  colors_["steelblue2"] = RGBColor(92, 172, 238);
+  colors_["steelblue3"] = RGBColor(79, 148, 205);
+  colors_["steelblue4"] = RGBColor(54, 100, 139);
+  colors_["tan"] = RGBColor(210, 180, 140);
+  colors_["tan1"] = RGBColor(255, 165, 79);
+  colors_["tan2"] = RGBColor(238, 154, 73);
+  colors_["tan3"] = RGBColor(205, 133, 63);
+  colors_["tan4"] = RGBColor(139, 90, 43);
+  colors_["thistle"] = RGBColor(216, 191, 216);
+  colors_["thistle1"] = RGBColor(255, 225, 255);
+  colors_["thistle2"] = RGBColor(238, 210, 238);
+  colors_["thistle3"] = RGBColor(205, 181, 205);
+  colors_["thistle4"] = RGBColor(139, 123, 139);
+  colors_["tomato"] = RGBColor(255, 99, 71);
+  colors_["tomato1"] = RGBColor(255, 99, 71);
+  colors_["tomato2"] = RGBColor(238, 92, 66);
+  colors_["tomato3"] = RGBColor(205, 79, 57);
+  colors_["tomato4"] = RGBColor(139, 54, 38);
+  colors_["turquoise"] = RGBColor(64, 224, 208);
+  colors_["turquoise1"] = RGBColor(0, 245, 255);
+  colors_["turquoise2"] = RGBColor(0, 229, 238);
+  colors_["turquoise3"] = RGBColor(0, 197, 205);
+  colors_["turquoise4"] = RGBColor(0, 134, 139);
+  colors_["violet"] = RGBColor(238, 130, 238);
+  colors_["violetred"] = RGBColor(208, 32, 144);
+  colors_["violetred1"] = RGBColor(255, 62, 150);
+  colors_["violetred2"] = RGBColor(238, 58, 140);
+  colors_["violetred3"] = RGBColor(205, 50, 120);
+  colors_["violetred4"] = RGBColor(139, 34, 82);
+  colors_["wheat"] = RGBColor(245, 222, 179);
+  colors_["wheat1"] = RGBColor(255, 231, 186);
+  colors_["wheat2"] = RGBColor(238, 216, 174);
+  colors_["wheat3"] = RGBColor(205, 186, 150);
+  colors_["wheat4"] = RGBColor(139, 126, 102);
+  colors_["whitesmoke"] = RGBColor(245, 245, 245);
+  colors_["yellow"] = RGBColor(255, 255, 0);
+  colors_["yellow1"] = RGBColor(255, 255, 0);
+  colors_["yellow2"] = RGBColor(238, 238, 0);
+  colors_["yellow3"] = RGBColor(205, 205, 0);
+  colors_["yellow4"] = RGBColor(139, 139, 0);
+  colors_["yellowgreen"] = RGBColor(154, 205, 50);
+}
+
diff --git a/src/Bpp/Graphics/R/RColorSet.h b/src/Bpp/Graphics/R/RColorSet.h
new file mode 100644
index 0000000..970c151
--- /dev/null
+++ b/src/Bpp/Graphics/R/RColorSet.h
@@ -0,0 +1,78 @@
+//
+// File: RColorSet.h
+// Created by: Julien Dutheil
+// Created on: Mon Apr 14 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2008)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _RCOLORSET_H_
+#define _RCOLORSET_H_
+
+#include "../ColorSet.h"
+
+namespace bpp
+{
+
+/**
+ * @brief R color definitions.
+ */
+class RColorSet:
+  public AbstractColorSet
+{
+  public:
+    /**
+     * The following R code has been used to generate this code:
+     * @code
+     * c<-colors()
+     * file<-"Rcolors.cpp"
+     * unlink(file)
+     * for(i in c)
+     * {
+     *   r<-col2rgb(i)["red",1]
+     *   g<-col2rgb(i)["green",1]
+     *   b<-col2rgb(i)["blue",1]
+     *   cat(file=file, append=TRUE, paste("  _colors[\"",i,"\"] = RGBColor(",r ,", ",g,", ", b, ");\n",sep="")); 
+     * }
+     * @endcode
+     */
+    RColorSet();
+    virtual ~RColorSet() {}
+
+};
+
+} // end of namespace bpp;
+
+#endif //_RCOLORSET_H_
+
diff --git a/src/Bpp/Graphics/RgbColor.h b/src/Bpp/Graphics/RgbColor.h
new file mode 100644
index 0000000..faeac00
--- /dev/null
+++ b/src/Bpp/Graphics/RgbColor.h
@@ -0,0 +1,157 @@
+//
+// File: RGBColor.h
+// Created by: Julien Dutheil
+// Created on: Thu Mar 16 2006
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _RGBCOLOR_H_
+#define _RGBCOLOR_H_
+
+// From the STL:
+#include <cmath>
+
+#include "../Text/TextTools.h"
+#include "../Exceptions.h"
+#include "../Clonable.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Describe a color according to its red, green and blue componants.
+ */
+class RGBColor:
+  public virtual Clonable
+{
+  protected:
+    unsigned int red_;
+    unsigned int green_;
+    unsigned int blue_;
+
+  public:
+    RGBColor(unsigned int red, unsigned int green, unsigned int blue): red_(red), green_(green), blue_(blue) {} 
+    RGBColor(): red_(0), green_(0), blue_(0) {} 
+    virtual ~RGBColor() {}
+
+#ifdef NO_VIRTUAL_COV
+    Clonable*
+#else
+    RGBColor*
+#endif
+    clone() const { return new RGBColor(*this); }
+
+  public:
+    bool operator==(const RGBColor & color) const
+    {
+      return red_ == color.red_ && green_ == color.green_ && blue_ == color.blue_;
+    }
+
+    /**
+     * @brief Comparison operator (for sorting purposes).
+     *
+     * The hexadecimal string representation is used for comparison.
+     *
+     * @param color The color to compare with.
+     */
+    bool operator<(const RGBColor & color) const
+    {
+      return toHex() < color.toHex();
+    }
+
+    /**
+     * @brief Get the HTML-like, hexadecimal description of this color.
+     */
+    std::string toHex() const
+    {
+      std::string hex = "#";
+      hex += decToHex(red_);
+      hex += decToHex(green_);
+      hex += decToHex(blue_);
+      return hex;
+    }
+
+    /**
+     * @brief Access to each color componant: 0=red, 1=green, 2=blue.
+     */
+    const unsigned int & operator[](unsigned int i) const
+    {
+      if(i == 0) return red_;
+      if(i == 1) return green_;
+      if(i == 2) return blue_;
+      throw Exception("Invalid color index");
+    }
+
+    /**
+     * @brief Access to each color componant: 0=red, 1=green, 2=blue.
+     */
+    unsigned int & operator[](unsigned int i)
+    {
+      if(i == 0) return red_;
+      if(i == 1) return green_;
+      if(i == 2) return blue_;
+      throw Exception("Invalid color index");
+    }
+
+    /**
+     * @brief Get a string description of the color, e.g. [R255,G0,B255].
+     */
+    std::string toString() const
+    {
+      return "[R" + TextTools::toString(red_) + ",G" + TextTools::toString(green_) + ",B" + TextTools::toString(blue_) + "]"; 
+    }
+
+  protected:
+    static std::string decToHex(unsigned int dec)
+    {
+      std::string hexa = "0123456789ABCDEF";
+      std::string hex = "";
+      while (dec > 15)
+      {
+        unsigned int tmp = dec - (int)floor((double)dec/16.)*16;
+        hex = hexa[tmp] + hex;
+        dec=(int)floor((double)dec/16.);
+      }
+      hex = hexa[dec] + hex;
+      if(hex.size() == 1) hex = "0" + hex;
+      return hex;
+    }
+
+};
+
+} // end of namespace bpp;
+
+#endif //_RGBCOLOR_H_
+
diff --git a/src/Bpp/Graphics/Svg/SvgGraphicDevice.cpp b/src/Bpp/Graphics/Svg/SvgGraphicDevice.cpp
new file mode 100644
index 0000000..0c68013
--- /dev/null
+++ b/src/Bpp/Graphics/Svg/SvgGraphicDevice.cpp
@@ -0,0 +1,171 @@
+//
+// File: SvgGraphicDevice.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Mar 10 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "SvgGraphicDevice.h"
+
+using namespace bpp;
+using namespace std;
+
+void SvgGraphicDevice::begin()
+{
+  layers_.clear();
+  minx_ = maxx_ = miny_ = maxy_ = 0;
+}
+
+void SvgGraphicDevice::end()
+{
+  //Header:
+  out_ << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" << endl;
+  out_ << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD Svg 1.1//EN\"" << endl;
+  out_ << "\"http://www.w3.org/Graphics/Svg/1.1/DTD/svg11.dtd\">" << endl;
+  out_ << "<svg width=\"" << (maxx_ - minx_) << "\" height=\"" << (maxy_ - miny_) << "\" version=\"1.1\"" << endl;
+  out_ << " xmlns=\"http://www.w3.org/2000/svg\"" << endl;
+  if (inkscapeEnabled_)
+    out_ << " xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"";
+  out_ << " >" << endl;
+  
+  out_ << "<g transform=\"translate(" << (-minx_) << "," << (-miny_) << ")\">" << endl;
+
+  for(map<int, vector<string> >::iterator it = layers_.begin(); it != layers_.end(); it++)
+  {
+    out_ << "<g id=\"layer" << it->first << "\"";
+    if(inkscapeEnabled_)
+    {
+      out_ << " inkscape:groupmode=\"layer\"";
+    }
+    out_ << " >" << endl;
+    vector<string> * v = &it->second;
+    for(unsigned int i = 0; i < v->size(); i++)
+    {
+      out_ << (*v)[i] << endl;
+    }
+    out_ << "</g>" << endl;
+  }
+  out_ << "</g>" << endl;
+  
+  out_ << "</svg>" << endl;
+}
+
+void SvgGraphicDevice::drawLine(double x1, double y1, double x2, double y2)
+{
+  x1 = x_(x1);
+  x2 = x_(x2);
+  y1 = y_(y1);
+  y2 = y_(y2);
+  string style = "stroke:" + colorToText(getCurrentForegroundColor()) + ";stroke-width:" + TextTools::toString(getCurrentPointSize());
+  if(getCurrentLineType() == LINE_DASHED)
+    style += ";stroke-dasharray:4,4";
+  else if(getCurrentLineType() == LINE_DOTTED)
+    style += ";stroke-dasharray:1,2";
+  ostringstream oss;
+  oss << "<line x1=\"" << x1 << "\" y1=\"" << y1 << "\" x2=\"" << x2 << "\" y2=\"" << y2 << "\" style=\"" << style << "\" />";
+  layers_[getCurrentLayer()].push_back(oss.str());
+  if (x1 < minx_) minx_ = x1;
+  if (x2 < minx_) minx_ = x2;
+  if (y1 < miny_) miny_ = y1;
+  if (y2 < miny_) miny_ = y2;
+  if (x1 > maxx_) maxx_ = x1;
+  if (x2 > maxx_) maxx_ = x2;
+  if (y1 > maxy_) maxy_ = y1;
+  if (y2 > maxy_) maxy_ = y2;
+}
+ 
+void SvgGraphicDevice::drawRect(double x, double y, double width, double height, short fill)
+{
+  x = x_(x);
+  y = y_(y);
+  width = x_(width);
+  height = y_(height);
+  string style = "stroke:" + colorToText(getCurrentForegroundColor()) + ";stroke-width:" + TextTools::toString(getCurrentPointSize());
+  if(fill == FILL_FILLED)
+  {
+    style += ";fill:" + colorToText(getCurrentBackgroundColor());
+  }
+  ostringstream oss;
+  oss << "<rect x=\"" << x << "\" y=\"" << y << "\" width=\"" << width << "\" height=\"" << height << "\" style=\"" << style << "\" />";
+  layers_[getCurrentLayer()].push_back(oss.str());
+  if (x < minx_) minx_ = x;
+  if (y < miny_) miny_ = y;
+  if (x + width > maxx_) maxx_ = x + width;
+  if (y + height > maxy_) maxx_ = y + height;
+}
+
+void SvgGraphicDevice::drawCircle(double x, double y, double radius, short fill)
+{
+  x = x_(x);
+  y = y_(y);
+  radius = x_(radius);
+  string style = "stroke:" + colorToText(getCurrentForegroundColor()) + ";stroke-width:" + TextTools::toString(getCurrentPointSize());
+  if(fill == FILL_FILLED)
+  {
+    style += ";fill:" + colorToText(getCurrentBackgroundColor());
+  }
+  ostringstream oss;
+  oss << "<rect cx=\"" << x << "\" cy=\"" << y << "\" cr=\"" << radius << "\" style=\"" << style << "\" />";
+  layers_[getCurrentLayer()].push_back(oss.str());
+}
+
+void SvgGraphicDevice::drawText(double x, double y, const std::string & text, short hpos, short vpos, double angle) throw (UnvalidFlagException)
+{
+  x = x_(x);
+  y = y_(y);
+  string style = "font-family:" + getCurrentFont().getFamily() + ";font-style:" + fontStyles_[getCurrentFont().getStyle()] + ";font-weight:" + fontWeights_[getCurrentFont().getWeight()] + ";font-size:" + TextTools::toString(getCurrentFont().getSize()) + "px";
+  style += ";dominant-baseline:";
+  if (vpos == TEXT_VERTICAL_BOTTOM)
+    style += "before-edge";
+  else if (vpos == TEXT_VERTICAL_TOP)
+    style += "after-edge";
+  else if (vpos == TEXT_VERTICAL_CENTER)
+    style += "middle";
+  else throw UnvalidFlagException("SvgGraphicDevice::drawText. Invalid vertical alignment option.");
+  style += ";text-anchor:";
+  if (hpos == TEXT_HORIZONTAL_LEFT)
+    style += "start";
+  else if (hpos == TEXT_HORIZONTAL_RIGHT)
+    style += "end";
+  else if (hpos == TEXT_HORIZONTAL_CENTER)
+    style += "middle";
+  else throw UnvalidFlagException("SvgGraphicDevice::drawText. Invalid horizontal alignment option.");
+  style += ";fill:" + colorToText(getCurrentForegroundColor());
+
+  ostringstream oss;
+  oss << "<text x=\"" << x << "\" y=\"" << y << "\" rotate=\"" << angle << "\" style=\"" << style << "\" >" << text << "</text>";
+  layers_[getCurrentLayer()].push_back(oss.str());
+}
+
diff --git a/src/Bpp/Graphics/Svg/SvgGraphicDevice.h b/src/Bpp/Graphics/Svg/SvgGraphicDevice.h
new file mode 100644
index 0000000..24fc012
--- /dev/null
+++ b/src/Bpp/Graphics/Svg/SvgGraphicDevice.h
@@ -0,0 +1,107 @@
+//
+// File: SvgGraphicDevice.h
+// Created by: Julien Dutheil
+// Created on: Mon Mar 10 2008
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 16, 2006)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _SVGGRAPHICDEVICE_H_
+#define _SVGGRAPHICDEVICE_H_
+
+#include "../AbstractGraphicDevice.h"
+#include "../ColorTools.h"
+
+// From the STL:
+#include <map>
+
+namespace bpp
+{
+
+/**
+ * @brief SVG plotting format.
+ */
+class SvgGraphicDevice:
+  public AbstractGraphicDevice
+{
+  private:
+    std::ostream& out_;
+    std::map<int, std::vector<std::string>, std::greater<int> > layers_; //Layer display as in xfig
+    bool inkscapeEnabled_;
+    double minx_, maxx_, miny_, maxy_;
+    std::map<short int, std::string> fontStyles_;
+    std::map<short int, std::string> fontWeights_;
+
+  public:
+    SvgGraphicDevice(std::ostream& out, bool inkscapeEnabled = false):
+      out_(out),
+      layers_(),
+      inkscapeEnabled_(inkscapeEnabled),
+      minx_(0), maxx_(0), miny_(0), maxy_(0),
+      fontStyles_(), fontWeights_()
+    {
+      fontStyles_[Font::STYLE_NORMAL] = "";
+      fontStyles_[Font::STYLE_ITALIC] = "italic";
+      fontWeights_[Font::WEIGHT_NORMAL] = "";
+      fontWeights_[Font::WEIGHT_BOLD] = "bold";
+    }
+
+    virtual ~SvgGraphicDevice() {}
+
+  public:
+    void begin();
+    void end();
+
+    void drawLine(double x1, double y1, double x2, double y2);
+    void drawRect(double x, double y, double width, double height, short fill = FILL_EMPTY);
+    void drawCircle(double x, double y, double radius, short fill = FILL_EMPTY);
+    void drawText(double x, double y, const std::string& text, short hpos = TEXT_HORIZONTAL_LEFT, short vpos = TEXT_VERTICAL_BOTTOM, double angle = 0) throw (UnvalidFlagException);
+    void comment(const std::string& text)
+    {
+      layers_[getCurrentLayer()].push_back("<!-- " + text + " -->");
+    }
+
+  public:
+    static std::string colorToText(const RGBColor& color)
+    {
+      return "rgb(" + TextTools::toString(color[0]) + "," + TextTools::toString(color[1]) + "," + TextTools::toString(color[2]) + ")";
+    }
+
+};
+
+} // end of namespace bpp.
+
+#endif //_SVGGRAPHICDEVICE_H_
+
+
diff --git a/src/Bpp/Io/BppODiscreteDistributionFormat.cpp b/src/Bpp/Io/BppODiscreteDistributionFormat.cpp
new file mode 100644
index 0000000..8ae25f0
--- /dev/null
+++ b/src/Bpp/Io/BppODiscreteDistributionFormat.cpp
@@ -0,0 +1,440 @@
+//
+// File: BppODiscreteDistributionFormatFormat.cpp
+// Created by: Laurent Guéguen
+// Created on: lundi 3 septembre 2012, à 14h 48
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for phylogenetic data analysis.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "BppODiscreteDistributionFormat.h"
+
+#include "../Io/FileTools.h"
+#include "../Text/TextTools.h"
+#include "../Text/StringTokenizer.h"
+#include "../Text/KeyvalTools.h"
+
+#include "../Numeric/Prob/DiscreteDistribution.h"
+#include "../Numeric/Prob/InvariantMixedDiscreteDistribution.h"
+#include "../Numeric/Prob/ConstantDistribution.h"
+#include "../Numeric/Prob/SimpleDiscreteDistribution.h"
+#include "../Numeric/Prob/MixtureOfDiscreteDistributions.h"
+#include "../Numeric/Prob/GammaDiscreteDistribution.h"
+#include "../Numeric/Prob/GaussianDiscreteDistribution.h"
+#include "../Numeric/Prob/BetaDiscreteDistribution.h"
+#include "../Numeric/Prob/ExponentialDiscreteDistribution.h"
+#include "../Numeric/Prob/TruncatedExponentialDiscreteDistribution.h"
+#include "../Numeric/Prob/UniformDiscreteDistribution.h"
+#include "../Numeric/AutoParameter.h"
+#include "BppOParametrizableFormat.h"
+
+using namespace bpp;
+
+// From the STL:
+#include <iomanip>
+
+using namespace std;
+
+
+DiscreteDistribution* BppODiscreteDistributionFormat::read(
+    const std::string& distDescription,
+    bool parseArguments)
+{
+  unparsedArguments_.clear();
+  string distName;
+  auto_ptr<DiscreteDistribution> rDist;
+  map<string, string> args;
+  KeyvalTools::parseProcedure(distDescription, distName, args);
+
+  if ((distName == "InvariantMixed") || (distName == "Invariant"))
+  {
+    // We have to parse the nested distribution first:
+    string nestedDistDescription = args["dist"];
+    if (TextTools::isEmpty(nestedDistDescription))
+      throw Exception("BppODiscreteDistributionFormat::read. Missing argument 'dist' for distribution 'Invariant'.");
+    if (verbose_)
+      ApplicationTools::displayResult("Invariant Mixed distribution", distName );
+    BppODiscreteDistributionFormat nestedReader(verbose_);
+    DiscreteDistribution* nestedDistribution = nestedReader.read(nestedDistDescription, true);
+    map<string, string> unparsedArgumentsNested(nestedReader.getUnparsedArguments());
+
+    // Now we create the Invariant rate distribution:
+    rDist.reset(new InvariantMixedDiscreteDistribution(nestedDistribution, 0.1, 0.000001));
+
+    // Then we update the parameter set:
+    for (map<string, string>::iterator it = unparsedArgumentsNested.begin();
+         it != unparsedArgumentsNested.end(); it++)
+    {
+      unparsedArguments_["Invariant." + it->first] = it->second;
+    }
+
+    if (args.find("p") != args.end())
+      unparsedArguments_["Invariant.p"] = args["p"];
+  }
+  else if (distName == "Constant")
+  {
+    if (args.find("value") == args.end())
+      throw Exception("Missing argument 'value' in Constant distribution");
+    rDist.reset(new ConstantDistribution(TextTools::to<double>(args["value"])));
+    unparsedArguments_["Constant.value"] = args["value"];
+  }
+  else if (distName == "Simple")
+  {
+    if (args.find("values") == args.end())
+      throw Exception("Missing argument 'values' in Simple distribution");
+    if (args.find("probas") == args.end())
+      throw Exception("Missing argument 'probas' in Simple distribution");
+    vector<double> probas, values;
+
+    string rf = args["values"];
+    StringTokenizer strtok(rf.substr(1, rf.length() - 2), ",");
+    while (strtok.hasMoreToken())
+      values.push_back(TextTools::toDouble(strtok.nextToken()));
+
+    rf = args["probas"];
+    StringTokenizer strtok2(rf.substr(1, rf.length() - 2), ",");
+    while (strtok2.hasMoreToken())
+      probas.push_back(TextTools::toDouble(strtok2.nextToken()));
+
+    std::map<size_t, std::vector<double> > ranges;
+
+    if (args.find("ranges") != args.end())
+    {
+      string rr = args["ranges"];
+      StringTokenizer strtok3(rr.substr(1, rr.length() - 2), ",");
+      string desc;
+      double deb, fin;
+      unsigned int num;
+      size_t po, pf, ppv;
+      while (strtok3.hasMoreToken())
+      {
+        desc = strtok3.nextToken();
+        po = desc.find("[");
+        ppv = desc.find(";");
+        pf = desc.find("]");
+        num = (unsigned int)(TextTools::toInt(desc.substr(1, po - 1)));
+        deb = TextTools::toDouble(desc.substr(po + 1, ppv - po - 1));
+        fin = TextTools::toDouble(desc.substr(ppv + 1, pf - ppv - 1));
+        vector<double> vd;
+        vd.push_back(deb);
+        vd.push_back(fin);
+        ranges[num] = vd;
+      }
+    }
+    if (ranges.size() == 0)
+      rDist.reset(new SimpleDiscreteDistribution(values, probas));
+    else
+      rDist.reset(new SimpleDiscreteDistribution(values, ranges, probas));
+
+    vector<string> v = rDist->getParameters().getParameterNames();
+
+    for (unsigned int i = 0; i < v.size(); i++)
+    {
+      unparsedArguments_[v[i]] = TextTools::toString(rDist->getParameterValue(rDist->getParameterNameWithoutNamespace(v[i])));
+    }
+  }
+  else if (distName == "Mixture")
+  {
+    if (args.find("probas") == args.end())
+      throw Exception("Missing argument 'probas' in Mixture distribution");
+    vector<double> probas;
+    vector<DiscreteDistribution*> v_pdd;
+    DiscreteDistribution* pdd;
+    string rf = args["probas"];
+    StringTokenizer strtok2(rf.substr(1, rf.length() - 2), ",");
+    while (strtok2.hasMoreToken())
+      probas.push_back(TextTools::toDouble(strtok2.nextToken()));
+
+    vector<string> v_nestedDistrDescr;
+
+    unsigned int nbd = 0;
+    while (args.find("dist" + TextTools::toString(++nbd)) != args.end())
+      v_nestedDistrDescr.push_back(args["dist" + TextTools::toString(nbd)]);
+
+    if (v_nestedDistrDescr.size() != probas.size())
+      throw Exception("Number of distributions (keyword 'dist" + TextTools::toString(probas.size()) + "') do not fit the number of probabilities");
+
+    BppODiscreteDistributionFormat nestedReader;
+
+    for (unsigned i = 0; i < v_nestedDistrDescr.size(); i++)
+    {
+      pdd = nestedReader.read(v_nestedDistrDescr[i], true);
+      map<string, string> unparsedArgumentsNested(nestedReader.getUnparsedArguments());
+
+      for (map<string, string>::iterator it = unparsedArgumentsNested.begin(); it != unparsedArgumentsNested.end(); it++)
+      {
+        unparsedArguments_[distName + "." + TextTools::toString(i + 1) + "_" + it->first] = it->second;
+      }
+      v_pdd.push_back(pdd);
+    }
+    rDist.reset(new MixtureOfDiscreteDistributions(v_pdd, probas));
+  }
+  else
+  {
+    if (args.find("n") == args.end())
+      throw Exception("Missing argument 'n' (number of classes) in " + distName
+                      + " distribution");
+    unsigned int nbClasses = TextTools::to<unsigned int>(args["n"]);
+
+    if (distName == "Gamma")
+    {
+      rDist.reset(new GammaDiscreteDistribution(nbClasses, 1, 1));
+      if (args.find("alpha") != args.end())
+        unparsedArguments_["Gamma.alpha"] = args["alpha"];
+      if (args.find("beta") != args.end())
+        unparsedArguments_["Gamma.beta"] = args["beta"];
+    }
+    else if (distName == "Gaussian")
+    {
+      rDist.reset(new GaussianDiscreteDistribution(nbClasses, 0, 1));
+      if (args.find("mu") != args.end())
+        unparsedArguments_["Gaussian.mu"] = args["mu"];
+      if (args.find("sigma") != args.end())
+        unparsedArguments_["Gaussian.sigma"] = args["sigma"];
+    }
+    else if (distName == "Beta")
+    {
+      rDist.reset(new BetaDiscreteDistribution(nbClasses, 1, 1));
+      if (args.find("alpha") != args.end())
+        unparsedArguments_["Beta.alpha"] = args["alpha"];
+      if (args.find("beta") != args.end())
+        unparsedArguments_["Beta.beta"] = args["beta"];
+    }
+    else if (distName == "Exponential")
+    {
+      rDist.reset(new ExponentialDiscreteDistribution(nbClasses, 1));
+      if (args.find("lambda") != args.end())
+        unparsedArguments_["Exponential.lambda"] = args["lambda"];
+      if (args.find("median") != args.end())
+        rDist->setMedian(true);
+    }
+    else if (distName == "TruncExponential")
+    {
+      rDist.reset(new TruncatedExponentialDiscreteDistribution(nbClasses, 1, 0));
+
+      if (args.find("median") != args.end())
+        rDist->setMedian(true);
+      if (args.find("lambda") != args.end())
+        unparsedArguments_["TruncExponential.lambda"] = args["lambda"];
+      if (args.find("tp") != args.end())
+        unparsedArguments_["TruncExponential.tp"] = args["tp"];
+    }
+    else if (distName == "Uniform")
+    {
+      if (args.find("begin") == args.end())
+        throw Exception("Missing argument 'begin' in Uniform distribution");
+      if (args.find("end") == args.end())
+        throw Exception("Missing argument 'end' in Uniform distribution");
+      rDist.reset(new UniformDiscreteDistribution(
+          nbClasses,
+          TextTools::to<double>(args["begin"]),
+          TextTools::to<double>(args["end"])));
+    }
+    else
+    {
+      throw Exception("Unknown distribution: " + distName + ".");
+    }
+  }
+  if (verbose_)
+  {
+    ApplicationTools::displayResult("Distribution", distName);
+    ApplicationTools::displayResult("Number of classes", TextTools::toString(rDist->getNumberOfCategories()));
+  }
+
+  if (parseArguments)
+    initialize_(*rDist);
+
+  return rDist.release();
+}
+
+
+void BppODiscreteDistributionFormat::write(const DiscreteDistribution& dist,
+                                           OutputStream& out,
+                                           std::map<std::string, std::string>& globalAliases,
+                                           std::vector<std::string>& writtenNames) const
+{
+  bool comma = false;
+
+  const DiscreteDistribution* pd;
+
+  out << dist.getName() + "(";
+
+  const InvariantMixedDiscreteDistribution* invar = dynamic_cast<const InvariantMixedDiscreteDistribution*>(&dist);
+  if (invar)
+  {
+    pd = invar->getVariableSubDistribution();
+    out << "dist=";
+    write(*pd, out, globalAliases, writtenNames);
+    comma = true;
+  }
+  else
+  {
+    const MixtureOfDiscreteDistributions* mix = dynamic_cast<const MixtureOfDiscreteDistributions*>(&dist);
+    if (mix)
+    {
+      size_t nd = mix->getNumberOfDistributions();
+      for (unsigned int i = 0; i < nd; i++)
+      {
+        if (comma)
+          out << ",";
+        out << "dist" + TextTools::toString(i + 1) + "=";
+        write(*mix->getNDistribution(i), out, globalAliases, writtenNames);
+        comma = true;
+      }
+      out << ",probas=(";
+      for (unsigned int i = 0; i < nd; i++)
+      {
+        out << mix->getNProbability(i);
+        if (i != nd - 1)
+          out << ",";
+      }
+      out << ")";
+      for (unsigned int i = 1; i < nd; i++)
+      {
+        writtenNames.push_back(mix->getNamespace() + "theta" + TextTools::toString(i));
+      }
+    }
+  }
+
+  if (dynamic_cast<const BetaDiscreteDistribution*>(&dist) ||
+      dynamic_cast<const ExponentialDiscreteDistribution*>(&dist) ||
+      dynamic_cast<const GammaDiscreteDistribution*>(&dist) ||
+      dynamic_cast<const GaussianDiscreteDistribution*>(&dist) ||
+      dynamic_cast<const TruncatedExponentialDiscreteDistribution*>(&dist) ||
+      dynamic_cast<const UniformDiscreteDistribution*>(&dist))
+  {
+    if (comma)
+      out << ",";
+    out << "n="  << dist.getNumberOfCategories();
+    comma = true;
+  }
+
+  const ConstantDistribution* pc = dynamic_cast<const ConstantDistribution*>(&dist);
+  if (pc && dist.getNumberOfParameters() == 0)
+  {
+    if (comma)
+      out << ",";
+    out << "value="  << pc->getLowerBound();
+    comma = true;
+  }
+
+  const SimpleDiscreteDistribution* ps = dynamic_cast<const SimpleDiscreteDistribution*>(&dist);
+  if (ps)
+  {
+    size_t nd = ps->getNumberOfCategories();
+    if (comma)
+      out << ",";
+    out << "values=(";
+    for (unsigned int i = 0; i < nd; i++)
+    {
+      out << ps->getCategory(i);
+      if (i != nd - 1)
+        out << ",";
+    }
+    out << "),probas=(";
+    for (size_t i = 0; i < nd; i++)
+    {
+      out << ps->getProbability(i);
+      if (i != nd - 1)
+        out << ",";
+    }
+    out << ")";
+
+    const std::map<size_t, std::vector<double> > range = ps->getRanges();
+    if (range.size() != 0)
+    {
+      out << ",ranges=(";
+      std::map<size_t, std::vector<double> >::const_iterator it(range.begin());
+      while (it != range.end())
+      {
+        out << "V" << TextTools::toString(it->first);
+        out << "[" << TextTools::toString(it->second[0]) << ";" << TextTools::toString(it->second[1]) << "]";
+        it++;
+        if (it != range.end())
+          out << ",";
+      }
+    }
+    out << ")";
+
+    for (size_t i = 1; i < nd; i++)
+    {
+      writtenNames.push_back(ps->getNamespace() + "theta" + TextTools::toString(i));
+    }
+    for (size_t i = 1; i < nd + 1; i++)
+    {
+      writtenNames.push_back(ps->getNamespace() + "V" + TextTools::toString(i));
+    }
+    comma = true;
+  }
+
+  // Writing the parameters
+  BppOParametrizableFormat bOP;
+  bOP.write(dynamic_cast<const ParameterAliasable*>(&dist), out, globalAliases, dist.getIndependentParameters().getParameterNames(), writtenNames, true, comma);
+  out << ")";
+}
+
+void BppODiscreteDistributionFormat::initialize_(
+  DiscreteDistribution& rDist) throw (Exception)
+{
+  ParameterList pl = rDist.getIndependentParameters();
+
+  for (size_t i = 0; i < pl.size(); ++i)
+  {
+    AutoParameter ap(pl[i]);
+    ap.setMessageHandler(ApplicationTools::warning);
+    pl.setParameter(i, ap);
+  }
+
+  for (size_t i = 0; i < pl.size(); ++i)
+  {
+    const string pName = pl[i].getName();
+    double value = ApplicationTools::getDoubleParameter(pName, unparsedArguments_, pl[i].getValue());
+    pl[i].setValue(value);
+    if (verbose_)
+      ApplicationTools::displayResult("Parameter found", pName + "=" + TextTools::toString(pl[i].getValue()));
+  }
+  
+  rDist.matchParametersValues(pl);
+  if (verbose_)
+  {
+    for (size_t c = 0; c < rDist.getNumberOfCategories(); ++c)
+    {
+      ApplicationTools::displayResult("- Category " + TextTools::toString(c)
+        + " (Pr = " + TextTools::toString(rDist.getProbability(c)) + ") rate",
+        TextTools::toString(rDist.getCategory(c)));
+    }
+  }
+}
+
+
+
diff --git a/src/Bpp/Io/BppODiscreteDistributionFormat.h b/src/Bpp/Io/BppODiscreteDistributionFormat.h
new file mode 100644
index 0000000..ecd8ec4
--- /dev/null
+++ b/src/Bpp/Io/BppODiscreteDistributionFormat.h
@@ -0,0 +1,96 @@
+//
+// File: Bpp0DiscreteDistributionFormat.h
+// Created by: Laurent Guéguen
+// Created on: lundi 3 septembre 2012, à 14h 42
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for phylogenetic data analysis.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#ifndef _BPPODISCRETEDISTRIBUTIONFORMAT_H_
+#define _BPPODISCRETEDISTRIBUTIONFORMAT_H_
+
+#include "IoDiscreteDistributionFactory.h"
+
+namespace bpp
+{
+/**
+ * @brief Discrete Distribution I/O in BppO format.
+ *
+ * Creates a new discrete distribution object according to
+ * distribution description syntax (see the Bio++ Progam Suite
+ * manual for a detailed description of this syntax).
+ *
+ */
+class BppODiscreteDistributionFormat :
+  public virtual IDiscreteDistribution,
+  public virtual ODiscreteDistribution
+{
+protected:
+  bool verbose_;
+  std::map<std::string, std::string> unparsedArguments_;
+
+public:
+  BppODiscreteDistributionFormat(bool verbose = true) : verbose_(verbose), unparsedArguments_() {}
+  virtual ~BppODiscreteDistributionFormat() {}
+
+public:
+  const std::string getFormatName() const { return "BppO"; }
+
+  const std::string getFormatDescription() const { return "Bpp Options format."; }
+
+  DiscreteDistribution* read(const std::string& distDescription, bool parseArguments = true);
+
+  const std::map<std::string, std::string>& getUnparsedArguments() const { return unparsedArguments_; }
+
+  void write(const DiscreteDistribution& dist,
+             OutputStream& out,
+             std::map<std::string, std::string>& globalAliases,
+             std::vector<std::string>& writtenNames) const;
+
+protected:
+  /**
+   * @brief Set parameter initial values of a given distribution according to options.
+   *
+   * Parameters actually depends on the distribution passed as argument.
+   *
+   * @param rDist The distribution to set up.
+   * @throw Exception if an error occured.
+   */
+  void initialize_(DiscreteDistribution& rDist) throw (Exception);
+};
+
+} // end of namespace bpp.
+
+#endif // _BPPODISCRETEDISTRIBUTIONFORMAT_H_
+
diff --git a/src/Bpp/Io/BppOParametrizableFormat.cpp b/src/Bpp/Io/BppOParametrizableFormat.cpp
new file mode 100644
index 0000000..c5f9587
--- /dev/null
+++ b/src/Bpp/Io/BppOParametrizableFormat.cpp
@@ -0,0 +1,118 @@
+//
+// File: BppOParametrizableFormat.cpp
+// Created by: Laurent Guéguen
+// Created on: lundi 3 septembre 2012, à 15h 37
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for phylogenetic data analysis.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "BppOParametrizableFormat.h"
+
+using namespace bpp;
+
+// From the STL:
+#include <iomanip>
+#include <algorithm>
+
+
+using namespace std;
+
+void BppOParametrizableFormat::write(const Parametrizable* parametrizable,
+                                     OutputStream& out,
+                                     std::vector<std::string>& writtenNames,
+                                     bool printComma) const
+{
+  ParameterList pl = parametrizable->getParameters();
+  unsigned int p = out.getPrecision();
+  out.setPrecision(12);
+  bool flag=printComma;
+  for (unsigned int i = 0; i < pl.size(); i++)
+    {
+      if (find(writtenNames.begin(),writtenNames.end(),pl[i].getName())==writtenNames.end()){
+        if (flag)
+          out << ",";
+        else
+          flag=true;
+        string pname = parametrizable->getParameterNameWithoutNamespace(pl[i].getName());
+        
+        (out << pname << "=").enableScientificNotation(false) << pl[i].getValue();
+        
+      }
+    }
+  out.setPrecision(p);
+}
+
+void BppOParametrizableFormat::write(const ParameterAliasable* parametrizable,
+                                     OutputStream& out,
+                                     std::map<std::string, std::string>& globalAliases,
+                                     const std::vector<std::string>& names,
+                                     std::vector<std::string>& writtenNames,
+                                     bool printLocalAliases,
+                                     bool printComma) const
+{
+  ParameterList pl = parametrizable->getIndependentParameters().subList(names);
+  unsigned int p = out.getPrecision();
+  out.setPrecision(12);
+  bool flag=printComma;
+  for (unsigned int i = 0; i < pl.size(); i++)
+    {
+      if (find(writtenNames.begin(),writtenNames.end(),pl[i].getName())==writtenNames.end()){
+        if (flag)
+          out << ",";
+        else
+          flag=true;
+        string pname = parametrizable->getParameterNameWithoutNamespace(pl[i].getName());
+      
+        // Check for global aliases:
+        if (globalAliases.find(pl[i].getName()) == globalAliases.end())
+          {
+            (out << pname << "=").enableScientificNotation(false) << pl[i].getValue();
+          }
+        else
+          out << pname << "=" << globalAliases[pl[i].getName()];
+      
+        // Now check for local aliases:
+        if (printLocalAliases)
+          {
+            vector<string> aliases = parametrizable->getAlias(pname);
+            for (unsigned int j = 0; aliases.size(); j++)
+              {
+                out << ", " << aliases[j] << "=" << pname;
+              }
+          }
+        writtenNames.push_back(pl[i].getName());
+      }
+    }
+  out.setPrecision(p);
+}
diff --git a/src/Bpp/Io/BppOParametrizableFormat.h b/src/Bpp/Io/BppOParametrizableFormat.h
new file mode 100644
index 0000000..946afb5
--- /dev/null
+++ b/src/Bpp/Io/BppOParametrizableFormat.h
@@ -0,0 +1,110 @@
+//
+// File: Bpp0ParametrizableFormat.h
+// Created by: Laurent Guéguen
+// Created on: lundi 3 septembre 2012, à 15h 30
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for phylogenetic data analysis.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BPPOPARAMETRIZABLEFORMAT_H_
+#define _BPPOPARAMETRIZABLEFORMAT_H_
+
+#include "IoParametrizable.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Parametrizable output in BppO format.
+   *
+   * Writes a new parametrizable object according to BppO description
+   * syntax (see the Bio++ Progam Suite manual for a detailed
+   * description of this syntax).
+   *
+   */
+  class BppOParametrizableFormat:
+    public OParametrizable
+  {
+  public:
+    BppOParametrizableFormat() {}
+    virtual ~BppOParametrizableFormat() {}
+
+  public:
+    const std::string getFormatName() const { return "BppO"; }
+
+    const std::string getFormatDescription() const { return "Bpp Options format."; }
+
+    /**
+     * @brief Write a Parametrizable to a stream.
+     *
+     * @param parametrizable A pointer to a Parametrizable object;
+     * @param out The output stream;
+     * @param writtenNames is the vector of the written
+     *        parameters so far [in, out];
+     * @param printComma boolean if a comma should be written at the
+     *        beginning of the description.
+     */
+    
+    void write(const Parametrizable* parametrizable,
+               OutputStream& out,
+               std::vector<std::string>& writtenNames,
+               bool printComma = false) const;
+    
+    /**
+     * @brief Write a ParameterAliasable to a stream.
+     *
+     * @param parametrizable A pointer to a Parametrizable object;
+     * @param out The output stream;
+     * @param globalAliases parameters linked to global alias; 
+     * @param names the names of the parameters to be written;
+     * @param writtenNames is the vector of the written
+     *        parameters so far [in, out];
+     * @param printLocalAliases boolean if local aliases should be written;
+     * @param printComma boolean if a comma should be written at the
+     *        beginning of the description.
+     */
+    
+    void write(const ParameterAliasable* parametrizable,
+               OutputStream& out,
+               std::map<std::string, std::string>& globalAliases,
+               const std::vector<std::string>& names,
+               std::vector<std::string>& writtenNames,
+               bool printLocalAliases = true,
+               bool printComma = false) const;
+  };
+
+} //end of namespace bpp.
+
+#endif //_BPPOPARAMETRIZABLEFORMAT_H_
+
diff --git a/src/Bpp/Io/FileTools.cpp b/src/Bpp/Io/FileTools.cpp
new file mode 100644
index 0000000..c6392f3
--- /dev/null
+++ b/src/Bpp/Io/FileTools.cpp
@@ -0,0 +1,153 @@
+//
+// File FileTools.cpp
+// Author : Guillaume Deuchst
+//          Julien Dutheil
+// Last modification : Tuesday August 23 2005
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "FileTools.h" // class's header file
+#include "../Text/TextTools.h"
+#include <sys/stat.h>
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+
+char FileTools::DIR_SEP = '/';
+
+/******************************************************************************/
+
+bool FileTools::fileExists(const std::string& filename)
+{
+  ifstream file(filename.c_str());
+  bool test = file;
+  file.close();
+  return test;
+}
+
+/******************************************************************************/
+
+bool FileTools::directoryExists(const std::string& path)
+{
+  ifstream file(path.c_str());
+  bool test = file;
+  file.close();
+  return test;
+}
+
+/******************************************************************************/
+
+std::string FileTools::getFileName(const std::string& path, char dirSep)
+{
+  size_t end = path.find_last_of(".");
+  size_t begin = path.find_last_of(dirSep) + 1;
+
+  // Return an empty string if specified string isn't a path
+  if (begin > end) return "";
+
+  // Copy path and deletion of directories and extension
+  string result(path);
+  result.erase(result.begin() + end, result.end());
+  result.erase(result.begin(), result.begin() + begin);
+
+  // Send file name
+  return result;
+}
+
+/******************************************************************************/
+
+streampos FileTools::getFileSize(const std::string& filename)
+{
+  std::ifstream stream;
+  streampos size;
+  stream.open(filename.c_str(), std::ios::ate);
+  size = stream.tellg();
+  stream.close();
+  return size;
+}
+
+/******************************************************************************/
+
+std::string FileTools::getParent(const std::string& path, char dirSep)
+{
+  // Position of file name:
+  size_t begin = path.find_last_of(dirSep);
+
+  // Copy string and delte filename:
+  string result(path);
+  result.erase(result.begin() + begin, result.end());
+
+  // Send directories
+  return result;
+}
+
+/******************************************************************************/
+
+std::string FileTools::getExtension(const std::string& path)
+{
+  size_t end = path.find_last_of(".");
+  return path.substr(end+1);
+}
+
+/******************************************************************************/
+
+std::vector<std::string> FileTools::putStreamIntoVectorOfStrings(std::istream& input)
+{
+  vector<string> vs;
+  string s = "";
+  while(input)
+  {
+    getline(input, s, '\n');
+    vs.push_back(s);
+  }
+  return vs;
+}
+
+/******************************************************************************/
+
+std::string FileTools::getNextLine(std::istream& in)
+{
+  if(in.eof()) return string("");
+  string temp("");
+  while(!in.eof() && TextTools::isEmpty(temp)) {
+    getline(in, temp, '\n');
+  }
+  return temp;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Io/FileTools.h b/src/Bpp/Io/FileTools.h
new file mode 100644
index 0000000..c8e7dd7
--- /dev/null
+++ b/src/Bpp/Io/FileTools.h
@@ -0,0 +1,162 @@
+//
+// File FileTools.h
+// Created by: Guillaume Deuchst
+//             Julien Dutheil
+// Last modification : Monday August 4 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _FILETOOLS_H_
+#define _FILETOOLS_H_
+
+// From the STL:
+#include <string>
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <cstdio>
+//#include <io.h>  // required for directoryExists method
+
+namespace bpp
+{
+
+/**
+ * @brief Some utilitary functions to deal with files.
+ *
+ * File paths default to unix, i.e. the directory seprator if '/'.
+ * This character is stored in the variable 'DIR_SEP', and hence may be changed by
+ * @code
+ * FileTools::DIR_SEP='\\';
+ * @endcode
+ * for windows programs.
+ * 
+ * Methods dealing with pathes have an optional dirSep argument, which default to DIR_SEP.
+ */
+class FileTools
+{
+	public:
+		static char DIR_SEP;
+	
+	public:
+		FileTools() {}
+		virtual ~FileTools() {}
+
+	public:
+		
+		/**
+		 * @brief Tells if a file exist.
+		 *
+		 * @param filename The path toward the file.
+		 * @return True if the file exists.
+		 */
+		static bool fileExists(const std::string& filename);
+		
+		/**
+		 * @brief Tells if a directory exist.
+		 *
+		 * NB: this is an alias for fileExists.
+		 * 
+		 * @param path The path toward the file.
+		 * @return True if the file exists.
+		 */
+		static bool directoryExists(const std::string& path);
+
+		/**
+		 * @brief Get the name of of a file, without extension.
+		 *
+		 * Example:
+		 * FileTools::getFileName("/path/file.ext") returns "file".
+		 * This method is not recursive, hence
+		 * FileTools::getfileName("/home/me/archive.tar.gz") returns "archive".
+		 * 
+		 * An empty string is returned if 'path' is not a valid path toward a file.
+		 *
+		 * @param path A file path.
+		 * @param dirSep The directory separator.
+		 * @return The filename of the file specified by path.
+		 */
+		static std::string getFileName(const std::string& path, char dirSep = DIR_SEP);
+
+    /**
+     * @brief Get the size of a file.
+     *
+     * @param filename The path toward the file.
+     * @return The size of the file.
+     * @author Sylvain Gaillard
+     */
+    static std::streampos getFileSize(const std::string& filename);
+
+		/**
+		 * @brief Get the path of the parent directry of the given file/dir.
+		 * 
+		 * @param path A file/directory path.
+		 * @param dirSep The directory separator.
+		 * @return The path towar dthe parent directory.
+		 */
+		static std::string getParent(const std::string& path, char dirSep = DIR_SEP);
+
+		/**
+		 * @brief Get the extension of a file.
+		 * 
+		 * Example:
+		 * FileTools::getExtension("/path/file.ext") returns "ext".
+		 * This method is not recursive, hence
+		 * FileTools::getExtension("/home/me/archive.tar.gz") returns "gz".
+		 * 
+		 * @param path A file path.
+		 * @return The extension of the file specified by path.
+		 */
+		static std::string getExtension(const std::string& path);
+	
+		/**
+		 * @brief Reads a stream and write each line in a vector.
+		 *
+		 * @param input Input stream.
+		 * @return A vector of strings.
+		 */
+		static std::vector<std::string> putStreamIntoVectorOfStrings(std::istream& input);
+
+		/**
+		 * @brief Get the next non-blanck line of a stream.
+		 *
+		 * @param in Input stream.
+		 */
+		static std::string getNextLine(std::istream& in);
+};
+
+} //end of namespace bpp.
+
+#endif	// _FILETOOLS_H_
+
diff --git a/src/Bpp/Io/IoDiscreteDistribution.h b/src/Bpp/Io/IoDiscreteDistribution.h
new file mode 100644
index 0000000..8c96b31
--- /dev/null
+++ b/src/Bpp/Io/IoDiscreteDistribution.h
@@ -0,0 +1,125 @@
+//
+// File: IoDiscreteDistribution.h
+// Created by: Laurent Guéguen
+// Created on: lundi 3 septembre 2012, à 14h 35
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for phylogenetic data analysis.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _IODISCRETEDISTRIBUTION_H_
+#define _IODISCRETEDISTRIBUTION_H_
+
+#include "../Numeric/Prob/DiscreteDistribution.h"
+#include "../Exceptions.h"
+#include "IoFormat.h"
+#include "OutputStream.h"
+
+namespace bpp
+{
+  /**
+   * @brief General interface for model I/O.
+   */
+  class IoDiscreteDistribution:
+    public virtual IOFormat
+  {
+  public:
+    IoDiscreteDistribution() {}
+    virtual ~IoDiscreteDistribution() {}
+
+  public:
+    virtual const std::string getDataType() const { return "Discrete Distribution"; }
+  };
+
+  /**
+   * @brief General interface for distance matrix readers.
+   */
+  class IDiscreteDistribution:
+    public virtual IoDiscreteDistribution
+  {
+  public:
+    IDiscreteDistribution() {}
+    virtual ~IDiscreteDistribution() {}
+
+  public:
+    /**
+     * @brief Read a discrete distribution from a string.
+     *
+     * @param distrDescription A string describing the distribution in the format.
+     * @param parseArguments Attempt to parse function arguments. If not, only store them and use default values instead.
+     * @return A new DiscreteDistribution object according to options specified.
+     * @throw Exception if an error occured.
+     */
+    virtual DiscreteDistribution* read(
+        const std::string& distrDescription,
+        bool parseArguments = true) = 0;
+
+    /**
+     * @return The arguments and their unparsed values from the last call of the read function, if there are any.
+     */
+    virtual const std::map<std::string, std::string>& getUnparsedArguments() const = 0;
+
+  };
+
+  /**
+   * @brief General interface writers.
+   */
+  class ODiscreteDistribution:
+    public virtual IoDiscreteDistribution
+  {
+  public:
+    ODiscreteDistribution() {}
+    virtual ~ODiscreteDistribution() {}
+
+  public:
+    /**
+     * @brief Write a discrete distribution to a stream.
+     *
+     * @param dist A discrete distribution object;
+     * @param out The output stream;
+     * @param globalAliases parameters linked to global alias. 
+     * @param writtenNames is the vector of the written
+     *        parameters so far [in, out];
+     * @throw Exception if an error occured.
+     */
+    virtual void write(const DiscreteDistribution& dist,
+                       OutputStream& out,
+                       std::map<std::string, std::string>& globalAliases,
+                       std::vector<std::string>& writtenNames) const = 0;
+  };
+
+
+} //end of namespace bpp.
+
+#endif //_IODISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Io/IoDiscreteDistributionFactory.cpp b/src/Bpp/Io/IoDiscreteDistributionFactory.cpp
new file mode 100644
index 0000000..7fb3346
--- /dev/null
+++ b/src/Bpp/Io/IoDiscreteDistributionFactory.cpp
@@ -0,0 +1,57 @@
+//
+// File IoDiscreteDistributionFactory.cpp
+// Created by: Laurent Guéguen
+// Created on: lundi 3 septembre 2012, à 14h 44
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for sequences analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "BppODiscreteDistributionFormat.h"
+
+using namespace bpp;
+
+const std::string IoDiscreteDistributionFactory::BPPO_FORMAT = "Bpp0"; 
+
+IDiscreteDistribution* IoDiscreteDistributionFactory::createReader(const std::string& format) throw (Exception)
+{
+  if(format == BPPO_FORMAT) return new BppODiscreteDistributionFormat();
+  else throw Exception("Format " + format + " is not supported for input.");
+}
+  
+ODiscreteDistribution* IoDiscreteDistributionFactory::createWriter(const std::string& format) throw (Exception)
+{
+  if(format == BPPO_FORMAT) return new BppODiscreteDistributionFormat();
+  else throw Exception("Format " + format + " is not supported for output.");
+}
+
diff --git a/src/Bpp/Io/IoDiscreteDistributionFactory.h b/src/Bpp/Io/IoDiscreteDistributionFactory.h
new file mode 100644
index 0000000..e18d12b
--- /dev/null
+++ b/src/Bpp/Io/IoDiscreteDistributionFactory.h
@@ -0,0 +1,99 @@
+//
+// File IODiscreteDistributionFactory.h
+// Created by: Laurent Guéguen
+// Created on: lundi 3 septembre 2012, à 14h 45
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for sequences analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _IODISCRETEDISTRIBUTIONFACTORY_H_
+#define _IODISCRETEDISTRIBUTIONFACTORY_H_
+
+#include "../Numeric/Prob/DiscreteDistribution.h"
+#include "../Exceptions.h"
+#include "IoDiscreteDistribution.h"
+
+//From the STL:
+#include <string>
+
+namespace bpp
+{
+
+/**
+ * @brief Utilitary class for creating discrete distribution readers and
+ * writers.
+ */
+class IoDiscreteDistributionFactory
+{
+public:
+  static const std::string BPPO_FORMAT;  
+
+public:
+
+  /**
+   * @brief Creates a new factory object.
+   *
+   * Example:
+   * @code
+   * IDiscreteDistribution* distReader = IoDiscreteDistributionFactory().createReader(IoDiscreteDistributionFactory::BPP_FORMAT);
+   * DiscreteDistribution* dist = distReader->read(...);
+   * delete distReader;
+   * @endcode
+   */
+  IoDiscreteDistributionFactory() {}
+  virtual ~IoDiscreteDistributionFactory() {}
+  
+  /**
+   * @brief Get a new dynamically created IDiscreteDistribution object.
+   *
+   * @param format The input file format.
+   * @return A pointer toward a new IDiscreteDistribution object.
+   * @throw Exception If the format name do not match any available format.
+   */
+  virtual IDiscreteDistribution* createReader(const std::string& format) throw (Exception);
+  
+  /**
+   * @brief Get a new dynamically created ODiscreteDistribution object.
+   *
+   * @param format The output file format.
+   * @return A pointer toward a new ODiscreteDistribution object.
+   * @throw Exception If the format name do not match any available format.
+   */
+  virtual ODiscreteDistribution* createWriter(const std::string& format) throw (Exception);
+};
+
+} //end of namespace bpp.
+
+#endif //_IODISCRETEDISTRIBUTIONFACTORY_H_
+
diff --git a/src/Bpp/Io/IoFormat.h b/src/Bpp/Io/IoFormat.h
new file mode 100644
index 0000000..fbbbd42
--- /dev/null
+++ b/src/Bpp/Io/IoFormat.h
@@ -0,0 +1,89 @@
+//
+// File IoFormat.h
+// Author : Julien Dutheil
+// Created on: 2005
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide utilitary
+  classes. This file belongs to the Bio++ Project.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _IOFORMAT_H_
+#define _IOFORMAT_H_
+
+#include "../Exceptions.h"
+
+// From STL:
+#include <string>
+
+namespace bpp
+{
+
+  /**
+   * @brief The IOFormat interface.
+   *
+   * This is the most basal class of any format I/O implementation.
+   */
+  class IOFormat
+  {
+  public:
+    IOFormat() {}
+    virtual ~IOFormat() {}
+
+  public:
+
+    /**
+     * @brief Get the type of data this format deals with.
+     *
+     * @return The type of data.
+     */
+    virtual const std::string getDataType() const = 0;
+		
+    /**
+     * @brief Get the name of the file format.
+     *
+     * @return The name of the format implemented.
+     */
+    virtual const std::string getFormatName() const = 0;
+		
+    /**
+     * @brief Get a description of the file format.
+     *
+     * @return A description of the format implemented.
+     */
+    virtual const std::string getFormatDescription() const = 0;
+  };
+
+} //end of namespace bpp.
+
+#endif	// _IOFORMAT_H_
+
diff --git a/src/Bpp/Io/IoParametrizable.h b/src/Bpp/Io/IoParametrizable.h
new file mode 100644
index 0000000..aaf0bef
--- /dev/null
+++ b/src/Bpp/Io/IoParametrizable.h
@@ -0,0 +1,117 @@
+//
+// File: IOParametrizable.h
+// Created by: Laurent Guéguen
+// Created on: lundi 3 septembre 2012, à 14h 35
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for phylogenetic data analysis.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _IOPARAMETRIZABLE_H_
+#define _IOPARAMETRIZABLE_H_
+
+#include "../Numeric/ParameterAliasable.h"
+
+#include "IoFormat.h"
+#include "OutputStream.h"
+
+#include <map>
+namespace bpp
+{
+  /**
+   * @brief General interface for parametrizable Output.
+   */
+  class IOParametrizable:
+    public virtual IOFormat
+  {
+  public:
+    IOParametrizable() {}
+    virtual ~IOParametrizable() {}
+
+  public:
+    virtual const std::string getDataType() const { return "Parametrizable"; }
+  };
+
+  /**
+   * @brief General interface writers.
+   */
+  class OParametrizable:
+    public virtual IOParametrizable
+  {
+  public:
+    OParametrizable() {}
+    virtual ~OParametrizable() {}
+
+  public:
+    /**
+     * @brief Write a Parametrizable to a stream.
+     *
+     * @param parametrizable A pointer to a Parametrizable object;
+     * @param out The output stream;
+     * @param writtenNames is the vector of the written
+     *        parameters so far [in, out];
+     * @param printComma boolean if a comma should be written at the
+     *        beginning of the description.
+     */
+    virtual void write(const Parametrizable* parametrizable,
+                       OutputStream& out,
+                       std::vector<std::string>& writtenNames,
+                       bool printComma=false) const = 0;
+ 
+    /**
+     * @brief Write a ParameterAliasable to a stream.
+     *
+     * @param parametrizable A pointer to a Parametrizable object;
+     * @param out The output stream;
+     * @param globalAliases parameters linked to global alias; 
+     * @param names the names of the parameters to be written;
+     * @param writtenNames is the vector of the written
+     *        parameters so far [in, out];
+     * @param printLocalAliases boolean if local aliases should be written;
+     * @param printComma boolean if a comma should be written at the
+     *        beginning of the description.
+     */
+    virtual void write(const ParameterAliasable* parametrizable,
+                       OutputStream& out,
+                       std::map<std::string, std::string>& globalAliases,
+                       const std::vector<std::string>& names,
+                       std::vector<std::string>& writtenNames,
+                       bool printLocalAliases = true,
+                       bool printComma=false) const = 0;
+  };
+
+
+} //end of namespace bpp.
+
+#endif //_IOPARAMETRIZABLE_H_
+
diff --git a/src/Bpp/Io/OutputStream.h b/src/Bpp/Io/OutputStream.h
new file mode 100644
index 0000000..452bb07
--- /dev/null
+++ b/src/Bpp/Io/OutputStream.h
@@ -0,0 +1,354 @@
+//
+// File: BppStream.h
+// Created by: Julien Dutheil
+// Created on: Mon Jan 25 17:41 2010
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BPPSTREAM_H_
+#define _BPPSTREAM_H_
+
+#include "../Clonable.h"
+
+//From the STL:
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <memory>
+#include <iomanip>
+
+namespace bpp
+{
+
+/**
+ * @brief OutputStream interface.
+ *
+ * This interface define several << operators for outputing messages.
+ * Wrapper classes for the STL streams are available as special
+ * implementations, but this interface can be used to redirect the output to
+ * files or to graphical components for instance.
+ */
+class OutputStream :
+  public virtual Clonable
+{
+public:
+  virtual OutputStream& operator<<(const std::string& message) = 0;
+  virtual OutputStream& operator<<(const char* message) = 0;
+  virtual OutputStream& operator<<(const char& message) = 0;
+  virtual OutputStream& operator<<(const int& message) = 0;
+  virtual OutputStream& operator<<(const unsigned int& message) = 0;
+  virtual OutputStream& operator<<(const long int& message) = 0;
+  virtual OutputStream& operator<<(const unsigned long int& message) = 0;
+  virtual OutputStream& operator<<(const double& message) = 0;
+  virtual OutputStream& operator<<(const long double& message) = 0;
+  virtual OutputStream& operator<<(const bool& message) = 0;
+  virtual OutputStream& endLine() = 0;
+  virtual OutputStream& flush() = 0;
+  virtual OutputStream& setPrecision(unsigned int digit) = 0;
+  virtual unsigned int getPrecision() const = 0;
+  virtual OutputStream& enableScientificNotation(bool yn) = 0;
+  virtual bool isScientificNotationEnabled() const = 0;
+
+  /**
+   * @name The Clonable interface.
+   *
+   * @{
+   */
+#ifndef NO_VIRTUAL_COV
+  OutputStream* clone() const = 0;
+#endif
+  /** @} */
+
+};
+
+
+
+
+
+/**
+ * @brief Helper implementation of the OutputStream interface.
+ */
+class AbstractOutputStream :
+  public virtual OutputStream
+{
+private:
+  unsigned int precision_;
+  bool scienceNotation_;
+
+public:
+  AbstractOutputStream() : precision_(6), scienceNotation_(false) {}
+
+public:
+  OutputStream& setPrecision(unsigned int digit)
+  {
+    precision_ = digit;
+    return *this;
+  }
+  unsigned int getPrecision() const { return precision_; }
+
+  virtual OutputStream& enableScientificNotation(bool yn) { scienceNotation_ = yn; return *this; }
+  virtual bool isScientificNotationEnabled() const { return scienceNotation_; }
+};
+
+
+
+
+
+/**
+ * @brief Null output stream (swich off output).
+ */
+class NullOutputStream :
+  public AbstractOutputStream
+{
+public:
+  NullOutputStream& operator<<(const std::string& message) { return *this; }
+  NullOutputStream& operator<<(const char* message) { return *this; }
+  NullOutputStream& operator<<(const char& message) { return *this; }
+  NullOutputStream& operator<<(const int& message) { return *this; }
+  NullOutputStream& operator<<(const unsigned int& message) { return *this; }
+  NullOutputStream& operator<<(const long int& message) { return *this; }
+  NullOutputStream& operator<<(const unsigned long int& message) { return *this; }
+  NullOutputStream& operator<<(const double& message) { return *this; }
+  NullOutputStream& operator<<(const long double& message) { return *this; }
+  NullOutputStream& operator<<(const bool& message) { return *this; }
+  NullOutputStream& endLine() { return *this; }
+  NullOutputStream& flush() { return *this; }
+
+  NullOutputStream* clone() const { return new NullOutputStream(*this); }
+
+};
+
+
+
+
+
+
+/**
+ * @brief STL output stream.
+ *
+ * This class wraps the std::ostream class.
+ * It takes as input a pointer toward an existing stream that will then be
+ * owned by the wrapper, as a smart pointer.
+ * Any copy of this class will then result in an inactivation of the original
+ * version (in other word, you can't have two wrappers for the same stream).
+ */
+class StlOutputStream :
+  public AbstractOutputStream
+{
+private:
+  mutable std::auto_ptr<std::ostream> stream_;
+
+public:
+  StlOutputStream(std::ostream* stream): stream_(stream) {}
+  StlOutputStream(const StlOutputStream& stlos) : stream_(stlos.stream_) {}
+  StlOutputStream& operator=(const StlOutputStream& stlos)
+  {
+    stream_ = stlos.stream_;
+    return *this;
+  }
+
+public:
+  StlOutputStream& operator<<(const std::string& message) { if (stream_.get()) *stream_ << message; return *this; }
+  StlOutputStream& operator<<(const char* message) { if (stream_.get()) *stream_ << message; return *this; }
+  StlOutputStream& operator<<(const char& message) { if (stream_.get()) *stream_ << message; return *this; }
+  StlOutputStream& operator<<(const int& message) { if (stream_.get()) *stream_ << message; return *this; }
+  StlOutputStream& operator<<(const unsigned int& message) { if (stream_.get()) *stream_ << message; return *this; }
+  StlOutputStream& operator<<(const long int& message) { if (stream_.get()) *stream_ << message; return *this; }
+  StlOutputStream& operator<<(const unsigned long int& message) { if (stream_.get()) *stream_ << message; return *this; }
+  StlOutputStream& operator<<(const double& message)
+  {
+    if (stream_.get())
+      *stream_ << std::setprecision(getPrecision()) << (isScientificNotationEnabled() ? std::scientific : std::fixed) << message;
+    return *this;
+  }
+  StlOutputStream& operator<<(const long double& message)
+  {
+    if (stream_.get())
+      *stream_ << std::setprecision(getPrecision()) << (isScientificNotationEnabled() ? std::scientific : std::fixed) << message;
+    return *this;
+  }
+  StlOutputStream& operator<<(const bool& message) { if (stream_.get()) *stream_ << message; return *this; }
+  StlOutputStream& endLine() { if (stream_.get()) *stream_ << std::endl; return *this; }
+  StlOutputStream& flush() { if (stream_.get()) stream_->flush(); return *this; }
+
+  StlOutputStream* clone() const { return new StlOutputStream(*this); }
+
+};
+
+
+
+
+
+/**
+ * @brief STL wrapper for output stream.
+ *
+ * This class wraps the std::ostream class, by forwarding to the STL class.
+ * It does not own the STL stream and won't delete it.
+ */
+class StlOutputStreamWrapper :
+  public AbstractOutputStream
+{
+protected:
+  std::ostream* stream_;
+
+public:
+  StlOutputStreamWrapper(std::ostream* stream): stream_(stream) {}
+  StlOutputStreamWrapper(const StlOutputStreamWrapper& stlos) : stream_(stlos.stream_) {}
+  StlOutputStreamWrapper& operator=(const StlOutputStreamWrapper& stlos) { stream_ = stlos.stream_; return *this; }
+
+public:
+  StlOutputStreamWrapper& operator<<(const std::string& message) { if (stream_) *stream_ << message; return *this; }
+  StlOutputStreamWrapper& operator<<(const char* message) { if (stream_) *stream_ << message; return *this; }
+  StlOutputStreamWrapper& operator<<(const char& message) { if (stream_) *stream_ << message; return *this; }
+  StlOutputStreamWrapper& operator<<(const int& message) { if (stream_) *stream_ << message; return *this; }
+  StlOutputStreamWrapper& operator<<(const unsigned int& message) { if (stream_) *stream_ << message; return *this; }
+
+  StlOutputStreamWrapper& operator<<(const long int& message) { if (stream_) *stream_ << message; return *this; }
+  StlOutputStreamWrapper& operator<<(const unsigned long int& message) { if (stream_) *stream_ << message; return *this; }
+  StlOutputStreamWrapper& operator<<(const double& message)
+  {
+    if (stream_)
+      *stream_ << std::setprecision(getPrecision()) << (isScientificNotationEnabled() ? std::scientific : std::fixed) << message;
+    return *this;
+  }
+  StlOutputStreamWrapper& operator<<(const long double& message)
+  {
+    if (stream_)
+      *stream_ << std::setprecision(getPrecision()) << (isScientificNotationEnabled() ? std::scientific : std::fixed) << message;
+    return *this;
+  } 
+  StlOutputStreamWrapper& operator<<(const bool& message) { if (stream_) *stream_ << message; return *this; }
+  StlOutputStreamWrapper& endLine() { if (stream_) *stream_ << std::endl; return *this; }
+  StlOutputStreamWrapper& flush() { if (stream_) stream_->flush(); return *this; }
+
+  StlOutputStreamWrapper* clone() const { return new StlOutputStreamWrapper(*this); }
+
+};
+
+/**
+ * @brief Standard output stream.
+ *
+ * This class wraps the std::cout stream.
+ */
+class StdOut :
+  public AbstractOutputStream
+{
+public:
+  OutputStream& operator<<(const std::string& message) { std::cout << message; return *this; }
+  OutputStream& operator<<(const char* message) { std::cout << message; return *this; }
+  OutputStream& operator<<(const char& message) { std::cout << message; return *this; }
+  OutputStream& operator<<(const int& message) { std::cout << message; return *this; }
+  OutputStream& operator<<(const unsigned int& message) { std::cout << message; return *this; }
+  OutputStream& operator<<(const long int& message) { std::cout << message; return *this; }
+  OutputStream& operator<<(const unsigned long int& message) { std::cout << message; return *this; }
+  OutputStream& operator<<(const double& message)
+  {
+    std::cout << std::setprecision(getPrecision()) << (isScientificNotationEnabled() ? std::scientific : std::fixed) << message;
+    return *this;
+  }
+  OutputStream& operator<<(const long double& message)
+  {
+    std::cout << std::setprecision(getPrecision()) << (isScientificNotationEnabled() ? std::scientific : std::fixed) << message;
+    return *this;
+  }
+  OutputStream& operator<<(const bool& message) { std::cout << message; return *this; }
+  OutputStream& endLine() { std::cout << std::endl; return *this; }
+  OutputStream& flush() { std::cout.flush(); return *this; }
+
+  StdOut* clone() const { return new StdOut(*this); }
+
+};
+
+
+
+
+
+/**
+ * @brief Standard error stream.
+ *
+ * This class wraps the std::cerr stream.
+ */
+class StdErr :
+  public AbstractOutputStream
+{
+public:
+  OutputStream& operator<<(const std::string& message) { std::cerr << message; return *this; }
+  OutputStream& operator<<(const char* message) { std::cerr << message; return *this; }
+  OutputStream& operator<<(const char& message) { std::cerr << std::setprecision(getPrecision()) << message; return *this; }
+  OutputStream& operator<<(const int& message) { std::cerr << std::setprecision(getPrecision()) << message; return *this; }
+  OutputStream& operator<<(const unsigned int& message) { std::cerr << message; return *this; }
+  OutputStream& operator<<(const long int& message) { std::cerr << std::setprecision(getPrecision()) << message; return *this; }
+  OutputStream& operator<<(const unsigned long int& message) { std::cerr << message; return *this; }
+  OutputStream& operator<<(const double& message)
+  {
+    std::cerr << std::setprecision(getPrecision()) << (isScientificNotationEnabled() ? std::scientific : std::fixed) << message;
+    return *this;
+  }
+  OutputStream& operator<<(const long double& message)
+  {
+    std::cerr << std::setprecision(getPrecision()) << (isScientificNotationEnabled() ? std::scientific : std::fixed) << message;
+    return *this;
+  }
+  OutputStream& operator<<(const bool& message) { std::cerr << message; return *this; }
+  OutputStream& endLine() { std::cerr << std::endl; return *this; }
+  OutputStream& flush() { std::cerr.flush(); return *this; }
+
+#ifndef NO_VIRTUAL_COV
+  StdErr* clone() const { return new StdErr(*this); }
+#endif
+
+};
+
+/**
+ * @brief String output stream.
+ *
+ * This class wraps the std::ostringstream stream.
+ */
+class StdStr :
+  public StlOutputStreamWrapper
+{
+public:
+  StdStr(): StlOutputStreamWrapper(new std::ostringstream()){}
+  
+  std::string str() const { return dynamic_cast<const std::ostringstream*>(stream_)->str();}
+
+  ~StdStr() { delete stream_;}
+};
+
+} // end of namespace bpp;
+
+#endif //_BPPSTREAM_H_
+
diff --git a/src/Bpp/Numeric/AbstractParameterAliasable.cpp b/src/Bpp/Numeric/AbstractParameterAliasable.cpp
new file mode 100644
index 0000000..98157bd
--- /dev/null
+++ b/src/Bpp/Numeric/AbstractParameterAliasable.cpp
@@ -0,0 +1,207 @@
+//
+// File: AbstractParameterAliasable.cpp
+// Created by: Julien Dutheil
+// Created on: Sun Mar 29 09:10 2009
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "AbstractParameterAliasable.h"
+#include "VectorTools.h"
+
+using namespace bpp;
+using namespace std;
+
+AbstractParameterAliasable::AbstractParameterAliasable(const AbstractParameterAliasable& ap) :
+  AbstractParametrizable(ap),
+  independentParameters_(ap.independentParameters_),
+  aliasListenersRegister_()
+{
+  // Actualize the register with adequate pointers:
+  for (map<string, AliasParameterListener*>::const_iterator it = ap.aliasListenersRegister_.begin();
+       it != ap.aliasListenersRegister_.end();
+       it++)
+  {
+    AliasParameterListener* listener = it->second->clone();
+    listener->setParameterList(&getParameters_());
+    aliasListenersRegister_[it->first] = listener;
+    //Now correct parameters with appropriate pointers:
+    for (unsigned int i = 0; i < getNumberOfParameters(); ++i) {
+      if (getParameters_()[i].hasParameterListener(it->first)) {
+        getParameters_()[i].removeParameterListener(it->first);
+        getParameters_()[i].addParameterListener(listener, false);
+      }
+    }
+  }
+}
+
+AbstractParameterAliasable& AbstractParameterAliasable::operator=(const AbstractParameterAliasable& ap)
+{
+  independentParameters_ = ap.independentParameters_;
+
+  // Actualize the register with adequate pointers:
+  for (map<string, AliasParameterListener*>::const_iterator it = ap.aliasListenersRegister_.begin();
+       it != ap.aliasListenersRegister_.end();
+       it++)
+  {
+    AliasParameterListener* listener = it->second->clone();
+    listener->setParameterList(&getParameters_());
+    aliasListenersRegister_[it->first] = listener;
+    //Now correct parameters with appropriate pointers:
+    for (unsigned int i = 0; i < getNumberOfParameters(); ++i) {
+      if (getParameters_()[i].hasParameterListener(it->first)) {
+        getParameters_()[i].removeParameterListener(it->first);
+        getParameters_()[i].addParameterListener(listener, false);
+      }
+    }
+  }
+  return *this;
+}
+
+AbstractParameterAliasable::~AbstractParameterAliasable()
+{
+  // Delete the registry content:
+  for (map<string, AliasParameterListener*>::iterator it = aliasListenersRegister_.begin();
+       it != aliasListenersRegister_.end();
+       it++)
+  {
+    delete it->second;
+  }
+}
+
+void AbstractParameterAliasable::aliasParameters(const std::string& p1, const std::string& p2)
+throw (ParameterNotFoundException, Exception)
+{
+  // In case this is the first time we call this method:
+  if (getNumberOfParameters() > 0 && independentParameters_.size() == 0)
+    independentParameters_ = getParameters();
+
+  if (!hasParameter(p1))
+    throw ParameterNotFoundException("AbstractParameterAliasable::aliasParameters", p1);
+  if (!hasParameter(p2))
+    throw ParameterNotFoundException("AbstractParameterAliasable::aliasParameters", p2);
+  if (!independentParameters_.hasParameter(getNamespace() + p2))
+    throw Exception("AbstractParameterAliasable::aliasParameters. Parameter " + p2 + " is already aliased to a parameter and can't be aliased twice.");
+
+  string id = "__alias_" + p2 + "_to_" + p1;
+  string idCheck = "__alias_" + p1 + "_to_" + p2;
+  if (aliasListenersRegister_.find(idCheck) != aliasListenersRegister_.end())
+    throw Exception("AbstractParameterAliasable::aliasParameters. Trying to alias parameter " + p2 + " to " + p1 + ", but parameter " + p1 + " is already aliased to parameter " + p2 + ".");
+  Parameter* param1 = &getParameter_(p1);
+  Parameter* param2 = &getParameter_(p2);
+  if (!param1->hasConstraint())
+  {
+    if (param2->hasConstraint())
+      throw Exception("AbstractParameterAliasable::aliasParameters. Cannot alias parameter " + p2 + " to " + p1 + ", because the constraints attached to these two parameters are different.");
+  }
+  else
+  // We use a small trick here, we test the constraints on the basis of their string description (C++ does not provide a default operator==() :( ).
+  if (param2->hasConstraint() && (param1->getConstraint()->getDescription() != param2->getConstraint()->getDescription()))
+    throw Exception("AbstractParameterAliasable::aliasParameters. Cannot alias parameter " + p2 + " to " + p1 + ", because the constraints attached to these two parameters are different.");
+
+  // Every thing seems ok, let's create the listener and register it:
+  AliasParameterListener* aliasListener = new AliasParameterListener(id, getParameters().whichParameterHasName(getNamespace() + p2), &getParameters_());
+  aliasListenersRegister_[id] = aliasListener;
+  // Now we add it to the appropriate parameter, that is p1.
+  // The parameter will not own the listener, the bookkeeping being achieved by the register:
+  param1->addParameterListener(aliasListener, false);
+  // Finally we remove p2 from the list of independent parameters:
+  independentParameters_.deleteParameter(getNamespace() + p2);
+}
+
+void AbstractParameterAliasable::unaliasParameters(const std::string& p1, const std::string& p2)
+throw (ParameterNotFoundException, Exception)
+{
+  if (!hasParameter(p1))
+    throw ParameterNotFoundException("AbstractParameterAliasable::unaliasParameters", p1);
+  if (!hasParameter(p2))
+    throw ParameterNotFoundException("AbstractParameterAliasable::unaliasParameters", p2);
+
+  string id = "__alias_" + p2 + "_to_" + p1;
+  map<string, AliasParameterListener*>::iterator it = aliasListenersRegister_.find(id);
+  if (it == aliasListenersRegister_.end())
+    throw Exception("AbstractParameterAliasable::unaliasParameters. Parameter " + p2 + " is not aliased to parameter " + p1 + ".");
+  // Remove the listener:
+  getParameter_(p1).removeParameterListener(id);
+  delete it->second;
+  aliasListenersRegister_.erase(it);
+  // Finally we re-add p2 to the list of independent parameters:
+  independentParameters_.addParameter(getParameter(p2));
+}
+
+void AbstractParameterAliasable::setNamespace(const std::string& prefix)
+{
+  string currentName;
+  // First we correct the independent parameter list
+  for (unsigned int i = 0; i < independentParameters_.size(); i++)
+  {
+    currentName = independentParameters_[i].getName();
+    if (TextTools::startsWith(currentName, getNamespace()))
+      independentParameters_[i].setName(prefix + currentName.substr(getNamespace().size()));
+    else
+      independentParameters_[i].setName(prefix + currentName);
+  }
+  // Then we modify all the listeners
+  for (map<string, AliasParameterListener*>::iterator it = aliasListenersRegister_.begin();
+       it != aliasListenersRegister_.end();
+       it++)
+  {
+    currentName = it->second->getName();
+    if (TextTools::startsWith(currentName, getNamespace()))
+      it->second->rename(prefix + currentName.substr(getNamespace().size()));
+    else
+      it->second->rename(prefix + currentName);
+  }
+  // Finally we notify the mother class:
+  AbstractParametrizable::setNamespace(prefix);
+}
+
+vector<string> AbstractParameterAliasable::getAlias(const string& name) const
+{
+  vector<string> aliases;
+  for (map<string, AliasParameterListener*>::const_iterator it = aliasListenersRegister_.begin();
+       it != aliasListenersRegister_.end();
+       it++)
+  {
+    if (it->second->getName() == name)
+    {
+      string alias = it->second->getAlias();
+      aliases.push_back(alias);
+      vector<string> chainAliases = getAlias(alias);
+      VectorTools::append(aliases, chainAliases);
+    }
+  }
+  return aliases;
+}
+
diff --git a/src/Bpp/Numeric/AbstractParameterAliasable.h b/src/Bpp/Numeric/AbstractParameterAliasable.h
new file mode 100644
index 0000000..623161a
--- /dev/null
+++ b/src/Bpp/Numeric/AbstractParameterAliasable.h
@@ -0,0 +1,208 @@
+//
+// File: AbstractParameterAliasable.h
+// Created by: Julien Dutheil
+// Created on: Thu May 14 17:08 2009
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _ABSTRACTPARAMETERALIASABLE_H_
+#define _ABSTRACTPARAMETERALIASABLE_H_
+
+#include "AbstractParametrizable.h"
+#include "ParameterAliasable.h"
+
+//From the STL:
+#include <map>
+
+namespace bpp
+{
+
+  /**
+   * @brief Inner listener class used by AbstractParameterAliasable.
+   */
+  class AliasParameterListener:
+    public ParameterListener
+  {
+    private:
+      std::string id_;
+      size_t alias_;
+      ParameterList *pl_;
+      std::string name_;
+
+    public:
+      AliasParameterListener(const std::string& id, size_t alias, ParameterList* pl):
+        id_(id),
+        alias_(alias),
+        pl_(pl),
+        name_()
+      {
+        //This allow us to check if the parameter position have changed at some point...
+        name_ = (*pl_)[alias].getName();
+      }
+
+      AliasParameterListener(const AliasParameterListener& apl):
+        id_(apl.id_),
+        alias_(apl.alias_),
+        pl_(apl.pl_),
+        name_(apl.name_)
+      {}
+
+      AliasParameterListener& operator=(const AliasParameterListener& apl)
+      {
+        id_    = apl.id_;
+        alias_ = apl.alias_;
+        pl_    = apl.pl_;
+        name_  = apl.name_;
+        return *this;
+      }
+
+      AliasParameterListener* clone() const { return new AliasParameterListener(*this); }
+
+    public:
+      const std::string& getId() const { return id_; }
+
+      void setParameterList(ParameterList* pl) { pl_ = pl; }
+
+      void parameterNameChanged(ParameterEvent& event) throw (Exception) {}
+    
+      void parameterValueChanged(ParameterEvent& event) throw (Exception)
+      {
+        Parameter* p = &(*pl_)[alias_];
+        if (p->getName() != name_)
+          throw Exception("AbstractParameterAliasable::AliasParameterListener::parameterValueChanged. Error, aliased parameter have change, maybe because it was renamed, or a parameter was removed?");
+        p->setValue(event.getParameter()->getValue());
+      }
+
+      const std::string& getName() const { return name_; }
+
+      void rename(const std::string& name) { name_ = name; }
+
+      const std::string& getAlias() const { return (*pl_)[alias_].getName(); }
+      
+  };
+
+  /**
+   * @brief A partial implementation of the Parametrizable interface.
+   *
+   * Parameters are stored in a protected ParameterList object.
+   *
+   * The abstract fireParameterChanged() method is provided so that the derived class
+   * know when a parameter has changed, and can be updated.
+   * All methods call the corresponding method in ParameterList and then call the
+   * fireParameterChanged() method.
+   */
+  class AbstractParameterAliasable:
+    public AbstractParametrizable,
+    public virtual ParameterAliasable
+  {
+    private:
+
+      mutable ParameterList independentParameters_;
+
+      /**
+       * Contains all parameter listeners for maintening alias relationships.
+       * The registry will be updated appropriately upon cloning and deleting.
+       */
+      std::map<std::string, AliasParameterListener *> aliasListenersRegister_;
+  
+    public:
+      AbstractParameterAliasable(const std::string& prefix) :
+        AbstractParametrizable(prefix),
+        independentParameters_(),
+        aliasListenersRegister_()
+      {}
+
+      AbstractParameterAliasable(const AbstractParameterAliasable& ap);
+    
+      AbstractParameterAliasable& operator=(const AbstractParameterAliasable& ap);
+
+      virtual ~AbstractParameterAliasable();
+
+    public:
+      void setNamespace(const std::string& prefix);
+ 
+      const ParameterList& getIndependentParameters() const { return independentParameters_; }
+    
+      size_t getNumberOfIndependentParameters() const { return independentParameters_.size(); }
+
+      void aliasParameters(const std::string& p1, const std::string& p2) throw (ParameterNotFoundException, Exception);
+
+      void unaliasParameters(const std::string& p1, const std::string& p2) throw (ParameterNotFoundException, Exception);
+
+      /**
+       * @return The list of names of the parameters that are aliased with a given parameter.
+       * The implementation is recursive, which means that in the case of A->B->C, getalias(C) will return both A and B.
+       * @param name The name of the parameter to look for.
+       */
+      std::vector<std::string> getAlias(const std::string& name) const;
+
+      void fireParameterChanged(const ParameterList& parameters)
+      {
+        independentParameters_.matchParametersValues(getParameters());
+      }
+
+    protected:
+      void addParameter_(Parameter* parameter)
+      {
+        AbstractParametrizable::addParameter_(parameter);
+        independentParameters_.addParameter(parameter->clone());
+      }
+
+      void addParameters_(const ParameterList& parameters)
+      {
+        AbstractParametrizable::addParameters_(parameters);
+        independentParameters_.addParameters(parameters);
+      }
+
+      void deleteParameter_(size_t index) throw (IndexOutOfBoundsException)
+      {
+        std::string name = getParameter_(index).getName();
+        AbstractParametrizable::deleteParameter_(index);
+        if (independentParameters_.hasParameter(name))
+        independentParameters_.deleteParameter(name);
+      }
+
+      void resetParameters_()
+      {
+        AbstractParametrizable::resetParameters_();
+        independentParameters_.reset();
+      }
+
+  };
+
+} //end of namespace bpp.
+
+#endif //_ABSTRACTPARAMETERALIASABLE_H_
+
diff --git a/src/Bpp/Numeric/AbstractParametrizable.cpp b/src/Bpp/Numeric/AbstractParametrizable.cpp
new file mode 100644
index 0000000..d8b6142
--- /dev/null
+++ b/src/Bpp/Numeric/AbstractParametrizable.cpp
@@ -0,0 +1,70 @@
+//
+// File: AbstractParametrizable.cpp
+// Created by: Julien Dutheil
+// Created on: Sun Mar 29 09:10 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "AbstractParametrizable.h"
+
+using namespace bpp;
+using namespace std;
+
+void AbstractParametrizable::setNamespace(const std::string& prefix)
+{
+  //We need to update all parameter names!
+  //First correct the global parameter list
+  string currentName;
+  for(unsigned int i = 0; i < parameters_.size(); i++)
+  {
+    currentName = parameters_[i].getName();
+    if (TextTools::startsWith(currentName, prefix_))
+      parameters_[i].setName(prefix + currentName.substr(prefix_.size()));
+    else
+      parameters_[i].setName(prefix + currentName);
+  }
+
+  //Then we store the new namespace:
+  prefix_ = prefix;
+}
+
+std::string AbstractParametrizable::getParameterNameWithoutNamespace(const std::string& name) const
+{
+  if(TextTools::startsWith(name, prefix_))
+    return name.substr(prefix_.size());
+  else
+    return name;
+}
+
diff --git a/src/Bpp/Numeric/AbstractParametrizable.h b/src/Bpp/Numeric/AbstractParametrizable.h
new file mode 100644
index 0000000..ba52630
--- /dev/null
+++ b/src/Bpp/Numeric/AbstractParametrizable.h
@@ -0,0 +1,207 @@
+//
+// File: AbstractParametrizable.h
+// Created by: Julien Dutheil
+// Created on: Sun Mar 29 09:10 2009
+// Created from file Parametrizable.h
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _ABSTRACTPARAMETRIZABLE_H_
+#define _ABSTRACTPARAMETRIZABLE_H_
+
+#include "Parametrizable.h"
+
+//From the STL:
+#include <map>
+
+namespace bpp
+{
+
+/**
+ * @brief A partial implementation of the Parametrizable interface.
+ *
+ * Parameters are stored in a protected ParameterList object.
+ *
+ * The abstract fireParameterChanged() method is provided so that the derived class
+ * know when a parameter has changed, and can be updated.
+ * All methods call the corresponding method in ParameterList and then call the
+ * fireParameterChanged() method.
+ */
+class AbstractParametrizable:
+  public virtual Parametrizable
+{
+  private:
+    ParameterList parameters_;
+    std::string prefix_;
+
+  public:
+    AbstractParametrizable(const std::string& prefix) : parameters_(), prefix_(prefix) {}
+
+    virtual ~AbstractParametrizable() {}
+
+  public:
+    bool hasParameter(const std::string& name) const { return parameters_.hasParameter(prefix_ + name); }
+
+    const ParameterList& getParameters() const { return parameters_; }
+    
+    const Parameter& getParameter(const std::string& name) const throw (ParameterNotFoundException)
+    {
+      return parameters_.getParameter(prefix_ + name);
+    }
+  
+    double getParameterValue(const std::string& name) const
+      throw (ParameterNotFoundException)
+    { 
+      return getParameter(name).getValue();
+    }
+
+    void setAllParametersValues(const ParameterList & parameters) 
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      parameters_.setAllParametersValues(parameters);
+      fireParameterChanged(parameters);
+    }
+
+    void setParameterValue(const std::string& name, double value) 
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      parameters_.setParameterValue(prefix_ + name, value);
+      fireParameterChanged(parameters_.subList(prefix_ + name));
+    }
+
+    void setParametersValues(const ParameterList& parameters)
+      throw (ParameterNotFoundException, ConstraintException)
+    { 
+      parameters_.setParametersValues(parameters);
+      fireParameterChanged(parameters);
+    }
+
+    bool matchParametersValues(const ParameterList& parameters)
+      throw (ConstraintException)
+    {
+      bool test = parameters_.matchParametersValues(parameters);
+      if (test) 
+        fireParameterChanged(parameters);
+      return test;
+    }
+
+    size_t getNumberOfParameters() const { return parameters_.size(); }
+     
+    void setNamespace(const std::string& prefix);
+    
+    std::string getNamespace() const { return prefix_; }
+    
+    std::string getParameterNameWithoutNamespace(const std::string& name) const;
+
+    /**
+     * @brief Notify the class when one or several parameters have changed.
+     *
+     * @param parameters A ParameterList object with parameters that changed.
+     */
+    virtual void fireParameterChanged(const ParameterList& parameters) = 0;
+
+  protected:
+    void addParameter_(Parameter* parameter)
+    {
+      if (parameter)
+        parameters_.addParameter(parameter);
+    }
+
+    void addParameters_(const ParameterList& parameters)
+    {
+      parameters_.addParameters(parameters);
+    }
+
+    void deleteParameter_(size_t index) throw (IndexOutOfBoundsException)
+    {
+      if (index >= parameters_.size())
+        throw IndexOutOfBoundsException("AbstractParametrizable::deleteParameter_.", index, 0, parameters_.size() - 1);
+      parameters_.deleteParameter(index);
+    }
+
+    void resetParameters_()
+    {
+      parameters_.reset();
+    }
+
+    /**
+     * @param name The name of the parameter.
+     * @return A reference toward the corresponding parameter.
+     * @throw ParameterNotFoundException If no parameter with that name is found in the list.
+     */
+    Parameter& getParameter_(const std::string& name) throw (ParameterNotFoundException)
+    {
+      return parameters_.getParameter(prefix_ + name);
+    }
+  
+    /**
+     * @param name The name of the parameter, including its namespace.
+     * @return A reference toward the corresponding parameter.
+     * @throw ParameterNotFoundException If no parameter with that name is found in the list.
+     */
+    Parameter& getParameterWithNamespace_(const std::string& name) throw (ParameterNotFoundException)
+    {
+      return getParameter_(name);
+    }
+    /**
+     * @param name The name of the parameter, including its namespace.
+     * @return A reference toward the corresponding parameter.
+     * @throw ParameterNotFoundException If no parameter with that name is found in the list.
+     */
+    const Parameter& getParameterWithNamespace_(const std::string& name) const throw (ParameterNotFoundException)
+    {
+      return getParameter(name);
+    }
+
+    Parameter& getParameter_(size_t index) throw (IndexOutOfBoundsException)
+    {
+      if (index >= parameters_.size())
+        throw IndexOutOfBoundsException("AbstractParametrizable::getParameter_.", index, 0, parameters_.size() - 1);
+      return parameters_[index];
+    }
+    const Parameter& getParameter_(size_t index) const throw (IndexOutOfBoundsException)
+    {
+      if(index >= parameters_.size())
+        throw IndexOutOfBoundsException("AbstractParametrizable::getParameter_.", index, 0, parameters_.size() - 1);
+      return parameters_[index];
+    }
+    
+    ParameterList& getParameters_() { return parameters_; }
+};
+
+} //end of namespace bpp.
+
+#endif //_ABSTRACTPARAMETRIZABLE_H_
+
diff --git a/src/Bpp/Numeric/AdaptiveKernelDensityEstimation.cpp b/src/Bpp/Numeric/AdaptiveKernelDensityEstimation.cpp
new file mode 100644
index 0000000..c3fde70
--- /dev/null
+++ b/src/Bpp/Numeric/AdaptiveKernelDensityEstimation.cpp
@@ -0,0 +1,141 @@
+//
+// File: AdaptiveKernelDensityEstimation.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Nov 05 13:25:07 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "AdaptiveKernelDensityEstimation.h"
+#include "Matrix/MatrixTools.h"
+#include "NumConstants.h"
+
+using namespace bpp;
+using namespace std;
+
+void AdaptiveKernelDensityEstimation::init_()
+{
+  //Compute the covariance matrix of the sample:
+  MatrixTools::covar(x_, covar_);
+
+  //Compute the mean vector
+  sampleMean_(x_, xMean_);
+  
+  //Compute the inverse of the square root of the covariance matrix:
+  MatrixTools::pow<double>(covar_, -0.5, invSqrtCovar_);   
+
+  //Compute the bandwidth:
+  h_ = std::pow(4. / ((2 * static_cast<double>(r_) + 1.) * static_cast<double>(n_)), 1. / (static_cast<double>(r_) + 4.));
+  //Compute as much as we can in advance to simplify the density calculation:
+  c1_ = 1. / (std::sqrt(MatrixTools::det(covar_)) * static_cast<double>(n_) * std::pow(h_, static_cast<int>(r_)));
+  
+  //Now compute the local tuning of the bandwidth.
+  //First estimate the pilot density:
+  vector<double> xi(r_);
+  LinearMatrix<double> diff_xi(r_, 1);
+  LinearMatrix<double>  std_xi(r_, 1);
+  for (unsigned int i = 0; i < n_; i++)
+  {
+    //Get the current xi point to evaluate:
+    for(unsigned int k = 0; k < r_; k++)
+      xi[k] = x_(k, i);
+     
+    //Sum loop, over all xi's:
+    double sum = 0;
+    for (unsigned int j = 0; j < n_; j++)
+    {
+      for (unsigned int k = 0; k < r_; k++)
+        diff_xi(k, 0) = xi[k] - x_(k, j);
+      MatrixTools::mult(invSqrtCovar_, diff_xi, std_xi);
+      MatrixTools::scale(std_xi, 1. / h_);
+      sum += kernel_(std_xi);
+    }
+    pilot_[i] = c1_ * sum;
+  }
+
+  //Compute the tuning parameters:
+  double g = 0;
+  for (unsigned int i = 0; i < n_; i++)
+    g += std::log(pilot_[i]);
+  g = std::exp(g / static_cast<double>(n_));
+  for (unsigned int i = 0; i < n_; i++)
+    lambda_[i] = std::pow(g / pilot_[i], gamma_);
+
+  //Compute as much as we can in advance to simplify the density calculation:
+  for (unsigned int i = 0; i < n_; i++)
+    c2_[i] = std::pow(lambda_[i], - static_cast<double>(r_));
+}
+
+void AdaptiveKernelDensityEstimation::sampleMean_(const Matrix<double>& x, std::vector<double>& mean)
+{
+  size_t nc = x.getNumberOfColumns();
+  size_t nr = x.getNumberOfRows();
+  mean.resize(nr);
+  for (size_t i = 0; i < nr; i++)
+  {
+    mean[i] = 0;
+    for (size_t j = 0; j < nc; j++)
+      mean[i] += x(i, j);
+    mean[i] /= static_cast<double>(nc);
+  }
+}
+
+double AdaptiveKernelDensityEstimation::kernel_(const Matrix<double>& x)
+{
+  //x is supposed to have only one column and r_ rows.
+  //We compute the scalar product of the column with itself:
+  double scalar = 0;
+  for (size_t i = 0; i < r_; i++)
+    scalar += std::pow(x(i, 0), 2.);
+
+  return std::pow(2. * NumConstants::PI(), -static_cast<double>(r_) / 2.) * std::exp(-0.5 * scalar);
+}
+
+double AdaptiveKernelDensityEstimation::kDensity(const std::vector<double>& x)
+{
+  LinearMatrix<double> diff_xi(r_, 1);
+  LinearMatrix<double> std_xi(r_, 1);
+  //Sum loop, over all xi's:
+  double sum = 0;
+  for(unsigned int j = 0; j < n_; j++)
+  {
+    for(unsigned int k = 0; k < r_; k++)
+      diff_xi(k, 0) = x[k] - x_(k, j);
+    MatrixTools::mult(invSqrtCovar_, diff_xi, std_xi);
+    MatrixTools::scale(std_xi, 1. / (h_ * lambda_[j]));
+    sum += kernel_(std_xi) * c2_[j];
+  }
+  return c1_ * sum;  
+}
+
diff --git a/src/Bpp/Numeric/AdaptiveKernelDensityEstimation.h b/src/Bpp/Numeric/AdaptiveKernelDensityEstimation.h
new file mode 100644
index 0000000..4abf2e8
--- /dev/null
+++ b/src/Bpp/Numeric/AdaptiveKernelDensityEstimation.h
@@ -0,0 +1,122 @@
+//
+// File: AdaptiveKernelDensityEstimation.h
+// Created by: Julien Dutheil
+// Created on: Thu Nov 05 13:25:07 2009
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _ADAPTIVEKERNELDENSITYESTIMATION_H_
+#define _ADAPTIVEKERNELDENSITYESTIMATION_H_
+
+#include "Matrix/Matrix.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Density estimation using the adaptive kernel method.
+ *
+ * For now this implementation is quite restricted, more options may be implemented later...
+ *
+ * The source for this method can be found is the appendix of the following paper:
+ * Ivan Kojadinovic, _Computational Statistics and Data Analaysis_ (2004), 46:269-294 
+ *
+ * @author Julien Dutheil
+ */
+class AdaptiveKernelDensityEstimation
+{
+  private:
+    RowMatrix<double> x_; //The original sample
+    size_t n_;
+    size_t r_;
+    RowMatrix<double> covar_; //The covariance matrix, used for the linear transformation
+    RowMatrix<double> invSqrtCovar_; //The inverse of the square root of the covariance matrix, used for the linear transformation
+    std::vector<double> xMean_;
+    double gamma_; //Tune the effect of the pilot density.
+    double c1_;
+    std::vector<double> c2_;
+    double h_; //The bandwidth.
+    std::vector<double> lambda_; //The local tuning coefficient of the bandwidth.
+    std::vector<double> pilot_; //The pilot density
+
+  public:
+    /**
+     * @brief Build a new AdaptiveKernelDensityEstimation object.
+     * @param x A mtrix contianing the sample point, one point per column.
+     * The row of the matrix are the dimension of the sampled vectors, wich can be 1.
+     * @param gamma Controls the influence of the pilot density. A value of 0
+     * maximizes the impact of the pilot density, and hence corresponds to the standard
+     * Kernel Density Estimation method. A value in ]0,1] allows a local adjustement of
+     * the bandwith. The 0.5 value is commonly used.
+     */
+    AdaptiveKernelDensityEstimation(const Matrix<double>& x, double gamma = 0.5):
+      x_(x), n_(x.getNumberOfColumns()), r_(x.getNumberOfRows()),
+      covar_(), invSqrtCovar_(), xMean_(), gamma_(gamma),
+      c1_(0), c2_(x.getNumberOfColumns()), h_(0),
+      lambda_(x.getNumberOfColumns()), pilot_(x.getNumberOfColumns())
+    {
+      init_();
+    }
+    virtual ~AdaptiveKernelDensityEstimation() {}
+
+  public:
+
+    /**
+     * @return The value of the estimated density for point x.
+     * @param x The point where to estimate the density.
+     */
+    double kDensity(const std::vector<double>& x);
+
+  private:
+    void init_();
+
+    void sampleMean_(const Matrix<double>& x, std::vector<double>& mean);
+    
+    /**
+     * @brief The kernel function.
+     *
+     * For now a standard normal density is used, further options may be added later,
+     * including the possibility to use your own function.
+     *
+     * @param x The point for which to compute the density, as a matrix with 1 column and r_ rows.
+     * @return The value of the kernel function at the corresponding point.
+     */
+    double kernel_(const Matrix<double>& x);
+
+};
+
+} //End of namespace bpp.
+
+#endif //_ADAPTIVEKERNELDENSITYESTIMATION_H_
diff --git a/src/Bpp/Numeric/AutoParameter.cpp b/src/Bpp/Numeric/AutoParameter.cpp
new file mode 100644
index 0000000..3289be9
--- /dev/null
+++ b/src/Bpp/Numeric/AutoParameter.cpp
@@ -0,0 +1,120 @@
+//
+// File: AutoParameter.cpp
+// Created by: Julien Dutheil
+// Created on: Tue Nov 11 22:15:16 2003
+//
+
+/*
+  Copyright or © or Copr. CNRS, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "AutoParameter.h"
+#include "NumConstants.h"
+
+#include <iostream>
+
+using namespace std;
+
+// Utils:
+#include "../Text/TextTools.h"
+#include "../App/ApplicationTools.h"
+
+using namespace bpp;
+
+/******************************************************************************/
+
+string AutoParameter::CONSTRAINTS_AUTO   = "auto";
+string AutoParameter::CONSTRAINTS_IGNORE = "ignore";
+string AutoParameter::CONSTRAINTS_KEEP   = "keep";
+
+/** Constructors: *************************************************************/
+
+AutoParameter::AutoParameter(const std::string& name, double value, Constraint* constraint, bool attachConstraint) throw (ConstraintException):
+  Parameter(name, value, constraint, attachConstraint), messageHandler_(ApplicationTools::message) {}
+
+AutoParameter::AutoParameter(const Parameter& p): Parameter(p), messageHandler_(ApplicationTools::message) {}
+
+AutoParameter::AutoParameter(const AutoParameter& p): Parameter(p), messageHandler_(p.messageHandler_) {}
+
+AutoParameter& AutoParameter::operator=(const AutoParameter& p)
+{
+  Parameter::operator=(p);
+  messageHandler_ = p.messageHandler_;
+  return *this;	
+}
+
+/******************************************************************************/
+	
+void AutoParameter::setValue(double value) throw (ConstraintException)
+{
+  try
+    { 
+      // First we try to assign this value:
+      Parameter::setValue(value);
+    }
+  catch (ConstraintException& ce)
+    { 
+      // Aie, there's a pb here...
+      if (messageHandler_)
+        {
+          (*messageHandler_) << "Constraint match at parameter ";
+          (*messageHandler_) << name_;
+          (*messageHandler_) << ", badValue = ";
+          (*messageHandler_) << ce.getBadValue();
+          (*messageHandler_) << " ";
+          (*messageHandler_ << constraint_->getDescription()).endLine();
+        }
+      double limit = constraint_->getAcceptedLimit(value);
+      try
+        { // We try to assign the limit then.
+          Parameter::setValue(limit);
+        }
+      catch(ConstraintException& ce2)
+        { 
+          // Aie, the limit is not reachable, so we perform a smaller step...
+          //Parameter::setValue((getValue() + limit) / 2);
+          try
+            {
+              // Try on the right:
+              Parameter::setValue(limit + NumConstants::TINY());
+            }
+          catch(ConstraintException& ce3)
+            {
+              // Try on the left:
+              Parameter::setValue(limit - NumConstants::TINY());
+            }
+        }
+    }
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/AutoParameter.h b/src/Bpp/Numeric/AutoParameter.h
new file mode 100644
index 0000000..3343232
--- /dev/null
+++ b/src/Bpp/Numeric/AutoParameter.h
@@ -0,0 +1,146 @@
+//
+// File: AutoParameter.h
+// Created by: Julien Dutheil
+// Created on: Tue Nov 11 22:15:16 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _AUTOPARAMETER_H_
+#define _AUTOPARAMETER_H_
+
+#include "Parameter.h"
+
+//From Utils:
+#include "../Io/OutputStream.h"
+
+namespace bpp
+{
+
+/**
+ * @brief The AutoParameter class.
+ *
+ * This class overides the setValue() method of class Parameter so that no
+ * Exception is thrown. This allows to perform optimization under constraint.
+ */ 
+
+class AutoParameter:
+  public Parameter
+{
+	private:
+    OutputStream* messageHandler_;
+	
+	public:
+		
+		/**
+		 * @brief Build a new AutoParameter.
+		 *
+		 * @param name The parameter name.
+		 * @param value The parameter value.
+		 * @param constraint An optional pointer toward a Constraint object.
+     * @param attachConstraint Tell if the constraint must be attached to this parameter, or shared
+     * between different objects. See Parameter.
+		 * @throw ConstraintException If the parameter value does not match the contraint.
+		 */
+		AutoParameter(const std::string& name = "", double value = 0, Constraint* constraint = 0, bool attachConstraint = false) throw (ConstraintException);
+
+		/**
+		 * @brief Copy constructor.
+		 *
+		 * @param param The parameter to copy.
+		 */
+		AutoParameter(const Parameter& param);
+	
+		/**
+		 * @brief Copy constructor.
+		 *
+		 * @param param The parameter to copy.
+		 */
+		AutoParameter(const AutoParameter& param);
+
+		/**
+		 * @brief Assignment operator.
+		 *
+		 * @param param The parameter to copy.
+		 */
+		AutoParameter& operator=(const AutoParameter& param);
+	
+		virtual ~AutoParameter() {}
+	
+		AutoParameter* clone() const { return new AutoParameter(* this); }
+	
+  public:	
+	
+		/**
+		 * @brief Set the value of this parameter.
+		 *
+		 * This method is redefined so that no constraintException is thrown!
+		 * When a Constraint is match, we automatically apply a correct value instead.
+		 * This correct value is the nearest limit reached by the value, or a value next to
+		 * the limit if the limit is not reachable.
+		 *
+		 * This allow to perform optimization under constraint whith algorithms that are not
+		 * initially built for this.
+		 *
+		 * @param value the new parameter value.
+		 * @throw ConstraintException Never thrown!
+		 */
+		virtual void setValue(double value) throw (ConstraintException);
+	
+	public: //Specific method:
+		
+		/**
+		 * @brief Set the message handler for this AutoParameter.
+		 *
+		 * The message handler keeps all messages that the parameter may send.
+		 * The default handler is set to standard output, but you can pass any
+		 * ostream object (cerr, ofstream, etc.).
+		 *
+		 * A NULL pointer disable message output.
+		 * 
+		 * @param mh The message handler to use.
+		 */
+		virtual void setMessageHandler(OutputStream* mh) { messageHandler_ = mh; }
+		
+	public:
+	
+		static std::string CONSTRAINTS_AUTO;
+		static std::string CONSTRAINTS_IGNORE;
+		static std::string CONSTRAINTS_KEEP;
+};
+
+} //end of namespace bpp.
+
+#endif	//_AUTOPARAMETER_H_
+
diff --git a/src/Bpp/Numeric/Constraints.h b/src/Bpp/Numeric/Constraints.h
new file mode 100644
index 0000000..187ec4c
--- /dev/null
+++ b/src/Bpp/Numeric/Constraints.h
@@ -0,0 +1,384 @@
+//
+// File: Constraints.h
+// Created by: Julien Dutheil
+// Created on: Thu Dec 25 19:35:17 2003
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#ifndef _CONSTRAINTS_H_
+#define _CONSTRAINTS_H_
+
+// From the STL:
+#include <string>
+#include <iostream>
+
+// From Utils:
+#include "../Clonable.h"
+#include "../Text/TextTools.h"
+
+#include "NumConstants.h"
+
+namespace bpp
+{
+/**
+ * @brief The constraint interface.
+ *
+ * It provides a method that tells if a given value is correct.
+ */
+class Constraint : public Clonable
+{
+public:
+  Constraint() {}
+  virtual ~Constraint() {}
+
+  Constraint* clone() const = 0;
+
+public:
+  /**
+   * @brief Tell if a given value is correct.
+   *
+   * @param value The value to test.
+   * @return True is the value is correct.
+   */
+  virtual bool isCorrect(double value) const = 0;
+
+  /**
+   * @brief Tell if all the values in a given interval are correct.
+   *
+   * @param min, max  The bounds of the interval.
+   * @return True is the value is correct.
+   */
+  virtual bool includes(double min, double max) const = 0;
+
+  /**
+   * @brief Give the nearest limit for a bad value.
+   *
+   * @param value The bad value.
+   * @return The nearer limit.
+   */
+  virtual double getLimit(double value) const = 0;
+
+  /**
+   * @brief Give the nearest accepted limit for a bad value.
+   *
+   * The difference with getLimit() is when the Constraint is open at
+   * the limit, in which case the retruned value is the limit +- 1e-12.
+   *
+   * @param value The bad value.
+   * @return The nearer limit.
+   */
+  virtual double getAcceptedLimit(double value) const = 0;
+
+  /**
+   * @brief Give a short description on the type of constraint.
+   *
+   * @return A string which describes the constraint.
+   */
+  virtual std::string getDescription() const = 0;
+
+  /**
+   * @brief Intersect this Constraint with another one
+   *
+   * @param c the intersected Constraint
+   * @return the intersection
+   */
+  virtual Constraint* operator&(const Constraint& c) const = 0;
+};
+
+/**
+ * @brief An interval, either bounded or not, which can also have infinite bounds.
+ *
+ * The upper and lower bound can be included or not (strict bound), finite or infinite (in that case, equal to a very large value).
+ * Despite the mathematical non-sense, and infinite bound can be either excluded or included.
+ */
+
+class IntervalConstraint : public Constraint
+{
+protected:
+  /**
+   * @brief The boundaries of the interval
+   *
+   **/
+  double lowerBound_, upperBound_;
+
+  /**
+   * @brief Boolean flags are true if the boundaries are included
+   *
+   **/
+  bool inclLowerBound_, inclUpperBound_;
+  /**
+   *
+   * @brief the accepted precision on the boundary (default: 1e-12)
+   **/
+
+  double precision_;
+  
+
+public:
+  IntervalConstraint() :  lowerBound_(NumConstants::MINF()),
+                upperBound_(NumConstants::PINF()),
+                inclLowerBound_(true),
+                inclUpperBound_(true),
+                precision_(NumConstants::TINY()) {}
+
+  IntervalConstraint(double lowerBound, double upperBound, bool inclLower, bool inclUpper, double precision = NumConstants::TINY()) :
+    lowerBound_(lowerBound),
+    upperBound_(upperBound),
+    inclLowerBound_(inclLower),
+    inclUpperBound_(inclUpper),
+    precision_(precision) {}
+ 
+  /**
+   * @brief Create an interval with an infinite lower/upper bound.
+   *
+   * The infinite bound will not be included, following mathematical conventions.
+   *
+   * @param isPositive Tell if the infinite bound is positive or negative.
+   * @param bound The finite bound.
+   * @param incl Tell if the finite bound is included or not.
+   * @param precision Parameter precision.
+   */
+  IntervalConstraint(bool isPositive, double bound, bool incl, double precision = NumConstants::TINY()) :
+    lowerBound_(isPositive ? bound : NumConstants::MINF()),
+    upperBound_(isPositive ? NumConstants::PINF() : bound),
+    inclLowerBound_(isPositive ? incl : false),
+    inclUpperBound_(isPositive ? false : incl),
+    precision_(precision) {}
+ 
+  virtual ~IntervalConstraint() {}
+
+  IntervalConstraint* clone() const { return new IntervalConstraint(*this); }
+
+public:
+  void setLowerBound(double lowerBound, bool strict) { lowerBound_ = lowerBound; inclLowerBound_ = !strict; }
+  void setUpperBound(double upperBound, bool strict) { upperBound_ = upperBound; inclUpperBound_ = !strict; }
+
+  double getLowerBound() const { return lowerBound_; }
+  double getUpperBound() const { return upperBound_; }
+
+  bool strictLowerBound() const { return !inclLowerBound_; }
+  bool strictUpperBound() const { return !inclUpperBound_; }
+
+  bool finiteLowerBound() const { return lowerBound_ > NumConstants::MINF(); }
+  bool finiteUpperBound() const { return upperBound_ < NumConstants::PINF(); }
+
+  bool includes(double min, double max) const
+  {
+    return (inclLowerBound_ ? min >= getLowerBound() : min > getLowerBound()) &&
+           (inclUpperBound_ ? max <= getUpperBound() : max < getUpperBound());
+  }
+
+  virtual bool isCorrect(double value) const
+  {
+    return (inclLowerBound_ ? value >= getLowerBound() : value > getLowerBound()) &&
+           (inclUpperBound_ ? value <= getUpperBound() : value < getUpperBound());
+  }
+
+  bool operator<(double value) const
+  {
+    return inclUpperBound_ ? upperBound_ < value : upperBound_ <= value;
+  }
+
+  bool operator>(double value) const
+  {
+    return inclLowerBound_ ? lowerBound_ > value : lowerBound_ >= value;
+  }
+
+  bool operator<=(double value) const
+  {
+    return upperBound_ <= value;
+  }
+
+  bool operator>=(double value) const
+  {
+    return lowerBound_ >= value;
+  }
+
+  double getLimit(double value) const
+  {
+    return isCorrect(value) ? value :
+           (*this >= value ? lowerBound_ : upperBound_);
+  }
+
+  double getAcceptedLimit(double value) const
+  {
+    return isCorrect(value) ? value :
+           (*this >= value ?
+            strictLowerBound() ? lowerBound_ + precision_ : lowerBound_ :
+            strictUpperBound() ? upperBound_ - precision_ : upperBound_);
+  }
+
+  double getPrecision() const
+  {
+    return precision_;
+  }
+  
+  std::string getDescription() const
+  {
+    return (inclLowerBound_ ? "[ " : "]")
+           + (finiteLowerBound() ? TextTools::toString(lowerBound_) : "-inf")
+           + ", "
+           + (finiteUpperBound() ? TextTools::toString(upperBound_) : "+inf")
+           + (inclUpperBound_ ? "] " : "[");
+  }
+
+  /**
+   * @brief Intersect this IntervalConstraint with another one
+   *
+   * @param c the intersected IntervalConstraint
+   * @return the intersection, or NULL if c is not an IntervalConstraint. The
+   * resulting precision is the maximum of both precisions.
+   */
+  Constraint* operator&(const Constraint& c) const
+  {
+    double lowerBound, upperBound;
+    bool inclLowerBound, inclUpperBound;
+
+    const IntervalConstraint* pi = dynamic_cast<const IntervalConstraint*>(&c);
+
+    if (pi)
+    {
+      if (lowerBound_ <= pi->lowerBound_)
+      {
+        lowerBound = pi->lowerBound_;
+        inclLowerBound = pi->inclLowerBound_;
+      }
+      else
+      {
+        lowerBound = lowerBound_;
+        inclLowerBound = inclLowerBound_;
+      }
+
+      if (upperBound_ >= pi->upperBound_)
+      {
+        upperBound = pi->upperBound_;
+        inclUpperBound = pi->inclUpperBound_;
+      }
+      else
+      {
+        upperBound = upperBound_;
+        inclUpperBound = inclUpperBound_;
+      }
+      return new IntervalConstraint(lowerBound, upperBound, inclLowerBound, inclUpperBound, (precision_>pi->getPrecision())?precision_:pi->getPrecision());
+    }
+    else
+      return 0;
+  }
+
+  /**
+   * @brief Intersect this IntervalConstraint with another one
+   *
+   * @param c the intersected IntervalConstraint
+   * @return this IntervalConstraint modified, or not modified if c is not an
+   * IntervalConstraint. The precision is set to the maximum of bith precisions.
+   */
+  
+  IntervalConstraint& operator&=(const Constraint& c)
+  {
+    const IntervalConstraint* pi = dynamic_cast<const IntervalConstraint*>(&c);
+
+    if (pi)
+    {
+      if (lowerBound_ <= pi->lowerBound_)
+      {
+        lowerBound_ = pi->lowerBound_;
+        inclLowerBound_ = pi->inclLowerBound_;
+      }
+      else
+      {
+        lowerBound_ = lowerBound_;
+        inclLowerBound_ = inclLowerBound_;
+      }
+
+      if (upperBound_ >= pi->upperBound_)
+      {
+        upperBound_ = pi->upperBound_;
+        inclUpperBound_ = pi->inclUpperBound_;
+      }
+      else
+      {
+        upperBound_ = upperBound_;
+        inclUpperBound_ = inclUpperBound_;
+      }
+      if (pi->getPrecision()>precision_)
+        precision_=pi->getPrecision();
+    }
+
+    return *this;
+  }
+
+  /**
+   * @brief Tells if this interval equals another one
+   *
+   * @param i the compared IntervalConstraint
+   */
+  bool operator==(const IntervalConstraint& i) const
+  {
+    return lowerBound_ == i.lowerBound_
+      && inclLowerBound_ == i.inclLowerBound_
+      && upperBound_ == i.upperBound_
+      && inclUpperBound_ == i.inclUpperBound_;
+  }
+
+  /**
+   * @brief Tells if this interval is different from another one
+   *
+   * @param i the compared IntervalConstraint
+   */
+  bool operator!=(const IntervalConstraint& i) const
+  {
+    return lowerBound_ != i.lowerBound_
+      || inclLowerBound_ != i.inclLowerBound_
+      || upperBound_ != i.upperBound_
+      || inclUpperBound_ != i.inclUpperBound_;
+  }
+
+  /**
+   * @brief Tells if this interval is included or equal in another one
+   *
+   * @param i the compared IntervalConstraint
+   */
+  bool operator<=(const IntervalConstraint& i) const
+  {
+    return lowerBound_ >= i.lowerBound_
+           && upperBound_ <= i.upperBound_;
+  }
+};
+
+
+} // end of namespace bpp.
+
+#endif  // _CONSTRAINTS_H_
+
diff --git a/src/Bpp/Numeric/DataTable.cpp b/src/Bpp/Numeric/DataTable.cpp
new file mode 100644
index 0000000..7c0d8a8
--- /dev/null
+++ b/src/Bpp/Numeric/DataTable.cpp
@@ -0,0 +1,594 @@
+//
+// File: DataTable.cpp
+// Created by: Julien Dutheil
+// Created on: Aug 2005
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "DataTable.h"
+#include "VectorTools.h"
+#include "../Io/FileTools.h"
+#include "../Text/TextTools.h"
+#include "../Text/StringTokenizer.h"
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+
+DataTable::DataTable(size_t nRow, size_t nCol) :
+  nRow_(nRow), nCol_(nCol), data_(nCol), rowNames_(0), colNames_(0)
+{
+  for(size_t i = 0; i < nCol; i++)
+    data_[i].resize(nRow);
+}
+  
+DataTable::DataTable(size_t nCol) :
+  nRow_(0), nCol_(nCol), data_(nCol), rowNames_(0), colNames_(0)
+{
+}
+  
+DataTable::DataTable(const std::vector<std::string>& colNames) throw (DuplicatedTableColumnNameException) :
+  nRow_(0), nCol_(colNames.size()), data_(colNames.size()), rowNames_(0), colNames_(0)
+
+{
+  setColumnNames(colNames); //May throw an exception.  
+}
+  
+DataTable::DataTable(const DataTable& table) :
+  nRow_(table.nRow_), nCol_(table.nCol_), data_(table.data_), rowNames_(0), colNames_(0)
+{
+  if(table.rowNames_) rowNames_ = new vector<string>(*table.rowNames_);
+  if(table.colNames_) colNames_ = new vector<string>(*table.colNames_);
+}
+
+DataTable& DataTable::operator=(const DataTable & table)
+{
+  nRow_ = table.nRow_;
+  nCol_ = table.nCol_;
+  data_ = table.data_;
+  if(rowNames_) delete rowNames_;
+  if(colNames_) delete colNames_;
+  rowNames_ = 0;
+  colNames_ = 0;
+  if(table.rowNames_) rowNames_ = new vector<string>(*table.rowNames_);
+  if(table.colNames_) colNames_ = new vector<string>(*table.colNames_);
+  return *this;
+}
+
+/******************************************************************************/
+
+DataTable::~DataTable()
+{
+  if(rowNames_ != NULL) delete rowNames_;
+  if(colNames_ != NULL) delete colNames_;
+}
+
+/******************************************************************************/
+/*                             Cell access                                    */
+/******************************************************************************/
+
+string & DataTable::operator()(size_t rowIndex, size_t colIndex) throw (IndexOutOfBoundsException)
+{
+  if(colIndex >= nCol_) throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", colIndex, 0, nCol_ - 1);
+  if(rowIndex >= data_[colIndex].size()) throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", rowIndex, 0, data_[colIndex].size() - 1);
+  return data_[colIndex][rowIndex];
+}
+
+const string & DataTable::operator()(size_t rowIndex, size_t colIndex) const throw (IndexOutOfBoundsException)
+{
+  if(colIndex >= nCol_) throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", colIndex, 0, nCol_ - 1);
+  if(rowIndex >= data_[colIndex].size()) throw IndexOutOfBoundsException("DataTable::operator(size_t, size_t).", rowIndex, 0, data_[colIndex].size() - 1);
+  return data_[colIndex][rowIndex];
+}
+
+/******************************************************************************/
+
+string & DataTable::operator()(const string & rowName, const string & colName)
+throw (NoTableRowNamesException, NoTableColumnNamesException, TableNameNotFoundException)
+{
+  if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::operator(const string &, const string &).");
+  if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::operator(const string &, const string &).");
+  try
+  {
+    size_t rowIndex = VectorTools::which(*rowNames_, rowName);
+    size_t colIndex = VectorTools::which(*colNames_, colName);
+    return (*this)(rowIndex, colIndex);
+  }
+  catch(ElementNotFoundException<string> & ex)
+  {
+    throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement());
+  }
+}
+
+const string & DataTable::operator()(const string & rowName, const string & colName) const
+throw (NoTableRowNamesException, NoTableColumnNamesException, TableNameNotFoundException)
+{
+  if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::operator(const string &, const string &).");
+  if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::operator(const string &, const string &).");
+  try
+  {
+    size_t rowIndex = VectorTools::which(*rowNames_, rowName);
+    size_t colIndex = VectorTools::which(*colNames_, colName);
+    return (*this)(rowIndex, colIndex);
+  }
+  catch(ElementNotFoundException<string> & ex) 
+  {
+    throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement());
+  }
+}
+    
+/******************************************************************************/
+
+string & DataTable::operator()(const string & rowName, size_t colIndex)
+throw (NoTableRowNamesException, TableNameNotFoundException, IndexOutOfBoundsException)
+{
+  if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::operator(const string &, size_t).");
+  if(colIndex >= nCol_) throw IndexOutOfBoundsException("DataTable::operator(const string &, size_t).", colIndex, 0, nCol_ - 1);
+  try
+  {
+    size_t rowIndex = VectorTools::which(*rowNames_, rowName);
+    return (*this)(rowIndex, colIndex);
+  }
+  catch(ElementNotFoundException<string> & ex)
+  {
+    throw TableNameNotFoundException("DataTable::operator(const string &, size_t).", *ex.getElement());
+  }
+}
+
+const string & DataTable::operator()(const string & rowName, size_t colIndex) const
+throw (NoTableRowNamesException, TableNameNotFoundException, IndexOutOfBoundsException)
+{
+  if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::operator(const string &, size_t).");
+  if(colIndex >= nCol_) throw IndexOutOfBoundsException("DataTable::operator(const string &, size_t).", colIndex, 0, nCol_ - 1);
+  try
+  {
+    size_t rowIndex = VectorTools::which(*rowNames_, rowName);
+    return (*this)(rowIndex, colIndex);
+  }
+  catch(ElementNotFoundException<string> & ex)
+  {
+    throw TableNameNotFoundException("DataTable::operator(const string &, size_t).", *ex.getElement());
+  }
+}
+
+/******************************************************************************/
+
+string & DataTable::operator()(size_t rowIndex, const string & colName)
+throw (IndexOutOfBoundsException, NoTableColumnNamesException, TableNameNotFoundException)
+{
+  if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::operator(size_t, const string &).");
+  try
+  {
+    size_t colIndex = VectorTools::which(*colNames_, colName);
+    if(rowIndex >= data_[colIndex].size()) throw IndexOutOfBoundsException("DataTable::operator(size_t, const string &).", rowIndex, 0, data_[colIndex].size() - 1);
+    return (*this)(rowIndex, colIndex);
+  }
+  catch(ElementNotFoundException<string> & ex)
+  {
+    throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement());
+  }
+}
+
+const string & DataTable::operator()(size_t rowIndex, const string & colName) const
+throw (IndexOutOfBoundsException, NoTableColumnNamesException, TableNameNotFoundException)
+{
+  if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::operator(size_t, const string &).");
+  try
+  {
+    size_t colIndex = VectorTools::which(*colNames_, colName);
+    if(rowIndex >= data_[colIndex].size()) throw IndexOutOfBoundsException("DataTable::operator(size_t, const string &).", rowIndex, 0, data_[colIndex].size() - 1);
+    return (*this)(rowIndex, colIndex);
+  }
+  catch(ElementNotFoundException<string> & ex)
+  {
+    throw TableNameNotFoundException("DataTable::operator(const string &, const string &).", *ex.getElement());
+  }
+}
+
+/******************************************************************************/
+/*                             Work with names                                */
+/******************************************************************************/
+
+void DataTable::setRowNames(const vector<string> & rowNames)
+throw (DimensionException, DuplicatedTableRowNameException)
+{
+  if (!VectorTools::isUnique(rowNames))
+  {
+    throw DuplicatedTableRowNameException("DataTable::setRowNames(...). Row names must be unique.");
+  }
+  if (rowNames.size() != nRow_) throw DimensionException("DataTable::setRowNames.", rowNames.size(), nRow_);
+  else
+  {
+    if(rowNames_ != NULL) delete rowNames_;
+    rowNames_ = new vector<string>(rowNames.begin(), rowNames.end());
+  }
+}
+
+vector<string> DataTable::getRowNames() const throw (NoTableRowNamesException)
+{
+  if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::getRowNames().");
+  return * rowNames_;
+}
+
+string DataTable::getRowName(size_t index) const throw (NoTableRowNamesException, IndexOutOfBoundsException)
+{
+  if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::getRowName(size_t).");
+  if(index >= nRow_)    throw IndexOutOfBoundsException("DataTable::getRowName(size_t).", index, 0, nRow_ - 1);
+  return (* rowNames_)[index];
+}
+
+/******************************************************************************/
+
+void DataTable::setColumnNames(const vector<string> & colNames)
+throw (DimensionException, DuplicatedTableColumnNameException)
+{
+  if(!VectorTools::isUnique(colNames)) throw DuplicatedTableColumnNameException("DataTable::setColumnNames(...). Column names must be unique.");
+  if(colNames.size() != nCol_) throw DimensionException("DataTable::setColumnNames.", colNames.size(), nCol_);
+  else
+  {
+    if(colNames_ != NULL) delete colNames_;
+    colNames_ = new vector<string>(colNames.begin(), colNames.end());
+  }
+}
+
+vector<string> DataTable::getColumnNames() const throw (NoTableColumnNamesException)
+{
+  if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::getColumnNames().");
+  return *colNames_;
+}
+
+string DataTable::getColumnName(size_t index) const throw (NoTableColumnNamesException, IndexOutOfBoundsException)
+{
+  if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::getColumnName(size_t).");
+  if(index >= nCol_)    throw IndexOutOfBoundsException("DataTable::getColumnName(size_t).", index, 0, nCol_ - 1);
+  return (* colNames_)[index];
+}
+
+/******************************************************************************/
+/*                               Work on columns                              */
+/******************************************************************************/
+
+vector<string> & DataTable::getColumn(size_t index)
+  throw (IndexOutOfBoundsException)
+{
+  if(index >= nCol_) throw IndexOutOfBoundsException("DataTable::getColumn(size_t).", index, 0, nCol_ - 1);
+  return data_[index];
+}
+
+const vector<string> & DataTable::getColumn(size_t index) const
+  throw (IndexOutOfBoundsException)
+{
+  if(index >= nCol_) throw IndexOutOfBoundsException("DataTable::getColumn(size_t).", index, 0, nCol_ - 1);
+  return data_[index];
+}  
+
+vector<string> & DataTable::getColumn(const string & colName)
+  throw (NoTableColumnNamesException, TableColumnNameNotFoundException)
+{
+  if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::getColumn(const string &).");
+  try
+  {
+    size_t colIndex = VectorTools::which(*colNames_, colName);
+    return data_[colIndex];
+  }
+  catch(ElementNotFoundException<string> & ex)
+  {
+    throw TableColumnNameNotFoundException("DataTable::getColumn(const string &).", colName);
+  }
+}
+
+const vector<string> & DataTable::getColumn(const string & colName) const
+  throw (NoTableColumnNamesException, TableColumnNameNotFoundException)
+{
+  if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::getColumn(const string &).");
+  try
+  {
+    size_t colIndex = VectorTools::which(*colNames_, colName);
+    return data_[colIndex];
+  }
+  catch(ElementNotFoundException<string> & ex)
+  {
+    throw TableColumnNameNotFoundException("DataTable::getColumn(const string &).", colName);
+  }
+}
+
+bool DataTable::hasColumn(const string & colName) const
+{ 
+  if(colNames_ == NULL) return false;
+  for(size_t i = 0; i < colNames_->size(); i++)
+    if((* colNames_)[i] == colName) return true;
+  return false;
+}
+
+void DataTable::deleteColumn(size_t index)
+  throw (IndexOutOfBoundsException)
+{
+  if(index >= nCol_) throw IndexOutOfBoundsException("DataTable::deleteColumn(size_t).", index, 0, nCol_ - 1);
+  data_.erase(data_.begin() + index);
+  if(colNames_ != NULL) colNames_->erase(colNames_->begin()+index);
+  nCol_--;
+}
+
+void DataTable::deleteColumn(const string & colName)
+  throw (NoTableColumnNamesException, TableColumnNameNotFoundException)
+{
+  if(colNames_ == NULL) throw NoTableColumnNamesException("DataTable::deleteColumn(const string &).");
+  try
+  {
+    size_t colIndex = VectorTools::which(*colNames_, colName);
+    data_.erase(data_.begin() + colIndex);
+    colNames_->erase(colNames_->begin() + colIndex);
+    nCol_--;
+  }
+  catch(ElementNotFoundException<string> & ex)
+  {
+    throw TableColumnNameNotFoundException("DataTable::deleteColumn(const string &).", colName);
+  }
+}
+
+void DataTable::addColumn(const vector<string>& newColumn)
+  throw (DimensionException, TableColumnNamesException)
+{
+  if (colNames_)
+    throw TableColumnNamesException("DataTable::addColumn. Table has column names.");
+  if (newColumn.size() != nRow_)
+    throw DimensionException("DataTable::addColumn.", newColumn.size(), nRow_);
+  data_.push_back(newColumn);
+  nCol_++;
+}
+
+void DataTable::addColumn(const string& colName, const vector<string>& newColumn)
+  throw (DimensionException, NoTableColumnNamesException, DuplicatedTableColumnNameException)
+{
+  if(!colNames_)
+  {
+    if (nCol_ == 0) colNames_ = new vector<string>();
+    else throw NoTableColumnNamesException("DataTable::addColumn. Table has column names.");
+  }
+  if (newColumn.size() != nRow_)
+    throw DimensionException("DataTable::addColumn.", newColumn.size(), nRow_);
+  if (nCol_ > 0 && find(colNames_->begin(), colNames_->end(), colName) != colNames_->end())
+    throw DuplicatedTableColumnNameException("DataTable::addColumn(const string &, const vector<string> &). Column names must be unique.");
+  colNames_->push_back(colName);
+  data_.push_back(newColumn);
+  nCol_++;
+}
+
+/******************************************************************************/
+/*                               Work on rows                                 */
+/******************************************************************************/
+
+vector<string> DataTable::getRow(size_t index) const
+  throw (IndexOutOfBoundsException)
+{
+  if(index >= nRow_) throw IndexOutOfBoundsException("DataTable::getRow(size_t).", index, 0, nRow_ - 1);
+  vector<string> row;
+  for (size_t i = 0 ; i < nCol_ ; i++)
+    row.push_back(data_[i][index]);
+  return row;
+}
+
+vector<string> DataTable::getRow(const string& rowName) const
+  throw (NoTableRowNamesException, TableRowNameNotFoundException)
+{
+  if (!rowNames_) throw NoTableRowNamesException("DataTable::getRow(const string &).");
+  try
+  {
+    size_t rowIndex = VectorTools::which(*rowNames_, rowName);
+    vector<string> row;
+    for (size_t i = 0 ; i < nCol_ ; i++)
+      row.push_back(data_[i][rowIndex]);
+    return row;
+  }
+  catch(ElementNotFoundException<string> & ex)
+  {
+    throw TableRowNameNotFoundException("DataTable::getRow(const string &).", rowName);
+  }
+}
+
+bool DataTable::hasRow(const string & rowName) const
+{ 
+  if(rowNames_ == NULL) return false;
+  for(size_t i = 0; i < rowNames_->size(); i++)
+  {
+    if((* rowNames_)[i] == rowName) return true;
+  }
+  return false;
+}
+
+void DataTable::deleteRow(size_t index)
+  throw (IndexOutOfBoundsException)
+{
+  for(size_t j = 0; j < nCol_; j++)
+  {
+    vector<string> * column = & data_[j];
+    if(index >= column->size()) throw IndexOutOfBoundsException("DataTable::deleteRow(size_t).", index, 0, column->size() - 1);
+    column->erase(column->begin()+index);
+  }
+  if(rowNames_ != NULL) rowNames_->erase(rowNames_->begin()+index);
+  nRow_--;
+}
+
+void DataTable::deleteRow(const string& rowName)
+  throw (NoTableRowNamesException, TableRowNameNotFoundException)
+{
+  if(rowNames_ == NULL) throw NoTableRowNamesException("DataTable::deleteRow(const string &).");
+  try
+  {
+    size_t rowIndex = VectorTools::which(*rowNames_, rowName);
+    for(size_t j = 0; j < nCol_; j++)
+    {
+      vector<string> * column = & data_[j];
+      column->erase(column->begin()+rowIndex);
+    }
+    rowNames_->erase(rowNames_->begin()+rowIndex);
+    nRow_--;
+  }
+  catch(ElementNotFoundException<string> & ex)
+  {
+    throw TableRowNameNotFoundException("DataTable::deleteRow(const string &).", rowName);
+  }
+}
+
+void DataTable::addRow(const vector<string>& newRow)
+  throw (DimensionException, TableRowNamesException)
+{
+  if (rowNames_) throw TableRowNamesException("DataTable::addRow. Table has row names.");
+  if (newRow.size() != nCol_) throw DimensionException("DataTable::addRow.", newRow.size(), nCol_);
+  for (size_t j = 0; j < nCol_; j++)
+    data_[j].push_back(newRow[j]);
+  nRow_++;
+}
+
+void DataTable::addRow(const string& rowName, const vector<string>& newRow)
+  throw (DimensionException, NoTableRowNamesException, DuplicatedTableRowNameException)
+{
+  if (!rowNames_)
+  {
+    if (nRow_ == 0) rowNames_ = new vector<string>();
+    else throw NoTableRowNamesException("DataTable::addRow. Table has row names.");
+  }
+  if (newRow.size() != nCol_) throw DimensionException("DataTable::addRow.", newRow.size(), nCol_);
+  if (nRow_ > 0 && find(rowNames_->begin(), rowNames_->end(), rowName) != rowNames_->end())
+    throw DuplicatedTableRowNameException("DataTable::addRow(const string &, const vector<string> &). Row names must be unique.");
+  rowNames_->push_back(rowName);
+  for (size_t j = 0; j < nCol_; j++)
+    data_[j].push_back(newRow[j]);
+  nRow_++;
+}
+
+/******************************************************************************/
+/*                               Read from a CSV file                         */
+/******************************************************************************/
+
+DataTable* DataTable::read(istream& in, const string& sep, bool header, int rowNames)
+  throw (DimensionException, IndexOutOfBoundsException, DuplicatedTableRowNameException)
+{
+  string firstLine  = FileTools::getNextLine(in);
+  StringTokenizer st1(firstLine, sep, false, true);
+  vector<string> row1(st1.getTokens().begin(), st1.getTokens().end());
+  string secondLine = FileTools::getNextLine(in);
+  StringTokenizer st2(secondLine, sep, false, true);
+  vector<string> row2(st2.getTokens().begin(), st2.getTokens().end());
+  size_t nCol = row1.size();
+  bool hasRowNames;
+  DataTable * dt;
+  if(row1.size() == row2.size())
+  {
+    dt = new DataTable(nCol);
+    if(header)
+    { //Use first line as header.
+      dt->setColumnNames(row1);
+    }
+    else
+    {
+      dt->addRow(row1);
+    }
+    dt->addRow(row2);
+    hasRowNames = false;
+  }
+  else if(row1.size() == row2.size() - 1)
+  {
+    dt = new DataTable(nCol);
+    dt->setColumnNames(row1);
+    string rowName = *row2.begin();
+    dt->addRow(rowName, vector<string>(row2.begin()+1, row2.end()));
+    hasRowNames = true;
+  }
+  else throw DimensionException("DataTable::read(...). Row 2 has not the correct number of columns.", row2.size(), nCol);
+
+  // Now read each line:
+  string line = FileTools::getNextLine(in);
+  while(!TextTools::isEmpty(line))
+  {
+    StringTokenizer st(line, sep, false, true);
+    if(hasRowNames)
+    {
+      string rowName = *st.getTokens().begin();
+      vector<string> row(st.getTokens().begin()+1, st.getTokens().end());
+      dt->addRow(rowName, row);
+    }
+    else
+    {
+      vector<string> row(st.getTokens().begin(), st.getTokens().end());
+      dt->addRow(row);
+    }
+    line = FileTools::getNextLine(in);
+  }
+
+  // Row names:
+  if(rowNames > -1)
+  {
+    if((size_t)rowNames >= nCol) throw IndexOutOfBoundsException("DataTable::read(...). Invalid column specified for row names.", rowNames, 0, nCol-1);
+    vector<string> col = dt->getColumn((size_t)rowNames);
+    dt->setRowNames(col);
+    dt->deleteColumn(rowNames);
+  }
+  
+  return(dt);
+}
+
+/******************************************************************************/
+
+void DataTable::write(const DataTable& data, ostream& out, const string& sep, bool alignHeaders)
+{
+  size_t n = data.getNumberOfColumns();
+  if(n == 0) return;
+  if(data.hasColumnNames())
+  { //Write header
+    vector<string> colNames = data.getColumnNames();
+    if (alignHeaders && data.hasRowNames()) out << sep;
+    out << colNames[0];
+    for(size_t i = 1; i < n; i++) {
+      out << sep << colNames[i];
+    }
+    out << endl;
+  }
+  //Now write each row:
+  for(size_t i = 0; i < data.getNumberOfRows(); i++)
+  {
+    if(data.hasRowNames()) out << data.getRowName(i) << sep;
+    out << data(i, 0);
+    for(size_t j = 1; j < n; j++)
+    {
+      out << sep << data(i, j);
+    }
+    out << endl;
+  }
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/DataTable.h b/src/Bpp/Numeric/DataTable.h
new file mode 100644
index 0000000..b720ccf
--- /dev/null
+++ b/src/Bpp/Numeric/DataTable.h
@@ -0,0 +1,443 @@
+//
+// File: DataTable.h
+// Created by: Julien Dutheil
+// Created on: Aug 2005
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _DataTable_H_
+#define _DataTable_H_
+
+#include "VectorTools.h"
+#include "DataTableExceptions.h"
+#include "../Exceptions.h"
+#include "../Text/TextTools.h"
+#include "../Clonable.h"
+
+// From the STL:
+#include <string>
+#include<vector>
+#include <map>
+
+namespace bpp
+{
+
+/**
+ * @brief This class corresponds to a 'dataset', <i>i.e.</i> a table with data by rows
+ * and variable by columns.
+ *
+ * Data are stored as string objects, by column.
+ * A DataTable object is hence similar to a ColMatrix<string>.object.
+ * (NB: actually, ColMatrix does not exist yet...)
+ */
+class DataTable:
+  public Clonable
+{
+  
+  protected:
+    size_t nRow_, nCol_;
+    std::vector< std::vector<std::string> > data_;
+    std::vector<std::string>* rowNames_;
+    std::vector<std::string>* colNames_;
+
+  public:
+    
+    /**
+     * @brief Build a new void DataTable object with nRow rows and nCol columns.
+     *
+     * @param nRow The number of rows of the DataTable.
+     * @param nCol The number of columns of the DataTable.
+     */
+    DataTable(size_t nRow, size_t nCol);
+    
+    /**
+     * @brief Build a new void DataTable object with nCol columns.
+     *
+     * @param nCol The number of columns of the DataTable.
+     */
+    DataTable(size_t nCol);
+
+    /**
+     * @brief Build a new void DataTable object with named columns.
+     *
+     * @param colNames The names of the columns of the DataTable.
+     * @throw DuplicatedTableColumnNameException If colnames contains identical names.
+     */
+    DataTable(const std::vector<std::string>& colNames) throw (DuplicatedTableColumnNameException);
+
+    DataTable(const DataTable& table);
+
+    DataTable& operator=(const DataTable& table);
+
+    DataTable* clone() const { return new DataTable(*this); }
+
+    virtual ~DataTable();
+
+  public:
+
+    /**
+     * @return The element at a given position.
+     * @param rowIndex Row number.
+     * @param colIndex Column number.
+     * @throw IndexOutOfBoundsException If one of the index is greater or equal to the corresponding number of columns/rows. 
+     */
+    std::string& operator()(size_t rowIndex, size_t colIndex) throw (IndexOutOfBoundsException);
+    
+    /**
+     * @return The element at a given position.
+     * @param rowIndex Row number.
+     * @param colIndex Column number.
+     * @throw IndexOutOfBoundsException If one of the index is greater or equal to the corresponding number of columns/rows. 
+     */
+    const std::string& operator()(size_t rowIndex, size_t colIndex) const throw (IndexOutOfBoundsException);
+    
+    /**
+     * @return The element at a given position.
+     * @param rowName Row name.
+     * @param colName Column name.
+     * @throw NoTableRowNamesException If the table does not have names associated to rows. 
+     * @throw NoTableColumnNamesException If the table does not have names associated to columns. 
+     * @throw TableNameNotFoundException If one of rowName or colName do not match existing names. 
+     */
+    std::string& operator()(const std::string& rowName, const std::string& colName)
+            throw (NoTableRowNamesException, NoTableColumnNamesException, TableNameNotFoundException);
+    
+    /**
+     * @return The element at a given position.
+     * @param rowName Row name.
+     * @param colName Column name.
+     * @throw NoTableRowNamesException If the table does not have names associated to rows. 
+     * @throw NoTableColumnNamesException If the table does not have names associated to columns. 
+     * @throw TableNameNotFoundException If one of rowName or colName do not match existing names. 
+     */
+    const std::string& operator()(const std::string& rowName, const std::string& colName) const
+            throw (NoTableRowNamesException, NoTableColumnNamesException, TableNameNotFoundException);
+    
+    /**
+     * @return The element at a given position.
+     * @param rowName Row name.
+     * @param colIndex Column number.
+     * @throw NoTableRowNamesException If the table does not have names associated to rows. 
+     * @throw IndexOutOfBoundsException If the index is greater or equal to the number of columns. 
+     * @throw TableNameNotFoundException If rowName do not match existing names. 
+     */
+    std::string& operator()(const std::string& rowName, size_t colIndex)
+            throw (NoTableRowNamesException, TableNameNotFoundException, IndexOutOfBoundsException);
+    
+    /**
+     * @return The element at a given position.
+     * @param rowName Row name.
+     * @param colIndex Column number.
+     * @throw NoTableRowNamesException If the table does not have names associated to rows. 
+     * @throw IndexOutOfBoundsException If the index is greater or equal to the number of columns. 
+     * @throw TableNameNotFoundException If rowName do not match existing names. 
+     */
+    const std::string& operator()(const std::string& rowName, size_t colIndex) const
+            throw (NoTableRowNamesException, TableNameNotFoundException, IndexOutOfBoundsException);
+
+    /**
+     * @return The element at a given position.
+     * @param rowIndex Row number.
+     * @param colName Column name.
+     * @throw IndexOutOfBoundsException If the index is greater or equal to the number of rows. 
+     * @throw NoTableColumnNamesException If the table does not have names associated to columns. 
+     * @throw TableNameNotFoundException If colName do not match existing names. 
+     */
+    std::string& operator()(size_t rowIndex, const std::string& colName)
+            throw (IndexOutOfBoundsException, NoTableColumnNamesException, TableNameNotFoundException);
+    
+    /**
+     * @return The element at a given position.
+     * @param rowIndex Row number.
+     * @param colName Column name.
+     * @throw IndexOutOfBoundsException If the index is greater or equal to the number of rows. 
+     * @throw NoTableColumnNamesException If the table does not have names associated to columns. 
+     * @throw TableNameNotFoundException If colName do not match existing names. 
+     */
+    const std::string& operator()(size_t rowIndex, const std::string& colName) const
+            throw (IndexOutOfBoundsException, NoTableColumnNamesException, TableNameNotFoundException);
+    
+    /**
+     * @name Work on columns.
+     *
+     * @{
+     */
+
+    /**
+     * @return The number of columns in this table.
+     */
+    size_t getNumberOfColumns() const { return nCol_; }
+
+    /**
+     * @brief Set the column names of this table.
+     * 
+     * @param colNames The row names.
+     * @throw DimensionException If the number of names do not match the number of columns in the table.
+     * @throw DuplicatedTableColumnNameException If names are not unique.
+     */
+    void setColumnNames(const std::vector<std::string>& colNames) throw (DimensionException, DuplicatedTableColumnNameException);
+    /**
+     * @brief Get the column names of this table.
+     * 
+     * @return The column names of this table.
+     * @throw NoTableColumnNamesException If no column names are associated to this table.
+     */
+    std::vector<std::string> getColumnNames() const throw (NoTableColumnNamesException);
+    /**
+     * @brief Get a given column name.
+     * 
+     * @param index The index of the column.
+     * @return The column name associated to the given column.
+     * @throw NoTableColumnNamesException If no column names are associated to this table.
+     * @throw IndexOutOfBoundsException If index is >= number of columns.
+     */
+    std::string getColumnName(size_t index) const throw (NoTableColumnNamesException, IndexOutOfBoundsException);
+    
+    /**
+     * @return true If column names are associated to this table.
+     */
+    bool hasColumnNames() const { return colNames_!= 0; }
+
+    /**
+     * @return The values in the given column.
+     * @param index The index of the column.
+     * @throw IndexOutOfBoundsException If index is >= number of columns.
+     */
+    std::vector<std::string>& getColumn(size_t index) throw (IndexOutOfBoundsException);
+    /**
+     * @return The values in the given column.
+     * @param index The index of the column.
+     * @throw IndexOutOfBoundsException If index is >= number of columns.
+     */
+    const std::vector<std::string>& getColumn(size_t index) const throw (IndexOutOfBoundsException);
+    
+    /**
+     * @return The values in the given column.
+     * @param colName The name of the column.
+     * @throw NoTableColumnNamesException If no column names are associated to this table.
+     * @throw TableColumnNameNotFoundException If colName do not match existing column names. 
+     */
+    std::vector<std::string>& getColumn(const std::string& colName) throw (NoTableColumnNamesException, TableColumnNameNotFoundException);
+    /**
+     * @return The values in the given column.
+     * @param colName The name of the column.
+     * @throw NoTableColumnNamesException If no column names are associated to this table.
+     * @throw TableColumnNameNotFoundException If colName do not match existing column names. 
+     */
+    const std::vector<std::string>& getColumn(const std::string& colName) const throw (NoTableColumnNamesException, TableColumnNameNotFoundException);
+
+    /**
+     * @brief Tell is a given column exists.
+     *
+     * @param colName The name of the column to look for.
+     * @return true if the column was found, false if not or if there are no column names.
+     */
+    bool hasColumn(const std::string& colName) const;
+
+    /**
+     * @brief Delete the given column.
+     * 
+     * @param index The index of the column.
+     * @throw IndexOutOfBoundsException If index is >= number of columns.
+     */
+    void deleteColumn(size_t index) throw (IndexOutOfBoundsException);
+    
+    /**
+     * @brief Delete the given column.
+     * 
+     * @param colName The name of the column.
+     * @throw NoTableColumnNamesException If no column names are associated to this table.
+     * @throw TableColumnNameNotFoundException If colName do not match existing column names. 
+     */
+    void deleteColumn(const std::string& colName) throw (NoTableColumnNamesException, TableColumnNameNotFoundException);
+  
+    /**
+     * @brief Add a new column.
+     *
+     * @param newColumn The new column values.
+     * @throw DimensionException If the number of values does not match the number of rows.
+     * @throw TableColumnNamesException If the table has row names.
+     */
+    void addColumn(const std::vector<std::string>& newColumn) throw (DimensionException, TableColumnNamesException);
+    /**
+     * @brief Add a new column.
+     *
+     * @param colName   The name of the column.
+     * @param newColumn The new column values.
+     * @throw DimensionException If the number of values does not match the number of rows.
+     * @throw NoTableColumnNamesException If the table does not have row names.
+     * @throw DuplicatedTableColumnNameException If colName is already used.
+     */
+    void addColumn(const std::string& colName, const std::vector<std::string>& newColumn) throw (DimensionException, NoTableColumnNamesException, DuplicatedTableColumnNameException);
+    /** @} */
+    
+    /**
+     * @name Work on rows.
+     *
+     * @{
+     */
+    
+    /**
+     * @return The number of rows in this table.
+     */
+    size_t getNumberOfRows() const { return nRow_; }
+
+    /**
+     * @brief Set the row names of this table.
+     * 
+     * @param rowNames The row names.
+     * @throw DimensionException If the number of names do not match the number of rows in the table.
+     * @throw DuplicatedTableRowNameException If names are not unique.
+     */
+    void setRowNames(const std::vector<std::string>& rowNames) throw (DimensionException, DuplicatedTableRowNameException);
+
+    /**
+     * @brief Get the row names of this table.
+     * 
+     * @return The row names of this table.
+     * @throw NoTableRowNamesException If no row names are associated to this table.
+     */
+    std::vector<std::string> getRowNames() const throw (NoTableRowNamesException);
+
+    /**
+     * @brief Tell is a given row exists.
+     *
+     * @param rowName The name of the row to look for.
+     * @return true if the row was found, false if not or if there are no row names.
+     */
+    bool hasRow(const std::string& rowName) const;
+
+    /**
+     * @brief Get a given row name.
+     * 
+     * @param index The index of the row.
+     * @return The row name associated to the given row.
+     * @throw NoTableRowNamesException If no row names are associated to this table.
+     * @throw IndexOutOfBoundsException If index is >= number of rows.
+     */
+    std::string getRowName(size_t index) const throw (NoTableRowNamesException, IndexOutOfBoundsException);
+
+    /**
+     * @return true If row names are associated to this table.
+     */
+    bool hasRowNames() const { return rowNames_!= 0; }
+
+    /**
+     * @return A vector which contains a copy  in the given row.
+     * @param index The index of the row.
+     * @throw IndexOutOfBoundsException If index is >= number of rows.
+     */
+    std::vector<std::string> getRow(size_t index) const throw (IndexOutOfBoundsException);
+
+    /**
+     * @return A vector which contains a copy  in the given row.
+     * @param rowName The name of the row.
+     * @throw NoTableRowNamesException If no row names are associated to this table.
+     * @throw TableRowNameNotFoundException If rowName do not match existing row names.
+     */
+    std::vector<std::string> getRow(const std::string& rowName) const throw (NoTableRowNamesException, TableRowNameNotFoundException);
+
+    /**
+     * @brief Delete the given row.
+     * 
+     * @param index The index of the row.
+     * @throw IndexOutOfBoundsException If index is >= number of row.
+     */
+    void deleteRow(size_t index) throw (IndexOutOfBoundsException);
+
+    /**
+     * @brief Delete the given row.
+     * 
+     * @param rowName The name of the row.
+     * @throw NoTableRowNamesException If no row names are associated to this table.
+     * @throw TableRowNameNotFoundException If rowName do not match existing column names. 
+     */
+    void deleteRow(const std::string& rowName) throw (NoTableRowNamesException, TableRowNameNotFoundException);
+    
+    /**
+     * @brief Add a new row.
+     *
+     * @param newRow The new row values.
+     * @throw DimensionException If the number of values does not match the number of columns.
+     * @throw TableRowNamesException If the table has column names.
+     */
+    void addRow(const std::vector<std::string>& newRow) throw (DimensionException, TableRowNamesException);
+    /**
+     * @brief Add a new row.
+     *
+     * @param rowName   The name of the row.
+     * @param newRow    The new row values.
+     * @throw DimensionException If the number of values does not match the number of columns.
+     * @throw NoTableRowNamesException If the table does not have column names.
+     * @throw DuplicatedTableRowNameException If rowName is already used.
+     */
+    void addRow(const std::string& rowName, const std::vector<std::string>& newRow) throw (DimensionException, NoTableRowNamesException, DuplicatedTableRowNameException);
+    /** @} */
+
+  public:
+
+    /**
+     * @brief Read a table form a stream in CSV-like format.
+     *
+     * The number of rows is given by the second line in the file.
+     * By default, if the first line as one column less than the second one,
+     * the first line is taken as column names, and the first column as row names.
+     * Otherwise, no column names and no row names are specified, unless
+     * explicitely precised by the user.
+     * 
+     * @param in       The input stream.
+     * @param sep      The column delimiter.
+     * @param header   Tell if the first line must be used as column names, otherwise use default.
+     * @param rowNames Use a column as rowNames. If positive, use the specified column to compute rownames, otherwise use default;
+     * @return         A pointer toward a new DataTable object.
+     */
+    static DataTable* read(std::istream& in, const std::string& sep = "\t", bool header = true, int rowNames = -1)
+      throw (DimensionException, IndexOutOfBoundsException, DuplicatedTableRowNameException);
+
+    /**
+     * @brief Write a DataTable object to stream in CVS-like format.
+     * 
+     * @param data         The table to write.
+     * @param out          The output stream.
+     * @param sep          The column delimiter.
+     * @param alignHeaders If true, add a delimiter before the first column header if there is row names.
+     */
+    static void write(const DataTable& data, std::ostream& out, const std::string& sep = "\t", bool alignHeaders = false);
+};
+
+} //end of namespace bpp.
+
+#endif //_DataTable_H_
+
diff --git a/src/Bpp/Numeric/DataTableExceptions.h b/src/Bpp/Numeric/DataTableExceptions.h
new file mode 100644
index 0000000..e06d46d
--- /dev/null
+++ b/src/Bpp/Numeric/DataTableExceptions.h
@@ -0,0 +1,175 @@
+//
+// File: DataTableExceptions.h
+// Created by: Julien Dutheil
+// Created on: Tue Nov 2005 14:10
+// from file DataTable.h
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _DataTableExceptions_H_
+#define _DataTableExceptions_H_
+
+//#include "VectorTools.h"
+
+// From Utils:
+#include "../Exceptions.h"
+#include "../Text/TextTools.h"
+
+// From the STL:
+#include <string>
+
+namespace bpp
+{
+
+/**
+ * @brief Exception thrown when a given name is not found is a DataTable object.
+ */
+class TableNameNotFoundException:
+  public Exception
+{
+	protected:
+    std::string _name;
+		
+	public:
+		TableNameNotFoundException(const std::string & text, const std::string & name) :
+			Exception("TableNameNotFoundException: " + name + ". " + text), _name(name) {}
+		virtual ~TableNameNotFoundException() throw() {}
+
+	public:
+    std::string getName() const { return _name; }		
+};
+
+/**
+ * @brief Exception thrown when a given row name is not found is a DataTable object.
+ */
+class TableRowNameNotFoundException:
+  public TableNameNotFoundException
+{
+	public:
+		TableRowNameNotFoundException(const std::string & text, const std::string & name) :
+			TableNameNotFoundException("TableRowNameNotFoundException: " + name + ". " + text, name) {}
+		virtual ~TableRowNameNotFoundException() throw() {}
+};
+
+/**
+ * @brief Exception thrown when a given column name is not found is a DataTable object.
+ */
+class TableColumnNameNotFoundException:
+  public TableNameNotFoundException
+{
+	public:
+		TableColumnNameNotFoundException(const std::string & text, const std::string & name) :
+			TableNameNotFoundException("TableColumnNameNotFoundException: " + name + ". " + text, name) {}
+		virtual ~TableColumnNameNotFoundException() throw() {}
+};
+
+/**
+ * @brief Exception thrown when trying to retrieve a row by its name
+ * and no row names have been specified.
+ */
+class NoTableRowNamesException:
+  public Exception
+{
+	public:
+		NoTableRowNamesException(const std::string & text) :
+			Exception("NoTableRowNamesException: "+text) {}
+		virtual ~NoTableRowNamesException() throw() {}
+};
+
+/**
+ * @brief Exception thrown when trying to retrieve a column by its name
+ * and no column names have been specified.
+ */
+class NoTableColumnNamesException:
+  public Exception
+{
+	public:
+		NoTableColumnNamesException(const std::string & text) :
+			Exception("NoTableColumnNamesException: "+text) {}
+		virtual ~NoTableColumnNamesException() throw() {}
+};
+
+/**
+ * @brief General exception class dealing with row names.
+ */
+class TableRowNamesException:
+  public Exception
+{
+	public:
+		TableRowNamesException(const std::string & text) :
+			Exception("TableRowNamesException: "+text) {}
+		virtual ~TableRowNamesException() throw() {}
+};
+
+/**
+ * @brief General exception class dealing with column names.
+ */
+class TableColumnNamesException:
+  public Exception
+{
+	public:
+		TableColumnNamesException(const std::string & text) :
+			Exception("TableColumnNamesException: "+text) {}
+		virtual ~TableColumnNamesException() throw() {}
+};
+
+/**
+ * @brief Exception thrown when attempting to duplicate a row name.
+ */
+class DuplicatedTableRowNameException:
+  public Exception
+{
+	public:
+		DuplicatedTableRowNameException(const std::string & text) :
+			Exception("DuplicatedTableRowNameException: "+text) {}
+		virtual ~DuplicatedTableRowNameException() throw() {}
+};
+
+/**
+ * @brief Excpetion thrown when attempting to duplicate a column name.
+ */
+class DuplicatedTableColumnNameException:
+  public Exception
+{
+	public:
+		DuplicatedTableColumnNameException(const std::string & text) :
+			Exception("DuplicatedTableColumnNameException: "+text) {}
+		virtual ~DuplicatedTableColumnNameException() throw() {}
+};
+
+} //end of namespace bpp.
+
+#endif //_DataTableExceptions_H_
+
diff --git a/src/Bpp/Numeric/Function/AbstractNumericalDerivative.h b/src/Bpp/Numeric/Function/AbstractNumericalDerivative.h
new file mode 100644
index 0000000..c2436f4
--- /dev/null
+++ b/src/Bpp/Numeric/Function/AbstractNumericalDerivative.h
@@ -0,0 +1,285 @@
+//
+// File: AbstractNumericalDerivative.h
+// Created by: Julien Dutheil
+// Created on: Thu Aug 17 15:00 2006
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _ABSTRACTNUMERICALDERIVATIVE_H_
+#define _ABSTRACTNUMERICALDERIVATIVE_H_
+
+#include "Functions.h"
+#include "../Matrix/Matrix.h"
+
+//From the STL:
+#include <map>
+#include <vector>
+#include <string>
+
+namespace bpp
+{
+
+/**
+ * @brief Numerical derivative function wrapper, partial implementation.
+ *
+ * This class provides a wrapper for Function object, implementing the DerivableSecondOrder interface
+ * (Although no cross derivative is implemented for now).
+ * Derivations of this class can be used as full DerivableSecondOrder objects, with derivative functions.
+ * 
+ * Three kinds of constructors are provided: one with a Function object, another with a DerivableFirstOrder object, and one with a DerivableSecondOrder object.
+ * In the first case, all derivatives will be computed numerically.
+ * In the second case, first order derivative will be computed numerically only if no appropriate analytical derivative is available, second order derivative will always be computed numerically.
+ * In the last case, first and second order derivative will be computed numerically only if no appropriate analytical derivative is available.
+ */
+class AbstractNumericalDerivative:
+  public DerivableSecondOrder,
+  public FunctionWrapper
+{
+  protected:
+    DerivableFirstOrder *function1_;
+    DerivableSecondOrder *function2_;
+    double h_;
+    std::vector<std::string> variables_;
+    mutable std::map<std::string, size_t> index_; //Store positions in array corresponding to variable names.
+    std::vector<double> der1_;
+    std::vector<double> der2_;
+    RowMatrix<double> crossDer2_;
+    bool computeD1_, computeD2_, computeCrossD2_;
+    
+  public:
+    AbstractNumericalDerivative(Function* function):
+      FunctionWrapper(function), function1_(0), function2_(0),
+      h_(0.0001), variables_(), index_(), der1_(), der2_(), crossDer2_(),
+      computeD1_(true), computeD2_(true), computeCrossD2_(false) {}
+
+    AbstractNumericalDerivative(DerivableFirstOrder* function):
+      FunctionWrapper(function), function1_(function), function2_(0),
+      h_(0.0001), variables_(), index_(), der1_(), der2_(), crossDer2_(),
+      computeD1_(true), computeD2_(true), computeCrossD2_(false) {}
+
+    AbstractNumericalDerivative(DerivableSecondOrder* function):
+      FunctionWrapper(function), function1_(function), function2_(function),
+      h_(0.0001), variables_(), index_(), der1_(), der2_(), crossDer2_(),
+      computeD1_(true), computeD2_(true), computeCrossD2_(false) {}
+
+    AbstractNumericalDerivative(const AbstractNumericalDerivative& ad):
+      FunctionWrapper(ad), function1_(ad.function1_), function2_(ad.function2_),
+      h_(ad.h_), variables_(ad.variables_), index_(ad.index_), der1_(ad.der1_), der2_(ad.der2_), crossDer2_(ad.crossDer2_),
+      computeD1_(ad.computeD1_), computeD2_(ad.computeD2_), computeCrossD2_(ad.computeCrossD2_) {}
+
+    AbstractNumericalDerivative& operator=(const AbstractNumericalDerivative& ad)
+    {
+      FunctionWrapper::operator=(ad);
+      function1_ = ad.function1_;
+      function2_ = ad.function2_;
+      h_ = ad.h_;
+      variables_ = ad.variables_;
+      index_ = ad.index_;
+      der1_ = ad.der1_;
+      der2_ = ad.der2_;
+      crossDer2_ = ad.crossDer2_;
+      computeD1_ = ad.computeD1_;
+      computeD2_ = ad.computeD2_;
+      computeCrossD2_ = ad.computeCrossD2_;
+      return *this;
+    }
+
+    virtual ~AbstractNumericalDerivative() {}
+
+    AbstractNumericalDerivative* clone() const = 0;
+
+  public:
+    /**
+     * @brief Set the interval value used in numerical approximation.
+     *
+     * Default value is 0.0001.
+     *
+     * @param h Interval value.
+     */
+    void setInterval(double h) { h_ = h; }
+    
+    /**
+     * @return The interval value used in numerical approximation.
+     */
+    double getInterval() const { return h_; }
+    
+    /**
+     * @brief Set the list of parameters to derivate.
+     *
+     * @param variables A list of all parameter names.
+     */
+    void setParametersToDerivate(const std::vector<std::string>& variables)
+    {
+      variables_ = variables;
+      index_.clear();
+      for(size_t i = 0; i < variables_.size(); i++)
+        index_[variables_[i]] = i;
+      der1_.resize(variables_.size());
+      der2_.resize(variables_.size());
+      crossDer2_.resize(variables_.size(), variables_.size());
+    }
+    
+    /**
+     * @name The DerivableFirstOrder interface
+     *
+     * @{
+     */
+    void enableFirstOrderDerivatives(bool yn) { computeD1_ = yn; }
+    bool enableFirstOrderDerivatives() const { return computeD1_; }
+    
+    double getFirstOrderDerivative(const std::string& variable) const
+      throw (Exception)
+    {
+      if (function1_)
+      {
+        try
+        {
+          return function1_->getFirstOrderDerivative(variable);
+        }
+        catch (Exception& e) {}
+      }    
+      std::map<std::string, size_t>::iterator it = index_.find(variable);
+      if (computeD1_ && it != index_.end()) return der1_[it->second];
+      else throw Exception("First order derivative not computed for variable " + variable + "."); 
+    }
+    /** @} */
+    
+    /**
+     * @name The DerivableSecondOrder interface
+     *
+     * @{
+     */
+
+    void enableSecondOrderDerivatives(bool yn) { computeD2_ = yn; }
+    bool enableSecondOrderDerivatives() const { return computeD2_; }
+
+    double getSecondOrderDerivative(const std::string& variable) const
+      throw (Exception)
+    {
+      if (function2_)
+      {
+        try
+        {
+          return function2_->getSecondOrderDerivative(variable);
+        }
+        catch(Exception & e) {}
+      }    
+      std::map<std::string, size_t>::iterator it = index_.find(variable);
+      if(computeD2_ && it != index_.end()) return der2_[it->second];
+      else throw Exception("Second order derivative not computed for variable " + variable + "."); 
+    }
+
+    double getSecondOrderDerivative(const std::string& variable1, const std::string& variable2) const
+      throw (Exception)
+    {
+      if (function2_)
+      {
+        try
+        {
+          return function2_->getSecondOrderDerivative(variable1, variable2);
+        }
+        catch(Exception & e) {}
+      }    
+      std::map<std::string, size_t>::iterator it1 = index_.find(variable1);
+      std::map<std::string, size_t>::iterator it2 = index_.find(variable2);
+      if(computeCrossD2_ && it1 != index_.end() && it2 != index_.end()) return crossDer2_(it1->second, it2->second);
+      else throw Exception("Cross second order derivative not computed for variables " + variable1 + " and " + variable2 + "."); 
+    }
+    /** @} */
+     
+    /**
+     * @name The Parametrizable interface.
+     *
+     * @{
+     */
+    double f(const ParameterList& parameters) throw (Exception)
+    {
+      setParameters(parameters);
+      return getValue();
+    }
+    void setParameters(const ParameterList& parameters)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      function_->setParameters(parameters);
+      updateDerivatives(parameters);
+    }
+    void setAllParametersValues(const ParameterList& parameters)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      function_->setAllParametersValues(parameters);
+      updateDerivatives(parameters);
+    }
+    
+    void setParameterValue(const std::string& name, double value)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      function_->setParameterValue(name, value);
+      updateDerivatives(function_->getParameters().subList(name));
+    }
+    
+    void setParametersValues(const ParameterList& parameters)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      function_->setParametersValues(parameters);
+      updateDerivatives(parameters);
+    }
+    
+    bool matchParametersValues(const ParameterList& parameters)
+      throw (ConstraintException)
+    {
+      bool test = function_->matchParametersValues(parameters);
+      updateDerivatives(parameters);
+      return test;
+    }
+    /** @} */
+
+    void enableSecondOrderCrossDerivatives(bool yn) { computeCrossD2_ = yn; }
+    bool enableSecondOrderCrossDerivatives() const { return computeCrossD2_; }
+
+  protected:
+    /**
+     * @brief Compute derivatives.
+     *
+     * @param parameters The point where to compute derivatives. It is NOT passed as references,
+     * as the inner parameters of the function will be changed when computing the numerical derivatives.
+     */
+    virtual void updateDerivatives(const ParameterList parameters) = 0;
+    
+};
+
+} //end of namespace bpp.
+
+#endif //_ABSTRACTNUMERICALDERIVATIVE_H_
+
diff --git a/src/Bpp/Numeric/Function/AbstractOptimizer.cpp b/src/Bpp/Numeric/Function/AbstractOptimizer.cpp
new file mode 100644
index 0000000..0bfd823
--- /dev/null
+++ b/src/Bpp/Numeric/Function/AbstractOptimizer.cpp
@@ -0,0 +1,344 @@
+//
+// File: AbstractOptimizer.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Dec 22 12:18:09 2003
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "AbstractOptimizer.h"
+#include "../AutoParameter.h"
+#include "../../Text/TextTools.h"
+#include "../../App/ApplicationTools.h"
+
+// From the STL:
+#include <iomanip>
+#include <time.h>
+
+using namespace std;
+using namespace bpp;
+
+/******************************************************************************/
+
+AbstractOptimizer::AbstractOptimizer(Function* function):
+  function_(function),
+  parameters_(),
+  messageHandler_(ApplicationTools::message),
+  profiler_(ApplicationTools::message),
+  constraintPolicy_(AutoParameter::CONSTRAINTS_KEEP),
+  stopCondition_(0), defaultStopCondition_(0),
+  verbose_(true), isInitialized_(false), startTime_(), listeners_(),
+  updateParameters_(false), stepChar_("*"),
+  nbEvalMax_(1000000), nbEval_(0),
+  currentValue_(0), tolIsReached_(false)
+{
+}
+
+/******************************************************************************/
+
+AbstractOptimizer::AbstractOptimizer(const AbstractOptimizer& opt):
+  function_(opt.function_),
+  parameters_(opt.parameters_),
+  messageHandler_(opt.messageHandler_),
+  profiler_(opt.profiler_),
+  constraintPolicy_(opt.constraintPolicy_),
+  stopCondition_(0), defaultStopCondition_(0),
+  verbose_(opt.verbose_),
+  isInitialized_(opt.isInitialized_),
+  startTime_(opt.startTime_),
+  listeners_(), //We do not copy listeners!
+  updateParameters_(opt.updateParameters_),
+  stepChar_(opt.stepChar_),
+  nbEvalMax_(opt.nbEvalMax_),
+  nbEval_(opt.nbEval_),
+  currentValue_(opt.currentValue_),
+  tolIsReached_(opt.tolIsReached_)
+{
+  if (opt.stopCondition_)
+    {
+      stopCondition_        = dynamic_cast<OptimizationStopCondition *>(opt.stopCondition_->clone());
+      stopCondition_->setOptimizer(this);
+    }
+  else
+    stopCondition_        = 0;
+  if (opt.defaultStopCondition_)
+    {
+      defaultStopCondition_ = dynamic_cast<OptimizationStopCondition *>(opt.defaultStopCondition_->clone());
+      defaultStopCondition_->setOptimizer(this);
+    }
+  else
+    defaultStopCondition_ = 0;
+  //In case of AutoParameter instances, we must actualize the pointers toward _messageHandler:
+  if (isInitialized_)
+    {
+      if(constraintPolicy_ == AutoParameter::CONSTRAINTS_AUTO)   autoParameter();
+      else if(constraintPolicy_ == AutoParameter::CONSTRAINTS_IGNORE) ignoreConstraints();
+    }
+}
+
+/******************************************************************************/
+
+AbstractOptimizer& AbstractOptimizer::operator=(const AbstractOptimizer& opt)
+{
+  function_               = opt.function_;
+  parameters_             = opt.parameters_;
+  messageHandler_         = opt.messageHandler_;
+  profiler_               = opt.profiler_;
+  constraintPolicy_       = opt.constraintPolicy_;
+  tolIsReached_           = opt.tolIsReached_;
+  if (opt.stopCondition_)
+  {
+    stopCondition_        = dynamic_cast<OptimizationStopCondition *>(opt.stopCondition_->clone());
+    stopCondition_->setOptimizer(this);
+  }
+  else
+    stopCondition_        = 0;
+  if (opt.defaultStopCondition_)
+  {
+    defaultStopCondition_ = dynamic_cast<OptimizationStopCondition *>(opt.defaultStopCondition_->clone());
+    defaultStopCondition_->setOptimizer(this);
+  }
+  else
+    defaultStopCondition_ = 0;
+  nbEvalMax_              = opt.nbEvalMax_;
+  nbEval_                 = opt.nbEval_;
+  verbose_                = opt.verbose_;
+  isInitialized_          = opt.isInitialized_;
+  //In case of AutoParameter instances, we must actualize the pointers toward messageHandler_:
+  if (isInitialized_)
+  {
+    if (constraintPolicy_ == AutoParameter::CONSTRAINTS_AUTO)   autoParameter();
+    else if (constraintPolicy_ == AutoParameter::CONSTRAINTS_IGNORE) ignoreConstraints();
+  }
+  startTime_              = opt.startTime_;
+  listeners_.resize(0); //Reset listener list, do not copy it!
+  updateParameters_       = opt.updateParameters_;
+  stepChar_               = opt.stepChar_;
+  return *this;
+}
+
+/******************************************************************************/
+	
+void AbstractOptimizer::init(const ParameterList& params) throw (Exception)
+{
+  if (!function_) throw Exception("AbstractOptimizer::init. Optimizer currently has no function.");
+  //We do this in order to keep original constraints:
+  parameters_ = params;
+  //More secure, but too slow:
+  //parameters_ = function_->getParameters().subList(params.getParameterNames());
+  //parameters_.matchParametersValues(params);
+  if (constraintPolicy_ == AutoParameter::CONSTRAINTS_AUTO) autoParameter();
+  else if (constraintPolicy_ == AutoParameter::CONSTRAINTS_IGNORE) ignoreConstraints();
+  doInit(params);
+  nbEval_ = 0;
+  tolIsReached_ = false;
+  isInitialized_ = true;
+  time(&startTime_);
+  currentValue_ = function_->getValue();
+
+  profile("Step\t");
+  for (unsigned int i = 0; i < parameters_.size(); i++)
+  {
+    profile(parameters_[i].getName() + "\t"); 
+  }
+  profileln("Function\tTime");
+
+  //Parameters must be assigned by doInit:
+
+  printPoint(parameters_, currentValue_);
+  
+  // Initialize the StopCondition:
+  stopCondition_->init();
+  fireOptimizationInitializationPerformed(OptimizationEvent(this));
+}
+
+/******************************************************************************/
+
+double AbstractOptimizer::step() throw (Exception)
+{
+  currentValue_ = doStep();
+  printPoint(parameters_, currentValue_);
+  fireOptimizationStepPerformed(OptimizationEvent(this));
+  if (listenerModifiesParameters())
+  {
+    if (!updateParameters_)
+      parameters_.matchParametersValues(function_->getParameters());
+    //else already done!
+     //_currentValue = function_->getValue();
+    //Often useless, but avoid some bizare behaviour in particular cases:
+    currentValue_ = function_->f(parameters_);
+  }
+  tolIsReached_ = tolIsReached_ || stopCondition_->isToleranceReached();
+  return currentValue_;
+}
+
+/**************************************************************************/
+
+double AbstractOptimizer::optimize() throw (Exception)
+{
+  if (!isInitialized_)
+    throw Exception("AbstractOptimizer::optimize. Optimizer not initialized: call the 'init' method first!");
+  tolIsReached_ = false;
+  for (nbEval_ = 1; nbEval_ < nbEvalMax_ && ! tolIsReached_; nbEval_++)
+  {
+    if (verbose_)
+      ApplicationTools::displayUnlimitedGauge(nbEval_, "Optimizing... ");
+    step();
+  }
+  return currentValue_;
+}
+
+/******************************************************************************/
+
+void AbstractOptimizer::profile(double v)
+{
+  if (profiler_) *profiler_ << v;
+}	
+
+/******************************************************************************/
+
+void AbstractOptimizer::profileln(double v)
+{
+  if (profiler_) (*profiler_ << v).endLine();
+}
+	
+/******************************************************************************/
+
+void AbstractOptimizer::profile(unsigned int v)
+{
+  if (profiler_) *profiler_ << v;
+}
+/******************************************************************************/
+
+void AbstractOptimizer::profileln(unsigned int v)
+{
+  if (profiler_) (*profiler_ << v).endLine();
+}
+	
+/******************************************************************************/
+
+void AbstractOptimizer::profile(const std::string& s)
+{
+  if (profiler_) *profiler_ << s;
+}	
+
+/******************************************************************************/
+
+void AbstractOptimizer::profileln(const std::string& s)
+{
+  if (profiler_) (*profiler_ << s).endLine();
+}
+	
+/******************************************************************************/
+
+void AbstractOptimizer::printPoint(const ParameterList& params, double value)
+{
+  size_t ndim = params.size();
+  profile(nbEval_);
+  profile("\t");
+  for (size_t j = 0; j < ndim; j++)
+  {
+    profile(TextTools::toString(params[j].getValue()));
+    profile("\t"); 
+  }
+  profile(value);
+  profile("\t");
+  time_t seconds;
+  time(&seconds);
+  profileln(difftime(seconds, startTime_));
+}
+
+/******************************************************************************/
+
+void AbstractOptimizer::printMessage(const std::string& message)
+{
+  if (messageHandler_) (*messageHandler_ << message).endLine();
+}
+
+/******************************************************************************/
+
+void AbstractOptimizer::autoParameter()
+{
+  for (unsigned int i = 0; i < parameters_.size(); i++)
+  {
+    AutoParameter ap(parameters_[i]);
+    ap.setMessageHandler(messageHandler_);
+    parameters_.setParameter(i, ap);
+  }
+}
+
+/******************************************************************************/
+
+void AbstractOptimizer::ignoreConstraints()
+{
+  for (unsigned int i = 0; i < parameters_.size(); i++)
+  {
+    parameters_[i].removeConstraint();
+  }
+}
+
+/******************************************************************************/
+
+void AbstractOptimizer::fireOptimizationInitializationPerformed(const OptimizationEvent& event)
+{
+  for (unsigned int i = 0; i < listeners_.size(); i++)
+  {
+    listeners_[i]->optimizationInitializationPerformed(event);
+  }
+}
+
+/******************************************************************************/
+
+void AbstractOptimizer::fireOptimizationStepPerformed(const OptimizationEvent& event)
+{
+  for (unsigned int i = 0; i < listeners_.size(); i++)
+  {
+    listeners_[i]->optimizationStepPerformed(event);
+  }
+}
+
+/******************************************************************************/
+
+bool AbstractOptimizer::listenerModifiesParameters() const
+{
+  for (unsigned int i = 0; i < listeners_.size(); i++)
+  {
+    if (listeners_[i]->listenerModifiesParameters())
+      return true;
+  }
+  return false;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/AbstractOptimizer.h b/src/Bpp/Numeric/Function/AbstractOptimizer.h
new file mode 100644
index 0000000..a7564d6
--- /dev/null
+++ b/src/Bpp/Numeric/Function/AbstractOptimizer.h
@@ -0,0 +1,391 @@
+//
+// File: AbstractOptimizer.h
+// Created by: Julien Dutheil
+// Created on: Mon Dec 22 12:18:09 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _ABSTRACTOPTIMIZER_H_
+#define _ABSTRACTOPTIMIZER_H_
+
+#include "Optimizer.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Partial implementation of the Optimizer interface.
+ *
+ * This implementation is designed for unconstrained or simple-bounded optimization.
+ * You should not use it with global contraints.
+ * It also enables the gestion of listeners by maintaining a vector of pointers toward the listener.
+ * Important note: this list of listener is not duplicated in cas of copy of the Optimizer, as 
+ * listeners are expected to be bounded ot a particular instance.:if expand("%") == ""|browse confirm w|else|confirm w|endif
+ * 
+ *
+ */
+class AbstractOptimizer:
+  public virtual Optimizer
+{
+  private:
+    
+    /**
+     * @brief The function to optimize.
+     */
+    Function* function_;
+  
+    /**
+     * @brief The parameters that will be optimized.
+     */
+    ParameterList parameters_;
+  
+    /**
+     * @brief The message handler.
+     */
+    OutputStream* messageHandler_;
+  
+    /**
+     * @brief The profiler.
+     */
+    OutputStream* profiler_;
+    
+    /**
+     * @brief The constraint policy.
+     *
+     * Must be one the following:
+     * - CONSTRAINTS_KEEP: keep the constraint associated to the parameters (default).
+     * - CONSTRAINTS_IGNORE: remove all constraints.
+     * - CONSTRAINTS_AUTO: use AutoParameters to deal with constraints.
+     *
+     * @see AutoParameter
+     */      
+    std::string constraintPolicy_;
+    
+    /**
+     * @brief The stoping condition to use while optimizing.
+     */
+    OptimizationStopCondition* stopCondition_;
+    
+    /**
+     * @brief The default stoping condition to use while optimizing.
+     */
+    OptimizationStopCondition* defaultStopCondition_;
+
+    /**
+     * @brief State of the verbose mode: > 0 = enabled.
+     *
+     * This may not be used by the Optimizer.
+     */
+    unsigned int verbose_;
+
+    /**
+     * @brief Check if the optimizer have been feeded with initial parameters values.
+     */
+    bool isInitialized_;
+
+    time_t startTime_;
+
+    std::vector<OptimizationListener*> listeners_;
+
+    bool updateParameters_;
+
+    std::string stepChar_;
+
+  protected:
+
+    /**
+     * @brief The maximum number of function evaluations allowed.
+     */
+    unsigned int nbEvalMax_;
+    
+    /**
+     * @brief The current number of function evaluations achieved.
+     */
+    unsigned int nbEval_;
+
+    /**
+     * @brief The current value of the function.
+     */
+    double currentValue_;
+
+    /**
+     * @brief Tell if the tolerance level has been reached.
+     *
+     * This field is initilaised by the init() method, maintained by the
+     * step() method and used in the optimize() method.
+     */
+    bool tolIsReached_;
+
+  public:
+    AbstractOptimizer(Function* function = 0);
+
+    AbstractOptimizer(const AbstractOptimizer& opt);
+    
+    AbstractOptimizer& operator=(const AbstractOptimizer& opt);
+
+    virtual ~AbstractOptimizer()
+    {
+      delete stopCondition_;
+      delete defaultStopCondition_;
+    }
+  
+  public:
+    
+    /**
+     * @name The Optimizer interface.
+     *
+     * @{
+     */
+    /**
+     * @brief Basic implementation.
+     *
+     * Store all parameters, call the doInit method, print to profiler, initialize timer and notify all listeners.
+     */
+    void init(const ParameterList& params) throw (Exception);
+    /**
+     * @brief Basic implementation.
+     *
+     * Check if the optimizer is initialized, check if parameters need update because of listeners, call the doStep method, print the current point to the profiler, notify all listeners and return the current value of the function.
+     */
+    double step() throw (Exception);
+    /**
+     * @brief Basic implementation.
+     *
+     * Call the step method untill tolerance is reached.
+     */
+    double optimize() throw (Exception);
+    bool isInitialized() const { return isInitialized_; }
+    const ParameterList& getParameters() const { return parameters_; }
+  double getParameterValue(const std::string& name) const { return parameters_.getParameterValue(name); }
+    void setFunction(Function* function)
+    { 
+      function_ = function;
+      if (function) stopCondition_->init();
+    }
+    const Function* getFunction() const { return function_; }
+    Function* getFunction() { return function_; }
+    bool hasFunction() const { return function_ != 0; }
+    double getFunctionValue() const throw (NullPointerException)
+    {
+      if (!function_) throw NullPointerException("AbstractOptimizer::getFunctionValue. No function associated to this optimizer.");
+      return currentValue_;
+    }
+    
+    void setMessageHandler(OutputStream* mh) { messageHandler_ = mh; }
+    OutputStream* getMessageHandler() const { return messageHandler_; }
+    void setProfiler(OutputStream* profiler) { profiler_ = profiler; }
+    OutputStream* getProfiler() const { return profiler_; }
+
+    unsigned int getNumberOfEvaluations() const { return nbEval_; }
+    void setStopCondition(const OptimizationStopCondition& stopCondition)
+    {
+      stopCondition_ = dynamic_cast<OptimizationStopCondition*>(stopCondition.clone());
+    }
+    OptimizationStopCondition* getStopCondition() { return stopCondition_; }
+    const OptimizationStopCondition* getStopCondition() const { return stopCondition_; }
+    OptimizationStopCondition* getDefaultStopCondition() { return defaultStopCondition_; }
+    const OptimizationStopCondition* getDefaultStopCondition() const { return defaultStopCondition_; }
+    bool isToleranceReached() const { return tolIsReached_; }
+    bool isMaximumNumberOfEvaluationsReached() const { return nbEval_ >= nbEvalMax_; }
+    void setMaximumNumberOfEvaluations(unsigned int max) { nbEvalMax_ = max; }
+    void setVerbose(unsigned int v) { verbose_ = v; }
+    unsigned int getVerbose() const { return verbose_; }
+    void setConstraintPolicy(const std::string& constraintPolicy) { constraintPolicy_ = constraintPolicy; }
+    std::string getConstraintPolicy() const { return constraintPolicy_; }
+    void addOptimizationListener(OptimizationListener* listener)
+    {
+      if (listener)
+        listeners_.push_back(listener);
+    }
+    /** @} */
+
+    /**
+     * @brief Tell if we shall update all parameters after one optimization step.
+     *
+     * This is required only for functions that have non-independent parameters,
+     * which means that setting one parameter value may modify one or several other parameters.
+     * Depending on the optimizer, this may have no effect.
+     *
+     * @param yn true/false
+     */
+    void updateParameters(bool yn) { updateParameters_ = yn; }
+
+    /**
+     * @brief Tell if we shall update all parameters after one optimization step.
+     *
+     * This is required only for functions that have non-independent parameters,
+     * which means that setting one parameter value may modify one or several other parameters.
+     * Depending on the optimizer, this may have no effect.
+     *
+     * @return yn true/false
+     */
+    bool updateParameters() const { return updateParameters_; }
+
+    /**
+     * @brief Set the character to be displayed during optimization.
+     *
+     * @param c A character.
+     */
+    void setOptimizationProgressCharacter(const std::string& c) { stepChar_ = c; }
+    /**
+     * @return The character to be displayed during optimization.
+     */
+    const std::string& getOptimizationProgressCharacter() const { return stepChar_; }
+  
+  protected:
+
+    /**
+     * @brief This function is called by the init() method and contains all calculations.
+     *
+     * @param params The parameters to use for initialization.
+     */
+    virtual void doInit(const ParameterList& params) throw (Exception) = 0;
+    
+    /**
+     * @brief This function is called by the step() method and contains all calculations.
+     *
+     * @return The value of the function after the optimization step.
+     */
+    virtual double doStep() throw (Exception) = 0;
+    
+    /**
+     * @name Inner utilitary functions
+     *
+     * @{
+     */
+    
+    /**
+     * @brief Build a list of AutoParameter instead of Parameter.
+     */
+    void autoParameter();
+  
+    /**
+     * @brief Remove the constraints of all the arguments.
+     */
+    void ignoreConstraints();
+  
+    /**
+     * @brief Print to the profile if there is one.
+     *
+     * @param v The double value to print.
+     */
+    void profile(double v);
+  
+    /**
+     * @brief Print to the profile if there is one.
+     *
+     * @param v The unsigned int value to print.
+     */
+    void profile(unsigned int v);
+ 
+    /**
+     * @brief Print to the profile if there is one.
+     *
+     * @param s The string to print to the profile.
+     */
+    void profile(const std::string& s);
+  
+    /**
+     * @brief Print to the profile if there is one and end line.
+     *
+     * @param v The double value to print.
+     */
+    void profileln(double v);
+  
+    /**
+     * @brief Print to the profile if there is one and end line.
+     *
+     * @param v The unsigned int value to print.
+     */
+    void profileln(unsigned int v);
+ 
+    /**
+     * @brief Print to the profile if there is one and end line.
+     *
+     * @param s The string to print to the profile.
+     */
+    void profileln(const std::string& s);
+  
+    /**
+     * @brief Print parameters and corresponding function evaluation to profiler.
+     *
+     * @param params The parameters to print.
+     * @param value  The function evaluation.
+     */
+    void printPoint(const ParameterList& params, double value);
+    
+    /**
+     * @brief Give a message to print to the message handler.
+     *
+     * @param message The message to print.
+     */
+    void printMessage(const std::string& message);
+
+    /**
+     * @brief Notify all listeners that optimizer initialization was performed.
+     *
+     * This method should be called by the init method.
+     *
+     * @param event An OptimizationEvent object.
+     */
+    void fireOptimizationInitializationPerformed(const OptimizationEvent& event);
+
+    /**
+     * @brief Notify all listeners that an optimization step was performed.
+     *
+     * This method should be called by the step method.
+     *
+     * @param event An OptimizationEvent object.
+     */
+    void fireOptimizationStepPerformed(const OptimizationEvent& event);
+
+    bool listenerModifiesParameters() const;
+    /** @} */
+
+  protected:
+    ParameterList& getParameters_() { return parameters_; }
+    Parameter& getParameter_(size_t i) { return parameters_[i]; }
+    Function* getFunction_() { return function_; }
+    void setDefaultStopCondition_(OptimizationStopCondition* osc)
+    {
+      defaultStopCondition_ = osc;
+    }
+  
+};
+
+} //end of namespace bpp.
+
+#endif  //_ABSTRACTOPTIMIZER_H_
+
diff --git a/src/Bpp/Numeric/Function/BfgsMultiDimensions.cpp b/src/Bpp/Numeric/Function/BfgsMultiDimensions.cpp
new file mode 100644
index 0000000..c3035f8
--- /dev/null
+++ b/src/Bpp/Numeric/Function/BfgsMultiDimensions.cpp
@@ -0,0 +1,300 @@
+//
+// File: BfgsMultiDimensions.cpp
+// Created by: Laurent Guéguen
+// Created on: Dec 16 13:49 2010
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "BfgsMultiDimensions.h"
+#include "OneDimensionOptimizationTools.h"
+
+using namespace bpp;
+
+/******************************************************************************/
+
+BfgsMultiDimensions::BfgsMultiDimensions(DerivableFirstOrder* function) :
+  AbstractOptimizer(function),
+  //gtol_(gtol),
+  slope_(0),
+  Up_(),
+  Lo_(),
+  p_(),
+  gradient_(),
+  xi_(),
+  dg_(),
+  hdg_(),
+  hessian_(),
+  f1dim_(function)
+{
+  setDefaultStopCondition_(new FunctionStopCondition(this));
+  setStopCondition(*getDefaultStopCondition());
+  setOptimizationProgressCharacter(".");
+}
+
+/******************************************************************************/
+
+void BfgsMultiDimensions::doInit(const ParameterList& params) throw (Exception)
+{
+  size_t nbParams = params.size();
+  p_.resize(nbParams);
+  gradient_.resize(nbParams);
+  xi_.resize(nbParams);
+  dg_.resize(nbParams);
+  hdg_.resize(nbParams);
+  Up_.resize(nbParams);
+  Lo_.resize(nbParams);
+
+  hessian_.resize(nbParams);
+  for (size_t i = 0; i < nbParams; i++)
+  {
+    hessian_[i].resize(nbParams);
+  }
+
+  for (size_t i = 0; i < nbParams; i++)
+  {
+    const Constraint* cp = params[i].getConstraint();
+    if (!cp)
+    {
+      Up_[i] = NumConstants::VERY_BIG();
+      Lo_[i] = -NumConstants::VERY_BIG();
+    }
+    else
+    {
+      Up_[i] = cp->getAcceptedLimit(NumConstants::VERY_BIG()) - NumConstants::TINY();
+      Lo_[i] = cp->getAcceptedLimit(-NumConstants::VERY_BIG()) + NumConstants::TINY();
+    }
+  }
+
+  getFunction_()->enableFirstOrderDerivatives(true);
+  getFunction_()->setParameters(params);
+
+  getGradient(gradient_);
+
+  for (size_t i = 0; i < nbParams; i++)
+  {
+    p_[i] = getParameters()[i].getValue();
+
+    for (unsigned int j = 0; j < nbParams; j++)
+    {
+      hessian_[i][j] = 0.0;
+    }
+    hessian_[i][i] = 1.0;
+  }
+
+
+  double sum = 0;
+  for (size_t i = 0; i < nbParams; i++)
+  {
+    sum += p_[i] * p_[i];
+  }
+}
+
+/******************************************************************************/
+
+double BfgsMultiDimensions::doStep() throw (Exception)
+{
+  double f;
+  size_t n = getParameters().size();
+  // Loop over iterations.
+
+  unsigned int i;
+
+  for (i = 0; i < n; i++)
+  {
+    p_[i] = getParameters()[i].getValue();
+  }
+
+  setDirection();
+
+  getFunction()->enableFirstOrderDerivatives(false);
+  nbEval_ += OneDimensionOptimizationTools::lineSearch(f1dim_,
+                                                       getParameters_(), xi_,
+                                                       gradient_,
+                                                       // getStopCondition()->getTolerance(),
+                                                       0, 0,
+                                                       getVerbose() > 0 ? getVerbose() - 1 : 0);
+  getFunction()->enableFirstOrderDerivatives(true);
+
+  for (i = 0; i < n; i++)
+  {
+    xi_[i] = getParameters_()[i].getValue() - p_[i];
+  }
+
+  f = getFunction()->f(getParameters());
+  if (f > currentValue_) {
+    printMessage("!!! Function increase !!!");
+    printMessage("!!! Optimization might have failed. Try to reparametrize your function to remove constraints.");
+    tolIsReached_ = true;
+    return f;
+  }
+
+  if (tolIsReached_)
+  {
+    return f;
+  }
+
+  //double temp, test = 0.0;
+  //for (i = 0; i < n; i++)
+  //{
+  //  temp = xi_[i];
+  //  if (p_[i] > 1.0)
+  //    temp /= p_[i];
+  //  if (temp > test)
+  //    test = temp;
+  //}
+
+  //if (test < 1e-7)
+  //{
+  //  tolIsReached_ = true;
+  //  return f;
+  //}
+
+  for (i = 0; i < n; i++)
+  {
+    dg_[i] = gradient_[i];
+  }
+
+  getGradient(gradient_);
+  //test = 0.0;
+
+  //for (i = 0; i < n; i++)
+  //{
+  //  temp = abs(gradient_[i]);
+  //  if (abs(p_[i]) > 1.0)
+  //    temp /= p_[i];
+  //  if (temp > test)
+  //    test = temp;
+  //}
+
+  //if (f > 1.0)
+  //  test /= f;
+
+  //if (test < gtol_)
+  //{
+  //  tolIsReached_ = true;
+  //  return f;
+  //}
+
+  for (i = 0; i < n; i++)
+  {
+    dg_[i] = gradient_[i] - dg_[i];
+  }
+
+  for (i = 0; i < n; i++)
+  {
+    hdg_[i] = 0;
+    for (unsigned int j = 0; j < n; j++)
+    {
+      hdg_[i] += hessian_[i][j] * dg_[j];
+    }
+  }
+
+  double fae(0), fac(0), sumdg(0), sumxi(0);
+
+  for (i = 0; i < n; i++)
+  {
+    fac += dg_[i] * xi_[i];
+    fae += dg_[i] * hdg_[i];
+    sumdg += dg_[i] * dg_[i];
+    sumxi += xi_[i] * xi_[i];
+  }
+
+  if (fac > sqrt(1e-7 * sumdg * sumxi))
+  {
+    fac = 1.0 / fac;
+    double fad = 1.0 / fae;
+    for (i = 0; i < n; i++)
+    {
+      dg_[i] = fac * xi_[i] - fad * hdg_[i];
+    }
+    for (i = 0; i < n; i++)
+    {
+      for (unsigned int j = i; j < n; j++)
+      {
+        hessian_[i][j] += fac * xi_[i] * xi_[j] - fad * hdg_[i] * hdg_[j] + fae * dg_[i] * dg_[j];
+        hessian_[j][i] = hessian_[i][j];
+      }
+    }
+  }
+
+  return f;
+}
+
+/******************************************************************************/
+
+void BfgsMultiDimensions::getGradient(std::vector<double>& gradient) const
+{
+  for (unsigned int i = 0; i < gradient.size(); i++)
+  {
+    gradient[i] = getFunction()->getFirstOrderDerivative(getParameters()[i].getName());
+  }
+}
+
+/******************************************************************************/
+
+void BfgsMultiDimensions::setDirection()
+{
+  size_t nbParams = getParameters().size();
+
+  for (size_t i = 0; i < nbParams; i++)
+  {
+    xi_[i] = 0;
+    for (unsigned int j = 0; j < nbParams; j++)
+    {
+      xi_[i] -= hessian_[i][j] * gradient_[j];
+    }
+  }
+
+  double v = 1, alpmax = 1;
+  for (size_t i = 0; i < nbParams; i++)
+  {
+    if ((xi_[i] > 0) && (p_[i] + NumConstants::TINY() * xi_[i] < Up_[i]))
+      v = (Up_[i] - p_[i]) / xi_[i];
+    else if ((xi_[i] < 0) && (p_[i] + NumConstants::TINY() * xi_[i] > Lo_[i]))
+      v = (Lo_[i] - p_[i]) / xi_[i];
+    if (v < alpmax)
+      alpmax = v;
+  }
+
+  for (size_t i = 0; i < nbParams; i++)
+  {
+    if (p_[i] + NumConstants::TINY() * xi_[i] >= Up_[i])
+      xi_[i] = Up_[i] - p_[i];
+    else if (p_[i] + NumConstants::TINY() * xi_[i] <= Lo_[i])
+      xi_[i] = Lo_[i] - p_[i];
+    else
+      xi_[i] *= alpmax;
+  }
+}
diff --git a/src/Bpp/Numeric/Function/BfgsMultiDimensions.h b/src/Bpp/Numeric/Function/BfgsMultiDimensions.h
new file mode 100644
index 0000000..ab8c7c7
--- /dev/null
+++ b/src/Bpp/Numeric/Function/BfgsMultiDimensions.h
@@ -0,0 +1,123 @@
+//
+// File: BfgsMultiDimensions.h
+// Created by: Laurent Guéguen
+// Created on: Dec 16 13:49 2010
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BFGSMULTIDIMENSIONS_H_
+#define _BFGSMULTIDIMENSIONS_H_
+
+#include "AbstractOptimizer.h"
+#include "DirectionFunction.h"
+#include "../VectorTools.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Broyden–Fletcher–Goldfarb–Shanno (BFGS) optimization method.
+   *
+   * with a modification on the bounds taken from:
+   *  An active set limited memory BFGS algorithm for large-scale bound
+   *    constrained optimization, Yunhai Xiao & Dong-Hui Li. Math Meth
+   *    Oper Res (2008) 67:443­454
+   */
+  
+  class BfgsMultiDimensions:
+    public AbstractOptimizer
+  {
+  protected:
+    //double gtol_;
+    double slope_;
+
+    // vectors of the Lower & Upper bounds of the parameters
+    Vdouble Up_, Lo_;
+
+    mutable Vdouble p_, gradient_, xi_, dg_, hdg_;
+    mutable VVdouble hessian_;
+
+    mutable DirectionFunction f1dim_;
+
+    
+  public:
+
+    BfgsMultiDimensions(DerivableFirstOrder* function);
+
+    virtual ~BfgsMultiDimensions() {}
+
+    BfgsMultiDimensions* clone() const { return new BfgsMultiDimensions(*this); }
+
+  public:
+
+    /**
+     * @name From AbstractOptimizer.
+     *
+     * @{
+     */
+    const DerivableFirstOrder* getFunction() const
+    {
+      return dynamic_cast<const DerivableFirstOrder*>(AbstractOptimizer::getFunction());
+    }
+    DerivableFirstOrder* getFunction()
+    {
+      return dynamic_cast<DerivableFirstOrder*>(AbstractOptimizer::getFunction());
+    }
+    void doInit(const ParameterList& params) throw (Exception);
+
+    double doStep() throw (Exception);
+    /** @} */
+
+    void getGradient(std::vector<double>& gradient) const;
+
+  protected:
+    DerivableFirstOrder* getFunction_()
+    {
+      return dynamic_cast<DerivableFirstOrder*>(AbstractOptimizer::getFunction_());
+    }
+
+  private:
+    /**
+     * Sets the direction for linesearch in case of bounds
+     * To be used after gradient_ & pi_ are computed
+     */ 
+    void setDirection();
+    
+  };
+
+} //end of namespace bpp.
+
+#endif //_BFGSMULTIDIMENSIONS_H_
+
diff --git a/src/Bpp/Numeric/Function/BrentOneDimension.cpp b/src/Bpp/Numeric/Function/BrentOneDimension.cpp
new file mode 100644
index 0000000..6321268
--- /dev/null
+++ b/src/Bpp/Numeric/Function/BrentOneDimension.cpp
@@ -0,0 +1,214 @@
+//
+// File: BrentOneDimension.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Nov 17 11:45:58 2003
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "BrentOneDimension.h"
+#include "OneDimensionOptimizationTools.h"
+#include "../NumTools.h"
+#include "../NumConstants.h"
+#include "../../Text/TextTools.h"
+
+using namespace bpp;
+
+/******************************************************************************/
+
+bool BrentOneDimension::BODStopCondition::isToleranceReached() const
+{
+  callCount_++;
+  if (callCount_ <= burnin_) return false;
+  const BrentOneDimension* bod = dynamic_cast<const BrentOneDimension *>(optimizer_);
+  return getCurrentTolerance() <= (bod->tol2 - 0.5 * (bod->b - bod->a));
+}
+    
+/******************************************************************************/
+
+double BrentOneDimension::BODStopCondition::getCurrentTolerance() const
+{
+  // NRC Test for done:
+  const BrentOneDimension* bod = dynamic_cast<const BrentOneDimension *>(optimizer_);
+  return NumTools::abs(bod->x - bod->xm);
+}
+ 
+/******************************************************************************/
+
+BrentOneDimension::BrentOneDimension(Function* function) :
+  AbstractOptimizer(function),
+  a(0), b(0), d(0), e(0), etemp(0), fu(0), fv(0), fw(0), fx(0), p(0), q(0), r(0), tol1(0), tol2(0),
+  u(0), v(0), w(0), x(0), xm(0), _xinf(0), _xsup(0), isInitialIntervalSet_(false)
+{
+  setDefaultStopCondition_(new BODStopCondition(this));
+  setStopCondition(*getDefaultStopCondition());
+  setMaximumNumberOfEvaluations(10000);
+}
+
+/******************************************************************************/
+  
+double BrentOneDimension::ZEPS  = 1.0e-10;
+  
+/******************************************************************************/
+  
+void BrentOneDimension::doInit(const ParameterList& params) throw (Exception)
+{
+  if (params.size() != 1)
+    throw Exception("BrentOneDimension::init(). This optimizer only deals with one parameter.");
+
+  // Bracket the minimum.
+  Bracket bracket = OneDimensionOptimizationTools::bracketMinimum(_xinf, _xsup, getFunction(), getParameters());
+  if (getVerbose() > 0)
+  {
+    printMessage("Initial bracketing:");
+    printMessage("A: x = " + TextTools::toString(bracket.a.x) + ", f = " + TextTools::toString(bracket.a.f));
+    printMessage("B: x = " + TextTools::toString(bracket.b.x) + ", f = " + TextTools::toString(bracket.b.f));
+    printMessage("C: x = " + TextTools::toString(bracket.c.x) + ", f = " + TextTools::toString(bracket.c.f));
+  }
+  
+  // This will be the distance moved on the step before last.
+  e = 0.0;
+
+  // a and b must be in ascending order, but input abscissa need not be.
+  a = (bracket.a.x < bracket.c.x ? bracket.a.x : bracket.c.x);
+  b = (bracket.a.x > bracket.c.x ? bracket.a.x : bracket.c.x);
+  // Initializations...
+  fw = fv = fx = getFunction()->f(getParameters());
+  if (fx < bracket.b.f)
+  {
+    //We don't want to lose our initial guess!
+    x = w = v = bracket.b.x = getParameters()[0].getValue();
+  }
+  else
+  {
+    x = w = v = bracket.b.x;
+    getParameter_(0).setValue(x);
+    fw = fv = fx = getFunction()->f(getParameters());
+  }
+}
+
+/******************************************************************************/
+  
+void BrentOneDimension::setInitialInterval(double inf, double sup)
+{
+  if(sup > inf)
+  {
+    _xinf = inf; _xsup = sup;
+  }
+  else
+  {
+    _xinf = sup; _xsup = inf;
+  }
+  isInitialIntervalSet_ = true;
+}
+
+/******************************************************************************/
+
+double BrentOneDimension::doStep() throw (Exception)
+{
+  xm   = 0.5 * (a + b);
+  tol2 = 2.0 * (tol1 = getStopCondition()->getTolerance() * NumTools::abs(x) + ZEPS);
+  
+  if(NumTools::abs(e) > tol1)
+  {
+    r = (x - w) * (fx - fv);
+    q = (x - v) * (fx - fw);
+    p = (x - v) * q - (x - w) * r;
+    q = 2.0 * (q - r);
+    if (q > 0.0) p = -p;
+    q = NumTools::abs(q);
+    etemp = e;
+    e = d;
+    if (NumTools::abs(p) >= NumTools::abs(0.5 * q * etemp) || p <= q * (a - x) || p >= q * (b - x))
+      d = NumConstants::GOLDEN_RATIO_C() * (e = (x >= xm ? a - x : b - x));
+    else
+    {
+      d = p / q;
+      u = x + d;
+      if (u - a < tol2 || b - u < tol2)
+        d = NumTools::sign(tol1, xm - x);
+    }
+  }
+  else
+  {
+    d = NumConstants::GOLDEN_RATIO_C() * (e = (x >= xm ? a - x : b - x));
+  }
+  u = (NumTools::abs(d) >= tol1 ? x + d : x + NumTools::sign(tol1, d));
+
+  // Function evaluaton:
+  ParameterList pl = getParameters();
+  pl[0].setValue(u);
+  fu = getFunction()->f(pl);
+  if (fu <= fx)
+  {
+    if (u >= x) a = x; else b = x;
+    NumTools::shift(v, w, x, u);
+    NumTools::shift(fv, fw, fx, fu);
+  }
+  else
+  {
+    if (u < x) a = u; else b = u;
+    if (fu <= fw || w == x)
+    {
+      v  = w;
+      w  = u;
+      fv = fw;
+      fw = fu;
+    }
+    else if (fu <= fv || v == x || v == w)
+    {
+      v  = u;
+      fv = fu;
+    }
+  }
+
+  // Store results for this step:
+  getParameter_(0).setValue(x);
+  return fx;
+}
+
+/******************************************************************************/
+  
+double BrentOneDimension::optimize() throw (Exception)
+{
+  if (!isInitialIntervalSet_)
+    throw Exception("BrentOneDimension::optimize. Initial interval not set: call the 'setInitialInterval' method first!");
+  AbstractOptimizer::optimize();
+  // Apply parameters and evaluate function at minimum point:
+  currentValue_ = getFunction()->f(getParameters());
+  return currentValue_;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/BrentOneDimension.h b/src/Bpp/Numeric/Function/BrentOneDimension.h
new file mode 100644
index 0000000..21250e6
--- /dev/null
+++ b/src/Bpp/Numeric/Function/BrentOneDimension.h
@@ -0,0 +1,150 @@
+//
+// File: BrentOneDimension.h
+// Created by: Julien Dutheil
+// Created on: Mon Nov 17 11:45:58 2003
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BRENTONEDIMENSION_H_
+#define _BRENTONEDIMENSION_H_
+
+#include "AbstractOptimizer.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Brent's optimization for one parameter.
+ *
+ * A description of the algorithm can be found in:
+ * <pre>
+ * NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING
+ * (ISBN 0-521-43108-5)
+ * </pre>
+ * or there: <a href="http://en.wikipedia.org/wiki/Brent's_method">http://en.wikipedia.org/wiki/Brent's_method</a>.
+ */
+class BrentOneDimension:
+  public AbstractOptimizer
+{
+	public:
+		class BODStopCondition:
+      public AbstractOptimizationStopCondition
+		{
+      public:
+				BODStopCondition(BrentOneDimension* bod):
+          AbstractOptimizationStopCondition(bod) {
+            tolerance_ = bod->tol2;
+            burnin_ = 3;
+          }
+				virtual ~BODStopCondition() {}
+
+        BODStopCondition* clone() const { return new BODStopCondition(*this); } 
+			
+			public:
+				bool isToleranceReached() const;
+				double getCurrentTolerance() const;
+		};
+	
+	friend class BODStopCondition;
+	
+	protected:
+		double a, b, d, e, etemp, fu, fv, fw, fx, p, q, r, tol1, tol2, u, v, w, x, xm;
+		double _xinf, _xsup;
+    bool isInitialIntervalSet_;
+
+	public:
+		BrentOneDimension(Function* function = 0);
+		virtual ~BrentOneDimension() {}
+
+    BrentOneDimension* clone() const { return new BrentOneDimension(*this); }
+	
+	public:		
+		
+		/**
+		 * @name The Optimizer interface.
+		 *
+		 * @{
+		 */
+		
+		/**
+		 * @brief Initialize optimizer.
+		 *
+		 * Brent's algorithm needs 2 initial guesses, so you must call the
+		 * setInitialInterval() method first. This function actually performs:
+     * <ul>
+		 * <li>Parameter list actualisation;</li>
+		 * <li>Initial bracketting;</li>
+		 * <li>Function evaluation count reseting.</li>
+     * </ul>
+		 */
+    double optimize() throw (Exception); //redefinition
+		/** @} */
+		
+    void doInit(const ParameterList& params) throw (Exception);
+		
+    double doStep() throw (Exception);
+	
+	public:
+
+		/**
+		 * @name Specific method
+		 *
+		 * @{
+		 */
+		
+		/**
+		 * @brief Set intial search interval.
+		 *
+		 * @param inf Minimum value.
+		 * @param sup Maximum value.
+		 */
+		void setInitialInterval(double inf, double sup);
+		/** @} */
+
+    /**
+     * @return 'true' if the initial interval has been correctly set.
+     */
+    bool isInitialIntervalSet() const { return isInitialIntervalSet_; }
+	
+	public:
+		
+	static double ZEPS;
+
+};
+
+} //end of namespace bpp.
+
+#endif	//_BRENTONEDIMENSION_H_
+
diff --git a/src/Bpp/Numeric/Function/ConjugateGradientMultiDimensions.cpp b/src/Bpp/Numeric/Function/ConjugateGradientMultiDimensions.cpp
new file mode 100644
index 0000000..7e455ac
--- /dev/null
+++ b/src/Bpp/Numeric/Function/ConjugateGradientMultiDimensions.cpp
@@ -0,0 +1,124 @@
+//
+// File: ConjugateGradientMultiDimensions.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Apr 11 16:51 2007
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "ConjugateGradientMultiDimensions.h"
+#include "OneDimensionOptimizationTools.h"
+
+using namespace bpp;
+
+/******************************************************************************/
+
+ConjugateGradientMultiDimensions::ConjugateGradientMultiDimensions(DerivableFirstOrder* function):
+  AbstractOptimizer(function), optimizer_(function),
+  xi_(), h_(), g_(), f1dim_(function)
+{
+  setDefaultStopCondition_(new FunctionStopCondition(this));
+  setStopCondition(*getDefaultStopCondition());
+}
+
+/******************************************************************************/
+
+void ConjugateGradientMultiDimensions::doInit(const ParameterList & params) throw (Exception)
+{
+  size_t nbParams = params.size();
+  g_.resize(nbParams);
+  h_.resize(nbParams);
+  xi_.resize(nbParams);
+  getFunction_()->enableFirstOrderDerivatives(true);
+  getFunction_()->setParameters(params);
+  getGradient(xi_);
+  for(size_t i = 0; i < nbParams; i++)
+  {
+    g_[i]  = -xi_[i];
+    xi_[i] = h_[i] = g_[i];
+  }
+}
+
+/******************************************************************************/
+
+double ConjugateGradientMultiDimensions::doStep() throw (Exception)
+{
+  double gg, gam, f, dgg;
+  size_t n = getParameters().size();
+  //Loop over iterations.
+  getFunction_()->enableFirstOrderDerivatives(false);
+  nbEval_ += OneDimensionOptimizationTools::lineMinimization(f1dim_,
+      getParameters_(), xi_, getStopCondition()->getTolerance(),
+      0, 0, getVerbose() > 0 ? getVerbose() - 1 : 0);
+  getFunction_()->enableFirstOrderDerivatives(true);
+  f = getFunction()->f(getParameters());
+  if (tolIsReached_)
+  {
+    return f;
+  }
+  getGradient(xi_);
+  dgg = gg = 0.0;
+  for (unsigned j = 0; j < n; j++)
+  {
+    gg += g_[j] * g_[j];
+    /* dgg += xi[j] * xi[j]; */ //This statement for Fletcher-Reeves.
+    dgg += (xi_[j] + g_[j]) * xi_[j]; //This statement for Polak-Ribiere.
+  }
+  if (gg == 0.0)
+  { 
+    //Unlikely. If gradient is exactly zero then
+    return f;
+  }
+  gam = dgg / gg;
+  for(unsigned int j = 0; j < n; j++)
+  {
+    g_[j] = -xi_[j];
+    xi_[j] = h_[j] = g_[j] + gam * h_[j];
+  }
+  
+  return f;
+}
+
+/******************************************************************************/
+
+void ConjugateGradientMultiDimensions::getGradient(std::vector<double>& gradient) const
+{
+  for (size_t i = 0; i < gradient.size(); ++i)
+  {
+    gradient[i] = getFunction()->getFirstOrderDerivative(getParameters()[i].getName());
+  }
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/ConjugateGradientMultiDimensions.h b/src/Bpp/Numeric/Function/ConjugateGradientMultiDimensions.h
new file mode 100644
index 0000000..3c1925d
--- /dev/null
+++ b/src/Bpp/Numeric/Function/ConjugateGradientMultiDimensions.h
@@ -0,0 +1,110 @@
+//
+// File: ConjugateGradientMultiDimensions.h
+// Created by: Julien Dutheil
+// Created on: Wed Apr 11 16:51 2007
+//
+
+/*
+  Copyright or © or Copr. CNRS, (November 19, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _CONJUGATEGRADIENTMULTIDIMENSIONS_H_
+#define _CONJUGATEGRADIENTMULTIDIMENSIONS_H_
+
+#include "AbstractOptimizer.h"
+#include "BrentOneDimension.h"
+#include "DirectionFunction.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Conjugate gradient optimization method.
+   *
+   * A description of the algorithm can be found in:
+   * <pre>
+   * NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING
+   * (ISBN 0-521-43108-5)
+   * </pre>
+   * or there:
+   * <a href="http://en.wikipedia.org/wiki/Conjugate_gradient">http://en.wikipedia.org/wiki/Conjugate_gradient</a>.
+   */
+  class ConjugateGradientMultiDimensions:
+    public AbstractOptimizer
+  {
+  protected:
+    BrentOneDimension optimizer_; //One dimensional optimizer.
+    std::vector<double> xi_, h_, g_;
+    DirectionFunction f1dim_;
+
+  public:
+
+    ConjugateGradientMultiDimensions(DerivableFirstOrder* function);
+
+    virtual ~ConjugateGradientMultiDimensions() {}
+
+    ConjugateGradientMultiDimensions* clone() const { return new ConjugateGradientMultiDimensions(*this); }
+
+  public:
+
+    /**
+     * @name From AbstractOptimizer.
+     *
+     * @{
+     */
+    const DerivableFirstOrder* getFunction() const
+    {
+      return dynamic_cast<const DerivableFirstOrder*>(AbstractOptimizer::getFunction());
+    }
+    DerivableFirstOrder* getFunction()
+    {
+      return dynamic_cast<DerivableFirstOrder*>(AbstractOptimizer::getFunction());
+    }
+    void doInit(const ParameterList& params) throw (Exception);
+
+    double doStep() throw (Exception);
+    /** @} */
+
+    void getGradient(std::vector<double>& gradient) const;
+
+  protected:
+    DerivableFirstOrder* getFunction_()
+    {
+      return dynamic_cast<DerivableFirstOrder*>(AbstractOptimizer::getFunction_());
+    }
+    
+  };
+
+} //end of namespace bpp.
+
+#endif //_CONJUGATEGRADIENTMULTIDIMENSIONS_H_
+
diff --git a/src/Bpp/Numeric/Function/DirectionFunction.cpp b/src/Bpp/Numeric/Function/DirectionFunction.cpp
new file mode 100644
index 0000000..65828df
--- /dev/null
+++ b/src/Bpp/Numeric/Function/DirectionFunction.cpp
@@ -0,0 +1,109 @@
+//
+// File: DirectionFunction.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Apr 11 17:28 2007
+// From file PowellMultiDimensions.cpp
+//
+
+/*
+  Copyright or © or Copr. CNRS, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for phylogenetic data analysis.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "DirectionFunction.h"
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+
+void DirectionFunction::setParameters(const ParameterList & params)
+  throw (ParameterNotFoundException, ConstraintException)
+{
+  params_ = params;
+  double x = params_[0].getValue();
+  for(unsigned int j = 0; j < p_.size(); j++)
+    {
+      //      cout << p_[j].getValue() << " " << x << " " << xi_[j] << endl;
+      xt_[j].setValue((p_[j].getValue()) + x * xi_[j]);
+    }
+  function_->setParameters(xt_);
+}
+
+/******************************************************************************/
+
+double DirectionFunction::getValue() const throw (Exception)
+{
+  return function_->getValue();
+}
+
+/******************************************************************************/
+
+const ParameterList & DirectionFunction::getParameters() const throw (Exception)
+{
+  return params_;
+}
+
+/******************************************************************************/
+
+void DirectionFunction::init(const ParameterList & p, const vector<double> & xi)
+{
+  p_ = p;
+  xi_ = xi;
+  if(constraintPolicy_ == AutoParameter::CONSTRAINTS_AUTO)   autoParameter();
+  else if(constraintPolicy_ == AutoParameter::CONSTRAINTS_IGNORE) ignoreConstraints();
+  xt_ = p_;
+}
+
+/******************************************************************************/
+
+void DirectionFunction::autoParameter()
+{
+  for(unsigned int i = 0; i < p_.size(); i++)
+    {
+      AutoParameter ap(p_[i]);
+      ap.setMessageHandler(messenger_);
+      p_.setParameter(i, ap);
+    }
+}
+
+/******************************************************************************/
+
+void DirectionFunction::ignoreConstraints()
+{
+  for(unsigned int i = 0; i < p_.size(); i++)
+    {
+      p_[i].removeConstraint();
+    }
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/DirectionFunction.h b/src/Bpp/Numeric/Function/DirectionFunction.h
new file mode 100644
index 0000000..0363f60
--- /dev/null
+++ b/src/Bpp/Numeric/Function/DirectionFunction.h
@@ -0,0 +1,116 @@
+//
+// File: DirectionFunction.h
+// Created by: Julien Dutheil
+// Created on: Wed Apr 11 17:28 2007
+// From file PowellMultiDimensions.h
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _DIRECTIONFUNCTION_H_
+#define _DIRECTIONFUNCTION_H_
+
+#include "Functions.h"
+#include "../Parametrizable.h"
+#include "../AutoParameter.h"
+#include "../../App/ApplicationTools.h"
+#include "../../Io/OutputStream.h"
+
+namespace bpp
+{
+
+class DirectionFunction:
+  public Function,
+  public ParametrizableAdapter
+{
+  private:
+    mutable ParameterList params_, p_, xt_;
+    std::vector<double> xi_;
+    Function* function_;
+    std::string constraintPolicy_;
+    OutputStream* messenger_;
+      
+  public:
+    DirectionFunction(Function* function = 0) :
+      params_(), p_(), xt_(), xi_(),
+      function_(function), constraintPolicy_(AutoParameter::CONSTRAINTS_KEEP),
+      messenger_(ApplicationTools::message) {}
+
+    DirectionFunction(const DirectionFunction& df) :
+      ParametrizableAdapter(df), params_(df.params_), p_(df.p_), xt_(df.p_), xi_(df.xi_),
+      function_(df.function_), constraintPolicy_(df.constraintPolicy_), messenger_(df.messenger_) {}
+
+    DirectionFunction& operator=(const DirectionFunction& df)
+    {
+      ParametrizableAdapter::operator=(df);
+      params_ = df.params_;
+      p_ = df.p_;
+      xt_ = df.p_;
+      xi_ = df.xi_;
+      function_ = df.function_;
+      constraintPolicy_ = df.constraintPolicy_;
+      messenger_ = df.messenger_;
+      return *this;
+    }
+
+    virtual ~DirectionFunction() {}
+
+    DirectionFunction* clone() const { return new DirectionFunction(*this); }
+
+  public: // Function interface implementation:
+    void setParameters(const ParameterList& parameters)
+      throw (ParameterNotFoundException, ConstraintException);
+    double getValue() const throw (Exception);
+    const ParameterList & getParameters() const throw (Exception);
+
+  public: // Specific methods:
+    void init(const ParameterList & p, const std::vector<double> & xi);
+    void autoParameter();
+    void ignoreConstraints();
+    void setConstraintPolicy(const std::string & constraintPolicy) { constraintPolicy_ = constraintPolicy; }
+    std::string getConstraintPolicy() const { return constraintPolicy_; }
+    void setMessageHandler(OutputStream* messenger) { messenger_ = messenger; }
+    Function * getFunction() const { return function_; }
+    /**
+     * @return The set of parameters associated to the function, as specified by the init() method.
+     */
+    ParameterList getFunctionParameters() const { return p_; }
+    size_t getNumberOfParameters() const { return p_.size(); }
+
+};
+
+} //end of namespace bpp.
+
+#endif //_DIRECTIONFUNCTION_H_
+
diff --git a/src/Bpp/Numeric/Function/DownhillSimplexMethod.cpp b/src/Bpp/Numeric/Function/DownhillSimplexMethod.cpp
new file mode 100644
index 0000000..b6df0d9
--- /dev/null
+++ b/src/Bpp/Numeric/Function/DownhillSimplexMethod.cpp
@@ -0,0 +1,243 @@
+//
+// File: DownhillSimplexMethod.cpp
+// Created by: Julien Dutheil
+// Created on: Tue Nov  4 17:10:05 2003
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "DownhillSimplexMethod.h"
+#include "../NumTools.h"
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+
+double DownhillSimplexMethod::DSMStopCondition::getCurrentTolerance() const
+{
+	const DownhillSimplexMethod* dsm = dynamic_cast<const DownhillSimplexMethod *>(optimizer_);
+	double rTol = 2.0 * NumTools::abs(dsm->y_[dsm->iHighest_] - dsm->y_[dsm->iLowest_]) /
+		(NumTools::abs(dsm->y_[dsm->iHighest_]) + NumTools::abs(dsm->y_[dsm->iLowest_]));
+	return rTol;
+}
+	
+/******************************************************************************/
+			
+DownhillSimplexMethod::DownhillSimplexMethod(Function* function):
+  AbstractOptimizer(function), simplex_(), y_(), pSum_(), iHighest_(0), iNextHighest_(0), iLowest_(0)
+{
+	// Default values:
+	nbEvalMax_ = 5000;
+	setDefaultStopCondition_(new DSMStopCondition(this));
+	setStopCondition(*getDefaultStopCondition());
+}
+
+/******************************************************************************/
+
+void DownhillSimplexMethod::doInit(const ParameterList& params) throw (Exception)
+{
+	size_t nDim = getParameters().size();
+	nbEval_ = 0;
+
+	// Initialize the simplex:
+	simplex_.resize(nDim + 1);
+	y_.resize(nDim + 1);
+	double lambda = 0.2; //20% of the parameter value.
+  for(unsigned int i = 1; i < nDim + 1; i++)
+  {
+		// Copy the vector...
+		simplex_[i] = getParameters();
+		// ... and set the initial values.
+		for(unsigned int j = 0; j < nDim; j++)
+    {
+      //Hummm... that does not work when the first point is 0!!! where does this come from???
+			//simplex_[i][j].setValue(getParameters()[j].getValue() * (1. + (j == i - 1 ? lambda : 0.)));
+			simplex_[i][j].setValue(getParameters()[j].getValue() + (j == i - 1 ? lambda : 0.));
+    }
+		//Compute the corresponding f value:
+		y_[i] = getFunction()->f(simplex_[i]);
+    nbEval_++;
+	}
+  //Last function evaluation, setting current value:
+	simplex_[0] = getParameters();
+	y_[0] = getFunction()->f(simplex_[0]);
+  nbEval_++;
+	
+	pSum_ = getPSum();
+}
+	
+/******************************************************************************/
+
+double DownhillSimplexMethod::doStep() throw (Exception)
+{
+	// The number of dimensions of the parameter space:
+	size_t nDim = simplex_.getDimension();
+	size_t mpts = nDim + 1;
+
+	iLowest_ = 0;
+	// First we must determine which point is the highest (worst),
+	// next-highest, and lowest (best), by looping over the points
+	// in the simplex.
+	if(y_[0] > y_[1])
+  {
+		iHighest_ = 0;
+		iNextHighest_ = 1;
+	}
+  else
+  {
+		iHighest_ = 1;
+		iNextHighest_ = 0;
+	}
+	
+	for(unsigned int i = 0; i < mpts; i++)
+  {
+		if (y_[i] <= y_[iLowest_]) iLowest_ = i;
+		if (y_[i] > y_[iHighest_])
+    {
+			iNextHighest_ = iHighest_;
+			iHighest_ = i;
+		}
+    else if(y_[i] > y_[iNextHighest_] && i != iHighest_) iNextHighest_ = i;
+	}
+		
+  // Set current best point:
+	getParameters_() = simplex_[iLowest_];
+		
+	// Begin a new iteration.
+	// First extrapolate by a factor -1 through the face of the simplex
+	// across from high point, i.e., reflect the simplex from the high point.</p>
+
+	double yTry = tryExtrapolation(-1.0);
+	if (yTry <= y_[iLowest_])
+  {
+		// Expansion.
+		yTry = tryExtrapolation(2.0);
+	}
+  else if (yTry >= y_[iNextHighest_])
+  {
+		// Contraction.
+		double ySave = y_[iHighest_];
+		yTry = tryExtrapolation(0.5);
+		if (yTry >= ySave)
+    {
+			for (size_t i = 0; i < mpts; i++)
+      {
+				if (i != iLowest_)
+        {
+					for (size_t j = 0; j < nDim; j++)
+          {
+						pSum_[j].setValue(0.5 * (simplex_[i][j].getValue() + simplex_[iLowest_][j].getValue()));
+						simplex_[i][j].setValue(pSum_[j].getValue());
+					}
+					y_[i] = getFunction()->f(pSum_);
+	        nbEval_++;
+				}
+			}
+			nbEval_ += static_cast<unsigned int>(nDim);
+			pSum_ = getPSum();
+		}
+	}
+
+	return y_[iLowest_];
+}
+
+/******************************************************************************/
+
+double DownhillSimplexMethod::optimize() throw (Exception)
+{
+  AbstractOptimizer::optimize();
+
+	// set best shot:
+	return getFunction()->f(simplex_[iLowest_]);
+}
+
+/******************************************************************************/
+
+ParameterList DownhillSimplexMethod::getPSum()
+{
+	size_t ndim = simplex_.getDimension();
+	size_t mpts = ndim + 1;
+	
+	// Get a copy...
+	ParameterList pSum = getParameters();
+	// ... and initializes it.
+	for (size_t j = 0; j < ndim; j++)
+  {
+		double sum = 0.;
+		for (size_t i = 0; i < mpts; i++)
+    {
+			sum += simplex_[i][j].getValue();
+		}
+		pSum[j].setValue(sum);
+	}
+	return pSum;
+}
+
+/******************************************************************************/
+
+double DownhillSimplexMethod::tryExtrapolation(double fac)
+{
+	size_t ndim = simplex_.getDimension();
+	double fac1, fac2, yTry;
+
+	fac1 = (1.0 - fac) / static_cast<double>(ndim);
+	fac2 = fac1 - fac;
+	
+	// Get a copy...
+	ParameterList pTry = getParameters();
+	// and initialize it:
+	for (size_t j = 0; j < ndim; j++)
+  {
+		pTry[j].setValue(pSum_[j].getValue() * fac1 - simplex_[iHighest_][j].getValue() * fac2);
+	}
+	// Now compute the function for this new set of parameters:
+	yTry = getFunction()->f(pTry);
+  nbEval_++;
+	
+	// Then test this new point:
+	if (yTry < y_[iHighest_])
+  {
+		y_[iHighest_] = yTry;
+		for (size_t j = 0; j < ndim; j++)
+    {
+			pSum_[j].setValue(pSum_[j].getValue() + pTry[j].getValue() - simplex_[iHighest_][j].getValue());
+			simplex_[iHighest_][j].setValue(pTry[j].getValue());
+		}
+	}
+	return yTry;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/DownhillSimplexMethod.h b/src/Bpp/Numeric/Function/DownhillSimplexMethod.h
new file mode 100644
index 0000000..f9b7671
--- /dev/null
+++ b/src/Bpp/Numeric/Function/DownhillSimplexMethod.h
@@ -0,0 +1,171 @@
+//
+// File: DownhillSimplexMethod.h
+// Created by: Julien Dutheil
+// Created on: Tue Nov  4 17:10:05 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _DOWNHILLSIMPLEXMETHOD_H_
+#define _DOWNHILLSIMPLEXMETHOD_H_
+
+#include "AbstractOptimizer.h"
+#include "../VectorTools.h"
+
+// From the STL:
+#include <cmath>
+
+namespace bpp
+{
+
+/**
+ * @brief This implements the Downhill Simplex method in multidimensions.
+ *
+ * A description of the algorithm can be found in:
+ * <pre>
+ * NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING
+ * (ISBN 0-521-43108-5)
+ * </pre>
+ * or there:
+ * <a href="http://en.wikipedia.org/wiki/Nelder-Mead_method">http://en.wikipedia.org/wiki/Nelder-Mead_method</a>.
+ */
+class DownhillSimplexMethod:
+  public AbstractOptimizer
+{
+  public:
+    class DSMStopCondition:
+      public AbstractOptimizationStopCondition
+    {
+      public:
+        DSMStopCondition(DownhillSimplexMethod * dsm):
+          AbstractOptimizationStopCondition(dsm) {}
+        virtual ~DSMStopCondition() {}
+
+        DSMStopCondition* clone() const { return new DSMStopCondition(*this); }
+      
+      public:
+        bool isToleranceReached() const { return (getCurrentTolerance() < tolerance_); }
+        double getCurrentTolerance() const;
+    };
+  
+  friend class DSMStopCondition;
+  
+  private:
+    class Simplex
+    {
+      private:
+        std::vector<ParameterList> parameters_;
+
+      public: // Class constructor and destructor:
+        Simplex(): parameters_() {}
+        virtual ~Simplex() {}
+      
+      public: // Methods:
+        const ParameterList& operator[](size_t i) const { return parameters_[i]; }
+        ParameterList& operator[](size_t i) { return parameters_[i]; }
+        void resize(size_t size) { parameters_.resize(size); }
+        size_t getDimension() const { return parameters_[0].size(); }
+    };
+    
+  protected:
+    Simplex simplex_;
+    Vdouble y_;
+    ParameterList pSum_;
+    unsigned int iHighest_, iNextHighest_, iLowest_;
+  
+  public:
+
+    /**
+     * @brief Build a new Downhill Simplex optimizer.
+     *
+     * @param function A pointer toward an object implementing the Optimizable interface.
+     */
+    DownhillSimplexMethod(Function * function);
+  
+    virtual ~DownhillSimplexMethod() {}
+
+#ifndef NO_VIRTUAL_COV
+    DownhillSimplexMethod*
+#else 
+    Clonable*
+#endif
+    clone() const { return new DownhillSimplexMethod(*this); }
+  
+  public:    
+    /**
+     * @name The Optimizer interface.
+     *
+     * @{
+     */
+    
+    /**
+     * @brief Multidimensional minimization of the function function_ by the
+     * downhill simplex method of Nelder and Mead.
+     */
+    double optimize() throw (Exception);
+    /** @} */
+
+    void doInit(const ParameterList& params) throw (Exception);
+    
+    double doStep() throw (Exception);
+  
+  protected:
+    
+    /**
+     * @name Specific inner methods
+     *
+     * @{
+     */
+    
+    /**
+     * @brief Update the pSum_ variable.
+     */
+    ParameterList getPSum();
+  
+    /**
+     * @brief Extrapolates by a factor fac through the face of the simplex from the high point.
+     * Try the new point and replaces the high point if it is better.
+     *
+     * @param fac Extrapolation factor.
+     * @return The value of the function for the new point.
+     */
+    double tryExtrapolation(double fac);
+
+    /** @} */
+};
+
+} //end of namespace bpp.
+
+#endif  //_DOWNHILLSIMPLEXMETHOD_H_
+
diff --git a/src/Bpp/Numeric/Function/FivePointsNumericalDerivative.cpp b/src/Bpp/Numeric/Function/FivePointsNumericalDerivative.cpp
new file mode 100644
index 0000000..647ac90
--- /dev/null
+++ b/src/Bpp/Numeric/Function/FivePointsNumericalDerivative.cpp
@@ -0,0 +1,140 @@
+//
+// File: FivePointsNumericalDerivative.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Aug 17 15:00 2006
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "FivePointsNumericalDerivative.h"
+using namespace bpp;
+using namespace std;
+
+void FivePointsNumericalDerivative::updateDerivatives(const ParameterList parameters)
+throw (ParameterNotFoundException, ConstraintException)
+{
+  if (computeD1_ && variables_.size() > 0)
+  {
+    if (function1_) function1_->enableFirstOrderDerivatives(false);
+    if (function2_) function2_->enableSecondOrderDerivatives(false);
+    function_->setParameters(parameters);
+    f3_ = function_->getValue();
+    string lastVar;
+    bool functionChanged = false;
+    ParameterList p;
+    bool start = true;
+    for (unsigned int i = 0; i < variables_.size(); i++)
+    {
+      string var = variables_[i];
+      if (!parameters.hasParameter(var)) continue;
+      if (!start)
+      {
+        vector<string> vars(2);
+        vars[0] = var;
+        vars[1] = lastVar;
+        p = parameters.subList(vars);
+      }
+      else
+      {
+        p = parameters.subList(var);
+        start = true;
+      }
+      lastVar = var;
+      functionChanged = true;
+      double value = function_->getParameterValue(var);
+      double h = (1. + std::abs(value)) * h_;
+      //Compute four other points:
+      try
+      {
+        p[0].setValue(value - 2 * h);
+        function_->setParameters(p);
+        f1_ = function_->getValue();
+        try
+        {
+          p[0].setValue(value + 2 * h);
+          function_->setParameters(p);
+          f5_ = function_->getValue();
+          //No limit raised, use central approximation:
+          p[0].setValue(value - h);
+          function_->setParameters(p);
+          f2_ = function_->getValue();
+          p[0].setValue(value + h);
+          function_->setParameters(p);
+          f4_ = function_->getValue();
+          der1_[i] = (f1_ - 8. * f2_ + 8. * f4_ - f5_) / (12. * h);
+          der2_[i] = (-f1_ + 16. * f2_ - 30. * f3_ + 16. * f4_ - f5_) / (12. * h * h);
+        }
+        catch (ConstraintException& ce)
+        {
+          //Right limit raised, use backward approximation:
+          p[0].setValue(value - h);
+          function_->setParameters(p);
+          f2_ = function_->getValue();
+          p[0].setValue(value - 2 * h);
+          function_->setParameters(p);
+          f1_ = function_->getValue();
+          der1_[i] = (f3_ - f2_) / h;
+          der2_[i] = (f3_ - 2. * f2_ + f1_) / (h * h);
+        }
+      }
+      catch (ConstraintException& ce)
+      {
+        //Left limit raised, use forward approximation:
+        p[0].setValue(value + h);
+        function_->setParameters(p);
+        f4_ = function_->getValue();
+        p[0].setValue(value + 2 * h);
+        function_->setParameters(p);
+        f5_ = function_->getValue();
+        der1_[i] = (f4_ - f3_) / h;
+        der2_[i] = (f5_ - 2. * f4_ + f3_) / (h * h);
+      }
+    }
+    //Reset last parameter and compute analytical derivatives if any.
+    if (function1_) function1_->enableFirstOrderDerivatives(computeD1_);
+    if (function2_) function2_->enableSecondOrderDerivatives(computeD2_);
+    if (functionChanged)
+      function_->setParameters(parameters.subList(lastVar));
+  }
+  else
+  {
+    //Reset initial value and compute analytical derivatives if any.
+    if (function1_) function1_->enableFirstOrderDerivatives(computeD1_);
+    if (function2_) function2_->enableSecondOrderDerivatives(computeD2_);
+    function_->setParameters(parameters);
+    //Just in  case derivatives are not computed:
+    f3_ = function_->getValue();
+  }
+}
+
diff --git a/src/Bpp/Numeric/Function/FivePointsNumericalDerivative.h b/src/Bpp/Numeric/Function/FivePointsNumericalDerivative.h
new file mode 100644
index 0000000..77cb6f1
--- /dev/null
+++ b/src/Bpp/Numeric/Function/FivePointsNumericalDerivative.h
@@ -0,0 +1,125 @@
+//
+// File: FivePointsNumericalDerivative.h
+// Created by: Julien Dutheil
+// Created on: Thu Aug 17 15:00 2006
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _FIVEPOINTSNUMERICALDERIVATIVE_H_
+#define _FIVEPOINTSNUMERICALDERIVATIVE_H_
+
+#include "Functions.h"
+#include "AbstractNumericalDerivative.h"
+
+//From the STL:
+#include <map>
+#include <vector>
+#include <string>
+
+namespace bpp
+{
+
+/**
+ * @brief Five points numerical derivative function wrapper.
+ *
+ * Numerical derivatives use three points to compute the derivatives.
+ * @f$x_0 at f$ is the focus point, @f$x_{-2} = x_0-2h at f$, @f$x_{-1} = x_0-h at f$, @f$x_{+1}=x_0+h at f$ and @f$x_{+2} = x_0+2h at f$
+ * are other points, with function values @f$f_0 at f$, @f$f_{-2}@f$, @f$f_{-1}@f$, @f$f_{+1}@f$ and @f$f_{+2}@f$ respectively.
+ * The derivatives are then computed using the central formulas:
+ * @f{eqnarray*}
+ * \dfrac{\partial   f}{\partial x  } &=& \dfrac{f_{-2}-8f_{-1}+8f_{+1}-f_{+2}}{12h}\\
+ * \dfrac{\partial^2 f}{\partial x^2} &=& \dfrac{-f_{-2}+16f_{-1}-30f_0+16f_{+1}-f_{+2}}{12h^2}\\
+ * @f}
+ * In case of border limit (when @f$x_{-2}@f$ or @f$x_{+2}@f$ are not computable), 
+ * the foreward and backward three points computations are performed, respectively:
+ * @f{eqnarray*}
+ * \dfrac{\partial   f}{\partial x  } &=& \dfrac{f_{+1}-f_0}{h}\\
+ * \dfrac{\partial^2 f}{\partial x^2} &=& \dfrac{f_{+2}-2f_{+1}+f_0}{h^2}\\
+ * @f}
+ * and
+ * @f{eqnarray*}
+ * \dfrac{\partial   f}{\partial x  } &=& \dfrac{f_0-f_{-1}}{h}\\
+ * \dfrac{\partial^2 f}{\partial x^2} &=& \dfrac{f_0-2f_{-1}+f_{-2}}{h^2}\\
+ * @f}
+ *
+ * The @f$h at f$ parameter is computed in a parameter dependent manner:
+ * @f$ h = x \times e at f$, with @f$x \neq 0 at f$ being the current parameter value.
+ * If @f$x = 0 at f$, @f$h = e at f$.
+ * Default value is provided for @f$e at f$ and corresponds to the _h field.
+ * The default value works fine in most cases, but you may want to change it using the setInterval method.
+ *
+ * @warning cross second order derivatives are not implemented with the five points method.
+ * @see AbstractNumericalDerivative
+ */
+class FivePointsNumericalDerivative:
+  public AbstractNumericalDerivative
+{
+  private:
+    double f1_, f2_, f3_, f4_, f5_;
+    
+  public:
+    FivePointsNumericalDerivative(Function* function) :
+      AbstractNumericalDerivative(function), f1_(), f2_(), f3_(), f4_(), f5_() {}
+    FivePointsNumericalDerivative(DerivableFirstOrder* function) :
+      AbstractNumericalDerivative(function), f1_(), f2_(), f3_(), f4_(), f5_() {}
+    FivePointsNumericalDerivative(DerivableSecondOrder* function) :
+      AbstractNumericalDerivative(function), f1_(), f2_(), f3_(), f4_(), f5_() {}
+    virtual ~FivePointsNumericalDerivative() {}
+
+    FivePointsNumericalDerivative* clone() const { return new FivePointsNumericalDerivative(*this); }
+
+  public:
+    
+    double getValue() const throw (Exception)
+    {
+      return f3_;
+    }
+
+    double getSecondOrderDerivative(const std::string& variable1, const std::string& variable2) const
+      throw (Exception)
+    {
+      throw Exception("Unimplemented cross derivative.");
+    }
+  
+  protected:
+    void updateDerivatives(const ParameterList parameters)
+      throw (ParameterNotFoundException, ConstraintException);
+    
+};
+
+} //end of namespace bpp.
+
+#endif //_FIVEPOINTSNUMERICALDERIVATIVE_H_
+
diff --git a/src/Bpp/Numeric/Function/FunctionTools.cpp b/src/Bpp/Numeric/Function/FunctionTools.cpp
new file mode 100644
index 0000000..fa16e5d
--- /dev/null
+++ b/src/Bpp/Numeric/Function/FunctionTools.cpp
@@ -0,0 +1,140 @@
+//
+// File: FunctionTools.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Apr 13 10:47 2009
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "FunctionTools.h"
+#include "../../App/ApplicationTools.h"
+
+using namespace bpp;
+
+//From the STL;
+#include <algorithm>
+using namespace std;
+
+void ParameterGrid::addDimension(const std::string& name, const Vdouble& values) throw (Exception)
+{
+  if (find(names_.begin(), names_.end(), name) != names_.end()) throw Exception("ParameterGrid::addDimension(). A dimension with name '" + name + "' already exists in the grid.");
+  if (values.size() == 0) throw Exception("ParameterGrid::addDimension(). Empty vector given! The dimension should at least contain one point.");
+  names_.push_back(name);
+  grid_.push_back(values);
+}
+ 
+const Vdouble& ParameterGrid::getPointsForDimension(const std::string& name) const throw (Exception)
+{
+  for(unsigned int i = 0; i < names_.size(); i++)
+    if (names_[i] == name)
+      return grid_[i];
+  throw Exception("ParameterGrid::getPointsForDimension(). No dimension with name '" + name + "' was found in the grid.");
+}
+
+const Vdouble& ParameterGrid::getPointsForDimension(unsigned int i) const throw (IndexOutOfBoundsException)
+{
+  if (i >= names_.size()) throw IndexOutOfBoundsException("ParameterGrid::getPointsForDimension().", i, 0, names_.size() - 1);
+  return grid_[i];
+}
+
+size_t ParameterGrid::getTotalNumberOfPoints() const
+{
+  if (grid_.size() == 0) return 0;
+  size_t n = 1;
+  for (size_t i = 0; i < grid_.size(); i++)
+    n *= grid_[i].size();
+  return n;
+}
+
+VVdouble* FunctionTools::computeGrid(
+    Function& function,
+    const ParameterGrid& grid) throw (Exception)
+{
+  //Init stuff...
+  size_t n = grid.getNumberOfDimensions();
+  VVdouble* data = new VVdouble();
+  if(n == 0) return data; //Empty data table returned.
+
+  VVdouble points = grid.getPoints();
+
+  //Get the parameter list. this may throw an exception if the grid does not
+  //match the function parameters...
+  ParameterList pl = function.getParameters().subList(grid.getDimensionNames());
+  for(unsigned int i = 0; i < n; i++)
+    pl.setParameterValue(grid.getDimensionName(i), grid.getPointsForDimension(i)[0]);
+
+  //Iterate over all dimensions:
+  unsigned int currentDimension = 0;
+  vector<unsigned int> currentPointInDimension(n);
+  vector<double> row(n + 1);
+  size_t nbPoints = grid.getTotalNumberOfPoints();
+  ApplicationTools::displayMessage("Computing likelihood profile...");
+  for (unsigned int i = 0; true ; i++)
+  {
+    ApplicationTools::displayGauge(i, nbPoints - 1, '=');
+    //We start by adding the current point to the table:
+    for (unsigned int j = 0; j < n; j++)
+      row[j] = pl[j].getValue();
+    row[n] = function.f(pl);
+    data->push_back(row);
+
+    //Now increment iterator:
+    bool dimensionChanged = false;
+    while (currentDimension < n && currentPointInDimension[currentDimension] == points[currentDimension].size() - 1)
+    {
+      currentDimension++;
+      dimensionChanged = true;
+    }
+    //Stopping condition:
+    if (currentDimension == n) break;
+
+    currentPointInDimension[currentDimension]++;
+    if (dimensionChanged)
+    {
+      for (unsigned int j = 0; j < currentDimension; j++)
+        currentPointInDimension[j] = 0;
+      currentDimension = 0;
+    }
+   
+    //Set the new parameter value:
+    for (unsigned int j = 0; j < points.size(); j++)
+    {
+      pl.setParameterValue(grid.getDimensionName(j), points[j][currentPointInDimension[j]]);
+    }
+  }
+  ApplicationTools::displayMessage("\n");
+  //and we are done:
+  return data;
+}
+
diff --git a/src/Bpp/Numeric/Function/FunctionTools.h b/src/Bpp/Numeric/Function/FunctionTools.h
new file mode 100644
index 0000000..d406120
--- /dev/null
+++ b/src/Bpp/Numeric/Function/FunctionTools.h
@@ -0,0 +1,122 @@
+//
+// File: FunctionTools.h
+// Created by: Julien Dutheil
+// Created on: Mon Apr 13 10:00 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _FUNCTIONTOOLS_H_
+#define _FUNCTIONTOOLS_H_
+
+#include "Functions.h"
+#include "../VectorTools.h"
+
+namespace bpp
+{
+
+/**
+ * @brief This class is a data structure to specify a set of parameter values (most likely for evaluation by a Function)
+ *
+ * @see FunctionTools
+ */
+class ParameterGrid
+{
+  private:
+    std::vector<std::string> names_;
+    VVdouble grid_;
+
+  public:
+    ParameterGrid(): names_(), grid_() {}
+    virtual ~ParameterGrid() {}
+
+  public:
+    /**
+     * @brief Add a new dimension (parameter name + corresponding values).
+     *
+     * @param name The name of the dimension (parameter name).
+     * @param values The values the parameter will take.
+     * @throw Exception in case the dimension is note valid (duplicated parameter name for instance).
+     */
+    void addDimension(const std::string& name, const Vdouble& values) throw (Exception);
+
+    const std::vector<std::string>& getDimensionNames() const { return names_; }
+    
+    const std::string& getDimensionName(unsigned int i) const throw (IndexOutOfBoundsException)
+    {
+      if (i >= names_.size()) throw IndexOutOfBoundsException("ParameterGrid::getDimensionName().", i, 0, names_.size()-1);
+      return names_[i];
+    }
+
+    size_t getNumberOfDimensions() const { return names_.size(); }
+    
+    /**
+     * @return The total number of points in the grid, that is the product of all dimension sizes.
+     */
+    size_t getTotalNumberOfPoints() const;
+
+    const VVdouble& getPoints() const { return grid_; }
+    const Vdouble& getPointsForDimension(unsigned int i) const throw (IndexOutOfBoundsException);
+    const Vdouble& getPointsForDimension(const std::string& name) const throw (Exception);
+};
+
+/**
+ * @brief This class contains static methods to deal with Function objects.
+ */
+class FunctionTools
+{
+  public:
+    /**
+     * @brief Evaluates a function on all points in a given grid.
+     *
+     * @param function The function to use for the evaluation.
+     * @param grid     The grid defining the set of points to evaluate.
+     * @return A pointer toward a dynamically created vector of vector
+     * of doubles. Each row correpsonds to a combination of parameters
+     * and the corresponding function value. There is hence one column
+     * per parameter, and one additional column containing the
+     * corresponding function evaluations. When DataTable supports
+     * different column type, we will probably return a DataTable instead.
+     * @throw Exception If the parameter names in the grid do not match
+     * the ones in the function, or a constraint is matched, etc.
+     */
+    static VVdouble* computeGrid(
+        Function& function,
+        const ParameterGrid& grid) throw (Exception);
+};
+
+} //end of namespace bpp
+
+#endif //_FUNCTIONTOOLS_H_
+
diff --git a/src/Bpp/Numeric/Function/Functions.h b/src/Bpp/Numeric/Function/Functions.h
new file mode 100644
index 0000000..7c2e790
--- /dev/null
+++ b/src/Bpp/Numeric/Function/Functions.h
@@ -0,0 +1,659 @@
+//
+// File: Functions.h
+// Created by: Julien Dutheil
+// Created on: Sun Nov  9 23:11:00 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _FUNCTIONS_H_
+#define _FUNCTIONS_H_
+
+#include "../ParameterList.h"
+#include "../Parametrizable.h"
+#include "../AbstractParametrizable.h"
+#include "../ParameterExceptions.h"
+
+// From Utils:
+#include "../../Clonable.h"
+#include "../../Exceptions.h"
+
+// From the STL:
+#include <cmath>
+
+namespace bpp
+{
+
+/**
+ * @brief This is the function abstract class.
+ *
+ * This class provides the interface for function objet
+ * and a default implementation of the f() function.
+ *
+ * The f() function sends the value of the function according to a
+ * given set of parameters.
+ *
+ * However for complexe function like likelihood for instance,
+ * computing the function value takes some time, and one do not want
+ * to perform several times the computation for an identical set of 
+ * parameters.
+ * The setParameters() method hence allows to set the parameter value
+ * for which the function is to be computed, perform the computation
+ * and store the results.
+ * The getValue() methods send the result of the computation.
+ * One may hence access to the result of the computation by calling the
+ * getvalue() method without re-computating the function.
+ * The f(parameters) function is a shortcut for
+ * @code
+ * setParameters(parameters);
+ * return getValue();
+ * @endcode
+ * for convinience.
+ *
+ * @see Parameter, ParameterList
+ */
+class Function:
+  public virtual Parametrizable
+{    
+  public:
+    Function() {}
+    virtual ~Function() {}
+
+  public:
+
+    /**
+     * @brief Set the point where the function must be computed.
+     *
+     * @param parameters The parameter set to pass to the function.
+     */
+    virtual void setParameters(const ParameterList& parameters) throw (ParameterNotFoundException, ConstraintException, Exception) = 0;
+
+    /**
+     * @brief Get the value of the function at the current point.
+     *
+     * @return The value of the function.
+     * @throw Exception If no point is specified or if an error occured.
+     */
+    virtual double getValue() const throw (Exception) = 0;
+    
+    /**
+     * @brief Get the value of the function according to a given set of parameters.
+     * 
+     * @param parameters The parameter set to pass to the function.
+     * @return The value of the function with the given parameter set.
+     * @throw Exception If an error occured.
+     */
+    virtual double f(const ParameterList& parameters) throw (Exception)
+    {
+      setParameters(parameters);
+      return getValue();
+    }
+};
+
+/**
+ * @brief This is the abstract class for first order derivable functions.
+ *
+ * This class adds the getFirstOrderDerivative() and df() shortcut functions.
+ */
+class DerivableFirstOrder:
+  public virtual Function
+{
+  public:
+    DerivableFirstOrder() {}
+    virtual ~DerivableFirstOrder() {}
+
+#if defined(NO_VIRTUAL_COV)
+    Clonable* clone() const = 0;
+#else
+    DerivableFirstOrder* clone() const = 0;
+#endif
+
+  public:
+
+    /**
+     * @brief Tell if derivatives must be computed.
+     *
+     * @param yn yes/no
+     */
+    virtual void enableFirstOrderDerivatives(bool yn) = 0;
+    
+    /**
+     * @brief Tell if derivatives must be computed.
+     *
+     * @return yes/no
+     */
+    virtual bool enableFirstOrderDerivatives() const = 0;
+
+    /**
+     * @brief Get the derivative of the function at the current point.
+     *
+     * @param variable   The name of the @f$ x @f$ variable in @f$ \frac{df}{dx} @f$.
+     * @return The value of the function.
+     * @throw Exception If no point is specified or if an error occured.
+     */
+    virtual double getFirstOrderDerivative(const std::string& variable) const throw (Exception) = 0;
+    
+    /**
+     * @brief Get the value of the first derivative of the function
+     * according to a given set of parameters.
+     *
+     * @param variable   The name of the @f$ x @f$ variable in @f$ \frac{df}{dx} @f$.
+     * @param parameters The parameter set to pass to the function.
+     * @return The value of the function with the given parameter set.
+     * @throw Exception If an error occured.
+     */
+    virtual double df(const std::string& variable, const ParameterList& parameters) throw (Exception)
+    {
+      setParameters(parameters);
+      return getFirstOrderDerivative(variable);
+    }
+};
+
+/**
+ * @brief This is the abstract class for second order derivable functions.
+ * 
+ * This class adds the getSecondOrderDerivative() and d2f() shortcut functions.
+ * Cross derivative functions are also provided.
+ */
+class DerivableSecondOrder:
+  public virtual DerivableFirstOrder
+{
+  public:
+    DerivableSecondOrder() {}
+    virtual ~DerivableSecondOrder() {}
+
+#if defined(NO_VIRTUAL_COV)
+    Clonable* clone() const = 0;
+#else
+    DerivableSecondOrder* clone() const = 0;
+#endif
+
+  public:
+
+    /**
+     * @brief Tell if derivatives must be computed.
+     *
+     * @param yn yes/no
+     */
+    virtual void enableSecondOrderDerivatives(bool yn) = 0;
+    
+    /**
+     * @brief Tell if derivatives must be computed.
+     *
+     * @return yes/no
+     */
+    virtual bool enableSecondOrderDerivatives() const = 0;
+
+    /**
+     * @brief Get the second order derivative of the function at the current point.
+     *
+     * @param variable   The name of the @f$ x @f$ variable in @f$ \frac{\partial^2 f}{\partial x^2} @f$.
+     * @return The value of the function.
+     * @throw Exception If no point is specified or if an error occured.
+     */
+    virtual double getSecondOrderDerivative(const std::string& variable) const throw (Exception) = 0;
+  
+    /**
+     * @brief Get the value of the second order derivative of the function
+     * according to a given set of parameters.
+     *
+     * @param variable   The name of the @f$ x @f$ variable in @f$ \frac{\partial^2 f}{\partial x^2} @f$.
+     * @param parameters The parameter set to pass to the function.
+     * @return The value of the function with the given parameter set.
+     * @throw Exception If an error occured.
+     */
+    virtual double d2f(const std::string& variable, const ParameterList& parameters) throw (Exception)
+    {
+      setParameters(parameters);
+      return getSecondOrderDerivative(variable);
+    }    
+
+    /**
+     * @brief Get the value of the cross derivative of the function
+     * according to a given set of parameters.
+     *
+     * @param variable1  The name of the @f$ x @f$ variable in @f$ \frac{\partial^2 f}{\partial x \partial y} @f$.
+     * @param variable2  The name of the @f$ y @f$ variable in @f$ \frac{\partial^2 f}{\partial x \partial y} @f$.
+     * @return The value of the function with the given parameter set.
+     * @throw Exception If an error occured.
+     */
+    virtual double getSecondOrderDerivative(const std::string& variable1, const std::string& variable2) const throw (Exception) = 0;  
+    
+    /**
+     * @brief Get the value of the cross derivative of the function
+     * according to a given set of parameters.
+     *
+     * @param variable1  The name of the @f$ x @f$ variable in @f$ \frac{\partial^2 f}{\partial x \partial y} @f$.
+     * @param variable2  The name of the @f$ y @f$ variable in @f$ \frac{\partial^2 f}{\partial x \partial y} @f$.
+     * @param parameters The parameter set to pass to the function.
+     * @return The value of the function with the given parameter set.
+     * @throw Exception If an error occured.
+     */
+    virtual double d2f(const std::string& variable1, const std::string& variable2, const ParameterList& parameters) throw (Exception)
+    {
+      setParameters(parameters);
+      return getSecondOrderDerivative(variable1, variable2);
+    }
+};
+
+/**
+ * @brief General class that wraps a function into another one.
+ * This class is meant to be derivated and just provides a general framework.
+ */
+class FunctionWrapper:
+  public virtual Function
+{
+  protected:
+    Function* function_;
+
+  public:
+    FunctionWrapper(Function* function) : function_(function) {}
+    FunctionWrapper(const FunctionWrapper& fw) : function_(fw.function_) {}
+    FunctionWrapper& operator=(const FunctionWrapper& fw)
+    {
+      function_ = fw.function_;
+      return *this;
+    }
+
+  public:
+    bool hasParameter(const std::string& name) const
+    {
+      return function_->hasParameter(name);
+    }
+
+    void setParameters(const ParameterList & parameters)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      function_->setParameters(parameters);
+    }
+
+    const ParameterList& getParameters() const throw (Exception)
+    {
+      return function_->getParameters();  
+    }
+
+    const Parameter& getParameter(const std::string & name) const throw (ParameterNotFoundException)
+    {
+      return function_->getParameter(name);
+    }
+
+    double getValue() const throw (Exception)
+    {
+      return function_->getValue();
+    }
+    
+    double f(const ParameterList& parameters) throw (Exception)
+    {
+      return function_->f(parameters);
+    }
+    
+    double getParameterValue(const std::string& name) const throw (ParameterNotFoundException)
+    {
+      return function_->getParameterValue(name);
+    }
+      
+    void setAllParametersValues(const ParameterList & parameters)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      function_->setAllParametersValues(parameters);
+    }
+    
+    void setParameterValue(const std::string& name, double value)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      function_->setParameterValue(name, value);
+    }
+    
+    void setParametersValues(const ParameterList& parameters)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      function_->setParametersValues(parameters);
+    }
+    
+    bool matchParametersValues(const ParameterList& parameters)
+      throw (ConstraintException)
+    {
+      return function_->matchParametersValues(parameters);
+    }
+
+    size_t getNumberOfParameters() const
+    {
+      return function_->getNumberOfParameters();
+    }
+
+    void setNamespace(const std::string& prefix)
+    {
+      function_->setNamespace(prefix);
+    }
+
+    std::string getNamespace() const
+    {
+      return function_->getNamespace();
+    }
+
+    std::string getParameterNameWithoutNamespace(const std::string& name) const
+    {
+      return function_->getParameterNameWithoutNamespace(name);
+    }
+
+};
+
+
+
+/**
+ * @brief General class that wraps a function into another one.
+ * This class is meant to be derivated and just provides a general framework.
+ */
+class DerivableFirstOrderWrapper:
+  public FunctionWrapper,
+  public virtual DerivableFirstOrder
+{
+  public:
+    DerivableFirstOrderWrapper(DerivableFirstOrder* function) : FunctionWrapper(function) {}
+
+  public:
+    void enableFirstOrderDerivatives(bool yn) {
+      dynamic_cast<DerivableFirstOrder*>(function_)->enableFirstOrderDerivatives(yn);
+    }
+    
+    bool enableFirstOrderDerivatives() const {
+      return dynamic_cast<DerivableFirstOrder*>(function_)->enableFirstOrderDerivatives();
+    }
+
+    double getFirstOrderDerivative(const std::string& variable) const throw (Exception) {
+      return dynamic_cast<DerivableFirstOrder*>(function_)->getFirstOrderDerivative(variable);
+    }
+
+};
+
+
+
+/**
+ * @brief General class that wraps a function into another one.
+ * This class is meant to be derivated and just provides a general framework.
+ */
+class DerivableSecondOrderWrapper:
+  public DerivableFirstOrderWrapper,
+  public virtual DerivableSecondOrder
+{
+  public:
+    DerivableSecondOrderWrapper(DerivableSecondOrder* function) : DerivableFirstOrderWrapper(function) {}
+
+  public:
+    void enableSecondOrderDerivatives(bool yn) {
+      dynamic_cast<DerivableSecondOrder*>(function_)->enableSecondOrderDerivatives(yn);
+    }
+    
+    bool enableSecondOrderDerivatives() const {
+      return dynamic_cast<DerivableSecondOrder*>(function_)->enableSecondOrderDerivatives();
+    }
+
+    double getSecondOrderDerivative(const std::string& variable) const throw (Exception) {
+      return dynamic_cast<DerivableSecondOrder*>(function_)->getSecondOrderDerivative(variable);
+    }
+
+    double getSecondOrderDerivative(const std::string& variable1, const std::string& variable2) const throw (Exception) {
+      return dynamic_cast<DerivableSecondOrder*>(function_)->getSecondOrderDerivative(variable1, variable2);
+    }
+
+};
+
+
+
+/**
+ * @brief Wrapper class for optimization under constraints.
+ *
+ * Catch any ConstraintException thrown and send +inf.
+ */
+class InfinityFunctionWrapper:
+  public FunctionWrapper
+{
+  protected:
+    mutable bool constraintMatch_;
+    
+  public:
+    InfinityFunctionWrapper(Function* function) :
+      FunctionWrapper(function),
+      constraintMatch_(false) {}
+    virtual ~InfinityFunctionWrapper() {}
+
+#if defined(NO_VIRTUAL_COV)
+    Clonable* clone() const { return new InfinityFunctionWrapper(*this); }
+#else
+    InfinityFunctionWrapper* clone() const { return new InfinityFunctionWrapper(*this); }
+#endif
+
+  public:
+
+    void setParameters(const ParameterList& parameters)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      try
+      {
+        function_->setParameters(parameters);
+        constraintMatch_ = false;
+      }
+      catch(ConstraintException& ce)
+      {
+        constraintMatch_ = true;
+      }
+    }
+
+    double getValue() const throw (Exception)
+    {
+      return constraintMatch_ ? -log(0.) :  function_->getValue();
+    }
+    
+    double f(const ParameterList& parameters) throw (Exception)
+    {
+      setParameters(parameters);
+      return getValue();
+    }
+          
+    void setAllParametersValues(const ParameterList & parameters)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      try
+      {
+        function_->setAllParametersValues(parameters);
+        constraintMatch_ = false;
+      }
+      catch(ConstraintException& ce)
+      {
+        constraintMatch_ = true;
+      }
+    }
+    
+    void setParameterValue(const std::string& name, double value)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      try
+      {
+        function_->setParameterValue(name, value);
+        constraintMatch_ = false;
+      }
+      catch(ConstraintException& ce)
+      {
+        constraintMatch_ = true;
+      }
+    }
+    
+    void setParametersValues(const ParameterList& parameters)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+      try
+      {
+        function_->setParametersValues(parameters);
+        constraintMatch_ = false;
+      }
+      catch(ConstraintException& ce)
+      {
+        constraintMatch_ = true;
+      }
+    }
+    
+    bool matchParametersValues(const ParameterList& parameters)
+      throw (ConstraintException)
+    {
+      try
+      {
+        bool test = function_->matchParametersValues(parameters);
+        constraintMatch_ = false;
+        return test;
+      }
+      catch (ConstraintException& ce)
+      {
+        constraintMatch_ = true;
+        return false;
+      }
+    }
+
+};
+
+/**
+ * @brief Wrapper class for optimization under constraints.
+ *
+ * Catch any ConstraintException thrown and send +inf.
+ */
+class InfinityDerivableFirstOrderWrapper :
+  public virtual InfinityFunctionWrapper
+{
+  public:
+    InfinityDerivableFirstOrderWrapper(DerivableFirstOrder* function) : InfinityFunctionWrapper(function) {}
+    virtual ~InfinityDerivableFirstOrderWrapper() {}
+    
+#if defined(NO_VIRTUAL_COV)
+    Clonable* clone() const { return new InfinityDerivableFirstOrderWrapper(*this); }
+#else
+    InfinityDerivableFirstOrderWrapper* clone() const { return new InfinityDerivableFirstOrderWrapper(*this); }
+#endif
+
+  public:
+    
+    double getFirstOrderDerivative(const std::string& variable) const throw (Exception)
+    {
+      return constraintMatch_ ? -log(0.) :  (dynamic_cast<DerivableFirstOrder *>(function_)->getFirstOrderDerivative(variable));    
+    }
+    
+    double df(const std::string& variable, const ParameterList& parameters) throw (Exception)
+    {
+      setParameters(parameters);
+      return getFirstOrderDerivative(variable);
+    }
+};
+
+/**
+ * @brief Wrapper class for optimization under constraints.
+ *
+ * Catch any ConstraintException thrown and send +inf.
+ */
+class InfinityDerivableSecondOrderWrapper :
+  public virtual InfinityDerivableFirstOrderWrapper
+{
+  public:
+    InfinityDerivableSecondOrderWrapper(DerivableFirstOrder* function):
+      InfinityFunctionWrapper(function),
+      InfinityDerivableFirstOrderWrapper(function) {}
+    virtual ~InfinityDerivableSecondOrderWrapper() {}
+
+#if defined(NO_VIRTUAL_COV)
+    Clonable* clone() const { return new InfinityDerivableSecondOrderWrapper(*this); }
+#else
+    InfinityDerivableSecondOrderWrapper* clone() const { return new InfinityDerivableSecondOrderWrapper(*this); }
+#endif
+
+  public:
+
+    double getSecondOrderDerivative(const std::string& variable) const throw (Exception)
+    {
+      return constraintMatch_ ? -log(0.) :  (dynamic_cast<DerivableSecondOrder *>(function_)->getSecondOrderDerivative(variable));          
+    }
+  
+    double d2f(const std::string & variable, const ParameterList& parameters) throw (Exception)
+    {
+      setParameters(parameters);
+      return getSecondOrderDerivative(variable);
+    }    
+
+    double getSecondOrderDerivative(const std::string& variable1, const std::string& variable2) const throw (Exception)
+    {
+      return constraintMatch_ ? -log(0.) :  (dynamic_cast<DerivableSecondOrder *>(function_)->getSecondOrderDerivative(variable1, variable2));      
+    }
+    
+    double d2f(const std::string & variable1, const std::string& variable2, const ParameterList& parameters) throw (Exception)
+    {
+      setParameters(parameters);
+      return getSecondOrderDerivative(variable1, variable2);
+    }
+};
+
+
+/**
+ * @brief A simple funciton with two parameters, mostly for testing and debugging :)
+ *
+ * @author Julien Dutheil.
+ */
+class TestFunction :
+  public virtual Function,
+  public AbstractParametrizable
+{
+  public:
+    TestFunction(double x = 0, double y = 0) :
+      AbstractParametrizable("")
+    {
+      addParameter_(new Parameter("x", x));
+      addParameter_(new Parameter("y", y));
+    }
+
+    Clonable* clone() const { return new TestFunction(*this); }
+
+    void setParameters(const ParameterList& parameters) throw (Exception) 
+    {
+      matchParametersValues(parameters);
+    }
+
+    double getValue() const throw (Exception)
+    {
+      double x = getParameter("x").getValue();
+      double y = getParameter("y").getValue();
+      return (x*x + y*y);
+    }
+
+    void fireParameterChanged(const ParameterList& parameters) {}
+};
+
+} //end of namespace bpp.
+
+#endif  //_FUNCTIONS_H_
+
diff --git a/src/Bpp/Numeric/Function/GoldenSectionSearch.cpp b/src/Bpp/Numeric/Function/GoldenSectionSearch.cpp
new file mode 100644
index 0000000..840d48a
--- /dev/null
+++ b/src/Bpp/Numeric/Function/GoldenSectionSearch.cpp
@@ -0,0 +1,178 @@
+//
+// File: GoldenSectionSearch.cpp
+// Created by: Julien Dutheil 
+// Created on: Mon Nov 10 10:42:17 2003
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "GoldenSectionSearch.h"
+#include "OneDimensionOptimizationTools.h"
+#include "../NumTools.h"
+#include "../NumConstants.h"
+#include "../../Text/TextTools.h"
+
+using namespace bpp;
+
+/******************************************************************************/
+
+bool GoldenSectionSearch::GSSStopCondition::isToleranceReached() const
+{
+  callCount_++;
+  if (callCount_ <= burnin_) return false;
+  return getTolerance() <= tolerance_;
+}
+    
+/******************************************************************************/
+
+double GoldenSectionSearch::GSSStopCondition::getCurrentTolerance() const
+{
+  // NRC Test for done:
+  const GoldenSectionSearch* gss = dynamic_cast<const GoldenSectionSearch*>(optimizer_);
+  double x0 = gss->x0;
+  double x1 = gss->x1;
+  double x2 = gss->x2;
+  double x3 = gss->x3;
+  return NumTools::abs(x3 - x0) / (NumTools::abs(x1) + NumTools::abs(x2));
+}
+  
+/******************************************************************************/
+
+GoldenSectionSearch::GoldenSectionSearch(Function* function) :
+  AbstractOptimizer(function),
+  f1(0), f2(0), x0(0), x1(0), x2(0), x3(0), xinf_(0), xsup_(0), isInitialIntervalSet_(false)
+{
+  nbEvalMax_ = 10000;
+  setDefaultStopCondition_(new GSSStopCondition(this));
+  setStopCondition(*getDefaultStopCondition());
+}
+
+/******************************************************************************/
+
+void GoldenSectionSearch::doInit(const ParameterList& params) throw (Exception)
+{
+  // Set the initial value (no use here! Use setInitialValues() instead).
+  if(params.size() != 1) throw Exception("GoldenSectionSearch::init(). This optimizer only deals with one parameter.");
+
+  // Bracket the minimum.
+  Bracket bracket = OneDimensionOptimizationTools::bracketMinimum(xinf_, xsup_, getFunction(), getParameters());
+  if (getVerbose() > 0)
+  {
+    printMessage("Initial bracketing:");
+    printMessage("A: x = " + TextTools::toString(bracket.a.x) + ", f = " + TextTools::toString(bracket.a.f));
+    printMessage("B: x = " + TextTools::toString(bracket.b.x) + ", f = " + TextTools::toString(bracket.b.f));
+    printMessage("C: x = " + TextTools::toString(bracket.c.x) + ", f = " + TextTools::toString(bracket.c.f));
+  }
+  
+  // At any given time we will keep track of four points, x0, x1, x2 and x3.
+  x0 = bracket.a.x;
+  x3 = bracket.c.x;
+  if (NumTools::abs(bracket.c.x - bracket.b.x)
+      > NumTools::abs(bracket.b.x - bracket.a.x))
+  {
+    // Make x0 to x1 the smaller segment,
+    x1 = bracket.b.x;
+    // and fill in the new point to be tried.
+    x2 = bracket.b.x + NumConstants::GOLDEN_RATIO_C() * (bracket.c.x - bracket.b.x);
+  }
+  else
+  {
+    x2 = bracket.b.x;
+    x1 = bracket.b.x - NumConstants::GOLDEN_RATIO_C() * (bracket.b.x - bracket.a.x);
+  }
+  // The initial function evaluations.
+  // Note that we never need to evaluate the function at the original endpoints.
+  getParameter_(0).setValue(x1); f1 = getFunction()->f(getParameters());
+  getParameter_(0).setValue(x2); f2 = getFunction()->f(getParameters());
+}
+
+/******************************************************************************/
+
+void GoldenSectionSearch::setInitialInterval(double inf, double sup)
+{
+  if(sup > inf)
+  {
+    xinf_ = inf; xsup_ = sup;
+  }
+  else
+  {
+    xinf_ = sup; xsup_ = inf;
+  }
+  isInitialIntervalSet_ = true;
+}
+
+/******************************************************************************/
+
+double GoldenSectionSearch::doStep() throw (Exception)
+{
+  if (!isInitialIntervalSet_) throw Exception("GoldenSectionSearch::step. Initial interval not set: call the 'setInitialInterval' method first!");
+  
+  nbEval_++;
+
+  if (f2 < f1)
+  {
+    // One possible outcome, its housekeeping,
+    NumTools::shift<double>(x0, x1, x2);
+    x2 = NumConstants::GOLDEN_RATIO_R() * x1 + NumConstants::GOLDEN_RATIO_C() * x3;
+    // and a new function evaluation.
+    getParameter_(0).setValue(x2);
+    tolIsReached_ = nbEval_ > 2 && getStopCondition()->isToleranceReached();
+    NumTools::shift<double>(f1, f2, getFunction()->f(getParameters()));
+    return f2;
+  }
+  else
+  {
+    // The other outcome,
+    NumTools::shift<double>(x3, x2, x1);
+    x1 = NumConstants::GOLDEN_RATIO_R() * x2 + NumConstants::GOLDEN_RATIO_C() * x0;
+    // and its new function evaluation.
+    getParameter_(0).setValue(x1);
+    tolIsReached_ = nbEval_ > 2 && getStopCondition()->isToleranceReached();
+    NumTools::shift<double>(f2, f1, getFunction()->f(getParameters()));
+    return f1;
+  }
+}
+
+/******************************************************************************/
+
+double GoldenSectionSearch::getFunctionValue() const throw (NullPointerException)
+{
+  if (!hasFunction())
+    throw NullPointerException("GoldenSectionSearch::getFunctionValue. No function associated to this optimizer.");
+  //return NumTools::min(f1, f2); 
+  return currentValue_; 
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/GoldenSectionSearch.h b/src/Bpp/Numeric/Function/GoldenSectionSearch.h
new file mode 100644
index 0000000..be3ae33
--- /dev/null
+++ b/src/Bpp/Numeric/Function/GoldenSectionSearch.h
@@ -0,0 +1,145 @@
+//
+// File: GoldenSectionSearch.h
+// Created by: Julien Dutheil
+// Created on: Mon Nov 10 10:42:17 2003
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _GOLDENSECTIONSEARCH_H_
+#define _GOLDENSECTIONSEARCH_H_
+
+#include "AbstractOptimizer.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Golden Section Search optimization algorithm for one parameter.
+ *
+ * A description of the algorithm can be found in:
+ * <pre>
+ * NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING
+ * (ISBN 0-521-43108-5)
+ * </pre>
+ * or there:
+ * <a href="http://en.wikipedia.org/wiki/Golden_section_search">http://en.wikipedia.org/wiki/Golden_section_search</a>.
+ */
+class GoldenSectionSearch:
+  public AbstractOptimizer
+{	
+	public:
+		class GSSStopCondition:
+      public AbstractOptimizationStopCondition
+		{
+			public:
+				GSSStopCondition(GoldenSectionSearch* gss):
+          AbstractOptimizationStopCondition(gss) {}
+				virtual ~GSSStopCondition() {}
+
+        GSSStopCondition* clone() const { return new GSSStopCondition(*this); }
+			
+			public:
+				bool isToleranceReached() const;
+        double getCurrentTolerance() const;
+		};
+	
+	friend class GSSStopCondition;
+
+	private:
+		double f1, f2, x0, x1, x2, x3;
+		double xinf_, xsup_;
+    bool isInitialIntervalSet_;
+	
+	public:
+		
+		GoldenSectionSearch(Function* function);
+		virtual ~GoldenSectionSearch() {}
+
+    GoldenSectionSearch* clone() const { return new GoldenSectionSearch(*this); }
+	
+	public:
+		
+		/**
+		 * @name The Optimizer interface.
+		 *
+		 * @{
+		 */
+		
+		/**
+		 * @brief Initialize optimizer.
+		 *
+		 * The golden section search needs 2 initial guesses, so you must call the
+		 * setInitialInterval() method first. This function actually performs:
+		 * <ul>
+		 * <li>Parameter list actualisation;</li>
+		 * <li>Initial bracketting;</li>
+		 * <li>Function evaluation count reseting.</li>
+		 * </ul>
+		 */
+		double getFunctionValue() const throw (NullPointerException);
+		/** @} */
+		
+    void doInit(const ParameterList & params) throw (Exception);
+
+		double doStep() throw (Exception);
+	
+		/**
+		 * @name Specific method
+		 *
+		 * @{
+		 */
+		
+		/**
+		 * @brief Set intial search interval.
+		 *
+		 * @param inf Minimum value.
+		 * @param sup Maximum value.
+		 */
+		void setInitialInterval(double inf, double sup);
+		/** @} */
+
+    /**
+     * @return 'true' if the initial interval has been correctly set.
+     */
+    bool isInitialIntervalSet() const { return isInitialIntervalSet_; }
+
+  protected:
+		
+};
+
+} //end of namespace bpp.
+
+#endif	//_GOLDENSECTIONSEARCH_H_
+
diff --git a/src/Bpp/Numeric/Function/MetaOptimizer.cpp b/src/Bpp/Numeric/Function/MetaOptimizer.cpp
new file mode 100644
index 0000000..6dad184
--- /dev/null
+++ b/src/Bpp/Numeric/Function/MetaOptimizer.cpp
@@ -0,0 +1,208 @@
+//
+// File: MetaOptimizer.cpp
+// Created by: Julien Dutheil
+// Created on: Fri Oct 12 16:05 2007
+// From file: NewtonBrentMetaOptimizer.cpp
+// Created on: Tue Nov 17 17:22 2004
+// 
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+/**************************************************************************/
+
+#include "MetaOptimizer.h"
+#include "../../App/ApplicationTools.h"
+
+using namespace bpp;
+using namespace std;
+
+/**************************************************************************/
+
+string MetaOptimizerInfos::IT_TYPE_STEP = "step";
+string MetaOptimizerInfos::IT_TYPE_FULL = "full";
+
+/**************************************************************************/
+
+MetaOptimizer::MetaOptimizer(
+    Function* function,
+    MetaOptimizerInfos* desc,
+    unsigned int n):
+  AbstractOptimizer(function),
+  optDesc_(desc), optParameters_(desc->getNumberOfOptimizers()),
+  nbParameters_(desc->getNumberOfOptimizers()), n_(n),
+  precisionStep_(-1.), stepCount_(0), initialValue_(-1.)
+{
+  setDefaultStopCondition_(new FunctionStopCondition(this));
+  setStopCondition(*getDefaultStopCondition());
+  precisionStep_ = log10(getStopCondition()->getTolerance()) / n_;
+  setOptimizationProgressCharacter("");
+}
+
+/**************************************************************************/
+
+MetaOptimizer::MetaOptimizer(
+    const MetaOptimizer& opt):
+  AbstractOptimizer(opt),
+  optDesc_(dynamic_cast<MetaOptimizerInfos *>(opt.optDesc_->clone())),
+  optParameters_(opt.optParameters_),
+  nbParameters_(opt.nbParameters_),
+  n_(opt.n_),
+  precisionStep_(opt.precisionStep_),
+  stepCount_(opt.stepCount_),
+  initialValue_(opt.initialValue_)
+{}
+
+/**************************************************************************/
+
+MetaOptimizer& MetaOptimizer::operator=(
+    const MetaOptimizer& opt)
+{
+  AbstractOptimizer::operator=(opt);
+  optDesc_       = dynamic_cast<MetaOptimizerInfos *>(opt.optDesc_->clone());
+  optParameters_ = opt.optParameters_;
+  nbParameters_  = opt.nbParameters_;
+  n_             = opt.n_;
+  precisionStep_ = opt.precisionStep_;
+  stepCount_     = opt.stepCount_;
+  initialValue_  = opt.initialValue_;
+  return *this;
+}
+
+/**************************************************************************/
+
+MetaOptimizer::~MetaOptimizer()
+{
+  // Delete all optimizers:
+  delete optDesc_;
+}
+
+/**************************************************************************/
+
+void MetaOptimizer::doInit(const ParameterList& parameters)
+  throw (Exception)
+{
+  optParameters_.resize(optDesc_->getNumberOfOptimizers());
+  for (unsigned int i = 0; i < optDesc_->getNumberOfOptimizers(); i++)
+  {
+    optParameters_[i].reset();
+    for (size_t j = 0; j < optDesc_->getParameterNames(i).size(); j++)
+    {
+      string pname = optDesc_->getParameterNames(i)[j];
+      if (parameters.hasParameter(pname))
+      {
+        optParameters_[i].addParameter(parameters.getParameter(pname));
+      }
+    }
+    nbParameters_[i] = optParameters_[i].size();
+  }
+
+  // Initialize optimizers:
+  for (unsigned int i = 0; i < optDesc_->getNumberOfOptimizers(); i++)
+  {
+    if (nbParameters_[i] > 0)
+    {
+      Optimizer * opt = optDesc_->getOptimizer(i);
+      dynamic_cast<AbstractOptimizer*>(opt)->updateParameters(updateParameters());
+      opt->setProfiler(getProfiler());
+      opt->setMessageHandler(getMessageHandler());
+      opt->setConstraintPolicy(getConstraintPolicy());
+      opt->setVerbose(getVerbose() > 0 ? getVerbose() - 1 : 0);
+    }
+  }
+  
+  // Actualize parameters:
+  getParameters_().matchParametersValues(getFunction()->getParameters());
+  
+  getFunction()->setParameters(getParameters());
+  initialValue_ = getFunction()->getValue();
+  // Reset counter:
+  stepCount_ = 1;
+  // Recompute step if precision has changed:
+  precisionStep_ = (log10(getStopCondition()->getTolerance()) - log10(initialValue_)) / n_;
+}
+
+/**************************************************************************/
+
+double MetaOptimizer::doStep() throw (Exception)
+{
+  stepCount_++;
+  
+  int tolTest = 0;
+  double tol = getStopCondition()->getTolerance();
+  if (stepCount_ <= n_)
+  {
+    tol = initialValue_ * pow(10, stepCount_ * precisionStep_);
+  }
+  
+  for (unsigned int i = 0; i < optDesc_->getNumberOfOptimizers(); i++)
+  {
+    if (nbParameters_[i] > 0)
+    {
+      if (getVerbose() > 1 && ApplicationTools::message)
+      {
+        (ApplicationTools::message->endLine() << optDesc_->getName(i)).endLine();
+        ApplicationTools::message->flush();
+      }
+      if (optDesc_->requiresFirstOrderDerivatives(i))
+        dynamic_cast<DerivableFirstOrder*>(getFunction())->enableFirstOrderDerivatives(true);
+      if (optDesc_->requiresSecondOrderDerivatives(i))  
+        dynamic_cast<DerivableSecondOrder*>(getFunction())->enableSecondOrderDerivatives(true);
+
+      optParameters_[i].matchParametersValues(getParameters());
+      Optimizer * opt = optDesc_->getOptimizer(i);
+      opt->getStopCondition()->setTolerance(tol);
+      opt->init(optParameters_[i]);
+      if (optDesc_->getIterationType(i) == MetaOptimizerInfos::IT_TYPE_STEP)
+        opt->step();
+      else if (optDesc_->getIterationType(i) == MetaOptimizerInfos::IT_TYPE_FULL)
+        opt->optimize();
+      else throw Exception("MetaOptimizer::step. Unknown iteration type specified.");
+      nbEval_ += opt->getNumberOfEvaluations();
+      if (optDesc_->requiresFirstOrderDerivatives(i))
+        dynamic_cast<DerivableFirstOrder*>(getFunction())->enableFirstOrderDerivatives(false);
+      if (optDesc_->requiresSecondOrderDerivatives(i))  
+        dynamic_cast<DerivableSecondOrder*>(getFunction())->enableSecondOrderDerivatives(false);
+      if (getVerbose() > 1) cout << endl;
+      getParameters_().matchParametersValues(opt->getParameters());
+    }
+    tolTest += nbParameters_[i] > 0 ? 1 : 0;
+  }
+  tolIsReached_ = (tolTest == 1);
+   
+  return getFunction()->getValue();
+}
+
+/**************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/MetaOptimizer.h b/src/Bpp/Numeric/Function/MetaOptimizer.h
new file mode 100644
index 0000000..228c769
--- /dev/null
+++ b/src/Bpp/Numeric/Function/MetaOptimizer.h
@@ -0,0 +1,250 @@
+//
+// File: MetaOptimizer.h
+// Created by: Julien Dutheil
+// Created on: Fri Oct 12 16:05 2007
+// From file: NewtonBrentMetaOptimizer.h
+// Created on: Tue Nov 17 17:22 2004
+// 
+//
+
+/*
+  Copyright or © or Copr. CNRS, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for phylogenetic data analysis.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef METAOPTIMIZER_H__
+#define METAOPTIMIZER_H__
+
+#include "AbstractOptimizer.h"
+
+// From the STL:
+#include <vector>
+
+namespace bpp
+{
+
+  /**
+   * @brief Provide a list of optimizer and corresponding options to be used with the MetaOptimizer class.
+   */
+  class MetaOptimizerInfos:
+    public virtual Clonable
+  {
+  public:
+    static std::string IT_TYPE_STEP;
+    static std::string IT_TYPE_FULL;
+
+  private:
+    std::vector<std::string> names_;
+    std::vector<Optimizer*> optimizers_;
+    std::vector< std::vector<std::string> > parameterNames_;
+    std::vector<unsigned short> derivatives_;
+    std::vector<std::string> itTypes_;
+
+  public:
+    MetaOptimizerInfos() : names_(), optimizers_(), parameterNames_(), derivatives_(), itTypes_() {}
+    MetaOptimizerInfos(const MetaOptimizerInfos& infos) :
+      names_(infos.names_),
+      optimizers_(infos.optimizers_),
+      parameterNames_(infos.parameterNames_),
+      derivatives_(infos.derivatives_),
+      itTypes_(infos.itTypes_)
+    {
+      for (unsigned int i = 0; i < optimizers_.size(); i++)
+        optimizers_[i] = dynamic_cast<Optimizer*>(infos.optimizers_[i]->clone());
+    }
+
+    MetaOptimizerInfos& operator=(const MetaOptimizerInfos& infos)
+    {
+      names_          = infos.names_;
+      optimizers_     = infos.optimizers_;
+      parameterNames_ = infos.parameterNames_;
+      derivatives_    = infos.derivatives_;
+      itTypes_        = infos.itTypes_;
+      for (unsigned int i = 0; i < optimizers_.size(); i++)
+        optimizers_[i] = dynamic_cast<Optimizer *>(infos.optimizers_[i]->clone());
+      return *this;
+    }
+
+    virtual ~MetaOptimizerInfos()
+    {
+      for(unsigned int i = 0; i < optimizers_.size(); i++)
+        delete optimizers_[i];
+    }
+
+  public:
+#ifndef NO_VIRTUAL_COV
+    MetaOptimizerInfos* clone() const { return new MetaOptimizerInfos(*this); }
+#else
+    Clonable* clone() const { return new MetaOptimizerInfos(*this); }
+#endif
+
+  public:
+    /**
+     * @brief Add a new optimizer to the set.
+     *
+     * @param name the name of the optimizer. It is used for display only.
+     * @param optimizer A pointer toward the optimizer to add. The set will own the underlying object, which will be destroyed together with the set.
+     * @param params A list of parameter names to optimize with this optimizer.
+     * @param derivatives 0, 1 or 2: does this parameter use no, first order or second order derivatives?
+     * @param type For each optimization step, shall we perform a full optimization with this optimizer or only one step?
+     */
+    virtual void addOptimizer(const std::string & name, Optimizer * optimizer, const std::vector<std::string> & params, const short derivatives = 0, const std::string & type = IT_TYPE_STEP)
+    {
+      names_.push_back(name);
+      optimizers_.push_back(optimizer);
+      parameterNames_.push_back(params);
+      derivatives_.push_back(derivatives);
+      itTypes_.push_back(type);
+    }
+
+    /**
+     * @return The display name of the ith optimizer in the set.
+     */
+    virtual const std::string& getName(unsigned int i) const { return names_[i]; }
+    
+    /**
+     * @return The ith optimizer in the set.
+     */
+    virtual Optimizer* getOptimizer(unsigned int i) { return optimizers_[i]; }
+    /**
+     * @return The ith optimizer in the set.
+     */
+    virtual const Optimizer* getOptimizer(unsigned int i) const { return optimizers_[i]; }
+
+    /**
+     * @return The parameter names associated to the ith optimizer in the set.
+     */
+    virtual std::vector<std::string>& getParameterNames(unsigned int i) { return parameterNames_[i]; }
+    /**
+     * @return The parameter names associated to the ith optimizer in the set.
+     */
+    virtual const std::vector<std::string>& getParameterNames(unsigned int i) const { return parameterNames_[i]; }
+
+    /**
+     * @return The type of iteration to perform for the ith optimizer in the set.
+     */
+    virtual std::string& getIterationType(unsigned int i) { return itTypes_[i]; }
+    /**
+     * @return The type of iteration to perform for the ith optimizer in the set.
+     */
+    virtual const std::string& getIterationType(unsigned int i) const { return itTypes_[i]; }
+
+    /**
+     * @return True if the ith optimizer in the set requires first order derivatives.
+     */
+    virtual bool requiresFirstOrderDerivatives(unsigned int i) const { return derivatives_[i] > 0; }  
+    /**
+     * @return True if the ith optimizer in the set requires second order derivatives.
+     */
+    virtual bool requiresSecondOrderDerivatives(unsigned int i) const { return derivatives_[i] > 1; }  
+
+    /**
+     * @return The number of optimizers in the set.
+     */
+    virtual size_t getNumberOfOptimizers() const { return optimizers_.size(); }
+  };
+
+  /**
+   * @brief Meta-optimizer.
+   *
+   * This optimizer uses a set of optimizers to applyied sequentially on distinct parameters.
+   * The set of optimizers is fully specified by a MetaOptimizerInfos object.
+   * 
+   * To decrease the optimization time, the precision of the optimizers can be increased progressively:
+   * if @f$\varepsilon at f$ is the final precision required, one may consider using a precision increment of @f$\sigma=\log_10(\varepsilon/n)@f$, where @f$n at f$ is the number of progressive steps.
+   * During the first step optimization step, the precisions of type 1 and 2 optimizers are set to @f$10^{\sigma}@f$, @f$10^{2\sigma}@f$ for step 2, ... until precision @f$10^{n\sigma}=\varepsilon at f$ at step @f$n at f$ and later.
+   * This saves some time spending in the first steps of the estimation.
+   * The number of steps @f$n at f$ is set in the constructor of the optimizer.
+   *
+   * This optimizer can be used with numerical derivatives.
+   * 
+   * @see MetaOptimizerInfos.
+   */
+  class MetaOptimizer:
+    public AbstractOptimizer
+  {
+  private:
+    MetaOptimizerInfos* optDesc_;
+    std::vector<ParameterList> optParameters_;
+    std::vector<size_t> nbParameters_;
+    unsigned int n_;
+    double precisionStep_;
+    unsigned int stepCount_;
+    double initialValue_;
+		
+  public:
+    /**
+     * @brief Build a new MetaOptimizer object.
+     *
+     * @param function The function to be optimized.
+     * @param desc     A MetaOptimizerInfos object describing the optimizers to use.
+     *                 The optimizer will own the instance of the MetaOptimizerInfos object.
+     * @param n        The number of progressive steps to use in optimization).
+     */
+    MetaOptimizer(Function* function, MetaOptimizerInfos* desc, unsigned int n = 1);
+
+    virtual ~MetaOptimizer();
+
+    MetaOptimizer(const MetaOptimizer& opt);
+
+    MetaOptimizer& operator=(const MetaOptimizer& opt);
+
+    MetaOptimizer* clone() const { return new MetaOptimizer(*this); }
+
+  public:
+		
+    void setFunction(Function* function)
+    { 
+      AbstractOptimizer::setFunction(function);
+      for(unsigned int i = 0; i < optDesc_->getNumberOfOptimizers(); i++)
+        optDesc_->getOptimizer(i)->setFunction(function);
+    }
+
+    void doInit(const ParameterList& parameters) throw (Exception);
+    
+    double doStep() throw (Exception);
+
+    /**
+     * @return The MetaOptimizerInfos object associated to this optimizer.
+     */
+    MetaOptimizerInfos* getOptimizers() { return optDesc_; }
+    
+    /**
+     * @return The MetaOptimizerInfos object associated to this optimizer.
+     */
+    const MetaOptimizerInfos* getOptimizers() const { return optDesc_; }
+
+  };
+
+} //end of namespace bpp.
+
+#endif //METAOPTIMIZER_H__
+
diff --git a/src/Bpp/Numeric/Function/NewtonBacktrackOneDimension.cpp b/src/Bpp/Numeric/Function/NewtonBacktrackOneDimension.cpp
new file mode 100644
index 0000000..888d56f
--- /dev/null
+++ b/src/Bpp/Numeric/Function/NewtonBacktrackOneDimension.cpp
@@ -0,0 +1,124 @@
+//
+// File: NewtonBacktrackOneDimension.cpp
+// Created by: Laurent Guéguen
+// Created on: jeudi 16 décembre 2010, à 15h 45
+//
+
+/*
+  Copyright or © or Copr. CNRS, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "NewtonBacktrackOneDimension.h"
+#include "../NumTools.h"
+#include "../../Text/TextTools.h"
+
+using namespace bpp;
+
+/******************************************************************************/
+
+NewtonBacktrackOneDimension::NewtonBacktrackOneDimension(Function* function, double slope, double test) :
+  AbstractOptimizer(function),
+  fold_(0), f_(0), a_(0), alam_(0), alamin_(0), alam2_(0), b_(0), disc_(0), f2_(0), rhs1_(0), rhs2_(0), slope_(slope), test_(test), tmplam_(0)
+    
+{
+  setDefaultStopCondition_(new NBODStopCondition(this));
+  setStopCondition(*getDefaultStopCondition());
+  setMaximumNumberOfEvaluations(10000);
+}
+
+/******************************************************************************/
+  
+void NewtonBacktrackOneDimension::doInit(const ParameterList& params) throw (Exception)
+{
+  // Set the initial value (no use here! Use setInitialValues() instead).
+  if(params.size() != 1) throw Exception("NewtonBacktrackOneDimension::init(). This optimizer only deals with one parameter.");
+  fold_ = getFunction()->f(getParameters());
+  getStopCondition()->setTolerance(getStopCondition()->getTolerance()/test_);
+  alamin_=getStopCondition()->getTolerance();
+  alam_=1;
+}
+
+/******************************************************************************/
+
+double NewtonBacktrackOneDimension::doStep() throw (Exception)
+{
+  if (alam_<alamin_){
+    getParameter_(0).setValue(0);
+    tolIsReached_=true;
+    return fold_;
+  }
+
+  getParameter_(0).setValue(alam_);
+  f_ = getFunction()->f(getParameters());
+
+  if (f_<=fold_+alam_*0.0001*slope_){
+    tolIsReached_=true;
+    return f_;
+  }
+
+  if (alam_==1){
+    tmplam_=-slope_/(2.0*(f_-fold_-slope_));
+    f2_=f_;
+    alam_=tmplam_>0.1?tmplam_:0.1;
+    return f_;
+  }
+  
+  rhs1_= f_-fold_-alam_*slope_;
+  rhs2_= f2_-fold_-alam2_*slope_;
+
+  a_=(rhs1_/(alam_*alam_)-rhs2_/(alam2_*alam2_))/(alam_-alam2_);
+  b_=(-alam2_*rhs1_/(alam_*alam_)+alam_*rhs2_/(alam2_*alam2_))/(alam_-alam2_);
+
+  if (a_==0.0)
+    tmplam_= -slope_/(2.0*b_);
+  else {
+    disc_=b_*b_-3.0*a_*slope_;
+    if (disc_<0.0)
+      tmplam_=0.5*alam_;
+    else
+      if (b_<=0)
+        tmplam_=(-b_+sqrt(disc_))/(3.0*a_);
+      else
+        tmplam_=-slope_/(b_+sqrt(disc_));
+  }
+  if (tmplam_> 0.5* alam_)
+    tmplam_=0.5*alam_;
+
+  alam2_=alam_;
+  f2_=f_;
+  alam_=tmplam_>0.1*alam_?tmplam_:0.1*alam_;
+
+  return f_;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/NewtonBacktrackOneDimension.h b/src/Bpp/Numeric/Function/NewtonBacktrackOneDimension.h
new file mode 100644
index 0000000..bfe2368
--- /dev/null
+++ b/src/Bpp/Numeric/Function/NewtonBacktrackOneDimension.h
@@ -0,0 +1,124 @@
+//
+// File: NewtonBacktrackOneDimension.h
+// Created by: Laurent Guéguen
+// Created on: jeudi 16 décembre 2010, à 15h 43
+//
+
+/*
+  Copyright or © or Copr. CNRS, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _NEWTONBACKTRACKONEDIMENSION_H_
+#define _NEWTONBACKTRACKONEDIMENSION_H_
+
+#include "AbstractOptimizer.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Newton's backtrack nearly optimization for one parameter.
+   *
+   *
+   * This algorithm looks for a value that 'sufficiently low' enough
+   * near the minimum of the function, but does not look for the
+   * minimum. It needs the first derivative of a function.
+   *
+   *  Search a 'sufficiently low' value for a function in a given
+   *  direction.
+   *
+   * This function implements the algorithm described for example in page 385 of
+   *
+   * <pre>
+   * NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING
+   * (ISBN 0-521-43108-5)
+   * </pre>
+   */
+
+  class NewtonBacktrackOneDimension:
+    public AbstractOptimizer
+  {
+  public:
+    class NBODStopCondition:
+      public AbstractOptimizationStopCondition
+    {
+    public:
+      NBODStopCondition(NewtonBacktrackOneDimension* bod):
+        AbstractOptimizationStopCondition(bod) {}
+      virtual ~NBODStopCondition() {}
+      
+      NBODStopCondition* clone() const { return new NBODStopCondition(*this); } 
+      
+    public:
+      void init() {}
+      bool isToleranceReached() const { return false; }
+      double getCurrentTolerance() const { return 0; }
+    };
+    
+    friend class NBODStopCondition;
+    
+  public:
+
+    /*
+     *@brief Constructor
+     @param function  a pointer to the function
+     @param slope the slope of the backtrack
+     @param test the inverse factor on the stop tolerance
+     *
+     */
+    
+    NewtonBacktrackOneDimension(Function* function, double slope, double test);
+    virtual ~NewtonBacktrackOneDimension() {}
+
+    NewtonBacktrackOneDimension* clone() const { return new NewtonBacktrackOneDimension(*this); }
+
+  private:
+    double fold_, f_, a_, alam_, alamin_, alam2_, b_, disc_, f2_, rhs1_, rhs2_, slope_, test_, tmplam_;
+    
+  public:
+		
+    void doInit(const ParameterList& params) throw (Exception);
+		
+    double doStep() throw (Exception);
+
+  protected:
+    DerivableFirstOrder* getFunction_()
+    {
+      return dynamic_cast<DerivableFirstOrder*>(AbstractOptimizer::getFunction_());
+    }
+    
+  };
+
+} //end of namespace bpp.
+
+#endif	//_NEWTONBACKTRACKONEDIMENSION_H_
+
diff --git a/src/Bpp/Numeric/Function/NewtonOneDimension.cpp b/src/Bpp/Numeric/Function/NewtonOneDimension.cpp
new file mode 100644
index 0000000..2887243
--- /dev/null
+++ b/src/Bpp/Numeric/Function/NewtonOneDimension.cpp
@@ -0,0 +1,122 @@
+//
+// File: NewtonOneDimension.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Apr 26 14:16 2007
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "NewtonOneDimension.h"
+#include "../NumTools.h"
+#include "../../Text/TextTools.h"
+
+using namespace bpp;
+
+/******************************************************************************/
+
+NewtonOneDimension::NewtonOneDimension(DerivableSecondOrder* function) :
+  AbstractOptimizer(function),
+  _param(),
+  _maxCorrection(10)
+{
+  setDefaultStopCondition_(new FunctionStopCondition(this));
+  setStopCondition(*getDefaultStopCondition());
+  nbEvalMax_ = 10000;
+}
+
+/******************************************************************************/
+  
+void NewtonOneDimension::doInit(const ParameterList& params) throw (Exception)
+{
+  // Set the initial value (no use here! Use setInitialValues() instead).
+  if (params.size() != 1)
+    throw Exception("NewtonOneDimension::init(). This optimizer only deals with one parameter.");
+  _param = params[0].getName();
+  currentValue_ = getFunction()->f(getParameters());  
+  getStopCondition()->init();
+}
+
+/******************************************************************************/
+
+double NewtonOneDimension::doStep() throw (Exception)
+{
+  double movement;  
+  ParameterList newPoint = getParameters();
+  ParameterList bckPoint = getFunction()->getParameters();
+  double newValue;
+  double  firstOrderDerivative = getFunction()->getFirstOrderDerivative(_param);
+  double secondOrderDerivative = getFunction()->getSecondOrderDerivative(_param);
+  if (secondOrderDerivative <= 0)
+  {
+    printMessage("!!! Second order derivative is negative (" + TextTools::toString(getParameters()[0].getValue()) + "). No move performed.");
+    //movements[i] = 0;  // We want to reach a minimum, not a maximum!
+    // My personnal improvement:
+    movement = -firstOrderDerivative / secondOrderDerivative;
+  }
+  else movement = firstOrderDerivative / secondOrderDerivative;
+  if (std::isnan(movement))
+  {
+    printMessage("!!! Non derivable point. No move performed. (f=" + TextTools::toString(currentValue_) + ", d1=" + TextTools::toString(firstOrderDerivative) + ", d2=" + TextTools::toString(secondOrderDerivative) + ").");
+    movement = 0; // Either first or second order derivative is infinity. This may happen when the function == inf at this point.
+  }
+  newPoint[0].setValue(getParameters()[0].getValue() - movement); 
+  newValue = getFunction()->f(newPoint);
+
+  // Check newValue:
+  unsigned int count = 0;
+  while (newValue > currentValue_)
+  {
+    //Restore previous point (all parameters in case of global constraint):
+    getFunction()->setParameters(bckPoint);
+
+    count++;
+    if (count >= _maxCorrection)
+    {
+      printMessage("!!! Felsenstein-Churchill correction applied too much time. Stopping here. Convergence probably not reached.");
+      tolIsReached_ = true;
+      return currentValue_;
+      //throw Exception("NewtonOneDimension::step(). Felsenstein-Churchill correction applied more than 10000 times.");
+    }
+    printMessage("!!! Function at new point is greater than at current point: " + TextTools::toString(newValue) + ">" + TextTools::toString(currentValue_) + ". Applying Felsenstein-Churchill correction, value = " + TextTools::toString(newPoint[0].getValue()));
+    movement = movement / 2;
+    newPoint[0].setValue(getParameters()[0].getValue() - movement);
+    newValue = getFunction()->f(newPoint);
+  }
+
+  getParameters_() = newPoint; // Function as been set to newPoint by the call of f(newPoint).
+  return newValue;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/NewtonOneDimension.h b/src/Bpp/Numeric/Function/NewtonOneDimension.h
new file mode 100644
index 0000000..18f27d4
--- /dev/null
+++ b/src/Bpp/Numeric/Function/NewtonOneDimension.h
@@ -0,0 +1,92 @@
+//
+// File: NewtonOneDimension.h
+// Created by: Julien Dutheil
+// Created on: Thu Apr 26 14:16 2007
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _NEWTONONEDIMENSION_H_
+#define _NEWTONONEDIMENSION_H_
+
+#include "AbstractOptimizer.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Newton's optimization for one parameter.
+ */
+class NewtonOneDimension:
+  public AbstractOptimizer
+{
+	private:
+    std::string _param;
+    unsigned int _maxCorrection;
+
+	public:
+		NewtonOneDimension(DerivableSecondOrder* function = 0);
+		virtual ~NewtonOneDimension() {}
+
+    NewtonOneDimension* clone() const { return new NewtonOneDimension(*this); }
+	
+	public:		
+		
+    const DerivableSecondOrder* getFunction() const
+    {
+      return dynamic_cast<const DerivableSecondOrder*>(AbstractOptimizer::getFunction());
+    }
+    DerivableSecondOrder* getFunction()
+    {
+      return dynamic_cast<DerivableSecondOrder*>(AbstractOptimizer::getFunction());
+    }
+
+    void doInit(const ParameterList& params) throw (Exception);
+		
+    double doStep() throw (Exception);
+
+    void setMaximumNumberOfCorrections(unsigned int mx) { _maxCorrection = mx; }
+	
+  protected:
+    DerivableSecondOrder* getFunction_()
+    {
+      return dynamic_cast<DerivableSecondOrder*>(AbstractOptimizer::getFunction_());
+    }
+    
+};
+
+} //end of namespace bpp.
+
+#endif	//_NEWTONONEDIMENSION_H_
+
diff --git a/src/Bpp/Numeric/Function/OneDimensionOptimizationTools.cpp b/src/Bpp/Numeric/Function/OneDimensionOptimizationTools.cpp
new file mode 100644
index 0000000..ac707cb
--- /dev/null
+++ b/src/Bpp/Numeric/Function/OneDimensionOptimizationTools.cpp
@@ -0,0 +1,259 @@
+//
+// File: OneDimensionOptimizationTools.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Nov 17 11:15:22 2003
+//
+
+/*
+  Copyright or © or Copr. CNRS, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus. This file is part of the Bio++ project.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "NewtonBacktrackOneDimension.h"
+#include "BrentOneDimension.h"
+#include "OneDimensionOptimizationTools.h"
+#include "../NumTools.h"
+#include "../NumConstants.h"
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************
+ *                              The Point class                               *
+ ******************************************************************************/
+ 
+inline void BracketPoint::set(double xval, double fval) { this->x = xval; this->f = fval; }	
+
+/******************************************************************************
+ *                             The Bracket class                              *
+ ******************************************************************************/
+ 
+inline void Bracket::setA(double xa, double fa) { a.set(xa, fa); }
+inline void Bracket::setB(double xb, double fb) { b.set(xb, fb); }
+inline void Bracket::setC(double xc, double fc) { c.set(xc, fc); }
+
+/******************************************************************************/
+	
+Bracket OneDimensionOptimizationTools::bracketMinimum(
+                                                      double a,
+                                                      double b,
+                                                      Function * function,
+                                                      ParameterList parameters)
+{
+  Bracket bracket;
+  // Copy the parameter to use.
+  bracket.a.x = a;
+  parameters[0].setValue(bracket.a.x); bracket.a.f = function->f(parameters);
+  bracket.b.x = b;
+  parameters[0].setValue(bracket.b.x); bracket.b.f = function->f(parameters);
+  if (bracket.b.f > bracket.a.f)
+    {		
+      // Switch roles of first and second point so that we can go downhill
+      // in the direction from a to b.
+      NumTools::swap<double>(bracket.a.x, bracket.b.x);
+      NumTools::swap<double>(bracket.a.f, bracket.b.f);
+    }
+	
+  // First guess for third point:
+  bracket.c.x = bracket.b.x + NumConstants::GOLDEN_RATIO_PHI() * (bracket.b.x - bracket.a.x);
+  parameters[0].setValue(bracket.c.x); bracket.c.f = function->f(parameters);
+	
+  // Keep returning here until we bracket:
+  while (bracket.b.f > bracket.c.f)
+    {
+      // Compute xu by parabolic extrapolation from a, b, c. TINY is used to prevent
+      // any possible division by 0.
+      double r = (bracket.b.x - bracket.a.x) * (bracket.b.f - bracket.c.f);
+      double q = (bracket.b.x - bracket.c.x) * (bracket.b.f - bracket.a.f);
+		
+      double xu = bracket.b.x - ((bracket.b.x - bracket.c.x) * q - (bracket.b.x - bracket.a.x) * r) /
+        (2.0 * NumTools::sign(NumTools::max(NumTools::abs(q - r), NumConstants::VERY_TINY()), q - r));
+      double xulim = (bracket.b.x) + GLIMIT * (bracket.c.x - bracket.b.x);
+      double fu;
+		
+      // We don't go farther than this.
+      // Test various possibilities:
+      if ((bracket.b.x - xu) * (xu - bracket.c.x) > 0.0)
+        {
+          parameters[0].setValue(xu); fu = function->f(parameters);
+          if (fu < bracket.c.f)
+            {
+              bracket.setA(bracket.b.x, bracket.b.f);
+              bracket.setB(xu, fu);
+              return bracket;
+            }
+          else if (fu > bracket.b.f)
+            {
+              bracket.setC(xu, fu);
+              return bracket;
+            }
+          // Parabolic fit was no use.
+          // Use default magnification.
+          xu = bracket.c.x + NumConstants::GOLDEN_RATIO_PHI() * (bracket.c.x - bracket.b.x);
+          parameters[0].setValue(xu); fu = function->f(parameters);
+        }
+      else if ((bracket.c.x - xu) * (xu - xulim) > 0.0)
+        {
+          // Parabolic fit is between point 3 and its allowed limit.
+          parameters[0].setValue(xu); fu = function->f(parameters);
+          if (fu < bracket.c.f)
+            {
+              NumTools::shift<double>(bracket.b.x, bracket.c.x, xu, bracket.c.x + NumConstants::GOLDEN_RATIO_PHI() * (bracket.c.x - bracket.b.x));
+              parameters[0].setValue(xu);
+              NumTools::shift<double>(bracket.b.f, bracket.c.f, fu, function->f(parameters));
+            }
+        }
+      else if ((xu - xulim) * (xulim - bracket.c.x) >= 0.0)
+        {
+          // Limit parabolic xu to maximum allowed value.
+          xu = xulim;
+          parameters[0].setValue(xu); fu = function->f(parameters);
+        }
+      else
+        {
+          // Reject parabolic xu, use default magnification.
+          xu = bracket.c.x + NumConstants::GOLDEN_RATIO_PHI() * (bracket.c.x - bracket.b.x);
+          parameters[0].setValue(xu); fu = function->f(parameters);
+        }
+      // Eliminate oldest point and continue.
+      NumTools::shift<double>(bracket.a.x, bracket.b.x, bracket.c.x, xu);
+      NumTools::shift<double>(bracket.a.f, bracket.b.f, bracket.c.f, fu);
+    }
+  return bracket;
+}
+
+/******************************************************************************/
+
+unsigned int OneDimensionOptimizationTools::lineMinimization(
+                                                             DirectionFunction& f1dim,
+                                                             ParameterList& parameters,
+                                                             std::vector<double>& xi,
+                                                             double tolerance,
+                                                             OutputStream* profiler,
+                                                             OutputStream* messenger,
+                                                             int verbose)
+{
+  // Initial guess for brackets:
+  double ax = 0.;
+  double xx = 0.01;
+  
+  f1dim.setConstraintPolicy(AutoParameter::CONSTRAINTS_AUTO);
+  f1dim.setMessageHandler(messenger);
+  f1dim.init(parameters, xi);
+  BrentOneDimension bod(&f1dim);
+  bod.setMessageHandler(messenger);
+  bod.setProfiler(profiler);
+  bod.setVerbose(verbose >= 1 ? 1 : 0);
+  bod.setOptimizationProgressCharacter(".");
+  bod.getStopCondition()->setTolerance(0.01);
+  bod.setInitialInterval(ax, xx);
+  bod.setConstraintPolicy(AutoParameter::CONSTRAINTS_KEEP);
+  ParameterList singleParameter;
+  singleParameter.addParameter(Parameter("x", 0.0));
+  bod.init(singleParameter);
+  bod.optimize();
+  //Update parameters:
+  //parameters.matchParametersValues(f1dim.getFunction()->getParameters());
+  
+  double xmin = f1dim.getParameters()[0].getValue();
+  for(size_t j = 0; j < parameters.size(); j++)
+  {
+    xi[j] *= xmin;
+    parameters[j].setValue(parameters[j].getValue() + xi[j]);
+  }
+  return bod.getNumberOfEvaluations();
+}
+
+/******************************************************************************/
+
+unsigned int OneDimensionOptimizationTools::lineSearch(DirectionFunction& f1dim,
+                                                       ParameterList& parameters,
+                                                       std::vector<double>& xi,
+                                                       std::vector<double>& gradient,
+                                                       OutputStream* profiler,
+                                                       OutputStream* messenger,
+                                                       int verbose)
+{
+  size_t size = xi.size();
+  
+  f1dim.setConstraintPolicy(AutoParameter::CONSTRAINTS_AUTO);
+  f1dim.setMessageHandler(messenger);
+  f1dim.init(parameters, xi);
+
+  double slope=0;
+  for (unsigned int i=0;i<size;i++)
+    slope+=xi[i]*gradient[i];
+
+  //  if (slope>=0)
+  //  throw Exception("Slope problem in OneDimensionOptimizationTools::lineSearch. Slope="+TextTools::toString(slope));
+
+  double x, temp, test=0;
+  for (unsigned int i=0;i<size;i++){
+    x=abs(parameters[i].getValue());
+    temp=abs(xi[i]);
+    if (x>1.0)
+      temp/=x;
+    if (temp>test)
+      test=temp;
+  }
+
+  NewtonBacktrackOneDimension nbod(&f1dim, slope, test);
+
+  nbod.setMessageHandler(messenger);
+  nbod.setProfiler(profiler);
+  nbod.setVerbose(verbose >= 1 ? 1 : 0);
+  nbod.setOptimizationProgressCharacter(".");
+  nbod.getStopCondition()->setTolerance(0.0001);
+  //  nbod.setInitialInterval(ax, xx);
+  nbod.setConstraintPolicy(AutoParameter::CONSTRAINTS_KEEP);
+  ParameterList singleParameter;
+  singleParameter.addParameter(Parameter("x", 0.0));
+  nbod.init(singleParameter);
+  nbod.optimize();
+  //Update parameters:
+  //parameters.matchParametersValues(f1dim.getFunction()->getParameters());
+  
+  double xmin = f1dim.getParameters()[0].getValue();
+  for(unsigned int j = 0; j < parameters.size(); j++)
+    {
+      xi[j] *= xmin;
+      parameters[j].setValue(parameters[j].getValue() + xi[j]);
+    }
+
+  return nbod.getNumberOfEvaluations();
+}
+
+/******************************************************************************/
+
+double OneDimensionOptimizationTools::GLIMIT = 100.0;
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/OneDimensionOptimizationTools.h b/src/Bpp/Numeric/Function/OneDimensionOptimizationTools.h
new file mode 100644
index 0000000..75ab4aa
--- /dev/null
+++ b/src/Bpp/Numeric/Function/OneDimensionOptimizationTools.h
@@ -0,0 +1,138 @@
+//
+// File: OneDimensionOptimizationTools.h
+// Created by: Julien Dutheil
+// Created on: Mon Nov 17 11:15:22 2003
+//
+
+/*
+  Copyright or © or Copr. CNRS, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus. This file is part of the Bio++ project.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _ONEDIMENSIONOPTIMIZATIONTOOLS_H_
+#define _ONEDIMENSIONOPTIMIZATIONTOOLS_H_
+
+#include "Functions.h"
+#include "DirectionFunction.h"
+#include "../../Io/OutputStream.h"
+
+namespace bpp
+{
+
+  class BracketPoint
+  {		
+  public:
+    double x;
+    double f;
+
+  public: // Constructor and destructor:
+    BracketPoint(): x(0), f(0) {}
+    BracketPoint(double xval, double fval): x(xval), f(fval) {}
+    virtual ~BracketPoint() {}
+		
+  public:
+    void set(double x, double f);
+		
+  };
+		
+  class Bracket
+  {	
+  public: // Constructor and destructor::
+    Bracket(): a(), b(), c() {}
+    virtual ~Bracket() {}
+			
+  public: // Methods:
+    void setA(double xa, double fa);
+    void setB(double xb, double fb);
+    void setC(double xc, double fc);
+			
+  public:
+    BracketPoint a, b, c;
+  };
+
+  /**
+   * @brief Tools of one parameter-functions optimizations.
+   *
+   * For now, contains only one method to bracket a minimum.
+   */
+  class OneDimensionOptimizationTools
+  {
+  public:
+    OneDimensionOptimizationTools() {}
+    virtual ~OneDimensionOptimizationTools() {}
+
+  public:
+		
+    /**
+     * @brief Bracket a minimum.
+     *
+     * Given a function func, and given distinct initial points x1 and x2,
+     * this routine searches in the downhill direction (defined by the function as
+     * evaluated at the initial points) and returns a Bracket object with new points
+     * a.x, b.x and c.x that bracket a minimum of the function. Also returned are the
+     * function values at the three points, a.f, b.f and c.f.
+     *
+     * @param a, b       Two initial values for the parameter.
+     * @param function   The function to bracket.
+     * @param parameters The parameter to use as a variable.
+     * @return           A bracket object.
+     */
+    static Bracket bracketMinimum(double a, double b, Function* function, ParameterList parameters);
+	
+    static unsigned int lineMinimization(DirectionFunction& f1dim, ParameterList& parameters, std::vector<double>& xi, double tolerance, OutputStream* profiler = 0, OutputStream* messenger = 0, int verbose = 2);
+
+    /**
+     * @brief Search a 'sufficiently low' value for a function in a given direction.
+     *
+     * This function performs a similar computation as the lnsrch function defined at page 385 of
+     *
+     * <pre>
+     * NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING
+     * (ISBN 0-521-43108-5)
+     * </pre>
+     * 
+     * without the stpmax argument, since the steps are bounded in another way.
+     */ 
+    static unsigned int lineSearch(DirectionFunction& f1dim, ParameterList& parameters, std::vector<double>& xi, std::vector<double>& gradient, OutputStream* profiler = 0, OutputStream* messenger = 0, int verbose = 2);
+                                 
+  public:
+		
+    /**
+     * @brief Maximum magnification allowed for a parabolic-fit step.
+     */
+    static double GLIMIT;
+	
+  };
+
+} //end of namespace bpp.
+
+#endif	//_ONEDIMENSIONOPTIMIZATIONTOOLS_H_
+
diff --git a/src/Bpp/Numeric/Function/OptimizationStopCondition.cpp b/src/Bpp/Numeric/Function/OptimizationStopCondition.cpp
new file mode 100644
index 0000000..9098c3c
--- /dev/null
+++ b/src/Bpp/Numeric/Function/OptimizationStopCondition.cpp
@@ -0,0 +1,241 @@
+//
+// File: OptimizationStopCondition.cpp
+// Created by: Julien Dutheil
+// Created on: Tue Dec 23 11:51:31 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "OptimizationStopCondition.h"
+#include "Optimizer.h"
+#include "../VectorTools.h"
+#include "../NumTools.h"
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+
+ParametersStopCondition::ParametersStopCondition(
+  const Optimizer* optimizer) :
+  AbstractOptimizationStopCondition(optimizer),
+  lastParametersEstimates_(),
+  newParametersEstimates_()
+{
+  init();
+  if (newParametersEstimates_.size() == 0)
+  {
+    cout << "DEBUG: WARNING!!! No parameter passed to ParametersStopCondition constructor. "
+         << "Be sure to have initialized the Optimizer first!" << endl; 
+  }
+}
+
+ParametersStopCondition::ParametersStopCondition(
+  const Optimizer* optimizer,
+  double tolerance) :
+  AbstractOptimizationStopCondition(optimizer, tolerance),
+  lastParametersEstimates_(),
+  newParametersEstimates_()
+{
+  init();
+  if (newParametersEstimates_.size() == 0)
+  {
+    cout << "DEBUG: WARNING!!! No parameter passed to ParametersStopCondition constructor. "
+         << "Be sure to have initialized the Optimizer first!" << endl; 
+  }
+}
+
+ParametersStopCondition::ParametersStopCondition(
+  const Optimizer* optimizer,
+  int burnin) :
+  AbstractOptimizationStopCondition(optimizer, burnin),
+  lastParametersEstimates_(),
+  newParametersEstimates_()
+{
+  init();
+  if (newParametersEstimates_.size() == 0)
+  {
+    cout << "DEBUG: WARNING!!! No parameter passed to ParametersStopCondition constructor. "
+         << "Be sure to have initialized the Optimizer first!" << endl; 
+  }
+}
+
+ParametersStopCondition::ParametersStopCondition(
+  const Optimizer* optimizer,
+  double tolerance,
+  int burnin) :
+  AbstractOptimizationStopCondition(optimizer, tolerance, burnin),
+  lastParametersEstimates_(),
+  newParametersEstimates_()
+{
+  init();
+  if (newParametersEstimates_.size() == 0)
+  {
+    cout << "DEBUG: WARNING!!! No parameter passed to ParametersStopCondition constructor. "
+         << "Be sure to have initialized the Optimizer first!" << endl; 
+  }
+}
+
+/******************************************************************************/
+
+void ParametersStopCondition::init()
+{
+  AbstractOptimizationStopCondition::init();
+  if (optimizer_->getFunction() != 0)
+    newParametersEstimates_ = optimizer_->getParameters();
+}
+
+/******************************************************************************/
+
+bool ParametersStopCondition::isToleranceReached() const
+{
+  callCount_++;
+  lastParametersEstimates_ = newParametersEstimates_;
+  newParametersEstimates_  = optimizer_->getParameters();
+  if (callCount_ <= burnin_) return false;
+  for (unsigned int i = 0; i < newParametersEstimates_.size(); i++)
+  {
+    Parameter& p = newParametersEstimates_[i];
+    double lastEstimate = lastParametersEstimates_.getParameter(p.getName()).getValue();
+    double newEstimate = p.getValue();
+    double tol = NumTools::abs<double>(newEstimate - lastEstimate);
+    if (tol > tolerance_)
+    {
+      return false;
+    }
+  }
+  return true;
+}
+
+/******************************************************************************/
+
+double ParametersStopCondition::getCurrentTolerance() const
+{
+  if (callCount_ > burnin_) {
+    double maxTol = 0.;
+    for (unsigned int i = 0; i < newParametersEstimates_.size(); i++)
+    {
+      Parameter& p = newParametersEstimates_[i];
+      double lastEstimate = lastParametersEstimates_.getParameter(p.getName()).getValue();
+      double newEstimate = p.getValue();
+      double tol = NumTools::abs<double>(newEstimate - lastEstimate);
+      if (tol > maxTol)
+        maxTol = tol;
+    }
+    return maxTol;
+  } else {
+    return std::max(tolerance_, 1.);
+  }
+}
+
+/******************************************************************************/
+
+FunctionStopCondition::FunctionStopCondition(
+  const Optimizer* optimizer) :
+  AbstractOptimizationStopCondition(optimizer),
+  lastFunctionValue_(-log(0.)),
+  newFunctionValue_(-log(0.))
+{
+  init();
+}
+
+FunctionStopCondition::FunctionStopCondition(
+  const Optimizer* optimizer,
+  double tolerance) :
+  AbstractOptimizationStopCondition(optimizer, tolerance),
+  lastFunctionValue_(-log(0.)),
+  newFunctionValue_(-log(0.))
+{
+  init();
+}
+
+FunctionStopCondition::FunctionStopCondition(
+  const Optimizer* optimizer,
+  int burnin) :
+  AbstractOptimizationStopCondition(optimizer, burnin),
+  lastFunctionValue_(-log(0.)),
+  newFunctionValue_(-log(0.))
+{
+  init();
+}
+
+FunctionStopCondition::FunctionStopCondition(
+  const Optimizer* optimizer,
+  double tolerance,
+  int burnin) :
+  AbstractOptimizationStopCondition(optimizer, tolerance, burnin),
+  lastFunctionValue_(-log(0.)),
+  newFunctionValue_(-log(0.))
+{
+  init();
+}
+
+FunctionStopCondition::~FunctionStopCondition() {}
+
+/******************************************************************************/
+
+void FunctionStopCondition::init()
+{
+  AbstractOptimizationStopCondition::init();
+  newFunctionValue_ = -log(0.);
+  if (optimizer_->getFunction() != 0)
+  {
+    newFunctionValue_ = optimizer_->getFunctionValue();
+  }
+}
+
+/******************************************************************************/
+
+bool FunctionStopCondition::isToleranceReached() const
+{
+  callCount_++;
+  lastFunctionValue_ = newFunctionValue_;
+  newFunctionValue_  = optimizer_->getFunctionValue();
+  if (callCount_ <= burnin_) return false;
+  double tol = NumTools::abs<double>(newFunctionValue_ - lastFunctionValue_);
+  return tol < tolerance_;
+}
+
+/******************************************************************************/
+
+double FunctionStopCondition::getCurrentTolerance() const
+{
+  if (callCount_ > burnin_)
+    return NumTools::abs<double>(newFunctionValue_ - lastFunctionValue_);
+  else
+    return std::max(tolerance_, 1.);
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/OptimizationStopCondition.h b/src/Bpp/Numeric/Function/OptimizationStopCondition.h
new file mode 100644
index 0000000..3501205
--- /dev/null
+++ b/src/Bpp/Numeric/Function/OptimizationStopCondition.h
@@ -0,0 +1,313 @@
+//
+// File: OptimizationStopCondition.h
+// Created by: Julien Dutheil
+// Created on: Tue Dec 23 11:51:31 2003
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _OPTIMIZATIONSTOPCONDITION_H_
+#define _OPTIMIZATIONSTOPCONDITION_H_
+
+#include "../ParameterList.h"
+
+using namespace std;
+
+namespace bpp
+{
+
+  class Optimizer;
+	
+  /******************************************************************************/
+
+  /**
+   * @brief Interface for otimization stop condition objet.
+   *
+   * Classes implementing the OptimizationStopCondition interface
+   * provides the isToleranceReached() function that tells when
+   * the optimization process reached a given tolerance parameter.
+   * This parameter may be set or retrieve using the setTolerance()
+   * and getTolerance() functions.
+   *
+   * OptimizationStopCondition implementations may be general and work on
+   * parameter (@see ParametersStopCondition) or function (@see FunctionStopCondition) values,
+   * or be specific to a given optimization method.
+   */
+  class OptimizationStopCondition:
+    public virtual Clonable
+  {
+  public:
+    OptimizationStopCondition() {}
+    virtual ~OptimizationStopCondition() {}
+
+#ifndef NO_VIRTUAL_COV
+    OptimizationStopCondition *
+#else
+    Clonable*
+#endif
+    clone() const = 0;
+	
+  public:
+
+    /**
+     * @return The optimizer to which this instance belongs to. 
+     */
+    virtual const Optimizer* getOptimizer() const = 0;
+    /**
+     * @brief Set the optimizer attached to this instance.
+     *
+     * @param optimizer The optimizer to which this instance belongs to. 
+     */
+    virtual void setOptimizer(const Optimizer* optimizer) = 0;
+
+    /**
+     * @brief Initialize the condition.
+     */
+    virtual void init() = 0;
+
+    /**
+     * @brief Tell if the we reached the desired tolerance with a given 
+     * new set of estimates.
+     *
+     * The new parameter list is compared to the last estimates,
+     * and the lastParameterEstimates list is actulaized with the newParameters list.
+     *
+     * @return True if the tolerance level is reached.
+     */
+    virtual bool isToleranceReached() const = 0;
+		
+    /**
+     * @brief Set the tolerance parameter.
+     *
+     * @param tolerance The tolerance parameter.
+     */	
+    virtual void setTolerance(double tolerance) = 0;
+
+    /**
+     * @brief Get the tolerance parameter.
+     *
+     * @return The tolerance parameter.
+     */	
+    virtual double getTolerance() const = 0;
+    
+    /**
+     * @brief Get the current tolerance.
+     *
+     * This is computed from the last check performed.
+     * Initially, it is equal to the tolerance parameter.
+     *
+     * @return The current tolerance achieved.
+     */	
+    virtual double getCurrentTolerance() const = 0;
+  };
+
+  /******************************************************************************/
+
+  /**
+   * @brief Partial implementation of the OptimizationStopCondition interface.
+   *
+   * This class provides:
+   * - A pointer toward the Optimizer this objet deals with,
+   * - A tolerance value,
+   * - A counter of the number of calls toward the isToleranceReached() function,
+   * - A burnin function, that prohibe the optimization to stop prematurely.
+   */   
+  class AbstractOptimizationStopCondition:
+    public virtual OptimizationStopCondition
+  {
+  protected:
+    const Optimizer* optimizer_;
+    double tolerance_;
+
+    /**
+     * @brief Count the number of times the isToleranceReached() function
+     * has been called.
+     */
+    mutable double callCount_;
+	
+    int burnin_;
+	
+  public:
+    AbstractOptimizationStopCondition(const Optimizer* optimizer):
+        optimizer_(optimizer),
+        tolerance_(0.000001),
+        callCount_(0),
+        burnin_(0) {}
+    
+    AbstractOptimizationStopCondition(const Optimizer* optimizer, double tolerance):
+        optimizer_(optimizer),
+        tolerance_(tolerance),
+        callCount_(0),
+        burnin_(0) {}
+
+    AbstractOptimizationStopCondition(const Optimizer* optimizer, int burnin):
+        optimizer_(optimizer),
+        tolerance_(0.000001),
+        callCount_(0),
+        burnin_(burnin) {}
+
+    AbstractOptimizationStopCondition(const Optimizer* optimizer, double tolerance, int burnin):
+        optimizer_(optimizer),
+        tolerance_(tolerance),
+        callCount_(0),
+        burnin_(burnin) {}
+
+    AbstractOptimizationStopCondition(const AbstractOptimizationStopCondition& aosc):
+        optimizer_(aosc.optimizer_),
+        tolerance_(aosc.tolerance_),
+        callCount_(aosc.callCount_),
+        burnin_(aosc.burnin_) {}
+	
+    AbstractOptimizationStopCondition& operator=(const AbstractOptimizationStopCondition& aosc)
+    {
+      optimizer_ = aosc.optimizer_;
+      tolerance_ = aosc.tolerance_;
+      callCount_ = aosc.callCount_;
+      burnin_    = aosc.burnin_;
+      return *this;
+    }
+
+    virtual ~AbstractOptimizationStopCondition() {}
+
+  public:
+    const Optimizer* getOptimizer() const { return optimizer_; }
+    void setOptimizer(const Optimizer* optimizer) { optimizer_ = optimizer; }
+    void setTolerance(double tolerance) { tolerance_ = tolerance; }
+    double getTolerance() const { return tolerance_; }
+    void init() { resetCounter(); }
+    virtual void resetCounter() { callCount_ = 0; }
+    virtual void setBurnin(int burnin) { burnin_ = burnin; }
+    virtual int getBurnin() const { return burnin_; }
+
+  };
+	
+  /******************************************************************************/
+
+  /**
+   * @brief Stop condition on parameters.
+   *
+   * This stops the optimization when \f$\forall i\; |\lambda_{i,t}-\lambda_{i,t-1}| \leq \mbox{tolerance}\f$,
+   * where \f$\lambda_{i, t}\f$ is the value of the ith parameter at iteration \f$t\f$,
+   * and \f$\lambda_{i, t-1}\f$ is the value of the ith parameter at iteration \f$t-1\f$.
+   */
+  class ParametersStopCondition:
+    public AbstractOptimizationStopCondition
+  {
+  private:
+
+    /**
+     * @brief The last estimates of the parameters.
+     *
+     * This is used by the isToleranceReached() method.
+     */
+    mutable ParameterList lastParametersEstimates_;
+		
+    /**
+     * @brief The new estimates of the parameters.
+     *
+     * This is used by the isToleranceReached() method.
+     */
+    mutable ParameterList newParametersEstimates_;
+	
+  public:
+    ParametersStopCondition(const Optimizer* optimizer);
+    ParametersStopCondition(const Optimizer* optimizer, double tolerance);
+    ParametersStopCondition(const Optimizer* optimizer, int burnin);
+    ParametersStopCondition(const Optimizer* optimizer, double tolerance, int burnin);
+		
+    virtual ~ParametersStopCondition() {}
+
+    ParametersStopCondition* clone() const { return new ParametersStopCondition(*this); }
+	
+  public:
+    void init();
+
+    bool isToleranceReached() const;
+    
+    double getCurrentTolerance() const;
+  };
+
+  /******************************************************************************/
+
+  /**
+   * @brief Stop condition on function value.
+   *
+   * This stops the optimization when \f$|f\left(\left\{\lambda_{i,t}\right\}\right)-f\left(\left\{\lambda_{i,t-1}\right\}\right)| \leq \mbox{tolerance}\f$,
+   * where \f$f\left(\left\{\lambda_{i, t}\right\}\right)\f$ is the value of the function given the parameter values at iteration \f$t\f$,
+   * and \f$f\left(\left\{\lambda_{i, t-1}\right\}\right)\f$ is the value of the function given the parameter velues at iteration \f$t-1\f$.
+   */
+  class FunctionStopCondition:
+    public AbstractOptimizationStopCondition
+  {
+  private:
+    /**
+     * @brief The last value of the function.
+     *
+     * This is used by the isToleranceReached() method.
+     */
+    mutable double lastFunctionValue_;
+		
+    /**
+     * @brief The new value of the function.
+     *
+     * This is used by the isToleranceReached() method.
+     */
+    mutable double newFunctionValue_;
+	
+  public:
+    FunctionStopCondition(const Optimizer* optimizer);
+    FunctionStopCondition(const Optimizer* optimizer, double tolerance);
+    FunctionStopCondition(const Optimizer* optimizer, int burnin);
+    FunctionStopCondition(const Optimizer* optimizer, double tolerance, int burnin);
+		
+    virtual ~FunctionStopCondition();
+
+#ifndef NO_VIRTUAL_COV
+    FunctionStopCondition*
+#else
+    Clonable*
+#endif
+    clone() const { return new FunctionStopCondition(*this); }
+	
+  public:
+    void init();
+    bool isToleranceReached() const;
+    double getCurrentTolerance() const;
+
+  };
+
+} //end of namespace bpp.
+
+#endif	//_OPTIMIZATIONSTOPCONDITION_H_
+
diff --git a/src/Bpp/Numeric/Function/Optimizer.h b/src/Bpp/Numeric/Function/Optimizer.h
new file mode 100644
index 0000000..2231bad
--- /dev/null
+++ b/src/Bpp/Numeric/Function/Optimizer.h
@@ -0,0 +1,402 @@
+//
+// File: Optimizer.h
+// Created by: Julien Dutheil
+// Created on: Tue Nov  4 16:01:27 2003
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _OPTIMIZER_H_
+#define _OPTIMIZER_H_
+
+#include "Functions.h"
+#include "../ParameterList.h"
+#include "OptimizationStopCondition.h"
+#include "../../Clonable.h"
+#include "../../Io/OutputStream.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief An event object which indicates that an optimization event occured.
+   */
+  class OptimizationEvent
+  {
+  private:
+    Optimizer* optimizer_;
+
+  public:
+
+    /**
+     * @param optimizer A pointer toward the optimizer that launched the event.
+     */
+    OptimizationEvent(Optimizer* optimizer): optimizer_(optimizer) {}
+    OptimizationEvent(const OptimizationEvent& oe): optimizer_(oe.optimizer_) {}
+    OptimizationEvent& operator=(const OptimizationEvent& oe)
+    {
+      optimizer_ = oe.optimizer_;
+      return *this;
+    }
+    virtual ~OptimizationEvent() {}
+
+  public:
+    
+    /**
+     * @return A pointer toward the optimizer that launched the event.
+     */
+    Optimizer* getOptimizer() { return optimizer_; }
+    
+    /**
+     * @return A pointer toward the optimizer that launched the event.
+     */
+    const Optimizer* getOptimizer() const { return optimizer_; }
+  };
+
+
+
+
+
+
+  /**
+   * @brief The listener interface for receiving optimization events.
+   * 
+   * The class that is interested in processing an optimization event implements this interface,
+   * and the object created with that class is registered with a component,
+   * using the component's addOptimizationListener method.
+   * More kinds of events may be processed in the future.
+   */
+  class OptimizationListener
+  {
+  public:
+    OptimizationListener() {}
+    virtual ~OptimizationListener() {}
+
+  public:
+    virtual void optimizationInitializationPerformed(const OptimizationEvent& event) = 0;
+    virtual void optimizationStepPerformed(const OptimizationEvent& event) = 0;
+    /**
+     * @return 'true' If this listener modifies the parameter set.
+     */
+    virtual bool listenerModifiesParameters() const = 0;
+  };
+
+
+  
+  
+
+  /**
+   * @brief This is the basal interface for all optimization methods.
+   * 
+   * An optimizer deals with Function objects.
+   * Optimizer objects are event-driven: they notify listeners when a step is performed.
+   */
+  class Optimizer:
+    public virtual Clonable
+  {
+  public:
+    Optimizer() {}
+    virtual ~Optimizer() {}
+
+#if defined(NO_VIRTUAL_COV)
+    Clonable* clone() const = 0;
+#else
+    Optimizer* clone() const = 0;
+#endif
+	
+  public:
+		
+    /**
+     * @brief Set the initial values of the parameters.
+     *
+     * @param params The initial values of parameters.
+     * @throw Exception If a problem occured during initialization.
+     */
+    virtual void init(const ParameterList& params) throw (Exception) = 0;
+
+    /**
+     * @return 'true' if this optimizer has been initialized.
+     */
+    virtual bool isInitialized() const = 0;
+
+    /**
+     * @brief Perform an optimization step.
+     *
+     * @return the value of the function after this step.
+     * @throw Exception If a problem occured during optimization or if the optimizer has not been initialized.
+     */
+    virtual double step() throw (Exception) = 0;
+
+    /**
+     * @return The parameters with their current values.
+     */
+    virtual const ParameterList& getParameters() const = 0;
+
+    /**
+     * @return The value associated with a given parameter name.
+     */
+    
+    virtual double getParameterValue(const std::string& name) const = 0;
+    /**
+     * @brief Get the current function value.
+     *
+     * @return The value of the function at the point specified by _parameters.
+     * @throw NullPointerException If no function is associated with this optimizer.
+     */
+      virtual double getFunctionValue() const throw (NullPointerException) = 0;
+		
+    /**
+     * @brief Perform as many optimization steps untill the stop condition is met.
+     *
+     * @return The value of the function after optimization is completed.
+     * @throw Exception If a problem occured during optimization or if the optimizer has not been initialized.
+     */
+    virtual double optimize() throw (Exception) = 0;
+	
+    /**
+     * @brief Set the function to optimize.
+     *
+     * @param function The function to optimize.
+     */
+    virtual void setFunction(Function* function) = 0;
+		
+    /**
+     * @brief Get the current function being optimized.
+     *
+     * @return A const pointer toward the function being optimized.
+     */
+    virtual const Function* getFunction() const = 0;
+
+    /**
+     * @brief Get the current function being optimized.
+     *
+     * @return A const pointer toward the function being optimized.
+     */
+    virtual Function* getFunction() = 0;
+
+    /**
+     * @brief Tell if a funciton is associatied to this optimizer.
+     *
+     * @return True if a function has been associated to this optimizer.
+     */
+    virtual bool hasFunction() const = 0;
+
+    /**
+     * @brief Set the message handler for this optimizer.
+     *
+     * The message handler keeps all messages that the optimizer may send.
+     * The default handler is set to standard output, but you can pass any
+     * ostream object (cerr, ofstream, etc.).
+     *
+     * A NULL pointer disables message output.
+     *
+     * @param mh The message handler to use.
+     */
+    virtual void setMessageHandler(OutputStream* mh) = 0;
+		
+    /**
+     * @return The stream used for handling messages, if any.
+     */
+    virtual OutputStream* getMessageHandler() const = 0;
+		
+    /**
+     * @brief Set the profiler for this optimizer.
+     *
+     * The profiler keeps all the intermediate values taken by the parameters.
+     * The default profiler is set to standard output, but you can pass any
+     * ostream object (cerr, ofstream, etc.).
+     *
+     * A NULL pointer disables message output.
+     * 
+     * @param profiler The profiler to use.
+     */
+    virtual void setProfiler(OutputStream* profiler) = 0;
+		
+    /**
+     * @return The stream used for profiling, if any.
+     */
+    virtual OutputStream* getProfiler() const = 0;
+		
+    /**
+     * @brief Get the number of function evaluations performed since the
+     * call of the init function.
+     *
+     * @return The number of function evaluations.
+     */
+    virtual	unsigned int getNumberOfEvaluations() const = 0;
+		
+    /**
+     * @brief Set the stop condition of the optimization algorithm.
+     *
+     * @param stopCondition The stop condition to use while optimizing.
+     * @see OptimizationStopCondition.
+     */
+    virtual void setStopCondition(const OptimizationStopCondition& stopCondition) = 0;
+
+    /**
+     * @brief Get the stop condition of the optimization algorithm.
+     *
+     * @return The stop condition used while optimizing.
+     */
+    virtual OptimizationStopCondition* getStopCondition() = 0;
+
+    /**
+     * @brief Get the stop condition of the optimization algorithm.
+     *
+     * @return The stop condition used while optimizing.
+     */
+    virtual const OptimizationStopCondition* getStopCondition() const = 0;
+
+    /**
+     * @brief Get the default stop condition of the optimization algorithm.
+     *
+     * @return The default stop condition used while optimizing.
+     */
+    virtual OptimizationStopCondition* getDefaultStopCondition() = 0;
+		
+    /**
+     * @brief Get the default stop condition of the optimization algorithm.
+     *
+     * @return The default stop condition used while optimizing.
+     */
+    virtual const OptimizationStopCondition* getDefaultStopCondition() const = 0;
+		
+    /**
+     * @brief Tell if the tolerance level is reached.
+     *
+     * @return Whether the tolerance is reached or not.
+     * @see OptimizationStopCondition
+     */
+    virtual bool isToleranceReached() const = 0;
+		
+    /**
+     * @brief Tell if the maximum number of function evaluations is reached.
+     *
+     * @return Whether the maximum number of function evaluations is reached or not.
+     */
+    virtual bool isMaximumNumberOfEvaluationsReached() const = 0;
+
+    /**
+     * @brief Set the maximum number of function evaluation to perform during optimization.
+     *
+     * @param max The maximum number of evaluations to perform.
+     */
+    virtual void setMaximumNumberOfEvaluations(unsigned int max) = 0;
+
+    /**
+     * @brief Set the verbose level.
+     *
+     * 0 = off
+     * 1 = on
+     * 2 = more verbose
+     * 3 = even more, etc.
+     *
+     * In most cases, only the 0 and 1 levels are implemented.
+     *
+     * @param v verbose level.
+     */
+    virtual void setVerbose(unsigned int v) = 0;
+
+    /**
+     * @brief Get the verbose level.
+     *
+     * @return verbose level.
+     */
+    virtual unsigned int getVerbose() const = 0;
+
+    /**
+     * @brief Set the constraint policy for this optimizer.
+     *
+     * @param constraintPolicy The constraint policy.
+     */
+    virtual void setConstraintPolicy(const std::string & constraintPolicy) = 0;
+
+    /**
+     * @brief Get the constraint policy for this optimizer.
+     *
+     * @return The constraint policy.
+     */
+    virtual std::string getConstraintPolicy() const = 0;
+
+    /**
+     * @brief Register a listener to this class.
+     *
+     * All registered listeners will be informed when an optimization event occur.
+     * See the documentation of the class to know what kind of events are supported.
+     *
+     * @param listener A listener to be registered with.
+     */
+    virtual void addOptimizationListener(OptimizationListener * listener) = 0; 
+
+  };
+
+
+
+
+
+  /**
+   * @brief Save intermediate optimization results to file.
+   */
+  class BackupListener:
+    public OptimizationListener
+  {
+  private:
+    std::string backupFile_;
+
+  public:
+    BackupListener(const string& backupFile):
+      backupFile_(backupFile) {}
+
+    virtual ~BackupListener() {}
+
+  public:
+    void optimizationInitializationPerformed(const OptimizationEvent& event) {}
+    
+    void optimizationStepPerformed(const OptimizationEvent& event) {
+      std::ofstream bck(backupFile_.c_str(), std::ios::out);
+      bck << "f(x)=" << setprecision(20) << event.getOptimizer()->getFunction()->getValue() << endl;
+      ParameterList pl = event.getOptimizer()->getFunction()->getParameters();
+      for (unsigned int i = 0; i < pl.size(); ++i) {
+        bck << pl[i].getName() << "=" <<  setprecision(20) << pl[i].getValue() << std::endl;
+      }
+      bck.close();
+    }
+    
+    bool listenerModifiesParameters() const { return false; };
+  };
+
+} //end of namespace bpp.
+
+#endif	//_OPTIMIZER_H_
+
diff --git a/src/Bpp/Numeric/Function/PowellMultiDimensions.cpp b/src/Bpp/Numeric/Function/PowellMultiDimensions.cpp
new file mode 100644
index 0000000..6f164f3
--- /dev/null
+++ b/src/Bpp/Numeric/Function/PowellMultiDimensions.cpp
@@ -0,0 +1,170 @@
+//
+// File: PowellMultiDimensions.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Nov 17 15:16:45 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "PowellMultiDimensions.h"
+#include "BrentOneDimension.h"
+#include "OneDimensionOptimizationTools.h"
+#include "../NumTools.h"
+
+using namespace bpp;
+
+/******************************************************************************/
+
+bool PowellMultiDimensions::PMDStopCondition::isToleranceReached() const {
+  callCount_++;
+  if (callCount_ <= burnin_) return false;
+  return getCurrentTolerance() < tolerance_;
+}
+
+double PowellMultiDimensions::PMDStopCondition::getCurrentTolerance() const
+{
+  // NRC Test for done:
+  const PowellMultiDimensions* pmd = dynamic_cast<const PowellMultiDimensions*>(optimizer_);
+  double fp   = pmd->fp_;
+  double fret = pmd->fret_;
+  return 2.0 * NumTools::abs(fp - fret) / (NumTools::abs(fp) + NumTools::abs(fret));
+}
+    
+/******************************************************************************/
+
+PowellMultiDimensions::PowellMultiDimensions(Function* function) :
+AbstractOptimizer(function), fp_(0), fret_(0), pt_(), xi_(), ncom_(0), pcom_(), xicom_(), f1dim_(function)
+{
+  setDefaultStopCondition_(new PMDStopCondition(this));
+  setStopCondition(*getDefaultStopCondition());
+}
+
+/******************************************************************************/
+
+void PowellMultiDimensions::doInit(const ParameterList& params) throw (Exception)
+{
+  // Build the initial matrix:
+  size_t n = params.size();
+  xi_.resize(n);
+  for (size_t i = 0; i < n; i++)
+  {
+    // Copy the parameter list:
+    xi_[i].resize(n);
+    for(unsigned int j = 0; j < n; j++)
+    {
+      // Set the directions to unit vectors:
+      xi_[i][j] = (j == i) ? 1 : 0;
+    }
+  }
+  
+  // Starting point:
+  fret_ = getFunction()->f(getParameters());
+  pt_   = getParameters();
+}
+  
+/******************************************************************************/
+  
+double PowellMultiDimensions::doStep() throw (Exception)
+{
+  size_t n = getParameters().size();
+  fp_ = fret_;
+  unsigned int ibig = 0;
+  double del = 0.0; // Will be the biggest function decrease
+  Vdouble xit(n);
+  
+  // In each iteration, loop over all directions in the set.
+  double fptt;
+  for(unsigned int i = 0; i < n; i++)
+  {
+    // Copy the direction:
+    for(unsigned int j = 0; j < n; j++)
+    {
+      xit[j] = xi_[j][i];
+    }
+    fptt = fret_;
+    nbEval_ += OneDimensionOptimizationTools::lineMinimization(f1dim_,
+        getParameters_(), xit, getStopCondition()->getTolerance(),
+        0, getMessageHandler(), getVerbose() > 0 ? getVerbose() - 1 : 0);
+    fret_ = getFunction()->f(getParameters());
+    if (getVerbose() > 2) printPoint(getParameters(), fret_);
+    if (fret_ > fp_) throw Exception("DEBUG: PowellMultiDimensions::doStep(). Line minimization failed!");
+    if (fptt - fret_ > del)
+    {
+      del = fptt - fret_;
+      ibig = i;
+    }
+  }
+
+  ParameterList ptt = getParameters();
+  for (unsigned int j = 0; j < n; j++)
+  {
+    ptt[j].setValue(2.0 * getParameters()[j].getValue() - pt_[j].getValue());
+    xit[j] = getParameters()[j].getValue() - pt_[j].getValue();
+    pt_[j].setValue(getParameters()[j].getValue());
+  }
+  fptt = getFunction()->f(ptt);
+  if (fptt < fp_)
+  {
+    double t = 2.0 * (fp_ - 2.0 * fret_ + fptt) * NumTools::sqr(fp_ - fret_ - del) - del * NumTools::sqr(fp_ - fptt);
+    if (t < 0.0)
+    {
+      //cout << endl << "New direction: drection " << ibig << " removed." << endl;
+      nbEval_ += OneDimensionOptimizationTools::lineMinimization(f1dim_,
+          getParameters_(), xit, getStopCondition()->getTolerance(),
+          0, getMessageHandler(), getVerbose() > 0 ? getVerbose() - 1 : 0);
+      fret_ = getFunction()->f(getParameters());
+      if (fret_ > fp_) throw Exception("DEBUG: PowellMultiDimensions::doStep(). Line minimization failed!");
+      for (unsigned int j = 0; j < n; j++)
+      {
+        xi_[j][ibig]  = xi_[j][n - 1];
+        xi_[j][n - 1] = xit[j];
+      }
+    }
+  }
+  else getFunction()->setParameters(getParameters());
+
+  return fret_;
+}
+
+/******************************************************************************/
+
+double PowellMultiDimensions::optimize() throw (Exception)
+{
+  AbstractOptimizer::optimize();
+  // Apply best parameter:
+  return getFunction()->f(getParameters());
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/PowellMultiDimensions.h b/src/Bpp/Numeric/Function/PowellMultiDimensions.h
new file mode 100644
index 0000000..f65897a
--- /dev/null
+++ b/src/Bpp/Numeric/Function/PowellMultiDimensions.h
@@ -0,0 +1,115 @@
+//
+// File: PowellMultiDimensions.h
+// Created by: Julien Dutheil
+// Created on: Mon Nov 17 15:16:45 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+zs a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef POWELLMULTIDIMENSIONS_H__
+#define POWELLMULTIDIMENSIONS_H__
+
+#include "DirectionFunction.h"
+#include "AbstractOptimizer.h"
+#include "../VectorTools.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Powell's multi-dimensions optimization algorithm for one parameter.
+ *
+ * A description of the algorithm can be found for example in:
+ * <pre>
+ * NUMERICAL RECIPES IN C: THE ART OF SCIENTIFIC COMPUTING
+ * (ISBN 0-521-43108-5)
+ * </pre>
+ */
+class PowellMultiDimensions:
+  public AbstractOptimizer
+{
+	public:
+		class PMDStopCondition:
+      public AbstractOptimizationStopCondition
+		{
+			public:
+				PMDStopCondition(PowellMultiDimensions* pmd):
+          AbstractOptimizationStopCondition(pmd) {}
+				virtual ~PMDStopCondition() {}
+
+        PMDStopCondition* clone() const { return new PMDStopCondition(*this); }
+			
+			public:
+				bool isToleranceReached() const;
+        double getCurrentTolerance() const;
+		};
+	
+	friend class PMDStopCondition;
+		
+	protected:
+		double fp_;
+		double fret_;
+		ParameterList pt_;
+		VVdouble xi_;
+		
+		unsigned int ncom_;
+		ParameterList pcom_, xicom_;
+		DirectionFunction f1dim_;
+		
+	public:
+		PowellMultiDimensions(Function* function);
+		virtual ~PowellMultiDimensions() {}
+
+    PowellMultiDimensions* clone() const { return new PowellMultiDimensions(*this); }
+	
+	public:		
+		
+		/**
+		 * @name The Optimizer interface.
+		 *
+		 * @{
+		 */		
+		double optimize() throw (Exception);
+		/** @} */
+
+		void doInit(const ParameterList & params) throw (Exception);
+		
+    double doStep() throw (Exception);	
+	
+};
+
+} //end of namespace bpp.
+
+#endif	//_POWELLMULTIDIMENSIONS_H_
+
diff --git a/src/Bpp/Numeric/Function/ReparametrizationFunctionWrapper.cpp b/src/Bpp/Numeric/Function/ReparametrizationFunctionWrapper.cpp
new file mode 100644
index 0000000..620da3d
--- /dev/null
+++ b/src/Bpp/Numeric/Function/ReparametrizationFunctionWrapper.cpp
@@ -0,0 +1,194 @@
+//
+// File: ReparametrizationFunctionWrapper.h
+// Created by: Julien Dutheil
+// Created on: Fri Jan  30 09:30 2009
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "ReparametrizationFunctionWrapper.h"
+#include "../../App/ApplicationTools.h"
+#include <typeinfo>
+using namespace bpp;
+using namespace std;
+
+void ReparametrizationFunctionWrapper::init_(bool verbose)
+{
+  for (unsigned int i = 0; i < functionParameters_.size(); i++)
+  {
+    Parameter& p = functionParameters_[i];
+    Constraint* constraint = p.getConstraint();
+    const string name = p.getName();
+    double value = p.getValue();
+    if (!constraint)
+    {
+      if (verbose)
+        ApplicationTools::displayMessage("Parameter " + name + " does not need to be transformed.");
+      addParameter_(new PlaceboTransformedParameter(name, value));
+    }
+    else
+    {
+      IntervalConstraint* interval = dynamic_cast<IntervalConstraint*>(constraint);
+      if (interval) {
+        bool isInfinite = (!interval->finiteLowerBound()) || (!interval->finiteUpperBound());
+        if (!isInfinite)
+        {
+          if (!interval->strictLowerBound() && !interval->strictUpperBound())
+          {
+            // Case 1: [a,b]
+            // This solves an issue if the original value is at the bound.
+            double correctedValue = value;
+            if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
+              correctedValue = interval->getLowerBound() + NumConstants::TINY();
+            if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
+              correctedValue = interval->getUpperBound() - NumConstants::TINY();
+            IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound(), interval->getUpperBound());
+            addParameter_(pp);
+            if (verbose)
+              ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
+          }
+          else if (interval->strictLowerBound() && interval->strictUpperBound())
+          {
+            // Case 2: ]a,b[
+            // We have to correct the bound in order to prevent numerical issues.
+            // It can happens that the original bound is matched because of rounding errors.
+            IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, value, interval->getLowerBound() + NumConstants::TINY(), interval->getUpperBound() - NumConstants::TINY());
+            addParameter_(pp);
+            if (verbose)
+              ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
+          }
+          else if (!interval->strictLowerBound() && interval->strictUpperBound())
+          {
+            // Case 3: [a,b[
+            // This solves an issue if the original value is at the bound.
+            double correctedValue = value;
+            if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
+              correctedValue = interval->getLowerBound() + NumConstants::TINY();
+            IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound(), interval->getUpperBound() - NumConstants::TINY());
+            addParameter_(pp);
+            if (verbose)
+              ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
+          }
+          else if (interval->strictLowerBound() && !interval->strictUpperBound())
+          {
+            // Case 4: ]a,b]
+            // This solve an issue if the original value is at the bound.
+            double correctedValue = value;
+            if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
+              correctedValue = interval->getUpperBound() - NumConstants::TINY();
+            IntervalTransformedParameter* pp = new IntervalTransformedParameter(name, correctedValue, interval->getLowerBound() + NumConstants::TINY(), interval->getUpperBound());
+            addParameter_(pp);
+            if (verbose)
+              ApplicationTools::displayMessage("Parameter " + name + " was tanh transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
+          }
+        }
+        else
+        {
+          if (interval->strictLowerBound() && !interval->finiteUpperBound())
+          {
+            // Case 5: ]a, +inf[
+            RTransformedParameter* pp = new RTransformedParameter(name, value, interval->getLowerBound() + NumConstants::TINY(), true);
+            addParameter_(pp);
+            if (verbose)
+              ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
+          }
+          else if (!interval->strictLowerBound() && !interval->finiteUpperBound())
+          {
+            // Case 6: [a, +inf[
+            // This solve an issue if the original value is at the bound.
+            double correctedValue = value;
+            if (abs(value - interval->getLowerBound()) < NumConstants::TINY())
+              correctedValue = interval->getLowerBound() + NumConstants::TINY();
+            RTransformedParameter* pp = new RTransformedParameter(name, correctedValue, interval->getLowerBound(), true);
+            addParameter_(pp);
+            if (verbose)
+              ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
+          }
+          else if (!interval->finiteLowerBound() && interval->strictUpperBound())
+          {
+            // Case 7: ]-inf, a[
+            RTransformedParameter* pp = new RTransformedParameter(name, value, interval->getUpperBound() - NumConstants::TINY(), false);
+            addParameter_(pp);
+            if (verbose)
+              ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
+          }
+          else if (!interval->finiteLowerBound() && !interval->strictUpperBound())
+          {
+            // Case 8: ]-inf, a]
+            // This solve an issue if the original value is at the bound.
+            double correctedValue = value;
+            if (abs(value - interval->getUpperBound()) < NumConstants::TINY())
+              correctedValue = interval->getUpperBound() - NumConstants::TINY();
+            RTransformedParameter* pp = new RTransformedParameter(name, correctedValue, interval->getUpperBound(), false);
+            addParameter_(pp);
+            if (verbose)
+              ApplicationTools::displayMessage("Parameter " + name + " was log transformed: " + TextTools::toString(value) + "->" + TextTools::toString(pp->getValue()));
+          }
+        }
+      }
+      else
+      {
+        // Nothing found
+        if (verbose)
+        {
+          ApplicationTools::displayWarning("No transformation found for this constraint '" + constraint->getDescription() + "'! Parameter " + p.getName());
+        }
+        addParameter_(new PlaceboTransformedParameter(name, value));
+      }
+    }
+  }
+}
+
+void ReparametrizationFunctionWrapper::fireParameterChanged(const ParameterList& parameters)
+{
+  // Recompute function parameters:
+  // We could update only the parameter that actually changed,
+  // but that would implied a quick sort on parameter names (nlog(n))
+  // whereas using a loop over the set is in o(n). It should hence be
+  // more efficient in most cases.
+  for (unsigned int i = 0; i < getNumberOfParameters(); i++)
+  {
+    double x = dynamic_cast<TransformedParameter&>(getParameter_(i)).getOriginalValue();
+    try
+    {
+      functionParameters_[i].setValue(x);
+    }
+    catch (ConstraintException& ce)
+    {
+      (*ApplicationTools::error << "Oups, value " << x << " led to a constraint exception. The transformed value was " << getParameter_(i).getValue()).endLine();
+      throw ce;
+    }
+  }
+}
+
diff --git a/src/Bpp/Numeric/Function/ReparametrizationFunctionWrapper.h b/src/Bpp/Numeric/Function/ReparametrizationFunctionWrapper.h
new file mode 100644
index 0000000..cc6ac1d
--- /dev/null
+++ b/src/Bpp/Numeric/Function/ReparametrizationFunctionWrapper.h
@@ -0,0 +1,274 @@
+//
+// File: ReparametrizationFunctionWrapper.h
+// Created by: Julien Dutheil
+// Created on: Fri Jan  30 09:30 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _REPARAMETRIZATIONFUNCTIONWRAPPER_H_
+#define _REPARAMETRIZATIONFUNCTIONWRAPPER_H_
+
+#include "Functions.h"
+#include "../AbstractParametrizable.h"
+#include "../TransformedParameter.h"
+
+namespace bpp {
+
+/**
+ * @brief Function wrapper that remove simple constraints on parameters.
+ *
+ * This function takes as input another function and reparametrize it when possible.
+ * currently, only constraint of the type ]a, b[ where a and b can be +/- inf.
+ */
+class ReparametrizationFunctionWrapper:
+  public virtual Function,
+  public AbstractParametrizable
+{
+   private:
+    Function* function_;
+    ParameterList functionParameters_;
+    
+  public:
+    /**
+     * @brief Build a new reparametrization wrapper for the given function, using all available parameters.
+     *
+     * @param function The function to reparametrize.
+     * @param verbose Print some information.
+     */
+    ReparametrizationFunctionWrapper(Function* function, bool verbose=true) :
+      AbstractParametrizable(function->getNamespace()),
+      function_(function),
+      functionParameters_(function->getParameters())
+    {
+      init_(verbose);
+    }
+
+    /**
+     * @brief Build a new reparametrization wrapper for the given function, using only the specified parameters.
+     *
+     * @param function The function to reparametrize.
+     * @param parameters The list of parameters that will be reparametrized. The intersection with the
+     * list of function parameters will be used in the reparametrized function. Any other parameters
+     * (in the given list or in the original function) will be ignored.
+     * @param verbose Print some information.
+     */
+    ReparametrizationFunctionWrapper(Function* function, const ParameterList& parameters, bool verbose=true) :
+      AbstractParametrizable(function->getNamespace()),
+      function_(function),
+      functionParameters_(function->getParameters().getCommonParametersWith(parameters))
+    {
+      init_(verbose);
+    }
+    
+    ReparametrizationFunctionWrapper(const ReparametrizationFunctionWrapper& rfw) :
+      AbstractParametrizable(rfw),
+      function_(rfw.function_),
+      functionParameters_(rfw.functionParameters_) {}
+    
+    ReparametrizationFunctionWrapper& operator=(const ReparametrizationFunctionWrapper& rfw)
+    {
+      AbstractParametrizable::operator=(rfw),
+      function_ = rfw.function_;
+      functionParameters_ = rfw.functionParameters_;
+      return *this;
+    }
+
+    virtual ~ReparametrizationFunctionWrapper() {}
+
+#if defined(NO_VIRTUAL_COV)
+    Clonable* clone() const { return new ReparametrizationFunctionWrapper(*this); }
+#else
+    ReparametrizationFunctionWrapper* clone() const { return new ReparametrizationFunctionWrapper(*this); }
+#endif
+
+  private:
+    void init_(bool verbose);
+
+  public:
+    virtual const Function& getFunction() const { return *function_; } 
+    
+    virtual Function& getFunction() { return *function_; } 
+
+    void setParameters(const ParameterList& parameters)
+      throw (ParameterNotFoundException, ConstraintException)
+    {
+//      parameters.printParameters(std::cout);
+      matchParametersValues(parameters);
+      //We only set parameters that have been changed:
+//      functionParameters_.printParameters(std::cout);
+      function_->setParameters(functionParameters_.subList(parameters.getParameterNames()));
+    }
+
+    double getValue() const throw (Exception)
+    {
+      return function_->getValue();
+    }
+
+    void fireParameterChanged (const ParameterList &parameters);
+
+};
+
+/**
+ * @brief Function wrapper that remove simple constraints on parameters. Also transform first order derivatives.
+ *
+ * This function takes as input another function and reparametrize it when possible.
+ * currently, only constraint of the type ]a, b[ where a and b can be +/- inf.
+ */
+class ReparametrizationDerivableFirstOrderWrapper:
+  public virtual DerivableFirstOrder,
+  public ReparametrizationFunctionWrapper
+{
+    
+  public:
+    /**
+     * @brief Build a new reparametrization wrapper for the given function, using all available parameters.
+     *
+     * @param function The function to reparametrize.
+     * @param verbose Print some information.
+     */
+    ReparametrizationDerivableFirstOrderWrapper(DerivableFirstOrder* function, bool verbose=true) :
+      ReparametrizationFunctionWrapper(function, verbose)
+    {}
+
+    /**
+     * @brief Build a new reparametrization wrapper for the given function, using only the specified parameters.
+     *
+     * @param function The function to reparametrize.
+     * @param parameters The list of parameters that will be reparametrized. The intersection with the
+     * list of function parameters will be used in the reparametrized function. Any other parameters
+     * (in the given list or in the original function) will be ignored.
+     * @param verbose Print some information.
+     */
+    ReparametrizationDerivableFirstOrderWrapper(DerivableFirstOrder* function, const ParameterList& parameters, bool verbose=true) :
+      ReparametrizationFunctionWrapper(function, parameters, verbose)
+    {}
+    
+    virtual ~ReparametrizationDerivableFirstOrderWrapper() {}
+
+#if defined(NO_VIRTUAL_COV)
+    Clonable* clone() const { return new ReparametrizationDerivableFirstOrderWrapper(*this); }
+#else
+    ReparametrizationDerivableFirstOrderWrapper* clone() const { return new ReparametrizationDerivableFirstOrderWrapper(*this); }
+#endif
+
+  private:
+    void init_(bool verbose);
+
+  public:
+    void enableFirstOrderDerivatives(bool yn) { dynamic_cast<DerivableFirstOrder&>(getFunction()).enableFirstOrderDerivatives(yn); }
+    
+    bool enableFirstOrderDerivatives() const { return dynamic_cast<const DerivableFirstOrder&>(getFunction()).enableFirstOrderDerivatives(); }
+
+    double getFirstOrderDerivative(const std::string& variable) const throw (Exception)
+    {
+      return dynamic_cast<const DerivableFirstOrder&>(getFunction()).getFirstOrderDerivative(variable)
+           * dynamic_cast<const TransformedParameter&>(getParameter(variable)).getFirstOrderDerivative();
+    }
+
+};
+
+
+/**
+ * @brief Function wrapper that remove simple constraints on parameters. Also transform first and second order derivatives.
+ *
+ * This function takes as input another function and reparametrize it when possible.
+ * currently, only constraint of the type ]a, b[ where a and b can be +/- inf.
+ */
+class ReparametrizationDerivableSecondOrderWrapper:
+  public virtual DerivableSecondOrder,
+  public ReparametrizationDerivableFirstOrderWrapper
+{
+    
+  public:
+    /**
+     * @brief Build a new reparametrization wrapper for the given function, using all available parameters.
+     *
+     * @param function The function to reparametrize.
+     * @param verbose Print some information.
+     */
+    ReparametrizationDerivableSecondOrderWrapper(DerivableSecondOrder* function, bool verbose=true) :
+      ReparametrizationDerivableFirstOrderWrapper(function, verbose)
+    {}
+
+    /**
+     * @brief Build a new reparametrization wrapper for the given function, using only the specified parameters.
+     *
+     * @param function The function to reparametrize.
+     * @param parameters The list of parameters that will be reparametrized. The intersection with the
+     * list of function parameters will be used in the reparametrized function. Any other parameters
+     * (in the given list or in the original function) will be ignored.
+     * @param verbose Print some information.
+     */
+    ReparametrizationDerivableSecondOrderWrapper(DerivableSecondOrder* function, const ParameterList& parameters, bool verbose=true) :
+      ReparametrizationDerivableFirstOrderWrapper(function, parameters, verbose)
+    {}
+    
+    virtual ~ReparametrizationDerivableSecondOrderWrapper() {}
+
+#if defined(NO_VIRTUAL_COV)
+    Clonable* clone() const { return new ReparametrizationDerivableSecondOrderWrapper(*this); }
+#else
+    ReparametrizationDerivableSecondOrderWrapper* clone() const { return new ReparametrizationDerivableSecondOrderWrapper(*this); }
+#endif
+
+  private:
+    void init_(bool verbose);
+
+  public:
+    void enableSecondOrderDerivatives(bool yn) { dynamic_cast<DerivableSecondOrder&>(getFunction()).enableSecondOrderDerivatives(yn); }
+    
+    bool enableSecondOrderDerivatives() const { return dynamic_cast<const DerivableSecondOrder&>(getFunction()).enableSecondOrderDerivatives(); }
+
+    double getSecondOrderDerivative(const std::string& variable) const throw (Exception)
+    {
+      return dynamic_cast<const DerivableSecondOrder&>(getFunction()).getSecondOrderDerivative(variable)
+           * pow(dynamic_cast<const TransformedParameter&>(getParameter(variable)).getFirstOrderDerivative(), 2)
+           + dynamic_cast<const DerivableSecondOrder&>(getFunction()).getFirstOrderDerivative(variable)
+           * dynamic_cast<const TransformedParameter&>(getParameter(variable)).getSecondOrderDerivative();
+    }
+
+    double getSecondOrderDerivative(const std::string& variable1, const std::string& variable2) const throw (Exception)
+    {
+      return dynamic_cast<const DerivableSecondOrder&>(getFunction()).getSecondOrderDerivative(variable1, variable2)
+           * dynamic_cast<const TransformedParameter&>(getParameter(variable1)).getFirstOrderDerivative()
+           * dynamic_cast<const TransformedParameter&>(getParameter(variable2)).getFirstOrderDerivative();
+    }
+ 
+};
+
+} //end of namespace bpp.
+
+#endif //_REPARAMETRIZATIONFUNCTIONWRAPPER_H_
+
diff --git a/src/Bpp/Numeric/Function/SimpleMultiDimensions.cpp b/src/Bpp/Numeric/Function/SimpleMultiDimensions.cpp
new file mode 100644
index 0000000..a651f9d
--- /dev/null
+++ b/src/Bpp/Numeric/Function/SimpleMultiDimensions.cpp
@@ -0,0 +1,114 @@
+//
+// File: SimpleMultiDimensions.cpp
+// Created by: Julien Dutheil
+// Created on: Tue Nov 16 17:51 2004
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+/******************************************************************************/
+
+#include "SimpleMultiDimensions.h"
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+
+SimpleMultiDimensions::SimpleMultiDimensions(Function* function):
+  AbstractOptimizer(function), nbParams_(0), optimizer_(function)
+{
+  setDefaultStopCondition_(new FunctionStopCondition(this));
+  setStopCondition(*getDefaultStopCondition());
+  setOptimizationProgressCharacter("");
+}
+
+/******************************************************************************/
+
+void SimpleMultiDimensions::setFunction(Function* function)
+{
+  AbstractOptimizer::setFunction(function);
+  optimizer_.setFunction(function);
+  getStopCondition()->init();
+}
+
+/******************************************************************************/
+
+void SimpleMultiDimensions::doInit(const ParameterList& params) throw (Exception)
+{
+  nbParams_ = params.size();
+  if (nbParams_ == 0) return;
+
+  // Initialize optimizers:
+  unsigned int nbEvalMax = nbEvalMax_ / static_cast<unsigned int>(nbParams_);
+  optimizer_.setMaximumNumberOfEvaluations(nbEvalMax);
+  optimizer_.setProfiler(getProfiler());
+  optimizer_.setMessageHandler(getMessageHandler());
+  optimizer_.getStopCondition()->setTolerance(getStopCondition()->getTolerance());
+  optimizer_.setConstraintPolicy(getConstraintPolicy());
+  optimizer_.setVerbose(getVerbose() > 0 ? getVerbose() - 1 : 0);
+  optimizer_.setInitialInterval(0., 1.);
+  getFunction()->setParameters(getParameters());
+}
+
+/******************************************************************************/
+
+double SimpleMultiDimensions::doStep() throw (Exception)
+{
+  double f = getFunction()->getValue();
+  for (unsigned int i = 0; i < nbParams_; i++)
+  {
+    if (getVerbose() > 0)
+    {
+      cout << getParameters()[i].getName() << ":";
+      cout.flush();
+    }
+    // Re-init optimizer according to new values:
+    double v = getParameters()[i].getValue();
+    double t = std::max(0.000001, std::min(std::abs(v), getStopCondition()->getTolerance()));
+    optimizer_.setInitialInterval(v - t, v + t);
+    optimizer_.init(getParameters().subList(i));
+
+    // Optimize through this dimension:
+    f = optimizer_.optimize();
+    if (getVerbose() > 0) cout << endl;
+    getParameters_().matchParametersValues(getFunction()->getParameters());
+    nbEval_ += optimizer_.getNumberOfEvaluations(); 
+  }
+  tolIsReached_ = nbParams_ <= 1;
+  return f;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/SimpleMultiDimensions.h b/src/Bpp/Numeric/Function/SimpleMultiDimensions.h
new file mode 100644
index 0000000..2747f10
--- /dev/null
+++ b/src/Bpp/Numeric/Function/SimpleMultiDimensions.h
@@ -0,0 +1,99 @@
+//
+// File: SimpleMultiDimensions.h
+// Created by: Julien Dutheil
+// Created on: Tue Nov 16 17:51 2004
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _SIMPLEMULTIDIMENSIONS_H_
+#define _SIMPLEMULTIDIMENSIONS_H_
+
+#include "AbstractOptimizer.h"
+#include "BrentOneDimension.h"
+
+namespace bpp
+{
+
+/**
+ * @brief This Optimizer is a very simple multi-dimensions optimizer, calling
+ * a one dimensional optimizer on each parameter.
+ *
+ * The one-dimensional optimizer used is BrentOneDimension.
+ * Consider using PowellMultiDimensions optimizer for a more efficient modified version of the algorithm.
+ */
+class SimpleMultiDimensions:
+  public AbstractOptimizer
+{
+	private:
+
+		size_t nbParams_;
+
+		BrentOneDimension optimizer_; // One dimensional optimizer.
+
+	public:
+
+		SimpleMultiDimensions(Function* function);
+
+		virtual ~SimpleMultiDimensions() {}
+
+    SimpleMultiDimensions* clone() const { return new SimpleMultiDimensions(*this); }
+
+	public:
+		/**
+		 * @name The Optimizer interface.
+		 *
+		 * @{
+		 */
+		void setFunction(Function * function);
+		/** @} */
+		
+		void doInit(const ParameterList& params) throw (Exception);
+
+    double doStep() throw (Exception);
+
+    /**
+     * @return The optimizer used to optimize each parameter.
+     */
+    Optimizer& getOneDimensionOptimizer() { return optimizer_; } 
+    /**
+     * @return The optimizer used to optimize each parameter.
+     */
+    const Optimizer& getOneDimensionOptimizer() const { return optimizer_; } 
+};
+
+} //end of namespace bpp.
+
+#endif //_SIMPLEMULTIDIMENSIONS_H_
+
diff --git a/src/Bpp/Numeric/Function/SimpleNewtonMultiDimensions.cpp b/src/Bpp/Numeric/Function/SimpleNewtonMultiDimensions.cpp
new file mode 100644
index 0000000..12b3603
--- /dev/null
+++ b/src/Bpp/Numeric/Function/SimpleNewtonMultiDimensions.cpp
@@ -0,0 +1,110 @@
+//
+// File: SimpleNewtonMultiDimensions.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Apr 26 15:29 2007
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+/******************************************************************************/
+
+#include "SimpleNewtonMultiDimensions.h"
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+
+SimpleNewtonMultiDimensions::SimpleNewtonMultiDimensions(DerivableSecondOrder* function):
+  AbstractOptimizer(function), nbParams_(0), optimizer_(function)
+{
+  setDefaultStopCondition_(new FunctionStopCondition(this));
+  setStopCondition(*getDefaultStopCondition());
+  setOptimizationProgressCharacter("");
+}
+
+/******************************************************************************/
+
+void SimpleNewtonMultiDimensions::setFunction(Function* function)
+{
+  AbstractOptimizer::setFunction(function);
+  optimizer_.setFunction(function);
+}
+
+/******************************************************************************/
+
+void SimpleNewtonMultiDimensions::doInit(const ParameterList& params) throw (Exception)
+{
+  nbParams_ = params.size();
+  if (nbParams_ == 0) return;
+
+  // Initialize optimizers:
+  unsigned int nbEvalMax = nbEvalMax_ / static_cast<unsigned int>(nbParams_);
+  optimizer_.setMaximumNumberOfEvaluations(nbEvalMax);
+  optimizer_.setProfiler(getProfiler());
+  optimizer_.setMessageHandler(getMessageHandler());
+  optimizer_.getStopCondition()->setTolerance(getStopCondition()->getTolerance());
+  optimizer_.setConstraintPolicy(getConstraintPolicy());
+  optimizer_.setVerbose(getVerbose() > 0 ? getVerbose() - 1 : 0);
+  optimizer_.setMaximumNumberOfCorrections(10);
+  getFunction()->setParameters(getParameters());
+}
+
+/******************************************************************************/
+
+double SimpleNewtonMultiDimensions::doStep() throw (Exception)
+{
+  double f = getFunction()->getValue();
+  for (unsigned int i = 0; i < nbParams_; i++)
+  {
+    if (getVerbose() > 0)
+    {
+      cout << getParameters()[i].getName() << ":";
+      cout.flush();
+    }
+    // Re-init optimizer according to new values:
+    optimizer_.init(getParameters().subList(i));
+
+    // Optimize through this dimension:
+    f = optimizer_.optimize();
+    if (getVerbose() > 0) cout << endl;
+    getParameters_().matchParametersValues(getFunction()->getParameters());
+    nbEval_ += optimizer_.getNumberOfEvaluations(); 
+  }
+  tolIsReached_ = nbParams_ <= 1;
+  return f;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Function/SimpleNewtonMultiDimensions.h b/src/Bpp/Numeric/Function/SimpleNewtonMultiDimensions.h
new file mode 100644
index 0000000..7de20e4
--- /dev/null
+++ b/src/Bpp/Numeric/Function/SimpleNewtonMultiDimensions.h
@@ -0,0 +1,98 @@
+//
+// File: SimpleNewtonMultiDimensions.h
+// Created by: Julien Dutheil
+// Created on: Thu Apr 26 15:29 2007
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _SIMPLENEWTONMULTIDIMENSIONS_H_
+#define _SIMPLENEWTONMULTIDIMENSIONS_H_
+
+#include "AbstractOptimizer.h"
+#include "NewtonOneDimension.h"
+
+namespace bpp
+{
+
+/**
+ * @brief This Optimizer is a simple multi-dimensions optimizer, calling
+ * the Newton one dimensional optimizer on each parameter.
+ *
+ * The one-dimensional optimizer used is NewtonOneDimension.
+ */
+class SimpleNewtonMultiDimensions:
+  public AbstractOptimizer
+{
+	private:
+
+		size_t nbParams_;
+
+		NewtonOneDimension optimizer_; // One dimensional optimizer.
+
+	public:
+
+		SimpleNewtonMultiDimensions(DerivableSecondOrder* function);
+
+		virtual ~SimpleNewtonMultiDimensions() {};
+
+    SimpleNewtonMultiDimensions* clone() const { return new SimpleNewtonMultiDimensions(*this); }
+
+	public:
+		/**
+		 * @name The Optimizer interface.
+		 *
+		 * @{
+		 */
+		void setFunction(Function* function);
+		/** @} */
+
+		void doInit(const ParameterList& params) throw (Exception);
+
+		double doStep() throw (Exception);
+
+    /**
+     * @return The optimizer used to optimize each parameter.
+     */
+    Optimizer& getOneDimensionOptimizer() { return optimizer_; } 
+    /**
+     * @return The optimizer used to optimize each parameter.
+     */
+    const Optimizer& getOneDimensionOptimizer() const { return optimizer_; } 
+};
+
+} //end of namespace bpp.
+
+#endif //_SIMPLENEWTONMULTIDIMENSIONS_H_
+
diff --git a/src/Bpp/Numeric/Function/ThreePointsNumericalDerivative.cpp b/src/Bpp/Numeric/Function/ThreePointsNumericalDerivative.cpp
new file mode 100644
index 0000000..732f9fd
--- /dev/null
+++ b/src/Bpp/Numeric/Function/ThreePointsNumericalDerivative.cpp
@@ -0,0 +1,249 @@
+//
+// File: ThreePointsNumericalDerivative.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Aug 17 15:00 2006
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "ThreePointsNumericalDerivative.h"
+
+using namespace bpp;
+using namespace std;
+
+void ThreePointsNumericalDerivative::updateDerivatives(const ParameterList parameters)
+throw (ParameterNotFoundException, ConstraintException)
+{
+  if (computeD1_ && variables_.size() > 0)
+  {
+    if (function1_) function1_->enableFirstOrderDerivatives(false);
+    if (function2_) function2_->enableSecondOrderDerivatives(false);
+    function_->setParameters(parameters);
+    f2_ = function_->getValue();
+    if ((abs(f2_) >= NumConstants::VERY_BIG()) || isnan(f2_)){
+      for (unsigned int i = 0; i < variables_.size(); i++){
+        der1_[i]=log(-1);
+        der2_[i]=log(-1);
+      }
+      return;
+    }
+      
+    string lastVar;
+    bool functionChanged = false;
+    ParameterList p;
+    bool start = true;
+    for (unsigned int i = 0; i < variables_.size(); i++)
+    {
+      string var = variables_[i];
+      if (!parameters.hasParameter(var)) continue;
+      if (!start)
+      {
+        vector<string> vars(2);
+        vars[0] = var;
+        vars[1] = lastVar;
+        p = parameters.subList(vars);
+      }
+      else
+      {
+        p = parameters.subList(var);
+        start = false;
+      }
+      lastVar = var;
+      functionChanged = true;
+      double value = function_->getParameterValue(var);
+      double h = -(1. + std::abs(value)) * h_;
+      if (abs(h)<p[0].getPrecision())
+        h=h<0?-p[0].getPrecision():p[0].getPrecision();
+      double hf1(0), hf3(0);
+      unsigned int nbtry=0;
+      
+      //Compute f1_
+      while (hf1==0){
+        try
+          {
+            p[0].setValue(value + h);
+            function_->setParameters(p); //also reset previous parameter...
+            
+            p = p.subList(0);
+            f1_ = function_->getValue();
+            if ((abs(f1_) >= NumConstants::VERY_BIG()) || isnan(f1_))
+              throw ConstraintException("f1_ too large", &p[0], f1_);
+            else
+              hf1=h;
+          }
+        catch (ConstraintException& ce)
+          {
+            if (++nbtry==10) // no possibility to compute derivatives
+              break;
+            else
+              if (h<0)
+                h=-h;  // try on the right
+              else
+                h/=-2; // try again on the left with smaller interval
+          }
+      }
+
+      if (hf1!=0){
+        //Compute f3_ 
+        if (h<0)
+          h=-h;  // on the right 
+        else
+          h/=2; //  on the left with smaller interval
+
+        nbtry=0;
+        while (hf3==0){
+          try
+            {
+              p[0].setValue(value + h);
+              function_->setParameters(p); //also reset previous parameter...
+            
+              p = p.subList(0);
+              f3_ = function_->getValue();
+              if ((abs(f3_) >= NumConstants::VERY_BIG()) || isnan(f3_))
+                throw ConstraintException("f3_ too large", &p[0], f3_);
+              else
+                hf3=h;
+            }
+          catch (ConstraintException& ce)
+            {
+              if (++nbtry==10) // no possibility to compute derivatives
+                break;
+              else
+                if (h<0)
+                  h=-h;  // try on the right
+                else
+                  h/=-2; // try again on the left with smaller interval
+            }
+        }
+      }
+      
+      if (hf3==0){
+          der1_[i]=log(-1);
+          der2_[i]=log(-1);
+      }
+      else {
+        der1_[i] = (f1_ - f3_) / (hf1-hf3);
+        der2_[i] = ((f1_ - f2_)/hf1 - (f3_ - f2_)/hf3)*2/(hf1-hf3);
+      }
+    }
+
+
+    
+    
+    if (computeCrossD2_)
+    {
+      string lastVar1, lastVar2;
+      for (unsigned int i = 0; i < variables_.size(); i++)
+      {
+        string var1 = variables_[i];
+        if (!parameters.hasParameter(var1)) continue;
+        for (unsigned int j = 0; j < variables_.size(); j++)
+        {
+          if (j == i)
+          {
+            crossDer2_(i, j) = der2_[i];
+            continue;
+          }
+          string var2 = variables_[j];
+          if (!parameters.hasParameter(var2)) continue;
+
+          vector<string> vars(2);
+          vars[0] = var1;
+          vars[1] = var2;
+          if (i > 0 && j > 0)
+          {
+            if (lastVar1 != var1 && lastVar1 != var2) vars.push_back(lastVar1);
+            if (lastVar2 != var1 && lastVar2 != var2) vars.push_back(lastVar2);
+          }
+          p = parameters.subList(vars);
+
+          double value1 = function_->getParameterValue(var1);
+          double value2 = function_->getParameterValue(var2);
+          double h1 = (1. + std::abs(value1)) * h_;
+          double h2 = (1. + std::abs(value2)) * h_;
+
+          //Compute 4 additional points:
+          try
+          {
+            p[0].setValue(value1 - h1);
+            p[1].setValue(value2 - h2);
+            function_->setParameters(p); //also reset previous parameter...
+            vector<size_t> tmp(2);
+            tmp[0] = 0;
+            tmp[1] = 1;
+            p = p.subList(tmp); //removed the previous parameters.
+            f11_ = function_->getValue();
+
+            p[1].setValue(value2 + h2);
+            function_->setParameters(p.subList(1));
+            f12_ = function_->getValue();
+
+            p[0].setValue(value1 + h1);
+            function_->setParameters(p.subList(0));
+            f22_ = function_->getValue();
+
+            p[1].setValue(value2 - h2);
+            function_->setParameters(p.subList(1));
+            f21_ = function_->getValue();
+
+            crossDer2_(i, j) = ((f22_ - f21_) - (f12_ - f11_)) / (4 * h1 * h2);
+          }
+          catch (ConstraintException& ce)
+          {
+            throw Exception("ThreePointsNumericalDerivative::setParameters. Could not compute cross derivatives at limit.");
+          }
+
+          lastVar1 = var1;
+          lastVar2 = var2;
+        }
+      }
+    }
+
+    //Reset last parameter and compute analytical derivatives if any.
+    if (function1_) function1_->enableFirstOrderDerivatives(computeD1_);
+    if (function2_) function2_->enableSecondOrderDerivatives(computeD2_);
+    if (functionChanged)
+      function_->setParameters(parameters.subList(lastVar));
+  }
+  else
+  {
+    //Reset initial value and compute analytical derivatives if any.
+    if (function1_) function1_->enableFirstOrderDerivatives(computeD1_);
+    if (function2_) function2_->enableSecondOrderDerivatives(computeD2_);
+    function_->setParameters(parameters);
+    //Just in case derivatives are not computed:
+    f2_ = function_->getValue();
+  }
+}
+
diff --git a/src/Bpp/Numeric/Function/ThreePointsNumericalDerivative.h b/src/Bpp/Numeric/Function/ThreePointsNumericalDerivative.h
new file mode 100644
index 0000000..80a2bc1
--- /dev/null
+++ b/src/Bpp/Numeric/Function/ThreePointsNumericalDerivative.h
@@ -0,0 +1,118 @@
+//
+// File: ThreePointsNumericalDerivative.h
+// Created by: Julien Dutheil
+// Created on: Thu Aug 17 15:00 2006
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _THREEPOINTSNUMERICALDERIVATIVE_H_
+#define _THREEPOINTSNUMERICALDERIVATIVE_H_
+
+#include "Functions.h"
+#include "AbstractNumericalDerivative.h"
+
+//From the STL:
+#include <map>
+#include <vector>
+#include <string>
+
+namespace bpp
+{
+
+/**
+ * @brief Three points numerical derivative function wrapper.
+ *
+ * Numerical derivatives use three points to compute the derivatives.
+ * @f$x_0 at f$ is the focus point, @f$x_{-1} = x_0-h at f$ and @f$x_{+1} = x_0+h at f$
+ * are other points, with function values @f$f_0 at f$, @f$f_{-1}@f$ and @f$f_{+1}@f$ respectively.
+ * The derivatives are then computed using the central formulas:
+ * @f{eqnarray*}
+ * \dfrac{\partial   f}{\partial x  } &=& \dfrac{f_{+1}-f_{-1}}{2h}\\
+ * \dfrac{\partial^2 f}{\partial x^2} &=& \dfrac{f_{+1}-2f_0+f_{-1}}{h^2}\\
+ * @f}
+ * In case of border limit (when @f$x_{-1}@f$ or @f$x_{+1}@f$ are not computable), 
+ * the foreward and backward computations are performed, respectively:
+ * @f{eqnarray*}
+ * \dfrac{\partial   f}{\partial x  } &=& \dfrac{f_{+1}-f_0}{h}\\
+ * \dfrac{\partial^2 f}{\partial x^2} &=& \dfrac{f_{+2}-2f_{+1}+f_0}{h^2}\\
+ * @f}
+ * and
+ * @f{eqnarray*}
+ * \dfrac{\partial   f}{\partial x  } &=& \dfrac{f_0-f_{-1}}{h}\\
+ * \dfrac{\partial^2 f}{\partial x^2} &=& \dfrac{f_0-2f_{-1}+f_{-2}}{h^2}\\
+ * @f}
+ *
+ * The @f$h at f$ parameter is computed in a parameter dependent manner:
+ * @f$ h = x \times e at f$, with @f$x \neq 0 at f$ being the current parameter value.
+ * If @f$x = 0 at f$, @f$h = e at f$.
+ * Default value is provided for @f$e at f$ and corresponds to the _h field.
+ * The default value works fine in most cases, but you may want to change it using the setInterval method.
+ *
+ * @see AbstractNumericalDerivative
+ */
+class ThreePointsNumericalDerivative:
+  public AbstractNumericalDerivative
+{
+  private:
+    double f1_, f2_, f3_, f11_, f22_, f12_, f21_;
+    
+  public:
+    ThreePointsNumericalDerivative (Function* function) :
+      AbstractNumericalDerivative(function), f1_(), f2_(), f3_(), f11_(), f22_(), f12_(), f21_() {}
+    ThreePointsNumericalDerivative (DerivableFirstOrder * function) :
+      AbstractNumericalDerivative(function), f1_(), f2_(), f3_(), f11_(), f22_(), f12_(), f21_() {}
+    ThreePointsNumericalDerivative (DerivableSecondOrder * function) :
+      AbstractNumericalDerivative(function), f1_(), f2_(), f3_(), f11_(), f22_(), f12_(), f21_() {}
+    virtual ~ThreePointsNumericalDerivative() {}
+
+    ThreePointsNumericalDerivative* clone() const { return new ThreePointsNumericalDerivative(*this); }
+
+  public:
+    
+    double getValue() const throw (Exception)
+    {
+      return f2_;
+    }
+    
+  protected:
+    void updateDerivatives(const ParameterList parameters)
+      throw (ParameterNotFoundException, ConstraintException);
+    
+};
+
+} //end of namespace bpp.
+
+#endif //_THREEPOINTSNUMERICALDERIVATIVE_H_
+
diff --git a/src/Bpp/Numeric/Function/TwoPointsNumericalDerivative.cpp b/src/Bpp/Numeric/Function/TwoPointsNumericalDerivative.cpp
new file mode 100644
index 0000000..8970e59
--- /dev/null
+++ b/src/Bpp/Numeric/Function/TwoPointsNumericalDerivative.cpp
@@ -0,0 +1,121 @@
+//
+// File: TwoPointsNumericalDerivative.cpp
+// Created by: Julien Dutheil
+// Created on: Mon May 28 10:33 2007
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "TwoPointsNumericalDerivative.h"
+
+using namespace bpp;
+using namespace std;
+
+void TwoPointsNumericalDerivative::updateDerivatives(const ParameterList parameters)
+throw (ParameterNotFoundException, ConstraintException)
+{
+  if (computeD1_ && variables_.size() > 0)
+  {
+    if (function1_) function1_->enableFirstOrderDerivatives(false);
+    if (function2_) function2_->enableSecondOrderDerivatives(false);
+    function_->setParameters(parameters);
+    f1_ = function_->getValue();
+    string lastVar;
+    bool functionChanged = false;
+    bool start = true;
+    for (unsigned int i = 0; i < variables_.size(); i++)
+    {
+      string var = variables_[i];
+      if (!parameters.hasParameter(var)) continue;
+      ParameterList p;
+      if (!start)
+      {
+        vector<string> vars(2);
+        vars[0] = var;
+        vars[1] = lastVar;
+        lastVar = var;
+        functionChanged = true;
+        p = parameters.subList(vars);
+      }
+      else
+      {
+        p = parameters.subList(var);
+        lastVar = var;
+        functionChanged = true;
+        start = false;
+      }
+      double value = function_->getParameterValue(var);
+      double h = (1 + std::abs(value)) * h_;
+      //Compute one other point:
+      try
+      {
+        p[0].setValue(value + h);
+        function_->setParameters(p);
+        f2_ = function_->getValue();
+      }
+      catch (ConstraintException& ce1)
+      {
+        //Right limit raised, use backward approximation:
+        try
+        {
+          p[0].setValue(value - h);
+          function_->setParameters(p);
+          f2_ = function_->getValue();
+          der1_[i] = (f1_ - f2_) / h;
+        }
+        catch (ConstraintException& ce2)
+        {
+          //PB: can't compute derivative, because of a two narrow interval (lower than h)
+          throw ce2;
+        }
+      }
+      //No limit raised, use forward approximation:
+      der1_[i] = (f2_ - f1_) / h;
+    }
+    //Reset last parameter and compute analytical derivatives if any:
+    if (function1_) function1_->enableFirstOrderDerivatives(computeD1_);
+    if (functionChanged)
+      function_->setParameters(parameters.subList(lastVar));
+  }
+  else
+  {
+    //Reset initial value and compute analytical derivatives if any.
+    if (function1_) function1_->enableFirstOrderDerivatives(computeD1_);
+    if (function2_) function2_->enableSecondOrderDerivatives(computeD2_);
+    //Just in case derivatives are not computed:
+    function_->setParameters(parameters);
+    f1_ = function_->getValue();
+  }
+}
+
diff --git a/src/Bpp/Numeric/Function/TwoPointsNumericalDerivative.h b/src/Bpp/Numeric/Function/TwoPointsNumericalDerivative.h
new file mode 100644
index 0000000..9b236bc
--- /dev/null
+++ b/src/Bpp/Numeric/Function/TwoPointsNumericalDerivative.h
@@ -0,0 +1,121 @@
+//
+// File: TwoPointsNumericalDerivative.h
+// Created by: Julien Dutheil
+// Created on: Mon May 28 10:33 2007
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _TWOPOINTSNUMERICALDERIVATIVE_H_
+#define _TWOPOINTSNUMERICALDERIVATIVE_H_
+
+#include "Functions.h"
+#include "AbstractNumericalDerivative.h"
+
+//From the STL:
+#include <map>
+#include <vector>
+#include <string>
+
+namespace bpp
+{
+
+/**
+ * @brief Two points numerical derivative function wrapper.
+ *
+ * Numerical derivatives use two points to compute the (first order) derivatives.
+ * @f$x_0 at f$ is the focus point and @f$x_{+1} = x_0+h at f$ (or @f$x_0-h at f$, if constrained on the right).
+ * Corresponding function values are @f$f_0 at f$, @f$f_{-1}@f$ and @f$f_{+1/-1}@f$ respectively.
+ * The derivatives are then computed using the central formulas:
+ * @f{eqnarray*}
+ * \dfrac{\partial   f}{\partial x  } &=& \dfrac{f_{+1}-f_{0}}{h}\mathrm{\ or}\\
+ * \dfrac{\partial   f}{\partial x  } &=& \dfrac{f_{0}-f_{-1}}{h}\\
+ * @f}
+ * This class does not allow computation of second order derivatives.
+ *
+ * The @f$h at f$ parameter is computed in a parameter dependent manner:
+ * @f$ h = x \times e at f$, with @f$x \neq 0 at f$ being the current parameter value.
+ * If @f$x = 0 at f$, @f$h = e at f$.
+ * Default value is provided for @f$e at f$ and corresponds to the _h field.
+ * The default value works fine in most cases, but you may want to change it using the setInterval method.
+ *
+ * @see AbstractNumericalDerivative, ThreePointsNumericalDerivative, FivePointsNumericalDerivative
+ */
+class TwoPointsNumericalDerivative:
+  public AbstractNumericalDerivative
+{
+  private:
+    double f1_, f2_;
+    
+  public:
+    TwoPointsNumericalDerivative(Function* function) :
+      AbstractNumericalDerivative(function), f1_(), f2_() {}
+    TwoPointsNumericalDerivative(DerivableFirstOrder* function) :
+      AbstractNumericalDerivative(function), f1_(), f2_() {}
+    virtual ~TwoPointsNumericalDerivative() {}
+
+    TwoPointsNumericalDerivative* clone() const { return new TwoPointsNumericalDerivative(*this); }
+
+  public:
+    
+    double getValue() const throw (Exception) { return f1_; }
+
+    /**
+     * @name The DerivableSecondOrder interface
+     *
+     * @{
+     */
+    double getSecondOrderDerivative(const std::string & variable) const
+      throw (Exception)
+    {
+      throw Exception("Second order derivative not avalaible with two points method."); 
+    }
+
+    double getSecondOrderDerivative(const std::string & variable1, const std::string & variable2) const
+      throw (Exception)
+    {
+      throw Exception("Unimplemented cross derivative.");
+    }
+    /** @} */
+    
+  protected:
+    void updateDerivatives(const ParameterList parameters)
+      throw (ParameterNotFoundException, ConstraintException);
+    
+};
+
+} //end of namespace bpp.
+
+#endif //_TWOPOINTSNUMERICALDERIVATIVE_H_
+
diff --git a/src/Bpp/Numeric/Hmm/HmmEmissionProbabilities.h b/src/Bpp/Numeric/Hmm/HmmEmissionProbabilities.h
new file mode 100644
index 0000000..5f8efeb
--- /dev/null
+++ b/src/Bpp/Numeric/Hmm/HmmEmissionProbabilities.h
@@ -0,0 +1,154 @@
+//
+// File: HmmEmissionProbabilities.h
+// Created by: Julien Dutheil
+// Created on: Fri Sep 04 13:14 2009 from file HmmLikelihood.
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _HMMEMISSIONPROBABILITIES_H_
+#define _HMMEMISSIONPROBABILITIES_H_
+
+#include "HmmStateAlphabet.h"
+#include "HmmExceptions.h"
+#include "../Parametrizable.h"
+
+//From the STL:
+#include <vector>
+
+namespace bpp
+{
+
+/**
+ * @brief Interface for computing emission probabilities in a Hidden Markov Model.
+ *
+ * This class is part of the HMM framework. It compute the probabilities of the data
+ * conditionned on each hidden state. The emission probabilities class also has in charge
+ * the data, its putative compression, and the number of position in the sequence of
+ * observed states.
+ *
+ * @see HmmStateAlphabet
+ * @see HmmTransitionMatrix
+ */
+class HmmEmissionProbabilities:
+  public virtual Parametrizable
+{
+  public:
+    virtual HmmEmissionProbabilities* clone() const = 0;
+
+    virtual const HmmStateAlphabet* getHmmStateAlphabet() const = 0;
+ 
+    /**
+     * @brief Set the new hidden state alphabet.
+     * @param stateAlphabet The new state alphabet.
+     * @throw UnvalidStateAlphabetException if the new alphabet is uncorrect (for instance is NULL pointer).
+     */
+    virtual void setHmmStateAlphabet(const HmmStateAlphabet* stateAlphabet) throw (HmmUnvalidAlphabetException) = 0;
+
+    /**
+     * @name Access emission probabilities per site.
+     *
+     * This functions are handy, but might not be the most efficient way to retrieve the probabilities.
+     * @{
+     */
+   
+    /**
+     * @param pos The position of the sequential data to consider.
+     * @param stateIndex The index of the hidden state to consider, as defined by the HmmStateAlphabet object associated to this class.
+     */
+    virtual double getEmissionProbability(size_t pos, size_t stateIndex) const throw (Exception) = 0;
+    virtual void getEmissionProbabilities(size_t pos, std::vector<double>& probs) const throw (Exception) = 0;
+    virtual void getEmissionProbabilitiesForEachPosition(std::vector< std::vector<double> >& probs, bool append) const throw (Exception) = 0;
+    
+    /**
+     * @param pos The position of the sequential data to consider.
+     * @param stateIndex The index of the hidden state to consider, as defined by the HmmStateAlphabet object associated to this class.
+     */
+    virtual double getLogEmissionProbability(size_t pos, size_t stateIndex) const throw (Exception) = 0;
+    virtual void getLogEmissionProbabilities(size_t pos, std::vector<double>& probs) const throw (Exception) = 0;
+    virtual void getLogEmissionProbabilitiesForEachPosition(std::vector< std::vector<double> >& probs, bool append) const throw (Exception) = 0;
+
+    /**@} */
+
+    /**
+     * @brief Operator access to the emission probabilities.
+     *
+     * This is the fastest way to get the values, but no checking is performed on the indices.
+     * For debugging purpose, the getEmissionProbability would be a safer use.
+     *
+     * @param pos The position of the sequential data to consider.
+     * @param state The index of the hidden state to consider, as defined by the HmmStateAlphabet object associated to this class.
+     */
+    virtual double operator()(size_t pos, size_t state) const = 0;
+
+    /**
+     * @brief Operator access to the emission probabilities.
+     *
+     * This is the fastest way to get the values, but no checking is performed on the indices.
+     * For debugging purpose, the getEmissionProbability would be a safer use.
+     *
+     * @param pos The position of the sequential data to consider.
+     * @return A vector of probabilities, whose size is the number of hidden states.
+     */
+    virtual const std::vector<double>& operator()(size_t pos) const = 0;
+    
+    /**
+     * @return The number of positions in the data.
+     */
+    virtual size_t getNumberOfPositions() const = 0;
+
+    /**
+     * @brief Get the index of a given state in the list of observed states.
+     * The indexing if up to the implementation of this interface.
+     * 
+     * @param pos The position of the observed state in the original sequence.
+     * @return The index of the observed state in the list.
+     */
+    virtual size_t getObservedStateIndex(size_t pos) const = 0;
+    
+    /**
+     * @brief Get all emission probabilities, in a compressed form.
+     *
+     * @return a 2-dimensions array E[i,j], where i is the index of the observed states (@see getObservedStateIndex), and j in the index of the hidden state.
+     * @param probs a 2-dimensional array which is going to be resized and filled with the emission probabilities.
+     */
+    virtual void getEmissionProbabilities(std::vector< std::vector<double> >& probs) const = 0;
+
+
+};
+
+} //end of namespace bpp.
+
+#endif //_HMMEMISSIONPROBABILITIES_H_
+
diff --git a/src/Bpp/Numeric/Hmm/HmmExceptions.h b/src/Bpp/Numeric/Hmm/HmmExceptions.h
new file mode 100644
index 0000000..1abead2
--- /dev/null
+++ b/src/Bpp/Numeric/Hmm/HmmExceptions.h
@@ -0,0 +1,83 @@
+//
+// File: HmmExceptions.h
+// Created by: Julien Dutheil
+// Created on: Fri Sep 04 15:30 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 16, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _HMMEXCEPTIONS_H_
+#define _HMMEXCEPTIONS_H_
+
+#include "../../Exceptions.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Exception thrown when an unvalid state is requested.
+   *
+   * This class belongs to the HMM framework.
+   *
+   * @author Julien Dutheil
+   */
+  class HmmBadStateException:
+    public Exception
+  {
+    public:
+      HmmBadStateException(const std::string& description): Exception(description) {}
+
+  };
+
+
+
+  /**
+   * @brief Exception thrown when an unvalid alphabet is specified.
+   *
+   * This class belongs to the HMM fra;ework.
+   *
+   * @author Julien Dutheil
+   */
+  class HmmUnvalidAlphabetException:
+    public Exception
+  {
+    public:
+      HmmUnvalidAlphabetException(const std::string& description): Exception(description) {}
+
+  };
+
+}; //end of namespace bpp.
+
+#endif //_HMMEXCEPTIONS_H_
+
diff --git a/src/Bpp/Numeric/Hmm/HmmLikelihood.h b/src/Bpp/Numeric/Hmm/HmmLikelihood.h
new file mode 100644
index 0000000..20bf4a1
--- /dev/null
+++ b/src/Bpp/Numeric/Hmm/HmmLikelihood.h
@@ -0,0 +1,104 @@
+//
+// File: HmmLikelihood.h
+// Created by: Julien Dutheil
+// Created on: Fri Oct 26 11:20 2007
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _HMMLIKELIHOOD_H_
+#define _HMMLIKELIHOOD_H_
+
+
+// From NumCalc:
+#include "../Function/Functions.h"
+#include "HmmStateAlphabet.h"
+#include "HmmTransitionMatrix.h"
+#include "HmmEmissionProbabilities.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Basal interface for Hidden Markov Models likelihood computation.
+ *
+ * HmmLikelihood classes compute the probability of data according to parameters (likelihood),
+ * using the so-called forward recursion:
+ *
+ * - Initialisation: @f[ f_0({\cal A}_0), \ldots, f_0({\cal A}_n) @f] The initial frequencies, set to the equilibrium frequencies of the chain.
+ * - Recursion (for i=1 to l, the length of the sequence data): @f[ f_i({\cal A}_y) = e_y(D_i) \sum_{x=1}^n f_{i-1}({\cal A}_x) \cdot p_{x,y} @f]
+ * - Termination: @f[ \Pr(D) = \sum_{x=1}^n f_l({\cal A}_x) @f]
+ * where @f$ {\cal A}_{1..n} @f$ denotes the hidden states of the alphabet, @f$ e_y(D_i) @f$ the
+ * probability of the data at position i conditioned on hidden state y (emission probabilities)
+ * and @f$ p_{x,y} @f$ is the probability of havving hidden state y at state i+1 knowing there
+ * is hidden state x at position i (transition probabilities). These essential elements are given
+ * respectively by the HmmEmissionProbabilities and HmmTransitionMatrix object associated to this
+ * class. Both objects have to share the same HmmStateAlphabet instance, which describes all
+ * allowed hidden states.
+ *
+ * The HmmLikelihood interface provides essentially two major methods:
+ * - A method to retrieve the likelihood value (parameter estimation)
+ * - Two methods to retrieve the posterio probabilities of each state using the forward and backward conditionnal likelihoods (posterior decoding).
+ */
+class HmmLikelihood:
+  public virtual Function
+{
+  public:
+
+#ifndef NO_VIRTUAL_COV
+    virtual HmmLikelihood* clone() const = 0;
+#endif
+
+    virtual const HmmStateAlphabet& getHmmStateAlphabet() const = 0;
+    virtual HmmStateAlphabet& getHmmStateAlphabet() = 0;
+    
+    virtual const HmmTransitionMatrix& getHmmTransitionMatrix() const = 0;
+    virtual HmmTransitionMatrix& getHmmTransitionMatrix() = 0;
+    
+    virtual const HmmEmissionProbabilities& getHmmEmissionProbabilities() const = 0;
+    virtual HmmEmissionProbabilities& getHmmEmissionProbabilities() = 0;
+
+    virtual void getHiddenStatesPosteriorProbabilities(std::vector< std::vector<double> >& probs, bool append) const throw (Exception) = 0;
+    
+    virtual double getLogLikelihood() const = 0;
+    
+    virtual const std::vector<size_t>& getBreakPoints() const = 0;
+    virtual void setBreakPoints(const std::vector<size_t>& breakPoints) = 0;
+     
+};
+
+} //end of namespace bpp.
+
+#endif //_HMMLIKELIHOOD_H_
+
diff --git a/src/Bpp/Numeric/Hmm/HmmStateAlphabet.h b/src/Bpp/Numeric/Hmm/HmmStateAlphabet.h
new file mode 100644
index 0000000..15e30f9
--- /dev/null
+++ b/src/Bpp/Numeric/Hmm/HmmStateAlphabet.h
@@ -0,0 +1,128 @@
+//
+// File: HmmStateAlphabet.h
+// Created by: Julien Dutheil
+// Created on: Fri Oct 26 11:07 2007
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 16, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _HMMSTATEALPHABET_H_
+#define _HMMSTATEALPHABET_H_
+
+#include "HmmExceptions.h"
+#include "../Parametrizable.h"
+#include "../../Exceptions.h"
+
+//From the STL:
+#include <vector>
+
+//using namespace bpp;
+
+namespace bpp {
+
+  class StateListener;
+  class StateChangedEvent;
+
+  /**
+   * @brief Hidden states alphabet.
+   *
+   * Implementations of this interface describe the set of hidden states of a Hidden Markov Model.
+   */
+  class HmmStateAlphabet:
+    public virtual Parametrizable
+  {
+    public:
+      HmmStateAlphabet() {}
+      virtual ~HmmStateAlphabet() {}
+
+    public:
+      /**
+       * @param stateIndex The index of a hidden state.
+       * @return The corresponding hidden state.
+       * @see getNumberOfStates
+       */
+      virtual const Clonable& getState(unsigned int stateIndex) const throw (HmmBadStateException) = 0;
+
+      /**
+       * @param stateIndex The index of a hidden state.
+       * @return The corresponding hidden state.
+       * @see getNumberOfStates
+       */
+      virtual Clonable& getState(unsigned int stateIndex) throw (HmmBadStateException) = 0;
+
+      virtual unsigned int getNumberOfStates() const = 0;
+
+      /**
+       * @brief Tell if this instance can work with the instance of alphabet given as input.
+       *
+       * In many case, this will return true is the pointer provided as argument refers to this object.
+       *
+       * @param stateAlphabet The alphabet to check.
+       * @return true if the matrix is compatible with the given alphabet.
+       */
+      virtual bool worksWith(const HmmStateAlphabet* stateAlphabet) const = 0;
+ 
+  };
+
+  class StateListener
+  {
+    public:
+      StateListener() {}
+      virtual ~StateListener() {}
+
+    public:
+      virtual void stateChanged(StateChangedEvent& event) = 0;
+  };
+
+  class StateChangedEvent
+  {
+    protected:
+      std::vector<unsigned int> states_;
+
+    public:
+      StateChangedEvent(unsigned int stateIndex): states_(1)
+    {
+      states_[0] = stateIndex;
+    }
+      StateChangedEvent(std::vector<unsigned int>& states): states_(states) {}
+
+    public:
+      const std::vector<unsigned int>& getStates() const { return states_; }
+      std::vector<unsigned int>& getStates() { return states_; }
+
+  };
+
+}
+#endif //_HMMSTATEALPHABET_H_
+
diff --git a/src/Bpp/Numeric/Hmm/HmmTransitionMatrix.h b/src/Bpp/Numeric/Hmm/HmmTransitionMatrix.h
new file mode 100644
index 0000000..72ddd80
--- /dev/null
+++ b/src/Bpp/Numeric/Hmm/HmmTransitionMatrix.h
@@ -0,0 +1,107 @@
+//
+// File: HmmTransitionMatrix.h
+// Created by: Julien Dutheil
+// Created on: Sat Oct 27 10:24 2007
+//
+
+/*
+Copyright or © or Copr. Bio++Development Team, (November 16, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _HMMTRANSITIONMATRIX_H_
+#define _HMMTRANSITIONMATRIX_H_
+
+#include "HmmStateAlphabet.h"
+#include "HmmExceptions.h"
+#include "../Matrix/Matrix.h"
+#include "../Parametrizable.h"
+
+//Fron the STL:
+#include <vector>
+
+namespace bpp
+{
+
+/**
+ * @brief Describe the transition probabilities between hidden states of a Hidden Markov Model.
+ *
+ * This class is part of the HMM framework.
+ */
+class HmmTransitionMatrix:
+  public virtual Parametrizable
+{
+  public:
+
+    /**
+     * @return The hidden alphabet associated to this model.
+     */
+    virtual const HmmStateAlphabet* getHmmStateAlphabet() const = 0;
+
+    /**
+     * @brief Set the new hidden state alphabet.
+     * @param stateAlphabet The new state alphabet.
+     * @throw UnvalidStateAlphabetException if the new alphabet is uncorrect (for instance is NULL pointer).
+     */
+    virtual void setHmmStateAlphabet(const HmmStateAlphabet* stateAlphabet) throw (HmmUnvalidAlphabetException) = 0;
+   
+    /**
+     * @return The number of states in the model.
+     */
+    virtual unsigned int getNumberOfStates() const = 0;
+
+    /**
+     * @brief Get the transition probability between two states.
+     *
+     * @param i initial state.
+     * @param j final state.
+     * @return the transition probability between the two states.
+     */
+    virtual double Pij(unsigned int i, unsigned int j) const = 0;
+
+    /**
+     * @brief Get all transition probabilities as a matrix.
+     *
+     * @return A n*n matrix will all transition probabilities (n being the number of hidden states).
+     */
+    virtual const Matrix<double>& getPij() const = 0;
+
+    /**
+     * @return The vector of equilibrium frequencies of the Markov chain described by the matrix.
+     */
+    virtual const std::vector<double>& getEquilibriumFrequencies() const = 0;
+
+};
+
+} //end of namespace bpp
+
+#endif //_HMMTRANSITIONMATRIX_H_
+
diff --git a/src/Bpp/Numeric/Hmm/LogsumHmmLikelihood.cpp b/src/Bpp/Numeric/Hmm/LogsumHmmLikelihood.cpp
new file mode 100644
index 0000000..a8aa7fd
--- /dev/null
+++ b/src/Bpp/Numeric/Hmm/LogsumHmmLikelihood.cpp
@@ -0,0 +1,291 @@
+//
+// File: LogsumHmmLikelihood.cpp
+// Created by: Julien Dutheil
+// Created on: Fri Oct 26 11:57 2007
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 16, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "LogsumHmmLikelihood.h"
+
+// from the STL:
+#include <iostream>
+#include <algorithm>
+using namespace bpp;
+using namespace std;
+
+LogsumHmmLikelihood::LogsumHmmLikelihood(
+    HmmStateAlphabet* hiddenAlphabet,
+    HmmTransitionMatrix* transitionMatrix,
+    HmmEmissionProbabilities* emissionProbabilities,
+    const std::string& prefix) throw (Exception):
+  AbstractParametrizable(prefix),
+  hiddenAlphabet_(hiddenAlphabet),
+  transitionMatrix_(transitionMatrix),
+  emissionProbabilities_(emissionProbabilities),
+  logLikelihood_(),
+  partialLogLikelihoods_(),
+  logLik_(),
+  breakPoints_(),
+  nbStates_(),
+  nbSites_()
+{
+  if (!hiddenAlphabet)        throw Exception("LogsumHmmLikelihood: null pointer passed for HmmStateAlphabet.");
+  if (!transitionMatrix)      throw Exception("LogsumHmmLikelihood: null pointer passed for HmmTransitionMatrix.");
+  if (!emissionProbabilities) throw Exception("LogsumHmmLikelihood: null pointer passed for HmmEmissionProbabilities.");
+  if (!hiddenAlphabet_->worksWith(transitionMatrix->getHmmStateAlphabet()))
+    throw Exception("LogsumHmmLikelihood: HmmTransitionMatrix and HmmEmissionProbabilities should point toward the same HmmStateAlphabet object.");
+  if (!hiddenAlphabet_->worksWith(emissionProbabilities->getHmmStateAlphabet()))
+    throw Exception("LogsumHmmLikelihood: HmmTransitionMatrix and HmmEmissionProbabilities should point toward the same HmmStateAlphabet object.");
+  nbStates_ = hiddenAlphabet_->getNumberOfStates();
+  nbSites_ = emissionProbabilities_->getNumberOfPositions();
+
+  //Manage parameters:
+  addParameters_(hiddenAlphabet_->getParameters());
+  addParameters_(transitionMatrix_->getParameters());
+  addParameters_(emissionProbabilities_->getParameters());
+
+  //Init arrays:
+  logLikelihood_.resize(nbSites_ * nbStates_);
+  
+  //Compute:
+  computeForward_();
+}
+
+void LogsumHmmLikelihood::fireParameterChanged(const ParameterList& pl)
+{
+  bool alphabetChanged    = hiddenAlphabet_->matchParametersValues(pl);
+  bool transitionsChanged = transitionMatrix_->matchParametersValues(pl);
+  bool emissionChanged    = emissionProbabilities_->matchParametersValues(pl);
+  // these lines are necessary because the transitions and emissions can depend on the alphabet.
+  // we could use a StateChangeEvent, but this would result in computing some calculations twice in some cases
+  // (when both the alphabet and other parameter changed).
+  if (alphabetChanged && !transitionsChanged) transitionMatrix_->setParametersValues(transitionMatrix_->getParameters());
+  if (alphabetChanged && !emissionChanged) emissionProbabilities_->setParametersValues(emissionProbabilities_->getParameters());
+  
+  computeForward_();
+}
+
+/***************************************************************************************************************************/
+
+void LogsumHmmLikelihood::computeForward_()
+{
+  double x, a;
+  vector<double> logTrans(nbStates_ * nbStates_);
+
+  //Transition probabilities:
+  for (size_t i = 0; i < nbStates_; i++)
+  {
+    size_t ii = i * nbStates_;
+    for (size_t j = 0; j < nbStates_; j++)
+      logTrans[ii + j] = log(transitionMatrix_->Pij(static_cast<int>(j), static_cast<int>(i)));
+  }
+
+  //Initialisation:
+  const vector<double>* emissions = &(*emissionProbabilities_)(0);
+  for (size_t j = 0; j < nbStates_; j++)
+  {
+    size_t jj = j * nbStates_;
+    x = logTrans[jj] + log(transitionMatrix_->getEquilibriumFrequencies()[0]);
+    for (size_t k = 1; k < nbStates_; k++)
+    {
+      a = logTrans[k + jj] + log(transitionMatrix_->getEquilibriumFrequencies()[k]);
+      x = NumTools::logsum(x, a);
+    }
+    logLikelihood_[j] = log((*emissions)[j]) + x;
+  }
+ 
+  //Recursion:
+  size_t nextBrkPt = nbSites_; //next break point
+  vector<size_t>::const_iterator bpIt = breakPoints_.begin();
+  if (bpIt != breakPoints_.end()) nextBrkPt = *bpIt;
+  partialLogLikelihoods_.clear();
+ 
+  for (size_t i = 1; i < nbSites_; i++)
+  {
+    size_t ii = i * nbStates_;
+    size_t iip = (i - 1) * nbStates_;
+    emissions = &(*emissionProbabilities_)(i);
+    if (i < nextBrkPt)
+    {
+      for (size_t j = 0; j < nbStates_; j++)
+      {
+        size_t jj = j * nbStates_;
+        x = logTrans[jj] + logLikelihood_[iip];
+        for (size_t k = 1; k < nbStates_; k++)
+        {
+          a = logTrans[jj + k] + logLikelihood_[iip + k];
+          x = NumTools::logsum(x, a);
+        }
+        logLikelihood_[ii + j] = log((*emissions)[j]) + x;
+      }
+    }
+    else //Reset markov chain:
+    {
+      //Termination of previous segment:
+      double tmpLog = logLikelihood_[(i - 1) * nbStates_];
+      for (size_t k = 1; k < nbStates_; k++)
+        tmpLog = NumTools::logsum(tmpLog, logLikelihood_[(i - 1) * nbStates_ + k]);
+      partialLogLikelihoods_.push_back(tmpLog);
+
+      for (size_t j = 0; j < nbStates_; j++)
+      {
+        size_t jj = j * nbStates_;
+        x = logTrans[jj] + log(transitionMatrix_->getEquilibriumFrequencies()[0]);
+        for (size_t k = 1; k < nbStates_; k++)
+        {
+          a = logTrans[jj + k] + log(transitionMatrix_->getEquilibriumFrequencies()[k]);
+          x = NumTools::logsum(x, a);
+        }
+        logLikelihood_[ii + j] = log((*emissions)[j]) + x;
+      }
+      bpIt++;
+      if (bpIt != breakPoints_.end()) nextBrkPt = *bpIt;
+      else nextBrkPt = nbSites_;
+    }
+  }
+  //Termination:
+  double tmpLog = logLikelihood_[(nbSites_ - 1) * nbStates_];
+  for (unsigned int k = 1; k < nbStates_; k++)
+    tmpLog = NumTools::logsum(tmpLog, logLikelihood_[(nbSites_ - 1) * nbStates_ + k]);
+  partialLogLikelihoods_.push_back(tmpLog);
+  
+  //Compute likelihood:
+  logLik_ = 0;
+  vector<double> copy = partialLogLikelihoods_; //We need to keep the original order for posterior decoding.
+  sort(copy.begin(), copy.end());
+  for (size_t i = copy.size(); i > 0; --i)
+    logLik_ += copy[i - 1];
+}
+
+/***************************************************************************************************************************/
+
+void LogsumHmmLikelihood::computeBackward_(std::vector< std::vector<double> >& b) const
+{
+  b.resize(nbSites_);
+  for (size_t i = 0; i < nbSites_; i++)
+  {
+    b[i].resize(nbStates_);
+  }
+  double x;
+
+  //Transition probabilities:
+  vector<double> logTrans(nbStates_ * nbStates_);
+  for (size_t i = 0; i < nbStates_; i++)
+  {
+    size_t ii = i * nbStates_;
+    for (size_t j = 0; j < nbStates_; j++)
+      logTrans[ii + j] = log(transitionMatrix_->Pij(static_cast<int>(i), static_cast<int>(j)));
+  }
+
+
+  //Initialisation:
+  const vector<double>* emissions = 0;
+  size_t nextBrkPt = 0; //next break point
+  vector<size_t>::const_reverse_iterator bpIt = breakPoints_.rbegin();
+  if (bpIt != breakPoints_.rend()) nextBrkPt = *bpIt;
+  
+  for (size_t k = 0; k < nbStates_; k++)
+  {
+    b[nbSites_ - 1][k] = 0.;
+  }
+
+  //Recursion:
+  for (size_t i = nbSites_ - 1; i > 0; i--)
+  {
+    emissions = &(*emissionProbabilities_)(i);
+    if (i > nextBrkPt)
+    {
+      for (size_t j = 0; j < nbStates_; j++)
+      {
+        size_t jj = j * nbStates_;
+        x = log((*emissions)[0]) + logTrans[jj] + b[i][0];
+        for (size_t k = 1; k < nbStates_; k++)
+        {
+          x = NumTools::logsum(x, log((*emissions)[k]) + logTrans[jj + k] + b[i][k]);
+        }
+        b[i - 1][j] = x;
+      }    
+    }
+    else //Reset markov chain
+    {
+      for (unsigned int j = 0; j < nbStates_; j++)
+      {
+        b[i - 1][j] = 0.;
+      }    
+      bpIt++;
+      if (bpIt != breakPoints_.rend()) nextBrkPt = *bpIt;
+      else nextBrkPt = 0;
+    }
+  }
+}
+
+/***************************************************************************************************************************/
+
+void LogsumHmmLikelihood::getHiddenStatesPosteriorProbabilities(std::vector< std::vector<double> >& probs, bool append) const throw (Exception)
+{
+  size_t offset = append ? probs.size() : 0;
+  probs.resize(offset + nbSites_);
+  for (size_t i = 0; i < nbSites_; i++)
+  {
+    probs[offset + i].resize(nbStates_);
+  }
+
+  vector< vector<double> > logB;
+  computeBackward_(logB);
+ 
+  size_t nextBrkPt = nbSites_; //next break point
+  vector<size_t>::const_iterator bpIt = breakPoints_.begin();
+  if (bpIt != breakPoints_.end()) nextBrkPt = *bpIt;
+ 
+  vector<double>::const_iterator logLikIt = partialLogLikelihoods_.begin();
+  for (size_t i = 0; i < nbSites_; i++)
+  {
+    if (i == nextBrkPt) {
+      logLikIt++;
+      bpIt++;
+      if (bpIt != breakPoints_.end()) nextBrkPt = *bpIt;
+      else nextBrkPt = nbSites_;
+    }
+
+    size_t ii = i * nbStates_;
+    for (size_t j = 0; j < nbStates_; j++)
+    {
+      probs[offset + i][j] = exp(logLikelihood_[ii + j] + logB[i][j] - *logLikIt);
+    }
+  }
+}
+
+/***************************************************************************************************************************/
+
diff --git a/src/Bpp/Numeric/Hmm/LogsumHmmLikelihood.h b/src/Bpp/Numeric/Hmm/LogsumHmmLikelihood.h
new file mode 100644
index 0000000..5501d85
--- /dev/null
+++ b/src/Bpp/Numeric/Hmm/LogsumHmmLikelihood.h
@@ -0,0 +1,190 @@
+//
+// File: LogsumHmmLikelihood.h
+// Created by: Julien Dutheil
+// Created on: Mon Nov 23 11:27 2009
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _LOGSUMHMMLIKELIHOOD_H_
+#define _LOGSUMHMMLIKELIHOOD_H_
+
+#include "HmmLikelihood.h"
+#include "../AbstractParametrizable.h"
+#include "../NumTools.h"
+#include "../Matrix/Matrix.h"
+
+//From the STL:
+#include <vector>
+#include <memory>
+
+namespace bpp {
+
+  /**
+   * @brief A simple implementation of hidden Markov models recursion.
+   *
+   * This implementation uses the logsum method described in Durbin et al "Biological sequence analysis", Cambridge University Press,
+   * and further developped in Tobias P. Mann "Numerically Stable Hidden Markov Model Implementation" (2006) http://bozeman.genome.washington.edu/compbio/mbt599_2006/hmm_scaling_revised.pdf .
+   * It also offer the possibility to specify "breakpoints", where the chain will be reset to the equilibrium frequencies.
+   *
+   * Although probably more numerically accurate, this method is slower than the rescaling, as it involves one exponentiation per site and per hidden state!
+   *
+   * @see RescaledHmmLikelihood
+   */
+  class LogsumHmmLikelihood:
+    public virtual HmmLikelihood,
+    public AbstractParametrizable
+  {
+    private:
+      /**
+       * @brief The alphabet describing the hidden states.
+       */
+      std::auto_ptr<HmmStateAlphabet> hiddenAlphabet_;
+      std::auto_ptr<HmmTransitionMatrix> transitionMatrix_;
+      std::auto_ptr<HmmEmissionProbabilities> emissionProbabilities_;
+
+      /**
+       * @brief The likelihood array.
+       *
+       * logLikelihood_[i * nbStates_ + j] corresponds to Pr(x1...xi, yi=j),
+       * where the x are the observed states, and y the hidden states.
+       */
+      std::vector<double> logLikelihood_;
+      std::vector<double> partialLogLikelihoods_;
+      double logLik_;
+
+      std::vector<size_t> breakPoints_;
+
+      size_t nbStates_, nbSites_;
+
+    public:
+      /**
+       * @brief Build a new LogsumHmmLikelihood object.
+       *
+       * @warning the HmmTransitionMatrix and HmmEmissionProbabilities object passed as argument must be non-null
+       * and point toward the same HmmStateAlphabet instance. The three object will be copied if needed, and
+       * deleted when the hmm likelihood objet is deleted. You should secure a copy before if you don't want them to
+       * be destroyed with this object.
+       */
+      LogsumHmmLikelihood(
+          HmmStateAlphabet* hiddenAlphabet,
+          HmmTransitionMatrix* transitionMatrix,
+          HmmEmissionProbabilities* emissionProbabilities,
+          const std::string& prefix) throw (Exception);
+
+      LogsumHmmLikelihood(const LogsumHmmLikelihood& lik):
+        AbstractParametrizable(lik),
+        hiddenAlphabet_(dynamic_cast<HmmStateAlphabet*>(lik.hiddenAlphabet_->clone())),
+        transitionMatrix_(dynamic_cast<HmmTransitionMatrix*>(lik.transitionMatrix_->clone())),
+        emissionProbabilities_(dynamic_cast<HmmEmissionProbabilities*>(lik.emissionProbabilities_->clone())),
+        logLikelihood_(lik.logLikelihood_),
+        partialLogLikelihoods_(lik.partialLogLikelihoods_),
+        logLik_(lik.logLik_),
+        breakPoints_(lik.breakPoints_),
+        nbStates_(lik.nbStates_),
+        nbSites_(lik.nbSites_)
+      {
+        // Now adjust pointers:
+        transitionMatrix_->setHmmStateAlphabet(hiddenAlphabet_.get());
+        emissionProbabilities_->setHmmStateAlphabet(hiddenAlphabet_.get());
+      }
+
+      LogsumHmmLikelihood& operator=(const LogsumHmmLikelihood& lik)
+      {
+        AbstractParametrizable::operator =(lik);
+        hiddenAlphabet_        = std::auto_ptr<HmmStateAlphabet>(dynamic_cast<HmmStateAlphabet*>(lik.hiddenAlphabet_->clone()));
+        transitionMatrix_      = std::auto_ptr<HmmTransitionMatrix>(dynamic_cast<HmmTransitionMatrix*>(lik.transitionMatrix_->clone()));
+        emissionProbabilities_ = std::auto_ptr<HmmEmissionProbabilities>(dynamic_cast<HmmEmissionProbabilities*>(lik.emissionProbabilities_->clone()));
+        logLikelihood_         = lik.logLikelihood_;
+        partialLogLikelihoods_ = lik.partialLogLikelihoods_;
+        logLik_                = lik.logLik_;
+        breakPoints_           = lik.breakPoints_;
+        nbStates_              = lik.nbStates_;
+        nbSites_               = lik.nbSites_;
+
+        // Now adjust pointers:
+        transitionMatrix_->setHmmStateAlphabet(hiddenAlphabet_.get());
+        emissionProbabilities_->setHmmStateAlphabet(hiddenAlphabet_.get());
+        return *this;
+      }
+
+      virtual ~LogsumHmmLikelihood() {}
+
+#ifndef NO_VIRTUAL_COV
+      LogsumHmmLikelihood*
+#else
+      Clonable*
+#endif
+      clone() const { return new LogsumHmmLikelihood(*this); }
+
+    public:
+      const HmmStateAlphabet& getHmmStateAlphabet() const { return *hiddenAlphabet_; }
+      HmmStateAlphabet& getHmmStateAlphabet() { return *hiddenAlphabet_; }
+
+      const HmmTransitionMatrix& getHmmTransitionMatrix() const { return *transitionMatrix_; }
+      HmmTransitionMatrix& getHmmTransitionMatrix() { return *transitionMatrix_; }
+
+      const HmmEmissionProbabilities& getHmmEmissionProbabilities() const { return *emissionProbabilities_; }
+      HmmEmissionProbabilities& getHmmEmissionProbabilities() { return *emissionProbabilities_; }
+
+      void setBreakPoints(const std::vector<size_t>& breakPoints) {
+        breakPoints_ = breakPoints;
+        computeForward_();
+      }
+
+      const std::vector<size_t>& getBreakPoints() const { return breakPoints_; }
+
+      void setParameters(const ParameterList& pl) throw (Exception)
+      {
+        setParametersValues(pl);
+      }
+
+      double getValue() const throw (Exception) { return -logLik_; }
+
+      double getLogLikelihood() const { return logLik_; }
+
+      void fireParameterChanged(const ParameterList& pl);
+
+      void getHiddenStatesPosteriorProbabilities(std::vector< std::vector<double> >& probs, bool append = false) const throw (Exception);
+
+    protected:
+      void computeForward_();
+      void computeBackward_(std::vector< std::vector<double> >& b) const;
+
+  };
+
+}
+
+#endif //_LOGSUMHMMLIKELIHOOD_H_
+
diff --git a/src/Bpp/Numeric/Hmm/LowMemoryRescaledHmmLikelihood.cpp b/src/Bpp/Numeric/Hmm/LowMemoryRescaledHmmLikelihood.cpp
new file mode 100644
index 0000000..6caf388
--- /dev/null
+++ b/src/Bpp/Numeric/Hmm/LowMemoryRescaledHmmLikelihood.cpp
@@ -0,0 +1,246 @@
+//
+// File: LowMemoryRescaledHmmLikelihood.h
+// Created by: Julien Dutheil
+// Created on: Wed Dec 16 10:47 2009
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for phylogenetic data analysis.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "LowMemoryRescaledHmmLikelihood.h"
+
+// from the STL:
+#include <iostream>
+#include <algorithm>
+using namespace bpp;
+using namespace std;
+
+LowMemoryRescaledHmmLikelihood::LowMemoryRescaledHmmLikelihood(
+  HmmStateAlphabet* hiddenAlphabet,
+  HmmTransitionMatrix* transitionMatrix,
+  HmmEmissionProbabilities* emissionProbabilities,
+  const std::string& prefix,
+  size_t maxSize) throw (Exception) :
+  AbstractParametrizable(prefix),
+  hiddenAlphabet_(hiddenAlphabet),
+  transitionMatrix_(transitionMatrix),
+  emissionProbabilities_(emissionProbabilities),
+  likelihood1_(),
+  likelihood2_(),
+  logLik_(),
+  maxSize_(maxSize),
+  breakPoints_(),
+  nbStates_(),
+  nbSites_()
+{
+  if (!hiddenAlphabet) throw Exception("LowMemoryRescaledHmmLikelihood: null pointer passed for HmmStateAlphabet.");
+  if (!transitionMatrix) throw Exception("LowMemoryRescaledHmmLikelihood: null pointer passed for HmmTransitionMatrix.");
+  if (!emissionProbabilities) throw Exception("LowMemoryRescaledHmmLikelihood: null pointer passed for HmmEmissionProbabilities.");
+  if (!hiddenAlphabet_->worksWith(transitionMatrix->getHmmStateAlphabet()))
+    throw Exception("LowMemoryRescaledHmmLikelihood: HmmTransitionMatrix and HmmEmissionProbabilities should point toward the same HmmStateAlphabet object.");
+  if (!hiddenAlphabet_->worksWith(emissionProbabilities->getHmmStateAlphabet()))
+    throw Exception("LowMemoryRescaledHmmLikelihood: HmmTransitionMatrix and HmmEmissionProbabilities should point toward the same HmmStateAlphabet object.");
+  nbStates_ = hiddenAlphabet_->getNumberOfStates();
+  nbSites_ = emissionProbabilities_->getNumberOfPositions();
+
+  // Manage parameters:
+  addParameters_(hiddenAlphabet_->getParameters());
+  addParameters_(transitionMatrix_->getParameters());
+  addParameters_(emissionProbabilities_->getParameters());
+
+  // Init arrays:
+  likelihood1_.resize(nbStates_);
+  likelihood2_.resize(nbStates_);
+
+  // Compute:
+  computeForward_();
+}
+
+void LowMemoryRescaledHmmLikelihood::fireParameterChanged(const ParameterList& pl)
+{
+   bool alphabetChanged    = hiddenAlphabet_->matchParametersValues(pl);
+   bool transitionsChanged = transitionMatrix_->matchParametersValues(pl);
+   bool emissionChanged    = emissionProbabilities_->matchParametersValues(pl);
+  // these lines are necessary because the transitions and emissions can depend on the alphabet.
+  // we could use a StateChangeEvent, but this would result in computing some calculations twice in some cases
+  // (when both the alphabet and other parameter changed).
+  if (alphabetChanged && !transitionsChanged) transitionMatrix_->setParametersValues(transitionMatrix_->getParameters());
+  if (alphabetChanged && !emissionChanged) emissionProbabilities_->setParametersValues(emissionProbabilities_->getParameters());
+
+  computeForward_();
+}
+
+/***************************************************************************************************************************/
+
+void LowMemoryRescaledHmmLikelihood::computeForward_()
+{
+  double x;
+  vector<double> tmp(nbStates_);
+  vector<double> lScales(min(maxSize_, nbSites_));
+  vector<double> trans(nbStates_ * nbStates_);
+
+  // Transition probabilities:
+  for (size_t i = 0; i < nbStates_; i++)
+  {
+   size_t ii = i * nbStates_;
+    for (size_t j = 0; j < nbStates_; j++)
+    {
+      trans[ii + j] = transitionMatrix_->Pij(static_cast<int>(j), static_cast<int>(i));
+    }
+  }
+
+  // Initialisation:
+  double scale = 0;
+  const vector<double>* emissions = &(*emissionProbabilities_)(0);
+  for (size_t j = 0; j < nbStates_; j++)
+  {
+   size_t jj = j * nbStates_;
+    x = 0;
+    for (size_t k = 0; k < nbStates_; k++)
+    {
+      x += trans[k + jj] * transitionMatrix_->getEquilibriumFrequencies()[k];
+    }
+    tmp[j] = (*emissions)[j] * x;
+    scale += tmp[j];
+  }
+  for (size_t j = 0; j < nbStates_; j++)
+  {
+    likelihood1_[j] = tmp[j] / scale;
+  }
+  lScales[0] = log(scale);
+
+  vector<double>* previousLikelihood = &likelihood2_, * currentLikelihood = &likelihood1_, * tmpLikelihood;
+
+  // Recursion:
+  size_t nextBrkPt = nbSites_; // next break point
+  vector<size_t>::const_iterator bpIt = breakPoints_.begin();
+  if (bpIt != breakPoints_.end()) nextBrkPt = *bpIt;
+
+  double a;
+  logLik_ = 0;
+  size_t offset = 0;
+  greater<double> cmp;
+  for (size_t i = 1; i < nbSites_; i++)
+  {
+    //Swap pointers:
+    tmpLikelihood = previousLikelihood;
+    previousLikelihood = currentLikelihood;
+    currentLikelihood = tmpLikelihood;
+
+    scale = 0;
+    emissions = &(*emissionProbabilities_)(i);
+    if (i < nextBrkPt)
+    {
+      for (size_t j = 0; j < nbStates_; j++)
+      {
+        size_t jj = j * nbStates_;
+        x = 0;
+        for (size_t k = 0; k < nbStates_; k++)
+        {
+          a = trans[jj + k] * (*previousLikelihood)[k];
+          if (a < 0)
+          {
+            // *ApplicationTools::warning << "Negative value for likelihood at " << i << ", state " << j << ": " << _likelihood[i-1][k] << ", Pij = " << _hiddenModel->Pij(k, j) << endl;
+            a = 0;
+          }
+          x += a;
+        }
+        tmp[j] = (*emissions)[j] * x;
+        if (tmp[j] < 0)
+        {
+          // *ApplicationTools::warning << "Negative emission probability at " << i << ", state " << j << ": " << _emissions[i][j] << endl;
+          tmp[j] = 0;
+        }
+        scale += tmp[j];
+      }
+    }
+    else // Reset markov chain:
+    {
+      for (size_t j = 0; j < nbStates_; j++)
+      {
+        size_t jj = j * nbStates_;
+        x = 0;
+        for (size_t k = 0; k < nbStates_; k++)
+        {
+          a = trans[jj + k] * transitionMatrix_->getEquilibriumFrequencies()[k];
+          if (a < 0)
+          {
+            // *ApplicationTools::warning << "Negative value for likelihood at " << i << ", state " << j << ": " << _likelihood[i-1][k] << ", Pij = " << _hiddenModel->Pij(k, j) << endl;
+            a = 0;
+          }
+          x += a;
+        }
+        tmp[j] = (*emissions)[j] * x;
+        if (tmp[j] < 0)
+        {
+          // *ApplicationTools::warning << "Negative emission probability at " << i << ", state " << j << ": " << _emissions[i][j] << endl;
+          tmp[j] = 0;
+        }
+        scale += tmp[j];
+      }
+      bpIt++;
+      if (bpIt != breakPoints_.end()) nextBrkPt = *bpIt;
+      else nextBrkPt = nbSites_;
+    }
+
+    for (size_t j = 0; j < nbStates_; j++)
+    {
+      if (scale > 0) (*currentLikelihood)[j] = tmp[j] / scale;
+      else (*currentLikelihood)[j] = 0;
+    }
+    lScales[i - offset] = log(scale);
+  
+    if (i - offset == maxSize_ - 1)
+    {
+      //We make partial calculations and reset the arrays:
+      double partialLogLik = 0;
+      sort(lScales.begin(), lScales.end(), cmp);
+      for (size_t j = 0; j < maxSize_; ++j)
+      {
+        partialLogLik += lScales[j];
+      }
+      logLik_ += partialLogLik;
+      offset += maxSize_;
+    }
+  }
+  sort(lScales.begin(), lScales.begin() + nbSites_ - offset, cmp);
+  double partialLogLik = 0;
+  for (size_t i = 0; i < nbSites_ - offset; ++i)
+  {
+    partialLogLik += lScales[i];
+  }
+  logLik_ += partialLogLik;
+}
+
+/***************************************************************************************************************************/
+
diff --git a/src/Bpp/Numeric/Hmm/LowMemoryRescaledHmmLikelihood.h b/src/Bpp/Numeric/Hmm/LowMemoryRescaledHmmLikelihood.h
new file mode 100644
index 0000000..06d49ad
--- /dev/null
+++ b/src/Bpp/Numeric/Hmm/LowMemoryRescaledHmmLikelihood.h
@@ -0,0 +1,198 @@
+//
+// File: LowMemoryRescaledHmmLikelihood.h
+// Created by: Julien Dutheil
+// Created on: Wed Dec 16 10:47 2009
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for phylogenetic data analysis.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#ifndef _LOWMEMORYRESCALEDHMMLIKELIHOOD_H_
+#define _LOWMEMORYRESCALEDHMMLIKELIHOOD_H_
+
+#include "HmmLikelihood.h"
+#include "../AbstractParametrizable.h"
+#include "../Matrix/Matrix.h"
+
+// From the STL:
+#include <vector>
+#include <memory>
+
+namespace bpp
+{
+/**
+ * @brief A modified implementation of the RescaledHmmLikelihood implementation, with lower memory usage.
+ *
+ * This implementation is similar to the one used in the RescaledHmmLikelihood class,
+ * but does not store the full likelihood array. The benefit of it is a significantly reduced
+ * memory usage, allowing to compute likelihood for very large data sets.
+ * The drawback is that this class can't compute posterior probabilities, and can hence only
+ * be used to estimate parameters.
+ */
+class LowMemoryRescaledHmmLikelihood :
+  public virtual HmmLikelihood,
+  public AbstractParametrizable
+{
+private:
+  /**
+   * @brief The alphabet describing the hidden states.
+   */
+  std::auto_ptr<HmmStateAlphabet> hiddenAlphabet_;
+  std::auto_ptr<HmmTransitionMatrix> transitionMatrix_;
+  std::auto_ptr<HmmEmissionProbabilities> emissionProbabilities_;
+
+  /**
+   * @brief The likelihood array.
+   *
+   * Here we use two arrays for the i and i-1 positions
+   */
+  std::vector<double> likelihood1_;
+  std::vector<double> likelihood2_;
+  double logLik_;
+  size_t maxSize_;
+
+  std::vector<size_t> breakPoints_;
+
+  size_t nbStates_, nbSites_;
+
+public:
+  /**
+   * @brief Build a new LowMemoryRescaledHmmLikelihood object.
+   *
+   * @warning the HmmTransitionMatrix and HmmEmissionProbabilities object passed as argument must be non-null
+   * and point toward the same HmmStateAlphabet instance. The three object will be copied if needed, and
+   * deleted when the hmm likelihood objet is deleted. You should secure a copy before if you don't want them to
+   * be destroyed with this object.
+   *
+   * @param hiddenAlphabet The hidden states alphabet to use.
+   * @param transitionMatrix The transition matrix to use.
+   * @param emissionProbabilities The emission probabilities to use.
+   * @param prefix A namespace for parameter names.
+   * @param maxSize the maximum size of the vector of scales. If this size is exceeded, then a temporary likelihood computation is made and stored, and the vector is reset.
+   * the size of the vector specify the memory usage of the class. A two low value can lead to numerical precision errors.
+   */
+  LowMemoryRescaledHmmLikelihood(
+    HmmStateAlphabet* hiddenAlphabet,
+    HmmTransitionMatrix* transitionMatrix,
+    HmmEmissionProbabilities* emissionProbabilities,
+    const std::string& prefix,
+    size_t maxSize = 1000000) throw (Exception);
+
+  LowMemoryRescaledHmmLikelihood(const LowMemoryRescaledHmmLikelihood& lik) :
+    AbstractParametrizable(lik),
+    hiddenAlphabet_(dynamic_cast<HmmStateAlphabet*>(lik.hiddenAlphabet_->clone())),
+    transitionMatrix_(dynamic_cast<HmmTransitionMatrix*>(lik.transitionMatrix_->clone())),
+    emissionProbabilities_(dynamic_cast<HmmEmissionProbabilities*>(lik.emissionProbabilities_->clone())),
+    likelihood1_(lik.likelihood1_),
+    likelihood2_(lik.likelihood2_),
+    logLik_(lik.logLik_),
+    maxSize_(lik.maxSize_),
+    breakPoints_(lik.breakPoints_),
+    nbStates_(lik.nbStates_),
+    nbSites_(lik.nbSites_)
+  {
+    // Now adjust pointers:
+    transitionMatrix_->setHmmStateAlphabet(hiddenAlphabet_.get());
+    emissionProbabilities_->setHmmStateAlphabet(hiddenAlphabet_.get());
+  }
+
+  LowMemoryRescaledHmmLikelihood& operator=(const LowMemoryRescaledHmmLikelihood& lik)
+  {
+    AbstractParametrizable::operator=(lik);
+    hiddenAlphabet_        = std::auto_ptr<HmmStateAlphabet>(dynamic_cast<HmmStateAlphabet*>(lik.hiddenAlphabet_->clone()));
+    transitionMatrix_      = std::auto_ptr<HmmTransitionMatrix>(dynamic_cast<HmmTransitionMatrix*>(lik.transitionMatrix_->clone()));
+    emissionProbabilities_ = std::auto_ptr<HmmEmissionProbabilities>(dynamic_cast<HmmEmissionProbabilities*>(lik.emissionProbabilities_->clone()));
+    likelihood1_           = lik.likelihood1_;
+    likelihood2_           = lik.likelihood2_;
+    logLik_                = lik.logLik_;
+    maxSize_               = lik.maxSize_;
+    breakPoints_           = lik.breakPoints_;
+    nbStates_              = lik.nbStates_;
+    nbSites_               = lik.nbSites_;
+
+    // Now adjust pointers:
+    transitionMatrix_->setHmmStateAlphabet(hiddenAlphabet_.get());
+    emissionProbabilities_->setHmmStateAlphabet(hiddenAlphabet_.get());
+    return *this;
+  }
+
+  virtual ~LowMemoryRescaledHmmLikelihood() {}
+
+#ifndef NO_VIRTUAL_COV
+  LowMemoryRescaledHmmLikelihood*
+#else
+  Clonable*
+#endif
+  clone() const { return new LowMemoryRescaledHmmLikelihood(*this); }
+
+public:
+  const HmmStateAlphabet& getHmmStateAlphabet() const { return *hiddenAlphabet_; }
+  HmmStateAlphabet& getHmmStateAlphabet() { return *hiddenAlphabet_; }
+
+  const HmmTransitionMatrix& getHmmTransitionMatrix() const { return *transitionMatrix_; }
+  HmmTransitionMatrix& getHmmTransitionMatrix() { return *transitionMatrix_; }
+
+  const HmmEmissionProbabilities& getHmmEmissionProbabilities() const { return *emissionProbabilities_; }
+  HmmEmissionProbabilities& getHmmEmissionProbabilities() { return *emissionProbabilities_; }
+
+  void setBreakPoints(const std::vector<size_t>& breakPoints) {
+    breakPoints_ = breakPoints;
+    computeForward_();
+  }
+
+  const std::vector<size_t>& getBreakPoints() const { return breakPoints_; }
+
+  void setParameters(const ParameterList& pl) throw (Exception)
+  {
+    setParametersValues(pl);
+  }
+
+  double getValue() const throw (Exception) { return -logLik_; }
+
+  double getLogLikelihood() const { return logLik_; }
+
+  void fireParameterChanged(const ParameterList& pl);
+
+  void getHiddenStatesPosteriorProbabilities(std::vector< std::vector<double> >& probs, bool append = false) const throw (NotImplementedException)
+  {
+    throw (NotImplementedException("LowMemoryRescaledHmmLikelihood::getHiddenStatesPosteriorProbabilities. This class can't compute posterior probabilities, use RescaledHmmLikelihood instead."));    
+  }
+
+protected:
+  void computeForward_();
+};
+
+}
+
+#endif // _RESCALEDHMMLIKELIHOOD_H_
+
diff --git a/src/Bpp/Numeric/Hmm/RescaledHmmLikelihood.cpp b/src/Bpp/Numeric/Hmm/RescaledHmmLikelihood.cpp
new file mode 100644
index 0000000..cc7350f
--- /dev/null
+++ b/src/Bpp/Numeric/Hmm/RescaledHmmLikelihood.cpp
@@ -0,0 +1,317 @@
+//
+// File: RescaledHmmLikelihood.cpp
+// Created by: Julien Dutheil
+// Created on: Fri Oct 26 11:57 2007
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "RescaledHmmLikelihood.h"
+
+#include "../../App/ApplicationTools.h"
+
+// from the STL:
+#include <iostream>
+#include <algorithm>
+using namespace bpp;
+using namespace std;
+
+RescaledHmmLikelihood::RescaledHmmLikelihood(
+    HmmStateAlphabet* hiddenAlphabet,
+    HmmTransitionMatrix* transitionMatrix,
+    HmmEmissionProbabilities* emissionProbabilities,
+    const std::string& prefix) throw (Exception):
+  AbstractParametrizable(prefix),
+  hiddenAlphabet_(hiddenAlphabet),
+  transitionMatrix_(transitionMatrix),
+  emissionProbabilities_(emissionProbabilities),
+  likelihood_(),
+  scales_(),
+  logLik_(),
+  breakPoints_(),
+  nbStates_(),
+  nbSites_()
+{
+  if (!hiddenAlphabet)        throw Exception("RescaledHmmLikelihood: null pointer passed for HmmStateAlphabet.");
+  if (!transitionMatrix)      throw Exception("RescaledHmmLikelihood: null pointer passed for HmmTransitionMatrix.");
+  if (!emissionProbabilities) throw Exception("RescaledHmmLikelihood: null pointer passed for HmmEmissionProbabilities.");
+  if (!hiddenAlphabet_->worksWith(transitionMatrix->getHmmStateAlphabet()))
+    throw Exception("RescaledHmmLikelihood: HmmTransitionMatrix and HmmEmissionProbabilities should point toward the same HmmStateAlphabet object.");
+  if (!hiddenAlphabet_->worksWith(emissionProbabilities->getHmmStateAlphabet()))
+    throw Exception("RescaledHmmLikelihood: HmmTransitionMatrix and HmmEmissionProbabilities should point toward the same HmmStateAlphabet object.");
+  nbStates_ = hiddenAlphabet_->getNumberOfStates();
+  nbSites_ = emissionProbabilities_->getNumberOfPositions();
+
+  //Manage parameters:
+  addParameters_(hiddenAlphabet_->getParameters());
+  addParameters_(transitionMatrix_->getParameters());
+  addParameters_(emissionProbabilities_->getParameters());
+
+  //Init arrays:
+  likelihood_.resize(nbSites_ * nbStates_);
+  scales_.resize(nbSites_);
+  
+  //Compute:
+  computeForward_();
+}
+
+void RescaledHmmLikelihood::fireParameterChanged(const ParameterList& pl)
+{
+  bool alphabetChanged    = hiddenAlphabet_->matchParametersValues(pl);
+  bool transitionsChanged = transitionMatrix_->matchParametersValues(pl);
+  bool emissionChanged    = emissionProbabilities_->matchParametersValues(pl);
+  // these lines are necessary because the transitions and emissions can depend on the alphabet.
+  // we could use a StateChangeEvent, but this would result in computing some calculations twice in some cases
+  // (when both the alphabet and other parameter changed).
+  if (alphabetChanged && !transitionsChanged) transitionMatrix_->setParametersValues(transitionMatrix_->getParameters());
+  if (alphabetChanged && !emissionChanged) emissionProbabilities_->setParametersValues(emissionProbabilities_->getParameters());
+  
+  computeForward_();
+}
+
+/***************************************************************************************************************************/
+
+void RescaledHmmLikelihood::computeForward_()
+{
+  double x;
+  vector<double> tmp(nbStates_);
+  vector<double> lScales(nbSites_);
+  vector<double> trans(nbStates_ * nbStates_);
+
+  //Transition probabilities:
+  for (size_t i = 0; i < nbStates_; i++)
+  {
+    size_t ii = i * nbStates_;
+    for (size_t j = 0; j < nbStates_; j++) {
+      trans[ii + j] = transitionMatrix_->Pij(static_cast<int>(j), static_cast<int>(i));
+      if (isnan(trans[ii + j]))
+        throw Exception("RescaledHmmLikelihood::computeForward_. NaN transition probability");
+      if (trans[ii + j] < 0)
+        throw Exception("RescaledHmmLikelihood::computeForward_. Negative transition probability: " + TextTools::toString(trans[ii + j]));
+    }
+  }
+
+  //Initialisation:
+  scales_[0] = 0;
+  const vector<double>* emissions = &(*emissionProbabilities_)(0);
+  for (size_t j = 0; j < nbStates_; j++)
+  {
+    size_t jj = j * nbStates_;
+    x = 0;
+    for (size_t k = 0; k < nbStates_; k++)
+    {
+      x += trans[k + jj] * transitionMatrix_->getEquilibriumFrequencies()[k];
+      //cerr << j << "\t" << k << "\t" << trans[k + jj] << "\t" << transitionMatrix_->getEquilibriumFrequencies()[k] << "\t" << trans[k + jj] * transitionMatrix_->getEquilibriumFrequencies()[k] << "\t" << x << endl;  
+    }
+    tmp[j] = (*emissions)[j] * x;
+    //cerr << "e[j]=" << (*emissions)[j] << "\t" << tmp[j] << endl;
+    scales_[0] += tmp[j];
+  }
+  for (size_t j = 0; j < nbStates_; j++)
+  {
+    likelihood_[j] = tmp[j] / scales_[0];
+  }
+  lScales[0] = log(scales_[0]);
+ 
+  //Recursion:
+  size_t nextBrkPt = nbSites_; //next break point
+  vector<size_t>::const_iterator bpIt = breakPoints_.begin();
+  if (bpIt != breakPoints_.end()) nextBrkPt = *bpIt;
+  
+  double a;
+  for (size_t i = 1; i < nbSites_; i++)
+  {
+    size_t ii = i * nbStates_;
+    size_t iip = (i - 1) * nbStates_;
+    scales_[i] = 0 ;
+    emissions = &(*emissionProbabilities_)(i);
+    if (i < nextBrkPt)
+    {
+      for (size_t j = 0; j < nbStates_; j++)
+      {
+        size_t jj = j * nbStates_;
+        x = 0;
+        for (size_t k = 0; k < nbStates_; k++)
+        {
+          a = trans[jj + k] * likelihood_[iip + k];
+          //if (a < 0)
+          //{
+          //  (*ApplicationTools::warning << "Negative value for likelihood at " << i << ", state " << j << ": " << likelihood_[iip + k] << ", Pij = " << trans[jj + k]).endLine();
+          //  a = 0;
+          //}
+          x += a;
+        }
+        tmp[j] = (*emissions)[j] * x;
+        if (tmp[j] < 0)
+        {
+          (*ApplicationTools::warning << "Negative probability at " << i << ", state " << j << ": " << (*emissions)[j] << "\t" << x).endLine();
+          tmp[j] = 0;
+        }
+        scales_[i] += tmp[j];
+      }
+    }
+    else //Reset markov chain:
+    {
+      for (size_t j = 0; j < nbStates_; j++)
+      {
+        size_t jj = j * nbStates_;
+        x = 0;
+        for (size_t k = 0; k < nbStates_; k++)
+        {
+          a = trans[jj + k] * transitionMatrix_->getEquilibriumFrequencies()[k];
+          //if (a < 0)
+          //{
+          //  (*ApplicationTools::warning << "Negative value for likelihood at " << i << ", state " << j << ": ,Pij = " << trans[jj + k]).endLine();
+          //  a = 0;
+          //}
+          x += a;
+        }
+        tmp[j] = (*emissions)[j] * x;
+        //if (tmp[j] < 0)
+        //{
+        //  (*ApplicationTools::warning << "Negative emission probability at " << i << ", state " << j << ": " << (*emissions)[j]).endLine();
+        //  tmp[j] = 0;
+        //}
+        scales_[i] += tmp[j];
+      }
+      bpIt++;
+      if (bpIt != breakPoints_.end()) nextBrkPt = *bpIt;
+      else nextBrkPt = nbSites_;
+    }
+
+    for (size_t j = 0; j < nbStates_; j++)
+    {
+      if (scales_[i] > 0) likelihood_[ii + j] = tmp[j] / scales_[i];
+      else                likelihood_[ii + j] = 0;
+    }
+    lScales[i] = log(scales_[i]);
+  }
+  greater<double> cmp;
+  sort(lScales.begin(), lScales.end(), cmp);
+  logLik_ = 0;
+  for (size_t i = 0; i < nbSites_; ++i)
+  {
+    logLik_ += lScales[i];
+  }
+}
+
+/***************************************************************************************************************************/
+
+void RescaledHmmLikelihood::computeBackward_(std::vector< std::vector<double> >& b) const
+{
+  b.resize(nbSites_);
+  for (size_t i = 0; i < nbSites_; i++)
+  {
+    b[i].resize(nbStates_);
+  }
+  double x;
+
+  //Transition probabilities:
+  vector<double> trans(nbStates_ * nbStates_);
+  for (size_t i = 0; i < nbStates_; i++)
+  {
+    size_t ii = i * nbStates_;
+    for (size_t j = 0; j < nbStates_; j++)
+      trans[ii + j] = transitionMatrix_->Pij(static_cast<int>(i), static_cast<int>(j));
+  }
+
+
+  //Initialisation:
+  const vector<double>* emissions = 0;
+  size_t nextBrkPt = 0; //next break point
+  vector<size_t>::const_reverse_iterator bpIt = breakPoints_.rbegin();
+  if (bpIt != breakPoints_.rend()) nextBrkPt = *bpIt;
+  
+  for (size_t j = 0; j < nbStates_; j++)
+  {
+    x = 0;
+    b[nbSites_ - 1][j] = 1.;
+  }
+
+  //Recursion:
+  for (size_t i = nbSites_ - 1; i > 0; i--)
+  {
+    emissions = &(*emissionProbabilities_)(i);
+    if (i > nextBrkPt)
+    {
+      for (size_t j = 0; j < nbStates_; j++)
+      {
+        x = 0;
+        size_t jj = j * nbStates_;
+        for (size_t k = 0; k < nbStates_; k++)
+        {
+          x += (*emissions)[k] * trans[jj + k] * b[i][k];
+        }
+        b[i-1][j] = x / scales_[i];
+      }    
+    }
+    else //Reset markov chain
+    {
+      for (size_t j = 0; j < nbStates_; j++)
+      {
+        b[i-1][j] = 1.;
+      }    
+      bpIt++;
+      if (bpIt != breakPoints_.rend()) nextBrkPt = *bpIt;
+      else nextBrkPt = 0;
+    }
+  }
+}
+
+/***************************************************************************************************************************/
+
+void RescaledHmmLikelihood::getHiddenStatesPosteriorProbabilities(std::vector< std::vector<double> >& probs, bool append) const throw (Exception)
+{
+  size_t offset = append ? probs.size() : 0;
+  probs.resize(offset + nbSites_);
+  for (size_t i = 0; i < nbSites_; i++)
+  {
+    probs[offset + i].resize(nbStates_);
+  }
+
+  vector< vector<double> > b;
+  computeBackward_(b);
+  
+  for (size_t i = 0; i < nbSites_; i++)
+  {
+    size_t ii = i * nbStates_;
+    for (size_t j = 0; j < nbStates_; j++)
+    {
+      probs[offset + i][j] = likelihood_[ii + j] * b[i][j];
+    }
+  }
+}
+
+/***************************************************************************************************************************/
+
diff --git a/src/Bpp/Numeric/Hmm/RescaledHmmLikelihood.h b/src/Bpp/Numeric/Hmm/RescaledHmmLikelihood.h
new file mode 100644
index 0000000..c775c5b
--- /dev/null
+++ b/src/Bpp/Numeric/Hmm/RescaledHmmLikelihood.h
@@ -0,0 +1,184 @@
+//
+// File: RescaledHmmLikelihood.h
+// Created by: Julien Dutheil
+// Created on: Fri Oct 26 11:57 2007
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 16, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for phylogenetic data analysis.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _RESCALEDHMMLIKELIHOOD_H_
+#define _RESCALEDHMMLIKELIHOOD_H_
+
+#include "HmmLikelihood.h"
+#include "../AbstractParametrizable.h"
+#include "../Matrix/Matrix.h"
+
+//From the STL:
+#include <vector>
+#include <memory>
+
+namespace bpp {
+
+  /**
+   * @brief A simple implementation of hidden Markov models recursion.
+   *
+   * This implementation uses the rescaling method described in Durbin et al "Biological sequence analysis", Cambridge University Press.
+   * It also offer the possibility to specify "breakpoints", where the chain will be reset to the equilibrium frequencies.
+   */
+  class RescaledHmmLikelihood:
+    public virtual HmmLikelihood,
+    public AbstractParametrizable
+  {
+    private:
+      /**
+       * @brief The alphabet describing the hidden states.
+       */
+      std::auto_ptr<HmmStateAlphabet> hiddenAlphabet_;
+      std::auto_ptr<HmmTransitionMatrix> transitionMatrix_;
+      std::auto_ptr<HmmEmissionProbabilities> emissionProbabilities_;
+
+      /**
+       * @brief The likelihood array.
+       *
+       * likelihood_[i * nbStates_ + j] corresponds to Pr(x1...xi, yi=j),
+       * where the x are the observed states, and y the hidden states.
+       */
+      std::vector<double> likelihood_;
+      std::vector<double> scales_;
+      double logLik_;
+
+      std::vector<size_t> breakPoints_;
+
+      size_t nbStates_, nbSites_;
+
+    public:
+      /**
+       * @brief Build a new RescaledHmmLikelihood object.
+       *
+       * @warning the HmmTransitionMatrix and HmmEmissionProbabilities object passed as argument must be non-null
+       * and point toward the same HmmStateAlphabet instance. The three object will be copied if needed, and
+       * deleted when the hmm likelihood objet is deleted. You should secure a copy before if you don't want them to
+       * be destroyed with this object.
+       */
+      RescaledHmmLikelihood(
+          HmmStateAlphabet* hiddenAlphabet,
+          HmmTransitionMatrix* transitionMatrix,
+          HmmEmissionProbabilities* emissionProbabilities,
+          const std::string& prefix) throw (Exception);
+
+      RescaledHmmLikelihood(const RescaledHmmLikelihood& lik):
+        AbstractParametrizable(lik),
+        hiddenAlphabet_(dynamic_cast<HmmStateAlphabet*>(lik.hiddenAlphabet_->clone())),
+        transitionMatrix_(dynamic_cast<HmmTransitionMatrix*>(lik.transitionMatrix_->clone())),
+        emissionProbabilities_(dynamic_cast<HmmEmissionProbabilities*>(lik.emissionProbabilities_->clone())),
+        likelihood_(lik.likelihood_),
+        scales_(lik.scales_),
+        logLik_(lik.logLik_),
+        breakPoints_(lik.breakPoints_),
+        nbStates_(lik.nbStates_),
+        nbSites_(lik.nbSites_)
+    {
+      // Now adjust pointers:
+      transitionMatrix_->setHmmStateAlphabet(hiddenAlphabet_.get());
+      emissionProbabilities_->setHmmStateAlphabet(hiddenAlphabet_.get());
+    }
+
+      RescaledHmmLikelihood& operator=(const RescaledHmmLikelihood& lik)
+      {
+        AbstractParametrizable::operator =(lik);
+        hiddenAlphabet_        = std::auto_ptr<HmmStateAlphabet>(dynamic_cast<HmmStateAlphabet*>(lik.hiddenAlphabet_->clone()));
+        transitionMatrix_      = std::auto_ptr<HmmTransitionMatrix>(dynamic_cast<HmmTransitionMatrix*>(lik.transitionMatrix_->clone()));
+        emissionProbabilities_ = std::auto_ptr<HmmEmissionProbabilities>(dynamic_cast<HmmEmissionProbabilities*>(lik.emissionProbabilities_->clone()));
+        likelihood_            = lik.likelihood_;
+        scales_                = lik.scales_;
+        logLik_                = lik.logLik_;
+        breakPoints_           = lik.breakPoints_;
+        nbStates_              = lik.nbStates_;
+        nbSites_               = lik.nbSites_;
+
+        // Now adjust pointers:
+        transitionMatrix_->setHmmStateAlphabet(hiddenAlphabet_.get());
+        emissionProbabilities_->setHmmStateAlphabet(hiddenAlphabet_.get());
+        return *this;
+      }
+
+      virtual ~RescaledHmmLikelihood() {}
+
+#ifndef NO_VIRTUAL_COV
+      RescaledHmmLikelihood*
+#else
+        Clonable*
+#endif
+        clone() const { return new RescaledHmmLikelihood(*this); }
+
+    public:
+      const HmmStateAlphabet& getHmmStateAlphabet() const { return *hiddenAlphabet_; }
+      HmmStateAlphabet& getHmmStateAlphabet() { return *hiddenAlphabet_; }
+
+      const HmmTransitionMatrix& getHmmTransitionMatrix() const { return *transitionMatrix_; }
+      HmmTransitionMatrix& getHmmTransitionMatrix() { return *transitionMatrix_; }
+
+      const HmmEmissionProbabilities& getHmmEmissionProbabilities() const { return *emissionProbabilities_; }
+      HmmEmissionProbabilities& getHmmEmissionProbabilities() { return *emissionProbabilities_; }
+
+      void setBreakPoints(const std::vector<size_t>& breakPoints) {
+        breakPoints_ = breakPoints;
+        computeForward_();
+      }
+
+      const std::vector<size_t>& getBreakPoints() const { return breakPoints_; }
+
+      void setParameters(const ParameterList& pl) throw (Exception)
+      {
+        setParametersValues(pl);
+      }
+
+      double getValue() const throw (Exception) { return -logLik_; }
+
+      double getLogLikelihood() const { return logLik_; }
+
+      void fireParameterChanged(const ParameterList& pl);
+
+      void getHiddenStatesPosteriorProbabilities(std::vector< std::vector<double> >& probs, bool append = false) const throw (Exception);
+
+    protected:
+      void computeForward_();
+      void computeBackward_(std::vector< std::vector<double> >& b) const;
+
+  };
+
+}
+
+#endif //_RESCALEDHMMLIKELIHOOD_H_
+
diff --git a/src/Bpp/Numeric/Matrix/EigenValue.h b/src/Bpp/Numeric/Matrix/EigenValue.h
new file mode 100644
index 0000000..17050c1
--- /dev/null
+++ b/src/Bpp/Numeric/Matrix/EigenValue.h
@@ -0,0 +1,1244 @@
+//
+// File: EigenValue.h
+// Created by: Julien Dutheil
+// Created on: Tue Apr 7 16:24 2004
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+
+
+#ifndef _EIGENVALUE_H_
+#define _EIGENVALUE_H_
+
+#include <algorithm>
+// for min(), max() below
+
+#include <cmath>
+// for abs() below
+#include <climits>
+
+#include "Matrix.h"
+#include "../NumTools.h"
+
+namespace bpp
+{
+
+/** 
+ * @brief Computes eigenvalues and eigenvectors of a real (non-complex) matrix. 
+ * 
+ * [This class and its documentation is adpated from the C++ port of the JAMA library.]
+ * 
+ * If A is symmetric, then A = V*D*V' where the eigenvalue matrix D is
+ * diagonal and the eigenvector matrix V is orthogonal. That is,
+ * the diagonal values of D are the eigenvalues, and
+ * V*V' = I, where I is the identity matrix.  The columns of V 
+ * represent the eigenvectors in the sense that A*V = V*D.
+ *
+ * If A is not symmetric, then the eigenvalue matrix D is block diagonal
+ * with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues,
+ * a + i*b, in 2-by-2 blocks, [a, b; -b, a].  That is, if the complex
+ * eigenvalues look like
+ * <pre>
+ * 
+ *         u + iv     .        .          .      .    .
+ *           .      u - iv     .          .      .    .
+ *           .        .      a + ib       .      .    .
+ *           .        .        .        a - ib   .    .
+ *           .        .        .          .      x    .
+ *           .        .        .          .      .    y
+ * </pre>
+ * then D looks like
+ * <pre>
+ * 
+ *           u        v        .          .      .    .
+ *          -v        u        .          .      .    . 
+ *           .        .        a          b      .    .
+ *           .        .       -b          a      .    .
+ *           .        .        .          .      x    .
+ *           .        .        .          .      .    y
+ * </pre>
+ * This keeps V a real matrix in both symmetric and non-symmetric
+ *  cases, and A*V = V*D.
+ *
+ *
+ * The matrix V may be badly
+ * conditioned, or even singular, so the validity of the equation
+ * A = V*D*inverse(V) depends upon the condition number of V.
+ *
+ * (Adapted from JAMA, a Java Matrix Library, developed by jointly 
+ *  by the Mathworks and NIST; see  http://math.nist.gov/javanumerics/jama).
+ */
+template <class Real>
+class EigenValue
+{
+
+  private:
+   /** 
+    * @brief Row and column dimension (square matrix).
+    */
+   size_t n_;
+
+   /**
+    * @brief Tell if the matrix is symmetric.
+    */
+   bool issymmetric_;
+
+   /**
+    * @name Arrays for internal storage of eigenvalues.
+    *
+    * @{
+    */
+   std::vector<Real> d_;         /* real part */
+   std::vector<Real> e_;         /* img part */
+   /** @} */
+   
+   /**
+    * @brief Array for internal storage of eigenvectors.
+    */
+   RowMatrix<Real> V_;
+
+   /**
+    * @brief Matrix for internal storage of nonsymmetric Hessenberg form.
+    *
+    * Internal storage of nonsymmetric Hessenberg form.
+    */
+   RowMatrix<Real> H_;
+   
+
+   /**
+    * @brief Matrix for internal storage of eigen values in a matrix form.
+    *
+    * Internal storage of eigen values in a matrix form.
+    */
+   mutable RowMatrix<Real> D_;
+
+   /**
+    * @brief Working storage for nonsymmetric algorithm.
+    *
+    * Working storage for nonsymmetric algorithm.
+    */
+   std::vector<Real> ort_;
+
+   /**
+    * @brief Symmetric Householder reduction to tridiagonal form.
+    *
+    * This is derived from the Algol procedures tred2 by
+    * Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+    * Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+    * Fortran subroutine in EISPACK.
+    */
+   void tred2()
+   {
+     for (size_t j = 0; j < n_; j++)
+     {
+       d_[j] = V_(n_-1,j);
+     }
+
+     // Householder reduction to tridiagonal form.
+   
+     for (int i = static_cast<int>(n_)-1; i > 0; i--)
+     {
+       // Scale to avoid under/overflow.
+   
+       Real scale = 0.0;
+       Real h = 0.0;
+       for (int k = 0; k < i; k++)
+       {
+         scale = scale + NumTools::abs<Real>(d_[k]);
+       }
+       if (scale == 0.0)
+       {
+         e_[i] = d_[i-1];
+         for (int j = 0; j < i; j++)
+         {
+           d_[j] = V_(i-1,j);
+           V_(i,j) = 0.0;
+           V_(j,i) = 0.0;
+         }
+       }
+       else
+       {
+         // Generate Householder vector.
+   
+         for (int k = 0; k < i; k++)
+         {
+           d_[k] /= scale;
+           h += d_[k] * d_[k];
+         }
+         Real f = d_[i-1];
+         Real g = sqrt(h);
+         if (f > 0)
+         {
+           g = -g;
+         }
+         e_[i] = scale * g;
+         h = h - f * g;
+         d_[i-1] = f - g;
+         for (int j = 0; j < i; j++)
+         {
+           e_[j] = 0.0;
+         }
+   
+         // Apply similarity transformation to remaining columns.
+   
+         for (int j = 0; j < i; j++)
+         {
+           f = d_[j];
+           V_(j,i) = f;
+           g = e_[j] + V_(j,j) * f;
+           for (int k = j+1; k <= i-1; k++)
+           {
+             g += V_(k,j) * d_[k];
+             e_[k] += V_(k,j) * f;
+           }
+           e_[j] = g;
+         }
+         f = 0.0;
+         for (int j = 0; j < i; j++)
+         {
+           e_[j] /= h;
+           f += e_[j] * d_[j];
+         }
+         Real hh = f / (h + h);
+         for (int j = 0; j < i; j++)
+         {
+           e_[j] -= hh * d_[j];
+         }
+         for (int j = 0; j < i; j++)
+         {
+           f = d_[j];
+           g = e_[j];
+           for (int k = j; k <= i-1; k++)
+           {
+             V_(k,j) -= (f * e_[k] + g * d_[k]);
+           }
+           d_[j] = V_(i-1,j);
+           V_(i,j) = 0.0;
+         }
+       }
+       d_[i] = h;
+     }
+   
+     // Accumulate transformations.
+   
+     for (size_t i = 0; i < n_-1; i++)
+     {
+       V_(n_-1,i) = V_(i,i);
+       V_(i,i) = 1.0;
+       Real h = d_[i+1];
+       if (h != 0.0)
+       {
+         for (size_t k = 0; k <= i; k++)
+         {
+           d_[k] = V_(k,i+1) / h;
+         }
+         for (size_t j = 0; j <= i; j++)
+         {
+           Real g = 0.0;
+           for (size_t k = 0; k <= i; k++)
+           {
+             g += V_(k,i+1) * V_(k,j);
+           }
+           for (size_t k = 0; k <= i; k++)
+           {
+             V_(k,j) -= g * d_[k];
+           }
+         }
+       }
+       for (size_t k = 0; k <= i; k++)
+       {
+         V_(k,i+1) = 0.0;
+       }
+     }
+     for (size_t j = 0; j < n_; j++)
+     {
+       d_[j] = V_(n_-1,j);
+       V_(n_-1,j) = 0.0;
+     }
+     V_(n_-1,n_-1) = 1.0;
+     e_[0] = 0.0;
+   } 
+
+   /**
+    * @brief Symmetric tridiagonal QL algorithm.
+    *
+    * This is derived from the Algol procedures tql2, by
+    * Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+    * Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+    * Fortran subroutine in EISPACK.
+    */
+   void tql2 ()
+   {
+     for (size_t i = 1; i < n_; i++)
+     {
+       e_[i-1] = e_[i];
+     }
+     e_[n_-1] = 0.0;
+   
+     Real f = 0.0;
+     Real tst1 = 0.0;
+     Real eps = pow(2.0,-52.0);
+     for (int l = 0; l < static_cast<int>(n_); l++)
+     {
+       // Find small subdiagonal element
+   
+       tst1 = std::max(tst1, NumTools::abs<Real>(d_[l]) + NumTools::abs<Real>(e_[l]));
+       int m = l;
+
+       // Original while-loop from Java code
+       while (m < static_cast<int>(n_))
+       {
+         if (NumTools::abs<Real>(e_[m]) <= eps*tst1)
+         {
+           break;
+         }
+         m++;
+       }
+
+       // If m == l, d_[l] is an eigenvalue,
+       // otherwise, iterate.
+   
+       if (m > l)
+       {
+         int iter = 0;
+         do
+         {
+           iter = iter + 1;  // (Could check iteration count here.)
+   
+           // Compute implicit shift
+   
+           Real g = d_[l];
+           Real p = (d_[l+1] - g) / (2.0 * e_[l]);
+           Real r = hypot(p,1.0);
+           if (p < 0)
+           {
+             r = -r;
+           }
+           d_[l] = e_[l] / (p + r);
+           d_[l+1] = e_[l] * (p + r);
+           Real dl1 = d_[l+1];
+           Real h = g - d_[l];
+           for (size_t i = l+2; i < n_; i++)
+           {
+             d_[i] -= h;
+           }
+           f = f + h;
+   
+           // Implicit QL transformation.
+   
+           p = d_[m];
+           Real c = 1.0;
+           Real c2 = c;
+           Real c3 = c;
+           Real el1 = e_[l+1];
+           Real s = 0.0;
+           Real s2 = 0.0;
+           for (int i = m-1; i >= l; i--)
+           {
+             c3 = c2;
+             c2 = c;
+             s2 = s;
+             g = c * e_[i];
+             h = c * p;
+             r = hypot(p,e_[i]);
+             e_[i+1] = s * r;
+             s = e_[i] / r;
+             c = p / r;
+             p = c * d_[i] - s * g;
+             d_[i+1] = h + s * (c * g + s * d_[i]);
+   
+             // Accumulate transformation.
+   
+             for (size_t k = 0; k < n_; k++)
+             {
+               h = V_(k,i+1);
+               V_(k,i+1) = s * V_(k,i) + c * h;
+               V_(k,i) = c * V_(k,i) - s * h;
+             }
+           }
+           p = -s * s2 * c3 * el1 * e_[l] / dl1;
+           e_[l] = s * p;
+           d_[l] = c * p;
+   
+           // Check for convergence.
+   
+         } while (NumTools::abs<Real>(e_[l]) > eps*tst1);
+       }
+       d_[l] = d_[l] + f;
+       e_[l] = 0.0;
+     }
+     
+     // Sort eigenvalues and corresponding vectors.
+   
+     for (size_t i = 0; n_ > 0 && i < n_-1; i++)
+     {
+       size_t k = i;
+       Real p = d_[i];
+       for (size_t j = i+1; j < n_; j++)
+       {
+         if (d_[j] < p)
+         {
+           k = j;
+           p = d_[j];
+         }
+       }
+       if (k != i)
+       {
+         d_[k] = d_[i];
+         d_[i] = p;
+         for (size_t j = 0; j < n_; j++)
+         {
+           p = V_(j,i);
+           V_(j,i) = V_(j,k);
+           V_(j,k) = p;
+         }
+       }
+     }
+   }
+
+   /**
+    * @brief Nonsymmetric reduction to Hessenberg form.
+    *
+    * This is derived from the Algol procedures orthes and ortran,
+    * by Martin and Wilkinson, Handbook for Auto. Comp.,
+    * Vol.ii-Linear Algebra, and the corresponding
+    * Fortran subroutines in EISPACK.
+    */
+   void orthes ()
+   {
+     int low = 0;
+     int high = static_cast<int>(n_)-1;
+   
+     for (int m = low+1; m <= high-1; m++)
+     {
+       // Scale column.
+   
+       Real scale = 0.0;
+       for (int i = m; i <= high; i++)
+       {
+         scale = scale + NumTools::abs<Real>(H_(i,m-1));
+       }
+       if (scale != 0.0)
+       {
+         // Compute Householder transformation.
+   
+         Real h = 0.0;
+         for (int i = high; i >= m; i--)
+         {
+           ort_[i] = H_(i,m-1)/scale;
+           h += ort_[i] * ort_[i];
+         }
+         Real g = sqrt(h);
+         if (ort_[m] > 0)
+         {
+           g = -g;
+         }
+         h = h - ort_[m] * g;
+         ort_[m] = ort_[m] - g;
+   
+         // Apply Householder similarity transformation
+         // H = (I-u*u'/h)*H*(I-u*u')/h)
+   
+         for (int j = m; j < static_cast<int>(n_); j++)
+         {
+           Real f = 0.0;
+           for (int i = high; i >= m; i--)
+           {
+             f += ort_[i]*H_(i,j);
+           }
+           f = f/h;
+           for (int i = m; i <= high; i++)
+           {
+             H_(i,j) -= f*ort_[i];
+           }
+         }
+   
+         for (int i = 0; i <= high; i++)
+         {
+           Real f = 0.0;
+           for (int j = high; j >= m; j--)
+           {
+             f += ort_[j]*H_(i,j);
+           }
+           f = f/h;
+           for (int j = m; j <= high; j++)
+           {
+             H_(i,j) -= f*ort_[j];
+           }
+         }
+         ort_[m] = scale*ort_[m];
+         H_(m,m-1) = scale*g;
+       }
+     }
+   
+     // Accumulate transformations (Algol's ortran).
+
+     for (size_t i = 0; i < n_; i++)
+     {
+       for (size_t j = 0; j < n_; j++)
+       {
+         V_(i,j) = (i == j ? 1.0 : 0.0);
+       }
+     }
+
+     for (int m = high-1; m >= low+1; m--)
+     {
+       if (H_(m,m-1) != 0.0)
+       {
+         for (int i = m+1; i <= high; i++)
+         {
+           ort_[i] = H_(i,m-1);
+         }
+         for (int j = m; j <= high; j++)
+         {
+           Real g = 0.0;
+           for (int i = m; i <= high; i++)
+           {
+             g += ort_[i] * V_(i,j);
+           }
+           // Double division avoids possible underflow
+           g = (g / ort_[m]) / H_(m,m-1);
+           for (int i = m; i <= high; i++)
+           {
+             V_(i,j) += g * ort_[i];
+           }
+         }
+       }
+     }
+   }
+
+
+   // Complex scalar division.
+
+   Real cdivr, cdivi;
+   void cdiv(Real xr, Real xi, Real yr, Real yi)
+   {
+     Real r,d;
+     if (NumTools::abs<Real>(yr) > NumTools::abs<Real>(yi))
+     {
+       r = yi/yr;
+       d = yr + r*yi;
+       cdivr = (xr + r*xi)/d;
+       cdivi = (xi - r*xr)/d;
+     }
+     else
+     {
+       r = yr/yi;
+       d = yi + r*yr;
+       cdivr = (r*xr + xi)/d;
+       cdivi = (r*xi - xr)/d;
+     }
+   }
+
+
+   // Nonsymmetric reduction from Hessenberg to real Schur form.
+
+  void hqr2 ()
+  {
+    //  This is derived from the Algol procedure hqr2,
+    //  by Martin and Wilkinson, Handbook for Auto. Comp.,
+    //  Vol.ii-Linear Algebra, and the corresponding
+    //  Fortran subroutine in EISPACK.
+  
+    // Initialize
+   
+    int nn = static_cast<int>(this->n_);
+    int n = nn-1;
+    int low = 0;
+    int high = nn-1;
+    Real eps = pow(2.0,-52.0);
+    Real exshift = 0.0;
+    Real p=0,q=0,r=0,s=0,z=0,t,w,x,y;
+   
+    // Store roots isolated by balanc and compute matrix norm
+   
+    Real norm = 0.0;
+    for (int i = 0; i < nn; i++)
+    {
+      if ((i < low) || (i > high))
+      {
+        d_[i] = H_(i,i);
+        e_[i] = 0.0;
+      }
+      for (int j = std::max(i-1,0); j < nn; j++)
+      {
+        norm = norm + NumTools::abs<Real>(H_(i,j));
+      }
+    }
+   
+    // Outer loop over eigenvalue index
+  
+    int iter = 0;
+    while (n >= low)
+    {
+      // Look for single small sub-diagonal element
+  
+      int l = n;
+      while (l > low)
+      {
+        s = NumTools::abs<Real>(H_(l-1,l-1)) + NumTools::abs<Real>(H_(l,l));
+        if (s == 0.0)
+        {
+          s = norm;
+        }
+        if (NumTools::abs<Real>(H_(l,l-1)) < eps * s)
+        {
+          break;
+        }
+        l--;
+      }
+      
+      // Check for convergence
+      // One root found
+  
+      if (l == n)
+      {
+        H_(n,n) = H_(n,n) + exshift;
+        d_[n] = H_(n,n);
+        e_[n] = 0.0;
+        n--;
+        iter = 0;
+  
+        // Two roots found
+  
+      }
+      else if (l == n-1)
+      {
+        w = H_(n,n-1) * H_(n-1,n);
+        p = (H_(n-1,n-1) - H_(n,n)) / 2.0;
+        q = p * p + w;
+        z = sqrt(NumTools::abs<Real>(q));
+        H_(n,n) = H_(n,n) + exshift;
+        H_(n-1,n-1) = H_(n-1,n-1) + exshift;
+        x = H_(n,n);
+  
+        // Real pair
+  
+        if (q >= 0)
+        {
+          if (p >= 0)
+          {
+            z = p + z;
+          }
+          else
+          {
+            z = p - z;
+          }
+          d_[n-1] = x + z;
+          d_[n] = d_[n-1];
+          if (z != 0.0)
+          {
+            d_[n] = x - w / z;
+          }
+          e_[n-1] = 0.0;
+          e_[n] = 0.0;
+          x = H_(n,n-1);
+          s = NumTools::abs<Real>(x) + NumTools::abs<Real>(z);
+          p = x / s;
+          q = z / s;
+          r = sqrt(p * p+q * q);
+          p = p / r;
+          q = q / r;
+  
+          // Row modification
+  
+          for (int j = n-1; j < nn; j++)
+          {
+            z = H_(n-1,j);
+            H_(n-1,j) = q * z + p * H_(n,j);
+            H_(n,j) = q * H_(n,j) - p * z;
+          }
+  
+          // Column modification
+  
+          for (int i = 0; i <= n; i++)
+          {
+            z = H_(i,n-1);
+            H_(i,n-1) = q * z + p * H_(i,n);
+            H_(i,n) = q * H_(i,n) - p * z;
+          }
+  
+          // Accumulate transformations
+  
+          for (int i = low; i <= high; i++)
+          {
+            z = V_(i,n-1);
+            V_(i,n-1) = q * z + p * V_(i,n);
+            V_(i,n) = q * V_(i,n) - p * z;
+          }
+   
+          // Complex pair
+  
+        }
+        else
+        {
+          d_[n-1] = x + p;
+          d_[n] = x + p;
+          e_[n-1] = z;
+          e_[n] = -z;
+        }
+        n = n - 2;
+        iter = 0;
+  
+        // No convergence yet
+  
+      }
+      else
+      {
+        // Form shift
+  
+        x = H_(n,n);
+        y = 0.0;
+        w = 0.0;
+        if (l < n)
+        {
+          y = H_(n-1,n-1);
+          w = H_(n,n-1) * H_(n-1,n);
+        }
+  
+        // Wilkinson's original ad hoc shift
+  
+        if (iter == 10)
+        {
+          exshift += x;
+          for (int i = low; i <= n; i++)
+          {
+            H_(i,i) -= x;
+          }
+          s = NumTools::abs<Real>(H_(n,n-1)) + NumTools::abs<Real>(H_(n-1,n-2));
+          x = y = 0.75 * s;
+          w = -0.4375 * s * s;
+        }
+
+        // MATLAB's new ad hoc shift
+        if (iter == 30)
+        {
+          s = (y - x) / 2.0;
+          s = s * s + w;
+          if (s > 0)
+          {
+            s = sqrt(s);
+            if (y < x)
+            {
+              s = -s;
+            }
+            s = x - w / ((y - x) / 2.0 + s);
+            for (int i = low; i <= n; i++)
+            {
+              H_(i,i) -= s;
+            }
+            exshift += s;
+            x = y = w = 0.964;
+          }
+        }
+  
+        iter = iter + 1;   // (Could check iteration count here.)
+  
+        // Look for two consecutive small sub-diagonal elements
+  
+        int m = n-2;
+        while (m >= l)
+        {
+          z = H_(m,m);
+          r = x - z;
+          s = y - z;
+          p = (r * s - w) / H_(m+1,m) + H_(m,m+1);
+          q = H_(m+1,m+1) - z - r - s;
+          r = H_(m+2,m+1);
+          s = NumTools::abs<Real>(p) + NumTools::abs<Real>(q) + NumTools::abs<Real>(r);
+          p = p / s;
+          q = q / s;
+          r = r / s;
+          if (m == l)
+          {
+            break;
+          }
+          if (NumTools::abs<Real>(H_(m,m-1)) * (NumTools::abs<Real>(q) + NumTools::abs<Real>(r)) <
+               eps * (NumTools::abs<Real>(p) * (NumTools::abs<Real>(H_(m-1,m-1)) + NumTools::abs<Real>(z) +
+               NumTools::abs<Real>(H_(m+1,m+1)))))
+          {
+            break;
+          }
+          m--;
+        }
+  
+        for (int i = m+2; i <= n; i++)
+        {
+          H_(i,i-2) = 0.0;
+          if (i > m+2)
+          {
+            H_(i,i-3) = 0.0;
+          }
+        }
+ 
+        // Double QR step involving rows l:n and columns m:n
+   
+        for (int k = m; k <= n-1; k++)
+        {
+          int notlast = (k != n-1);
+          if (k != m)
+          {
+            p = H_(k,k-1);
+            q = H_(k+1,k-1);
+            r = (notlast ? H_(k+2,k-1) : 0.0);
+            x = NumTools::abs<Real>(p) + NumTools::abs<Real>(q) + NumTools::abs<Real>(r);
+            if (x != 0.0)
+            {
+              p = p / x;
+              q = q / x;
+              r = r / x;
+            }
+          }
+          if (x == 0.0)
+          {
+            break;
+          }
+          s = sqrt(p * p + q * q + r * r);
+          if (p < 0)
+          {
+            s = -s;
+          }
+          if (s != 0)
+          {
+            if (k != m)
+            {
+              H_(k,k-1) = -s * x;
+            }
+            else if (l != m)
+            {
+              H_(k,k-1) = -H_(k,k-1);
+            }
+            p = p + s;
+            x = p / s;
+            y = q / s;
+            z = r / s;
+            q = q / p;
+            r = r / p;
+   
+            // Row modification
+   
+            for (int j = k; j < nn; j++)
+            {
+              p = H_(k,j) + q * H_(k+1,j);
+              if (notlast)
+              {
+                p = p + r * H_(k+2,j);
+                H_(k+2,j) = H_(k+2,j) - p * z;
+              }
+              H_(k,j) = H_(k,j) - p * x;
+              H_(k+1,j) = H_(k+1,j) - p * y;
+            }
+   
+            // Column modification
+   
+            for (int i = 0; i <= std::min(n,k+3); i++)
+            {
+              p = x * H_(i,k) + y * H_(i,k+1);
+              if (notlast)
+              {
+                p = p + z * H_(i,k+2);
+                H_(i,k+2) = H_(i,k+2) - p * r;
+              }
+              H_(i,k) = H_(i,k) - p;
+              H_(i,k+1) = H_(i,k+1) - p * q;
+            }
+   
+            // Accumulate transformations
+   
+            for (int i = low; i <= high; i++)
+            {
+              p = x * V_(i,k) + y * V_(i,k+1);
+              if (notlast)
+              {
+                p = p + z * V_(i,k+2);
+                V_(i,k+2) = V_(i,k+2) - p * r;
+              }
+              V_(i,k) = V_(i,k) - p;
+              V_(i,k+1) = V_(i,k+1) - p * q;
+            }
+          }  // (s != 0)
+        }  // k loop
+      }  // check convergence
+    }  // while (n >= low)
+      
+    // Backsubstitute to find vectors of upper triangular form
+
+    if (norm == 0.0)
+    {
+       return;
+    }
+   
+    for (n = nn-1; n >= 0; n--)
+    {
+      p = d_[n];
+      q = e_[n];
+   
+      // Real vector
+   
+      if (q == 0)
+      {
+        int l = n;
+        H_(n,n) = 1.0;
+        for (int i = n-1; i >= 0; i--)
+        {
+          w = H_(i,i) - p;
+          r = 0.0;
+          for (int j = l; j <= n; j++)
+          {
+            r = r + H_(i,j) * H_(j,n);
+          }
+          if (e_[i] < 0.0)
+          {
+            z = w;
+            s = r;
+          }
+          else
+          {
+            l = i;
+            if (e_[i] == 0.0)
+            {
+              if (w != 0.0)
+              {
+                H_(i,n) = -r / w;
+              }
+              else
+              {
+                H_(i,n) = -r / (eps * norm);
+              }
+   
+              // Solve real equations
+   
+            }
+            else
+            {
+              x = H_(i,i+1);
+              y = H_(i+1,i);
+              q = (d_[i] - p) * (d_[i] - p) + e_[i] * e_[i];
+              t = (x * s - z * r) / q;
+              H_(i,n) = t;
+              if (NumTools::abs<Real>(x) > NumTools::abs<Real>(z))
+              {
+                H_(i+1,n) = (-r - w * t) / x;
+              }
+              else
+              {
+                H_(i+1,n) = (-s - y * t) / z;
+              }
+            }
+   
+            // Overflow control
+   
+            t = NumTools::abs<Real>(H_(i,n));
+            if ((eps * t) * t > 1)
+            {
+              for (int j = i; j <= n; j++)
+              {
+                H_(j,n) = H_(j,n) / t;
+              }
+            }
+          }
+        }
+   
+        // Complex vector
+   
+      }
+      else if (q < 0)
+      {
+        int l = n-1;
+
+        // Last vector component imaginary so matrix is triangular
+   
+        if (NumTools::abs<Real>(H_(n,n-1)) > NumTools::abs<Real>(H_(n-1,n)))
+        {
+          H_(n-1,n-1) = q / H_(n,n-1);
+          H_(n-1,n) = -(H_(n,n) - p) / H_(n,n-1);
+        }
+        else
+        {
+          cdiv(0.0,-H_(n-1,n),H_(n-1,n-1)-p,q);
+          H_(n-1,n-1) = cdivr;
+          H_(n-1,n) = cdivi;
+        }
+        H_(n,n-1) = 0.0;
+        H_(n,n) = 1.0;
+        for (int i = n-2; i >= 0; i--)
+        {
+          Real ra,sa,vr,vi;
+          ra = 0.0;
+          sa = 0.0;
+          for (int j = l; j <= n; j++)
+          {
+            ra = ra + H_(i,j) * H_(j,n-1);
+            sa = sa + H_(i,j) * H_(j,n);
+          }
+          w = H_(i,i) - p;
+   
+          if (e_[i] < 0.0)
+          {
+            z = w;
+            r = ra;
+            s = sa;
+          }
+          else
+          {
+            l = i;
+            if (e_[i] == 0)
+            {
+              cdiv(-ra,-sa,w,q);
+              H_(i,n-1) = cdivr;
+              H_(i,n) = cdivi;
+            }
+            else
+            {
+              // Solve complex equations
+ 
+              x = H_(i,i+1);
+              y = H_(i+1,i);
+              vr = (d_[i] - p) * (d_[i] - p) + e_[i] * e_[i] - q * q;
+              vi = (d_[i] - p) * 2.0 * q;
+              if ((vr == 0.0) && (vi == 0.0))
+              {
+                vr = eps * norm * (NumTools::abs<Real>(w) + NumTools::abs<Real>(q) +
+                NumTools::abs<Real>(x) + NumTools::abs<Real>(y) + NumTools::abs<Real>(z));
+              }
+              cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
+              H_(i,n-1) = cdivr;
+              H_(i,n) = cdivi;
+              if (NumTools::abs<Real>(x) > (NumTools::abs<Real>(z) + NumTools::abs<Real>(q)))
+              {
+                H_(i+1,n-1) = (-ra - w * H_(i,n-1) + q * H_(i,n)) / x;
+                H_(i+1,n) = (-sa - w * H_(i,n) - q * H_(i,n-1)) / x;
+              }
+              else
+              {
+                cdiv(-r-y*H_(i,n-1),-s-y*H_(i,n),z,q);
+                H_(i+1,n-1) = cdivr;
+                H_(i+1,n) = cdivi;
+              }
+            }
+ 
+            // Overflow control
+            t = std::max(NumTools::abs<Real>(H_(i,n-1)),NumTools::abs<Real>(H_(i,n)));
+            if ((eps * t) * t > 1)
+            {
+              for (int j = i; j <= n; j++)
+              {
+                H_(j,n-1) = H_(j,n-1) / t;
+                H_(j,n) = H_(j,n) / t;
+              }
+            }
+          }
+        }
+      }
+    }
+   
+    // Vectors of isolated roots
+   
+    for (int i = 0; i < nn; i++)
+    {
+      if (i < low || i > high)
+      {
+        for (int j = i; j < nn; j++)
+        {
+          V_(i,j) = H_(i,j);
+        }
+      }
+    }
+   
+    // Back transformation to get eigenvectors of original matrix
+   
+    for (int j = nn-1; j >= low; j--)
+    {
+      for (int i = low; i <= high; i++)
+      {
+        z = 0.0;
+        for (int k = low; k <= std::min(j,high); k++)
+        {
+          z = z + V_(i,k) * H_(k,j);
+        }
+        V_(i,j) = z;
+      }
+    }
+  }
+
+  public:
+
+   bool isSymmetric() const { return issymmetric_; }
+
+
+    /**
+     * @brief Check for symmetry, then construct the eigenvalue decomposition
+     *
+     * @param A    Square real (non-complex) matrix
+     */
+    EigenValue(const Matrix<Real>& A) :
+      n_(A.getNumberOfColumns()),
+      issymmetric_(true),
+      d_(n_),
+      e_(n_),
+      V_(n_,n_),
+      H_(),
+      D_(n_, n_),
+      ort_(),
+      cdivr(), cdivi()
+    {
+      if (n_ > INT_MAX)
+        throw Exception("EigenValue: can only be computed for matrices <= " + TextTools::toString(INT_MAX));
+      for (size_t j = 0; (j < n_) && issymmetric_; j++)
+      {
+        for (size_t i = 0; (i < n_) && issymmetric_; i++)
+        {
+          issymmetric_ = (A(i,j) == A(j,i));
+        }
+      }
+
+      if (issymmetric_)
+      {
+        for (size_t i = 0; i < n_; i++)
+        {
+          for (size_t j = 0; j < n_; j++)
+          {
+            V_(i,j) = A(i,j);
+          }
+        }
+   
+        // Tridiagonalize.
+        tred2();
+   
+        // Diagonalize.
+        tql2();
+      }
+      else
+      {
+        H_.resize(n_,n_);
+        ort_.resize(n_);
+         
+        for (size_t j = 0; j < n_; j++)
+        {
+          for (size_t i = 0; i < n_; i++)
+          {
+            H_(i,j) = A(i,j);
+          }
+        }
+   
+        // Reduce to Hessenberg form.
+        orthes();
+   
+        // Reduce Hessenberg to real Schur form.
+        hqr2();
+      }
+    }
+
+
+    /**
+     * @brief Return the eigenvector matrix
+     *
+     * @return V
+     */
+    const RowMatrix<Real>& getV() const { return V_; }
+
+    /**
+     * @brief Return the real parts of the eigenvalues
+     *
+     * @return real(diag(D))
+     */
+    const std::vector<Real>& getRealEigenValues() const { return d_; }
+
+    /**
+     * @brief Return the imaginary parts of the eigenvalues in parameter e.
+     *
+     * @return e: new matrix with imaginary parts of the eigenvalues.
+     */
+    const std::vector<Real>& getImagEigenValues() const { return e_; }
+   
+    /**
+     * @brief Computes the block diagonal eigenvalue matrix.
+     * 
+     * If the original matrix A is not symmetric, then the eigenvalue 
+     * matrix D is block diagonal with the real eigenvalues in 1-by-1 
+     * blocks and any complex eigenvalues,
+     * a + i*b, in 2-by-2 blocks, [a, b; -b, a].  That is, if the complex
+     * eigenvalues look like
+     * <pre>
+     *
+     *       u + iv     .        .          .      .    .
+     *         .      u - iv     .          .      .    .
+     *         .        .      a + ib       .      .    .
+     *         .        .        .        a - ib   .    .
+     *         .        .        .          .      x    .
+     *         .        .        .          .      .    y
+     * </pre>
+     *     then D looks like
+     * <pre>
+     *
+     *         u        v        .          .      .    .
+     *        -v        u        .          .      .    . 
+     *         .        .        a          b      .    .
+     *         .        .       -b          a      .    .
+     *         .        .        .          .      x    .
+     *         .        .        .          .      .    y
+     * </pre>
+     * This keeps V a real matrix in both symmetric and non-symmetric
+     * cases, and A*V = V*D.
+     *
+     * @return D: upon return, the matrix is filled with the block diagonal 
+     * eigenvalue matrix.
+     */
+    const RowMatrix<Real>& getD() const
+    {
+      for (size_t i = 0; i < n_; i++)
+      {
+        for (size_t j = 0; j < n_; j++)
+        {
+          D_(i,j) = 0.0;
+        }
+        D_(i,i) = d_[i];
+        if (e_[i] > 0)
+        {
+          D_(i,i+1) = e_[i];
+        }
+        else if (e_[i] < 0)
+        {
+          D_(i,i-1) = e_[i];
+        }
+      }
+      return D_;
+    }
+};
+
+} //end of namespace bpp.
+
+#endif //_EIGENVALUE_H_
+
diff --git a/src/Bpp/Numeric/Matrix/LUDecomposition.h b/src/Bpp/Numeric/Matrix/LUDecomposition.h
new file mode 100644
index 0000000..dc3b8cc
--- /dev/null
+++ b/src/Bpp/Numeric/Matrix/LUDecomposition.h
@@ -0,0 +1,465 @@
+//
+// File: LU.h
+// Created by: Julien Dutheil
+// Created on: Tue Apr 7 16:24 2004
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#ifndef _LU_H_
+#define _LU_H_
+
+#include "Matrix.h"
+#include "../NumTools.h"
+#include "../../Exceptions.h"
+
+// From the STL:
+#include <algorithm>
+#include <vector>
+// for min(), max() below
+
+namespace bpp
+{
+/**
+ * @brief LU Decomposition.
+ *
+ * [This class and its documentation is adpated from the C++ port of the JAMA library.]
+ *
+ * For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
+ * unit lower triangular matrix L, an n-by-n upper triangular matrix U,
+ * and a permutation vector piv of length m so that A(piv,:) = L*U.
+ * If m < n, then L is m-by-m and U is m-by-n.
+ *
+ * The LU decompostion with pivoting always exists, even if the matrix is
+ * singular, so the constructor will never fail.  The primary use of the
+ * LU decomposition is in the solution of square systems of simultaneous
+ * linear equations. This will fail if isNonsingular() returns false.
+ */
+template<class Real>
+class LUDecomposition
+{
+private:
+  /* Array for internal storage of decomposition.  */
+  RowMatrix<Real> LU;
+  RowMatrix<Real> L_;
+  RowMatrix<Real> U_;
+  size_t m, n;
+  int pivsign;
+  std::vector<size_t> piv;
+
+private:
+  static void permuteCopy(const Matrix<Real>& A, const std::vector<size_t>& piv, size_t j0, size_t j1, Matrix<Real>& X)
+  {
+    size_t piv_length = piv.size();
+
+    X.resize(piv_length, j1 - j0 + 1);
+
+    for (size_t i = 0; i < piv_length; i++)
+    {
+      for (size_t j = j0; j <= j1; j++)
+      {
+        X(i, j - j0) = A(piv[i], j);
+      }
+    }
+  }
+
+  static void permuteCopy(const std::vector<Real>& A, const std::vector<size_t>& piv, std::vector<Real>& X)
+  {
+    size_t piv_length = piv.size();
+    if (piv_length != A.size())
+      X.clean();
+
+    X.resize(piv_length);
+
+    for (size_t i = 0; i < piv_length; i++)
+    {
+      X[i] = A[piv[i]];
+    }
+  }
+
+public:
+  /**
+   * @brief LU Decomposition
+   *
+   * @param  A   Rectangular matrix
+   * @return LU Decomposition object to access L, U and piv.
+   */
+
+  // This is the constructor in JAMA C++ port. However, it seems to have some bug...
+  // We use the original JAMA's 'experimental' port, which gives good results instead.
+  /*	  LUDecomposition (const Matrix<Real> &A) : LU(A), m(A.getNumberOfRows()), n(A.getNumberOfColumns()), piv(A.getNumberOfRows())
+        {
+
+        // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
+
+
+        for (size_t i = 0; i < m; i++) {
+        piv[i] = i;
+        }
+        pivsign = 1;
+        //Real *LUrowi = 0;;
+        vector<Real> LUrowi;
+        vector<Real> LUcolj;
+
+        // Outer loop.
+
+        for (size_t j = 0; j < n; j++) {
+
+        // Make a copy of the j-th column to localize references.
+
+        LUcolj = LU.col(j);
+        //for (size_t i = 0; i < m; i++) {
+      //  LUcolj[i] = LU(i,j);
+      //}
+
+      // Apply previous transformations.
+
+      for (size_t i = 0; i < m; i++) {
+        //LUrowi = LU[i];
+        LUrowi = LU.row(i);
+
+        // Most of the time is spent in the following dot product.
+
+        size_t kmax = NumTools::min<size_t>(i,j);
+        double s = 0.0;
+        for (size_t k = 0; k < kmax; k++) {
+        s += LUrowi[k] * LUcolj[k];
+        }
+
+        LUrowi[j] = LUcolj[i] -= s;
+        }
+
+        // Find pivot and exchange if necessary.
+
+        size_t p = j;
+        for (size_t i = j+1; i < m; i++) {
+        if (NumTools::abs<Real>(LUcolj[i]) > NumTools::abs<Real>(LUcolj[p])) {
+        p = i;
+        }
+        }
+        if (p != j) {
+        size_t k=0;
+        for (k = 0; k < n; k++) {
+        double t = LU(p,k);
+        LU(p,k) = LU(j,k);
+        LU(j,k) = t;
+        }
+        k = piv[p];
+        piv[p] = piv[j];
+        piv[j] = k;
+        pivsign = -pivsign;
+        }
+
+        // Compute multipliers.
+
+        if ((j < m) && (LU(j,j) != 0.0)) {
+        for (size_t i = j+1; i < m; i++) {
+        LU(i,j) /= LU(j,j);
+        }
+        }
+        }
+        }
+   */
+
+  LUDecomposition (const Matrix<Real>& A) :
+    LU(A),
+    L_(A.getNumberOfRows(), A.getNumberOfColumns()),
+    U_(A.getNumberOfColumns(), A.getNumberOfColumns()),
+    m(A.getNumberOfRows()),
+    n(A.getNumberOfColumns()),
+    pivsign(1),
+    piv(A.getNumberOfRows())
+  {
+    for (size_t i = 0; i < m; i++)
+    {
+      piv[i] = i;
+    }
+    // Main loop.
+    for (size_t k = 0; k < n; k++)
+    {
+      // Find pivot.
+      size_t p = k;
+      for (size_t i = k + 1; i < m; i++)
+      {
+        if (NumTools::abs<Real>(LU(i, k)) > NumTools::abs<Real>(LU(p, k)))
+        {
+          p = i;
+        }
+      }
+      // Exchange if necessary.
+      if (p != k)
+      {
+        for (size_t j = 0; j < n; j++)
+        {
+          double t = LU(p, j); LU(p, j) = LU(k, j); LU(k, j) = t;
+        }
+        size_t t = piv[p]; piv[p] = piv[k]; piv[k] = t;
+        pivsign = -pivsign;
+      }
+      // Compute multipliers and eliminate k-th column.
+      if (LU(k, k) != 0.0)
+      {
+        for (size_t i = k + 1; i < m; i++)
+        {
+          LU(i, k) /= LU(k, k);
+          for (size_t j = k + 1; j < n; j++)
+          {
+            LU(i, j) -= LU(i, k) * LU(k, j);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * @brief Return lower triangular factor
+   *
+   * @return L
+   */
+  const RowMatrix<Real>& getL()
+  {
+    for (size_t i = 0; i < m; i++)
+    {
+      for (size_t j = 0; j < n; j++)
+      {
+        if (i > j)
+        {
+          L_(i, j) = LU(i, j);
+        }
+        else if (i == j)
+        {
+          L_(i, j) = 1.0;
+        }
+        else
+        {
+          L_(i, j) = 0.0;
+        }
+      }
+    }
+    return L_;
+  }
+
+  /**
+   * @brief Return upper triangular factor
+   *
+   * @return U portion of LU factorization.
+   */
+  const RowMatrix<Real>& getU ()
+  {
+    for (size_t i = 0; i < n; i++)
+    {
+      for (size_t j = 0; j < n; j++)
+      {
+        if (i <= j)
+        {
+          U_(i, j) = LU(i, j);
+        }
+        else
+        {
+          U_(i, j) = 0.0;
+        }
+      }
+    }
+    return U_;
+  }
+
+  /**
+   * @brief Return pivot permutation vector
+   *
+   * @return piv
+   */
+  std::vector<size_t> getPivot () const
+  {
+    return piv;
+  }
+
+
+  /**
+   * @brief Compute determinant using LU factors.
+   *
+   * @return determinant of A, or 0 if A is not square.
+   */
+  Real det() const
+  {
+    if (m != n)
+    {
+      return Real(0);
+    }
+    Real d = Real(pivsign);
+    for (size_t j = 0; j < n; j++)
+    {
+      d *= LU(j, j);
+    }
+    return d;
+  }
+
+  /**
+   * @brief Solve A*X = B
+   *
+   * @param  B [in]  A Matrix with as many rows as A and any number of columns.
+   * @param  X [out]  A RowMatrix that will be changed such that L*U*X = B(piv,:).
+   * @return  the lowest diagonal term (in absolute value), for further checkings
+   *             of non-singularity of LU.
+   *
+   * If B is nonconformant or LU is singular, an Exception is raised.
+   *
+   */
+  Real solve (const Matrix<Real>& B, Matrix<Real>& X) const throw (BadIntegerException, ZeroDivisionException)
+  {
+    /* Dimensions: A is mxn, X is nxk, B is mxk */
+
+    if (B.getNumberOfRows() != m)
+    {
+      throw BadIntegerException("Wrong dimension in LU::solve", static_cast<int>(B.getNumberOfRows()));
+    }
+
+    Real minD = NumTools::abs<Real>(LU(0, 0));
+    for (size_t i = 1; i < m; i++)
+    {
+      Real currentValue = NumTools::abs<Real>(LU(i, i));
+      if (currentValue < minD)
+        minD = currentValue;
+    }
+
+    if (minD < NumConstants::SMALL())
+    {
+      throw ZeroDivisionException("Singular matrix in LU::solve.");
+    }
+
+    // Copy right hand side with pivoting
+    size_t nx = B.getNumberOfColumns();
+
+    permuteCopy(B, piv, 0, nx - 1, X);
+
+    // Solve L*Y = B(piv,:)
+    for (size_t k = 0; k < n; k++)
+    {
+      for (size_t i = k + 1; i < n; i++)
+      {
+        for (size_t j = 0; j < nx; j++)
+        {
+          X(i, j) -= X(k, j) * LU(i, k);
+        }
+      }
+    }
+    // Solve U*X = Y;
+    // !!! Do not use unsigned int with -- loop!!!
+    // for (int k = n-1; k >= 0; k--) {
+    size_t k = n;
+
+    do
+    {
+      k--;
+      for (size_t j = 0; j < nx; j++)
+      {
+        X(k, j) /= LU(k, k);
+      }
+      for (size_t i = 0; i < k; i++)
+      {
+        for (size_t j = 0; j < nx; j++)
+        {
+          X(i, j) -= X(k, j) * LU(i, k);
+        }
+      }
+    }
+    while (k > 0);
+
+    return minD;
+  }
+
+
+  /**
+   * @brief Solve A*x = b, where x and b are vectors of length equal	to the number of rows in A.
+   *
+   * @param  b [in] a vector (Array1D> of length equal to the first dimension	of A.
+   * @param  x [out] a vector that will be changed so that so that L*U*x = b(piv).
+   * @return  the lowest diagonal term (in absolute value), for further checkings
+   *             of non-singularity of LU.
+   *
+   * If B is nonconformant or LU is singular, an Exception is raised.
+   */
+  Real solve (const std::vector<Real>& b, std::vector<Real>& x)  const throw (BadIntegerException, ZeroDivisionException)
+  {
+    /* Dimensions: A is mxn, X is nxk, B is mxk */
+
+    if (b.dim1() != m)
+    {
+      throw BadIntegerException("Wrong dimension in LU::solve", b.dim1());
+    }
+
+    Real minD = NumTools::abs<Real>(LU(0, 0));
+    for (size_t i = 1; i < m; i++)
+    {
+      Real currentValue = NumTools::abs<Real>(LU(i, i));
+      if (currentValue < minD)
+        minD = currentValue;
+    }
+
+    if (minD < NumConstants::SMALL())
+    {
+      throw ZeroDivisionException("Singular matrix in LU::solve.");
+    }
+
+    permuteCopy(b, piv, x);
+
+    // Solve L*Y = B(piv)
+    for (size_t k = 0; k < n; k++)
+    {
+      for (size_t i = k + 1; i < n; i++)
+      {
+        x[i] -= x[k] * LU(i, k);
+      }
+    }
+
+    // Solve U*X = Y;
+    // for (size_t k = n-1; k >= 0; k--) {
+    size_t k = n;
+    do
+    {
+      k--;
+      x[k] /= LU(k, k);
+      for (size_t i = 0; i < k; i++)
+      {
+        x[i] -= x[k] * LU(i, k);
+      }
+    }
+    while (k > 0);
+
+    return minD;
+  }
+}; /* class LU */
+} // end of namespace bpp.
+
+#endif // _LU_H_
+
diff --git a/src/Bpp/Numeric/Matrix/Matrix.h b/src/Bpp/Numeric/Matrix/Matrix.h
new file mode 100644
index 0000000..42d2f32
--- /dev/null
+++ b/src/Bpp/Numeric/Matrix/Matrix.h
@@ -0,0 +1,430 @@
+//
+// File: Matrix.h
+// Authors: Julien Dutheil
+//          Sylvain Gaillard
+// Created on: Tue Apr 07 11:58 2004
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+
+#ifndef _MATRIX_H_
+#define _MATRIX_H_
+
+#include <vector>
+#include "../../Clonable.h"
+#include "../NumConstants.h"
+#include "../NumTools.h"
+#include "../VectorExceptions.h"
+#include <iostream>
+
+namespace bpp
+{
+/**
+ * @brief The matrix template interface.
+ */
+template<class Scalar>
+class Matrix :
+  public Clonable
+{
+public:
+  Matrix() {}
+  virtual ~Matrix() {}
+
+public:
+  /**
+   * @return \f$m_{i,j}\f$.
+   * @param i row index.
+   * @param j column index.
+   */
+  virtual const Scalar& operator()(size_t i, size_t j) const = 0;
+  /**
+   * @return \f$m_{i,j}\f$.
+   * @param i row index.
+   * @param j column index.
+   */
+  virtual Scalar& operator()(size_t i, size_t j) = 0;
+
+  virtual bool equals(const Matrix& m, double threshold = NumConstants::TINY())
+  {
+    if (m.getNumberOfRows() != getNumberOfRows() || m.getNumberOfColumns() != getNumberOfColumns())
+      return false;
+    for (size_t i = 0; i < getNumberOfRows(); i++)
+    {
+      for (size_t j = 0; j < getNumberOfColumns(); j++)
+      {
+        if (NumTools::abs<double>(static_cast<double>(operator()(i, j)) - static_cast<double>(m(i, j))) > threshold) return false;
+      }
+    }
+    return true;
+  }
+  /**
+   * @return The number of rows.
+   */
+  virtual size_t getNumberOfRows() const = 0;
+  /**
+   * @return The number of columns.
+   */
+  virtual size_t getNumberOfColumns() const = 0;
+  /**
+   * @return the row at position i as a vector.
+   * @param i The index of the row.
+   */
+  virtual std::vector<Scalar> row(size_t i) const = 0;
+  /**
+   * @return the column at position j as a vector.
+   * @param j The index of the column.
+   */
+  virtual std::vector<Scalar> col(size_t j) const = 0;
+  /**
+   * @brief Resize the matrix.
+   *
+   * @param nRows The new number of rows.
+   * @param nCols The new number of columns.
+   */
+  virtual void resize(size_t nRows, size_t nCols) = 0;
+};
+
+/**
+ * @brief Matrix storage by row.
+ *
+ * This matrix is a vector of vector of Scalar.
+ * Row access is in \f$O(1)\f$ while column access is in \f$O(nRow)\f$.
+ */
+template<class Scalar>
+class RowMatrix :
+  public Matrix<Scalar>
+{
+private:
+  std::vector< std::vector<Scalar> > m_;
+
+public:
+  RowMatrix() : m_() {}
+
+  RowMatrix(size_t nRow, size_t nCol) : m_(nRow)
+  {
+    for (size_t i = 0; i < nRow; i++)
+    {
+      m_[i].resize(nCol);
+    }
+  }
+
+  RowMatrix(const Matrix<Scalar>& m) : m_(m.getNumberOfRows())
+  {
+    size_t nr = m.getNumberOfRows();
+    size_t nc = m.getNumberOfColumns();
+    for (size_t i = 0; i < nr; i++)
+    {
+      m_[i].resize(nc);
+      for (size_t j = 0; j < nc; j++)
+      {
+        m_[i][j] = m(i, j);
+      }
+    }
+  }
+
+  RowMatrix& operator=(const Matrix<Scalar>& m)
+  {
+    size_t nr = m.getNumberOfRows();
+    m_.resize(nr);
+    size_t nc = m.getNumberOfColumns();
+    for (size_t i = 0; i < nr; i++)
+    {
+      m_[i].resize(nc);
+      for (size_t j = 0; j < nc; j++)
+      {
+        m_[i][j] = m(i, j);
+      }
+    }
+    return *this;
+  }
+
+  virtual ~RowMatrix() {}
+
+public:
+  RowMatrix* clone() const { return new RowMatrix(*this); }
+
+  const Scalar& operator()(size_t i, size_t j) const { return m_[i][j]; }
+
+  Scalar& operator()(size_t i, size_t j) { return m_[i][j]; }
+
+  size_t getNumberOfRows() const { return m_.size(); }
+
+  size_t getNumberOfColumns() const { return m_.size() == 0 ? 0 : m_[0].size(); }
+
+  std::vector<Scalar> row(size_t i) const
+  {
+    std::vector<Scalar> r(getNumberOfColumns());
+    for (size_t j = 0; j < getNumberOfColumns(); j++) { r[j] = operator()(i, j); }
+    return r;
+  }
+
+  std::vector<Scalar> col(size_t j) const
+  {
+    std::vector<Scalar> c(getNumberOfRows());
+    for (size_t i = 0; i < getNumberOfRows(); i++) { c[i] = operator()(i, j); }
+    return c;
+  }
+
+  void resize(size_t nRows, size_t nCols)
+  {
+    m_.resize(nRows);
+    for (size_t i = 0; i < nRows; i++)
+    {
+      m_[i].resize(nCols);
+    }
+  }
+
+  void addRow(const std::vector<Scalar>& newRow) throw (DimensionException)
+  {
+    if (newRow.size() != getNumberOfColumns()) throw DimensionException("RowMatrix::addRow: invalid row dimension", newRow.size(), getNumberOfColumns());
+    m_.push_back(newRow);
+  }
+};
+
+/**
+ * @brief Matrix storage in one vector.
+ *
+ * This Matrix is a simple vector of Scalar of size n x m.
+ * Element access is in \f$O(1)\f$ but resizing the matrix while keeping the
+ * old values is in \f$O(nm)\f$.
+ *
+ * Basic usage:
+ * @code
+ * LinearMatrix<int> m(3, 2); // Create a 3x2 matrix of int
+ * m(1, 2) = 5; // Set the value of element at row = 1, col = 2 to 5
+ * int x = m(0, 1); // Get the value of element at row = 0, col = 1;
+ * @endcode
+ *
+ * @author Sylvain Gaillard
+ */
+template<class Scalar>
+class LinearMatrix :
+  public Matrix<Scalar>
+{
+private:
+  std::vector<Scalar> m_;
+  size_t rows_;
+  size_t cols_;
+
+public:
+  /**
+   * @brief Build a 0 x 0 matrix.
+   */
+  LinearMatrix() : m_(),
+    rows_(0),
+    cols_(0) { resize_(0, 0); }
+
+  /**
+   * @brief build a nRow x nCol matrix.
+   */
+  LinearMatrix(size_t nRow, size_t nCol) : m_(),
+    rows_(nRow),
+    cols_(nCol) { resize_(nRow, nCol); }
+
+  LinearMatrix(const Matrix<Scalar>& m) : m_(m.getNumberOfRows() * m.getNumberOfColumns())
+  {
+    size_t nr = m.getNumberOfRows();
+    size_t nc = m.getNumberOfColumns();
+    for (size_t i = 0; i < nr; i++)
+    {
+      for (size_t j = 0; j < nc; j++)
+      {
+        m_[i * cols_ + j] = m(i, j);
+      }
+    }
+  }
+
+  LinearMatrix& operator=(const Matrix<Scalar>& m)
+  {
+    size_t nr = m.getNumberOfRows();
+    size_t nc = m.getNumberOfColumns();
+    m_.resize(nr * nc);
+    for (size_t i = 0; i < nr; i++)
+    {
+      m_[i].resize(nc);
+      for (size_t j = 0; j < nc; j++)
+      {
+        m_[i * cols_ + j] = m(i, j);
+      }
+    }
+    return *this;
+  }
+
+  /**
+   * @brief Destructor.
+   */
+  virtual ~LinearMatrix() {}
+
+public:
+  LinearMatrix* clone() const { return new LinearMatrix(*this); }
+
+  const Scalar& operator()(size_t i, size_t j) const { return m_[i * cols_ + j]; }
+
+  Scalar& operator()(size_t i, size_t j) { return m_[i * cols_ + j]; }
+
+  size_t getNumberOfRows() const { return rows_; }
+
+  size_t getNumberOfColumns() const { return cols_; }
+
+  std::vector<Scalar> row(size_t i) const
+  {
+    std::vector<Scalar> r(getNumberOfColumns());
+    for (size_t j = 0; j < getNumberOfColumns(); j++)
+    {
+      r[j] = operator()(i, j);
+    }
+    return r;
+  }
+
+  std::vector<Scalar> col(size_t j) const
+  {
+    std::vector<Scalar> c(getNumberOfRows());
+    for (size_t i = 0; i < getNumberOfRows(); i++)
+    {
+      c[i] = operator()(i, j);
+    }
+    return c;
+  }
+
+  /**
+   * @copydoc Matrix::resize
+   *
+   * This method resize the matrix keeping old data in place.
+   * @see LinearMatrix::resize(size_t nRow, size_t nCol, bool keepValues)
+   */
+  void resize(size_t nRows, size_t nCols)
+  {
+    resize(nRows, nCols, true);
+  }
+
+  /**
+   * @brief Resize the matrix.
+   *
+   * This task may be memory consumming if keepValues is true because it use
+   * a copy of the input matrix to keep trace of the values.
+   *
+   * @param nRows the new number of rows
+   * @param nCols the new number of columns
+   * @param keepValues if old values must be kept in the resized matrix.
+   * If keepValues = false, old values are still in the matrix but not at
+   * the same positions. For instance:
+   * @code
+   * LinearMatrix<int> m(3, 2);
+   * for (size_t i = 0 ; i < m.getNumberOfRows() ; i++) {
+   *   for (size_t j = 0 ; j < m.getNumberOfColumns() ; j++) {
+   *     m(i, j) = i * m.nCols() + j + 1;
+   *   }
+   * }
+   * MatrixTools::print(m);
+   * // 3x2
+   * // [
+   * // [1, 2]
+   * // [3, 4]
+   * // [5, 6]
+   * // ]
+   * LinearMatrix<int> m2 = m;
+   * m2.resize(2, 4, false); // resize the matrix with keepValues = false
+   * MatrixTools::print(m2);
+   * // 2x4
+   * // [
+   * // [1, 2, 3, 4]
+   * // [5, 6, 0, 0]
+   * // ]
+   * LinearMatrix<int> m3 = m;
+   * m3.resize(2, 4, true); // resize the matrix with keepValues = true
+   * MatrixTools::print(m3);
+   * // 2x4
+   * // [
+   * // [1, 2, 0, 0]
+   * // [3, 4, 0, 0]
+   * // ]
+   * @endcode
+   */
+  void resize(size_t nRows, size_t nCols, bool keepValues)
+  {
+    LinearMatrix<Scalar> tmpM;
+    if (keepValues)
+      tmpM = *this;
+    resize_(nRows, nCols);
+    if (keepValues)
+    {
+      for (size_t i = 0; i < nRows; i++)
+      {
+        for (size_t j = 0; j < nCols; j++)
+        {
+          if (i < tmpM.getNumberOfRows() && j < tmpM.getNumberOfColumns())
+          {
+            operator()(i, j) = tmpM(i, j);
+          }
+          else
+          {
+            operator()(i, j) = 0;
+          }
+        }
+      }
+    }
+  }
+
+private:
+  /**
+   * @brief Internal basic resize fonctionnalities.
+   */
+  void resize_(size_t nRows, size_t nCols)
+  {
+    m_.resize(nRows * nCols);
+    rows_ = nRows;
+    cols_ = nCols;
+  }
+};
+
+template<class Scalar>
+bool operator==(const Matrix<Scalar>& m1, const Matrix<Scalar>& m2)
+{
+  if (m1.getNumberOfRows() != m2.getNumberOfRows() || m1.getNumberOfColumns() != m2.getNumberOfColumns())
+    return false;
+  for (size_t i = 0; i < m1.getNumberOfRows(); i++)
+  {
+    for (size_t j = 0; j < m1.getNumberOfColumns(); j++)
+    {
+      if (m1(i, j) != m2(i, j))
+        return false;
+    }
+  }
+  return true;
+}
+} // end of namespace bpp.
+
+#endif // _MATRIX_H_
+
diff --git a/src/Bpp/Numeric/Matrix/MatrixTools.h b/src/Bpp/Numeric/Matrix/MatrixTools.h
new file mode 100644
index 0000000..b1a62e8
--- /dev/null
+++ b/src/Bpp/Numeric/Matrix/MatrixTools.h
@@ -0,0 +1,1280 @@
+//
+// File: MatrixTools.h
+// Created by: Julien Dutheil
+// Created on: Mon Jan 19 16:42:25 2004
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus. This file is part of the Bio++ project.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#ifndef _MATRIXTOOLS_H_
+#define _MATRIXTOOLS_H_
+
+#include "../VectorTools.h"
+#include "Matrix.h"
+#include "LUDecomposition.h"
+#include "EigenValue.h"
+
+#include <cstdio>
+#include <iostream>
+
+namespace bpp
+{
+/**
+ * @brief Functions dealing with matrices.
+ */
+class MatrixTools
+{
+public:
+  MatrixTools() {}
+  ~MatrixTools() {}
+
+public:
+  /**
+   * @brief Copy operation. This function supplies the lack of inheritence of the assigment operator :D .
+   *
+   * @param A [in] Original matrix.
+   * @param O [out] A copy of the given matrix.
+   */
+  template<class MatrixA, class MatrixO>
+  static void copy(const MatrixA& A, MatrixO& O)
+  {
+    O.resize(A.getNumberOfRows(), A.getNumberOfColumns());
+    for (size_t i = 0; i < A.getNumberOfRows(); i++)
+    {
+      for (size_t j = 0; j < A.getNumberOfColumns(); j++)
+      {
+        O(i, j) = A(i, j);
+      }
+    }
+  }
+
+  /**
+   * @brief Get a identity matrix of a given size.
+   *
+   * @param n the size of the matrix.
+   * @param O [out] A identity matrix of size n.
+   */
+  template<class Matrix>
+  static void getId(size_t n, Matrix& O)
+  {
+    O.resize(n, n);
+    for (size_t i = 0; i < n; i++)
+    {
+      for (size_t j = 0; j < n; j++) {
+        O(i, j) = (i == j) ? 1 : 0;
+      }
+    }
+  }
+
+  /**
+   * @param D [in] A vector of diagonal elements.
+   * @param O [out] A diagonal matrix with diagonal elements taken from a vector.
+   */
+  template<class Scalar>
+  static void diag(const std::vector<Scalar>& D, Matrix<Scalar>& O)
+  {
+    size_t n = D.size();
+    O.resize(n, n);
+    for (size_t i = 0; i < n; i++)
+    {
+      for (size_t j = 0; j < n; j++) { O(i, j) = (i == j) ? D[i] : 0;}
+    }
+  }
+
+  /**
+   * @param x [in] A scalar
+   * @param n [in] the dimension of the output matrix
+   * @param O [out] A diagonal matrix with diagonal elements equal to x
+   */
+  template<class Scalar>
+  static void diag(const Scalar x, size_t n, Matrix<Scalar>& O)
+  {
+    O.resize(n, n);
+    for (size_t i = 0; i < n; i++)
+      {
+        for (size_t j = 0; j < n; j++) { O(i, j) = (i == j) ? x : 0;}
+      }
+  }
+
+  /**
+   * @param M [in] The matrix.
+   * @param O [out] The diagonal elements of a square matrix as a vector.
+   * @throw DimensionException If M is not a square matrix.
+   */
+  template<class Scalar>
+  static void diag(const Matrix<Scalar>& M, std::vector<Scalar>& O) throw (DimensionException)
+  {
+    size_t nc = M.getNumberOfColumns();
+    size_t nr = M.getNumberOfRows();
+    if (nc != nr) throw DimensionException("MatrixTools::diag(). M must be a square matrix.", nr, nc);
+    O.resize(nc);
+    for (size_t i = 0; i < nc; i++) { O[i] = M(i, i);}
+  }
+
+  /**
+   * @brief Set all elements in M to value x.
+   * @param M A matrix.
+   * @param x The value to use.
+   */
+  template<class Matrix, class Scalar>
+  static void fill(Matrix& M, Scalar x)
+  {
+    for (size_t i = 0; i < M.getNumberOfRows(); i++)
+    {
+      for (size_t j = 0; j < M.getNumberOfColumns(); j++)
+      {
+        M(i, j) = x;
+      }
+    }
+  }
+
+  /**
+   * @brief Multiply all elements of a matrix by a given value, and add a constant.
+   *
+   * Performs \f$\forall i \forall j m_{i,j} = a.m_{i,j}+b\f$.
+   *
+   * @param A A matrix.
+   * @param a Multiplicator.
+   * @param b Constant.
+   */
+  template<class Matrix, class Scalar>
+  static void scale(Matrix& A, Scalar a, Scalar b = 0)
+  {
+    for (size_t i = 0; i < A.getNumberOfRows(); i++)
+    {
+      for (size_t j = 0; j < A.getNumberOfColumns(); j++)
+      {
+        A(i, j) = a * A(i, j) + b;
+      }
+    }
+  }
+
+  /**
+   * @param A [in] First matrix.
+   * @param B [in] Second matrix.
+   * @param O [out] The dot product of two matrices.
+   */
+  template<class Scalar>
+  static void mult(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O) throw (DimensionException)
+  {
+    size_t ncA = A.getNumberOfColumns();
+    size_t nrA = A.getNumberOfRows();
+    size_t nrB = B.getNumberOfRows();
+    size_t ncB = B.getNumberOfColumns();
+    if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
+    O.resize(nrA, ncB);
+    for (size_t i = 0; i < nrA; i++)
+    {
+      for (size_t j = 0; j < ncB; j++)
+      {
+        O(i, j) = 0;
+        for (size_t k = 0; k < ncA; k++)
+        {
+          O(i, j) += A(i, k) * B(k, j);
+        }
+      }
+    }
+  }
+
+  /**
+   * @brief Compute A . D . B where D is a diagonal matrix in O(n^3).
+   *
+   * Since D is a diagonal matrix, this function is more efficient than doing
+   * mult(mult(A, diag(D)), B), which involves two 0(n^3) operations.
+   *
+   * @param A [in] The first matrix.
+   * @param D [in] The diagonal matrix (only diagonal elements in a vector)
+   * @param B [in] The second matrix.
+   * @param O [out] The result matrix.
+   * @throw DimensionException If matrices have not the appropriate size.
+   */
+  template<class Scalar>
+  static void mult(const Matrix<Scalar>& A, const std::vector<Scalar>& D, const Matrix<Scalar>& B, Matrix<Scalar>& O) throw (DimensionException)
+  {
+    size_t ncA = A.getNumberOfColumns();
+    size_t nrA = A.getNumberOfRows();
+    size_t nrB = B.getNumberOfRows();
+    size_t ncB = B.getNumberOfColumns();
+    if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
+    if (ncA != D.size()) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size.", D.size(), ncA);
+    O.resize(nrA, ncB);
+    for (size_t i = 0; i < nrA; i++)
+    {
+      for (size_t j = 0; j < ncB; j++)
+      {
+        O(i, j) = 0;
+        for (size_t k = 0; k < ncA; k++)
+        {
+          O(i, j) += A(i, k) * B(k, j) * D[k];
+        }
+      }
+    }
+  }
+
+  /**
+   * @brief Compute A . (U+D+L) . B where D is a diagonal matrix, U
+   * (resp. L) is a matrix in which the only non-zero terms are on the
+   * diagonal that is over (resp. under) the main diagonal, in O(n^3).
+   *
+   * Since D is a diagonal matrix, this function is more efficient than doing
+   * mult(mult(A, diag(D)), B), which involves two 0(n^3) operations.
+   *
+   * @param A [in] The first matrix.
+   * @param D [in] The diagonal matrix (only diagonal elements in a vector)
+   * @param U [in] The upper diagonal matrix (only upper diagonal elements in a vector)
+   * @param L [in] The lower diagonal matrix (only lower diagonal elements in a vector)
+   * @param B [in] The second matrix.
+   * @param O [out] The result matrix.
+   * @throw DimensionException If matrices have not the appropriate size.
+   */
+  template<class Scalar>
+  static void mult(const Matrix<Scalar>& A, const std::vector<Scalar>& D, const std::vector<Scalar>& U, const std::vector<Scalar>& L, const Matrix<Scalar>& B, Matrix<Scalar>& O) throw (DimensionException)
+  {
+    size_t ncA = A.getNumberOfColumns();
+    size_t nrA = A.getNumberOfRows();
+    size_t nrB = B.getNumberOfRows();
+    size_t ncB = B.getNumberOfColumns();
+    if (ncA != nrB) throw DimensionException("MatrixTools::mult(). nrows B != ncols A.", nrB, ncA);
+    if (ncA != D.size()) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size.", D.size(), ncA);
+    if (ncA != U.size()+1) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size-1.", U.size(), ncA);
+    if (ncA != L.size()+1) throw DimensionException("MatrixTools::mult(). Vector size is not equal to matrix size-1.", L.size(), ncA);
+    O.resize(nrA, ncB);
+    for (size_t i = 0; i < nrA; i++)
+      {
+        for (size_t j = 0; j < ncB; j++)
+          {
+            O(i, j) = A(i, 0) * D[0] * B(0, j);
+            if (nrB>1)
+              O(i, j) += A(i,0) * U[0] * B(1,j);
+            for (size_t k = 1; k < ncA-1; k++)
+              {
+                O(i, j) += A(i, k) * (L[k-1] * B(k-1, j) + D[k] * B(k, j) + U[k] * B(k+1,j));
+              }
+            if (ncA>=2)
+              O(i, j) += A(i, ncA-1) * L[ncA-2] * B(ncA-2, j);
+            O(i,j) += A(i, ncA-1) * D[ncA-1] * B(ncA-1, j);
+          }
+      }
+  }
+
+  /**
+   * @brief Add matrix B to matrix A.
+   *
+   * @param A [in] Matrix A
+   * @param B [in] Matrix B
+   * @throw DimensionException If A and B have note the same size.
+   */
+  template<class MatrixA, class MatrixB>
+  static void add(MatrixA& A, const MatrixB& B) throw (DimensionException)
+  {
+    size_t ncA = A.getNumberOfColumns();
+    size_t nrA = A.getNumberOfRows();
+    size_t nrB = B.getNumberOfRows();
+    size_t ncB = B.getNumberOfColumns();
+    if (ncA != ncB) throw DimensionException("MatrixTools::operator+(). A and B must have the same number of colums.", ncB, ncA);
+    if (nrA != nrB) throw DimensionException("MatrixTools::operator+(). A and B must have the same number of rows.", nrB, nrA);
+    for (size_t i = 0; i < A.getNumberOfRows(); i++)
+    {
+      for (size_t j = 0; j < A.getNumberOfColumns(); j++)
+      {
+        A(i, j) += B(i, j);
+      }
+    }
+  }
+
+  /**
+   * @brief Add matrix x.B to matrix A.
+   *
+   * @param A [in,out] Matrix A
+   * @param x [in] Scalar x
+   * @param B [in] Matrix B
+   * @throw DimensionException If A and B have note the same size.
+   */
+  template<class MatrixA, class MatrixB, class Scalar>
+  static void add(MatrixA& A, Scalar& x, const MatrixB& B) throw (DimensionException)
+  {
+    size_t ncA = A.getNumberOfColumns();
+    size_t nrA = A.getNumberOfRows();
+    size_t nrB = B.getNumberOfRows();
+    size_t ncB = B.getNumberOfColumns();
+    if (ncA != ncB) throw DimensionException("MatrixTools::operator+(). A and B must have the same number of colums.", ncB, ncA);
+    if (nrA != nrB) throw DimensionException("MatrixTools::operator+(). A and B must have the same number of rows.", nrB, nrA);
+    for (size_t i = 0; i < A.getNumberOfRows(); i++)
+      {
+        for (size_t j = 0; j < A.getNumberOfColumns(); j++)
+          {
+            A(i, j) += x*B(i, j);
+          }
+      }
+  }
+
+  /**
+   * @brief Compute the power of a given matrix.
+   *
+   * @param A [in] The matrix.
+   * @param p The number of multiplications.
+   * @param O [out]\f$  A^p \f$ computed recursively:
+   *               \f$ A^{2n} = (A^n)^2 \f$
+   *               \f$ A^{2n+1} = A*(A^n)^2 \f$   
+   * If p = 0, sends the identity matrix.
+   * @throw DimensionException If m is not a square matrix.
+   */
+  template<class Matrix>
+  static void pow(const Matrix& A, size_t p, Matrix& O) throw (DimensionException)
+  {
+    size_t n = A.getNumberOfRows();
+    if (n != A.getNumberOfColumns()) throw DimensionException("MatrixTools::pow(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
+    switch(p){
+    case 0:
+      getId<Matrix>(n, O);
+      break;
+    case 1:
+      copy(A,O);
+      break;
+    case 2:
+      mult(A,A,O);
+      break;
+    default:
+      Matrix tmp;
+      if (p%2){
+        pow(A,p/2,tmp);
+        pow(tmp,2,O);
+      }
+      else{
+        pow(A,(p-1)/2,tmp);
+        pow(tmp,2,O);
+        mult(A,O,tmp);
+        copy(tmp,O);
+      }
+    }
+  }
+
+  /**
+   * @brief Compute the power of a given matrix, using eigen value decomposition.
+   *
+   * @param A [in] The matrix.
+   * @param p The power of the matrix.
+   * @param O [out]\f$\prod_{i=1}^p m\f$.
+   * If p = 0, sends the identity matrix.
+   * @throw DimensionException If m is not a square matrix.
+   */
+  template<class Scalar>
+  static void pow(const Matrix<Scalar>& A, double p, Matrix<Scalar>& O) throw (DimensionException)
+  {
+    size_t n = A.getNumberOfRows();
+    if (n != A.getNumberOfColumns()) throw DimensionException("MatrixTools::pow(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
+    EigenValue<Scalar> eigen(A);
+    RowMatrix<Scalar> rightEV, leftEV;
+    rightEV = eigen.getV();
+    inv(rightEV, leftEV);
+    mult(rightEV, VectorTools::pow(eigen.getRealEigenValues(), p), leftEV, O);
+  }
+
+  /**
+   * @brief Perform matrix exponentiation using diagonalization.
+   *
+   * @warning This method currently relies only on diagonalization, so it won't work if your matrix is not diagonalizable.
+   * The function may be extended later to deal with other cases.
+   *
+   * @param A [in] The matrix.
+   * @param O [out]\f$\prod_{i=1}^p m\f$.
+   * @throw DimensionException If m is not a square matrix.
+   */
+  template<class Scalar>
+  static void exp(const Matrix<Scalar>& A, Matrix<Scalar>& O) throw (DimensionException)
+  {
+    size_t n = A.getNumberOfRows();
+    if (n != A.getNumberOfColumns()) throw DimensionException("MatrixTools::exp(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
+    EigenValue<Scalar> eigen(A);
+    RowMatrix<Scalar> rightEV, leftEV;
+    rightEV = eigen.getV();
+    inv(rightEV, leftEV);
+    mult(rightEV, VectorTools::exp(eigen.getRealEigenValues()), leftEV, O);
+  }
+
+  /**
+   * @brief Compute a vector of the first powers of a given matrix.
+   *
+   * @param A [in] The matrix.
+   * @param p The number of powers.
+   * @param vO [out] the vector of the powers (from 0 to p)
+   *
+   * @throw DimensionException If m is not a square matrix.
+   */
+  
+  template<class Matrix, class Scalar>
+  static void Taylor(const Matrix& A, size_t p, std::vector< RowMatrix<Scalar> > & vO) throw (DimensionException)
+  {
+    size_t n = A.getNumberOfRows();
+    if (n != A.getNumberOfColumns())
+      throw DimensionException("MatrixTools::pow(). nrows != ncols.", A.getNumberOfColumns(), A.getNumberOfRows());
+    vO.resize(p+1);
+    getId<Matrix>(n, vO[0]);
+    copy(A,vO[1]);
+    
+    for (size_t i = 1; i < p; i++)
+      {
+        mult(vO[i], A, vO[i+1]);
+      }
+  }
+
+  /**
+   * @return The position of the maximum value in the matrix.
+   * @param m The matrix.
+   */
+  template<class Matrix>
+  static std::vector<size_t> whichMax(const Matrix& m)
+  {
+    size_t nrows = m.getNumberOfRows();
+    size_t ncols = m.getNumberOfColumns();
+    std::vector<size_t> pos(2);
+    size_t imax = 0;
+    size_t jmax = 0;
+    double currentMax = log(0.);
+    for (size_t i = 0; i < nrows; i++)
+    {
+      for (size_t j = 0; j < ncols; j++)
+      {
+        double currentValue = m(i, j);
+        // cout << currentValue << "\t" << (currentValue > currentMax) << endl;
+        if (currentValue > currentMax)
+        {
+          imax = i;
+          jmax = j;
+          currentMax = currentValue;
+        }
+      }
+    }
+    pos[0] = imax;
+    pos[1] = jmax;
+    return pos;
+  }
+
+  /**
+   * @return The position of the minimum value in the matrix.
+   * @param m The matrix.
+   */
+  template<class Matrix>
+  static std::vector<size_t> whichMin(const Matrix& m)
+  {
+    size_t nrows = m.getNumberOfRows();
+    size_t ncols = m.getNumberOfColumns();
+    std::vector<size_t> pos(2);
+    size_t imin = 0;
+    size_t jmin = 0;
+    double currentMin = -log(0.);
+    for (size_t i = 0; i < nrows; i++)
+    {
+      for (size_t j = 0; j < ncols; j++)
+      {
+        double currentValue = m(i, j);
+        if (currentValue < currentMin)
+        {
+          imin = i;
+          jmin = j;
+          currentMin = currentValue;
+        }
+      }
+    }
+    pos[0] = imin;
+    pos[1] = jmin;
+    return pos;
+  }
+
+  /**
+   * @return The maximum value in the matrix.
+   * @param m The matrix.
+   */
+  template<class Real>
+  static Real max(const Matrix<Real>& m)
+  {
+    size_t nrows = m.getNumberOfRows();
+    size_t ncols = m.getNumberOfColumns();
+    Real currentMax = log(0.);
+    for (size_t i = 0; i < nrows; i++)
+    {
+      for (size_t j = 0; j < ncols; j++)
+      {
+        Real currentValue = m(i, j);
+        // cout << currentValue << "\t" << (currentValue > currentMax) << endl;
+        if (currentValue > currentMax)
+        {
+          currentMax = currentValue;
+        }
+      }
+    }
+    return currentMax;
+  }
+
+
+  /**
+   * @return The minimum value in the matrix.
+   * @param m The matrix.
+   */
+  template<class Real>
+  static Real min(const Matrix<Real>& m)
+  {
+    size_t nrows = m.getNumberOfRows();
+    size_t ncols = m.getNumberOfColumns();
+    Real currentMin = -log(0.);
+    for (size_t i = 0; i < nrows; i++)
+    {
+      for (size_t j = 0; j < ncols; j++)
+      {
+        Real currentValue = m(i, j);
+        if (currentValue < currentMin)
+        {
+          currentMin = currentValue;
+        }
+      }
+    }
+    return currentMin;
+  }
+
+  /**
+   * @brief Print a matrix to a stream.
+   *
+   * @param m The matrix to print.
+   * @param out The stream to use.
+   */
+  template<class Matrix>
+  static void print(const Matrix& m, std::ostream& out = std::cout)
+  {
+    out << m.getNumberOfRows() << "x" << m.getNumberOfColumns() << std::endl;
+    out << "[" << std::endl;
+    for (size_t i = 0; i < m.getNumberOfRows(); i++)
+    {
+      out << "[";
+      for (size_t j = 0; j < m.getNumberOfColumns() - 1; j++)
+      {
+        out << m(i, j) << ", ";
+      }
+      if (m.getNumberOfColumns() > 0) out << m(i, m.getNumberOfColumns() - 1) << "]" << std::endl;
+    }
+    out << "]" << std::endl;
+  }
+
+  /**
+   * @brief Print a matrix to a stream, so that it is read by R.
+   *
+   * @param m The matrix to print.
+   * @param variableName The name of the R variable handeling the matrix
+   * @param out The stream to use.
+   */
+  template<class Matrix>
+  static void printForR(const Matrix& m, const std::string& variableName = "x", std::ostream& out = std::cout)
+  {
+    out.precision(12);
+    out << variableName << "<-matrix(c(";
+    for (size_t i = 0; i < m.getNumberOfRows(); i++)
+    {
+      for (size_t j = 0; j < m.getNumberOfColumns(); j++)
+      {
+        if (i > 0 || j > 0)
+          out << ", ";
+        out << m(i, j);
+      }
+    }
+    out << "), nrow=" << m.getNumberOfRows() << ", byrow=TRUE)" << std::endl;
+  }
+
+
+  /**
+   * @brief Print a vector to a stream.
+   *
+   * @param v The vector to print.
+   * @param out The stream to use.
+   */
+  template<class Real>
+  static void print(const std::vector<Real>& v, std::ostream& out = std::cout)
+  {
+    out << v.size() << std::endl;
+    out << "[";
+    for (size_t i = 0; i < v.size() - 1; i++)
+    {
+      out << v[i] << ", ";
+    }
+    if (v.size() > 0) out << v[v.size() - 1];
+    out << "]" << std::endl;
+  }
+
+  /**
+   * @return True if the matrix is a square matrix.
+   * @param A A matrix.
+   */
+  template<class Matrix>
+  static bool isSquare(const Matrix& A) { return A.getNumberOfRows() == A.getNumberOfColumns(); }
+
+  /**
+   * @param A [in] The matrix to inverse.
+   * @param O [out] The inverse matrix of A.
+   * @return x the minimum absolute value of the diagonal of the LU decomposition
+   * @throw DimensionException If A is not a square matrix.
+   */
+  template<class Scalar>
+  static Scalar inv(const Matrix<Scalar>& A, Matrix<Scalar>& O) throw (DimensionException, ZeroDivisionException)
+  {
+    if (!isSquare(A)) throw DimensionException("MatrixTools::inv(). Matrix A is not a square matrix.", A.getNumberOfRows(), A.getNumberOfColumns());
+    LUDecomposition<Scalar> lu(A);
+    RowMatrix<Scalar> I;
+    getId(A.getNumberOfRows(), I);
+    return lu.solve(I, O);
+  }
+
+  /**
+   * @brief Get determinant of a square matrix.
+   *
+   * This implementation is in @f$o(n^3)@f$ and uses the LU decomposition method.
+   *
+   * @param A [in] The input matrix.
+   * @return The determinant of A.
+   * @throw DimensionException If A is not a square matrix.
+   */
+  template<class Scalar>
+  static double det(const Matrix<Scalar>& A) throw (DimensionException)
+  {
+    if (!isSquare(A)) throw DimensionException("MatrixTools::det(). Matrix A is not a square matrix.", A.getNumberOfRows(), A.getNumberOfColumns());
+    LUDecomposition<Scalar> lu(A);
+    return lu.det();
+  }
+
+  /**
+   * @param A [in] The matrix to transpose.
+   * @param O [out] The transposition of A.
+   */
+  template<class MatrixA, class MatrixO>
+  static void transpose(const MatrixA& A, MatrixO& O)
+  {
+    O.resize(A.getNumberOfColumns(), A.getNumberOfRows());
+    for (size_t i = 0; i < A.getNumberOfColumns(); i++)
+    {
+      for (size_t j = 0; j < A.getNumberOfRows(); j++)
+      {
+        O(i, j) = A(j, i);
+      }
+    }
+  }
+
+  /**
+   * @brief Compute the variance-covariance matrix of an input matrix.
+   *
+   * The input matrix represent a n-sample of a random vector of dimension r.
+   * It is assumed to have r rows and n columns.
+   * The variance matrix is then computed as @f[ V = A\cdot A^T - \mu\cdot\mu^T at f],
+   * where @f$\mu at f$ is the mean vector of the sample.
+   * the output matrix is a square matrix of size r.
+   *
+   * @param A [in] The intput matrix.
+   * @param O [out] The resulting variance covariance matrix.
+   */
+  template<class Scalar>
+  static void covar(const Matrix<Scalar>& A, Matrix<Scalar>& O)
+  {
+    size_t r = A.getNumberOfRows();
+    size_t n = A.getNumberOfColumns();
+    O.resize(r, r);
+    RowMatrix<Scalar> tA;
+    transpose(A, tA);
+    mult(A, tA, O);
+    scale(O, 1. / static_cast<double>(n));
+    RowMatrix<Scalar> mean(r, 1);
+    for (size_t i = 0; i < r; i++)
+    {
+      for (size_t j = 0; j < n; j++)
+      {
+        mean(i, 0) += A(i, j);
+      }
+      mean(i, 0) /= static_cast<double>(n);
+    }
+    RowMatrix<Scalar> tMean;
+    transpose(mean, tMean);
+    RowMatrix<Scalar> meanMat;
+    mult(mean, tMean, meanMat);
+    scale(meanMat, -1.);
+    add(O, meanMat);
+  }
+
+  /**
+   * @brief Compute the Kronecker product of two row matrices.
+   *
+   * @param A [in] The first row matrix.
+   * @param B [in] The second row matrix.
+   * @param O [out] The product \f$A \otimes B\f$.
+   */
+  template<class Scalar>
+  static void kroneckerMult(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O)
+  {
+    size_t ncA = A.getNumberOfColumns();
+    size_t nrA = A.getNumberOfRows();
+    size_t nrB = B.getNumberOfRows();
+    size_t ncB = B.getNumberOfColumns();
+    O.resize(nrA * nrB, ncA * ncB);
+    for (size_t ia = 0; ia < nrA; ia++)
+    {
+      for (size_t ja = 0; ja < ncA; ja++)
+      {
+        Scalar aij = A(ia, ja);
+        for (size_t ib = 0; ib < nrB; ib++)
+        {
+          for (size_t jb = 0; jb < ncB; jb++)
+          {
+            O(ia * nrB + ib, ja * ncB + jb) = aij * B(ib, jb);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * @brief Compute the Hadamard product of two row matrices with same dimensions.
+   *
+   * @param A [in] The first row matrix.
+   * @param B [in] The second row matrix.
+   * @param O [out] The Hadamard product.
+   */
+  template<class Scalar>
+  static void hadamardMult(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O)
+  {
+    size_t ncA = A.getNumberOfColumns();
+    size_t nrA = A.getNumberOfRows();
+    size_t nrB = B.getNumberOfRows();
+    size_t ncB = B.getNumberOfColumns();
+    if (nrA != nrB) throw DimensionException("MatrixTools::hadamardMult(). nrows A != nrows B.", nrA, nrB);
+    if (ncA != ncB) throw DimensionException("MatrixTools::hadamardMult(). ncols A != ncols B.", ncA, ncB);
+    O.resize(nrA, ncA);
+    for (size_t i = 0; i < nrA; i++)
+    {
+      for (size_t j = 0; j < ncA; j++)
+      {
+        O(i, j) = A(i, j) * B(i, j);
+      }
+    }
+  }
+
+  /**
+   * @brief Compute the "Hadamard" product of a row matrix and a vector containing weights, according to rows or columns.
+   *
+   * @param A [in] The row matrix.
+   * @param B [in] The vector of row or column weights.
+   * @param O [out] The 'Hadamard' product.
+   * @param row Boolean. If row is set to 'true', the vector contains weights for rows. Otherwise the vector contains weights for columns.
+   */
+  template<class Scalar>
+  static void hadamardMult(const Matrix<Scalar>& A, const std::vector<Scalar>& B, Matrix<Scalar>& O, bool row = true)
+  {
+    size_t ncA = A.getNumberOfColumns();
+    size_t nrA = A.getNumberOfRows();
+    size_t sB = B.size();
+    if (row == true && nrA != sB) throw DimensionException("MatrixTools::hadamardMult(). nrows A != size of B.", nrA, sB);
+    if (row == false && ncA != sB) throw DimensionException("MatrixTools::hadamardMult(). ncols A != size of B.", ncA, sB);
+    O.resize(nrA, ncA);
+    if (row)
+    {
+      for (size_t i = 0; i < nrA; i++)
+      {
+        for (size_t j = 0; j < ncA; j++)
+        {
+          O(i, j) = A(i, j) * B[i];
+        }
+      }
+    }
+    else
+    {
+      for (size_t i = 0; i < nrA; i++)
+      {
+        for (size_t j = 0; j < ncA; j++)
+        {
+          O(i, j) = A(i, j) * B[j];
+        }
+      }
+    }
+  }
+
+  /**
+   * @brief Compute the Kronecker sum of two row matrices.
+   *
+   * @param A [in] The first row matrix.
+   * @param B [in] The second row matrix.
+   * @param O [out] The product \f$A \oplus B\f$.
+   */
+  template<class Scalar>
+  static void kroneckerSum(const Matrix<Scalar>& A, const Matrix<Scalar>& B, Matrix<Scalar>& O)
+  {
+    size_t ncA = A.getNumberOfColumns();
+    size_t nrA = A.getNumberOfRows();
+    size_t nrB = B.getNumberOfRows();
+    size_t ncB = B.getNumberOfColumns();
+    O.resize(nrA + nrB, ncA + ncB);
+    for (size_t ia = 0; ia < nrA; ia++)
+    {
+      for (size_t ja = 0; ja < ncA; ja++)
+      {
+        O(ia, ja) = A(ia, ja);
+      }
+    }
+    for (size_t ib = 0; ib < nrB; ib++)
+    {
+      for (size_t jb = 0; jb < nrB; jb++)
+      {
+        O(nrA + ib, ncA + jb) = B(ib, jb);
+      }
+    }
+  }
+
+  /**
+   * @brief Compute the Kronecker sum of n row matrices.
+   *
+   * @param vA [in] A vector of row matrices of any size.
+   * @param O [out] The product \f$\bigoplus_i A_i\f$.
+   */
+  template<class Scalar>
+  static void kroneckerSum(const std::vector< Matrix<Scalar>*>& vA, Matrix<Scalar>& O)
+  {
+    size_t nr = 0;
+    size_t nc = 0;
+    for (size_t k = 0; k < vA.size(); k++)
+    {
+      nr += vA[k]->getNumberOfRows();
+      nc += vA[k]->getNumberOfColumns();
+    }
+    O.resize(nr, nc);
+    size_t rk = 0; // Row counter
+    size_t ck = 0; // Col counter
+    for (size_t k = 0; k < vA.size(); k++)
+    {
+      const Matrix<Scalar>* Ak = vA[k];
+      for (size_t i = 0; i < Ak->getNumberOfRows(); i++)
+      {
+        for (size_t j = 0; j < Ak->getNumberOfColumns(); j++)
+        {
+          O(rk + i, ck + j) = (*Ak)(i, j);
+        }
+      }
+      rk += Ak->getNumberOfRows();
+      ck += Ak->getNumberOfColumns();
+    }
+  }
+
+  /**
+   * @brief Convert to a vector of vector.
+   *
+   * @param M [in] A matrix object.
+   * @param vO [out] The output vector of vector (will be resized accordingly).
+   */
+  template<class Scalar>
+  static void toVVdouble(const Matrix<Scalar>& M, std::vector< std::vector<Scalar> >& vO)
+  {
+    size_t n = M.getNumberOfRows();
+    size_t m = M.getNumberOfColumns();
+    vO.resize(n);
+    for (size_t i = 0; i < n; i++)
+    {
+      vO[i].resize(m);
+      for (size_t j = 0; j < m; j++)
+      {
+        vO[i][j] = M(i, j);
+      }
+    }
+  }
+
+  /**
+   * @brief Sum all elements in M.
+   * @param M A matrix.
+   * @return The sum of all elements.
+   */
+  template<class Scalar>
+  static Scalar sumElements(const Matrix<Scalar>& M)
+  {
+    Scalar sum = 0;
+    for (size_t i = 0; i < M.getNumberOfRows(); i++)
+    {
+      for (size_t j = 0; j < M.getNumberOfColumns(); j++)
+      {
+        sum += M(i, j);
+      }
+    }
+    return sum;
+  }
+
+
+  
+  /**
+   * @brief Linear Assignment Problem
+   *
+   * The algorithm coded here is described in 
+   * * A Shortest Augmenting Path Algorithm for Dense and Sparse Linear Assignment Problems, Computing 38, 325-340, 1987
+   * by R. Jonker and A. Volgenant, University of Amsterdam.
+   *
+   * @param assignCost [input/output] Cost matrix
+   * @param rowSol     [output] Column assigned to row in solution
+   * @param colSol     [output] Row assigned to column in solution
+   * @param u          [output] Dual variables, row reduction numbers
+   * @param v          [output] Dual variables, column reduction numbers
+   * @return The optimal cost.
+   */
+  template<class Scalar>
+  static Scalar lap(Matrix<Scalar>& assignCost,
+      std::vector<int> &rowSol, 
+      std::vector<int> &colSol, 
+      std::vector<Scalar> &u, 
+      std::vector<Scalar> &v) throw (Exception)
+  {
+    size_t dim = assignCost.getNumberOfRows();
+    if (assignCost.getNumberOfColumns() != dim)
+      throw Exception("MatrixTools::lap. Cost matrix should be scare.");
+  
+    bool unassignedFound;
+    size_t i, iMin;
+    size_t numFree = 0, previousNumFree, f, i0, k, freeRow;
+    std::vector<size_t> free(dim); // list of unassigned rows.
+    std::vector<size_t> pred(dim); // row-predecessor of column in augmenting/alternating path.
+    size_t j, j1, j2, endOfPath, last, low, up;
+    std::vector<size_t> colList(dim); // list of columns to be scanned in various ways.
+    std::vector<short int> matches(dim, 0); // counts how many times a row could be assigned.
+    Scalar min;
+    Scalar h;
+    size_t uMin, uSubMin;
+    Scalar v2;
+    std::vector<Scalar> d(dim); // 'cost-distance' in augmenting path calculation.
+
+    // Column reduction
+    for (j = dim; j > 0; j--)    // reverse order gives better results.
+    {
+      // find minimum cost over rows.
+      min = assignCost(0, j - 1); 
+      iMin = 0;
+      for (i = 1; i < dim; ++i) { 
+        if (assignCost(i, j - 1) < min) 
+        { 
+          min = assignCost(i, j - 1); 
+          iMin = i;
+        }
+      }
+      v[j - 1] = min; 
+
+      if (++matches[iMin] == 1) 
+      { 
+        // init assignment if minimum row assigned for first time.
+        rowSol[iMin] = j - 1; 
+        colSol[j - 1] = iMin; 
+      }
+      else
+        colSol[j - 1] = -1;        // row already assigned, column not assigned.
+    }
+
+    // Reduction tranfer
+    for (i = 0; i < dim; i++) { 
+      if (matches[i] == 0)     // fill list of unassigned 'free' rows.
+        free[numFree++] = i;
+      else {
+        if (matches[i] == 1)   // transfer reduction from rows that are assigned once.
+        {
+          j1 = rowSol[i]; 
+          min = -log(0);
+          for (j = 0; j < dim; j++)  
+            if (j != j1)
+              if (assignCost(i, j - 1) - v[j] < min) 
+                min = assignCost(i, j - 1) - v[j - 1];
+          v[j1] = v[j1] - min;
+        }
+      }
+    }
+
+    // Augmenting row reduction 
+    short loopcnt = 0;           // do-loop to be done twice.
+    do
+    {
+      loopcnt++;
+
+      // scan all free rows.
+      // in some cases, a free row may be replaced with another one to be scanned next.
+      k = 0; 
+      previousNumFree = numFree; 
+      numFree = 0;             // start list of rows still free after augmenting row reduction.
+      while (k < previousNumFree)
+      {
+        i = free[k]; 
+        k++;
+
+        // find minimum and second minimum reduced cost over columns.
+        uMin = assignCost(i, 0) - v[0]; 
+        j1 = 0; 
+        uSubMin = -log(0);
+        for (j = 1; j < dim; j++) 
+        {
+          h = assignCost(i, j) - v[j];
+          if (h < uSubMin) {
+            if (h >= uMin) 
+            { 
+              uSubMin = h; 
+              j2 = j;
+            }
+            else 
+            { 
+              uSubMin = uMin; 
+              uMin = h; 
+              j2 = j1; 
+              j1 = j;
+            }
+          }
+        }
+
+        i0 = colSol[j1];
+        if (uMin < uSubMin) {
+          // change the reduction of the minimum column to increase the minimum
+          // reduced cost in the row to the subminimum.
+          v[j1] = v[j1] - (uSubMin - uMin);
+        } else {                  // minimum and subminimum equal.
+          if (i0 >= 0)         // minimum column j1 is assigned.
+          { 
+            // swap columns j1 and j2, as j2 may be unassigned.
+            j1 = j2; 
+            i0 = colSol[j2];
+          }
+        }
+
+        // (re-)assign i to j1, possibly de-assigning an i0.
+        rowSol[i] = j1; 
+        colSol[j1] = i;
+
+        if (i0 >= 0) {          // minimum column j1 assigned earlier.
+          if (uMin < uSubMin) {
+            // put in current k, and go back to that k.
+            // continue augmenting path i - j1 with i0.
+            free[--k] = i0; 
+          } else { 
+            // no further augmenting reduction possible.
+            // store i0 in list of free rows for next phase.
+            free[numFree++] = i0; 
+          }
+        }
+      }
+    }
+    while (loopcnt < 2);       // repeat once.
+
+    // Augment solution for each free row.
+    for (f = 0; f < numFree; f++) 
+    {
+      freeRow = free[f];       // start row of augmenting path.
+
+      // Dijkstra shortest path algorithm.
+      // runs until unassigned column added to shortest path tree.
+      for (j = 0; j < dim; j++)  
+      { 
+        d[j] = assignCost(freeRow, j) - v[j]; 
+        pred[j] = freeRow;
+        colList[j] = j;        // init column list.
+      }
+
+      low = 0; // columns in 0..low-1 are ready, now none.
+      up = 0;  // columns in low..up-1 are to be scanned for current minimum, now none.
+               // columns in up..dim-1 are to be considered later to find new minimum, 
+               // at this stage the list simply contains all columns 
+      unassignedFound = false;
+      do
+      {
+        if (up == low)         // no more columns to be scanned for current minimum.
+        {
+          last = low - 1; 
+
+          // scan columns for up..dim-1 to find all indices for which new minimum occurs.
+          // store these indices between low..up-1 (increasing up). 
+          min = d[colList[up++]]; 
+          for (k = up; k < dim; k++) 
+          {
+            j = colList[k]; 
+            h = d[j];
+            if (h <= min)
+            {
+              if (h < min)     // new minimum.
+              { 
+                up = low;      // restart list at index low.
+                min = h;
+              }
+              // new index with same minimum, put on undex up, and extend list.
+              colList[k] = colList[up]; 
+              colList[up++] = j; 
+            }
+          }
+
+          // check if any of the minimum columns happens to be unassigned.
+          // if so, we have an augmenting path right away.
+          for (k = low; k < up; k++) { 
+            if (colSol[colList[k]] < 0) 
+            {
+              endOfPath = colList[k];
+              unassignedFound = true;
+              break;
+            }
+          }
+        }
+
+        if (!unassignedFound) 
+        {
+          // update 'distances' between freerow and all unscanned columns, via next scanned column.
+          j1 = colList[low]; 
+          low++; 
+          i = colSol[j1]; 
+          h = assignCost(i, j1) - v[j1] - min;
+
+          for (k = up; k < dim; k++) 
+          {
+            j = colList[k]; 
+            v2 = assignCost(i, j) - v[j] - h;
+            if (v2 < d[j])
+            {
+              pred[j] = i;
+              if (v2 == min) {  // new column found at same minimum value
+                if (colSol[j] < 0) 
+                {
+                  // if unassigned, shortest augmenting path is complete.
+                  endOfPath = j;
+                  unassignedFound = true;
+                  break;
+                }
+                // else add to list to be scanned right away.
+                else 
+                { 
+                  colList[k] = colList[up]; 
+                  colList[up++] = j; 
+                }
+              }
+              d[j] = v2;
+            }
+          }
+        } 
+      }
+      while (!unassignedFound);
+
+      // update column prices.
+      for (k = 0; k <= last; k++)  
+      { 
+        j1 = colList[k]; 
+        v[j1] = v[j1] + d[j1] - min;
+      }
+
+      // reset row and column assignments along the alternating path.
+      do
+      {
+        i = pred[endOfPath]; 
+        colSol[endOfPath] = i; 
+        j1 = endOfPath; 
+        endOfPath = rowSol[i]; 
+        rowSol[i] = j1;
+      }
+      while (i != freeRow);
+    }
+
+    // calculate optimal cost.
+    Scalar lapCost = 0;
+    for (i = 0; i < dim; i++)  
+    {
+      j = rowSol[i];
+      u[i] = assignCost(i, j) - v[j];
+      lapCost = lapCost + assignCost(i, j); 
+    }
+
+    return lapCost;
+  }
+
+};
+
+/* DEPRECATED
+   namespace MatrixOperators {
+
+   MatrixB operator*(const MatrixA & A, const MatrixB & B) throw (DimensionException)
+   {
+   return MatrixTools::mult<MatrixA, MatrixB>(A, B);
+   }
+
+   template<class MatrixA, class MatrixB>
+   MatrixA operator+(const MatrixA & A, const MatrixB & B) throw (DimensionException)
+   {
+   MatrixA C = A;
+   MatrixTools::add<MatrixA, MatrixB>(C, B);
+   return C;
+   }
+
+   template<class MatrixA, class MatrixB>
+   MatrixA operator+=(MatrixA & A, const MatrixB & B) throw (DimensionException)
+   {
+   MatrixTools::add<MatrixA, MatrixB>(A, B);
+   return A;
+   }
+
+   template<class Matrix>
+   Matrix operator-(const Matrix A)
+   {
+   Matrix B(A.getNumberOfRows(), A.getNumberOfColumns());
+   for(size_t i = 0; i < B.getNumberOfRows(); i++) {
+   for(size_t j = 0; j < B.getNumberOfColumns(); j++) {
+   B(i, j) = -A(i, j);
+   }
+   }
+   return B;
+   }
+
+   template<class MatrixA, class MatrixB>
+   MatrixA operator-(const MatrixA & A, const MatrixB & B) throw (DimensionException)
+   {
+   //    size_t ncA = A.getNumberOfColumns();
+   //    size_t nrA = A.getNumberOfRows();
+   //    size_t nrB = B.getNumberOfRows();
+   //    size_t ncB = B.getNumberOfColumns();
+   //    if(ncA != ncB) throw DimensionException("MatrixTools::operator-(). A and B must have the same number of colums.", ncB, ncA);
+   //    if(nrA != nrB) throw DimensionException("MatrixTools::operator-(). A and B must have the same number of rows.", nrB, nrA);
+   //    MatrixB C(A.getNumberOfRows(), A.getNumberOfColumns());
+   //    for(size_t i = 0; i < A.getNumberOfRows(); i++) {
+   //      for(size_t j = 0; j < A.getNumberOfColumns(); j++) {
+   //        C(i, j) = A(i, j) - B(i, j);
+   //      }
+   //    }
+   //    return C;
+   MatrixA C = A;
+   MatrixTools::add<MatrixA, MatrixB>(C, -B);
+   return C;
+   }
+
+   template<class MatrixA, class MatrixB>
+   MatrixA operator-=(MatrixA & A, const MatrixB & B) throw (DimensionException)
+   {
+   MatrixTools::add<MatrixA, MatrixB>(A, -B);
+   return A;
+   }
+
+   };
+ */
+} // end of namespace bpp.
+
+#endif  // _MATRIXTOOLS_H_
diff --git a/src/Bpp/Numeric/NumConstants.h b/src/Bpp/Numeric/NumConstants.h
new file mode 100644
index 0000000..fd8c809
--- /dev/null
+++ b/src/Bpp/Numeric/NumConstants.h
@@ -0,0 +1,102 @@
+//
+// File: NumConstants.h
+// Created by: Julien Dutheil
+// Created on: Tue Feb 03 14:21 2009
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus. This file is part of the Bio++ project.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _NUMCONSTANTS_H_
+#define _NUMCONSTANTS_H_
+
+#include <cmath>
+#include <limits>
+
+namespace bpp {
+
+  /**
+   * @brief this static class contains several useful constant values.
+   *
+   * This classe uses function in order to avoid the infamous "static initialization order fiasco".
+   * C++0x solves this...
+   */
+  class NumConstants
+  {
+
+  public:
+    /**
+     * @name Golden ratio.
+     *
+     * The golden ratio, @f$\phi at f$ is equal to @f$\frac{1+\sqrt{5}}{2} = 1.6180339887498948482\ldots at f$.
+     * We also define @f$R=\phi-1 at f$ and @f$C = 1 - R at f$.
+     * @{
+     */
+    static double GOLDEN_RATIO_PHI() { return (1. + sqrt(5.)) / 2.; }
+    static double GOLDEN_RATIO_R() { return GOLDEN_RATIO_PHI() - 1.; }
+    static double GOLDEN_RATIO_C() { return 1. - GOLDEN_RATIO_R(); }
+
+    /** @} */
+
+    static double MEGA() { return 1e6; }
+    static double KILO() { return 1e3; }
+    static double DECI() { return 1e-1; }
+    static double CENTI() { return 1e-2; }
+    static double MILLI() { return 1e-3; }
+    static double MICRO() { return 1e-6; }
+    static double NANO() { return 1e-9; }
+    static double PICO() { return 1e-12; }
+
+    static double SMALL() { return 1e-6; }
+    static double TINY() { return 1e-12; }
+    static double VERY_TINY() { return 1e-20; }
+    static double VERY_BIG() { return static_cast<double>(1.7E+23); }
+    
+    /**
+     * @name Define those constants in case they would not be available in stl/limits.
+     *
+     * @{
+     */
+    static double INF() { return std::numeric_limits<double>::has_infinity ? -log(0) : std::numeric_limits<double>::max(); }
+    static double PINF() { return std::numeric_limits<double>::has_infinity ? -log(0) : std::numeric_limits<double>::max(); }
+    static double MINF() { return std::numeric_limits<double>::has_infinity ? log(0) : std::numeric_limits<double>::min(); }
+    static double NaN() { return 3./0.; }
+    /** @} */
+
+    static double PI() { return 3.141593; }
+  };
+
+}//end of namespace bpp.
+
+#endif	//_NUMCONSTANTS_H_
+
diff --git a/src/Bpp/Numeric/NumTools.cpp b/src/Bpp/Numeric/NumTools.cpp
new file mode 100644
index 0000000..3157d30
--- /dev/null
+++ b/src/Bpp/Numeric/NumTools.cpp
@@ -0,0 +1,95 @@
+//
+// File: NumTools.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Nov 10 12:06:55 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "NumTools.h"
+#include "Matrix/Matrix.h"
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+  
+double NumTools::uniRoot(Function& f, const std::string& param, double a, double b, double tolerance) throw (Exception)
+{
+  ParameterList pl;
+  pl.addParameter(Parameter(param, a));
+  double fa = f.f(pl);
+  pl[0].setValue(b);
+  double fb = f.f(pl);
+  if(fa * fb > 0.) throw Exception("NumTools::uniRoot(). Initial interval values are not of opposite sign.");
+  double c = (a + b) / 2.;
+  double fc;
+  while(abs(fb - fa) > tolerance)
+  {
+    c = (a + b) / 2.; //Better use golden section here...
+    pl[0].setValue(c);
+    fc = f.f(pl);
+    
+    if(fc * fa < 0.)
+    {
+      b = c;
+      fb = fc;
+    }
+    else
+    {
+      a = c;
+      fa = fc;
+    }
+  }
+  return c;
+}
+ 
+/******************************************************************************/
+
+RowMatrix<double>* NumTools::computeHessianMatrix(DerivableSecondOrder& function, const ParameterList& parameters)
+{
+  size_t n = parameters.size();
+  vector<string> variables = parameters.getParameterNames();
+  RowMatrix<double>* hessian = new RowMatrix<double>(n, n);
+  for(unsigned int i = 0; i < n; i++)
+    for(unsigned int j = 0; j < n; j++)
+      if(j == i)
+        (*hessian)(i,j) = function.d2f(variables[i], parameters);
+      else
+        (*hessian)(i,j) = function.d2f(variables[i], variables[j], parameters);
+  return hessian;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/NumTools.h b/src/Bpp/Numeric/NumTools.h
new file mode 100644
index 0000000..1e48920
--- /dev/null
+++ b/src/Bpp/Numeric/NumTools.h
@@ -0,0 +1,205 @@
+//
+// File: NumTools.h
+// Created by: Julien Dutheil
+// Created on: Mon Nov 10 12:06:55 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _NUMTOOLS_H_
+#define _NUMTOOLS_H_
+
+#include "Function/Functions.h"
+
+namespace bpp
+{
+//Forward declaration:
+template<class Scalar> class RowMatrix;
+
+/**
+ * @brief Some utilitary function for numerical calculus.
+ */
+class NumTools
+{
+public:
+
+  /**
+   * @brief Get the magnitude of a value.
+   *
+   * This template function may work with any type for which the operators
+   * < and - are defined.
+   *
+   * @param a The value for which the magnitude must be returned.
+   * @return The magnitude of the value a.
+   */ 
+  template<class T> static T abs(T a) { return a < 0 ? -a : a; }
+
+  /**
+   * @brief Get the sign of a value.
+   *
+   * This template function may work with any type for which the operators
+   * < and == are defined.
+   *
+   * @param a The value for which the sign must be returned.
+   * @return -1 if a < 0, 0 if a = 0, 1 else.
+   */ 
+  template<class T> static T sign(T a) { return a < 0 ? -1 : (a == 0 ? 0 : 1); }
+
+  /**
+   * @brief Get the max between 2 values.
+   *
+   * This template function may work with any type for which the operator
+   * > is defined.
+   *
+   * @param a, b The two values to compare.
+   * @return a if a > b, b else.
+   */ 
+  template<class T> static T max(T a, T b) { return a > b ? a : b; }
+
+  /**
+   * @brief Get the min between 2 values.
+   *
+   * This template function may work with any type for which the operator
+   * < is defined.
+   *
+   * @param a, b The two values to compare.
+   * @return a if a < b, b else.
+   */ 
+  template<class T> static T min(T a, T b) { return a < b ? a : b; }
+
+  /**
+   * @brief Get the magnitude of a times the sign of b.
+   *
+   * @param a The value whose magnitude must be used.
+   * @param b The value whose sign must be used.
+   * @return abs<T>(a) * sign<T>(b).
+   */	 
+  template<class T> static T sign(T a, T b) { return abs<T>(a) * sign<T>(b); }
+
+  /**
+   * @brief Get the square of a number.
+   *
+   * @param a The value.
+   * @return @f$ a^2 @f$.
+   */ 
+  template<class T> static T sqr(T a) { return a * a; }
+
+  /**
+   * @brief Compute the logarithm of a sum from the sum of logarithms.
+   *
+   * The following formula is used:
+   * @f[
+   *  \ln(x) + \ln\left(1+ \exp\left(\ln(y) - \ln(x)\right)\right) = \ln(x + y)
+   * @f]
+   * see http://bozeman.genome.washington.edu/compbio/mbt599_2006/hmm_scaling_revised.pdf
+   *
+   * @param lnx The value.
+   * @param lny The power
+   * @return @f$ ln(x+y) @f$.
+   */ 
+  template<class T> static T logsum(T lnx, T lny) {  return (lny < lnx) ?
+      lnx + log(1. + exp(lny - lnx)) :
+      lny + log(1. + exp(lnx - lny));
+  }
+
+  /**************************************************************************/
+
+  template<class T> static void swap(T & a, T & b)
+  {
+	  T swap = a;
+	  a = b;
+	  b = swap;	
+  }
+
+  template<class T> static void shift(T & a, T & b, T c)
+  {
+  	a = b; b = c;
+  }
+
+  template<class T> static void shift(T & a, T & b, T & c, T d)
+  {
+  	a = b; b = c; c = d;
+  }
+
+  /**************************************************************************/
+
+  template<class T> static T fact(T n) { return (n == 0) ? 1 : n * fact(n - 1); }
+
+  /**************************************************************************/
+
+  template<class T> static T logFact(T n) { return (n == 0) ? 0 : (log(n) + logFact(n - 1)); }
+
+  /**************************************************************************/
+   
+  /**
+   * @brief Find one root of the given function.
+   *
+   * @param f The function to analyse.
+   * @param param The name of the parameter to solve.
+   * @param a Lower bound of initial interval.
+   * @param b Upper bound of initial interval.
+   * @param tolerance The final precision requested.
+   * @return The value of the parameter for which the function is zero.
+   * @throw Exception If something bad happened or if the initial interval do not contains a root.
+   */
+  static double uniRoot(Function & f, const std::string & param, double a, double b, double tolerance) throw (Exception);
+  
+  /**************************************************************************/
+  
+  /**
+   * @brief Compute the Hessian matrix for a function at a given point.
+   *
+   * @f[
+   * H(f(\theta)) = \begin{pmatrix}
+   * \frac{\partial^2 f(\theta)}{\partial \theta_1^2} & \frac{\partial^2 f(\theta)}{\partial \theta_1 \partial \theta_2} & \cdots & \frac{\partial^2 f(\theta)}{\partial \theta_1 \partial \theta_n}\\
+   * \frac{\partial^2 f(\theta)}{\partial \theta_2 \partial \theta_1} & \frac{\partial^2 f(\theta)}{\partial \theta_2^2} & \cdots & \frac{\partial^2 f(\theta)}{\partial \theta_2 \partial \theta_n}\\
+   * \vdots & \vdots & \ddots & \vdots \\
+   * \frac{\partial^2 f(\theta)}{\partial \theta_n \partial \theta_1} & \frac{\partial^2 f(\theta)}{\partial \theta_n \partial \theta_2} & \cdots & \frac{\partial^2 f(\theta)}{\partial \theta_n^2} 
+   * \end{pmatrix}
+   * @f]
+   *
+   * @param function A function with second order derivatives.
+   * @param parameters The set of parameters for which to compute the hessian matrix.
+   * @return A matrix with size equal to the number of parameters.
+   */
+  static RowMatrix<double>* computeHessianMatrix(DerivableSecondOrder& function, const ParameterList & parameters);
+ 
+  /**************************************************************************/
+
+};
+
+} //end of namespace bpp.
+
+#endif	//_NUMTOOLS_H_
+
diff --git a/src/Bpp/Numeric/Number.h b/src/Bpp/Numeric/Number.h
new file mode 100644
index 0000000..dbd3906
--- /dev/null
+++ b/src/Bpp/Numeric/Number.h
@@ -0,0 +1,100 @@
+//
+// File: Number.h
+// Created by: Julien Dutheil
+// Created on: Thu Nov 13 16:29:03 2003
+//
+
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _NUMBER_H_
+#define _NUMBER_H_
+
+#include "../Clonable.h"
+
+namespace bpp
+{
+
+/**
+ * @brief The Number object template class.
+ *
+ * This template class may be used to deal with number in an object way.
+ */
+template<class T> class Number: public Clonable
+{
+	protected:
+		/** @brief The value of this parameter. */
+		T _value;
+	
+	public:
+		
+		/**
+		 * @brief Build a new Number object with a specific value.
+		 *
+		 * @param value The value that the Number must have.
+		 */
+		Number(const T & value = 0): _value(value) {}
+			
+		virtual ~Number() {}
+
+    Number<T> & operator=(const T & t)
+    { 
+      _value = t;
+      return *this;
+    }
+	
+	public:
+	
+		/**
+		 * @name The Clonable interface.
+		 *
+		 * @{
+		 */
+		Number<T> * clone() const { return new Number<T>(_value); }
+		/** @} */
+	
+	public:
+		
+		/**
+		 * @brief Get the value of this number.
+		 *
+		 * @return The value of this number.
+		 */
+		T getValue() const { return _value; }
+};
+
+} //end of namespace bpp.
+
+#endif	//_NUMBER_H_
+
diff --git a/src/Bpp/Numeric/Parameter.cpp b/src/Bpp/Numeric/Parameter.cpp
new file mode 100644
index 0000000..836891d
--- /dev/null
+++ b/src/Bpp/Numeric/Parameter.cpp
@@ -0,0 +1,210 @@
+//
+// File: Parameter.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Oct 15 15:40:47 2003
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "Parameter.h"
+#include <cmath>
+
+//From Utils:
+#include "../Text/TextTools.h"
+
+using namespace bpp;
+
+#include <iostream>
+using namespace std;
+
+/******************************************************************************/
+
+ParameterEvent::ParameterEvent(Parameter* parameter): parameter_(parameter) {}
+
+/** Constructors: *************************************************************/
+
+Parameter::Parameter(const std::string& name, double value, Constraint* constraint, bool attachConstraint, double precision)
+  throw (ConstraintException) :
+  name_(name), value_(0), precision_(0), constraint_(constraint), attach_(attachConstraint), listeners_(), listenerAttach_()
+{
+  // This may throw a ConstraintException:
+  setValue(value);
+  setPrecision(precision);
+}
+
+Parameter::Parameter(const std::string& name, double value, const Constraint* constraint, double precision)
+  throw (ConstraintException) :
+  name_(name), value_(0), precision_(0), constraint_(constraint ? constraint->clone() : 0), attach_(true), listeners_(), listenerAttach_()
+{
+  // This may throw a ConstraintException:
+  setValue(value);
+  setPrecision(precision);
+}
+
+Parameter::Parameter(const Parameter& p) :
+  name_(p.name_),
+  value_(p.value_),
+  precision_(p.precision_),
+  constraint_(0),
+  attach_(p.attach_),
+  listeners_(p.listeners_),
+  listenerAttach_(p.listenerAttach_)
+{
+  if (p.attach_ && p.constraint_)
+    constraint_ = p.constraint_->clone();
+  else
+    constraint_ = p.constraint_;
+  for (size_t i = 0; i < listeners_.size(); i++)
+    if (listenerAttach_[i])
+      listeners_[i] = dynamic_cast<ParameterListener*>(p.listeners_[i]->clone());
+}
+
+Parameter& Parameter::operator=(const Parameter& p)
+{
+  name_           = p.name_;
+  value_          = p.value_;
+  precision_      = p.precision_;
+  attach_         = p.attach_;
+  if (p.attach_ && p.constraint_)
+    constraint_   = p.constraint_->clone();
+  else
+    constraint_   = p.constraint_;
+  listeners_      = p.listeners_;
+  listenerAttach_ = p.listenerAttach_;
+  for (size_t i = 0; i < listeners_.size(); i++)
+    if (listenerAttach_[i])
+      listeners_[i] = dynamic_cast<ParameterListener*>(p.listeners_[i]->clone());
+  return *this;	
+}
+
+/** Destructor: ***************************************************************/
+
+Parameter::~Parameter()
+{
+  if (attach_ && constraint_) delete constraint_;
+  for (size_t i = 0; i < listeners_.size(); i++)
+    if (listenerAttach_[i])
+      delete listeners_[i];
+} 
+
+/** Value: ********************************************************************/
+
+void Parameter::setValue(double value) throw (ConstraintException)
+{
+  if (std::abs(value-value_)>precision_/2){
+    if (constraint_ && !constraint_->isCorrect(value)) 
+      throw ConstraintException("Parameter::setValue", this, value);
+    value_ = value;
+    ParameterEvent event(this);
+    fireParameterValueChanged(event);
+  }
+}
+
+/** Precision: ********************************************************************/
+
+void Parameter::setPrecision(double precision)
+{
+  precision_=(precision<0)?0:precision;
+}
+
+/** Constraint: ***************************************************************/
+
+void Parameter::setConstraint(Constraint* constraint, bool attach)
+{
+  if (!constraint){
+    if (constraint_ && attach_)
+      delete constraint_;
+    constraint_=0;
+    attach_=false;
+  }
+  else {
+    if (constraint->isCorrect(value_)) {
+      if (constraint_ && attach_)
+        delete constraint_;
+      constraint_ = constraint;
+      attach_= attach;
+    }
+  else throw ConstraintException("Parameter::setConstraint", this, value_);
+  }
+}
+
+
+const Constraint* Parameter::removeConstraint()
+{
+  const Constraint * c = constraint_;
+  constraint_ = 0;
+  return c;
+}
+
+/******************************************************************************/
+
+void Parameter::removeParameterListener(const std::string& listenerId)
+{
+  for (unsigned int i = 0; i < listeners_.size(); i++)
+    {
+      if (listeners_[i]->getId() == listenerId)
+        {
+          if (listenerAttach_[i]) delete listeners_[i];
+          listeners_.erase(listeners_.begin() + i);
+          listenerAttach_.erase(listenerAttach_.begin() + i);
+        }
+    }
+}
+
+/******************************************************************************/
+
+bool Parameter::hasParameterListener(const std::string& listenerId)
+{
+  for (unsigned int i = 0; i < listeners_.size(); i++)
+    if (listeners_[i]->getId() == listenerId)
+      return true;
+  return false;
+}
+
+/******************************************************************************/
+
+const IntervalConstraint Parameter::R_PLUS(true, 0, true);
+
+const IntervalConstraint Parameter::R_PLUS_STAR(true, 0, false);
+
+const IntervalConstraint Parameter::R_MINUS(false, 0, true);
+
+const IntervalConstraint Parameter::R_MINUS_STAR(false, 0, false);
+
+const IntervalConstraint Parameter::PROP_CONSTRAINT_IN(0, 1, true, true);
+
+const IntervalConstraint Parameter::PROP_CONSTRAINT_EX(0, 1, false, false);
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Parameter.h b/src/Bpp/Numeric/Parameter.h
new file mode 100644
index 0000000..1b0b74f
--- /dev/null
+++ b/src/Bpp/Numeric/Parameter.h
@@ -0,0 +1,344 @@
+//
+// File: Parameter.h
+// Created by: Julien Dutheil
+// Created on: Wed Oct 15 15:40:47 2003
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _PARAMETER_H_
+#define _PARAMETER_H_
+
+#include "ParameterExceptions.h"
+#include "Constraints.h"
+#include "../Clonable.h"
+
+// From the STL:
+#include <string>
+#include <iostream>
+#include <vector>
+
+namespace bpp
+{
+
+  class Parameter;
+
+  class ParameterEvent:
+    public virtual Clonable
+  {
+  protected:
+    Parameter* parameter_;
+
+  public:
+    ParameterEvent(Parameter* parameter);
+    
+    ParameterEvent(const ParameterEvent& pe): parameter_(pe.parameter_) {}
+    ParameterEvent& operator=(const ParameterEvent& pe)
+    {
+      parameter_ = pe.parameter_;
+      return *this;
+    }
+
+#ifndef NO_VIRTUAL_COV
+    ParameterEvent*
+#else
+    Clonable*
+#endif
+    clone() const { return new ParameterEvent(*this); }
+
+  public:
+    const Parameter* getParameter() const { return parameter_; }
+    Parameter* getParameter() { return parameter_; }
+  };
+
+  /**
+   * @brief The parameter listener interface.
+   *
+   * Imlementing this interface allows to catch events associated to parameters modifications.
+   * Listeners must have an identifier that will be used to pinpoint it when attached to a list.
+   * This identifier needs not be unique though, but listeners with identical id will be undistinguishable.
+   */
+  class ParameterListener:
+    public virtual Clonable
+  {
+  public:
+#ifndef NO_VIRTUAL_COV
+    ParameterListener*
+#else
+    Clonable*
+#endif
+    clone() const = 0;
+
+  public:
+
+    /**
+     * @return The identifier of this listener.
+     */
+    virtual const std::string& getId() const = 0;
+
+    /**
+     * @brief Notify a renaming action.
+     *
+     * @param event Event associated to the acion.
+     */
+    virtual void parameterNameChanged(ParameterEvent& event) = 0;
+    
+    /**
+     * @brief Notify a value change.
+     *
+     * @param event Event associated to the acion.
+     */
+    virtual void parameterValueChanged(ParameterEvent& event) = 0;
+  };
+
+  /**
+   * @brief This class is designed to facilitate the manipulation of parameters.
+   *
+   * A parameter object contains a <i>value</i> stored as a double.
+   * It also contains a <i>name</i> and optionaly a constraint.
+   * Constraint objects allows to apply restriction on the value of the parameter,
+   * for instance positive number, or a particular interval and so on.
+   *
+   * @see ParameterList, Parametrizable, Constraint.
+   */
+  class Parameter:
+    public virtual Clonable
+  {
+  protected:
+    std::string name_;             //Parameter name
+    double value_;            //Parameter value
+    double precision_;  // Precision needed for Parameter value
+    Constraint* constraint_; //A constraint on the value
+    bool attach_;   // Tells if the constraint is attached to the Parameter
+    std::vector<ParameterListener*> listeners_;
+    std::vector<bool> listenerAttach_;
+  
+  public: // Class constructors and destructors:
+
+    /**
+     * @brief Default contructor. Creates a parameter with no name, no constraint, and a value of 0.
+     */
+    Parameter(): name_(""), value_(0), precision_(0), constraint_(0), attach_(true), listeners_(), listenerAttach_() {}
+    /**
+     * @brief Build a new parameter.
+     *
+     * @param name       The parameter name.
+     * @param value      The parameter value.
+     * @param constraint A  pointer toward a constraint Object.
+     * @param attachConstraint Tell if the constraint must be attached to this parameter, or shared
+     * @param precision An optional parameter precision (default 0)
+     * between different objects (the default behavior, for backward compatibility).
+     * If the first case, the constraint object will be destroyed when the parameter is destroyed,
+     * and duplicated when the parameter is copied.
+     * @throw ConstraintException If the parameter value does not match the contraint.
+     */
+    Parameter(const std::string& name, double value, Constraint* constraint, bool attachConstraint, double precision=0)
+      throw (ConstraintException);
+
+    /**
+     * @brief Build a new parameter.
+     *
+     * @param name       The parameter name.
+     * @param value      The parameter value.
+     * @param constraint An optional pointer toward a constraint Object. The constraint will be copied and attached to this instance.
+     * @param precision An optional parameter precision (default 0)
+     * @throw ConstraintException If the parameter value does not match the contraint.
+     */
+    Parameter(const std::string& name, double value, const Constraint* constraint = 0, double precision=0)
+      throw (ConstraintException);
+
+
+    /**
+     * @brief Copy constructor.
+     */
+    Parameter(const Parameter& param);
+    
+    /**
+     * @brief Assignment operator.
+     */
+    Parameter& operator=(const Parameter& param);
+  
+    virtual ~Parameter();
+    
+#ifndef NO_VIRTUAL_COV
+    Parameter*
+#else
+    Clonable*
+#endif
+    clone() const { return new Parameter(*this); }
+    
+  public:
+
+    /**
+     * @brief Set the name of this parameter.
+     *
+     * @param name the new parameter name.
+     */
+    virtual void setName(const std::string & name)
+    {
+      name_ = name;
+      ParameterEvent event(this);
+      fireParameterNameChanged(event);
+    }
+  
+    /**
+     * @brief Set the value of this parameter.
+     *
+     * @param value the new parameter value.
+     */
+    virtual void setValue(double value) throw (ConstraintException);
+  
+    /**
+     * @brief Set the precision of this parameter.
+     *
+     * @param precision the new parameter precision.
+     */
+    void setPrecision(double precision);
+    
+    /**
+     * @brief Get the name of this parameter.
+     *
+     * @return The parameter name.
+     */
+    virtual const std::string& getName() const { return name_; }
+  
+    /**
+     * @brief Get the value of this parameter.
+     *
+     * @return The parameter value.
+     */
+    virtual double getValue() const { return value_; }
+    
+    /**
+     * @brief Get the precision of this parameter.
+     *
+     * @return The precision value.
+     */
+    virtual double getPrecision() const { return precision_; }
+    
+    /**
+     * @brief Return the constraint associated to this parameter if there is one.
+     *
+     * @return A pointer toward the constraint, or NULL if there is no constraint.
+     */
+    virtual const Constraint* getConstraint() const { return constraint_; }
+    
+    /**
+     * @brief Return the constraint associated to this parameter if there is one.
+     *
+     * @return A pointer toward the constraint, or NULL if there is no constraint.
+     */
+    virtual Constraint* getConstraint() { return constraint_; }
+
+    /**
+     * @brief Tells if this parameter has a constraint.
+     *
+     * @return True if this parameter has a contraint.
+     */
+    virtual bool hasConstraint() const { return constraint_ != 0; }
+    
+    /**
+     * @brief Remove the constraint associated to this parameter.
+     *
+     * Warning! The contraint objet is not deleted.
+     *
+     * @return A pointer toward the formerly used contraint.
+     */
+    virtual const Constraint* removeConstraint();
+
+    /**
+     * @brief Set a constraint to this parameter.
+     *
+     * @param constraint a pointer to the constraint (may be null)
+     * @param attach says if the constraint is attached to the Parameter (default: false).
+     * @return A pointer toward the formerly used contraint.
+     */
+    
+    virtual void setConstraint(Constraint* constraint, bool attach = false);
+
+    /**
+     * @brief Add a new listener to this parameter.
+     *
+     * @param listener The listener to add.
+     * @param attachListener Tell if the parameter will own this listener.
+     * If so, deep copies will be made when cloning the parameter, and the listener will be destroyed upon
+     * destruction of the parameter or upon removal. Alternatively, only superficial copies will be made,
+     * and the listener will persist if the parameter is destroyed.
+     */
+    virtual void addParameterListener(ParameterListener* listener, bool attachListener = true)
+    {
+      listeners_.push_back(listener);
+      listenerAttach_.push_back(attachListener);
+    }
+
+    /**
+     * @brief Remove all listeners with a given id from this parameter.
+     *
+     * @param listenerId The id of listener to remove.
+     */
+    virtual void removeParameterListener(const std::string& listenerId);
+
+    /**
+     * @brief Tell is there is a listener with a given id from this parameter.
+     *
+     * @param listenerId The id of listener to remove.
+     * @return True if at list one listener with the given id was found.
+     */
+    virtual bool hasParameterListener(const std::string& listenerId);
+
+  protected:
+    void fireParameterNameChanged(ParameterEvent& event)
+    {
+      for(std::vector<ParameterListener *>::iterator it = listeners_.begin(); it != listeners_.end(); it++)
+        (*it)->parameterNameChanged(event);
+    }
+    void fireParameterValueChanged(ParameterEvent& event)
+    {
+      for(std::vector<ParameterListener *>::iterator it = listeners_.begin(); it != listeners_.end(); it++)
+        (*it)->parameterValueChanged(event);
+    }
+  
+  public:
+    static const IntervalConstraint R_PLUS;
+    static const IntervalConstraint R_PLUS_STAR;
+    static const IntervalConstraint R_MINUS;
+    static const IntervalConstraint R_MINUS_STAR;
+    static const IntervalConstraint PROP_CONSTRAINT_IN;
+    static const IntervalConstraint PROP_CONSTRAINT_EX;
+  };
+
+} //end of namespace bpp.
+
+#endif  //_PARAMETER_H_
+
diff --git a/src/Bpp/Numeric/ParameterAliasable.h b/src/Bpp/Numeric/ParameterAliasable.h
new file mode 100644
index 0000000..2ba444a
--- /dev/null
+++ b/src/Bpp/Numeric/ParameterAliasable.h
@@ -0,0 +1,172 @@
+//
+// File: ParameterAliasable.h
+// Created by: Julien Dutheil
+// Created on: Thu May 14 16:53 2009
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _PARAMETERALIASABLE_H_
+#define _PARAMETERALIASABLE_H_
+
+#include "Parametrizable.h"
+#include "ParameterExceptions.h"
+#include "ParameterList.h"
+
+//From the STL:
+#include <string>
+
+namespace bpp
+{
+
+/**
+ * @brief Extend the Parametrizable interface with support for parameter aliases.
+ *
+ * Parameter aliases allows several parameter to be constrained together, and 
+ * for instance, be jointly estimated.
+ * The alias relationship is not symmetric:
+ * @code
+ * aliasParameters("a","b");
+ * @endcode
+ * results in the value of "b" being updated when a is modified, but a will not be updated upon modification of "a".
+ * "b" will also be removed of the list of "independent" parameters.
+ * Furthermore, a parameter can only be aliased with another one:
+ * @code
+ * aliasParameters("a","b");
+ * aliasParameters("c","b"); //ERROR, throws an exception.
+ * @endcode
+ * However, several parameters can be aliased to the same one:
+ * @code
+ * aliasParameters("a","b");
+ * aliasParameters("a","c");
+ * @endcode
+ * In this case, modifying "a" will automatically update the values of "b" and "c", and "b" and "c" are removed from the list of indepedent parameters.
+ * Finally, parameters can be chained:
+ * @code
+ * aliasParameters("a","b");
+ * aliasParameters("b","c");
+ * @endcode
+ * is equivallent to the previous example.
+ */
+class ParameterAliasable :
+  public virtual Parametrizable
+{
+  public:
+    ParameterAliasable() {}
+    virtual ~ParameterAliasable() {}
+
+  public:
+
+    /**
+     * @brief Get the number of independent parameters.
+     *
+     * @return The number of independent parameters.
+     * If no parameters are aliased, this is equivalent to the getNumberOfParameters() method.
+     */
+    virtual size_t getNumberOfIndependentParameters() const = 0;
+
+    /**
+     * @brief Set two parameters as 'aliased'.
+     *
+     * The values of the two parameters will be synchronized, so that setting the value of one parameter will automatically set the value of the other one accordingly.
+     * @param p1 Original parameter.
+     * @param p2 Aliased parameter.
+     * @throw ParameterNotFoundException if p1 or p2 do not correspond to existing parameters.
+     * @throw Exception when trying to perform non-valid association.
+     */
+    virtual void aliasParameters(const std::string & p1, const std::string & p2) throw (ParameterNotFoundException, Exception) = 0; 
+
+    /**
+     * @brief Detach two parameters previously set as 'aliased'.
+     *
+     * The values of the two parameters will now be independent.
+     * @param p1 Original parameter.
+     * @param p2 Aliased parameter.
+     * @throw ParameterNotFoundException if p1 or p2 do not correspond to existing parameters.
+     * @throw Exception when trying to perform non-valid dissociation.
+      */
+    virtual void unaliasParameters(const std::string & p1, const std::string & p2) throw (ParameterNotFoundException, Exception)  = 0;
+
+    /**
+     * @brief Get the minimal list of parameters to set the model.
+     *
+     * If no parameters are aliased, this is the same a getParameters().
+     *
+     * @return A minimal set of parameters.
+     */
+    virtual const ParameterList & getIndependentParameters() const = 0;
+
+    /**
+     * @return The list of names of the parameters that are aliased with a given parameter.
+     * Depending on the implementation, the function may be recursive or not...
+     * @param name The name of the parameter to look for.
+     */
+    virtual std::vector<std::string> getAlias(const std::string& name) const = 0;
+};
+
+
+
+
+/**
+ * @brief A low-level implementation of the ParameterAliasable interface with void functions.
+ *
+ * @see Parameter, ParameterList, ParameterAliasable
+ */
+class ParameterAliasableAdapter:
+  public ParametrizableAdapter
+{
+	public:
+		ParameterAliasableAdapter() {}
+		virtual ~ParameterAliasableAdapter() {}
+
+	public:
+
+		/**
+		 * @name The ParameterAliasable interface.
+		 *
+		 * @{
+		 */
+		const ParameterList & getIndependentParameters() const { return getParameters(); }
+    void aliasParameters(const std::string & p1, const std::string & p2) throw (ParameterNotFoundException, Exception) {}
+    void unaliasParameters(const std::string & p1, const std::string & p2) throw (ParameterNotFoundException, Exception) {}
+    unsigned int getNumberOfIndependentParameters() const{ return 0; }
+    std::vector<std::string> getAlias(const std::string& name) const { return std::vector<std::string>(); }
+		/** @} */
+
+};
+
+} // end of namespace bpp.
+
+#endif // _PARAMETERALIASABLE_H_
+
diff --git a/src/Bpp/Numeric/ParameterExceptions.cpp b/src/Bpp/Numeric/ParameterExceptions.cpp
new file mode 100644
index 0000000..d06f268
--- /dev/null
+++ b/src/Bpp/Numeric/ParameterExceptions.cpp
@@ -0,0 +1,75 @@
+//
+// File: ParameterExceptions.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Nov  3 18:05:36 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "ParameterExceptions.h"
+#include "Parameter.h"
+
+// From Utils:
+#include "../Text/TextTools.h"
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+
+ParameterException::ParameterException(const std::string& text, const Parameter* param) :
+	Exception("ParameterException: " + text + (param != 0 ? "(" + param -> getName() + ")" : string(""))),
+	parameter_(param) {};
+		
+const Parameter* ParameterException::getParameter() const { return parameter_; }
+
+/******************************************************************************/
+
+ConstraintException::ConstraintException(const std::string& text, const Parameter* param, double badValue) :
+	ParameterException("ConstraintException: " + text + "(" + TextTools::toString(badValue) + ")"
+      + (param->hasConstraint() ? param->getConstraint()->getDescription() : "no constraint"), param),
+	badValue_(badValue) {};
+		
+double ConstraintException::getBadValue() const { return badValue_; }
+
+/******************************************************************************/
+
+ParameterNotFoundException::ParameterNotFoundException(const string& text, const string& param) :
+	Exception("ParameterNotFoundException: " + text + (!TextTools::isEmpty(param) ? "(" + param + ")" : string(""))),
+	parameter_(param) {};
+		
+std::string ParameterNotFoundException::getParameter() const { return parameter_; }
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/ParameterExceptions.h b/src/Bpp/Numeric/ParameterExceptions.h
new file mode 100644
index 0000000..72ce6d3
--- /dev/null
+++ b/src/Bpp/Numeric/ParameterExceptions.h
@@ -0,0 +1,164 @@
+//
+// File: ParameterExceptions.h
+// Created by: Julien Dutheil
+// Created on: Mon Nov  3 18:05:36 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _PARAMETEREXCEPTIONS_H_
+#define _PARAMETEREXCEPTIONS_H_
+
+// From Utils:
+#include "../Exceptions.h"
+
+// From the STL:
+#include <string>
+
+namespace bpp
+{
+
+class Parameter;
+
+/**
+ * @brief The parameter exception base class.
+ *
+ * @see Exception
+ */
+class ParameterException :
+  public Exception
+{
+
+	private:
+		const Parameter* parameter_;
+			
+	public:	// Class constructors and destructor:
+		/**
+		 * @brief Build a new ParameterException object.
+		 *
+		 * @param text A message to be passed to the exception hierarchy.
+		 * @param param A const pointer toward the parameter that threw the exception.
+		 */	
+		ParameterException(const std::string& text, const Parameter* param);
+
+    ParameterException(const ParameterException& pe):
+      Exception(pe),
+      parameter_(pe.parameter_) {} //We explicitely do not want to make a hard copy of the pointer here.
+
+    ParameterException& operator=(const ParameterException& pe)
+    {
+      Exception::operator=(pe);
+      parameter_ = pe.parameter_;
+      return *this;
+    }
+	
+		virtual ~ParameterException() throw () {}
+		
+	public:
+		/**
+		 * @brief Get the parameter that threw the exception.
+		 *
+		 * @return A const pointer toward the parameter.
+		 */
+		virtual const Parameter * getParameter() const;
+};
+
+/**
+ * @brief Exception thrown when a value do not match a given constraint.
+ *
+ * @see Constraint
+ */
+class ConstraintException : public ParameterException
+{
+	
+	private:
+		double badValue_;
+	
+	public: // Class constructor and destructor:
+		/**
+		 * @brief Build a new ConstraintException object.
+		 *
+		 * @param text     A message to be passed to the exception hierarchy.
+		 * @param param    A const pointer toward the parameter that threw the exception.
+		 * @param badValue The value that doesn't match the constraint.
+		 */	
+		ConstraintException(const std::string& text, const Parameter* param, double badValue);
+
+		virtual ~ConstraintException() throw () {}
+	
+	public:
+		/**
+		 * @brief Get the value that doesn't match the constraint.
+		 *
+		 * @return The faulty value.
+		 */
+		virtual double getBadValue() const;
+};
+
+/*******************************************************************************/
+
+/**
+ * @brief Exception thrown when a parameter is not found,
+ * for instance in a ParameterList.
+ */
+class ParameterNotFoundException : public Exception
+{
+
+	private:
+		const std::string parameter_;
+			
+	public:	// Class constructors and destructor:
+		/**
+		 * @brief Build a new ParameterNotFoundException object.
+		 *
+		 * @param text     A message to be passed to the exception hierarchy.
+		 * @param param    The name of the parameter not found.
+		 */	
+		ParameterNotFoundException(const std::string& text, const std::string& param = "");
+	
+		virtual ~ParameterNotFoundException() throw () {}
+		
+	public:
+		/**
+		 * @brief Get the name of the parameter not found.
+		 *
+		 * @return The parameter name.
+		 */
+		virtual std::string getParameter() const;		
+};
+
+} //end of namespace bpp.
+
+#endif	//_PARAMETEREXCEPTIONS_H_
+
diff --git a/src/Bpp/Numeric/ParameterList.cpp b/src/Bpp/Numeric/ParameterList.cpp
new file mode 100644
index 0000000..27651aa
--- /dev/null
+++ b/src/Bpp/Numeric/ParameterList.cpp
@@ -0,0 +1,489 @@
+//
+// File: ParameterList.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Oct 15 18:17:29 2003
+//
+
+/*
+   Copyright or © or Copr. Julien Dutheil, (November 19, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "ParameterList.h"
+
+using namespace bpp;
+
+#include <iostream>
+#include <algorithm>
+using namespace std;
+
+/** Copy constructor: *********************************************************/
+
+ParameterList::ParameterList(const ParameterList& pl) :
+  parameters_(pl.size())
+{
+  // Now copy all parameters:
+  for (unsigned int i = 0; i < size(); i++)
+  {
+    parameters_[i] = dynamic_cast<Parameter*>(pl.parameters_[i]->clone());
+  }
+}
+
+/** Assignation operator: *****************************************************/
+
+ParameterList& ParameterList::operator=(const ParameterList& pl)
+{
+  // First delete all parameters:
+  reset();
+
+  // Then resize the vector:
+  parameters_.resize(pl.size());
+
+  // Now copy all parameters:
+  for (unsigned int i = 0; i < pl.size(); i++)
+  {
+    parameters_[i] = dynamic_cast<Parameter*>(pl.parameters_[i]->clone());
+  }
+
+  return *this;
+}
+
+/** Destructor: ***************************************************************/
+
+ParameterList::~ParameterList()
+{
+  // Delete all parameter objects.
+  reset();
+}
+
+/******************************************************************************/
+const Parameter& ParameterList::getParameter(const std::string& name) const throw (ParameterNotFoundException)
+{
+  for (unsigned int i = 0; i < size(); i++)
+  {
+    const Parameter* p = parameters_[i];
+    if (p->getName() == name) return *p;
+  }
+  throw ParameterNotFoundException("ParameterList::getParameter('name').", name);
+}
+
+/******************************************************************************/
+double ParameterList::getParameterValue(const std::string& name) const throw (ParameterNotFoundException)
+{
+  for (unsigned int i = 0; i < size(); i++)
+  {
+    const Parameter* p = parameters_[i];
+    if (p->getName() == name) return p->getValue();
+  }
+  throw ParameterNotFoundException("ParameterList::getParameterValue('name').", name);
+}
+
+/******************************************************************************/
+Parameter& ParameterList::getParameter(const std::string& name) throw (ParameterNotFoundException)
+{
+  for (unsigned int i = 0; i < size(); i++)
+  {
+    Parameter* p = parameters_[i];
+    if (p->getName() == name) return *p;
+  }
+  throw ParameterNotFoundException("ParameterList::getParameter('name').", name);
+}
+
+/******************************************************************************/
+ParameterList ParameterList::subList(const std::vector<std::string>& names) const throw (ParameterNotFoundException)
+{
+  ParameterList pl;
+  for (unsigned int i = 0; i < names.size(); i++)
+  {
+    Parameter param = getParameter(names[i]);
+    pl.addParameter(param);
+  }
+  return pl;
+}
+
+/******************************************************************************/
+ParameterList ParameterList::subList(const std::string& name) const throw (ParameterNotFoundException)
+{
+  ParameterList pl;
+  Parameter param = getParameter(name);
+  pl.addParameter(param);
+  return pl;
+}
+
+/******************************************************************************/
+ParameterList ParameterList::subList(const std::vector<size_t>& parameters) const
+{
+  ParameterList pl;
+  for (unsigned int i = 0; i < parameters.size(); i++)
+  {
+    if (parameters[i] < size()) pl.parameters_.push_back(dynamic_cast<Parameter*>(parameters_[parameters[i]]->clone()));
+  }
+  return pl;
+}
+
+/******************************************************************************/
+ParameterList ParameterList::subList(size_t parameter) const
+{
+  ParameterList pl;
+  if (parameter < size()) pl.parameters_.push_back(dynamic_cast<Parameter*>(parameters_[parameter]->clone()));
+  return pl;
+}
+
+/******************************************************************************/
+ParameterList ParameterList::getCommonParametersWith(const ParameterList& params) const
+{
+  ParameterList pl;
+  for (unsigned int i = 0; i < params.size(); i++)
+  {
+    const Parameter& p = params[i];
+    if (hasParameter(p.getName()))
+      pl.parameters_.push_back(dynamic_cast<Parameter*>(p.clone()));                                                                        
+    // We use push_back instead of addParameter because we are sure the name is not duplicated.
+  }
+
+  return pl;
+}
+
+/******************************************************************************/
+
+std::vector<std::string> ParameterList::getParameterNames() const
+{
+  vector<string> pNames(size());
+  for (unsigned int i = 0; i < size(); i++)
+  {
+    pNames[i] = parameters_[i]->getName();
+  }
+  return pNames;
+}
+
+/******************************************************************************/
+
+void ParameterList::addParameter(const Parameter& param) throw (ParameterException)
+{
+  if (hasParameter(param.getName()))
+    throw ParameterException("ParameterList::addParameter. Parameter with name '" + param.getName() + "' already exists.", &param);
+  parameters_.push_back(dynamic_cast<Parameter*>(param.clone()));
+}
+
+/******************************************************************************/
+
+void ParameterList::addParameter(Parameter* param) throw (ParameterException)
+{
+  if (hasParameter(param->getName()))
+    throw ParameterException("ParameterList::addParameter. Parameter with name '" + param->getName() + "' already exists.", param);
+  parameters_.push_back(param);
+}
+
+/******************************************************************************/
+
+void ParameterList::setParameter(size_t index, const Parameter& param) throw (IndexOutOfBoundsException)
+{
+  if (index >= size()) throw IndexOutOfBoundsException("ParameterList::setParameter.", index, 0, size());
+  delete parameters_[index];
+  parameters_[index] = dynamic_cast<Parameter*>(param.clone());
+}
+
+/******************************************************************************/
+
+void ParameterList::includeParameters(const ParameterList& params)
+{
+  for (unsigned int i = 0; i < params.size(); i++)
+  {
+    if (hasParameter(params[i].getName()))
+      setParameterValue(params[i].getName(), params[i].getValue());
+    else
+      parameters_.push_back(dynamic_cast<Parameter*>(params[i].clone()));
+  }
+}
+
+/******************************************************************************/
+
+void ParameterList::addParameters(const ParameterList& params)
+throw (ParameterException)
+{
+  for (unsigned int i = 0; i < params.size(); i++)
+  {
+    addParameter(params[i]);
+  }
+}
+
+/******************************************************************************/
+
+void ParameterList::setParameterValue(const string& name, double value)
+throw (ParameterNotFoundException, ConstraintException)
+{
+  Parameter* p = &getParameter(name);
+  p->setValue(value);
+}
+
+/******************************************************************************/
+
+void ParameterList::setAllParametersValues(const ParameterList& params)
+throw (ParameterNotFoundException, ConstraintException)
+{
+  // First we check if all values are correct:
+  for (vector<Parameter*>::iterator it = parameters_.begin(); it < parameters_.end(); it++)
+  {
+    const Parameter* p = &params.getParameter((*it)->getName());
+    if ((*it)->hasConstraint() && !(*it)->getConstraint()->isCorrect(p->getValue()))
+      throw ConstraintException("ParameterList::setParametersValues()", *it, p->getValue());
+  }
+
+  // If all values are ok, we set them:
+  for (vector<Parameter*>::iterator it = parameters_.begin(); it < parameters_.end(); it++)
+  {
+    const Parameter* p = &params.getParameter((*it)->getName());
+    (*it)->setValue(p->getValue());
+  }
+}
+
+/******************************************************************************/
+
+void ParameterList::setParametersValues(const ParameterList& params)
+{
+  // First we check if all values are correct:
+  for (vector<Parameter*>::const_iterator it = params.parameters_.begin(); it < params.parameters_.end(); it++)
+  {
+    if (hasParameter((*it)->getName()))
+    {
+      Parameter* p = &getParameter((*it)->getName());
+      if (p->hasConstraint() && !p->getConstraint()->isCorrect((*it)->getValue()))
+        throw ConstraintException("ParameterList::setParametersValues()", p, (*it)->getValue());
+    }
+  }
+
+  // If all values are ok, we set them:
+  {
+    for (vector<Parameter*>::const_iterator it = params.parameters_.begin(); it < params.parameters_.end(); it++)
+    {
+      if (hasParameter((*it)->getName()))
+      {
+        Parameter* p = &getParameter((*it)->getName());
+        p->setValue((*it)->getValue());
+      }
+    }
+  }
+}
+
+/******************************************************************************/
+
+bool ParameterList::testParametersValues(const ParameterList& params) const
+{
+  // First we check if all values are correct:
+  for (vector<Parameter*>::const_iterator it = params.parameters_.begin(); it < params.parameters_.end(); it++)
+  {
+    if (hasParameter((*it)->getName()))
+    {
+      const Parameter* p = &getParameter((*it)->getName());
+      if (p->hasConstraint() && !p->getConstraint()->isCorrect((*it)->getValue()))
+        throw ConstraintException("ParameterList::matchParametersValues()", p, (*it)->getValue());
+    }
+  }
+
+  // If all values are ok, we test them:
+  bool ch = 0;
+
+  for (vector<Parameter*>::const_iterator it = params.parameters_.begin(); it < params.parameters_.end(); it++)
+  {
+    if (hasParameter((*it)->getName()))
+    {
+      const Parameter* p = &getParameter((*it)->getName());
+      if (p->getValue() != (*it)->getValue())
+        ch |= 1;
+    }
+  }
+  return ch;
+}
+
+/******************************************************************************/
+
+bool ParameterList::matchParametersValues(const ParameterList& params)
+throw (ConstraintException)
+{
+  // First we check if all values are correct:
+  for (vector<Parameter*>::const_iterator it = params.parameters_.begin(); it < params.parameters_.end(); it++)
+  {
+    if (hasParameter((*it)->getName()))
+    {
+      Parameter* p = &getParameter((*it)->getName());
+      if (p->hasConstraint() && !p->getConstraint()->isCorrect((*it)->getValue()))
+        throw ConstraintException("ParameterList::matchParametersValues()", p, (*it)->getValue());
+    }
+  }
+
+  // If all values are ok, we set them:
+  bool ch = 0;
+
+  for (vector<Parameter*>::const_iterator it = params.parameters_.begin(); it < params.parameters_.end(); it++)
+  {
+    if (hasParameter((*it)->getName()))
+    {
+      Parameter* p = &getParameter((*it)->getName());
+      if (p->getValue() != (*it)->getValue())
+        ch |= 1;
+      p->setValue((*it)->getValue());
+    }
+  }
+  return ch;
+}
+
+/******************************************************************************/
+void ParameterList::setAllParameters(const ParameterList& params)
+throw (ParameterNotFoundException)
+{
+  for (vector<Parameter*>::iterator it = parameters_.begin(); it < parameters_.end(); it++)
+  {
+    const Parameter* p = &params.getParameter((*it)->getName());
+    **it = *p;
+  }
+}
+
+/******************************************************************************/
+void ParameterList::setParameters(const ParameterList& params)
+throw (ParameterNotFoundException)
+{
+  for (vector<Parameter*>::const_iterator it = params.parameters_.begin(); it < params.parameters_.end(); it++)
+  {
+    Parameter* p = &getParameter((*it)->getName());
+    *p = **it;
+  }
+}
+
+/******************************************************************************/
+bool ParameterList::hasParameter(const std::string& name) const
+{
+  for (unsigned int i = 0; i < size(); i++)
+  {
+    const Parameter* p = parameters_[i];
+    if (p->getName() == name)
+      return true;
+  }
+  return false;
+}
+
+/******************************************************************************/
+void ParameterList::matchParameters(const ParameterList& params)
+{
+  for (vector<Parameter*>::const_iterator it = params.parameters_.begin(); it < params.parameters_.end(); it++)
+  {
+    if (hasParameter((*it)->getName()))
+    {
+      Parameter* p = &getParameter((*it)->getName());
+      *p = **it;
+    }
+  }
+}
+
+/******************************************************************************/
+void ParameterList::deleteParameter(const std::string& name) throw (ParameterNotFoundException)
+{
+  for (unsigned int i = 0; i < size(); i++)
+  {
+    Parameter* p = parameters_[i];
+    if (p->getName() == name)
+    {
+      delete p;
+      parameters_.erase(parameters_.begin() + i);
+      return;
+    }
+  }
+  throw ParameterNotFoundException("ParameterList::deleteParameter", name);
+}
+
+/******************************************************************************/
+void ParameterList::deleteParameters(const std::vector<std::string>& names) throw (ParameterNotFoundException)
+{
+  for (unsigned int i = 0; i < names.size(); i++)
+  {
+    deleteParameter(names[i]);
+  }
+}
+
+/******************************************************************************/
+void ParameterList::deleteParameter(size_t index) throw (IndexOutOfBoundsException)
+{
+  if (index >= size()) throw IndexOutOfBoundsException("ParameterList::deleteParameter.", index, 0, size());
+  Parameter* p = parameters_[index];
+  delete p;
+  parameters_.erase(parameters_.begin() + index);
+}
+
+/******************************************************************************/
+void ParameterList::deleteParameters(const std::vector<size_t>& indices) throw (IndexOutOfBoundsException)
+{
+  vector<size_t> tmp(indices);
+  sort(tmp.begin(), tmp.end());
+  for (vector<size_t>::reverse_iterator i = tmp.rbegin(); i != tmp.rend(); i++)
+  {
+    size_t index = *i;
+    if (index >= size()) throw IndexOutOfBoundsException("ParameterList::deleteParameter.", index, 0, size());
+    Parameter* p = parameters_[index];
+    delete p;
+    parameters_.erase(parameters_.begin() + index);
+  }
+}
+
+/******************************************************************************/
+size_t ParameterList::whichParameterHasName(const std::string& name) const throw (ParameterNotFoundException)
+{
+  for (size_t i = 0; i < size(); i++)
+  {
+    if (parameters_[i]->getName() == name) return i;
+  }
+  throw ParameterNotFoundException("ParameterList::whichParameterHasName.", name);
+}
+
+/******************************************************************************/
+void ParameterList::printParameters(OutputStream& out) const
+{
+  (out << "Name:\tValue:\tConstraint:").endLine();
+  (out << "_________________________________________________").endLine();
+  for (unsigned int i = 0; i < size(); i++)
+  {
+    out << parameters_[i]->getName();
+    out << "\t" << parameters_[i]->getValue();
+    out << (parameters_[i]->hasConstraint() ? "\t" + parameters_[i]->getConstraint()->getDescription() : string(""));
+    out.endLine();
+  }
+}
+
+/******************************************************************************/
+void ParameterList::reset()
+{
+  for (unsigned int i = 0; i < size(); i++)
+  {
+    delete parameters_[i];
+  }
+  parameters_.resize(0);
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/ParameterList.h b/src/Bpp/Numeric/ParameterList.h
new file mode 100644
index 0000000..da93029
--- /dev/null
+++ b/src/Bpp/Numeric/ParameterList.h
@@ -0,0 +1,374 @@
+//
+// File: ParameterList.h
+// Created by: Julien Dutheil
+// Created on: Wed Oct 15 18:17:29 2003
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#ifndef _PARAMETERLIST_H_
+#define _PARAMETERLIST_H_
+
+#include "Parameter.h"
+#include "../Clonable.h"
+#include "../Io/OutputStream.h"
+
+// From STL:
+#include <vector>
+#include <string>
+#include <iostream>
+
+namespace bpp
+{
+/**
+ * @brief The parameter list object.
+ *
+ * @author Julien Dutheil, Laurent Gueguen
+ * This is a vector of Parameter with a few additional methods, mainly for giving
+ * name access.
+ */
+class ParameterList :
+  public Clonable
+{
+private:
+  std::vector<Parameter*> parameters_;
+
+public:
+  /**
+   * @brief Build a new ParameterList object.
+   */
+  ParameterList() : parameters_() {}
+
+  /**
+   * @brief Copy constructor
+   *
+   * All parameters in the list will be cloned.
+   */
+  ParameterList(const ParameterList& pl);
+
+  ParameterList& operator=(const ParameterList& pl);
+
+  ParameterList* clone() const { return new ParameterList(*this); }
+
+  virtual ~ParameterList();
+
+public:
+  /**
+   * @return The number of parameters in the list.
+   */
+  size_t size() const { return parameters_.size(); }
+
+  /**
+   * @return The parameter at a given position.
+   * @warning No check is performed on the validity of the index given as input!
+   */
+  virtual const Parameter& operator[](size_t i) const { return *parameters_[i]; }
+  virtual Parameter& operator[](size_t i) { return *parameters_[i]; }
+
+  /**
+   * @brief Get the parameter with name <i>name</i>.
+   *
+   * @param name The name of the parameter to look for.
+   * @return A const reference toward the parameter with name <i>name</i>.
+   * @throw ParameterNotFoundException If no parameter with the given name is found.
+   */
+  virtual const Parameter& getParameter(const std::string& name) const throw (ParameterNotFoundException);
+
+  /**
+   * @brief Get the value of the parameter with name <i>name</i>.
+   *
+   * @param name The name of the parameter to look for.
+   * @return A value of the parameter with name <i>name</i>.
+   * @throw ParameterNotFoundException If no parameter with the given name is found.
+   */
+
+  virtual double getParameterValue(const std::string& name) const throw (ParameterNotFoundException);
+
+  /**
+   * @brief Get the parameter with name <i>name</i>.
+   *
+   * @param name The name of the parameter to look for.
+   * @return A reference toward the parameter with name <i>name</i>.
+   * @throw ParameterNotFoundException If no parameter with the given name is found.
+   */
+  virtual Parameter& getParameter(const std::string& name) throw (ParameterNotFoundException);
+
+  /**
+   * @brief Get given parameters as a sublist.
+   *
+   * @param names Name of the parameters to be included in the list.
+   * @return A list with all parameters specified.
+   * @throw ParameterNotFoundException If at least one name does not correspond to a parameter in the list.
+   */
+  virtual ParameterList subList(const std::vector<std::string>& names) const throw (ParameterNotFoundException);
+
+  /**
+   * @brief Get given parameter as a sublist.
+   *
+   * @param name Name of the parameter to be included in the list.
+   * @return A list with the parameter specified.
+   * @throw ParameterNotFoundException If no parameter with the given name is found.
+   */
+  virtual ParameterList subList(const std::string& name) const throw (ParameterNotFoundException);
+
+  /**
+   * @brief Get given parameters as a sublist.
+   *
+   * @param parameters Positions of the parameters to be included in the list.
+   * @return A list with all parameters specified.
+   */
+  virtual ParameterList subList(const std::vector<size_t>& parameters) const;
+
+  /**
+   * @brief Get given parameter as a sublist.
+   *
+   * @param parameter Position of the parameters to be included in the list.
+   * @return A list with the parameter specified.
+   */
+  virtual ParameterList subList(size_t parameter) const;
+
+  /**
+   * @brief Get the sublist containing all common parameter between this list and pl.
+   *
+   * @param params The list to compare to.
+   * @return A list with all common parameters.
+   */
+  virtual ParameterList getCommonParametersWith(const ParameterList& params) const;
+
+  /**
+   * @brief Get all parameter names in the list.
+   *
+   * @return A vector with all names in the same order as the parameters in the list.
+   */
+  virtual std::vector<std::string> getParameterNames() const;
+
+  /**
+   * @brief Add a new parameter at the end of the list.
+   *
+   * @param param The parameter to add to the list.
+   */
+  virtual void addParameter(const Parameter& param) throw (ParameterException);
+
+  /**
+   * @brief Add a new parameter at the end of the list.
+   *
+   * This function is more efficient than its reference counterpart,
+   * as it avoid an object copy. The ParameterList will own the pointer
+   * after addition, if it is successful.
+   *
+   * @param param A ppointer toward the parameter to add to the list.
+   */
+  virtual void addParameter(Parameter* param) throw (ParameterException);
+
+  /**
+   * @brief Change given parameter.
+   *
+   * @param index The position of the parameter to alter.
+   * @param param The parameter to add to the list.
+   * @throw IndexOutOfBoundsException if the index is not valid.
+   */
+  virtual void setParameter(size_t index, const Parameter& param) throw (IndexOutOfBoundsException);
+
+  /**
+   * @brief Add new parameters at the end of the list.
+   *
+   * @param params The parameter list containing the new paramters to add to the list.
+   */
+  virtual void addParameters(const ParameterList& params) throw (ParameterException);
+
+  /**
+   * @brief Add parameters to the list. If the parameter already
+   * exists, only the value is updated, otherwise the new parameter is
+   * added at the end of the list.
+   *
+   * @param params The parameter list containing the new paramters to add to the list.
+   */
+  virtual void includeParameters(const ParameterList& params);
+
+  /**
+   * @brief Set the value of parameter with name <i>name</i> to be equal to <i>value</i>.
+   *
+   * @param name the name of the parameter to set.
+   * @param value The value of the parameter.
+   * @throw ParameterNotFoundException If no parameter with the given name is found in the list.
+   * @throw ConstraintException If the value is incorrect.
+   */
+  virtual void setParameterValue(const std::string& name, double value)
+    throw (ParameterNotFoundException, ConstraintException);
+
+  /**
+   * @brief Set the parameters to be equals to <i>params</i>.
+   *
+   * The list must contain exactly the same parameters (ie same names)
+   * than the parameters available.
+   *
+   * @param params A list with all parameters.
+   * @see setParameters(), matchParameters();
+   * @throw ParameterNotFoundException If at least one name does not correspond to a parameter in the list.
+   * @throw ConstraintException If one value is incorrect (and the two parameter list do not have the same constraints).
+   */
+  virtual void setAllParametersValues(const ParameterList& params)
+    throw (ParameterNotFoundException, ConstraintException);
+
+  /**
+   * @brief Update the parameters from the ones in <i>params</i>
+   * that have matching names.
+   *
+   * @param params A list containing all parameters to update.
+   * @see setAllParameters(), matchParameters()
+   * @throw ConstraintException If one value is incorrect (and the two parameter list do not have the same constraints).
+   */
+  virtual void setParametersValues(const ParameterList& params);
+
+  /**
+   * @brief Returns true if the Parameter of the given name exists.
+   *
+   * @name A string name
+   */
+  virtual bool hasParameter(const std::string& name) const;
+
+  /**
+   * @brief Tests the parameters from <i>params</i>.
+   *
+   * Only common parameters with <i>params</i> are compared.
+   *
+   * @param params A list of parameters.
+   * @return true iff a least one parameter value is different.
+   */
+  virtual bool testParametersValues(const ParameterList& params) const;
+
+  /**
+   * @brief Update the parameters from <i>params</i>.
+   *
+   * Only common parameters with <i>params</i> will be updated.
+   *
+   * @param params A list of parameters.
+   * @return true iff a least one parameter value has been changed.
+   * @see setParameters(), setAllParameters()
+   */
+  virtual bool matchParametersValues(const ParameterList& params)
+    throw (ConstraintException);
+
+  /**
+   * @brief Set the parameters to be equals to <i>params</i>.
+   *
+   * The list must contain exactly the same parameters (ie same names)
+   * than the parameters available.
+   *
+   * @param params A list with all parameters.
+   * @see setParameters(), matchParameters();
+   */
+  virtual void setAllParameters(const ParameterList& params)
+    throw (ParameterNotFoundException);
+
+  /**
+   * @brief Update the parameters from <i>params</i>.
+   *
+   * <i>params</i> must be a subset of all parameters available.
+   *
+   * @param params A list containing all parameters to update.
+   * @see setAllParameters(), matchParameters()
+   */
+  virtual void setParameters(const ParameterList& params)
+    throw (ParameterNotFoundException);
+
+  /**
+   * @brief Update the parameters from <i>params</i>.
+   *
+   * Only common parameters with <i>params</i> will be updated.
+   *
+   * @param params A list of parameters.
+   * @see setParameters(), setAllParameters()
+   */
+  virtual void matchParameters(const ParameterList& params);
+
+  /**
+   * @brief Delete a parameter from the list.
+   *
+   * @param name The name of the parameter to delete from the list.
+   */
+  virtual void deleteParameter(const std::string& name) throw (ParameterNotFoundException);
+
+  /**
+   * @brief Delete several parameters from the list.
+   *
+   * @param names The names of the parameters to delete from the list.
+   */
+  virtual void deleteParameters(const std::vector<std::string>& names) throw (ParameterNotFoundException);
+
+  /**
+   * @brief Delete a parameter from the list.
+   *
+   * @param index The position of the parameter to delete in the list.
+   */
+  virtual void deleteParameter(size_t index) throw (IndexOutOfBoundsException);
+
+  /**
+   * @brief Delete several parameters from the list.
+   *
+   * @param indices The positions of the parameters to delete in the list.
+   * Duplicated positions will be considered only one time.
+   */
+  virtual void deleteParameters(const std::vector<size_t>& indices) throw (IndexOutOfBoundsException);
+
+  /**
+   * @brief Get the position of a given parameter according to its name.
+   *
+   * @param name The name of the parameter to look for.
+   * @return The position of the parameter if found. If several parameters exist with the given name,
+   * the position of the first one is returned.
+   * @throw ParameterNotFoundException If no parameter with the given name is found.
+   */
+  virtual size_t whichParameterHasName(const std::string& name) const throw (ParameterNotFoundException);
+
+  /**
+   * @brief Print all parameters.
+   */
+  virtual void printParameters(OutputStream& out) const;
+
+  virtual void printParameters(std::ostream& out) const
+  {
+    StlOutputStreamWrapper os(&out);
+    printParameters(os);
+  }
+
+  /**
+   * @brief Reset the list: delete all parameters.
+   */
+  virtual void reset();
+};
+} // end of namespace bpp.
+
+#endif  // _PARAMETERLIST_H_
+
diff --git a/src/Bpp/Numeric/Parametrizable.h b/src/Bpp/Numeric/Parametrizable.h
new file mode 100644
index 0000000..3c1a095
--- /dev/null
+++ b/src/Bpp/Numeric/Parametrizable.h
@@ -0,0 +1,230 @@
+//
+// File: Parametrizable.h
+// Created by: Julien Dutheil
+// Created on: Sun Oct 19 23:06:42 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _PARAMETRIZABLE_H_
+#define _PARAMETRIZABLE_H_
+
+// From Utils:
+#include "../Clonable.h"
+
+// From the STL:
+#include <string>
+
+#include "ParameterList.h"
+
+namespace bpp
+{
+
+/**
+ * @brief This is the interface for all objects that imply parameters.
+ *
+ * @see Parameter, ParameterList
+ */
+class Parametrizable:
+  public virtual Clonable
+{
+	public:
+		Parametrizable() {}
+		virtual ~Parametrizable() {}
+
+	public:
+    /**
+     * @brief Tell if there is a parameter with specified name.
+     *
+     * @param name The name of the parameter to look for.
+     * @return y/n.
+     */
+    virtual bool hasParameter(const std::string& name) const = 0;
+	
+		/**
+		 * @brief Get all parameters available.
+     *
+     * @see getIndependentParameters if some parameters are aliased.
+		 * @return A list with all parameters available.
+		 */
+		virtual const ParameterList& getParameters() const = 0;
+
+    /**
+     * @brief Get the parameter with specified name.
+     *
+     * @param name The name of the parameter to look for.
+     * @return The parameter with given name.
+     * @throw ParameterNotFoundException if no parameter with this name is found.
+     */
+    virtual const Parameter& getParameter(const std::string& name) const throw (ParameterNotFoundException) = 0;
+	
+		/**
+		 * @brief Get the value for parameter of name 'name'.
+		 *
+		 * @param name The name of the parameter.
+		 * @return the value of parameter <i>name</i>.
+		 */
+		virtual double getParameterValue(const std::string& name) const
+			throw (ParameterNotFoundException) = 0;
+
+		/**
+		 * @brief Set the parameters values to be equals to those of <i>parameters</i>.
+		 *
+		 * The list must contain exactly the same parameters (ie same names)
+		 * than the parameters available.
+		 *
+		 * @param parameters A list with all parameters.
+		 * @throw ParameterNotFoundException If a some parameter in the list is not in <i>params</i>.
+		 * @throw ConstraintException If a value in <i>parameters</i> does not match the constraint in the
+		 * corresponding parameter in the list.
+		 */
+		virtual void setAllParametersValues(const ParameterList& parameters) 
+			throw (ParameterNotFoundException, ConstraintException) = 0;
+
+		/**
+		 * @brief Set the value of parameter with name <i>name</i> to be equal to <i>value</i>.
+		 *
+		 * @param name the name of the parameter to set.
+		 * @param value The value of the parameter.
+		 * @throw ParameterNotFoundException If no parameter in the list has the name <i>name</i>.
+		 * @throw ConstraintException If <i>value</i> does not match the constraint associated to
+		 * parameter <i>name</i>.
+		 */
+		virtual void setParameterValue(const std::string& name, double value) 
+			throw (ParameterNotFoundException, ConstraintException) = 0;
+
+		/**
+		 * @brief Update the parameters from <i>parameters</i>.
+		 *
+		 * <i>parameters</i> must be a subset of all parameters available.
+		 *
+		 * @param parameters A list containing all parameters to update.
+		 * @throw ParameterNotFoundException If a some parameter in <i>params</i> is not in the list.
+		 * @throw ConstraintException If a value in <i>parameters</i> does not match the constraint in the
+		 * corresponding parameter in the list.
+		 */
+		virtual void setParametersValues(const ParameterList& parameters)
+			throw (ParameterNotFoundException, ConstraintException) = 0;
+
+		/**
+		 * @brief Update the parameters from <i>parameters</i>.
+		 *
+		 * Only common parameters with <i>parameters</i> will be updated.
+		 *
+		 * @param parameters A list of parameters.
+     * @return True if at least one parameter value has been changed.
+		 * @throw ConstraintException If a value in <i>parameters</i> does not match the constraint in the
+		 * corresponding parameter in the list.
+		 */
+		virtual bool matchParametersValues(const ParameterList& parameters)
+			throw (ConstraintException) = 0;
+
+    /**
+     * @brief Get the number of parameters.
+     *
+     * @see getNumberOfIndependentParameters If some parameters are aliased.
+     * @return The number of parameters.
+     */
+    virtual size_t getNumberOfParameters() const = 0;
+
+    /**
+     * @brief Set the namespace for the parameter names.
+     *
+     * @param prefix The 'namespace', that is a prefix to add to all parameter names.
+     * If parameter names are already prefixed, the new prefix will be used instead.
+     */
+    virtual void setNamespace(const std::string& prefix) = 0;
+
+    /**
+     * @return The current namespace used. This is an empty string if no namespace is currently defined.
+     */
+    virtual std::string getNamespace() const = 0;
+
+    /**
+     * @brief Resolves a parameter name according to the current namespace.
+     *
+     * @return The parameter name without the namespace prefix, if any.
+     */
+    virtual std::string getParameterNameWithoutNamespace(const std::string& name) const = 0;
+
+};
+
+/**
+ * @brief A low-level implementation of the Parametrizable interface with void functions.
+ *
+ * @see Parameter, ParameterList, Parametrizable
+ */
+class ParametrizableAdapter:
+  public virtual Parametrizable
+{
+  protected:
+    ParameterList parameters_;
+    Parameter parameter_;
+
+	public:
+		ParametrizableAdapter(): parameters_(), parameter_() {}
+		virtual ~ParametrizableAdapter() {}
+
+	public:
+
+		/**
+		 * @name The Parametrizable interface.
+		 *
+		 * @{
+		 */
+    bool hasParameter(const std::string & name) const { return parameters_.hasParameter(name); }
+		const ParameterList & getParameters() const { return parameters_; }
+    const Parameter & getParameter(const std::string & name) const throw (ParameterNotFoundException) { return parameter_; }
+		double getParameterValue(const std::string & name) const
+			throw (ParameterNotFoundException) { return 0; };
+		void setAllParametersValues(const ParameterList & parameters) 
+			throw (ParameterNotFoundException, ConstraintException) {}
+		void setParameterValue(const std::string & name, double value) 
+			throw (ParameterNotFoundException, ConstraintException) {}
+		void setParametersValues(const ParameterList & parameters)
+			throw (ParameterNotFoundException, ConstraintException) {}
+		bool matchParametersValues(const ParameterList & parameters)
+			throw (ConstraintException) { return false ;}
+    size_t getNumberOfParameters() const{ return 0; }
+    void setNamespace(const std::string& prefix) {}
+    std::string getNamespace() const { return ""; }
+    std::string getParameterNameWithoutNamespace(const std::string& name) const { return name; }
+		/** @} */
+
+};
+
+} //end of namespace bpp.
+
+#endif	//_PARAMETRIZABLE_H_
+
diff --git a/src/Bpp/Numeric/Prob/AbstractDiscreteDistribution.cpp b/src/Bpp/Numeric/Prob/AbstractDiscreteDistribution.cpp
new file mode 100644
index 0000000..3d25976
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/AbstractDiscreteDistribution.cpp
@@ -0,0 +1,466 @@
+//
+// File: AbstractDiscreteDistribution.cpp
+// Created by: Julien Dutheil
+// Created on: ?
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "AbstractDiscreteDistribution.h"
+
+#include "../Random/RandomTools.h"
+#include "../VectorTools.h"
+
+using namespace bpp;
+using namespace std;
+
+
+AbstractDiscreteDistribution::AbstractDiscreteDistribution(size_t nbClasses, const std::string& prefix) :
+  AbstractParameterAliasable(prefix),
+  numberOfCategories_(nbClasses),
+  distribution_(),
+  bounds_(nbClasses-1),
+  intMinMax_(-NumConstants::VERY_BIG(), NumConstants::VERY_BIG(), true, true),
+  median_(false)
+{}
+
+AbstractDiscreteDistribution::AbstractDiscreteDistribution(size_t nbClasses, double delta, const std::string& prefix) :
+  AbstractParameterAliasable(prefix),
+  numberOfCategories_(nbClasses),
+  distribution_(Order(delta)),
+  bounds_(nbClasses-1),
+  intMinMax_(-NumConstants::VERY_BIG(), NumConstants::VERY_BIG(),true, true),
+  median_(false)
+{}
+
+AbstractDiscreteDistribution::AbstractDiscreteDistribution(const AbstractDiscreteDistribution& adde) :
+  AbstractParameterAliasable(adde),
+  numberOfCategories_(adde.numberOfCategories_),
+  distribution_(adde.distribution_),
+  bounds_(adde.bounds_),
+  intMinMax_(adde.intMinMax_),
+  median_(adde.median_)
+{
+}
+
+AbstractDiscreteDistribution& AbstractDiscreteDistribution::operator=(const AbstractDiscreteDistribution& adde) 
+{
+  AbstractParameterAliasable::operator=(adde);
+  numberOfCategories_=adde.numberOfCategories_;
+  distribution_=adde.distribution_;
+  bounds_=adde.bounds_;
+  intMinMax_=adde.intMinMax_;
+  median_=adde.median_;
+
+  return *this;
+}
+
+/******************************************************************************/
+
+size_t AbstractDiscreteDistribution::getNumberOfCategories() const
+{
+  return numberOfCategories_;
+}
+
+void AbstractDiscreteDistribution::setNumberOfCategories(size_t nbClasses)
+{
+  if (nbClasses <= 0)
+    cerr << "DEBUG: ERROR!!! Number of categories is <= 0 in AbstractDiscreteDistribution::setNumberOfCategories()." << endl;
+
+  if (numberOfCategories_ != nbClasses)
+  {
+    numberOfCategories_ = nbClasses;
+    discretize();
+  }
+}
+
+
+/******************************************************************************/
+
+double AbstractDiscreteDistribution::getCategory(size_t categoryIndex) const
+{
+  map<double, double>::const_iterator it = distribution_.begin();
+  for (unsigned int i = 0; i < categoryIndex; i++)
+  {
+    it++;
+  }
+  return it->first;
+}
+
+/******************************************************************************/
+
+double AbstractDiscreteDistribution::getProbability(size_t categoryIndex) const
+{
+  map<double, double>::const_iterator it = distribution_.begin();
+  for (unsigned int i = 0; i < categoryIndex; i++)
+  {
+    it++;
+  }
+  return it->second;
+}
+
+/******************************************************************************/
+
+double AbstractDiscreteDistribution::getProbability(double category) const
+{
+  return distribution_.find(category)->second;
+}
+
+/******************************************************************************/
+
+Vdouble AbstractDiscreteDistribution::getCategories() const
+{
+  Vdouble result(distribution_.size());
+  unsigned int i = 0;
+  for (map<double, double>::const_iterator it = distribution_.begin();
+       it != distribution_.end();
+       it++)
+  {
+    result[i] = it->first;
+    i++;
+  }
+  return result;
+}
+
+/******************************************************************************/
+
+Vdouble AbstractDiscreteDistribution::getProbabilities() const
+{
+  Vdouble result(distribution_.size());
+  int i = 0;
+  for (map<double, double>::const_iterator it = distribution_.begin();
+       it != distribution_.end();
+       it++)
+  {
+    result[i] = it->second;
+    i++;
+  }
+  return result;
+}
+
+/******************************************************************************/
+
+void AbstractDiscreteDistribution::set(double category, double probability)
+{
+  distribution_[category] = probability;
+}
+
+/******************************************************************************/
+
+void AbstractDiscreteDistribution::add(double category, double probability)
+{
+  if (distribution_.find(category) == distribution_.end())
+  {
+    // new category
+    distribution_[category] = probability;
+  }
+  else
+  {
+    // existing category
+    distribution_[category] += probability;
+  }
+}
+
+/******************************************************************************/
+
+double AbstractDiscreteDistribution::rand() const
+{
+  double r = RandomTools::giveRandomNumberBetweenZeroAndEntry(1);
+  double cumprob = 0;
+  for (map<double, double>::const_iterator i = distribution_.begin();
+       i != distribution_.end();
+       i++)
+  {
+    cumprob += i->second;
+    if (r <= cumprob)
+      return i->first;
+  }
+  // This line can't be reached:
+  return -1.;
+}
+
+/******************************************************************************/
+
+double AbstractDiscreteDistribution::getInfCumulativeProbability(double category) const
+{
+  double prob = 0;
+  map<double, double>::const_iterator it = distribution_.find(category);
+  for (map<double, double>::const_iterator i = distribution_.begin();
+       i != it;
+       i++)
+  {
+    prob += i->second;
+  }
+  return prob;
+}
+
+/******************************************************************************/
+
+double AbstractDiscreteDistribution::getIInfCumulativeProbability(double category) const
+{
+  double prob = 0;
+  map<double, double>::const_iterator it = distribution_.find(category);
+  if (it == distribution_.end())
+    return 0;
+  for (map<double, double>::const_iterator i = ++it;
+       i != distribution_.end();
+       i++)
+  {
+    prob += i->second;
+  }
+  return 1. - prob;
+}
+
+/******************************************************************************/
+
+double AbstractDiscreteDistribution::getSupCumulativeProbability(double category) const
+{
+  double prob = 0;
+  map<double, double>::const_iterator it = distribution_.find(category);
+  if (it == distribution_.end())
+    return 0;
+  for (map<double, double>::const_iterator i = ++it;
+       i != distribution_.end();
+       i++)
+  {
+    prob += i->second;
+  }
+  return prob;
+}
+
+/******************************************************************************/
+
+double AbstractDiscreteDistribution::getSSupCumulativeProbability(double category) const
+{
+  double prob = 0;
+  map<double, double>::const_iterator it = distribution_.find(category);
+  for (map<double, double>::const_iterator i = distribution_.begin();
+       i != it;
+       i++)
+  {
+    prob += i->second;
+  }
+  return 1. - prob;
+}
+
+/******************************************************************************/
+
+void AbstractDiscreteDistribution::print(OutputStream& out) const
+{
+  for (map<double, double>::const_iterator i = distribution_.begin(); i != distribution_.end(); i++)
+  {
+    (out << "Pr(" << (i->first) << ") = " << (i->second)).endLine();
+  }
+}
+
+/******************************************************************************/
+
+double AbstractDiscreteDistribution::getValueCategory(double value) const
+{
+  if (!(intMinMax_.isCorrect(value)))
+    throw Exception("AbstractDiscreteDistribution::getValueCategory out of bounds:" + TextTools::toString(value));
+
+  map<double, double>::const_iterator it = distribution_.begin();
+  for (unsigned int i=1;i<bounds_.size();i++)
+    if (value<bounds_[i])
+      break;
+    else
+      it++;
+
+  return it->first;
+}
+
+/***********************************************************************/
+
+
+void AbstractDiscreteDistribution::discretize()
+{
+  /* discretization of distribution with equal proportions in each
+     category
+   */
+
+  distribution_.clear();
+  bounds_.resize(numberOfCategories_ - 1);
+
+  double minX = pProb(intMinMax_.getLowerBound());
+  double maxX = pProb(intMinMax_.getUpperBound());
+
+  double ec;
+  size_t i;
+  vector<double> values(numberOfCategories_);
+
+  if (maxX != minX)
+  {
+    // divide the domain into equiprobable intervals
+    ec = (maxX - minX) / static_cast<double>(numberOfCategories_);
+
+    for (i = 1; i < numberOfCategories_; i++)
+    {
+      bounds_[i-1] = qProb(minX + static_cast<double>(i) * ec);
+    }
+
+    // for each category, sets the value v as the median, adjusted
+    //      such that the sum of the values = 1
+    if (median_)
+    {
+      double t=0;
+      for (i = 0; i < numberOfCategories_; i++)
+        values[i] = qProb(minX + (static_cast<double>(i) + 0.5) * ec);
+
+      for (i = 0, t = 0; i < numberOfCategories_; i++)
+        t += values[i];
+
+      double mean = Expectation(intMinMax_.getUpperBound()) - Expectation(intMinMax_.getLowerBound());
+
+      for (i = 0; i < numberOfCategories_; i++)
+        values[i] *= mean / t / ec;
+    }
+    else
+      // for each category, sets the value v such that
+      //      v * length_of_the_interval = the surface of the category
+      {
+      double a = Expectation(intMinMax_.getLowerBound()), b;
+      for (i = 0; i < numberOfCategories_-1; i++)
+        {
+          b = Expectation(bounds_[i]);
+          values[i] = (b - a) / ec;
+          a = b;
+        }
+      values[numberOfCategories_-1] = (Expectation(intMinMax_.getUpperBound())-a) / ec;
+    }
+  }
+  else 
+    // if maxX==minX, uniform discretization of the range
+  {
+    ec = (intMinMax_.getUpperBound() - intMinMax_.getLowerBound()) / static_cast<double>(numberOfCategories_);
+    for (i = 1; i < numberOfCategories_; i++)
+      bounds_[i-1] = intMinMax_.getLowerBound() + static_cast<double>(i) * ec;
+
+    values[0] = (intMinMax_.getLowerBound() + bounds_[0]) / 2;
+    
+    for (i = 1; i < numberOfCategories_-1; i++)
+      values[i] = (bounds_[i-1] + bounds_[i]) / 2;
+
+    values[numberOfCategories_-1] = (intMinMax_.getUpperBound()+bounds_[numberOfCategories_ - 1]) / 2;
+  }
+
+  // adjustments near the boundaries of the domain, according to the precision chosen
+  if (intMinMax_.strictLowerBound())
+  {
+    for (i = 0; i < numberOfCategories_; i++)
+    {
+      if (values[i] < intMinMax_.getLowerBound() + precision())
+        values[i] = intMinMax_.getLowerBound() + precision();
+      else
+        break;
+    }
+  }
+  else
+  {
+    for (i = 0; i < numberOfCategories_; i++)
+    {
+      if (values[i] < intMinMax_.getLowerBound())
+        values[i] = intMinMax_.getLowerBound() + precision();
+      else
+        break;
+    }
+  }
+
+  if (intMinMax_.strictUpperBound())
+  {
+    for (i = numberOfCategories_; i > 0; i--)
+    {
+      if (values[i-1] > intMinMax_.getUpperBound() - precision())
+        values[i-1] = intMinMax_.getUpperBound() - precision();
+      else
+        break;
+    }
+  }
+  else
+  {
+    for (i = numberOfCategories_; i > 0; i--)
+    {
+      if (values[i-1] > intMinMax_.getUpperBound())
+        values[i-1] = intMinMax_.getUpperBound() - precision();
+      else
+        break;
+    }
+  }
+
+  // now the distribution_ map, taking care that all values are different
+  
+  double p = 1. / static_cast<double>(numberOfCategories_);
+  for (i = 0; i < numberOfCategories_; i++)
+  {
+    if (distribution_.find(values[i]) != distribution_.end())
+    {
+      unsigned int j = 1;
+      int f = ((values[i] + NumConstants::TINY()) >= intMinMax_.getUpperBound()) ? -1 : 1;
+      while (distribution_.find(values[i] + f * j * precision()) != distribution_.end())
+      {
+        j++;
+        f = ((values[i] + f * j * precision()) >= intMinMax_.getUpperBound()) ? -1 : 1;
+      }
+      distribution_[values[i] + f * j * precision()] = p;
+    }
+    else
+      distribution_[values[i]] = p;
+  }
+
+  return;
+}
+
+Vdouble AbstractDiscreteDistribution::getBounds() const
+{
+  Vdouble vb(numberOfCategories_ + 1);
+  vb[0] = getLowerBound();
+  for (unsigned int i = 0; i < numberOfCategories_ - 1; i++)
+    vb[i + 1] = getBound(i);
+  vb[numberOfCategories_] = getUpperBound();
+  return vb;
+}
+
+void AbstractDiscreteDistribution::restrictToConstraint(const Constraint& c)
+{
+  const IntervalConstraint* pi = dynamic_cast<const IntervalConstraint*>(&c);
+
+  if (!pi)
+    throw Exception("AbstractDiscreteDistribution::restrictToConstraint: the constraint is not an interval");
+
+  if (!(intMinMax_ <= (*pi)))
+  {
+    intMinMax_ &= c;
+    discretize();
+  }
+}
diff --git a/src/Bpp/Numeric/Prob/AbstractDiscreteDistribution.h b/src/Bpp/Numeric/Prob/AbstractDiscreteDistribution.h
new file mode 100644
index 0000000..64b90e4
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/AbstractDiscreteDistribution.h
@@ -0,0 +1,246 @@
+//
+// File: AbstractDiscreteDistribution.h
+// Created by: Julien Dutheil
+// Created on: ?
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _ABSTRACTDISCRETEDISTRIBUTION_H_
+#define _ABSTRACTDISCRETEDISTRIBUTION_H_
+
+#include "DiscreteDistribution.h"
+#include "../Constraints.h"
+#include "../AbstractParameterAliasable.h"
+
+#include <map>
+
+namespace bpp
+{
+
+  /**
+   * @brief Partial implementation of the DiscreteDistribution interface.
+   *
+   * This class uses a map to store the cateogry values as keys and probabilities as values.
+   * It uses its own comparator class to deal with double precision.
+   * By default, category values that differ less than 10E-9 will be considered identical.
+   */
+  class AbstractDiscreteDistribution :
+    public virtual DiscreteDistribution,
+    public virtual AbstractParameterAliasable
+  {
+
+  public:
+    
+    /**
+     * @brief Comparator class for AbstractDiscreteDistribution.
+     */
+    class Order
+    {
+    private:
+      double precision_;
+      
+    public:
+
+      Order(double prec=NumConstants::TINY()):
+        precision_(prec)
+      {}
+
+      Order(const Order& ord) :
+        precision_(ord.precision_)
+      {}
+
+      Order& operator=(const Order& ord)
+      {
+        precision_=ord.precision_;
+        return *this;
+      }
+
+      double precision() const {
+        return precision_;
+      }
+
+      void setPrecision(double prec) {
+        precision_=prec;
+      }
+      
+      bool operator() (double l1, double l2) const
+      {
+        return (l1 < l2 - precision_); 
+      }
+
+    };
+
+  protected:
+
+    /*
+     * The number of categories
+     */
+
+    size_t numberOfCategories_;  
+    /**
+     * These fields must be initialized in the constructor of the derived classes.
+     */
+    std::map<double, double, Order> distribution_;
+    
+    std::vector<double> bounds_;
+
+    /**
+     * @brief the interval where the distribution is defined/restricted.
+     *
+     */
+    
+    IntervalConstraint intMinMax_;    
+
+    /**
+     * Tells if the values in the classes is associated to the median or not (default: false)
+     *
+     */
+
+    bool median_;
+    
+  public:
+    AbstractDiscreteDistribution(size_t nbClasses, const std::string& prefix = ""); 
+
+    /**
+     * With additional precision value to discriminate categories (default 1e-12)
+     *
+     */
+    AbstractDiscreteDistribution(size_t nbClasses, double precision, const std::string& prefix = "");
+    
+    AbstractDiscreteDistribution(const AbstractDiscreteDistribution& adde);
+
+    AbstractDiscreteDistribution& operator=(const AbstractDiscreteDistribution& adde);
+    
+    virtual ~AbstractDiscreteDistribution() {}
+
+    
+  public:
+
+    /**
+     * @name The DiscreteDistribution interface.
+     *
+     * @{
+     */
+    size_t getNumberOfCategories() const;
+    void setNumberOfCategories(size_t nbClasses);
+    double getCategory(size_t categoryIndex) const;
+    double getProbability(size_t categoryIndex) const;
+    double getProbability(double category) const;
+    Vdouble getCategories() const;
+    Vdouble getProbabilities() const;
+    double getValueCategory(double value) const;
+    void set(double category, double probability);
+    void add(double category, double probability);
+    double getInfCumulativeProbability(double category) const;
+    double getIInfCumulativeProbability(double category) const;
+    double getSupCumulativeProbability(double category) const;
+    double getSSupCumulativeProbability(double category) const;
+    double rand() const;
+    double randC() const throw (Exception) { throw Exception("AbstractDiscreteDistribution::randC. No continuous version available for this distribution."); }
+
+    /*
+     *@return value of the internal bound
+     *
+     */
+    
+    double getBound(size_t i) const throw (IndexOutOfBoundsException)
+    {
+      if (i >= numberOfCategories_ - 1)
+        throw IndexOutOfBoundsException("AbstractDiscreteDistribution::getBound(i)", i , 0, numberOfCategories_-1);
+      return bounds_[i];
+    }  
+
+
+    /*
+     *@brief Information about the range of the distribution
+     *
+     */
+     
+
+    double getLowerBound() const
+    {
+      return intMinMax_.getLowerBound();
+    }
+
+    double getUpperBound() const
+    {
+      return intMinMax_.getUpperBound();
+    }
+
+    bool strictLowerBound() const
+    {
+      return intMinMax_.strictLowerBound();
+    }
+
+    bool strictUpperBound() const
+    {
+      return intMinMax_.strictUpperBound();
+    }
+
+    Vdouble getBounds() const;
+    
+    void print(OutputStream& out) const;
+
+    double precision() const { return distribution_.key_comp().precision();}
+      
+    void setMedian(bool median) {
+      if (median_ != median) {
+        median_ = median;
+        discretize();
+      }
+    }
+    
+    virtual void discretize();
+
+    /** @} */
+
+    /**
+     * @brief Restricts the distribution to the domain where the
+     * constraint is respected, in addition of other predefined
+     * constraints.
+     *
+     * @param c The Constraint to respect.
+     *
+     */
+    
+    virtual void restrictToConstraint(const Constraint& c);
+      
+
+  };
+
+} //end of namespace bpp.
+
+#endif  //_ABSTRACTDISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/BetaDiscreteDistribution.cpp b/src/Bpp/Numeric/Prob/BetaDiscreteDistribution.cpp
new file mode 100644
index 0000000..dc4d0f6
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/BetaDiscreteDistribution.cpp
@@ -0,0 +1,122 @@
+//
+// File: BetaDiscreteDistribution.cpp
+// Created by: Laurent Guéguen
+// Created on: lundi 31 mai 2010, à 11h 15
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "BetaDiscreteDistribution.h"
+#include "../Random/RandomTools.h"
+#include "../NumConstants.h"
+#include "../../Utils/MapTools.h"
+
+using namespace bpp;
+
+// From the STL:
+#include <cmath>
+
+using namespace std;
+
+/** Constructor: **************************************************************/
+
+BetaDiscreteDistribution::BetaDiscreteDistribution(size_t n, double alpha, double beta) :
+  AbstractParameterAliasable("Beta."),
+  AbstractDiscreteDistribution(n,NumConstants::VERY_TINY(),"Beta."), alpha_(alpha), beta_(beta), diffln_(0)
+{
+  addParameter_(new Parameter("Beta.alpha", alpha, new IntervalConstraint(1, 0.0001, true), true));
+
+  // For precision issues, beta cannot be too low
+  addParameter_(new Parameter("Beta.beta", beta, new IntervalConstraint(1, 0.1, true), true));
+  intMinMax_.setLowerBound(0, true);
+  intMinMax_.setUpperBound(1, true);
+
+  diffln_ = exp(RandomTools::lnBeta(alpha_ + 1, beta_) - RandomTools::lnBeta(alpha_, beta_));
+  discretize();
+}
+
+BetaDiscreteDistribution::BetaDiscreteDistribution(const BetaDiscreteDistribution& bdd) :
+  AbstractParameterAliasable(bdd),
+  AbstractDiscreteDistribution(bdd), alpha_(bdd.alpha_), beta_(bdd.beta_), diffln_(bdd.diffln_)
+{
+}
+
+BetaDiscreteDistribution& BetaDiscreteDistribution::operator=(const BetaDiscreteDistribution& bdd)
+{
+  AbstractParameterAliasable::operator=(bdd);
+  AbstractDiscreteDistribution::operator=(bdd);
+
+  alpha_=bdd.alpha_;
+  beta_=bdd.beta_;
+  diffln_=bdd.diffln_;
+  
+  return *this;
+}
+  
+/******************************************************************************/
+
+void BetaDiscreteDistribution::fireParameterChanged(const ParameterList& parameters)
+{
+  AbstractDiscreteDistribution::fireParameterChanged(parameters);
+  alpha_=getParameterValue("alpha");
+  beta_=getParameterValue("beta");
+
+  if (alpha_<=1 && intMinMax_.getLowerBound()==0)
+    intMinMax_.setLowerBound(precision(),false);
+
+  if (beta_<=1 && intMinMax_.getUpperBound()==1)
+    intMinMax_.setUpperBound(1-precision(),false);
+
+  diffln_=exp(RandomTools::lnBeta(alpha_+1,beta_)-RandomTools::lnBeta(alpha_,beta_));
+  discretize();
+}
+
+/******************************************************************************/
+
+double BetaDiscreteDistribution::qProb(double x) const
+{
+  return RandomTools::qBeta(x, alpha_, beta_);
+}
+
+double BetaDiscreteDistribution::pProb(double x) const 
+{
+  return RandomTools::pBeta(x, alpha_, beta_);
+}
+
+double BetaDiscreteDistribution::Expectation(double a) const
+{
+  return RandomTools::pBeta(a,alpha_+1,beta_)*diffln_;
+}
+
+    
diff --git a/src/Bpp/Numeric/Prob/BetaDiscreteDistribution.h b/src/Bpp/Numeric/Prob/BetaDiscreteDistribution.h
new file mode 100644
index 0000000..c4e66d3
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/BetaDiscreteDistribution.h
@@ -0,0 +1,117 @@
+//
+// File: BetaDiscreteDistribution.h
+// Created by: Laurent Guéguen
+// Created on: jeudi 27 mai 2010, à 23h 34
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _BETADISCRETEDISTRIBUTION_H_
+#define _BETADISCRETEDISTRIBUTION_H_
+
+#include "AbstractDiscreteDistribution.h"
+#include "../Random/RandomTools.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Discretized Beta distribution with parameters alpha and
+   * beta, on a given interval. On default, the interval is @f$ [0;1]
+   * @f$, but it can be restricted.
+   *
+   * The minimum (resp maximum) value of this distribution is set to
+   * 1e-12 (resp 1-1e-12) if alpha>1 (resp beta>1), otherwise it is 0
+   * (resp 1).
+   *
+   * The Parameters are: alpha and beta @f$ \in [0.0001;\infty[ @f$.
+   * @author Laurent Guéguen
+   */
+  
+  class BetaDiscreteDistribution:
+    public AbstractDiscreteDistribution
+  {
+  private:
+
+    double alpha_, beta_;
+
+    /* for computation economy */
+       
+    double diffln_;
+  public:
+    /**
+     * @brief Build a new discretized beta distribution.
+     *
+     * @param n the number of categories to use.
+     * @param alpha The alpha parameter.
+     * @param beta The beta parameter.
+     *
+     */
+    
+    BetaDiscreteDistribution(size_t n, double alpha = 1, double beta = 1);
+
+    BetaDiscreteDistribution(const BetaDiscreteDistribution&);
+
+    BetaDiscreteDistribution& operator=(const BetaDiscreteDistribution&);
+    
+    BetaDiscreteDistribution* clone() const { return new BetaDiscreteDistribution(*this); }
+  
+  public:
+
+    std::string getName() const { return "Beta";}
+
+    void fireParameterChanged(const ParameterList & parameters);
+  
+    double randC() const throw (Exception)
+    {
+      double x= RandomTools::randBeta(getParameterValue("alpha"),
+                                      getParameterValue("beta"));
+      while (!intMinMax_.isCorrect(x))
+        x= RandomTools::randBeta(getParameterValue("alpha"),
+                                 getParameterValue("beta"));
+      return x;
+    }
+
+    double qProb(double x) const;
+     
+    double pProb(double x) const;
+
+    double Expectation(double a) const;
+
+  };
+
+} //end of namespace bpp.
+
+#endif  //_BETADISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/ConstantDistribution.cpp b/src/Bpp/Numeric/Prob/ConstantDistribution.cpp
new file mode 100644
index 0000000..5dc0cd5
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/ConstantDistribution.cpp
@@ -0,0 +1,105 @@
+//
+// File: ConstantDistribution.cpp
+// Created by: jdutheil 
+// Created on: Fri Oct 24 08:48:03 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "ConstantDistribution.h"
+
+using namespace bpp;
+
+#include <iostream>
+
+using namespace std;
+
+/******************************************************************************/
+
+ConstantDistribution::ConstantDistribution(double value):
+  AbstractParameterAliasable("Constant."),
+  AbstractDiscreteDistribution(1, "Constant."),
+  value_(value)
+{
+  addParameter_(new Parameter("Constant.value", value)); 
+  distribution_[value_] = 1; //One single class  with probability 1.
+}
+
+ConstantDistribution::ConstantDistribution(const ConstantDistribution& cd) :
+  AbstractParameterAliasable(cd),
+  AbstractDiscreteDistribution(cd),
+  value_(cd.value_)
+{}
+
+ConstantDistribution& ConstantDistribution::operator=(const ConstantDistribution& cd)
+{
+  AbstractParameterAliasable::operator=(cd);
+  AbstractDiscreteDistribution::operator=(cd);
+  value_=cd.value_;
+
+  return *this;
+}
+
+/******************************************************************************/
+
+void ConstantDistribution::fireParameterChanged(const ParameterList& parameters) 
+{
+  AbstractDiscreteDistribution::fireParameterChanged(parameters);
+  
+  if (hasParameter("value")) {
+    value_=getParameterValue("value");
+    distribution_.clear();
+    distribution_[value_] = 1; //One single class of rate 1 with probability 1.
+  }
+}
+
+/******************************************************************************/
+
+void ConstantDistribution::restrictToConstraint(const Constraint& c)
+{
+  if (getNumberOfParameters()==0)
+    return;
+  
+  const IntervalConstraint* pi=dynamic_cast<const IntervalConstraint*>(&c);
+  if (!pi)
+    throw Exception("ConstantDistribution::restrictToConstraint: Non-interval exception");
+
+  if (! pi->isCorrect(getParameterValue("value")))
+    throw ConstraintException("Impossible to restrict to Constraint", &getParameter_("value"), getParameterValue("value"));
+
+  AbstractDiscreteDistribution::restrictToConstraint(c);
+
+  Parameter& p=getParameter_("value");
+  p.setConstraint(intMinMax_.clone(),true);
+}
diff --git a/src/Bpp/Numeric/Prob/ConstantDistribution.h b/src/Bpp/Numeric/Prob/ConstantDistribution.h
new file mode 100644
index 0000000..aa7cbcc
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/ConstantDistribution.h
@@ -0,0 +1,107 @@
+//
+// File: ConstantDistribution.h
+// Created by: jdutheil
+// Created on: Fri Oct 24 08:48:03 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _CONSTANTDISTRIBUTION_H_
+#define _CONSTANTDISTRIBUTION_H_
+
+#include "AbstractDiscreteDistribution.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Constant discrete distribution.
+   *
+   * Only one category with probability 1.0.
+   */
+  class ConstantDistribution :
+    public AbstractDiscreteDistribution
+  {
+  
+  private:
+    double value_;
+  
+  public:
+    /**
+     * @brief Builds a new ConstantDistribution object from a
+     *  value
+     *
+     * @param value The value of the distribution.
+     *
+     */
+    ConstantDistribution(double value);
+
+    ConstantDistribution(const ConstantDistribution&);
+
+    ConstantDistribution& operator=(const ConstantDistribution&);
+    
+    virtual ~ConstantDistribution() {}
+  
+    ConstantDistribution* clone() const
+    {
+      return new ConstantDistribution(*this);
+    }
+  
+  public:
+    void fireParameterChanged(const ParameterList& parameters);
+    
+    double randC() const throw (Exception) { return value_; }
+
+    std::string getName() const { return("Constant"); }
+
+    double getLowerBound() const { return value_; }
+                               
+    double getUpperBound() const { return value_; }
+
+    double qProb(double x) const { return (x >= 1) ? value_ : -NumConstants::VERY_BIG(); }
+     
+    double pProb(double x) const { return x < value_ ? 0 : 1; }
+                                
+    double Expectation(double a) const { return a < value_ ? 0 : 1; }
+
+    void restrictToConstraint(const Constraint& c);
+
+    void discretize() {}
+
+  };
+  
+} //end of namespace bpp.
+
+#endif  //_CONSTANTDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/DirichletDiscreteDistribution.cpp b/src/Bpp/Numeric/Prob/DirichletDiscreteDistribution.cpp
new file mode 100644
index 0000000..d43f6fe
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/DirichletDiscreteDistribution.cpp
@@ -0,0 +1,282 @@
+//
+// File: BetaDiscreteDistribution.cpp
+// Created by: Laurent Guéguen
+// Created on: jeudi 2 septembre 2010, à 17h 03
+//
+
+/*
+   Copyright or © or Copr. CNRS, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "DirichletDiscreteDistribution.h"
+#include "BetaDiscreteDistribution.h"
+#include "../Random/RandomTools.h"
+#include "../NumConstants.h"
+#include "../../Text/TextTools.h"
+
+using namespace bpp;
+
+// From the STL:
+#include <cmath>
+
+using namespace std;
+
+/** Constructor: **************************************************************/
+
+DirichletDiscreteDistribution::DirichletDiscreteDistribution(vector<size_t> vn, Vdouble valpha) :
+  AbstractParameterAliasable("Dirichlet."),
+  vpBDD_()
+{
+  if (vn.size() <= 0 || vn.size() != valpha.size() - 1)
+    throw Exception("Wrong number of categories for Dirichlet distribution: " + TextTools::toString(vn.size()));
+
+  for (size_t j = 0; j < valpha.size(); j++)
+  {
+    addParameter_(new Parameter("Dirichlet.alpha_" + TextTools::toString(j + 1), valpha[j], new IntervalConstraint(1, 0.0001, true), true));
+  }
+
+  for (size_t j = 0; j < vn.size(); j++)
+  {
+    if (vn[j] <= 0)
+      throw Exception("Wrong number of categories in Dirichlet distribution constructor: " + TextTools::toString(vn[j]));
+  }
+
+  for (size_t j = 0; j < vn.size(); j++)
+  {
+    vpBDD_.push_back(new BetaDiscreteDistribution(vn[j], 1, 1));
+  }
+
+  discretize(valpha);
+}
+
+DirichletDiscreteDistribution::~DirichletDiscreteDistribution()
+{
+  for (unsigned int i = 0; i < vpBDD_.size(); i++)
+  {
+    delete vpBDD_[i];
+  }
+}
+
+/******************************************************************************/
+
+void DirichletDiscreteDistribution::fireParameterChanged(const ParameterList& parameters)
+{
+  AbstractParameterAliasable::fireParameterChanged(parameters);
+  applyParameters();
+}
+
+/******************************************************************************/
+
+void DirichletDiscreteDistribution::applyParameters()
+{
+  Vdouble valpha;
+
+  for (unsigned int j = 0; j < vpBDD_.size() + 1; j++)
+  {
+    valpha.push_back(getParameterValue("alpha_" + TextTools::toString(j + 1)));
+  }
+
+  discretize(valpha);
+}
+
+/******************************************************************************/
+
+void DirichletDiscreteDistribution::discretize(Vdouble& valpha)
+{
+  /* discretization of Dirichlet distribution with equal proportions in
+     each category */
+
+  double x;
+  ParameterList pL;
+  pL.addParameter(Parameter("Beta.alpha", 1));
+  pL.addParameter(Parameter("Beta.beta", 1));
+  for (unsigned int j = 0; j < vpBDD_.size(); j++)
+  {
+    x = 0;
+    for (unsigned int i = j + 1; i < valpha.size(); i++)
+    {
+      x += valpha[i];
+    }
+
+    pL.setParameterValue("Beta.alpha", valpha[j]);
+    pL.setParameterValue("Beta.beta", x);
+
+    vpBDD_[j]->matchParametersValues(pL);
+  }
+}
+
+
+/******************************************************************************/
+
+size_t DirichletDiscreteDistribution::getNumberOfCategories() const
+{
+  size_t n = 1;
+
+  for (size_t j = 0; j < vpBDD_.size(); j++)
+  {
+    n *= vpBDD_[j]->getNumberOfCategories();
+  }
+
+  return n;
+}
+
+/******************************************************************************/
+
+Vdouble DirichletDiscreteDistribution::getValueCategory(Vdouble& value) const
+{
+  if (value.size() != vpBDD_.size() + 1)
+    throw Exception("Bad Vdouble parameter in DirichletDiscreteDistribution::getValueCategory");
+
+  Vdouble vd;
+  double y, sumc = 0;
+
+  for (size_t j = 0; j < vpBDD_.size(); j++)
+  {
+    if (1 - sumc < NumConstants::VERY_TINY())
+      y = vpBDD_[j]->getValueCategory(NumConstants::VERY_TINY());
+    else
+      y = vpBDD_[j]->getValueCategory(value[j] / (1 - sumc)) * (1 - sumc);
+    sumc += y;
+    vd.push_back(y);
+  }
+  vd.push_back(1 - sumc);
+  return vd;
+}
+
+/******************************************************************************/
+
+double DirichletDiscreteDistribution::getProbability(Vdouble& category) const
+{
+  if (category.size() != vpBDD_.size() + 1)
+    throw Exception("Bad Vdouble parameter in DirichletDiscreteDistribution::getProbability");
+
+  double sumc = 0;
+  double p = 1;
+
+  for (unsigned int j = 0; j < vpBDD_.size(); j++)
+  {
+    p *= vpBDD_[j]->getProbability(category[j] / (1 - sumc));
+    sumc += category[j];
+  }
+  return p;
+}
+
+/******************************************************************************/
+
+VVdouble DirichletDiscreteDistribution::getCategories() const
+{
+  VVdouble vvd1, vvd2;
+  Vdouble vdj, vd;
+  double sumc = 0;
+
+  vdj = vpBDD_[0]->getCategories();
+  for (unsigned int k = 0; k < vdj.size(); k++)
+  {
+    vd.push_back(vdj[k]);
+    vvd1.push_back(vd);
+    vd.pop_back();
+  }
+
+  for (unsigned int j = 1; j < vpBDD_.size(); j++)
+  {
+    vdj = vpBDD_[j]->getCategories();
+    vvd2.clear();
+    for (unsigned int i = 0; i < vvd1.size(); i++)
+    {
+      vd = vvd1[i];
+      sumc = 0;
+      for (unsigned int k = 0; k < vd.size(); k++)
+      {
+        sumc += vd[k];
+      }
+      for (unsigned int k = 0; k < vdj.size(); k++)
+      {
+        vd.push_back(vdj[k] * (1 - sumc));
+        vvd2.push_back(vd);
+        vd.pop_back();
+      }
+    }
+    vvd1 = vvd2;
+  }
+
+  vvd2.clear();
+  for (unsigned int i = 0; i < vvd1.size(); i++)
+  {
+    vd = vvd1[i];
+    sumc = 0;
+    for (unsigned int k = 0; k < vd.size(); k++)
+    {
+      sumc += vd[k];
+    }
+    vd.push_back(1 - sumc);
+    vvd2.push_back(vd);
+  }
+
+  return vvd2;
+}
+
+/******************************************************************************/
+
+Vdouble DirichletDiscreteDistribution::rand() const
+{
+  Vdouble vd;
+  double x, sumc = 0;
+  for (unsigned int j = 0; j < vpBDD_.size(); j++)
+  {
+    x = vpBDD_[j]->rand() * (1 - sumc);
+    sumc += x;
+    vd.push_back(x);
+  }
+
+  vd.push_back(1 - sumc);
+  return vd;
+}
+
+/******************************************************************************/
+
+Vdouble DirichletDiscreteDistribution::randC() const
+{
+  Vdouble vd;
+  double x, sumc = 0;
+  for (unsigned int j = 0; j < vpBDD_.size(); j++)
+  {
+    x = vpBDD_[j]->randC() * (1 - sumc);
+    sumc += x;
+    vd.push_back(x);
+  }
+
+  vd.push_back(1 - sumc);
+  return vd;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Prob/DirichletDiscreteDistribution.h b/src/Bpp/Numeric/Prob/DirichletDiscreteDistribution.h
new file mode 100644
index 0000000..959c3ec
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/DirichletDiscreteDistribution.h
@@ -0,0 +1,178 @@
+//
+// File: DirichletDiscreteDistribution.h
+// Created by: Laurent Guéguen
+// Created on: jeudi 2 septembre 2010, à 17h 03
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#ifndef _DIRICHLETDISCRETEDISTRIBUTION_H_
+#define _DIRICHLETDISCRETEDISTRIBUTION_H_
+
+#include "MultipleDiscreteDistribution.h"
+#include "BetaDiscreteDistribution.h"
+#include "../VectorTools.h"
+#include "../ParameterAliasable.h"
+#include "../../Exceptions.h"
+#include "../../Io/OutputStream.h"
+
+namespace bpp
+{
+/**
+ * @brief Discretized Dirichlet distribution. If the distribution is
+ * in n dimensions, the domain is the n-1 simplex.
+ *
+ * The discretization is made in the order of these dimensions. Then
+ * the order of the dimensions is not neutral on the resulting
+ * categories.
+ *
+ * Here is an example of the discretization process: if the
+ * distribution is in 3 dimensions, and the number of categories is
+ * 4 in the first dimension, 3 in the second and 5 in the third, the
+ * first interval is split in 4 equi-probable intervals, and each
+ * interval is split on the second dimension in 3 equi-probable
+ * intervals, and each of the 12 resulting 2D intervals is split in
+ * 5 equi-probable 3D-intervals. Eventually, there are 60
+ * equi-probable categories.
+ *
+ * In the same example, if the distribution is followed by the
+ * random vector @f$ (X_1,X_2,X_3) @f$, the 1D distribution used for
+ * @f$ X_1 @f$ is the marginal distribution, which discretized
+ * values are say, @f$ v_1^1, v_1^2, v_1^3, v_1^4 @f$, then the four
+ * 1D distributions used for @f$ X_2 @f$ are the conditional
+ * marginal distributions @f$ (X_2|X_1=v_1^1), (X_2|X_1=v_1^2),
+ * (X_2|X_1=v_1^3), (X_2|X_1=v_1^4) @f$. And in a similar way for
+ * @f$ X_3 @f$, with the 12 resulting conditions on @f$ X_1 @f$ and
+ * @f$ X_2 @f$.
+ *
+ *
+ * It uses the AbstractDiscreteDistribution comparator class to deal
+ * with double precision. By default, category values that differ
+ * less than 10E-9 will be considered identical.
+ *
+ *
+ * The successive discretization process is done using the
+ * distributions, if the parameters are @f$ (\alpha_1, ...,
+ * \alpha_n)@f$:
+ *
+ * @f$ X_1 @f$ follows Beta(@f$ \alpha_1, \sum_{i=2}^n \alpha_i @f$).
+ *
+ * @f$ X_j @f$ follows @f$ (1-\sum_{i=1}^{j-1} X_i) @f$ *
+ * Beta(@f$ \alpha_j, \sum_{i=j+1}^n \alpha_i @f$).
+ *
+ * @f$ X_n = 1 - \sum_{i=1}^{n-1} X_i @f$.
+ *
+ *
+ * The parameters are: alpha_1, ... alpha_n @f$ \in [0.0001;\infty[
+ * @f$.
+ */
+
+class DirichletDiscreteDistribution :
+  public MultipleDiscreteDistribution,
+  public AbstractParameterAliasable
+{
+private:
+  std::vector<BetaDiscreteDistribution* > vpBDD_;
+
+public:
+  /**
+   * @brief Build a new discretized Dirichlet distribution
+   *
+   * @param vn the vector of the dim-1 numbers of categories to use.
+   * @param valpha the vector of the dim alpha parameters.
+   */
+  DirichletDiscreteDistribution(std::vector<size_t> vn, Vdouble valpha);
+
+  ~DirichletDiscreteDistribution();
+
+  DirichletDiscreteDistribution* clone() const
+  {
+    return new DirichletDiscreteDistribution(*this);
+  }
+
+protected:
+  void applyParameters();
+
+public:
+  std::string getName() const {return("Dirichlet");}
+  
+  void fireParameterChanged(const ParameterList& parameters);
+
+  /**
+   * @return The number of categories
+   */
+  size_t getNumberOfCategories() const;
+
+  /**
+   * @param Vvalue
+   * @return The vector of categoryIndex of the classes the value is
+   * in. Throws a ConstraintException if the value is off the domain
+   * of the DirichletDiscreteDistribution.
+   */
+  Vdouble getValueCategory(Vdouble& Vvalue) const;
+
+  VVdouble getCategories() const;
+
+  /**
+   * @param category The vector of values associated to the class.
+   * @return The probability associated to a given class.
+   */
+  virtual double getProbability(Vdouble& category) const;
+
+  /**
+   * @brief Draw a random vector from this distribution.
+   *
+   * This vector will be one of the class values, drawn according
+   * to the class probabilities.
+   *
+   * @return A random number according to this distribution.
+   */
+
+  Vdouble rand() const;
+
+  /**
+   * @brief Draw a random vector from the continuous version of this
+   * distribution.
+   *
+   * @return A random vector according to this distribution.
+   */
+  Vdouble randC() const;
+
+protected:
+  void discretize(Vdouble& valpha);
+};
+} // end of namespace bpp.
+
+#endif  // _DIRICHLETDISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/DiscreteDistribution.h b/src/Bpp/Numeric/Prob/DiscreteDistribution.h
new file mode 100644
index 0000000..fa0fe1c
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/DiscreteDistribution.h
@@ -0,0 +1,322 @@
+//
+// File: DiscreteDistribution.h
+// Created by: Julien Dutheil
+// Created on: ?
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _DISCRETEDISTRIBUTION_H_
+#define _DISCRETEDISTRIBUTION_H_
+
+#include "../VectorTools.h"
+#include "../ParameterAliasable.h"
+#include "../NumConstants.h"
+#include "../../Exceptions.h"
+#include "../../Io/OutputStream.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Interface for discrete distribution objects.
+   *
+   * A discrete distribution usually contains a finite set of
+   * categories and a probability associated to each.
+   * 
+   * Each category (or class) is defined by two bounds, and sometimes by
+   * a mean or a median value.
+   *
+   * A discrete distribution may contain one or several parameters.
+   * The probabilities associated to each class usually depends on
+   * the parameter values.
+   * In some cases, the number and/or bounds of the classes may also 
+   * depend on the parameters values, depending on the kind of
+   * discretization used.
+   */
+  class DiscreteDistribution:
+    public virtual ParameterAliasable
+  {
+  public:
+    DiscreteDistribution() {}
+    virtual ~DiscreteDistribution() {}
+
+  
+#ifndef NO_VIRTUAL_COV
+    DiscreteDistribution* clone() const = 0;
+#endif
+
+  public:
+		
+    /**
+     * @brief Get the name of the distribution.
+     *
+     * @return The name of this distribution.
+     */
+    virtual std::string getName() const = 0;
+
+    /**
+     * @return The number of categories.
+     */
+    virtual size_t getNumberOfCategories() const = 0;
+
+    
+    /**
+     * @brief sets the number of categories and discretizes if there
+     * is a change in this number.
+     */
+    
+    virtual void setNumberOfCategories(size_t nbClasses) = 0;
+		
+    /**
+     * @param value 
+     * @return The value of the category the value is in. Throws a
+     * OutOfRangeException if the value is off the domain of the
+     * DiscreteDistribution.
+     */
+    
+    virtual double getValueCategory(double value) const = 0 ;
+    
+    /**
+     * @param categoryIndex Class index.
+     * @return The value associated to a given class.
+     */
+
+    virtual double getCategory(size_t categoryIndex) const = 0;
+		
+    /**
+     * @param categoryIndex Class index.
+     * @return The probability associated to a given class.
+     */
+    virtual double getProbability(size_t categoryIndex) const = 0;
+
+    /**
+     * @param category The value associated to the class.
+     * @return The probability associated to a given class.
+     */
+    virtual double getProbability(double category) const = 0;
+
+    /**
+     * @return A vector with all classes values.
+     */
+    virtual Vdouble getCategories() const = 0;
+    /**
+     * @return A vector with all probabilities.
+     */
+    virtual Vdouble getProbabilities() const = 0;
+
+    /**
+     * @brief Set the probability associated to a class.
+     *
+     * If the category does not exist, a new category is created
+     * with the corresponding probability.
+     * If the category already exist, its probability is set to 'probability'.
+     * The sum of all probabilities is not checked.
+     * 
+     * @param category The class value.
+     * @param probability The class probability.
+     */
+    virtual void set(double category, double probability) = 0;
+		
+    /**
+     * @brief Modify the probability associated to a class.
+     *
+     * If the category does not exist, a new category is created
+     * with the corresponding probability.
+     * if the category exists, add 'probability' to the existing probability.
+     * The sum of all probabilities is not checked.
+     * 
+     * @param category The class value.
+     * @param probability The class probability.
+     */
+    virtual void add(double category, double probability) = 0;
+
+    /**
+     * @return \f$Pr(x < \mbox{category})\f$.
+     * @param category The class value.
+     */
+    virtual double getInfCumulativeProbability(double category) const = 0;
+    /**
+     * @return \f$Pr(x \leq \mbox{category})\f$.
+     * @param category The class value.
+     */
+    virtual double getIInfCumulativeProbability(double category) const = 0;
+    /**
+     * @return \f$Pr(x > \mbox{category})\f$.
+     * @param category The class value.
+     */
+    virtual double getSupCumulativeProbability(double category) const = 0;
+    /**
+     * @return \f$Pr(x \geq \mbox{category})\f$.
+     * @param category The class value.
+     */
+    virtual double getSSupCumulativeProbability(double category) const = 0;
+	
+    /**
+     * @brief Draw a random number from this distribution.
+     *
+     * This number will be one of the class values, drawn according
+     * to the class probabilities.
+     * 
+     * @return A random number according to this distribution.
+     */
+    virtual double rand() const = 0;
+
+    /**
+     * @brief Draw a random number from the continuous version of this distribution, if it exists.
+     *
+     * Uses the continuous version of this distribution to draw a random number.
+     * 
+     * @return A random number according to this distribution.
+     * @throw Exception If there is no continuous version of this distribution.
+     */
+    virtual double randC() const throw (Exception) = 0;
+
+    /**
+     * @brief Return the quantile of the continuous version of the
+     * distribution, ie y such that @f$ Prob(X<y)=x @f$
+     * 
+     **/
+     
+    virtual double qProb(double x) const  = 0;
+
+    /**
+     * @brief Return the cumulative quantile of the continuous version
+     * of the distribution, ie @f$ Prob(X<x) @f$.
+     *
+     **/
+     
+    virtual double pProb(double x) const  = 0;
+
+    /**
+     * @brief Return a primitive function used for the expectation
+     * of the continuous version of the distribution, ie
+     * @f$ E(X|...<=X<a) = \int_{...}^a t.dProb(t) dt @f$.
+     *
+     **/
+     
+    virtual double Expectation(double a) const  = 0;
+
+    /**
+     *@brief Sets the median value to true to say that the value in a
+     * class is proportional to the median value of the class, the
+     * proportionality factor being such that the sum of the values
+     * equals the expectation of the distribution. If it is set to
+     * false, the value is the mean value in the class.
+     *
+     * If the median value is modified, the discretization process is
+     * launched.
+     *
+     * @param median tells how the value associated to each class is
+     * computed. 
+     */
+    
+    virtual void setMedian(bool median) = 0;
+    
+    /**
+     * @brief Discretizes the distribution in equiprobable classes.
+     */
+
+    virtual void discretize() = 0;
+
+    /**
+     *@return A vector of all the bounds
+     */
+    virtual Vdouble getBounds() const = 0;
+    
+    /**
+     * @return the i th internal bound
+     */
+    virtual double getBound(size_t) const = 0;
+
+    /**
+     *@brief methods about the range of the definition
+     *
+     **/
+     
+    /**
+     * @return The lowest value.
+     */
+    virtual double getLowerBound() const {
+      return (-NumConstants::VERY_BIG());
+    }
+  
+    /**
+     * @return The highest value.
+     */
+    virtual double getUpperBound() const {
+      return (NumConstants::VERY_BIG());
+    }
+  
+    /**
+     * @return The lowest value.
+     */
+    virtual bool strictLowerBound() const {
+      return (true);
+    }
+  
+    /**
+     * @return The highest value.
+     */
+    virtual bool strictUpperBound() const {
+      return (true);
+    }
+  
+    /**
+     * @brief Restricts the distribution to the domain where the
+     * constraint is respected, in addition of other predefined
+     * constraints.
+     *
+     * If the domain interval is modified, the discretization process
+     * is launched.
+     *
+     * @param c The Constraint to respect.
+     *
+     */
+    
+    virtual void restrictToConstraint(const Constraint& c) = 0;
+          
+    /**
+     * @brief Print the distribution (categories and corresponding probabilities) to a stream.
+     *
+     * @param out The outstream where to print the distribution.
+     */
+    virtual void print(OutputStream& out) const = 0;
+
+  };
+
+} //end of namespace bpp.
+
+#endif  //_DISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/ExponentialDiscreteDistribution.cpp b/src/Bpp/Numeric/Prob/ExponentialDiscreteDistribution.cpp
new file mode 100644
index 0000000..f63c9fb
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/ExponentialDiscreteDistribution.cpp
@@ -0,0 +1,74 @@
+//
+// File: ExponentialDiscreteDistribution.cpp
+// Created by: Julien Dutheil
+// Created on: Tue Nov 13 12:37 2007
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "ExponentialDiscreteDistribution.h"
+#include "../Random/RandomTools.h"
+#include "../NumConstants.h"
+#include "../../Utils/MapTools.h"
+
+using namespace bpp;
+
+// From the STL:
+#include <cmath>
+using namespace std;
+
+/****************************************************************/
+
+ExponentialDiscreteDistribution::ExponentialDiscreteDistribution(size_t n, double lambda) :
+  AbstractParameterAliasable("Exponential."),
+  AbstractDiscreteDistribution(n, "Exponential."),
+  lambda_(lambda)
+{
+  addParameter_(new Parameter("Exponential.lambda", lambda,  &Parameter::R_PLUS));
+
+  intMinMax_.setLowerBound(0, true);
+  discretize();
+}
+
+/******************************************************************************/
+
+void ExponentialDiscreteDistribution::fireParameterChanged(const ParameterList& parameters)
+{
+  AbstractDiscreteDistribution::fireParameterChanged(parameters);
+  lambda_ = getParameterValue("lambda");
+  discretize();
+}
+
+
+
diff --git a/src/Bpp/Numeric/Prob/ExponentialDiscreteDistribution.h b/src/Bpp/Numeric/Prob/ExponentialDiscreteDistribution.h
new file mode 100644
index 0000000..26c18ac
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/ExponentialDiscreteDistribution.h
@@ -0,0 +1,122 @@
+//
+// File: ExponentialDiscreteDistribution.h
+// Created by: Julien Dutheil
+// Created on: Tue Nov 13 12:37 2007
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#ifndef _EXPONENTIALDISCRETEDISTRIBUTION_H_
+#define _EXPONENTIALDISCRETEDISTRIBUTION_H_
+
+#include "AbstractDiscreteDistribution.h"
+#include "../Constraints.h"
+#include "../Random/RandomTools.h"
+
+namespace bpp
+{
+/**
+ * @brief Discretized Exponential distribution.
+ *
+ * @author Julien Dutheil
+ */
+class ExponentialDiscreteDistribution :
+  public AbstractDiscreteDistribution
+{
+protected:
+  double lambda_;
+
+public:
+  /**
+   * @brief Build a new discretized exponential distribution.
+   * @param n the number of categories to use.
+   * @param lambda The lambda parameter.
+   *
+   * The Parameter is: lambda @f$ \in [0;\infty[ @f$.
+   *
+   */
+
+  ExponentialDiscreteDistribution(size_t n, double lambda = 1.);
+
+  ExponentialDiscreteDistribution(const ExponentialDiscreteDistribution& dist) :
+    AbstractParameterAliasable(dist),
+    AbstractDiscreteDistribution(dist),
+    lambda_(dist.lambda_)
+  {}
+
+  ExponentialDiscreteDistribution& operator=(const ExponentialDiscreteDistribution& dist)
+  {
+    AbstractParameterAliasable::operator=(dist);    
+    AbstractDiscreteDistribution::operator=(dist);
+    lambda_ = dist.lambda_;
+    return *this;
+  }
+
+  ~ExponentialDiscreteDistribution(){};
+
+  ExponentialDiscreteDistribution* clone() const { return new ExponentialDiscreteDistribution(*this); }
+
+public:
+  std::string getName() const {return("Exponential");}
+  
+  void fireParameterChanged(const ParameterList& parameters);
+
+  double randC() const throw (Exception)
+  {
+    double x = RandomTools::randExponential(1. / getParameterValue("lambda"));
+    while (!intMinMax_.isCorrect(x))
+      x = RandomTools::randExponential(1. / getParameterValue("lambda"));
+
+    return x;
+  }
+
+  double pProb(double x) const
+  {
+    return 1. - exp(-lambda_ * x);
+  }
+
+  double qProb(double x) const
+  {
+    return -log(1. - x) / lambda_;
+  }
+
+  double Expectation(double a) const
+  {
+    return 1. / lambda_ - exp(-a * lambda_) * (a + 1. / lambda_);
+  }
+};
+} //end of namespace bpp.
+
+#endif  //_EXPONENTIALDISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/GammaDiscreteDistribution.cpp b/src/Bpp/Numeric/Prob/GammaDiscreteDistribution.cpp
new file mode 100644
index 0000000..74ef1b8
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/GammaDiscreteDistribution.cpp
@@ -0,0 +1,127 @@
+//
+// File: GammaDiscreteDistribution.cpp
+// Created by: Julien Dutheil
+// Created on: Sun Oct 26 20:36:12 2003
+//
+
+/*
+   Copyright or © or Copr. CNRS, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "GammaDiscreteDistribution.h"
+#include "../Random/RandomTools.h"
+#include "../NumConstants.h"
+#include "../../Utils/MapTools.h"
+
+using namespace bpp;
+
+// From the STL:
+#include <cmath>
+
+using namespace std;
+
+/** Constructor: **************************************************************/
+
+GammaDiscreteDistribution::GammaDiscreteDistribution(size_t n, double alpha, double beta, double minimumAlpha, double minimumBeta) :
+  AbstractParameterAliasable("Gamma."),
+  AbstractDiscreteDistribution(n, "Gamma."),
+  alpha_(alpha),
+  beta_(beta),
+  ga1_(1)
+{
+  // We use a lower bound of 0.0001 for alpha and beta to prohibe errors due to computer
+  // floating precision: if alpha is quite low (gamma -> constant), some classes
+  // may have the same category value, leading to a classe number lower than expected.
+  // NB: if this is the case, then a warning is shown. This may happen in optimization
+  // algorithms.
+  addParameter_(new Parameter("Gamma.alpha", alpha, new IntervalConstraint(1, minimumAlpha, true), true));
+  addParameter_(new Parameter("Gamma.beta", beta, new IntervalConstraint(1, minimumBeta, true), true));
+  ga1_ = exp(RandomTools::lnGamma(alpha_ + 1) - RandomTools::lnGamma(alpha_));
+
+  intMinMax_.setLowerBound(0, true);
+  discretize();
+}
+
+GammaDiscreteDistribution::GammaDiscreteDistribution(const GammaDiscreteDistribution& gdd) :
+  AbstractParameterAliasable(gdd),
+  AbstractDiscreteDistribution(gdd),
+  alpha_(gdd.alpha_),
+  beta_(gdd.beta_),
+  ga1_(gdd.ga1_)
+{
+}
+
+GammaDiscreteDistribution& GammaDiscreteDistribution::operator=(const GammaDiscreteDistribution& gdd)
+{
+  AbstractParameterAliasable::operator=(gdd);
+  AbstractDiscreteDistribution::operator=(gdd);
+  alpha_=gdd.alpha_;
+  beta_=gdd.beta_;
+  ga1_=gdd.ga1_;
+
+  return *this;
+}
+
+GammaDiscreteDistribution::~GammaDiscreteDistribution() {}
+
+/******************************************************************************/
+
+void GammaDiscreteDistribution::fireParameterChanged(const ParameterList& parameters)
+{
+  AbstractDiscreteDistribution::fireParameterChanged(parameters);
+  alpha_ = getParameterValue("alpha");
+  beta_ = getParameterValue("beta");
+  ga1_ = exp(RandomTools::lnGamma(alpha_ + 1) - RandomTools::lnGamma(alpha_));
+
+  discretize();
+}
+
+/******************************************************************************/
+
+// Adapted from function DiscreteGamma of Yang
+
+double GammaDiscreteDistribution::qProb(double x) const
+{
+  return RandomTools::qGamma(x, alpha_, beta_);
+}
+
+
+double GammaDiscreteDistribution::pProb(double x) const
+{
+  return RandomTools::pGamma(x, alpha_, beta_);
+}
+
+double GammaDiscreteDistribution::Expectation(double a) const
+{
+  return RandomTools::pGamma(a, alpha_ + 1, beta_) / beta_ * ga1_;
+}
+
diff --git a/src/Bpp/Numeric/Prob/GammaDiscreteDistribution.h b/src/Bpp/Numeric/Prob/GammaDiscreteDistribution.h
new file mode 100644
index 0000000..b8ed6d2
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/GammaDiscreteDistribution.h
@@ -0,0 +1,116 @@
+//
+// File: GammaDiscreteDistribution.h
+// Created by: Julien Dutheil
+// Created on: Sun Oct 26 20:36:12 2003
+//
+
+/*
+  Copyright or © or Copr. CNRS, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _GAMMADISCRETEDISTRIBUTION_H_
+#define _GAMMADISCRETEDISTRIBUTION_H_
+
+#include "AbstractDiscreteDistribution.h"
+#include "../Constraints.h"
+#include "../Random/RandomTools.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Discretized Gamma distribution.
+   *
+   * @author Julien Dutheil, Laurent Guéguen, with original code from Tal Pupko and Ziheng Yang.
+   */
+  
+  class GammaDiscreteDistribution:
+    public AbstractDiscreteDistribution
+  {
+  private:
+
+    double alpha_, beta_;
+
+    // To prevent useless computations
+    double ga1_;
+    
+  public:
+    std::string getName() const {return("Gamma");}
+
+    /**
+     * @brief Build a new discretized gamma distribution.
+     * @param n the number of categories to use.
+     * @param alpha The alpha parameter (shape)
+     * @param beta The beta parameter (rate)
+     * @param minimumAlpha The minimum allowed value for parameter alpha.
+     * @param minimumBeta The minimum allowed value for parameter beta.
+     *
+     * The Parameters are: alpha and beta @f$ \in [minimumBound;\infty[ @f$.
+     * Small values of alpha and/or beta can lead to discretization issues.
+     *
+     * If @f$ alpha > 1 @f$, the minimum value of the distribution is
+     * set to 1e-12, otherwise it is 0.
+     */
+    GammaDiscreteDistribution(size_t n, double alpha = 1., double beta = 1., double minimumAlpha = 0.05, double minimumBeta = 0.05);
+
+    GammaDiscreteDistribution(const GammaDiscreteDistribution&);
+
+    GammaDiscreteDistribution& operator=(const GammaDiscreteDistribution&);
+
+    virtual ~GammaDiscreteDistribution();
+
+    GammaDiscreteDistribution* clone() const { return new GammaDiscreteDistribution(*this); }
+
+    void fireParameterChanged(const ParameterList & parameters);
+  
+    double randC() const throw (Exception)
+    {
+      double x= RandomTools::randGamma(getParameterValue("alpha"),
+                                       getParameterValue("beta"));
+      while (!intMinMax_.isCorrect(x))
+        x= RandomTools::randGamma(getParameterValue("alpha"),
+                                  getParameterValue("beta"));
+      return x;
+    }
+
+    double qProb(double x) const;
+     
+    double pProb(double x) const;
+
+    double Expectation(double a) const;
+
+};
+
+} //end of namespace bpp.
+
+#endif  //_GAMMADISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/GaussianDiscreteDistribution.cpp b/src/Bpp/Numeric/Prob/GaussianDiscreteDistribution.cpp
new file mode 100644
index 0000000..833aa55
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/GaussianDiscreteDistribution.cpp
@@ -0,0 +1,109 @@
+//
+// File: GaussianDiscreteDistribution.cpp
+// Created by: Laurent Guéguen
+// Created on: April 2010
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "GaussianDiscreteDistribution.h"
+#include "../Random/RandomTools.h"
+#include "../NumConstants.h"
+#include "../../Utils/MapTools.h"
+
+using namespace bpp;
+
+// From the STL:
+#include <cmath>
+
+using namespace std;
+
+/** Constructor: **************************************************************/
+
+GaussianDiscreteDistribution::GaussianDiscreteDistribution(size_t n, double mu, double sigma) :
+  AbstractParameterAliasable("Gaussian."),
+  AbstractDiscreteDistribution(n,"Gaussian."), mu_(mu), sigma_(sigma)
+{
+  addParameter_(new Parameter("Gaussian.mu", mu));
+  addParameter_(new Parameter("Gaussian.sigma", sigma, &Parameter::R_PLUS_STAR));
+  discretize();
+}
+
+GaussianDiscreteDistribution::GaussianDiscreteDistribution(const GaussianDiscreteDistribution& gdd) :
+  AbstractParameterAliasable(gdd),
+  AbstractDiscreteDistribution(gdd),
+  mu_(gdd.mu_),
+  sigma_(gdd.sigma_)
+{
+}
+
+GaussianDiscreteDistribution& GaussianDiscreteDistribution::operator=(const GaussianDiscreteDistribution& gdd) 
+{
+  AbstractParameterAliasable::operator=(gdd);
+  AbstractDiscreteDistribution::operator=(gdd);
+  mu_=gdd.mu_;
+  sigma_=gdd.sigma_;
+
+  return *this;
+}
+
+GaussianDiscreteDistribution::~GaussianDiscreteDistribution() {}
+
+/******************************************************************************/
+
+void GaussianDiscreteDistribution::fireParameterChanged(const ParameterList& parameters)
+{
+  AbstractDiscreteDistribution::fireParameterChanged(parameters);
+  mu_ = getParameterValue("mu");
+  sigma_ = getParameterValue("sigma");
+  discretize();  
+}
+
+/******************************************************************************/
+
+double GaussianDiscreteDistribution::qProb(double x) const
+{
+  return RandomTools::qNorm(x, mu_, sigma_);
+}
+
+double GaussianDiscreteDistribution::pProb(double x) const
+{
+  return RandomTools::pNorm(x, mu_, sigma_);
+}
+
+double GaussianDiscreteDistribution::Expectation(double a) const
+{
+  return -sigma_/sqrt(2*M_PI)*exp(-pow((a-mu_)/sigma_,2)/2)
+    +mu_*RandomTools::pNorm(a,mu_,sigma_);
+}
diff --git a/src/Bpp/Numeric/Prob/GaussianDiscreteDistribution.h b/src/Bpp/Numeric/Prob/GaussianDiscreteDistribution.h
new file mode 100644
index 0000000..a7fb8bc
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/GaussianDiscreteDistribution.h
@@ -0,0 +1,104 @@
+//
+// File: GaussianDiscreteDistribution.h
+// Created by: Laurent Guéguen
+// Created on: April 2010
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _GAUSSIANDISCRETEDISTRIBUTION_H_
+#define _GAUSSIANDISCRETEDISTRIBUTION_H_
+
+#include "AbstractDiscreteDistribution.h"
+#include "../Constraints.h"
+#include "../Random/RandomTools.h"
+
+namespace bpp
+{
+
+/**
+ * @brief Discretized Gaussian distribution.
+ *
+ * @author Laurent Guéguen
+ */
+class GaussianDiscreteDistribution:
+  public AbstractDiscreteDistribution
+{
+  private:
+  double mu_, sigma_;
+  
+  public:
+    /**
+     * @brief Build a new discretized normal distribution.
+     * @param n the number of categories to use.
+     * @param mu The mean parameter.
+     * @param sigma The standard deviation parameter.
+     *
+     * The Parameters are: mu @f$ \in ]-\infty;\infty[ @f$ and sigma
+     * @f$ \in ]0;\infty[ @f$.
+     *
+     */
+  GaussianDiscreteDistribution(size_t n, double mu=0., double sigma = 1.);
+
+  GaussianDiscreteDistribution(const GaussianDiscreteDistribution&);
+
+  GaussianDiscreteDistribution& operator=(const GaussianDiscreteDistribution&);
+  
+  virtual ~GaussianDiscreteDistribution();
+
+  GaussianDiscreteDistribution* clone() const { return new GaussianDiscreteDistribution(*this); }
+  
+public:
+
+  std::string getName() const {return("Gaussian");}
+
+  void fireParameterChanged(const ParameterList & parameters);
+  
+  double randC() const throw (Exception)
+  {
+    return RandomTools::randGaussian(mu_,sigma_);
+  }
+
+  double qProb(double x) const;
+     
+  double pProb(double x) const;
+
+  double Expectation(double a) const;
+
+};
+  
+} //end of namespace bpp.
+
+#endif  //_GAUSSIANDISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/InvariantMixedDiscreteDistribution.cpp b/src/Bpp/Numeric/Prob/InvariantMixedDiscreteDistribution.cpp
new file mode 100644
index 0000000..68078a9
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/InvariantMixedDiscreteDistribution.cpp
@@ -0,0 +1,157 @@
+//
+// File: InvariantMixedDiscreteDistribution.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Dec 24 12:02 2007
+//
+
+/*
+   Copyright or © or Copr. CNRS, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "InvariantMixedDiscreteDistribution.h"
+#include "../../Utils/MapTools.h"
+
+
+using namespace bpp;
+using namespace std;
+
+/******************************************************************************/
+
+InvariantMixedDiscreteDistribution::InvariantMixedDiscreteDistribution(
+  DiscreteDistribution* dist, double p, double invariant) :
+  AbstractParameterAliasable("Invariant."),
+  AbstractDiscreteDistribution(1, "Invariant."),
+  dist_(dist),
+  invariant_(invariant),
+  p_(p),
+  nestedPrefix_(dist->getNamespace())
+{
+  // We first change the namespace of the nested distribution:
+  dist_->setNamespace("Invariant." + nestedPrefix_);
+  addParameters_(dist_->getIndependentParameters());
+  addParameter_(new Parameter("Invariant.p", p, &Parameter::PROP_CONSTRAINT_IN));
+
+  updateDistribution();
+}
+
+/******************************************************************************/
+
+void InvariantMixedDiscreteDistribution::fireParameterChanged(const ParameterList& parameters)
+{
+  AbstractDiscreteDistribution::fireParameterChanged(parameters);
+  p_ = getParameterValue("p");
+  dist_->matchParametersValues(parameters);
+
+  updateDistribution();
+}
+
+/******************************************************************************/
+
+void InvariantMixedDiscreteDistribution::updateDistribution()
+{
+  distribution_.clear();
+  bounds_.clear();
+
+  size_t distNCat = dist_->getNumberOfCategories();
+  vector<double> probs = dist_->getProbabilities();
+  vector<double> cats  = dist_->getCategories();
+
+  distribution_[invariant_] = p_;
+  for (size_t i = 0; i < distNCat; i++)
+  {
+    if (cats[i] == invariant_)
+      distribution_[invariant_] += (1. - p_) * probs[i];
+    else
+      distribution_[cats[i]] = (1. - p_) * probs[i];
+  }
+
+  intMinMax_.setLowerBound(dist_->getLowerBound(), !dist_->strictLowerBound());
+  intMinMax_.setUpperBound(dist_->getUpperBound(), !dist_->strictUpperBound());
+
+  if (invariant_ <= intMinMax_.getLowerBound())
+    intMinMax_.setLowerBound(invariant_, true);
+  if (invariant_ >= intMinMax_.getUpperBound())
+    intMinMax_.setUpperBound(invariant_, true);
+
+  numberOfCategories_ = distribution_.size();
+
+  // bounds_
+
+  // if invariant_ is between 2 values of dist_, bounds_ are set in the
+  // middle of the 3 values
+
+  bool nv = true;
+
+  double a = dist_->getCategory(0), b;
+  if (nv && (invariant_ < a))
+  {
+    bounds_.push_back((a + invariant_) / 2);
+    nv = false;
+  }
+
+  for (size_t i = 1; i < distNCat; i++)
+  {
+    b = dist_->getCategory(i);
+    if (nv && (invariant_ < b))
+    {
+      bounds_.push_back((a + invariant_) / 2);
+      bounds_.push_back((invariant_ + b) / 2);
+      nv = false;
+    }
+    else
+      bounds_.push_back(dist_->getBound(i - 1));
+    a = b;
+  }
+
+  if (nv)
+    bounds_.push_back((a + invariant_) / 2);
+}
+
+/******************************************************************************/
+
+void InvariantMixedDiscreteDistribution::setNamespace(const string& prefix)
+{
+  AbstractDiscreteDistribution::setNamespace(prefix);
+  // We also need to update the namespace of the nested distribution:
+  dist_->setNamespace(prefix + nestedPrefix_);
+}
+
+/******************************************************************************/
+
+void InvariantMixedDiscreteDistribution::restrictToConstraint(const Constraint& c)
+{
+  if (!c.isCorrect(invariant_))
+    throw ConstraintException("Impossible to restrict to Constraint", &getParameter_("p"), invariant_);
+
+  dist_->restrictToConstraint(c);
+  updateDistribution();
+}
diff --git a/src/Bpp/Numeric/Prob/InvariantMixedDiscreteDistribution.h b/src/Bpp/Numeric/Prob/InvariantMixedDiscreteDistribution.h
new file mode 100644
index 0000000..f807a0f
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/InvariantMixedDiscreteDistribution.h
@@ -0,0 +1,162 @@
+//
+// File: InvariantMixedDiscreteDistribution.h
+// Created by: Julien Dutheil
+// Created on: Mon Dec 24 12:02 2007
+//
+
+/*
+  Copyright or © or Copr. CNRS, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _INVARIANTMIXEDDISCRETEDISTRIBUTION_H_
+#define _INVARIANTMIXEDDISCRETEDISTRIBUTION_H_
+
+#include "AbstractDiscreteDistribution.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Discrete mixed distribution, with a one-category fixed value (called "invariant") and a user-specified multi-categories distribution.
+   *
+   * The term "invariant" comes from the use of such distributions in phylogenetics:
+   * the fixed category corresponds to a value of 0 and describes invariant positions in an alignment.
+   */
+  class InvariantMixedDiscreteDistribution:
+    public AbstractDiscreteDistribution
+  {
+  private:
+    DiscreteDistribution* dist_;
+    double invariant_, p_;
+    std::string nestedPrefix_;
+
+  public:
+    /**
+     * @brief Build a new InvariantMixedDiscreteDistribution object.
+     *
+     * @param dist            The distribution to use. The mixed distribution will "own" this distribution object.
+     * This means that the distribution will be cloned in case of copy of this instance, and will be
+     * deleted with this instance.
+     * @param p               The probability of being in the invariant category.
+     * @param invariant       The value of the invariant category (typically 0, but other values may be specified). 
+     */
+    InvariantMixedDiscreteDistribution(DiscreteDistribution* dist, double p, double invariant = 0.);
+    
+    virtual ~InvariantMixedDiscreteDistribution()
+    {
+      delete dist_;
+    }
+    
+    InvariantMixedDiscreteDistribution(const InvariantMixedDiscreteDistribution& imdd):
+      AbstractParameterAliasable(imdd),
+      AbstractDiscreteDistribution(imdd),
+      dist_(dynamic_cast<DiscreteDistribution *>(imdd.dist_->clone())),
+      invariant_(imdd.invariant_), p_(imdd.p_),
+      nestedPrefix_(imdd.nestedPrefix_)
+    {}
+    
+    InvariantMixedDiscreteDistribution& operator=(const InvariantMixedDiscreteDistribution& imdd)
+    {
+      AbstractParameterAliasable::operator=(imdd);
+      AbstractDiscreteDistribution::operator=(imdd);
+      dist_         = dynamic_cast<DiscreteDistribution *>(imdd.dist_->clone());
+      invariant_    = imdd.invariant_;
+      p_            = imdd.p_;
+      nestedPrefix_ = imdd.nestedPrefix_;
+      return *this;
+    }
+
+    InvariantMixedDiscreteDistribution* clone() const { return new InvariantMixedDiscreteDistribution(*this); }
+
+  public:
+
+    std::string getName() const {return("Invariant");}
+
+    void fireParameterChanged(const ParameterList & parameters);
+
+    void setNamespace(const std::string& prefix);
+
+    /*
+     *@ brief Sets the number of categories of the embedded
+     *distribution. The number of categories of this class equals this
+     *plus one if the invariant_ is not in the embedded distribution
+     *values.
+     *
+     */
+    
+    void setNumberOfCategories(unsigned int nbClasses) {
+      dist_->setNumberOfCategories(nbClasses);
+      updateDistribution();
+    }
+    
+    /**
+     * @return The nested, conditional, sub-distribution.
+     */
+    const DiscreteDistribution * getVariableSubDistribution() const { return dist_; }
+
+    double qProb(double x) const{
+      return (x>=p_+(1-p_)*dist_->pProb(invariant_))?dist_->qProb((x-p_)/(1-p_)):dist_->qProb(x/(1-p_));
+    }
+     
+    double pProb(double x) const{
+      return (1-p_)*dist_->pProb(x)+(x<invariant_)?0:p_;
+    }
+                                
+    double Expectation(double a) const{
+      return (1-p_)*dist_->Expectation(a)+(a<invariant_?0:p_);
+    }
+
+    void setMedian(bool median){
+      if (median_!=median){
+        median_=median;
+        dist_->setMedian(median);
+        updateDistribution();
+      }
+    }
+  
+    void discretize(){
+      dist_->discretize();
+      updateDistribution();
+    }
+
+    void restrictToConstraint(const Constraint& c);
+
+  protected:
+    void updateDistribution();
+
+
+  };
+
+} //end of namespace bpp.
+
+#endif //_INVARIANTMIXEDDISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/MixtureOfDiscreteDistributions.cpp b/src/Bpp/Numeric/Prob/MixtureOfDiscreteDistributions.cpp
new file mode 100644
index 0000000..e5872d2
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/MixtureOfDiscreteDistributions.cpp
@@ -0,0 +1,319 @@
+//
+// File: MixtureOfDiscreteDistributions
+// Created by: Laurent Guéguen
+// Created on: mercredi 9 juin 2010, à 23h 09
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "MixtureOfDiscreteDistributions.h"
+#include "../NumConstants.h"
+#include "../../Utils/MapTools.h"
+#include "../../Text/TextTools.h"
+
+using namespace bpp;
+using namespace std;
+
+MixtureOfDiscreteDistributions::MixtureOfDiscreteDistributions(const vector<DiscreteDistribution*>& distributions,
+                                                               const vector<double>& probas ) :
+  AbstractParameterAliasable("Mixture."),
+  AbstractDiscreteDistribution(1, "Mixture."),
+  vdd_(),
+  probas_(),
+  vNestedPrefix_()
+{
+  if (distributions.size() != probas.size())
+  {
+    throw Exception("MixtureOfDiscreteDistributions. Distributions and probabilities vectors must have the same size (" + TextTools::toString(distributions.size()) + " != " + TextTools::toString(probas.size()) + ").");
+  }
+
+  size_t size = distributions.size();
+  for (size_t i = 0; i < size; i++)
+  {
+    if (distributions[i] == 0)
+      throw Exception("MixtureOfDiscreteDistributions. Null DiscreteDistribution* in argument vector at index " + TextTools::toString(i));
+  }
+
+  for (size_t i = 0; i < size; i++)
+  {
+    probas_.push_back(probas[i]);
+  }
+
+  double sum = VectorTools::sum(probas);
+  if (fabs(1. - sum) > precision())
+    throw Exception("MixtureOfDiscreteDistributions. Probabilities must equal 1 (sum =" + TextTools::toString(sum) + ").");
+
+  double y = 1;
+  for (size_t i = 0; i < size - 1; i++)
+  {
+    addParameter_(new Parameter("Mixture.theta" + TextTools::toString(i + 1), probas[i] / y, &Parameter::PROP_CONSTRAINT_IN));
+    y -= probas[i];
+  }
+
+
+  for (size_t i = 0; i < size; i++)
+  {
+    vdd_.push_back(distributions[i]->clone());
+  }
+
+  //  Parameters
+
+  for (size_t i = 0; i < size; i++)
+  {
+    vNestedPrefix_.push_back(TextTools::toString(i + 1) + "_" + distributions[i]->getNamespace());
+  }
+
+  for (size_t i = 0; i < size; i++)
+  {
+    vdd_[i]->setNamespace("Mixture." + vNestedPrefix_[i]);
+  }
+
+  for (size_t i = 0; i < size; i++)
+  {
+    addParameters_(vdd_[i]->getParameters());
+  }
+
+  updateDistribution();
+}
+
+MixtureOfDiscreteDistributions::MixtureOfDiscreteDistributions(const MixtureOfDiscreteDistributions& mdd) :
+  AbstractParameterAliasable(mdd),
+  AbstractDiscreteDistribution(mdd),
+  vdd_(),
+  probas_(),
+  vNestedPrefix_()
+{
+  for (size_t i = 0; i < mdd.vdd_.size(); i++)
+  {
+    probas_.push_back(mdd.probas_[i]);
+    vdd_.push_back(mdd.vdd_[i]->clone());
+    vNestedPrefix_.push_back(mdd.vNestedPrefix_[i]);
+  }
+}
+
+MixtureOfDiscreteDistributions& MixtureOfDiscreteDistributions::operator=(const MixtureOfDiscreteDistributions& mdd)
+{
+  AbstractParameterAliasable::operator=(mdd);
+  AbstractDiscreteDistribution::operator=(mdd);
+  vdd_.clear();
+  probas_.clear();
+  vNestedPrefix_.clear();
+
+  for (size_t i = 0; i < mdd.vdd_.size(); i++)
+  {
+    probas_.push_back(mdd.probas_[i]);
+    vdd_.push_back(mdd.vdd_[i]->clone());
+    vNestedPrefix_.push_back(mdd.vNestedPrefix_[i]);
+  }
+
+  return *this;
+}
+
+MixtureOfDiscreteDistributions::~MixtureOfDiscreteDistributions()
+{
+  for (size_t i = 0; i < vdd_.size(); i++)
+  {
+    delete vdd_[i];
+  }
+
+  vdd_.clear();
+}
+
+void MixtureOfDiscreteDistributions::setNumberOfCategories(size_t nbClasses)
+{
+  for (size_t i = 0; i < vdd_.size(); i++)
+  {
+    vdd_[i]->setNumberOfCategories(nbClasses);
+  }
+
+  updateDistribution();
+}
+
+
+void MixtureOfDiscreteDistributions::fireParameterChanged(const ParameterList& parameters)
+{
+  AbstractDiscreteDistribution::fireParameterChanged(parameters);
+  size_t size = vdd_.size();
+  double x = 1.0;
+  for (size_t i = 0; i < size - 1; i++)
+  {
+    probas_[i] = getParameterValue("theta" + TextTools::toString(i + 1)) * x;
+    x *= 1 - getParameterValue("theta" + TextTools::toString(i + 1));
+  }
+
+  probas_[size - 1] = x;
+
+
+  for (size_t i = 0; i < size; i++)
+  {
+    vdd_[i]->matchParametersValues(parameters);
+  }
+
+  updateDistribution();
+}
+
+void MixtureOfDiscreteDistributions::updateDistribution()
+{
+  size_t size = vdd_.size();
+  distribution_.clear();
+  // calculation of distribution
+
+  for (size_t i = 0; i < size; i++)
+  {
+    vector<double> values = vdd_[i]->getCategories();
+    for (size_t j = 0; j < values.size(); j++)
+    {
+      distribution_[values[j]] = 0;
+    }
+  }
+
+  for (size_t i = 0; i < size; i++)
+  {
+    vector<double> values = vdd_[i]->getCategories();
+    vector<double> probas2 = vdd_[i]->getProbabilities();
+    for (size_t j = 0; j < values.size(); j++)
+    {
+      distribution_[values[j]] += probas2[j] * probas_[i];
+    }
+  }
+
+  numberOfCategories_ = distribution_.size();
+
+  // intMinMax_
+
+  double uB, lB;
+  uB = -NumConstants::VERY_BIG();
+  lB = NumConstants::VERY_BIG();
+
+  bool suB = true, slB = true;
+
+  for (size_t i = 0; i < size; i++)
+  {
+    if (vdd_[i]->getLowerBound() <= lB)
+    {
+      lB = vdd_[i]->getLowerBound();
+      slB = vdd_[i]->strictLowerBound();
+    }
+    if (vdd_[i]->getUpperBound() >= uB)
+    {
+      uB = vdd_[i]->getUpperBound();
+      suB = vdd_[i]->strictUpperBound();
+    }
+  }
+
+  intMinMax_.setLowerBound(lB, slB);
+  intMinMax_.setUpperBound(uB, suB);
+
+  // Compute midpoint bounds_:
+  vector<double> values = MapTools::getKeys<double, double, AbstractDiscreteDistribution::Order>(distribution_);
+
+  bounds_.resize(numberOfCategories_ - 1);
+
+  // Fill from 0 to numberOfCategories_-1 with midpoints:
+  for (size_t i = 0; i < numberOfCategories_ - 1; i++)
+  {
+    bounds_[i] = (values[i] + values[i + 1]) / 2.;
+  }
+}
+
+void MixtureOfDiscreteDistributions::setMedian(bool median)
+{
+  if (median_ != median)
+  {
+    median_ = median;
+    for (size_t i = 0; i < vdd_.size(); i++)
+    {
+      vdd_[i]->setMedian(median);
+    }
+    updateDistribution();
+  }
+}
+void MixtureOfDiscreteDistributions::discretize()
+{
+  for (size_t i = 0; i < vdd_.size(); i++)
+  {
+    vdd_[i]->discretize();
+  }
+
+  updateDistribution();
+}
+
+double MixtureOfDiscreteDistributions::pProb(double x) const
+{
+  double s = 0;
+  for (size_t i = 0; i < vdd_.size(); i++)
+  {
+    s += probas_[i] * vdd_[i]->pProb(x);
+  }
+  return s;
+}
+
+double MixtureOfDiscreteDistributions::qProb(double x) const
+{
+  throw Exception("MixtureOfDiscreteDistributions::qProb to difficult to compute: not implemented");
+  return 0;
+}
+
+double MixtureOfDiscreteDistributions::Expectation(double a) const
+{
+  double s = 0;
+  for (size_t i = 0; i < vdd_.size(); i++)
+  {
+    s += probas_[i] * vdd_[i]->Expectation(a);
+  }
+  return s;
+}
+
+void MixtureOfDiscreteDistributions::restrictToConstraint(const Constraint& c)
+{
+  for (size_t i = 0; i < vdd_.size(); i++)
+  {
+    vdd_[i]->restrictToConstraint(c);
+  }
+
+  updateDistribution();
+}
+
+/******************************************************************************/
+
+void MixtureOfDiscreteDistributions::setNamespace(const string& prefix)
+{
+  AbstractDiscreteDistribution::setNamespace(prefix);
+  // We also need to update the namespace of the nested distributions:
+  for (size_t i = 0; i < vdd_.size(); i++)
+  {
+    vdd_[i]->setNamespace(prefix + vNestedPrefix_[i]);
+  }
+}
+
diff --git a/src/Bpp/Numeric/Prob/MixtureOfDiscreteDistributions.h b/src/Bpp/Numeric/Prob/MixtureOfDiscreteDistributions.h
new file mode 100644
index 0000000..6b9397b
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/MixtureOfDiscreteDistributions.h
@@ -0,0 +1,167 @@
+//
+// File: MixtureOfDiscreteDistributions.h
+// Created by: Laurent Guéguen
+// Created on: mercredi 9 juin 2010, à 22h 44
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#ifndef _MIXTUREOFDISCRETEDISTRIBUTIONS_H_
+#define _MIXTUREOFDISCRETEDISTRIBUTIONS_H_
+
+#include "AbstractDiscreteDistribution.h"
+
+namespace bpp
+{
+/**
+ * @brief A Discrete distribution object defined by a vector of
+ * Discrete Distributions and a set of probabilities for these
+ * Discrete Distributions.
+ *
+ * The non-null values of the MixtureOfDiscreteDistributions are all
+ * the non-null values of the Discrete Distributions, with
+ * probabilities equal to their probabilities in each Discrete
+ * Distribution multiplied by the specific probability of this
+ * Distribution.
+ *
+ * Parameters:
+ *
+ * For the probabilities: they are called \c "theta1",... and defined
+ * as @f$ \theta_{i \in 1..\textrm{size-1}} @f$ such that probability
+ * of value @f$i @f$ is @f$ (1-\theta_1).(1-\theta_2)...\theta_{i} @f$
+ *
+ * For the values: they are the parameters of the Discrete
+ * Distributions, prefixed by the index in the vector of the Discrete
+ * Distributions.
+ *
+ */
+class MixtureOfDiscreteDistributions :
+  public AbstractDiscreteDistribution
+{
+protected:
+  std::vector<DiscreteDistribution*> vdd_;
+
+  std::vector<double> probas_;
+
+  std::vector<std::string> vNestedPrefix_;
+
+public:
+  /**
+   * @brief Builds a new MixtureOfDiscreteDistributions object from a
+   * vector of Discrete Distributions and a vector of probabilities.
+   * The Discrete Distributions are cloned in the constructor to
+   * become attributes.
+   *
+   * @param distributions The vector of pointers to Discrete
+   * Distributions.
+   * @param probas The vector of probabilities.
+   *
+   */
+
+  MixtureOfDiscreteDistributions(const std::vector<DiscreteDistribution*>& distributions, const std::vector<double>& probas);
+
+  ~MixtureOfDiscreteDistributions();
+
+  MixtureOfDiscreteDistributions(const MixtureOfDiscreteDistributions& mdd);
+
+  MixtureOfDiscreteDistributions& operator=(const MixtureOfDiscreteDistributions& mdd);
+
+#if defined(NO_VIRTUAL_COV)
+  Clonable* clone() const { return new MixtureOfDiscreteDistributions(*this); }
+#else
+  MixtureOfDiscreteDistributions* clone() const { return new MixtureOfDiscreteDistributions(*this); }
+#endif
+
+public:
+  std::string getName() const {return "Mixture"; }
+
+  /**
+   * @brief Returns the number of discrete distributions in the
+   * mixture.
+   *
+   */
+  size_t getNumberOfDistributions() const {return vdd_.size(); }
+
+  /**
+   * @brief Returns a pointer to the n-th discrete distribution in the mixture.
+   *
+   * @param n tne number of the distribution in the mixture;
+   */
+  const DiscreteDistribution* getNDistribution(size_t n) const
+  {
+    return vdd_[n];
+  }
+
+  /**
+   * @brief Returns the probability of the n-th discrete distribution in the mixture.
+   *
+   * @param n the number of the distribution in the mixture;
+   */
+  double getNProbability(size_t n) const
+  {
+    return probas_[n];
+  }
+
+  /**
+   * @brief sets the number of categories of EACH submodel to
+   * nbClasses, so the number of categories of the mixture is the sum
+   * of all these numbers.
+   *
+   */
+
+  void setNumberOfCategories(size_t nbClasses);
+
+  void fireParameterChanged(const ParameterList& parameters);
+
+  double qProb(double x) const;
+
+  double pProb(double x) const;
+
+  double Expectation(double a) const;
+
+  void setMedian(bool median);
+
+  void restrictToConstraint(const Constraint& c);
+
+  void discretize();
+
+  void setNamespace(const std::string& prefix);
+
+protected:
+  void updateDistribution();
+};
+} // end of namespace bpp.
+
+#endif  // _MIXTUREOFDISCRETEDISTRIBUTIONS_H__
+
diff --git a/src/Bpp/Numeric/Prob/MultipleDiscreteDistribution.h b/src/Bpp/Numeric/Prob/MultipleDiscreteDistribution.h
new file mode 100644
index 0000000..55068bf
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/MultipleDiscreteDistribution.h
@@ -0,0 +1,151 @@
+//
+// File: MultipleDiscreteDistribution.h
+// Created by: Laurent Guéguen
+// Created on: mardi 20 juillet 2010, à 14h 52
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 19, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _MULTIPLEDISCRETEDISTRIBUTION_H_
+#define _MULTIPLEDISCRETEDISTRIBUTION_H_
+
+#include "../VectorTools.h"
+#include "../ParameterAliasable.h"
+#include "../../Exceptions.h"
+#include "../../Io/OutputStream.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Interface for multiple discrete distribution objects.
+   *
+   * A multiple discrete distribution usually contains a vector of
+   * finite set of categories and a probability associated to each.
+   * The size of the vector is the dimension of the distribution.
+   *
+   * Each category (or class) is defined by two bounds, and sometimes
+   * by a mean or a median value.
+   *
+   * A multiple discrete distribution may contain one or several
+   * parameters. The probabilities associated to each class usually
+   * depends on the parameter values. In some cases, the number and/or
+   * bounds of the classes may also depend on the parameters values,
+   * depending on the kind of discretization used.
+   */
+
+  class MultipleDiscreteDistribution:
+    public virtual ParameterAliasable
+  {
+  public:
+    MultipleDiscreteDistribution() {}
+    
+    virtual ~MultipleDiscreteDistribution() {}
+
+#ifndef NO_VIRTUAL_COV
+    MultipleDiscreteDistribution * clone() const = 0;
+#endif
+
+  public:
+
+    /**
+     * @return The number of categories 
+     */
+    virtual size_t getNumberOfCategories() const = 0;
+
+    /**
+     * @param Vvalue The vector of values to check.
+     * @return The vector of categories of the classes the value is
+     * in. Throws a ConstraintException if the value is off the domain
+     * of the MultipleDiscreteDistribution.
+     */
+    
+    virtual Vdouble getValueCategory(Vdouble& Vvalue) const = 0;
+    
+    /**
+     * @param category The vector of values associated to the class.
+     * @return The probability associated to a given class.
+     */
+    virtual double getProbability(Vdouble& category) const = 0;
+
+
+  public:
+
+    /**
+     * @brief Draw a random vector from this distribution.
+     *
+     * This vector will be one of the class values, drawn according
+     * to the class probabilities.
+     * 
+     * @return A random number according to this distribution.
+     */
+    virtual Vdouble rand() const = 0;
+
+    /**
+     * @brief Draw a random vector from the continuous version of this distribution, if it exists.
+     *
+     * Uses the continuous version of this distribution to draw a random vector.
+     * 
+     * @return A random vector according to this distribution.
+     * @throw Exception If there is no continuous version of this distribution.
+     */
+    virtual Vdouble randC() const = 0;
+
+    /**
+     * @brief Checks if the Parameters can respect the given 
+     * Constraints (one per dimension) and optionnaly tries to modify
+     * their own Constraints.
+     *
+     * @param vc The vector of Constraint to respect.
+     * @param f boolean flag to say if the Constraints must be changed
+     * (if possible) (default: true)
+     *
+     * @return true if the Parameters Constraints are adapted to the
+     * given Constraints, false otherwise.
+     */
+    //virtual bool adaptToConstraint(const std::vector<Constraint&>& vc, bool f=true) = 0;
+    
+    /**
+     * @brief Print the distribution (categories and corresponding probabilities) to a stream.
+     *
+     * @param out The outstream where to print the distribution.
+     */
+    //    virtual void print(OutputStream& out) const = 0;
+
+  };
+
+} //end of namespace bpp.
+
+#endif  //_MULTIPLEDISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/SimpleDiscreteDistribution.cpp b/src/Bpp/Numeric/Prob/SimpleDiscreteDistribution.cpp
new file mode 100644
index 0000000..f7faf38
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/SimpleDiscreteDistribution.cpp
@@ -0,0 +1,350 @@
+//
+// File: SimpleDiscreteDistribution.cpp
+// Created by: Julien Dutheil
+// Created on: ?
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "SimpleDiscreteDistribution.h"
+#include "../NumConstants.h"
+#include "../../Utils/MapTools.h"
+#include "../../Text/TextTools.h"
+
+using namespace bpp;
+using namespace std;
+
+
+SimpleDiscreteDistribution::SimpleDiscreteDistribution(const map<double, double>& distribution,
+                                                       double prec,
+                                                       bool fixed) :
+  AbstractParameterAliasable("Simple."),
+  AbstractDiscreteDistribution(distribution.size(), prec, "Simple."),
+  givenRanges_()
+{
+  double sum = 0;
+  for (map<double, double>::const_iterator i = distribution.begin(); i != distribution.end(); i++)
+  {
+    distribution_[i->first] = i->second;
+    sum += i->second;
+  }
+  if (fabs(1. - sum) > precision())
+    throw Exception("SimpleDiscreteDistribution. Probabilities must equal 1 (sum =" + TextTools::toString(sum) + ").");
+
+  if (!fixed)
+  {
+    unsigned int n = 1;
+    double x, y = 1;
+    for (map<double, double>::const_iterator i = distribution.begin(); i != distribution.end(); i++)
+    {
+      addParameter_(new Parameter("Simple.V" + TextTools::toString(n), i->first));
+
+      if (n != numberOfCategories_)
+      {
+        x = i->second;
+        addParameter_(new Parameter("Simple.theta" + TextTools::toString(n), x / y, &Parameter::PROP_CONSTRAINT_IN));
+        y -= x;
+      }
+      n++;
+    }
+  }
+  discretize();
+}
+
+SimpleDiscreteDistribution::SimpleDiscreteDistribution(const vector<double>& values,
+                                                       const vector<double>& probas,
+                                                       double prec,
+                                                       bool fixed
+                                                       ) :
+  AbstractParameterAliasable("Simple."),
+  AbstractDiscreteDistribution(values.size(), prec, "Simple."),
+  givenRanges_()
+{
+  if (values.size() != probas.size())
+  {
+    throw Exception("SimpleDiscreteDistribution. Values and probabilities vectors must have the same size (" + TextTools::toString(values.size()) + " != " + TextTools::toString(probas.size()) + ").");
+  }
+  size_t size = values.size();
+
+  for (size_t i = 0; i < size; i++)
+  {
+    if (distribution_.find(values[i]) != distribution_.end())
+      throw Exception("SimpleDiscreteDistribution: two given values are equal");
+    else
+      distribution_[values[i]] = probas[i];
+  }
+
+  double sum = VectorTools::sum(probas);
+  if (fabs(1. - sum) > precision())
+    throw Exception("SimpleDiscreteDistribution. Probabilities must equal 1 (sum =" + TextTools::toString(sum) + ").");
+
+  if (!fixed)
+  {
+    double y = 1;
+    for (unsigned int i = 0; i < size - 1; i++)
+    {
+      addParameter_(new Parameter("Simple.V" + TextTools::toString(i + 1), values[i]));
+      addParameter_(new Parameter("Simple.theta" + TextTools::toString(i + 1), probas[i] / y, &Parameter::PROP_CONSTRAINT_IN));
+      y -= probas[i];
+    }
+    addParameter_(new Parameter("Simple.V" + TextTools::toString(size), values[size - 1]));
+  }
+
+  discretize();
+}
+
+SimpleDiscreteDistribution::SimpleDiscreteDistribution(const std::vector<double>& values,
+                                                       const std::map<size_t, std::vector<double> >& ranges,
+                                                       const std::vector<double>& probas,
+                                                       double prec,
+                                                       bool fixed) :
+  AbstractParameterAliasable("Simple."),
+  AbstractDiscreteDistribution(values.size(), prec, "Simple."),
+  givenRanges_()
+{
+  if (values.size() != probas.size())
+  {
+    throw Exception("SimpleDiscreteDistribution. Values and probabilities vectors must have the same size (" + TextTools::toString(values.size()) + " != " + TextTools::toString(probas.size()) + ").");
+  }
+  size_t size = values.size();
+
+  for (size_t i = 0; i < size; i++)
+  {
+    if (distribution_.find(values[i]) != distribution_.end())
+      throw Exception("SimpleDiscreteDistribution: two given values are equal");
+    else
+      distribution_[values[i]] = probas[i];
+  }
+
+  double sum = VectorTools::sum(probas);
+  if (fabs(1. - sum) > precision())
+    throw Exception("SimpleDiscreteDistribution. Probabilities must equal 1 (sum =" + TextTools::toString(sum) + ").");
+
+  if (!fixed)
+  {
+    double y = 1;
+    for (size_t i = 0; i < size - 1; i++)
+    {
+      map<size_t, vector<double> >::const_iterator it = ranges.find(i + 1);
+      if (it == ranges.end())
+        addParameter_(new Parameter("Simple.V" + TextTools::toString(i + 1), values[i]));
+      else
+      {
+        if (values[i] >= it->second[0] &&  values[i] <= it->second[1])
+        {
+          addParameter_(new Parameter("Simple.V" + TextTools::toString(i + 1), values[i], new IntervalConstraint(it->second[0], it->second[1], true, true), true));
+          givenRanges_[i + 1] = it->second;
+        }
+        else
+          throw Exception("SimpleDiscreteDistribution. Value and given range of parameter V" + TextTools::toString(i + 1) + " do not match: " + TextTools::toString(values[i]) + " vs [" + TextTools::toString(it->second[0]) + ";" + TextTools::toString(it->second[1]) + "]");
+      }
+      addParameter_(new Parameter("Simple.theta" + TextTools::toString(i + 1), probas[i] / y, &Parameter::PROP_CONSTRAINT_IN));
+      y -= probas[i];
+    }
+
+    map<size_t, vector<double> >::const_iterator it = ranges.find(size);
+    if (it == ranges.end())
+      addParameter_(new Parameter("Simple.V" + TextTools::toString(size), values[size - 1]));
+    else
+    {
+      if (values[size - 1] >= it->second[0] &&  values[size - 1] <= it->second[1])
+      {
+        addParameter_(new Parameter("Simple.V" + TextTools::toString(size), values[size - 1], new IntervalConstraint(it->second[0], it->second[1], true, true), true));
+        givenRanges_[size] = it->second;
+      }
+      else
+        throw Exception("SimpleDiscreteDistribution. Value and given range of parameter V" + TextTools::toString(size) + " do not match: " + TextTools::toString(values[size - 1]) + " vs [" + TextTools::toString(it->second[0]) + ";" + TextTools::toString(it->second[1]) + "]");
+    }
+  }
+
+  discretize();
+}
+
+
+SimpleDiscreteDistribution::SimpleDiscreteDistribution(const SimpleDiscreteDistribution& sdd) :
+  AbstractParameterAliasable(sdd),
+  AbstractDiscreteDistribution(sdd),
+  givenRanges_(sdd.givenRanges_)
+{}
+
+SimpleDiscreteDistribution& SimpleDiscreteDistribution::operator=(const SimpleDiscreteDistribution& sdd)
+{
+  AbstractParameterAliasable::operator=(sdd);
+  AbstractDiscreteDistribution::operator=(sdd);
+  givenRanges_ = sdd.givenRanges_;
+
+  return *this;
+}
+
+void SimpleDiscreteDistribution::fireParameterChanged(const ParameterList& parameters)
+{
+  if (getNumberOfParameters() != 0)
+  {
+    AbstractDiscreteDistribution::fireParameterChanged(parameters);
+    size_t size = distribution_.size();
+
+    distribution_.clear();
+    double x = 1.0;
+    double v;
+    for (size_t i = 0; i < size - 1; i++)
+    {
+      v = getParameterValue("V" + TextTools::toString(i + 1));
+      if (distribution_.find(v) != distribution_.end())
+      {
+        unsigned int j = 1;
+        int f = ((v + precision()) >= intMinMax_.getUpperBound()) ? -1 : 1;
+        while (distribution_.find(v + f * j * precision()) != distribution_.end())
+        {
+          j++;
+          f = ((v + f * j * precision()) >= intMinMax_.getUpperBound()) ? -1 : 1;
+        }
+        v += f * j * precision();
+        // approximation to avoid useless computings:
+        // setParameterValue("V"+TextTools::toString(i+1),v);
+      }
+      distribution_[v] = getParameterValue("theta" + TextTools::toString(i + 1)) * x;
+      x *= 1 - getParameterValue("theta" + TextTools::toString(i + 1));
+    }
+
+    v = getParameterValue("V" + TextTools::toString(size));
+    if (distribution_.find(v) != distribution_.end())
+    {
+      unsigned int j = 1;
+      int f = ((v + precision()) >= intMinMax_.getUpperBound()) ? -1 : 1;
+      while (distribution_.find(v + f * j * precision()) != distribution_.end())
+      {
+        j++;
+        f = ((v + f * j * precision()) >= intMinMax_.getUpperBound()) ? -1 : 1;
+      }
+      v += f * j * precision();
+      // approximation to avoid useless computings:
+      // setParameterValue("V"+TextTools::toString(size),v);
+    }
+    distribution_[v] = x;
+  }
+  discretize();
+}
+
+double SimpleDiscreteDistribution::qProb(double x) const
+{
+  double s = -NumConstants::VERY_BIG();
+  double x2 = x;
+  for (map<double, double>::const_iterator it = distribution_.begin(); it != distribution_.end(); it++)
+  {
+    x2 -= it->second;
+    if (x2 < 0)
+      return s;
+    else
+      s = it->second;
+  }
+
+  return s;
+}
+
+double SimpleDiscreteDistribution::pProb(double x) const
+{
+  double s = 0;
+  for (map<double, double>::const_iterator it = distribution_.begin(); it != distribution_.end(); it++)
+  {
+    if (it->first >= x)
+      s += it->second;
+    else
+      break;
+  }
+
+  return s;
+}
+
+double SimpleDiscreteDistribution::Expectation(double a) const
+{
+  double s = 0;
+  for (map<double, double>::const_iterator it = distribution_.begin(); it != distribution_.end(); it++)
+  {
+    if (it->first >= a)
+      s += it->second;
+    else
+      break;
+  }
+
+  return s;
+}
+
+
+void SimpleDiscreteDistribution::discretize()
+{
+  // Compute a new arbitray bounderi:
+  vector<double> values = MapTools::getKeys<double, double, AbstractDiscreteDistribution::Order>(distribution_);
+
+  // Fill from 0 to numberOfCategories_-2 with midpoints:
+  for (unsigned int i = 0; i < numberOfCategories_ - 1; i++)
+  {
+    bounds_[i] = (values[i] + values[i + 1]) / 2.;
+  }
+}
+
+void SimpleDiscreteDistribution::restrictToConstraint(const Constraint& c)
+{
+  if (getNumberOfParameters() == 0)
+    return;
+
+  const IntervalConstraint* pi = dynamic_cast<const IntervalConstraint*>(&c);
+
+  if (!pi)
+    throw Exception("SimpleDiscreteDistribution::restrictToConstraint: Non-interval exception");
+
+  map<double, double>::const_iterator it;
+
+  for (it = distribution_.begin(); it != distribution_.end(); it++)
+  {
+    if (!pi->isCorrect(it->first))
+      throw Exception("Impossible to restrict to Constraint value " + TextTools::toString(it->first));
+  }
+
+  AbstractDiscreteDistribution::restrictToConstraint(c);
+
+  size_t size = distribution_.size();
+  for (size_t i = 0; i < size; i++)
+  {
+    map<size_t, vector<double> >::const_iterator itr = givenRanges_.find(i + 1);
+    if (itr == givenRanges_.end())
+      getParameter_("V" + TextTools::toString(i + 1)).setConstraint(intMinMax_.clone(), true);
+    else
+    {
+      const Constraint* pc = getParameter_("V" + TextTools::toString(i + 1)).removeConstraint();
+      getParameter_("V" + TextTools::toString(i + 1)).setConstraint(*pc & *intMinMax_.clone(), true);
+      delete pc;
+    }
+  }
+}
+
diff --git a/src/Bpp/Numeric/Prob/SimpleDiscreteDistribution.h b/src/Bpp/Numeric/Prob/SimpleDiscreteDistribution.h
new file mode 100644
index 0000000..0c0cadf
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/SimpleDiscreteDistribution.h
@@ -0,0 +1,158 @@
+//
+// File: SimpleDiscreteDistribution.h
+// Created by: Julien Dutheil
+// Created on: ?
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _SIMPLEDISCRETEDISTRIBUTION_H_
+#define _SIMPLEDISCRETEDISTRIBUTION_H_
+
+#include "AbstractDiscreteDistribution.h"
+
+// From the STL:
+#include <map>
+
+namespace bpp
+{
+
+/**
+ * @brief A Discrete distribution object, where some specific
+ * probabilities are assigned to a finite set of values.
+ *
+ * Optional parameters:
+ *
+ * For the probabilities: they are called \c "theta1",... and defined
+ * as @f$ \theta_{i \in 1..\textrm{size-1}} @f$ such that probability of value @f$i @f$ is @f$ (1-\theta_1).(1-\theta_2)...\theta_{i} @f$
+ *
+ * For the values: they are called \c "V1", \c "V2" ...
+ *
+ */
+class SimpleDiscreteDistribution:
+  public AbstractDiscreteDistribution
+{
+private:
+
+  std::map<size_t, std::vector<double> > givenRanges_;
+  
+  public:
+    /**
+     * @brief Builds a new SimpleDiscreteDistribution object from a
+     * map<double,double> object. With this constructor, the
+     * probabilities are fixed (ie no parameters).
+     *
+     * Keys are taken to be interval values, and map values to be the corresponding probabilities.
+     *
+     * @param distribution The map object to use.
+     * @param precision to discriminate the categories
+     * @param fixed tells if there are parameters (default false means there are parameters).
+     */
+  
+  SimpleDiscreteDistribution(const std::map<double, double>& distribution, double precision=NumConstants::TINY(), bool fixed=false);
+
+  /**
+   * @brief Builds a new SimpleDiscreteDistribution object from a
+   * vector of values and a vector of probabilities
+   *
+   * @param values The vector of values.
+   * @param probas The vector of probabilities.
+   * @param prec precision used to discriminate the categories
+   * @param fixed tells if there are parameters (default false means there are parameters).
+   *
+   */
+
+  SimpleDiscreteDistribution(const std::vector<double>& values, const std::vector<double>& probas, double prec=NumConstants::TINY(), bool fixed=false);
+
+  /**
+   * @brief Builds a new SimpleDiscreteDistribution object from a
+   * vector of values, a map of ranges and a vector of probabilities
+   *
+   * @param values The vector of values.
+   * @param ranges The map of ranges. Each key is the index of the
+   *        parameter in the given vector of values, and the
+   *        associated value is a vector of two doubles, for the min
+   *        and the max of the range.
+   * @param probas The vector of probabilities.
+   * @param prec precision to discriminate the categories
+   * @param fixed tells if there are parameters (default false means there are parameters).
+   *
+   */
+
+  SimpleDiscreteDistribution(const std::vector<double>& values, const std::map<size_t, std::vector<double> >& ranges, const std::vector<double>& probas, double prec=NumConstants::TINY(), bool fixed=false);
+
+  virtual ~SimpleDiscreteDistribution() {}
+
+  SimpleDiscreteDistribution(const SimpleDiscreteDistribution&);
+
+  SimpleDiscreteDistribution& operator=(const SimpleDiscreteDistribution&);
+  
+  SimpleDiscreteDistribution * clone() const { return new SimpleDiscreteDistribution(*this); }
+
+public:
+
+  /*
+   *@brief Returns the map of the given ranges for the values.
+   *
+   */
+  
+  const std::map<size_t, std::vector<double> > getRanges() const { return givenRanges_;}
+    
+  std::string getName() const {return("Simple");}
+  
+  void discretize();
+  
+  void fireParameterChanged(const ParameterList & parameters);
+
+  double getLowerBound() const {
+    return distribution_.begin()->first;
+  }
+
+  double getUpperBound() const {
+    return distribution_.rbegin()->first;
+  }  
+  
+  double qProb(double x) const ;
+  
+  double pProb(double x) const ;
+                                
+  double Expectation(double a) const;
+
+  void restrictToConstraint(const Constraint& c);
+};
+
+} //end of namespace bpp.
+
+#endif  //_SIMPLEDISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/Simplex.cpp b/src/Bpp/Numeric/Prob/Simplex.cpp
new file mode 100644
index 0000000..29bb5f5
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/Simplex.cpp
@@ -0,0 +1,190 @@
+//
+// File: Simplex.cpp
+// Created by: Laurent Guéguen
+// Created on: mardi 31 mai 2011, à 13h 16
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "Simplex.h"
+#include "../NumConstants.h"
+
+#include "../VectorTools.h"
+
+using namespace bpp;
+using namespace std;
+
+Simplex::Simplex(const std::vector<double>& probas, unsigned short method, const std::string& name) : AbstractParameterAliasable(name),
+  dim_(probas.size()),
+  method_(method),
+  vProb_(),
+  valpha_()
+{
+  double sum = VectorTools::sum(probas);
+  if (fabs(1. - sum) > NumConstants::SMALL())
+    throw Exception("Simplex. Probabilities must equal 1 (sum =" + TextTools::toString(sum) + ").");
+
+  for (unsigned int i = 0; i < dim_; i++)
+  {
+    vProb_.push_back(probas[i]);
+  }
+
+  switch (method_)
+  {
+  case 2:
+    for (unsigned int i = 0; i < dim_ - 1; i++)
+    {
+      addParameter_(new Parameter(name + "theta" + TextTools::toString(i + 1), vProb_[i] / (vProb_[i] + vProb_[i + 1]), &Parameter::PROP_CONSTRAINT_IN));
+    }
+    for (unsigned int i = 0; i < dim_ - 1; i++)
+    {
+      valpha_.push_back(vProb_[i + 1] / vProb_[i]);
+    }
+    break;
+  case 1:
+    double y = 1;
+    for (unsigned int i = 0; i < dim_ - 1; i++)
+    {
+      addParameter_(new Parameter(name + "theta" + TextTools::toString(i + 1), vProb_[i] / y, &Parameter::PROP_CONSTRAINT_IN));
+      y -= vProb_[i];
+    }
+    break;
+  }
+}
+
+Simplex::Simplex(size_t dim, unsigned short method, const std::string& name) :
+  AbstractParameterAliasable(name),
+  dim_(dim),
+  method_(method),
+  vProb_(),
+  valpha_()
+{
+  for (size_t i = 0; i < dim_; i++)
+  {
+    vProb_.push_back(1. / static_cast<double>(dim_));
+  }
+
+  switch (method_)
+  {
+  case 2:
+    for (unsigned int i = 0; i < dim_ - 1; i++)
+    {
+      addParameter_(new Parameter(name+ "theta" + TextTools::toString(i + 1), 0.5, &Parameter::PROP_CONSTRAINT_IN));
+    }
+    for (unsigned int i = 0; i < dim_ - 1; i++)
+    {
+      valpha_.push_back(1.);
+    }
+    break;
+  case 1:
+    double y = 1;
+    for (unsigned int i = 0; i < dim_ - 1; i++)
+    {
+      addParameter_(new Parameter(name+"theta" + TextTools::toString(i + 1), vProb_[i] / y, &Parameter::PROP_CONSTRAINT_IN));
+      y -= vProb_[i];
+    }
+    break;
+  }
+}
+
+void Simplex::fireParameterChanged(const ParameterList& parameters)
+{
+  AbstractParameterAliasable::fireParameterChanged(parameters);
+
+  double x = 1.0;
+  switch (method_)
+  {
+  case 1:
+    double th;
+    for (unsigned int i = 0; i < dim_ - 1; i++)
+    {
+      th = getParameterValue("theta" + TextTools::toString(i + 1));
+      vProb_[i] = th * x;
+      x *= 1 - th;
+    }
+    vProb_[dim_ - 1] = x;
+    break;
+  case 2:
+    for (unsigned int i = 0; i < dim_ - 1; i++)
+    {
+      th = getParameterValue("theta" + TextTools::toString(i + 1));
+      valpha_[i] = (1 - th) / th;
+    }
+    th = 1;
+    vProb_[0] = 1;
+    x = 1.0;
+    for (unsigned int i = 0; i < dim_ - 1; i++)
+    {
+      th *= valpha_[i];
+      vProb_[i + 1] = th;
+      x += vProb_[i + 1];
+    }
+    for (unsigned int i = 0; i < dim_; i++)
+      vProb_[i] /= x;
+
+    break;
+  }
+}
+
+
+void Simplex::setFrequencies(const std::vector<double>& probas)
+{
+  double sum = VectorTools::sum(probas);
+  if (fabs(1. - sum) > NumConstants::SMALL())
+    throw Exception("Simplex::setFrequencies. Probabilities must equal 1 (sum =" + TextTools::toString(sum) + ").");
+
+  double y = 1;
+
+  ParameterList pl;
+  switch (method_)
+    {
+    case 1:
+      for (unsigned int i = 0; i < dim_ - 1; i++)
+        {
+          pl.addParameter(Parameter(getNamespace()+"theta" + TextTools::toString(i + 1), probas[i] / y));
+          y -= probas[i];
+        }
+      break;
+    case 2:
+      for (unsigned int i = 0; i < dim_ - 1; i++)
+        {
+          pl.addParameter(Parameter(getNamespace()+"theta" + TextTools::toString(i + 1), probas[i] / (probas[i] + probas[i + 1])));
+          valpha_[i]=probas[i + 1] / probas[i];
+        }
+      break;
+    }
+
+  matchParametersValues(pl);
+}
+
diff --git a/src/Bpp/Numeric/Prob/Simplex.h b/src/Bpp/Numeric/Prob/Simplex.h
new file mode 100644
index 0000000..20c1f66
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/Simplex.h
@@ -0,0 +1,162 @@
+//
+// File: Simplex.h
+// Created by: Laurent Guéguen
+// Created on: mardi 31 mai 2011, à 11h 02
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _SIMPLEX_H_
+#define _SIMPLEX_H_
+
+
+// From the STL:
+#include <vector>
+
+#include "../AbstractParameterAliasable.h"
+
+namespace bpp
+{
+
+/**
+ * @brief A Simplex object, used to define sets of probabilities that
+ * sum 1.
+ *
+ * The probabilities are denoted @f$p_i at f$ for @f$i \in <1,n>@f$.
+ *
+ * If they are parametrized, the parameters are called \c "theta1",
+ * ..., \c "theta(n-1)".
+ *
+ * Two ways of parametrization are available:
+ *
+ * Global ratio:
+ *
+ * @f$\forall i<n, \theta_i=\frac{p_i}{1-(p_1+...+p_{i-1})}@f$.
+ *
+ * In the reverse,
+ * @f$\forall i<n, p_i= (1-\theta_1).(1-\theta_2)...\theta_{i}@f$
+ * and @f$p_n=(1-\theta_1).(1-\theta_2)...(1-\theta_{n-1})@f$.
+ *
+ *
+ * Local ratio:
+ *
+ * @f$\theta_i = \frac{p_i}{p_i+p_{i+1}} \forall i \in 1..\textrm{n-1}@f$.
+ *
+ * In the reverse if we denote @f$\alpha_i=\frac{1-\theta_i}{\theta_i}@f$,
+ * @f$p_i=\frac{\alpha_1...\alpha_{i-1}}{1+\sum_{k=1}^{n-1}\alpha_1...\alpha_k}@f$.
+ *
+ */
+
+  class Simplex:
+    public AbstractParameterAliasable
+{
+private:
+  /*
+   *@brief The dimension+1 of the space simplex (ie the number of probabilities).
+   *
+   */
+   
+  size_t dim_;
+
+  /*
+   *@brief the method of parametrization.
+   *
+   * 0: No parametrization
+   * 1: Global ratio
+   * 2: Local ratio
+   *
+   */
+  unsigned short method_;
+  
+  std::vector<double> vProb_;
+
+  /*
+   *@brief just used with local ratio (method 2)
+   *
+   */
+  
+  std::vector<double> valpha_;
+  
+  
+public:
+
+  /**
+   * @brief Builds a new Simplex object from a number of
+   * probabilities. They are initialized equal.
+   *
+   * @param dim The number of probabilities.
+   * @param method  tells the method of parametrization (default 0)
+   *    0: No parametrization
+   *    1: Global ratio
+   *    2: Local ratio
+   * @param name The name passed to AbstractParameterAliasable constructor.
+   *
+   */
+  
+  Simplex(size_t dim, unsigned short method = 0, const std::string& name = "Simplex.");
+
+  /**
+   * @brief Builds a new Simplex object from a vector of probabilities
+   *
+   * @param probas The vector of probabilities.
+   * @param method  tells the method of parametrization (default 0)
+   *    0: No parametrization
+   *    1: Global ratio
+   *    2: Local ratio
+   * @param name The name passed to AbstractParameterAliasable constructor.
+   *
+   */
+
+  Simplex(const std::vector<double>& probas, unsigned short method = 0, const std::string& name = "Simplex.");
+  
+  virtual ~Simplex() {}
+
+  Simplex* clone() const { return new Simplex(*this); }
+
+public:
+  void fireParameterChanged(const ParameterList & parameters);
+
+  size_t dimension() const { return dim_; }
+
+  void setFrequencies(const std::vector<double>&);
+  
+  double prob(size_t i) const { return vProb_[i];}
+
+  unsigned short getMethod() const { return method_;}
+};
+
+} //end of namespace bpp.
+
+#endif  //_SIMPLEDISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/TruncatedExponentialDiscreteDistribution.cpp b/src/Bpp/Numeric/Prob/TruncatedExponentialDiscreteDistribution.cpp
new file mode 100644
index 0000000..628db47
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/TruncatedExponentialDiscreteDistribution.cpp
@@ -0,0 +1,90 @@
+//
+// File: TruncatedExponentialDiscreteDistribution.cpp
+// Created by: Julien Dutheil
+// Created on: Fri Jan 25 15:24 2008
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "TruncatedExponentialDiscreteDistribution.h"
+#include "../Random/RandomTools.h"
+#include "../../Utils/MapTools.h"
+
+using namespace bpp;
+
+// From the STL:
+#include <cmath>
+
+using namespace std;
+
+/** Constructor: **************************************************************/
+
+TruncatedExponentialDiscreteDistribution::TruncatedExponentialDiscreteDistribution(size_t n, double lambda, double truncationPoint) :
+  AbstractParameterAliasable("TruncExponential."),
+  AbstractDiscreteDistribution(n, "TruncExponential."),
+  lambda_(lambda),
+  tp_(truncationPoint),
+  cond_(1-exp(-lambda_*tp_))
+{
+  addParameter_(new Parameter("TruncExponential.tp", truncationPoint, &Parameter::R_PLUS));
+  addParameter_(new Parameter("TruncExponential.lambda", lambda,  &Parameter::R_PLUS));
+
+  intMinMax_.setLowerBound(0, true);
+  intMinMax_.setUpperBound(tp_, false);
+
+  discretize();
+}
+
+/******************************************************************************/
+
+void TruncatedExponentialDiscreteDistribution::fireParameterChanged(const ParameterList& parameters)
+{
+  AbstractDiscreteDistribution::fireParameterChanged(parameters);
+  lambda_ = getParameterValue("lambda");
+  tp_ = getParameterValue("tp");
+
+  intMinMax_.setUpperBound(tp_, false);
+  cond_=1-exp(-lambda_*tp_);
+  
+  discretize();
+}
+
+/******************************************************************************/
+
+void TruncatedExponentialDiscreteDistribution::restrictToConstraint(const Constraint& c)
+{
+  AbstractDiscreteDistribution::restrictToConstraint(c);
+
+  getParameter_("tp").setConstraint(intMinMax_.clone(), true);
+}
diff --git a/src/Bpp/Numeric/Prob/TruncatedExponentialDiscreteDistribution.h b/src/Bpp/Numeric/Prob/TruncatedExponentialDiscreteDistribution.h
new file mode 100644
index 0000000..8ed06af
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/TruncatedExponentialDiscreteDistribution.h
@@ -0,0 +1,154 @@
+//
+// File: TruncatedExponentialDiscreteDistribution.h
+// Created by: Julien Dutheil
+// Created on: Fri Jan 25 15:24 2008
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _TRUNCATEDEXPONENTIALDISCRETEDISTRIBUTION_H_
+#define _TRUNCATEDEXPONENTIALDISCRETEDISTRIBUTION_H_
+
+#include "ExponentialDiscreteDistribution.h"
+#include "../Constraints.h"
+#include "../Random/RandomTools.h"
+
+namespace bpp
+{
+/**
+ * @brief Discretized Truncated (on the right) Exponential
+ * distribution, where the probabilities are given the exponential,
+ * conditioned by the upper limit.
+ *
+ * This distribution has two parameters: the traditional exponential law parameter,
+ * and the abscissa of the truncation. The distribution will be truncated on the right
+ * of this point.
+ */
+  
+class TruncatedExponentialDiscreteDistribution :
+  public AbstractDiscreteDistribution
+{
+protected:
+  double lambda_;
+
+  double tp_;
+
+  /*
+   * Probability of the condition given x < tp_.
+   *
+   */
+   
+  double cond_;
+  
+public:
+  /**
+   * @brief Build a new truncated exponential discrete distribution.
+   * @param n the number of categories to use.
+   * @param lambda The lambda parameter
+   * @param truncationPoint The truncation point
+   *
+   * The Parameters are: lambda @f$ \in [0.000001;\infty[ @f$ and tp . at f$ \in [0;\infty[ @f$
+   *
+   */
+
+  TruncatedExponentialDiscreteDistribution(size_t n, double lambda = 1., double truncationPoint = 10);
+
+  TruncatedExponentialDiscreteDistribution(const TruncatedExponentialDiscreteDistribution& dist) :
+    AbstractParameterAliasable(dist),
+    AbstractDiscreteDistribution(dist),
+    lambda_(dist.lambda_),
+    tp_(dist.tp_),
+    cond_(dist.cond_)
+  {}
+
+  TruncatedExponentialDiscreteDistribution& operator=(const TruncatedExponentialDiscreteDistribution& dist)
+  {
+    AbstractParameterAliasable::operator=(dist);
+    AbstractDiscreteDistribution::operator=(dist);
+    lambda_= dist.lambda_;
+    tp_ = dist.tp_;
+    cond_ = dist.cond_;
+    return *this;
+  }
+
+  ~TruncatedExponentialDiscreteDistribution(){};
+
+  TruncatedExponentialDiscreteDistribution* clone() const { return new TruncatedExponentialDiscreteDistribution(*this); }
+
+public:
+
+  std::string getName() const {return("TruncExponential");}
+
+  void fireParameterChanged(const ParameterList& parameters);
+
+  double randC() const throw (Exception)
+  {
+    double x = RandomTools::randExponential(1. / getParameterValue("lambda"));
+    while (!intMinMax_.isCorrect(x))
+      x = RandomTools::randExponential(1. / getParameterValue("lambda"));
+
+    return x;
+  }
+
+  double pProb(double x) const
+  {
+    if (x>=tp_)
+      return 1.;
+    else
+      return (1. - exp(-lambda_ * x))/cond_;
+  }
+
+  double qProb(double x) const
+  {
+    if (x==1)
+      return tp_;
+    else
+      return -log(1. - cond_*x) / lambda_;
+  }
+
+  double Expectation(double a) const
+  {
+    if (a<tp_)
+      return (1. / lambda_ - exp(-a * lambda_) * (a + 1. / lambda_))/cond_;
+    else
+      return (1. / lambda_ - exp(-tp_ * lambda_) * (tp_ + 1. / lambda_))/cond_;
+      
+  }
+
+  void restrictToConstraint(const Constraint& c);
+};
+} //end of namespace bpp.
+
+#endif  //_TRUNCATEDEXPONENTIALDISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Prob/UniformDiscreteDistribution.cpp b/src/Bpp/Numeric/Prob/UniformDiscreteDistribution.cpp
new file mode 100644
index 0000000..1d2d03a
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/UniformDiscreteDistribution.cpp
@@ -0,0 +1,94 @@
+//
+// File: UniformDiscreteDistribution.cpp
+// Created by: Laurent Guéguen
+// Created on: April 2010
+//
+
+/*
+Copyright or © or Copr. CNRS, (2010)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "UniformDiscreteDistribution.h"
+#include "../Random/RandomTools.h"
+#include "../../Utils/MapTools.h"
+
+using namespace bpp;
+
+// From the STL:
+#include <cmath>
+
+using namespace std;
+
+/** Constructor: **************************************************************/
+
+UniformDiscreteDistribution::UniformDiscreteDistribution(unsigned int n, double min, double max) :
+  AbstractParameterAliasable("Uniform."),
+  AbstractDiscreteDistribution(n,"Uniform."),
+  min_((min<max)?min:max),
+  max_((min<max)?max:min) 
+{
+  intMinMax_.setLowerBound(min_,false);
+  intMinMax_.setUpperBound(max_,false);
+
+  discretize();
+}
+
+UniformDiscreteDistribution::UniformDiscreteDistribution(const UniformDiscreteDistribution& udd) : 
+  AbstractParameterAliasable(udd),
+  AbstractDiscreteDistribution(udd),
+  min_(udd.min_),
+  max_(udd.max_)
+{
+}
+
+UniformDiscreteDistribution& UniformDiscreteDistribution::operator=(const UniformDiscreteDistribution& udd) 
+{
+  AbstractParameterAliasable::operator=(udd);
+  AbstractDiscreteDistribution::operator=(udd);
+  min_=udd.min_;
+  max_=udd.max_;
+
+  return *this;
+}
+
+UniformDiscreteDistribution::~UniformDiscreteDistribution() {}
+
+/******************************************************************************/
+
+void UniformDiscreteDistribution::fireParameterChanged(const ParameterList& parameters)
+{
+}
+
+
+
+
+
diff --git a/src/Bpp/Numeric/Prob/UniformDiscreteDistribution.h b/src/Bpp/Numeric/Prob/UniformDiscreteDistribution.h
new file mode 100644
index 0000000..965d054
--- /dev/null
+++ b/src/Bpp/Numeric/Prob/UniformDiscreteDistribution.h
@@ -0,0 +1,113 @@
+//
+// File: UniformDiscreteDistribution.h
+// Created by: Laurent Guéguen
+// Created on: April 2010
+//
+
+/*
+  Copyright or © or Copr. CNRS, (2010)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _UNIFORMDISCRETEDISTRIBUTION_H_
+#define _UNIFORMDISCRETEDISTRIBUTION_H_
+
+#include "AbstractDiscreteDistribution.h"
+#include "../Constraints.h"
+#include "../Random/RandomTools.h"
+
+namespace bpp
+{
+
+  /**
+   * @brief Discretized Uniform distribution.
+   * All categories are equidistributed all along a given interval.
+   *
+   * @author Laurent Gueguen
+   */
+  class UniformDiscreteDistribution:
+    public AbstractDiscreteDistribution
+  {
+  private:
+    double min_;
+    double max_;
+
+  public:
+    /**
+     * @brief Build a new discretized uniform distribution.
+     * @param n the number of categories to use.
+     * @param min The minimun value (default 0)
+     * @param max The maximum value (default 1)
+     */
+    UniformDiscreteDistribution(unsigned int n, double min = 0., double max = 1.);
+
+    UniformDiscreteDistribution(const UniformDiscreteDistribution&);
+
+    UniformDiscreteDistribution& operator=(const UniformDiscreteDistribution&);
+    
+    virtual ~UniformDiscreteDistribution();
+
+    UniformDiscreteDistribution* clone() const { return new UniformDiscreteDistribution(*this); }
+  
+  public:
+    std::string getName() const {return("Uniform");}
+
+    void fireParameterChanged(const ParameterList & parameters);
+
+    double randC() const throw (Exception)
+    {
+      double x= RandomTools::giveRandomNumberBetweenZeroAndEntry(max_-min_)+min_;
+      while (!intMinMax_.isCorrect(x))
+        x= RandomTools::giveRandomNumberBetweenZeroAndEntry(max_-min_)+min_;
+      return x;
+    }
+
+    double qProb(double x) const
+    {
+      return min_+x*(max_-min_);
+    }
+    
+    double pProb(double x) const
+    {
+      return (x<=min_)?0:(x-min_)/(max_-min_);
+    }
+    
+    double Expectation(double a) const
+    {
+      return (a<=min_)?0:((a>=max_)?(max_+min_)/2:(a*a-min_*min_)/(max_-min_)/2);
+    }
+    
+  };
+
+} //end of namespace bpp.
+
+#endif  //_UNIFORMDISCRETEDISTRIBUTION_H_
+
diff --git a/src/Bpp/Numeric/Random/ContingencyTableGenerator.cpp b/src/Bpp/Numeric/Random/ContingencyTableGenerator.cpp
new file mode 100644
index 0000000..cf28bbd
--- /dev/null
+++ b/src/Bpp/Numeric/Random/ContingencyTableGenerator.cpp
@@ -0,0 +1,199 @@
+//
+// File ContingencyTableGenerator.cpp
+// Author: Julien Dutheil
+// Created on: Fri Dec 10 2010 16:19
+//
+
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "ContingencyTableGenerator.h"
+#include "../VectorTools.h"
+
+#include <iostream>
+
+using namespace bpp;
+using namespace std;
+
+/**************************************************************************/
+
+ContingencyTableGenerator::ContingencyTableGenerator(
+    const std::vector<size_t>& nrowt,
+    const std::vector<size_t>& ncolt):
+  nrowt_(nrowt),
+  ncolt_(ncolt),
+  nrow_(nrowt.size()),
+  ncol_(ncolt.size()),
+  nrowm_(0),
+  ncolm_(0),
+  jwork_(ncolt.size()),
+  ntot_(0),
+  fact_(0)
+{
+  if (nrow_ < 2 || ncol_ < 2)
+    throw Exception("ContingencyTableGenerator. Input marginals must have size greater than 1.");
+  ntot_ = VectorTools::sum(nrowt_);
+  if (ntot_ != VectorTools::sum(ncolt_))
+    throw Exception("ContingencyTableGenerator. Marginal do not sum to the same value.");
+  nrowm_ = nrow_ - 1;
+  ncolm_ = ncol_ - 1;
+  fact_.resize(ntot_ + 1);
+  double x = 0.;
+  fact_[0] = 0.;
+  for (unsigned int i = 1; i <= ntot_; i++) {
+    x = x + log(static_cast<double>(i));
+    fact_[i] = x;
+  } 
+}
+
+/* Algorithm AS 159 Applied Statistics (1981), vol. 30, no. 1
+   original (C) Royal Statistical Society 1981
+
+   Generate random two-way table with given marginal totals.
+
+   Heavily pretty edited by Martin Maechler, Dec 2003
+   use double precision for integer multiplication (against overflow);
+
+   Taken from R source file rcont.c and adapted by Julien Dutheil, Dec 2010
+*/
+
+RowMatrix<size_t> ContingencyTableGenerator::rcont2(const RandomFactory& generator)
+{
+  RowMatrix<size_t> table(nrow_, ncol_); //Result
+  size_t j, l, m, ia, ib, ic, jc, id, ie, ii, nll, nlm, nr_1, nc_1;
+  long double x, y, dummy, sumprb;
+  bool lsm, lsp;
+
+  nr_1 = nrow_ - 1;
+  nc_1 = ncol_ - 1;
+
+  ib = 0; /* -Wall */
+
+  /* Construct random matrix */
+  for (j = 0; j < nc_1; ++j)
+    jwork_[j] = ncolt_[j];
+
+  jc = ntot_;
+
+  for (l = 0; l < nr_1; ++l) { /* -----  matrix[ l, * ] ----- */
+    ia = nrowt_[l];
+    ic = jc;
+    jc -= ia;/* = n_tot - sum(nr[0:l]) */
+
+    for (m = 0; m < nc_1; ++m) {
+      id = jwork_[m];
+      ie = ic;
+      ic -= id;
+      ib = ie - ia;
+      ii = ib - id;
+
+      if (ie == 0) { /* Row [l,] is full, fill rest with zero entries */
+        for (j = m; j < nc_1; ++j)
+          table(l, j) = 0;
+        ia = 0;
+        break;
+      }
+
+      /* Generate pseudo-random number */
+      dummy = generator.drawNumber();
+
+      do {/* Outer Loop */
+
+        /* Compute conditional expected value of MATRIX(L, M) */
+
+        nlm = static_cast<size_t>(ia * (static_cast<long double>(id) / static_cast<long double>(ie)) + 0.5);
+        x = exp(fact_[ia] + fact_[ib] + fact_[ic] + fact_[id]
+          - fact_[ie] - fact_[nlm]
+          - fact_[id - nlm] - fact_[ia - nlm] - fact_[ii + nlm]);
+        if (x >= dummy)
+          break;
+
+        sumprb = x;
+        y = x;
+        nll = nlm;
+
+        do {
+          /* Increment entry in row L, column M */
+          j = static_cast<size_t>((id - nlm) * static_cast<long double>(ia - nlm));
+          lsp = (j == 0);
+          if (!lsp) {
+            ++nlm;
+            x = x * j / (static_cast<long double>(nlm) * (ii + nlm));
+            sumprb += x;
+            if (sumprb >= dummy)
+              goto L160;
+          }
+
+          do {
+            /* Decrement entry in row L, column M */
+            j = nll * (ii + nll);
+            lsm = (j == 0);
+            if (!lsm) {
+              --nll;
+              y = y * j / (static_cast<long double>(id - nll) * (ia - nll));
+              sumprb += y;
+              if (sumprb >= dummy) {
+                nlm = nll;
+                goto L160;
+              }
+              /* else */
+              if (!lsp)
+                break;/* to while (!lsp) */
+            }
+          } while (!lsm);
+        } while (!lsp);
+
+        dummy = sumprb * generator.drawNumber();
+
+      } while (true);
+
+L160:
+      table(l, m) = nlm;
+      ia -= nlm;
+      jwork_[m] -= nlm;
+    }
+    table(l, nc_1) = ia;/* last column in row l */
+  }
+
+  /* Compute entries in last row of MATRIX */
+  for (m = 0; m < nc_1; ++m)
+    table(nr_1, m) = jwork_[m];
+
+  table(nr_1, nc_1) = ib - table(nr_1, nc_1 - 1);
+
+  return table;
+}
+  
+/**************************************************************************/
+
diff --git a/src/Bpp/Numeric/Random/ContingencyTableGenerator.h b/src/Bpp/Numeric/Random/ContingencyTableGenerator.h
new file mode 100644
index 0000000..35d9a66
--- /dev/null
+++ b/src/Bpp/Numeric/Random/ContingencyTableGenerator.h
@@ -0,0 +1,93 @@
+//
+// File ContingencyTableGenerator.h
+// Author: Julien Dutheil
+// Created on: Fri Dec 10 2010 16:19
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _CONTINGENCYTABLEGENERATOR_H_
+#define _CONTINGENCYTABLEGENERATOR_H_
+
+#include "RandomFactory.h"
+#include "RandomTools.h"
+#include "../Matrix/Matrix.h"
+
+// From the STL:
+#include <cmath>
+#include <vector>
+
+namespace bpp
+{
+
+  /**
+ * @brief Generate a random contingency matrix with given marginal counts.
+ *
+ * This procedure was adapted from the original fortran code described in:
+ * Patefield, W. M. (1981) Algorithm AS159.  An efficient method of
+ * generating r x c tables with given row and column totals.
+ * _Applied Statistics_ *30*, 91-97.
+ * This algorithm is the one also used in R function chisq.test for instance.
+ *
+ * The code was adpated from file rcont.c, edited by Martin Maechler, Dec 2003,
+ * available in the R software source distribution.
+ *
+ * @param nrowt Marginal counts.
+ * @param ncolt Marginal counts.
+ * @return A random matrix of counts with the same marginals as specified.
+ */
+class ContingencyTableGenerator
+{
+  private:
+    std::vector<size_t> nrowt_;
+    std::vector<size_t> ncolt_;
+    size_t nrow_;
+    size_t ncol_;
+    size_t nrowm_;
+    size_t ncolm_;
+    std::vector<size_t> jwork_; //workspace
+    size_t ntot_; //total number of observations
+    std::vector<double> fact_; //log factorial
+
+  public:
+    ContingencyTableGenerator(const std::vector<size_t>& nrowt, const std::vector<size_t>& ncolt);
+
+  public:
+    RowMatrix<size_t> rcont2(const RandomFactory& generator = *RandomTools::DEFAULT_GENERATOR); 
+};
+
+} //end of namespace bpp.
+
+#endif  //_CONTINGENCYTABLEGENERATOR_H_
+
diff --git a/src/Bpp/Numeric/Random/RandomFactory.h b/src/Bpp/Numeric/Random/RandomFactory.h
new file mode 100644
index 0000000..45475d2
--- /dev/null
+++ b/src/Bpp/Numeric/Random/RandomFactory.h
@@ -0,0 +1,72 @@
+/*
+ * File RandomFactory.h
+ * Author : Sylvain Gaillard
+ * Last modification : Friday September 24 2004
+ */
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _RANDOMFACTORY_H_
+#define _RANDOMFACTORY_H_
+
+namespace bpp
+{
+
+/**
+ * @brief This is the interface for the Random Number Generators.
+ *
+ * A Random Number Generator draw numbers between two end points. Each
+ * number is taken from a given statistic distribution.
+ */
+class RandomFactory {
+	public:
+		RandomFactory() {}
+		virtual ~RandomFactory() {}
+
+	public:
+		/**
+		 * @brief Set the generator's seed.
+		 */
+		virtual void setSeed(long seed) = 0;
+
+		/**
+		 * @brief Return a random number.
+		 */
+		virtual double drawNumber() const = 0;
+};
+
+} //end of namespace bpp.
+
+#endif // _RANDOMFACTORY_H_
+
diff --git a/src/Bpp/Numeric/Random/RandomTools.cpp b/src/Bpp/Numeric/Random/RandomTools.cpp
new file mode 100644
index 0000000..42e7516
--- /dev/null
+++ b/src/Bpp/Numeric/Random/RandomTools.cpp
@@ -0,0 +1,1060 @@
+//
+// File RandomTools.cpp
+// Author : Julien Dutheil
+// Last modification : Friday Septembre 24 2004
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "RandomTools.h"
+#include "Uniform01K.h"
+#include "../VectorTools.h"
+#include "../NumConstants.h"
+
+#include <iostream>
+
+using namespace bpp;
+using namespace std;
+
+RandomFactory* RandomTools::DEFAULT_GENERATOR = new Uniform01K(time(NULL));
+
+// Initiate random seed :
+// RandomTools::RandInt RandomTools::r = time(NULL) ;
+
+void RandomTools::setSeed(long seed)
+{
+  DEFAULT_GENERATOR->setSeed(seed);
+}
+
+// Method to get a double random value (between 0 and specified range)
+// Note : the number you get is between 0 and entry not including entry !
+double RandomTools::giveRandomNumberBetweenZeroAndEntry(double entry, const RandomFactory& generator)
+{
+  // double tm = r.drawFloatNumber();
+  double tm = generator.drawNumber();
+  return tm * entry;
+}
+
+// Method to get a boolean random value
+bool RandomTools::flipCoin(const RandomFactory& generator)
+{
+  return (RandomTools::giveRandomNumberBetweenZeroAndEntry(1.0, generator) - 0.5) > 0;
+}
+
+// Method to get a integer random value (between 0 and specified range)
+// Note : the number you get is between 0 and entry not including entry !
+int RandomTools::giveIntRandomNumberBetweenZeroAndEntry(int entry, const RandomFactory& generator)
+{
+  return static_cast<int>(giveRandomNumberBetweenZeroAndEntry(entry, generator));
+}
+
+double RandomTools::randGaussian(double mean, double variance, const RandomFactory& generator)
+{
+  return RandomTools::qNorm(generator.drawNumber(), mean, sqrt(variance));
+}
+
+double RandomTools::randGamma(double dblAlpha, const RandomFactory& generator)
+{
+  assert(dblAlpha > 0.0);
+  if (dblAlpha < 1.0)
+    return RandomTools::DblGammaLessThanOne(dblAlpha, generator);
+  else if (dblAlpha > 1.0)
+    return RandomTools::DblGammaGreaterThanOne(dblAlpha, generator);
+  return -log(RandomTools::giveRandomNumberBetweenZeroAndEntry(1.0, generator));
+}
+
+double RandomTools::randGamma(double alpha, double beta, const RandomFactory& generator)
+{
+  double x = RandomTools::randGamma(alpha, generator) / beta;
+  return x;
+}
+
+double RandomTools::randExponential(double mean, const RandomFactory& generator)
+{
+  return -mean* log(RandomTools::giveRandomNumberBetweenZeroAndEntry(1, generator));
+}
+
+std::vector<size_t> RandomTools::randMultinomial(size_t n, const std::vector<double>& probs)
+{
+  double s = VectorTools::sum(probs);
+  double r;
+  double cumprob;
+  vector<size_t> sample(n);
+  for (unsigned int i = 0; i < n; i++)
+  {
+    r = RandomTools::giveRandomNumberBetweenZeroAndEntry(1);
+    cumprob = 0;
+    bool test = true;
+    for (unsigned int j = 0; test &(j < probs.size()); j++)
+    {
+      cumprob += probs[j] / s;
+      if (r <= cumprob)
+      {
+        sample[i] = j;
+        test = false;
+      }
+    }
+    // This test should never be true if probs sum to one:
+    if (test)
+      sample[i] = probs.size();
+  }
+  return sample;
+}
+
+// ------------------------------------------------------------------------------
+
+
+double RandomTools::DblGammaGreaterThanOne(double dblAlpha, const RandomFactory& generator)
+{
+  // Code adopted from David Heckerman
+  // -----------------------------------------------------------
+  //  DblGammaGreaterThanOne(dblAlpha)
+  //
+  //  routine to generate a gamma random variable with unit scale and
+  //      alpha > 1
+  //  reference: Ripley, Stochastic Simulation, p.90
+  //  Chang and Feast, Appl.Stat. (28) p.290
+  // -----------------------------------------------------------
+  double rgdbl[6];
+
+  rgdbl[1] = dblAlpha - 1.0;
+  rgdbl[2] = (dblAlpha - (1.0 / (6.0 * dblAlpha))) / rgdbl[1];
+  rgdbl[3] = 2.0 / rgdbl[1];
+  rgdbl[4] = rgdbl[3] + 2.0;
+  rgdbl[5] = 1.0 / sqrt(dblAlpha);
+
+  for ( ; ; )
+  {
+    double dblRand1;
+    double dblRand2;
+    do
+    {
+      dblRand1 = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.0, generator);
+      dblRand2 = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.0, generator);
+      if (dblAlpha > 2.5)
+        dblRand1 = dblRand2 + rgdbl[5] * (1.0 - 1.86 * dblRand1);
+    }
+    while (!(0.0 < dblRand1 && dblRand1 < 1.0));
+
+    double dblTemp = rgdbl[2] * dblRand2 / dblRand1;
+
+    if (rgdbl[3] * dblRand1 + dblTemp + 1.0 / dblTemp <= rgdbl[4] ||
+        rgdbl[3] * log(dblRand1) + dblTemp - log(dblTemp) < 1.0)
+    {
+      return dblTemp * rgdbl[1];
+    }
+  }
+  assert(false);
+  return 0.0;
+}
+
+double RandomTools::DblGammaLessThanOne(double dblAlpha, const RandomFactory& generator)
+{
+  // routine to generate a gamma random variable with
+  // unit scale and alpha < 1
+  // reference: Ripley, Stochastic Simulation, p.88
+  double dblTemp;
+  const double dblexp = exp(1.0);
+  for ( ; ; )
+  {
+    double dblRand0 = giveRandomNumberBetweenZeroAndEntry(1.0, generator);
+    double dblRand1 = giveRandomNumberBetweenZeroAndEntry(1.0, generator);
+    if (dblRand0 <= (dblexp / (dblAlpha + dblexp)))
+    {
+      dblTemp = pow(((dblAlpha + dblexp) * dblRand0) /
+                    dblexp, 1.0 / dblAlpha);
+      if (dblRand1 <= exp(-1.0 * dblTemp))
+        return dblTemp;
+    }
+    else
+    {
+      dblTemp = -1.0 * log((dblAlpha + dblexp) * (1.0 - dblRand0) / (dblAlpha * dblexp));
+      if (dblRand1 <= pow(dblTemp, dblAlpha - 1.0))
+        return dblTemp;
+    }
+  }
+  assert(false);
+  return 0.0;
+}
+
+/******************************************************************************/
+
+// From Yang's PAML package:
+
+/******************************************************************************/
+
+double RandomTools::qNorm(double prob)
+{
+  double a0 = -.322232431088, a1 = -1, a2 = -.342242088547, a3 = -.0204231210245;
+  double a4 = -.453642210148e-4, b0 = .0993484626060, b1 = .588581570495;
+  double b2 = .531103462366, b3 = .103537752850, b4 = .0038560700634;
+  double y, z = 0, p = prob, p1;
+
+  p1 = (p < 0.5 ? p : 1 - p);
+  if (p1 < 1e-20)
+    return -9999;
+
+  y = sqrt (log(1 / (p1 * p1)));
+  z = y + ((((y * a4 + a3) * y + a2) * y + a1) * y + a0) / ((((y * b4 + b3) * y + b2) * y + b1) * y + b0);
+  return p < 0.5 ? -z : z;
+}
+
+double RandomTools::qNorm(double prob, double mu, double sigma)
+{
+  return RandomTools::qNorm(prob) * sigma + mu;
+}
+
+
+double RandomTools::lnGamma (double alpha)
+{
+  double x = alpha, f = 0, z;
+
+  if (x < 7)
+  {
+    f = 1;  z = x - 1;
+    while (++z < 7)
+      f *= z;
+    x = z;   f = -log(f);
+  }
+  z = 1 / (x * x);
+  return f + (x - 0.5) * log(x) - x + .918938533204673
+         + (((-.000595238095238 * z + .000793650793651) * z - .002777777777778) * z
+            + .083333333333333) / x;
+}
+
+
+double RandomTools::incompleteGamma (double x, double alpha, double ln_gamma_alpha)
+{
+  int i;
+  double p = alpha, g = ln_gamma_alpha;
+  double accurate = 1e-8, overflow = 1e30;
+  double factor, gin = 0, rn = 0, a = 0, b = 0, an = 0, dif = 0, term = 0;
+  vector<double> pn(6);
+
+  if (x == 0)
+    return 0;
+  if (x < 0 || p <= 0)
+    return -1;
+
+  factor = exp(p * log(x) - x - g);
+  if (x > 1 && x >= p)
+    goto l30;
+  /* (1) series expansion */
+  gin = 1;  term = 1;  rn = p;
+l20:
+  rn++;
+  term *= x / rn;   gin += term;
+
+  if (term > accurate)
+    goto l20;
+  gin *= factor / p;
+  goto l50;
+l30:
+  /* (2) continued fraction */
+  a = 1 - p;   b = a + x + 1;  term = 0;
+  pn[0] = 1;  pn[1] = x;  pn[2] = x + 1;  pn[3] = x * b;
+  gin = pn[2] / pn[3];
+l32:
+  a++;  b += 2;  term++;   an = a * term;
+  for (i = 0; i < 2; i++)
+  {
+    pn[i + 4] = b * pn[i + 2] - an * pn[i];
+  }
+  if (pn[5] == 0)
+    goto l35;
+  rn = pn[4] / pn[5];   dif = fabs(gin - rn);
+  if (dif > accurate)
+    goto l34;
+  if (dif <= accurate * rn)
+    goto l42;
+l34:
+  gin = rn;
+l35:
+  for (i = 0; i < 4; i++)
+  {
+    pn[i] = pn[i + 2];
+  }
+  if (fabs(pn[4]) < overflow)
+    goto l32;
+  for (i = 0; i < 4; i++)
+  {
+    pn[i] /= overflow;
+  }
+  goto l32;
+l42:
+  gin = 1 - factor * gin;
+
+l50:
+
+  return gin;
+}
+
+
+double RandomTools::qChisq(double prob, double v)
+{
+  double e = .5e-6, aa = .6931471805, p = prob, g;
+  double xx, c, ch, a = 0, q = 0, p1 = 0, p2 = 0, t = 0, x = 0, b = 0, s1, s2, s3, s4, s5, s6;
+
+  if (p < .000002 || p > .999998 || v <= 0)
+    return -1;
+
+  g = lnGamma (v / 2);
+  xx = v / 2;   c = xx - 1;
+  if (v >= -1.24 * log(p))
+    goto l1;
+
+  ch = pow((p * xx * exp(g + xx * aa)), 1 / xx);
+  if (ch - e < 0)
+    return ch;
+  goto l4;
+l1:
+  if (v > .32)
+    goto l3;
+  ch = 0.4;   a = log(1 - p);
+l2:
+  q = ch;  p1 = 1 + ch * (4.67 + ch);  p2 = ch * (6.73 + ch * (6.66 + ch));
+  t = -0.5 + (4.67 + 2 * ch) / p1 - (6.73 + ch * (13.32 + 3 * ch)) / p2;
+  ch -= (1 - exp(a + g + .5 * ch + c * aa) * p2 / p1) / t;
+  if (fabs(q / ch - 1) - .01 <= 0)
+    goto l4;
+  else
+    goto l2;
+
+l3:
+  x = qNorm (p);
+  p1 = 0.222222 / v;   ch = v * pow((x * sqrt(p1) + 1 - p1), 3.0);
+  if (ch > 2.2 * v + 6)
+    ch = -2 * (log(1 - p) - c * log(.5 * ch) + g);
+l4:
+  q = ch;   p1 = .5 * ch;
+  if ((t = incompleteGamma (p1, xx, g)) < 0)
+  {
+    std::cerr << "err IncompleteGamma" << std::endl;
+    return -1;
+  }
+  p2 = p - t;
+  t = p2 * exp(xx * aa + g + p1 - c * log(ch));
+  b = t / ch;  a = 0.5 * t - b * c;
+
+  s1 = (210 + a * (140 + a * (105 + a * (84 + a * (70 + 60 * a))))) / 420;
+  s2 = (420 + a * (735 + a * (966 + a * (1141 + 1278 * a)))) / 2520;
+  s3 = (210 + a * (462 + a * (707 + 932 * a))) / 2520;
+  s4 = (252 + a * (672 + 1182 * a) + c * (294 + a * (889 + 1740 * a))) / 5040;
+  s5 = (84 + 264 * a + c * (175 + 606 * a)) / 2520;
+  s6 = (120 + c * (346 + 127 * c)) / 5040;
+  ch += t * (1 + 0.5 * t * s1 - b * c * (s1 - b * (s2 - b * (s3 - b * (s4 - b * (s5 - b * s6))))));
+  if (fabs(q / ch - 1) > e)
+    goto l4;
+
+  return ch;
+}
+
+
+double RandomTools::pNorm(double x, double mu, double sigma)
+{
+  return RandomTools::pNorm((x - mu) / sigma);
+}
+
+
+double RandomTools::pNorm(double x)
+{
+  const static double a[5] = {
+    2.2352520354606839287,
+    161.02823106855587881,
+    1067.6894854603709582,
+    18154.981253343561249,
+    0.065682337918207449113
+  };
+  const static double b[4] = {
+    47.20258190468824187,
+    976.09855173777669322,
+    10260.932208618978205,
+    45507.789335026729956
+  };
+  const static double c[9] = {
+    0.39894151208813466764,
+    8.8831497943883759412,
+    93.506656132177855979,
+    597.27027639480026226,
+    2494.5375852903726711,
+    6848.1904505362823326,
+    11602.651437647350124,
+    9842.7148383839780218,
+    1.0765576773720192317e-8
+  };
+  const static double d[8] = {
+    22.266688044328115691,
+    235.38790178262499861,
+    1519.377599407554805,
+    6485.558298266760755,
+    18615.571640885098091,
+    34900.952721145977266,
+    38912.003286093271411,
+    19685.429676859990727
+  };
+  const static double p[6] = {
+    0.21589853405795699,
+    0.1274011611602473639,
+    0.022235277870649807,
+    0.001421619193227893466,
+    2.9112874951168792e-5,
+    0.02307344176494017303
+  };
+  const static double q[5] = {
+    1.28426009614491121,
+    0.468238212480865118,
+    0.0659881378689285515,
+    0.00378239633202758244,
+    7.29751555083966205e-5
+  };
+
+  double xden, xnum, temp, del, eps, xsq, y, cum;
+  int i;
+
+  eps = 1e-20;
+
+  y = fabs(x);
+  if (y <= 0.67448975)   /* qnorm(3/4) = .6744.... -- earlier had 0.66291 */
+  {
+    if (y > eps)
+    {
+      xsq = x * x;
+      xnum = a[4] * xsq;
+      xden = xsq;
+      for (i = 0; i < 3; ++i)
+      {
+        xnum = (xnum + a[i]) * xsq;
+        xden = (xden + b[i]) * xsq;
+      }
+    }
+    else
+      xnum = xden = 0.0;
+
+    temp = x * (xnum + a[3]) / (xden + b[3]);
+    cum = 0.5 + temp;
+  }
+  else if (y <= sqrt(32))
+  {
+    /* Evaluate pnorm for 0.674.. = qnorm(3/4) < |x| <= sqrt(32) ~= 5.657 */
+
+    xnum = c[8] * y;
+    xden = y;
+    for (i = 0; i < 7; ++i)
+    {
+      xnum = (xnum + c[i]) * y;
+      xden = (xden + d[i]) * y;
+    }
+    temp = (xnum + c[7]) / (xden + d[7]);
+
+    xsq = trunc(y * 16) / 16;
+    del = (y - xsq) * (y + xsq);
+    cum = exp(-xsq * xsq * 0.5) * exp(-del * 0.5) * temp;
+
+    if (x > 0.)
+      cum = 1 - cum;
+  }
+  else if (-37.5193 < x  &&  x < 8.2924)
+  {
+    xsq = 1.0 / (x * x);
+    xnum = p[5] * xsq;
+    xden = xsq;
+    for (i = 0; i < 4; ++i)
+    {
+      xnum = (xnum + p[i]) * xsq;
+      xden = (xden + q[i]) * xsq;
+    }
+    temp = xsq * (xnum + p[4]) / (xden + q[4]);
+    temp = (1 / sqrt(2 * M_PI) - temp) / y;
+
+    xsq = trunc(x * 16) / 16;
+    del = (x - xsq) * (x + xsq);
+
+    cum = exp(-xsq * xsq * 0.5) * exp(-del * 0.5) * temp;
+
+    if (x > 0.)
+      cum = 1. - cum;
+  }
+  else   /* no log_p , large x such that probs are 0 or 1 */
+  {
+    if (x > 0)
+      cum = 1.;
+    else
+      cum = 0.;
+  }
+
+  return cum;
+}
+
+double RandomTools::lnBeta(double alpha, double beta)
+{
+  return lnGamma(alpha) + lnGamma(beta) - lnGamma(alpha + beta);
+}
+
+double RandomTools::randBeta(double alpha, double beta, const RandomFactory& generator)
+{
+  return RandomTools::qBeta(generator.drawNumber(), alpha, beta);
+}
+
+
+double RandomTools::qBeta(double prob, double alpha, double beta)
+{
+  double lower = NumConstants::VERY_TINY();
+  double upper = 1 - NumConstants::VERY_TINY();
+  double const1 = 2.30753;
+  double const2 = 0.27061;
+  double const3 = 0.99229;
+  double const4 = 0.04481;
+
+
+  int swap_tail, i_pb, i_inn;
+  double a, adj, logbeta, g, h, pp, prev, qq, r, s, t, tx, w, y, yprev;
+  double acu;
+  volatile double xinbta;
+
+  if (alpha <= 0. || beta < 0.)
+    throw ("RandomTools::qBeta wih non positive parameters");
+
+  if (prob < 0. || prob > 1.)
+    throw ("RandomTools::qBeta wih bad probability");
+
+  /* initialize */
+  logbeta = lnBeta(alpha, beta);
+
+  /* change tail if necessary;  afterwards   0 < a <= 1/2   */
+  if (prob <= 0.5)
+  {
+    a = prob;  pp = alpha; qq = beta; swap_tail = 0;
+  }
+  else   /* change tail, swap  alpha <-> beta :*/
+  {
+    a = 1 - prob;
+    pp = beta; qq = alpha; swap_tail = 1;
+  }
+
+  /* calculate the initial approximation */
+
+  /* y := {fast approximation of} qnorm(1 - a) :*/
+  r = sqrt(-2 * log(a));
+  y = r - (const1 + const2 * r) / (1. + (const3 + const4 * r) * r);
+  if (pp > 1 && qq > 1)
+  {
+    r = (y * y - 3.) / 6.;
+    s = 1. / (pp + pp - 1.);
+    t = 1. / (qq + qq - 1.);
+    h = 2. / (s + t);
+    w = y * sqrt(h + r) / h - (t - s) * (r + 5. / 6. - 2. / (3. * h));
+    xinbta = pp / (pp + qq * exp(w + w));
+  }
+  else
+  {
+    r = qq + qq;
+    t = 1. / (9. * qq);
+    t = r * pow(1. - t + y * sqrt(t), 3.0);
+    if (t <= 0.)
+      xinbta = 1. - exp((log1p(-a) + log(qq) + logbeta) / qq);
+    else
+    {
+      t = (4. * pp + r - 2.) / t;
+      if (t <= 1.)
+        xinbta = exp((log(a * pp) + logbeta) / pp);
+      else
+        xinbta = 1. - 2. / (t + 1.);
+    }
+  }
+
+  /* solve for x by a modified newton-raphson method, */
+  /* using the function pbeta_raw */
+
+  r = 1 - pp;
+  t = 1 - qq;
+  yprev = 0.;
+  adj = 1;
+  /* Sometimes the approximation is negative! */
+  if (xinbta < lower)
+    xinbta = 0.5;
+  else if (xinbta > upper)
+    xinbta = 0.5;
+
+  /* Desired accuracy should depend on  (a,p)
+   * This is from Remark .. on AS 109, adapted.
+   * However, it's not clear if this is "optimal" for IEEE double prec.
+
+   * acu = fmax2(lower, pow(10., -25. - 5./(pp * pp) - 1./(a * a)));
+
+   * NEW: 'acu' accuracy NOT for squared adjustment, but simple;
+   * ---- i.e.,  "new acu" = sqrt(old acu)
+
+   */
+  double po = pow(10., -13 - 2.5 / (pp * pp) - 0.5 / (a * a));
+  acu = (lower > po) ? lower : po;
+
+  tx = prev = 0.;  /* keep -Wall happy */
+
+  for (i_pb = 0; i_pb < 1000; i_pb++)
+  {
+    y = incompleteBeta(xinbta, pp, qq);
+// #ifdef IEEE_754
+//     if(!R_FINITE(y))
+// #else
+//       if (errno)
+// #endif
+//         ML_ERR_return_NAN;
+
+    y = (y - a) *
+        exp(logbeta + r * log(xinbta) + t * log1p(-xinbta));
+    if (y * yprev <= 0.)
+      prev = (fabs(adj) > lower) ? fabs(adj) : lower;
+    g = 1;
+    for (i_inn = 0; i_inn < 1000; i_inn++)
+    {
+      adj = g * y;
+      if (fabs(adj) < prev)
+      {
+        tx = xinbta - adj; /* trial new x */
+        if (tx >= 0. && tx <= 1)
+        {
+          if ((prev <= acu) || (fabs(y) <= acu))
+            return swap_tail ? 1 - xinbta : xinbta;
+          if (tx != 0. && tx != 1)
+            break;
+        }
+      }
+      g /= 3;
+    }
+    if (fabs(tx - xinbta) < 1e-15 * xinbta)
+      return swap_tail ? 1 - xinbta : xinbta;
+
+    xinbta = tx;
+    yprev = y;
+  }
+  // throw Exception("Bad precision in RandomTools::qBeta");
+
+  return swap_tail ? 1 - xinbta : xinbta;
+}
+
+double RandomTools::incompleteBeta(double x, double alpha, double beta)
+{
+  double t;
+  double xc;
+  double w;
+  double y;
+  int flag;
+  double big;
+  double biginv;
+  double maxgam;
+  double minlog;
+  double maxlog;
+
+  big = 4.503599627370496e15;
+  biginv = 2.22044604925031308085e-16;
+  maxgam = 171.624376956302725;
+  minlog = log(NumConstants::VERY_TINY());
+  maxlog = log(NumConstants::VERY_BIG());
+
+  if ((alpha <= 0) || (beta <= 0))
+    throw Exception("RandomTools::incompleteBeta not valid with non-positive parameters");
+
+  if ((x < 0) || (x > 1))
+    throw Exception("RandomTools::incompleteBeta out of bounds limit");
+
+  if (x == 0)
+    return 0;
+
+  if (x == 1)
+    return 1;
+
+  flag = 0;
+  if ((beta * x <= 1.0) && (x <= 0.95))
+  {
+    return incompletebetaps(alpha, beta, x, maxgam);
+  }
+  w = 1.0 - x;
+
+  if (x > alpha / (alpha + beta))
+  {
+    flag = 1;
+    t = alpha;
+    alpha = beta;
+    beta = t;
+    xc = x;
+    x = w;
+  }
+  else
+  {
+    xc = w;
+  }
+  if (flag == 1 && (beta * x <= 1.0) && (x <= 0.95) )
+  {
+    t = incompletebetaps(alpha, beta, x, maxgam);
+    if (t <= NumConstants::VERY_TINY())
+      return 1.0 - NumConstants::VERY_TINY();
+    else
+      return 1.0 - t;
+  }
+
+  y = x * (alpha + beta - 2.0) - (alpha - 1.0);
+  if (y < 0.0)
+  {
+    w = incompletebetafe(alpha, beta, x, big, biginv);
+  }
+  else
+  {
+    w = incompletebetafe2(alpha, beta, x, big, biginv) / xc;
+  }
+  y = alpha * log(x);
+  t = beta * log(xc);
+  if ( (alpha + beta < maxgam) && (fabs(y) < maxlog) && (fabs(t) < maxlog) )
+  {
+    t = pow(xc, beta);
+    t = t * pow(x, alpha);
+    t = t / alpha;
+    t = t * w;
+    t = t * exp(lnGamma(alpha + beta) - (lnGamma(alpha) + lnGamma(beta)));
+    if (flag == 1)
+    {
+      if (t < NumConstants::VERY_TINY())
+        return 1.0 - NumConstants::VERY_TINY();
+      else
+        return 1.0 - t;
+    }
+    else
+      return t;
+  }
+  y = y + t + lnGamma(alpha + beta) - lnGamma(alpha) - lnGamma(beta);
+  y = y + log(w / alpha);
+  if (y < minlog)
+  {
+    t = 0.0;
+  }
+  else
+  {
+    t = exp(y);
+  }
+  if (flag == 1)
+  {
+    if (t < NumConstants::VERY_TINY())
+      t = 1.0 - NumConstants::VERY_TINY();
+    else
+      t = 1.0 - t;
+  }
+  return t;
+}
+
+
+/**********************************************/
+
+double RandomTools::incompletebetafe(double a,
+                                     double b,
+                                     double x,
+                                     double big,
+                                     double biginv)
+{
+  double result;
+  double xk;
+  double pk;
+  double pkm1;
+  double pkm2;
+  double qk;
+  double qkm1;
+  double qkm2;
+  double k1;
+  double k2;
+  double k3;
+  double k4;
+  double k5;
+  double k6;
+  double k7;
+  double k8;
+  double r;
+  double t;
+  double ans;
+  double thresh;
+  int n;
+
+  k1 = a;
+  k2 = a + b;
+  k3 = a;
+  k4 = a + 1.0;
+  k5 = 1.0;
+  k6 = b - 1.0;
+  k7 = k4;
+  k8 = a + 2.0;
+  pkm2 = 0.0;
+  qkm2 = 1.0;
+  pkm1 = 1.0;
+  qkm1 = 1.0;
+  ans = 1.0;
+  r = 1.0;
+  n = 0;
+  thresh = 3.0 * NumConstants::VERY_TINY();
+  do
+  {
+    xk = -x * k1 * k2 / (k3 * k4);
+    pk = pkm1 + pkm2 * xk;
+    qk = qkm1 + qkm2 * xk;
+    pkm2 = pkm1;
+    pkm1 = pk;
+    qkm2 = qkm1;
+    qkm1 = qk;
+    xk = x * k5 * k6 / (k7 * k8);
+    pk = pkm1 + pkm2 * xk;
+    qk = qkm1 + qkm2 * xk;
+    pkm2 = pkm1;
+    pkm1 = pk;
+    qkm2 = qkm1;
+    qkm1 = qk;
+    if (qk != 0)
+    {
+      r = pk / qk;
+    }
+    if (r != 0)
+    {
+      t = fabs((ans - r) / r);
+      ans = r;
+    }
+    else
+    {
+      t = 1.0;
+    }
+    if (t < thresh)
+    {
+      break;
+    }
+    k1 = k1 + 1.0;
+    k2 = k2 + 1.0;
+    k3 = k3 + 2.0;
+    k4 = k4 + 2.0;
+    k5 = k5 + 1.0;
+    k6 = k6 - 1.0;
+    k7 = k7 + 2.0;
+    k8 = k8 + 2.0;
+    if (fabs(qk) + fabs(pk) > big)
+    {
+      pkm2 = pkm2 * biginv;
+      pkm1 = pkm1 * biginv;
+      qkm2 = qkm2 * biginv;
+      qkm1 = qkm1 * biginv;
+    }
+    if ((fabs(qk) < biginv) || (fabs(pk) < biginv))
+    {
+      pkm2 = pkm2 * big;
+      pkm1 = pkm1 * big;
+      qkm2 = qkm2 * big;
+      qkm1 = qkm1 * big;
+    }
+    n = n + 1;
+  }
+  while (n != 300);
+  result = ans;
+  return result;
+}
+
+
+/*************************************************************************
+   Continued fraction expansion #2
+   for incomplete beta integral
+
+   Cephes Math Library, Release 2.8:  June, 2000
+   Copyright 1984, 1995, 2000 by Stephen L. Moshier
+*************************************************************************/
+double RandomTools::incompletebetafe2(double a,
+                                      double b,
+                                      double x,
+                                      double big,
+                                      double biginv)
+{
+  double result;
+  double xk;
+  double pk;
+  double pkm1;
+  double pkm2;
+  double qk;
+  double qkm1;
+  double qkm2;
+  double k1;
+  double k2;
+  double k3;
+  double k4;
+  double k5;
+  double k6;
+  double k7;
+  double k8;
+  double r;
+  double t;
+  double ans;
+  double z;
+  double thresh;
+  int n;
+
+  k1 = a;
+  k2 = b - 1.0;
+  k3 = a;
+  k4 = a + 1.0;
+  k5 = 1.0;
+  k6 = a + b;
+  k7 = a + 1.0;
+  k8 = a + 2.0;
+  pkm2 = 0.0;
+  qkm2 = 1.0;
+  pkm1 = 1.0;
+  qkm1 = 1.0;
+  z = x / (1.0 - x);
+  ans = 1.0;
+  r = 1.0;
+  n = 0;
+  thresh = 3.0 * NumConstants::VERY_TINY();
+  do
+  {
+    xk = -z * k1 * k2 / (k3 * k4);
+    pk = pkm1 + pkm2 * xk;
+    qk = qkm1 + qkm2 * xk;
+    pkm2 = pkm1;
+    pkm1 = pk;
+    qkm2 = qkm1;
+    qkm1 = qk;
+    xk = z * k5 * k6 / (k7 * k8);
+    pk = pkm1 + pkm2 * xk;
+    qk = qkm1 + qkm2 * xk;
+    pkm2 = pkm1;
+    pkm1 = pk;
+    qkm2 = qkm1;
+    qkm1 = qk;
+    if (qk != 0)
+    {
+      r = pk / qk;
+    }
+    if (r != 0)
+    {
+      t = fabs((ans - r) / r);
+      ans = r;
+    }
+    else
+    {
+      t = 1.0;
+    }
+    if (t < thresh)
+    {
+      break;
+    }
+    k1 = k1 + 1.0;
+    k2 = k2 - 1.0;
+    k3 = k3 + 2.0;
+    k4 = k4 + 2.0;
+    k5 = k5 + 1.0;
+    k6 = k6 + 1.0;
+    k7 = k7 + 2.0;
+    k8 = k8 + 2.0;
+    if (fabs(qk) + fabs(pk) > big)
+    {
+      pkm2 = pkm2 * biginv;
+      pkm1 = pkm1 * biginv;
+      qkm2 = qkm2 * biginv;
+      qkm1 = qkm1 * biginv;
+    }
+    if ((fabs(qk) < biginv) || (fabs(pk) < biginv))
+    {
+      pkm2 = pkm2 * big;
+      pkm1 = pkm1 * big;
+      qkm2 = qkm2 * big;
+      qkm1 = qkm1 * big;
+    }
+    n = n + 1;
+  }
+  while (n != 300);
+  result = ans;
+  return result;
+}
+
+
+/*************************************************************************
+   Power series for incomplete beta integral.
+   Use when b*x is small and x not too close to 1.
+
+   Cephes Math Library, Release 2.8:  June, 2000
+   Copyright 1984, 1995, 2000 by Stephen L. Moshier
+*************************************************************************/
+double RandomTools::incompletebetaps(double a, double b, double x, double maxgam)
+{
+  double result;
+  double s;
+  double t;
+  double u;
+  double v;
+  double n;
+  double t1;
+  double z;
+  double ai;
+
+  ai = 1.0 / a;
+  u = (1.0 - b) * x;
+  v = u / (a + 1.0);
+  t1 = v;
+  t = u;
+  n = 2.0;
+  s = 0.0;
+  z = NumConstants::VERY_TINY() * ai;
+  while (fabs(v) > z)
+  {
+    u = (n - b) * x / n;
+    t = t * u;
+    v = t / (a + n);
+    s = s + v;
+    n = n + 1.0;
+  }
+  s = s + t1;
+  s = s + ai;
+  u = a * log(x);
+  if ((a + b < maxgam) && (fabs(u) < log(NumConstants::VERY_BIG())))
+  {
+    t = exp(lnGamma(a + b) - (lnGamma(a) + lnGamma(b)));
+    s = s * t * pow(x, a);
+  }
+  else
+  {
+    t = lnGamma(a + b) - lnGamma(a) - lnGamma(b) + u + log(s);
+    if (t < log(NumConstants::VERY_TINY()))
+    {
+      s = 0.0;
+    }
+    else
+    {
+      s = exp(t);
+    }
+  }
+  result = s;
+  return result;
+}
+
+/**************************************************************************/
+
diff --git a/src/Bpp/Numeric/Random/RandomTools.h b/src/Bpp/Numeric/Random/RandomTools.h
new file mode 100644
index 0000000..04ba6eb
--- /dev/null
+++ b/src/Bpp/Numeric/Random/RandomTools.h
@@ -0,0 +1,548 @@
+//
+// File RandomTools.h
+// Author : Julien Dutheil
+//          Sylvain Gaillard
+// Last modification : Thu November 6 2008
+//
+
+/*
+  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+  This software is a computer program whose purpose is to provide classes
+  for numerical calculus.
+
+  This software is governed by the CeCILL  license under French law and
+  abiding by the rules of distribution of free software.  You can  use, 
+  modify and/ or redistribute the software under the terms of the CeCILL
+  license as circulated by CEA, CNRS and INRIA at the following URL
+  "http://www.cecill.info". 
+
+  As a counterpart to the access to the source code and  rights to copy,
+  modify and redistribute granted by the license, users are provided only
+  with a limited warranty  and the software's author,  the holder of the
+  economic rights,  and the successive licensors  have only  limited
+  liability. 
+
+  In this respect, the user's attention is drawn to the risks associated
+  with loading,  using,  modifying and/or developing or reproducing the
+  software by the user in light of its specific status of free software,
+  that may mean  that it is complicated to manipulate,  and  that  also
+  therefore means  that it is reserved for developers  and  experienced
+  professionals having in-depth computer knowledge. Users are therefore
+  encouraged to load and test the software's suitability as regards their
+  requirements in conditions enabling the security of their systems and/or 
+  data to be ensured and,  more generally, to use and operate it in the 
+  same conditions as regards security. 
+
+  The fact that you are presently reading this means that you have had
+  knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _RANDOMTOOLS_H_
+#define _RANDOMTOOLS_H_
+
+#include "RandomFactory.h"
+#include "../VectorExceptions.h"
+#include "../VectorTools.h"
+#include "../../Exceptions.h"
+
+// From the STL:
+#include <cmath>
+#include <cassert>
+#include <ctime>
+#include <vector>
+
+namespace bpp
+{
+
+  /**
+   * @brief Utilitary function dealing with random numbers.
+   *
+   * This class uses Uniform01K generator by default.
+   * It is possible to change this by setting the DEFAULT_GENERATOR variable.
+   *
+   * This class is adapted from Pupko's SEMPHY library.
+   * It also borrow some code from Yang's PAML package.
+   *
+   * @see RandomFactory
+   */
+  class RandomTools
+  {
+  public:
+    RandomTools() {}
+    virtual ~RandomTools() {}
+
+  private:
+    /**
+     *@brief functions for the computation of incompleteBeta
+     */
+    static double incompletebetafe(double a,
+                                   double b,
+                                   double x,
+                                   double big,
+                                   double biginv);
+    static double incompletebetafe2(double a,
+                                    double b,
+                                    double x,
+                                    double big,
+                                    double biginv);
+    static double incompletebetaps(double a,
+                                   double b,
+                                   double x,
+                                   double maxgam);
+  
+  public:
+    static RandomFactory* DEFAULT_GENERATOR;
+    
+    /**
+     * @brief Get a double random value (between 0 and specified range).
+     *
+     * Note : the number you get is between 0 and entry not including entry !
+     * @param entry Max number to reach.
+     * @param generator Random number generator to use.
+     */
+    static double giveRandomNumberBetweenZeroAndEntry(double entry, const RandomFactory& generator = *DEFAULT_GENERATOR);
+
+    /**
+     * @brief Get a boolean random value.
+     *
+     * @param generator Random number generator to use.
+     */
+    static bool flipCoin(const RandomFactory& generator = *DEFAULT_GENERATOR);
+
+    /**
+     * @brief Get an integer random value (between 0 and specified range).
+     *
+     * Note : the number you get is between 0 and entry not including entry !
+     * @param entry Max number to reach.
+     * @param generator Random number generator to use.
+     */
+    static int giveIntRandomNumberBetweenZeroAndEntry(int entry, const RandomFactory& generator = *DEFAULT_GENERATOR);
+
+    /**
+     * @brief Set the default generator seed.
+     *
+     * @param seed New seed.
+     */
+    static void setSeed(long seed);
+
+    /**
+     * @return A random number drawn from a normal distribution.
+     * @param mean The mean of the law.
+     * @param variance The variance of the law.
+     * @param generator The uniform generator to use.
+     */
+    static double randGaussian(double mean, double variance, const RandomFactory& generator = *DEFAULT_GENERATOR);
+    
+    /**
+     * @return A random number drawn from a gamma distribution with unit scale (beta=1).
+     * @param dblAlpha The alpha parameter.
+     * @param generator The uniform generator to use.
+     */
+    static double randGamma(double dblAlpha, const RandomFactory& generator = *DEFAULT_GENERATOR);
+
+    /**
+     * @return A random number drawn from a gamma distribution.
+     * @param alpha The alpha parameter.
+     * @param beta The beta parameter.
+     * @param generator The uniform generator to use.
+     */
+    static double randGamma(double alpha, double beta, const RandomFactory& generator = *DEFAULT_GENERATOR);
+  
+    /**
+     * @return A random number drawn from a beta distribution.
+     * @param alpha The alpha parameter.
+     * @param beta The beta parameter.
+     * @param generator The uniform generator to use.
+     */
+
+    static double randBeta(double alpha, double beta, const RandomFactory& generator = *DEFAULT_GENERATOR);
+  
+    /**
+     * @return A random number drawn from an exponential distribution.
+     * @param mean The mean of the distribution.
+     * @param generator The uniform generator to use.
+     */
+    static double randExponential(double mean, const RandomFactory& generator = *DEFAULT_GENERATOR);
+
+    /**
+     * @brief Pick one element in a vector
+     *
+     * Pick one element randomly in a vector and return it.
+     *
+     * @param v The vector of elements.
+     * @param replace If set to yes, then elements are allowed to be picked more than once, and therefore can be re-"placed" in the final sample.(default: false)
+     * @return On element of the vector.
+     * @throw EmptyVectorException if the vector is empty.
+     *
+     * @author Sylvain Gaillard
+     */
+    template<class T>
+    static T pickOne(std::vector<T>& v, bool replace = false) throw (EmptyVectorException<T>) {
+      if (v.empty())
+        throw EmptyVectorException<T>("RandomTools::pickOne: input vector is empty", &v);
+      size_t pos = static_cast<size_t>(RandomTools::giveIntRandomNumberBetweenZeroAndEntry(static_cast<int>(v.size())));
+      if (replace)
+        return v[pos];
+      else {
+        T e = v[pos];
+        v[pos] = v.back();
+        v.pop_back();
+        return e;
+      }
+    }
+
+    /**
+     * @brief Sample a vector.
+     *
+     * The sample is a new vector of the specified size.
+     * If the size of the sample is identical to the original vector,
+     * the result is a shuffle of the original vector.
+     *
+     * @param vin The vector to sample.
+     * @param vout [out] The output vector to fill, with the appropriate size.
+     * @param replace Should sampling be with replacement?
+     * @return A vector which is a sample of v.
+     * @throw IndexOutOfBoundException if the sample size exceeds the original
+     * size when sampling without replacement.
+     * @throw EmptyVectorException if the vector is empty.
+     *
+     * @author Sylvain Gaillard
+     */
+    template<class T> 
+    static void getSample(const std::vector<T>& vin, std::vector<T>& vout, bool replace = false) throw (EmptyVectorException<T>, IndexOutOfBoundsException)
+    {
+      if (vout.size() > vin.size() && !replace)
+        throw IndexOutOfBoundsException("RandomTools::getSample: size exceeded v.size.", vout.size(), 0, vin.size());
+      std::vector<size_t> hat(vin.size());
+      for (size_t i = 0 ; i < vin.size() ; i++)
+        hat[i] = i;
+      for (size_t i = 0 ; i < vout.size() ; i++)
+        vout[i] = vin[pickOne(hat, replace)];
+    }
+
+    /**
+     * @brief Pick one element in a vector, with associated probability weights
+     *
+     * Pick one element randomly in a vector and return it.
+     * If you choose to make the picking without replacement the element is
+     * removed from the vector, and so is the corresponding weight
+     *
+     * @param v The vector of elements.
+     * @param w The vector of weight associated to the v elements.
+     * @param replace Should pick with replacement? (default: false)
+     * @return On element of the vector.
+     * @throw EmptyVectorException if the vector is empty.
+     *
+     * @author Julien Dutheil
+     */
+    template<class T>
+    static T pickOne(std::vector<T>& v, std::vector<double>& w, bool replace = false) throw (EmptyVectorException<T>) {
+      if (v.empty())
+        throw EmptyVectorException<T>("RandomTools::pickOne (with weight): input vector is empty", &v);
+      //Compute cumulative sum of weights:
+      std::vector<double> sumw = VectorTools::cumSum(w);
+      //Convert to cumulative distribution:
+      sumw /= sumw.back();
+      //Get random positions:
+      double prob = RandomTools::giveRandomNumberBetweenZeroAndEntry(1.0);
+      size_t pos = v.size() - 1;
+      for (size_t i = 0; i < v.size(); ++i) {
+        if (prob < sumw[i]) {
+          pos = i;
+          break;
+        }
+      }
+      if (replace)
+        return v[pos];
+      else {
+        T e = v[pos];
+        v[pos] = v.back();
+        v.pop_back();
+        w[pos] = w.back();
+        w.pop_back();
+        return e;
+      }
+    }
+
+    /**
+     * @brief Sample a vector, with associated probability weights.
+     *
+     * The sample is a new vector of the specified size.
+     * If the size of the sample is identical to the original vector,
+     * the result is a shuffle of the original vector.
+     *
+     * It has to be noted that in case of sampling without replacement,
+     * the effect of the weighting scheme will be lower as the sampe size becomes
+     * close to the population size. In case the two are equal (pure permutations),
+     * the weigths have no effect at all.
+     *
+     * @param vin The vector to sample.
+     * @param w The vector of weights.
+     * @param vout [out] The output vector to fill, with the appropriate size.
+     * @param replace Should sampling be with replacement?
+     * @return A vector which is a sample of v.
+     * @throw IndexOutOfBoundException if the sample size exceeds the original
+     * size when sampling without replacement.
+     * @throw EmptyVectorException if the vector is empty.
+     *
+     * @author Julien Dutheil
+     */
+   template<class T> 
+    static void getSample(const std::vector<T>& vin, const std::vector<double>& w, std::vector<T>& vout, bool replace = false) throw (EmptyVectorException<T>, IndexOutOfBoundsException)
+    {
+      if (vout.size() > vin.size() && !replace)
+        throw IndexOutOfBoundsException("RandomTools::getSample (with weights): size exceeded v.size.", vout.size(), 0, vin.size());
+      std::vector<size_t> hat(vin.size());
+      for (size_t i = 0 ; i < vin.size() ; i++)
+        hat[i] = i;
+      std::vector<double> w2(w); //non const copy
+      for (size_t i = 0 ; i < vout.size() ; i++)
+        vout[i] = vin[pickOne(hat, w2, replace)];
+    }
+
+    /**
+     * @brief Get a random state from a set of probabilities/scores.
+     *
+     * The input probabilities are scaled so that they sum to one.
+     * If 'x' probabilities are provided as input, the output vector will contain values between 0 and 'x-1'.
+     *
+     * @param n The sample size.
+     * @param probs The set of intput probabilities.
+     * @return A vector of int values corresponding to the output states. States are supposed to be in the same order as the input probabilities, the first state being '0'.
+     */ 
+    static std::vector<size_t> randMultinomial(size_t n, const std::vector<double>& probs);
+
+    /**
+     * @name Probability functions.
+     *
+     * @{
+     * Adapted from Yang's PAML package.
+     *
+     */
+
+    /**
+     * @brief Normal quantile function.
+     *
+     * Returns z so that Prob{x<z}=prob where x ~ N(0,1) and (1e-12)<prob<1-(1e-12)
+     * returns (-9999) if in error
+     * Odeh RE & Evans JO (1974) The percentage points of the normal distribution.
+     * Applied Statistics 22: 96-97 (AS70)
+     *
+     * Newer methods:
+     *  Wichura MJ (1988) Algorithm AS 241: the percentage points of the
+     *    normal distribution.  37: 477-484.
+     *  Beasley JD & Springer SG  (1977).  Algorithm AS 111: the percentage 
+     *    points of the normal distribution.  26: 118-121.
+     *
+     * @param prob The probability.
+     * @return The quantile corresponding to prob.
+     */
+    static double qNorm(double prob);
+  
+    /**
+     * @brief Normal quantile function.
+     *
+     * Returns z so that Prob{x<z}=prob where x ~ N(mu,sigma^2) and (1e-12)<prob<1-(1e-12)
+     * returns (-9999) if in error
+     * Odeh RE & Evans JO (1974) The percentage points of the normal distribution.
+     * Applied Statistics 22: 96-97 (AS70)
+     *
+     * Newer methods:
+     *  Wichura MJ (1988) Algorithm AS 241: the percentage points of the
+     *    normal distribution.  37: 477-484.
+     *  Beasley JD & Springer SG  (1977).  Algorithm AS 111: the percentage 
+     *    points of the normal distribution.  26: 118-121.
+     *
+     * @param prob The probability.
+     * @param mu The mean of the distribution
+     * @param sigma The standard deviation of the distribution
+     * @return The quantile corresponding to prob.
+     */
+    static double qNorm(double prob, double mu, double sigma);
+
+    /**
+     * @brief Computes \f$ln\left(\Gamma\left(\alpha\right)\right)\f$ given \f$\alpha\f$.
+     * 
+     * Returns ln(gamma(alpha)) for alpha>0, accurate to 10 decimal places.  
+     * Stirling's formula is used for the central polynomial part of the procedure.
+     * Pike MC & Hill ID (1966) Algorithm 291: Logarithm of the gamma function.
+     * Communications of the Association for Computing Machinery, 9:684
+     *
+     * @param alpha Alpha parameter.
+     * @return \f$ln\left(\Gamma\left(\alpha\right)\right)\f$
+     */
+    static double lnGamma (double alpha);
+
+    /**
+     * @brief Returns the incomplete gamma ratio I(x,alpha).
+     *
+     * X is the upper limit of the integration and alpha is the shape parameter.
+     * returns (-1) if in error
+     * ln_gamma_alpha = ln(Gamma(alpha)), is almost redundant.
+     * (1) series expansion     if (alpha>x || x<=1)
+     * (2) continued fraction   otherwise
+     * RATNEST FORTRAN by
+     * Bhattacharjee GP (1970) The incomplete gamma integral.  Applied Statistics,
+     * 19: 285-287 (AS32)
+     *
+     * @param x the upper limit of the integration.
+     * @param alpha the shape parameter.
+     * @param ln_gamma_alpha ln(Gamma(alpha)).
+     */
+    static double incompleteGamma(double x, double alpha, double ln_gamma_alpha);
+
+
+    /**
+     * @brief \f$\chi^2\f$ quantile function.
+     * 
+     * returns z so that Prob{x<z}=prob where x is Chi2 distributed with df=v
+     * returns -1 if in error.   0.000002<prob<0.999998
+     * RATNEST FORTRAN by
+     * Best DJ & Roberts DE (1975) The percentage points of the 
+     * Chi2 distribution.  Applied Statistics 24: 385-388.  (AS91)
+     * Converted into C by Ziheng Yang, Oct. 1993.
+     *
+     * @param prob The probability.
+     * @param v number of degree of freedom.
+     * @return The quantile corresponding to prob.
+     */
+    static double qChisq(double prob, double v);
+
+    /**
+     * @brief \f$\chi^2\f$ cumulative probability function.
+     *
+     * @param x The quantile for which the probability should be computed.
+     * @param v number of degree of freedom.
+     * @return The corresponding probability of the quantile.
+     */
+    static double pChisq(double x, double v)
+    {
+      if (x < 0) return 0;
+      return pGamma(x, v / 2, 0.5);
+    }
+
+    /**
+     * @brief The Gamma quantile function.
+     *
+     * @param prob The probability.
+     * @param alpha Alpha parameter.
+     * @param beta  Beta parameter.
+     * @return The quantile corresponding to prob.
+     */
+    static double qGamma(double prob, double alpha, double beta)
+    {
+      return qChisq(prob,2.0*(alpha))/(2.0*(beta));
+    }
+
+    /**
+     * @brief \f$\Gamma\f$ cumulative probability function.
+     *
+     * @param x The quantile for which the probability should be computed.
+     * @param alpha Alpha parameter.
+     * @param beta  Beta parameter.
+     * @return The corresponding probability of the quantile.
+     * @throw Exception If alpha or beta is invalid (<0).
+     *
+     */
+    static double pGamma(double x, double alpha, double beta) throw (Exception)
+    {
+      if (alpha < 0) throw Exception("RandomTools::pGamma. Negative alpha is not allowed.");
+      if (beta < 0) throw Exception("RandomTools::pGamma. Negative beta is not allowed.");
+      if (alpha == 0.) return 1.;
+      return incompleteGamma(beta*x, alpha, lnGamma(alpha));
+    }
+
+    /** @} */
+    
+    /**
+     * @name Other probability functions.
+     *
+     * Adapted from C routines for R programming langague
+     *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
+     *  Copyright (C) 1998    Ross Ihaka
+     *  Copyright (C) 2000-2002 The R Development Core Team
+     *  Copyright (C) 2003    The R Foundation
+
+     * @{
+     */
+    /**
+     * @brief Normal cumulative function.
+     *
+     * Returns Prob{x<=z} where x ~ N(0,1)
+     
+     * @param z the value.
+     * @return The corresponding probability.
+     */
+    static double pNorm(double z);
+
+    /* @brief Normal cumulative function.
+    *
+    * Returns Prob{x<=z} where x ~ N(mu,sigma^2)
+     
+    * @param z the value.
+    * @param mu The mean of the distribution
+    * @param sigma The standard deviation of the distribution
+    * @return The corresponding probability.
+    */
+    
+    static double pNorm(double z, double mu, double sigma);
+
+    /**
+     * @brief Computes
+     * \f$ln\left(Beta\left(\alpha,\beta\right)\right)\f$ given
+     * \f$\alpha\f$ and \f$b\eta\f$.
+     * 
+     * Returns ln(beta(alpha,beta)) for alpha>0 and beta>0.
+     *
+     * @param alpha, beta Alpha and Beta parameters.
+     * @return \f$ln\left(Beta\left(\alpha,\beta\right)\right)\f$
+     */
+
+    static double lnBeta (double alpha, double beta);
+
+    /**
+     * @brief Returns the regularized incomplete beta function
+     * @f$I_x(\alpha,\beta) = pbeta(x,\alpha,\beta at f$
+     *
+     * alpha and beta are the parameters of the function.
+     *
+     * Adapted From Cephes Math Library Release 2.8:  June, 2000
+     * Copyright by Stephen L. Moshier
+     * Under GPL License
+     *
+     * @param x the upper limit of the integration.
+     * @param alpha, beta the shape parameters.
+     */
+    static double incompleteBeta(double x, double alpha, double beta);
+    static double pBeta(double x, double alpha, double beta)
+    {
+      return incompleteBeta(x,alpha,beta);
+    }
+
+    /**
+     * @brief The Beta quantile function.
+     *
+     * An adaptation from the C code of R
+     *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
+     *  Copyright (C) 1998--2007  The R Development Core Team
+     *  based on code (C) 1979 and later Royal Statistical Society
+     *
+     * @param prob The probability.
+     * @param alpha Alpha parameter.
+     * @param beta  Beta parameter.
+     * @return The quantile corresponding to prob.
+     */
+    static double qBeta(double prob, double alpha, double beta);
+
+    /** @} */
+
+  private:
+    static double DblGammaGreaterThanOne(double dblAlpha, const RandomFactory& generator);
+    static double DblGammaLessThanOne(double dblAlpha, const RandomFactory& generator);
+  };
+
+} //end of namespace bpp.
+
+#endif  //_RANDOMTOOLS_H_
+
diff --git a/src/Bpp/Numeric/Random/Uniform01K.cpp b/src/Bpp/Numeric/Random/Uniform01K.cpp
new file mode 100644
index 0000000..af7213f
--- /dev/null
+++ b/src/Bpp/Numeric/Random/Uniform01K.cpp
@@ -0,0 +1,106 @@
+//
+// File Uniform01K.cpp
+// Author : Sylvain Gaillard
+// Last modification : Friday September 24 2004
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "Uniform01K.h"
+
+#include "../NumTools.h"
+
+using namespace bpp;
+
+const long Uniform01K::MAXNUMBER = 1000000000;
+const long Uniform01K::ZERO = 0;
+const long Uniform01K::MODSEED = 256434901;
+
+//** Class constructor: *******************************************************/
+
+Uniform01K::Uniform01K(long seed) :
+  _it1(), _it2()
+{
+	setSeed(seed);
+}
+
+//** Class destructor: *******************************************************/
+Uniform01K::~Uniform01K() {}
+
+//** Other methodes: *********************************************************/
+
+void Uniform01K::setSeed(long seed)
+{
+	long tmp1, tmp2;
+	unsigned short i, ii, j;
+	tmp1 = NumTools::abs(MODSEED - NumTools::abs(seed));
+	tmp1 %= MAXNUMBER;
+	_tab[55] = tmp1;
+	tmp2 = 1;
+
+	for (i = 1 ; i <= 54 ; i++)
+  {
+		ii = static_cast<unsigned short>((21 * i) % 55);
+		_tab[ii] = tmp2;
+		tmp2 = tmp1 - tmp2;
+
+		if (tmp2 < ZERO) tmp2 += MAXNUMBER;
+
+		tmp1 = _tab[ii];
+	}
+
+	for (j=1 ; j<=4 ; j++)
+		for (i=1 ; i<=55 ; i++)
+    {
+			_tab[i] -= _tab[1 + (i + 30) % 55];
+			if (_tab[i] < ZERO) _tab[i] += MAXNUMBER;
+		}
+	_it1 = 0;
+	_it2 = 31;
+}
+
+double Uniform01K::drawNumber() const
+{
+	if (++_it1 == 56) _it1 = 1;
+	if (++_it2 == 56) _it2 = 1;
+
+	long tmp = _tab[_it1] - _tab[_it2];
+	if (tmp < ZERO) tmp += MAXNUMBER;
+	_tab[_it2] = tmp;
+	double r = static_cast<double>(static_cast<long double>(tmp) / MAXNUMBER);
+	//if (r < 0.) return drawNumber(); // In case of negative number, take the next one in the serie.
+	//if (r > 1.) return drawNumber(); // In case of number > 1, take the next one in the serie.
+	return r;
+}
+
diff --git a/src/Bpp/Numeric/Random/Uniform01K.h b/src/Bpp/Numeric/Random/Uniform01K.h
new file mode 100644
index 0000000..408fd10
--- /dev/null
+++ b/src/Bpp/Numeric/Random/Uniform01K.h
@@ -0,0 +1,97 @@
+//
+// File Uniform01K.h
+// Author : Sylvain Gaillard
+// Last modification : Friday September 24 2004
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _UNIFORM01K_H_
+#define _UNIFORM01K_H_
+
+#include "RandomFactory.h"
+
+namespace bpp
+{
+
+/**
+ * @brief A uniform random number generator.
+ *
+ * This is a uniform generator which draw double between 0 and 1 excluding
+ * the end points.
+ * This generator is based on an algorithm described by D.E. Knuth, 1981,
+ * "Seminumerical Algorithms" 2nd ed., vol.2 of "The Art of Computer
+ * Programming" (Reading, MA: Addison-Wesley), §§3.2-3.3.
+ * 
+ * The algorithm used here is the one described in "Numerical Recipes in C".
+ */
+class Uniform01K : public virtual RandomFactory
+{
+	public: // Constructors and destructor
+		/**
+		 * @brief Create a Random Number Generator.
+		 *
+		 * @param seed The seed for the random numbers.
+		 */
+		Uniform01K(long seed);
+
+		/**
+		 * @brief Destroy the generator.
+		 */
+		virtual ~Uniform01K();
+
+	public:
+		/**
+		 * @brief Set the seed for a new set of random numbers.
+		 */
+		void setSeed(long seed);
+
+		/**
+		 * @brief Get a random number between 0.0 and 1.0 (exclusive of the end point values).
+		 */
+		double drawNumber() const;
+
+	private:
+		static const long MAXNUMBER;
+		static const long ZERO;
+		static const long MODSEED;
+		mutable long _tab[56];
+		mutable unsigned int _it1;
+		mutable unsigned int _it2;
+};
+
+} //end of namespace bpp.
+
+#endif // _UNIFORM01K_H_
+
diff --git a/src/Bpp/Numeric/Random/Uniform01QD.cpp b/src/Bpp/Numeric/Random/Uniform01QD.cpp
new file mode 100644
index 0000000..cb13fce
--- /dev/null
+++ b/src/Bpp/Numeric/Random/Uniform01QD.cpp
@@ -0,0 +1,54 @@
+//
+// File Uniform01QD.cpp
+// Author : Sylvain Gaillard
+// Last modification : Friday September 24 2004
+//
+
+/*
+Copyright or © or Copr. Bio++ Development TeamCNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "Uniform01QD.h"
+
+using namespace bpp;
+
+#include <cmath>
+
+using namespace std;
+
+double Uniform01QD::drawNumber() const
+{
+	seed_ = seed_ * 1103515245 + 12345;
+	if (seed_ < 0) seed_ = -seed_;
+	return static_cast<double>(seed_ / 2147483648.0L);
+}
+
diff --git a/src/Bpp/Numeric/Random/Uniform01QD.h b/src/Bpp/Numeric/Random/Uniform01QD.h
new file mode 100644
index 0000000..214f619
--- /dev/null
+++ b/src/Bpp/Numeric/Random/Uniform01QD.h
@@ -0,0 +1,91 @@
+//
+// File Uniform01QD.h
+// Author : Sylvain Gaillard
+// Last modification : Friday September 24 2004
+//
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+
+#ifndef _UNIFORM01QD_H_
+#define _UNIFORM01QD_H_
+
+#include "RandomFactory.h"
+
+namespace bpp
+{
+
+/**
+ * @brief A quick and dirty uniform random number generator.
+ *
+ * This is a congruential uniform generator which draw double between 0 and 1 excluding
+ * the end points.
+ *
+ * WARNING!!! Only works on 32bits architectures!
+ */
+class Uniform01QD : public virtual RandomFactory
+{
+	public: // Constructors and destructor
+		/**
+		 * @brief Create a Random Number Generator.
+		 *
+		 * @param seed The seed for the random numbers.
+		 */
+		Uniform01QD(long seed): seed_(seed) {}
+
+		/**
+		 * @brief Destroy the generator.
+		 */
+		virtual ~Uniform01QD() {}
+
+	public:
+		/**
+		 * @brief Set the seed for a new set of random numbers.
+		 */
+		void setSeed(long seed) { seed_ = seed; }
+
+		/**
+		 * @brief Get a random number between 0.0 and 1.0 (exclusive of the end point values).
+		 */
+		double drawNumber() const;
+
+	private:
+		mutable long seed_;
+};
+
+} //end of namespace bpp.
+
+#endif // _UNIFORM01QD_H_
+
diff --git a/src/Bpp/Numeric/Random/Uniform01WH.cpp b/src/Bpp/Numeric/Random/Uniform01WH.cpp
new file mode 100644
index 0000000..6bdb7e2
--- /dev/null
+++ b/src/Bpp/Numeric/Random/Uniform01WH.cpp
@@ -0,0 +1,56 @@
+//
+// File Uniform01WH.cpp
+// Author : Sylvain Gaillard
+// Last modification : Friday September 24 2004
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "Uniform01WH.h"
+
+using namespace bpp;
+
+#include <cmath>
+
+using namespace std;
+
+double Uniform01WH::drawNumber() const
+{
+	double i;
+	ix = (171 * ix) % 30269;
+	iy = (172 * iy) % 30307;
+	iz = (170 * iz) % 30323;
+	return modf((double) ix / 30269. + (double) iy / 30307. + (double) iz / 30323, &i);
+}
+
diff --git a/src/Bpp/Numeric/Random/Uniform01WH.h b/src/Bpp/Numeric/Random/Uniform01WH.h
new file mode 100644
index 0000000..0e7bab7
--- /dev/null
+++ b/src/Bpp/Numeric/Random/Uniform01WH.h
@@ -0,0 +1,97 @@
+//
+// File Uniform01WH.h
+// Author : Sylvain Gaillard
+// Last modification : Friday September 24 2004
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _UNIFORM01WH_H_
+#define _UNIFORM01WH_H_
+
+#include "RandomFactory.h"
+
+namespace bpp
+{
+
+/**
+ * @brief A uniform random number generator.
+ *
+ * This is a congruential uniform generator which draw double between 0 and 1 excluding
+ * the end points.
+ * This generator is based on a Fortan routine from Wichmann, B. A. and Hill, I. D. (1982).
+ * "An efficient and portable pseudorandom number generator," Applied Statistics, 31, 188-190
+ */
+class Uniform01WH : public virtual RandomFactory
+{
+	public: // Constructors and destructor
+		/**
+		 * @brief Create a Random Number Generator.
+		 *
+		 * @param seed The seed for the random numbers.
+		 */
+		Uniform01WH(long seed) : ix(seed), iy(seed), iz(seed) {}
+
+		/**
+		 * @brief Destroy the generator.
+		 */
+		virtual ~Uniform01WH();
+
+	public:
+		/**
+		 * @brief Set the seed for a new set of random numbers.
+		 */
+		void setSeed(long seed) { setSeeds(seed); }
+
+		/**
+		 * @brief Set the three seeds.
+		 */
+		void setSeeds(long seed1, long seed2 = 20356, long seed3 = 35412)
+    {
+      ix = seed1; iy = seed2; iz = seed3;
+    }
+
+		/**
+		 * @brief Get a random number between 0.0 and 1.0 (exclusive of the end point values).
+		 */
+		double drawNumber() const;
+
+	private:
+		mutable long ix, iy, iz;
+};
+
+} //end of namespace bpp.
+
+#endif // _UNIFORM01WH_H_
+
diff --git a/src/Bpp/Numeric/Range.h b/src/Bpp/Numeric/Range.h
new file mode 100644
index 0000000..81cf091
--- /dev/null
+++ b/src/Bpp/Numeric/Range.h
@@ -0,0 +1,519 @@
+//
+// File: Range.h
+// Created by: Julien Dutheil
+// Created on: Mon Nov 21 15:52 2011
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#ifndef _RANGE_H_
+#define _RANGE_H_
+
+#include "../Text/TextTools.h"
+#include "../Clonable.h"
+
+//From the STL:
+#include <string>
+#include <set>
+#include <algorithm>
+
+#include <iostream>
+
+namespace bpp {
+
+/**
+ * @brief The Range class, defining an interval.
+ *
+ * Methods are provided for extending the range, get union and intersection.
+ */
+template<class T> class Range:
+  public virtual Clonable
+{
+  private:
+    T begin_;
+    T end_;
+
+  public:
+    /**
+     * @brief Creates a new interval.
+     *
+     * If a > b, then the positions are swapped.
+     * If a == b, the interval is considered empty.
+     * Coordinates are 0-based and of type [a, b[,
+     * so that the length of the interval is computed as
+     * b - a.
+     *
+     * @param a First position
+     * @param b Second position
+     */
+    Range(const T& a = 0, const T& b = 0):
+      begin_(std::min(a, b)),
+      end_(std::max(a, b))
+    {}
+
+    Range(const Range<T>& range): begin_(range.begin_), end_(range.end_) {}
+    
+    Range<T>& operator=(const Range<T>& range) {
+      begin_ = range.begin_;
+      end_   = range.end_;
+      return *this;
+    }
+
+    Range<T>* clone() const { return new Range<T>(*this); }
+
+    virtual ~Range() {}
+
+  public:
+    bool operator==(const Range<T>& r) const {
+      return begin_ == r.begin_ && end_ == r.end_;
+    }
+    bool operator!=(const Range<T>& r) const {
+      return begin_ != r.begin_ || end_ != r.end_;
+    }
+    bool operator<(const Range<T>& r) const {
+      return begin_ < r.begin_ || end_ < r.end_;
+    }
+    virtual Range& operator+=(const T& val) {
+      begin_ += val;
+      end_ += val;
+      return *this;
+    }
+    virtual Range operator+(const T& val) {
+      return Range<T>(*this) += val;
+    }
+    virtual Range& operator-=(const T& val) {
+      begin_ -= val;
+      end_ -= val;
+      return *this;
+    }
+    virtual Range operator-(const T& val) {
+      return Range<T>(*this) -= val;
+    }
+
+    T begin() const { return begin_; }
+    
+    T end() const { return end_; }
+    
+    T length() const { return end_ - begin_; }
+
+    /**
+     * @param r Range to compare with.
+     * @return True if the two intervals overlap.
+     */
+    bool overlap(const Range& r) const
+    {
+      return (r.begin_ < end_ && r.end_ > begin_);
+    }
+
+    /**
+     * @param r Range to compare with.
+     * @return True if the two intervals are contiguous (i.e. the two intervals
+     * are adjacent and share one bound).
+     */
+    bool isContiguous(const Range& r) const
+    {
+      return (r.begin_ == end_ || r.end_ == begin_);
+    }
+
+    /**
+     * @param r Range to compare with.
+     * @return True if the given interval is included in the instanciated one.
+     */
+    bool contains(const Range& r) const
+    {
+      return (r.begin_ >= begin_ && r.end_ <= end_);
+    }
+
+    /**
+     * @brief Expand the current interval with the given one.
+     *
+     * If the two intervals do not overlap, then the interval is not modified.
+     * @param r input interval.
+     */
+    void expandWith(const Range& r)
+    {
+      if (r.begin_ < begin_ && r.end_ >= begin_)
+        begin_ = r.begin_;
+      if (r.end_ > end_ && r.begin_ <= end_)
+        end_ = r.end_;
+    }
+
+    /**
+     * @brief Restrict the current interval to the intersection with the given one.
+     *
+     * If the two intervals do not overlap, then the interval is set to empty.
+     * @param r input interval.
+     */
+    void sliceWith(const Range& r)
+    {
+      if (!overlap(r)) {
+        begin_ = 0;
+        end_   = 0;
+      } else {
+        if (r.begin_ > begin_ && r.begin_ <= end_)
+          begin_ = r.begin_;
+        if (r.end_ < end_ && r.end_ >= begin_)
+          end_ = r.end_;
+      }
+    }
+
+    /**
+     * @return True if then begining position equals the ending one.
+     */
+    bool isEmpty() const { return begin_ == end_; }
+
+    /**
+     * @return A string describing the range.
+     */
+    std::string toString() const {
+      return ("[" + TextTools::toString(begin_) + "," + TextTools::toString(end_) + "[");
+    }
+
+};
+
+/**
+ * @brief Interface discribing a collection of Range objects.
+ */
+template<class T> class RangeCollection {
+  public:
+    virtual ~RangeCollection() {}
+    /**
+     * @brief Add a new range to the collection.
+     *
+     * @param r The range to add to the collection.
+     */
+    virtual void addRange(const Range<T>& r) = 0;
+
+    /**
+     * @brief Get the intersection with a given range.
+     *
+     * The new multirange is the union of all ranges intersections with the given range.
+     *
+     * @param r Restriction range.
+     */
+    virtual void restrictTo(const Range<T>& r) = 0;
+
+    /**
+     * @brief Only keep the ranges that fall within the given range.
+     *
+     * @param r Restriction range.
+     */
+    virtual void filterWithin(const Range<T>& r) = 0;
+
+    /**
+     * @return A string representation of the set of intervals.
+     */
+    virtual std::string toString() const = 0;
+
+    /**
+     * @return True if the set does not contain any range.
+     */
+    virtual bool isEmpty() const = 0;
+
+    /**
+     * @return The number of ranges in the collection.
+     */
+    virtual size_t size() const = 0;
+
+    /**
+     * @return The ith range in the collection.
+     */
+    virtual const Range<T>& getRange(size_t i) const = 0;
+
+    /**
+     * @brief Clear the collection.
+     */
+    virtual void clear() = 0;
+};
+
+/**
+ * @brief A special class used inside RangeCollection.
+ */
+template<class T> class rangeComp_ {
+  public:
+    bool operator() (const Range<T>* a, const Range<T>* b) const {
+      return ((*a) < (*b));
+    }
+};
+
+/**
+ * @brief This class implements a data structure describing a set of intervales.
+ *
+ * Intervales can be overlapping, but empty intervales will be ignored/removed.
+ */
+template<class T> class RangeSet:
+  public RangeCollection<T>
+{
+  public:
+
+  private:
+    std::set< Range<T>*, rangeComp_<T> > ranges_;
+
+  public:
+    RangeSet(): ranges_() {}
+
+    RangeSet(const RangeSet<T>& set): ranges_()
+    {
+      for (typename std::set< Range<T>* >::iterator it = set.ranges_.begin(); it != set.ranges_.end(); ++it) {
+        ranges_.insert(ranges_.end(), (**it).clone());
+      }
+    }
+
+    RangeSet& operator=(const RangeSet<T>& set)
+    {
+      clear_();
+      for (typename std::set< Range<T>* >::iterator it = set.ranges_.begin(); it != set.ranges_.end(); ++it) {
+        ranges_.insert(ranges_.end(), (**it).clone());
+      }
+      return *this;
+    }
+
+    virtual ~RangeSet() {
+      clear_();
+    }
+
+  public:
+    void addRange(const Range<T>& r) {
+      if (!r.isEmpty())
+        ranges_.insert(r.clone());
+    }
+
+    void restrictTo(const Range<T>& r) {
+      typename std::set< Range<T>* >::iterator it = ranges_.begin();
+      while (it != ranges_.end()) {
+        (**it).sliceWith(r);
+        if ((**it).isEmpty()) {
+          typename std::set< Range<T>* >::iterator it2 = it;
+          delete *it;
+          ++it;
+          ranges_.erase(it2);
+        } else {
+          ++it;
+        }
+      }
+    }
+
+    void filterWithin(const Range<T>& r) {
+      typename std::set< Range<T>* >::iterator it = ranges_.begin();
+      while (it != ranges_.end()) {
+        if (r.contains(**it)) {
+          ++it;
+        } else {
+          typename std::set< Range<T>* >::iterator it2 = it;
+          delete *it;
+          ++it;
+          ranges_.erase(it2);
+        }
+      }
+    }
+    
+    std::string toString() const {
+      std::string s = "{ ";
+      for (typename std::set< Range<T>* >::const_iterator it = ranges_.begin(); it != ranges_.end(); ++it) {
+        s += (**it).toString() + " ";
+      }
+      s += "}";
+      return s;
+    }
+
+    bool isEmpty() const { return ranges_.size() == 0; }
+    
+    size_t size() const { return ranges_.size(); }
+
+    const Range<T>& getRange(size_t i) const {
+      typename std::set< Range<T>* >::const_iterator it = ranges_.begin();
+      for (size_t c = 0; c < i; ++c)
+        ++it;
+        //it = it++;
+      return **it;
+    }
+    
+    const std::set< Range<T>*, rangeComp_<T> >& getSet() const { return ranges_; }
+
+    std::set< Range<T>*, rangeComp_<T> >& getSet() { return ranges_; }
+
+    void clear() {
+      clear_();
+    }
+
+  private:
+    void clear_() {
+      for (typename std::set< Range<T>* >::const_iterator it = ranges_.begin(); it != ranges_.end(); ++it) {
+        delete *it;
+      }
+      ranges_.clear();
+    }
+};
+
+/**
+ * @brief This class implements a data structure describing a set of non-overlapping intervales.
+ */
+template<class T> class MultiRange:
+  public RangeCollection<T>
+{
+  private:
+    std::vector<Range<T>*> ranges_;
+
+  public:
+    MultiRange(): ranges_() {}
+
+    MultiRange(const MultiRange<T>& mr): ranges_()
+    {
+      for (size_t i = 0; i < mr.ranges_.size(); ++i)
+        ranges_.push_back(mr.ranges_[i]->clone());
+    }
+
+    MultiRange& operator=(const MultiRange<T>& mr)
+    {
+      clear_();
+      for (size_t i = 0; i < mr.ranges_.size(); ++i)
+        ranges_.push_back(mr.ranges_[i]->clone());
+      return *this;
+    }
+
+    virtual ~MultiRange() {
+      clear_();
+    }
+
+
+  public:
+    void addRange(const Range<T>& r) {
+      //this is a bit tricky, as many cases can happen. we have to check how many ranges overlap with the new one:
+      std::vector<size_t> overlappingPositions;
+      for (size_t i = 0; i < ranges_.size(); ++i) {
+        if (ranges_[i]->overlap(r))
+          overlappingPositions.push_back(i);
+      }
+      //check if not overlap:
+      if (overlappingPositions.size() == 0) {
+        //We simply add the new range to the list:
+        ranges_.push_back(r.clone());
+      } else {
+        //We extend the first overlapping element:
+        ranges_[overlappingPositions[0]]->expandWith(r);
+        //Now we merge all other overlapping ranges, if any:
+        for (size_t i = overlappingPositions.size() - 1; i > 0; --i) {
+          //Expand first range:
+          ranges_[overlappingPositions[0]]->expandWith(*ranges_[overlappingPositions[i]]);
+          //Then removes this range:
+          delete ranges_[overlappingPositions[i]];
+          ranges_.erase(ranges_.begin() + overlappingPositions[i]);
+        }
+      }
+      clean_();
+    }
+
+    void restrictTo(const Range<T>& r) {
+      for (size_t i = 0; i < ranges_.size(); ++i)
+        ranges_[i]->sliceWith(r);
+      clean_();
+    }
+
+    void filterWithin(const Range<T>& r) {
+      typename std::vector< Range<T>* >::iterator it = ranges_.begin();
+      while (it != ranges_.end()) {
+        if (r.contains(**it)) {
+          ++it;
+        } else {
+          delete *it;
+          it = ranges_.erase(it);
+        }
+      }
+    }
+ 
+    /**
+     * @return A string representation of the set of intervals.
+     */
+    std::string toString() const {
+      std::string s = "{ ";
+      for (size_t i = 0; i < ranges_.size(); ++i)
+        s += ranges_[i]->toString() + " ";
+      s += "}";
+      return s;
+    }
+
+    /**
+     * @return A vector with all interval bounds.
+     */
+    std::vector<T> getBounds() const {
+      std::vector<T> bounds;
+      for (size_t i = 0; i < ranges_.size(); ++i) {
+        bounds.push_back(ranges_[i]->begin());
+        bounds.push_back(ranges_[i]->end());
+      }
+      return bounds;
+    }
+
+    /**
+     * @return True if the set does not contain any range.
+     */
+    bool isEmpty() const { return ranges_.size() == 0; }
+
+    size_t size() const { return ranges_.size(); }
+
+    const Range<T>& getRange(size_t i) const { return *ranges_[i]; }
+
+    void clear() {
+      clear_();
+    }
+
+  private:
+    void clean_() {
+      //Reorder
+      rangeComp_<T> comp;
+      std::sort(ranges_.begin(), ranges_.end(), comp);
+      //Remove empty intervals:
+      typename std::vector< Range<T>* >::iterator it = ranges_.begin();
+      while (it != ranges_.end()) {
+        if ((**it).isEmpty()) {
+          delete *it;
+          it = ranges_.erase(it);
+        } else {
+          ++it;
+        }
+      }
+    }
+  private:
+    void clear_() {
+      for (size_t i = 0; i < ranges_.size(); ++i) {
+        delete ranges_[i];
+      }
+      ranges_.clear();
+    }
+
+};
+
+} //end of namespace bpp
+
+#endif //_RANGE_H_
diff --git a/src/Bpp/Numeric/Stat/ContingencyTableTest.cpp b/src/Bpp/Numeric/Stat/ContingencyTableTest.cpp
new file mode 100644
index 0000000..f70d6ae
--- /dev/null
+++ b/src/Bpp/Numeric/Stat/ContingencyTableTest.cpp
@@ -0,0 +1,129 @@
+//
+// File: ContingencyTableTest.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Dec 09 14:20 2010
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "ContingencyTableTest.h"
+#include "../Random/ContingencyTableGenerator.h"
+
+#include "../../App/ApplicationTools.h"
+#include "../VectorTools.h"
+#include "../Random/RandomTools.h"
+
+#include <iostream>
+#include <algorithm>
+
+using namespace bpp;
+using namespace std;
+
+ContingencyTableTest::ContingencyTableTest(const std::vector< std::vector<size_t> >& table, unsigned int nbPermutations, bool warn):
+  statistic_(0),
+  pvalue_(0),
+  df_(0),
+  margin1_(table.size()),
+  margin2_(0)
+{
+  //Compute marginals:
+  size_t n = table.size();
+  if (n < 2)
+    throw Exception("ContingencyTableTest. Table size should be at least 2x2!");
+  size_t m = table[0].size();
+  if (m < 2)
+    throw Exception("ContingencyTableTest. Table size should be at least 2x2!");
+  margin2_.resize(m);
+  for (size_t j = 0; j < m; ++j)
+    margin2_[j] = 0;
+  bool test = false;
+  for (size_t i = 0; i < n; ++i) {
+    if (table[i].size() != m)
+      throw Exception("ContingencyTableTest. Input array has non-homogeneous dimensions!");
+    for (size_t j = 0; j < m; ++j) {
+      size_t c = table[i][j];
+      if (c <= 5) test = true;
+      margin1_[i] += c;
+      margin2_[j] += c;
+    }
+  }
+  for (size_t i = 0; i < n; ++i)
+    if (margin1_[i] == 0)
+      throw Exception("ContingencyTableTest. Row " + TextTools::toString(i) + " sums to 0.");
+  for (size_t j = 0; j < m; ++j)
+    if (margin2_[j] == 0)
+      throw Exception("ContingencyTableTest. Column " + TextTools::toString(j) + " sums to 0.");
+
+
+  size_t tot = VectorTools::sum(margin1_);
+  df_ = static_cast<double>((m - 1) * (n - 1));
+  
+  RowMatrix<long double> expc(n, m);
+  for (size_t i = 0; i < n; ++i) {
+    for (size_t j = 0; j < m; ++j) {
+      long double c = table[i][j];
+      long double e = static_cast<long double>(margin1_[i] * margin2_[j]) / static_cast<long double>(tot);
+      expc(i, j) = e;
+      statistic_ += static_cast<double>(std::pow(c - e, 2.L) / e);
+    }
+  }
+
+  if (nbPermutations > 0) {
+    size_t count = 0;
+    ContingencyTableGenerator ctgen(margin1_, margin2_);
+    for (unsigned int k = 0; k < nbPermutations; ++k) {
+      //Randomize:
+      RowMatrix<size_t> table_rep = ctgen.rcont2();
+      //Recompute statistic:
+      double stat_rep = 0;
+      for (size_t i = 0; i < n; ++i) {
+        for (size_t j = 0; j < m; ++j) {
+          long double c = table_rep(i , j);
+          long double e = expc(i, j);
+          stat_rep += static_cast<double>(std::pow(c - e, 2.L) / e);
+        }
+      }
+      if (stat_rep >= statistic_)
+        count++;
+    }
+    pvalue_ = static_cast<double>(count + 1) / static_cast<double>(nbPermutations + 1);
+  } else {
+    if (test && warn)
+      ApplicationTools::displayWarning("Unsufficient observations, p-value might be incorrect.");
+
+    //Compute p-value:
+    pvalue_ = 1. - RandomTools::pChisq(statistic_, df_);
+  }
+}
+
diff --git a/src/Bpp/Numeric/Stat/ContingencyTableTest.h b/src/Bpp/Numeric/Stat/ContingencyTableTest.h
new file mode 100644
index 0000000..84111c9
--- /dev/null
+++ b/src/Bpp/Numeric/Stat/ContingencyTableTest.h
@@ -0,0 +1,98 @@
+//
+// File: ContingencyTableTest.h
+// Created by: Julien Dutheil
+// Created on: Thu Dec 09 14:20 2010
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _CONTINGENCYTABLETEST_H_
+#define _CONTINGENCYTABLETEST_H_
+
+#include "StatTest.h"
+
+//From the STL:
+#include <vector>
+
+namespace bpp
+{
+
+/**
+ * @brief Implements tests on contingency tables.
+ *
+ * Performs a chi square test on contingency tables.
+ */
+class ContingencyTableTest:
+  public virtual StatTest
+{
+  private:
+    double statistic_;
+    double pvalue_;
+    double df_;
+    std::vector<size_t> margin1_;
+    std::vector<size_t> margin2_;
+
+  public:
+    /**
+     * @brief Build a new test object and perform computations.
+     *
+     * @param table The input contingency table.
+     * @param nbPermutations If greater than 0, performs a randomization test instead of using the chisquare approximation.
+     * @param warn Should a warning message be displayed in case of unsufficient observations?
+     */
+    ContingencyTableTest(const std::vector< std::vector<size_t> >& table, unsigned int nbPermutations = 0, bool warn = true);
+    virtual ~ContingencyTableTest() {}
+
+#ifndef NO_VIRTUAL_COV
+    ContingencyTableTest*
+#else
+    Clonable*
+#endif
+    clone() const { return new ContingencyTableTest(*this); }
+
+  public:
+    std::string getName() const { return "Test on contingency table."; }
+    double getStatistic() const { return statistic_; }
+    double getPValue() const { return pvalue_; }
+    double getDegreesOfFreedom() const { return df_; }
+    const std::vector<size_t> getMarginRows() const { return margin1_; }
+    const std::vector<size_t> getMarginColumns() const { return margin2_; }
+
+};
+
+} //end of namespace bpp.
+
+#endif //_CONTINGENCYTABLETEST_H_
+
+
diff --git a/src/Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.cpp b/src/Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.cpp
new file mode 100644
index 0000000..83db931
--- /dev/null
+++ b/src/Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.cpp
@@ -0,0 +1,114 @@
+//
+// File: CorrespondenceAnalysis.cpp
+// Created by: Mathieu Groussin
+// Created on: Sun Mar 06 10:03 2011
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for phylogenetic data analysis.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "CorrespondenceAnalysis.h"
+#include "../../Matrix/Matrix.h"
+#include "../../Matrix/MatrixTools.h"
+#include "DualityDiagram.h"
+
+using namespace bpp;
+using namespace std;
+
+CorrespondenceAnalysis::CorrespondenceAnalysis(
+  const Matrix<double>& data,
+  unsigned int nbAxes,
+  double tol, bool verbose) throw (Exception) :
+  DualityDiagram(),
+  n_()
+{
+  size_t nRow = data.getNumberOfRows();
+  size_t nCol = data.getNumberOfColumns();
+
+  double tmp = 0.;
+  for (size_t i = 0; i < nRow; i++)
+  {
+    for (unsigned int j = 0; j < nCol; j++)
+    {
+      if (data(i, j) < 0.)
+        throw Exception("CorrespondenceAnalysis (constructor). Negative value(s) in the input data. This is not allowed !");
+      tmp += data(i, j);
+    }
+  }
+  n_ = tmp;
+
+  if (n_ == 0)
+    throw Exception("CorrespondenceAnalysis (constructor). All frequencies in the input data are zero...");
+
+  RowMatrix<double> dataTmp(data);
+  MatrixTools::scale(dataTmp, (1. / n_), 0.);
+
+  vector<double> rowWeights(nRow);
+  vector<double> colWeights(nCol);
+
+  for (size_t i = 0; i < nRow; i++)
+  {
+    for (unsigned int j = 0; j < nCol; j++)
+    {
+      rowWeights[i] += dataTmp(i, j);
+      colWeights[j] += dataTmp(i, j);
+    }
+  }
+
+  vector<double> tmpRowWeigths(nRow);
+  vector<double> tmpColWeigths(nCol);
+  for (size_t i = 0; i < rowWeights.size(); i++)
+  {
+    if (rowWeights[i] == 0.)
+      tmpRowWeigths[i] = 0.;
+    else
+      tmpRowWeigths[i] = 1. / rowWeights[i];
+  }
+  for (size_t j = 0; j < colWeights.size(); j++)
+  {
+    if (colWeights[j] == 0.)
+      tmpColWeigths[j] = 0.;
+    else
+      tmpColWeigths[j] = 1. / colWeights[j];
+  }
+
+  RowMatrix<double> tmpWeightedData(nRow, nCol);
+  RowMatrix<double> weightedData(nRow, nCol);
+  MatrixTools::hadamardMult(dataTmp, tmpRowWeigths, tmpWeightedData, true);
+  MatrixTools::hadamardMult(tmpWeightedData, tmpColWeigths, weightedData, false);
+  MatrixTools::scale(weightedData, 1., -1.);
+
+  setData(weightedData, rowWeights, colWeights, nbAxes, tol, verbose);
+}
+
+
diff --git a/src/Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.h b/src/Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.h
new file mode 100644
index 0000000..ccf7fce
--- /dev/null
+++ b/src/Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.h
@@ -0,0 +1,95 @@
+//
+// File: CorrespondenceAnalysis.h
+// Created by: Mathieu Groussin
+// Created on: Sun Mar 06 10:03 2011
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide basal and
+   utilitary classes. This file belongs to the Bio++ Project.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+
+#ifndef _CORRESPONDENCEANALYSIS_H_
+#define _CORRESPONDENCEANALYSIS_H_
+
+#include "../../Matrix/Matrix.h"
+#include "DualityDiagram.h"
+
+namespace bpp
+/**
+ * @brief This class allows to perform a correspondence analysis.
+ *
+ * All values in the input table have to be non-negative.
+ * The DualityDiagram class, core class of a multivariate analysis, is called internally.
+ *
+ * The code of this class is deeply inspired from the R code of the dudi.coa function available in the ade4 package.
+ */
+{
+class CorrespondenceAnalysis:
+  public DualityDiagram
+{
+private:
+  double n_;
+
+public:
+/**
+ * @brief Build a new CorrespondenceAnalysis object.
+ *
+ * @param data The input data (a RowMatrix) to analyse.
+ * @param nbAxes The number of kept axes during the analysis.
+ * @param tol Tolerance threshold for null eigenvalues (a value less than tol times the first one is considered as null)
+ * @param verbose Should warnings be dispayed.
+ * @throw Exception if an error occured.
+ */
+  CorrespondenceAnalysis(
+    const Matrix<double>& data,
+    unsigned int nbAxes,
+    double tol = 0.0000001,
+    bool verbose = true)
+  throw (Exception);
+
+  virtual ~CorrespondenceAnalysis() {}
+
+#ifndef NO_VIRTUAL_COV
+  CorrespondenceAnalysis*
+#else
+  Clonable*
+#endif
+  clone() const { return new CorrespondenceAnalysis(*this); }
+
+public:
+  double getSumOfAllValues() const throw (Exception) { return n_; }
+};
+} // end of namespace bpp.
+
+#endif  // _CORRESPONDENCEANALYSIS_H_
+
diff --git a/src/Bpp/Numeric/Stat/Mva/DualityDiagram.cpp b/src/Bpp/Numeric/Stat/Mva/DualityDiagram.cpp
new file mode 100644
index 0000000..0971a8a
--- /dev/null
+++ b/src/Bpp/Numeric/Stat/Mva/DualityDiagram.cpp
@@ -0,0 +1,291 @@
+//
+// File: DualityDiagram.cpp
+// Created by: Mathieu Groussin
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Tools, (November 16, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for phylogenetic data analysis.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "DualityDiagram.h"
+#include "../../Matrix/Matrix.h"
+#include "../../Matrix/MatrixTools.h"
+#include "../../Matrix/EigenValue.h"
+#include "../../../App/ApplicationTools.h"
+
+#include <cmath>
+
+using namespace bpp;
+using namespace std;
+
+DualityDiagram::DualityDiagram(
+  const Matrix<double>& matrix,
+  const vector<double>& rowWeights,
+  const vector<double>& colWeights,
+  unsigned int nbAxes,
+  double tol, bool verbose) throw (Exception) :
+  rowWeights_(rowWeights),
+  colWeights_(colWeights),
+  nbAxes_(nbAxes),
+  eigenValues_(),
+  eigenVectors_(),
+  rowCoord_(),
+  colCoord_(),
+  ppalAxes_(),
+  ppalComponents_()
+{
+  check_(matrix, rowWeights, colWeights, verbose);
+  compute_(matrix, tol, verbose);
+}
+
+void DualityDiagram::check_(
+  const Matrix<double>& matrix,
+  const vector<double>& rowWeights,
+  const vector<double>& colWeights,
+  unsigned int nbAxes) throw (Exception)
+{
+  size_t rowNb = matrix.getNumberOfRows();
+  size_t colNb = matrix.getNumberOfColumns();
+
+  if (rowWeights.size() != rowNb)
+    throw Exception("DualityDiagram::check_. The number of row weigths has to be equal to the number of rows!");
+  if (colWeights.size() != colNb)
+    throw Exception("DualityDiagram::check_. The number of column weigths has to be equal to the number of columns!");
+
+  // All row weigths have to be positive
+  for (vector<double>::const_iterator it = rowWeights.begin(); it != rowWeights.end(); it++)
+  {
+    if (*it < 0.)
+      throw Exception("DualityDiagram::check_. All row weights have to be positive");
+  }
+
+  // All column weigths have to be positive
+  for (vector<double>::const_iterator it = colWeights.begin(); it != colWeights.end(); it++)
+  {
+    if (*it < 0.)
+      throw Exception("DualityDiagram::check_. All column weights have to be positive");
+  }
+}
+
+
+void DualityDiagram::setData(
+  const Matrix<double>& matrix,
+  const vector<double>& rowWeights,
+  const vector<double>& colWeights,
+  unsigned int nbAxes,
+  double tol, bool verbose) throw (Exception)
+{
+  check_(matrix, rowWeights, colWeights, verbose);
+  rowWeights_ = rowWeights;
+  colWeights_ = colWeights;
+  nbAxes_     = nbAxes;
+  compute_(matrix, tol, verbose);
+}
+
+void DualityDiagram::compute_(const Matrix<double>& matrix,
+    double tol, bool verbose)
+{
+  size_t rowNb = matrix.getNumberOfRows();
+  size_t colNb = matrix.getNumberOfColumns();
+  
+  // If there are less rows than columns, the variance-covariance or correlation matrix is obtain differently (see below)
+  bool transpose = (rowNb < colNb);
+
+  // The initial matrix is multiplied by the square root of the row weigths.
+  vector<double> rW(rowWeights_);
+  for (unsigned int i = 0; i < rowWeights_.size(); i++)
+  {
+    rW[i] = sqrt(rowWeights_[i]);
+  }
+
+  RowMatrix<double> M1(rowNb, colNb);
+  MatrixTools::hadamardMult(matrix, rW, M1, true);
+
+  // The resulting matrix is then multiplied by the square root of the column weigths.
+  vector<double> cW(colWeights_);
+  for (unsigned int i = 0; i < colWeights_.size(); i++)
+  {
+    cW[i] = sqrt(colWeights_[i]);
+  }
+
+  RowMatrix<double> M2;
+  MatrixTools::hadamardMult(M1, cW, M2, false);
+
+  // The variance-covariance (if the data is centered) or the correlation (if the data is centered and normalized) matrix is calculated
+  RowMatrix<double> tM2;
+  MatrixTools::transpose(M2, tM2);
+  RowMatrix<double> M3;
+  if (!transpose)
+    MatrixTools::mult(tM2, M2, M3);
+  else
+    MatrixTools::mult(M2, tM2, M3);
+	
+  EigenValue<double> eigen(M3);
+  if (!eigen.isSymmetric())
+    throw Exception("DualityDiagram (constructor). The variance-covariance or correlation matrix should be symmetric...");
+
+  eigenValues_ = eigen.getRealEigenValues();
+  eigenVectors_ = eigen.getV();
+
+  // How many significant axes have to be conserved?
+  size_t rank = 0;
+  for (size_t i = eigenValues_.size(); i > 0; i--)
+  {
+    if ((eigenValues_[i - 1] / eigenValues_[eigenValues_.size() - 1]) > tol)
+      rank++;
+  }
+
+  if (nbAxes_ <=0)
+  {
+    throw Exception("DualityDiagram (constructor). The number of axes to keep must be positive.");
+  }
+  if (nbAxes_ > rank)
+  {
+    if (verbose)
+      ApplicationTools::displayWarning("The number of axes to kept has been reduced to conserve only significant axes");
+    nbAxes_ = rank;
+  }
+
+  /*The eigen values are initially sorted into ascending order by the 'eigen' function. Here the significant values are sorted
+     in the other way around.*/
+  vector<double> tmpEigenValues(nbAxes_);
+  size_t cpt = 0;
+  for (size_t i = eigenValues_.size(); i > (eigenValues_.size() - nbAxes_); i--)
+  {
+    tmpEigenValues[cpt] = eigenValues_[i-1];
+    cpt++;
+  }
+  eigenValues_ = tmpEigenValues;
+
+  for (vector<double>::iterator it = rowWeights_.begin(); it != rowWeights_.end(); it++)
+  {
+    if (*it == 0.)
+      *it = 1.;
+  }
+
+  for (vector<double>::iterator it = colWeights_.begin(); it != colWeights_.end(); it++)
+  {
+    if (*it == 0.)
+      *it = 1.;
+  }
+
+  vector<double> dval(nbAxes_);
+  for (size_t i = 0; i < dval.size(); i++)
+  {
+    dval[i] = sqrt(eigenValues_[i]);
+  }
+
+  vector<double> invDval(nbAxes_);
+  for (size_t i = 0; i < invDval.size(); i++)
+  {
+    invDval[i] = 1. / sqrt(eigenValues_[i]);
+  }
+
+  // Calculation of the row and column coordinates as well as the principal axes and components:
+  if (!transpose)
+  {
+    vector<double> tmpColWeights(colNb);
+    for (unsigned int i = 0; i < colWeights_.size(); i++)
+    {
+      tmpColWeights[i] = 1. / sqrt(colWeights_[i]);
+    }
+
+    // The eigen vectors are placed in the same order as their corresponding eigen value in eigenValues_.
+    RowMatrix<double> tmpEigenVectors;
+    tmpEigenVectors.resize(eigenVectors_.getNumberOfRows(), nbAxes_);
+    size_t cpt2 = 0;
+    for (size_t i = eigenVectors_.getNumberOfColumns(); i > (eigenVectors_.getNumberOfColumns() - nbAxes_); i--)
+    {
+      for (unsigned int j = 0; j < eigenVectors_.getNumberOfRows(); j++)
+      {
+        tmpEigenVectors(j, cpt2) = eigenVectors_(j, i-1);
+      }
+      cpt2++;
+    }
+	  
+    // matrix of principal axes
+    MatrixTools::hadamardMult(tmpEigenVectors, tmpColWeights, ppalAxes_, true);
+    // matrix of row coordinates
+    RowMatrix<double> tmpRowCoord_;
+    tmpRowCoord_.resize(rowNb, nbAxes_);
+    MatrixTools::hadamardMult(matrix, colWeights_, tmpRowCoord_, false);
+    MatrixTools::mult(tmpRowCoord_, ppalAxes_, rowCoord_);
+
+    // matrix of column coordinates
+    MatrixTools::hadamardMult(ppalAxes_, dval, colCoord_, false);
+    // matrix of principal components
+    MatrixTools::hadamardMult(rowCoord_, invDval, ppalComponents_, false);
+  }
+  else
+  {
+    vector<double> tmpRowWeights(rowNb);
+    for (unsigned int i = 0; i < rowWeights_.size(); i++)
+    {
+      tmpRowWeights[i] = 1. / sqrt(rowWeights_[i]);
+    }
+
+    // The eigen vectors are placed in the same order as their corresponding eigen value in eigenValues_.
+    RowMatrix<double> tmpEigenVectors;
+    tmpEigenVectors.resize(eigenVectors_.getNumberOfRows(), nbAxes_);
+    size_t cpt2 = 0;
+    for (size_t i = eigenVectors_.getNumberOfColumns(); i > (eigenVectors_.getNumberOfColumns() - nbAxes_); i--)
+    {
+      for (size_t j = 0; j < eigenVectors_.getNumberOfRows(); j++)
+      {
+        tmpEigenVectors(j, cpt2) = eigenVectors_(j, i-1);
+      }
+      cpt2++;
+    }
+
+    // matrix of principal components
+    MatrixTools::hadamardMult(tmpEigenVectors, tmpRowWeights, ppalComponents_, true);
+    // matrix of column coordinates
+    RowMatrix<double> tmpColCoord_;
+    tmpColCoord_.resize(colNb, nbAxes_);
+    MatrixTools::hadamardMult(matrix, rowWeights_, tmpColCoord_, true);
+    RowMatrix<double> tTmpColCoord_;
+    MatrixTools::transpose(tmpColCoord_, tTmpColCoord_);
+    MatrixTools::mult(tTmpColCoord_, ppalComponents_, colCoord_);
+
+    // matrix of row coordinates
+    MatrixTools::hadamardMult(ppalComponents_, dval, rowCoord_, false);
+    // matrix of principal axes
+    MatrixTools::hadamardMult(colCoord_, invDval, ppalAxes_, false);
+  }
+}
+
+/******************************************************************************/
+
+DualityDiagram::~DualityDiagram() {}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Numeric/Stat/Mva/DualityDiagram.h b/src/Bpp/Numeric/Stat/Mva/DualityDiagram.h
new file mode 100644
index 0000000..4900561
--- /dev/null
+++ b/src/Bpp/Numeric/Stat/Mva/DualityDiagram.h
@@ -0,0 +1,160 @@
+//
+// File: DualityDiagram.h
+// Created by: Mathieu Groussin
+// Created on: Sun Feb 27 22:03 2011
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide basal and
+   utilitary classes. This file belongs to the Bio++ Project.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+
+#ifndef _DUALITYDIAGRAM_H_
+#define _DUALITYDIAGRAM_H_
+
+#include "../../Matrix/Matrix.h"
+
+namespace bpp
+{
+/**
+ * @brief The core class of a multivariate analysis.
+ *
+ * In the constructor, the eigen values and vectors of the variance-covariance or correlation matrix are calculated.
+ * Eigen values and vectors are stored in the eigenValues_ and eigenVectors_ respectively.
+ * Furthermore, four matrices are calculated: the row and column coordinates as well as the principal axes and components.
+ *
+ * The code of this class is deeply inspired from the R code of the as.dudi function available in the ade4 package.
+ */
+class DualityDiagram:
+  public virtual Clonable
+{
+
+private:
+  std::vector<double> rowWeights_;
+  std::vector<double> colWeights_;
+  size_t nbAxes_;
+  std::vector<double> eigenValues_;
+  RowMatrix<double> eigenVectors_;
+  RowMatrix<double> rowCoord_;
+  RowMatrix<double> colCoord_;
+  RowMatrix<double> ppalAxes_;
+  RowMatrix<double> ppalComponents_;
+
+public:
+  /**
+   * @brief Build an empty DualityDiagram object.
+   *
+   */
+  DualityDiagram() :
+    rowWeights_(),
+    colWeights_(),
+    nbAxes_(),
+    eigenValues_(),
+    eigenVectors_(),
+    rowCoord_(),
+    colCoord_(),
+    ppalAxes_(),
+    ppalComponents_() {}
+
+  /**
+   * @brief Build a new DualityDiagram object.
+   *
+   * @param matrix The input data to analyse.
+   * @param rowWeights A vector of values specifying the weights of rows.
+   * @param colWeights A vector of values specifying the weights of columns.
+   * @param nbAxes The number of kept axes during the analysis.
+   * @param tol Tolerance threshold for null eigenvalues (a value less than tol times the first one is considered as null)
+   * @param verbose Should warnings be dispayed.
+   * @throw Exception if an error occured.
+   */
+  DualityDiagram(
+    const Matrix<double>& matrix,
+    const std::vector<double>& rowWeights,
+    const std::vector<double>& colWeights,
+    unsigned int nbAxes,
+    double tol = 0.0000001,
+    bool verbose = true) throw (Exception);
+
+  virtual ~DualityDiagram();
+
+#ifndef NO_VIRTUAL_COV
+  DualityDiagram*
+#else
+  Clonable*
+#endif
+  clone() const { return new DualityDiagram(*this); }
+
+private:
+  void check_(
+      const Matrix<double>& matrix,
+      const std::vector<double>& rowWeights,
+      const std::vector<double>& colWeights,
+      unsigned int nbAxes) throw (Exception);
+  void compute_(const Matrix<double>& matrix, double tol, bool verbose);
+
+public:
+  /**
+   * @brief Set the data and perform computations.
+   *
+   * @param matrix The input data to analyse.
+   * @param rowWeights A vector of values specifying the weights of rows.
+   * @param colWeights A vector of values specifying the weights of columns.
+   * @param nbAxes The number of kept axes during the analysis.
+   * @param tol Tolerance threshold for null eigenvalues (a value less than tol times the first one is considered as null)
+   * @param verbose Should warnings be dispayed.
+   * @throw Exception if an error occured.
+   */
+  void setData(
+      const Matrix<double>& matrix,
+      const std::vector<double>& rowWeights,
+      const std::vector<double>& colWeights,
+      unsigned int nbAxes,
+      double tol = 0.0000001,
+      bool verbose = true) throw (Exception);
+ 
+  std::vector<double> computeVariancePercentagePerAxis() throw (Exception);
+  
+  size_t getNbOfKeptAxes() const throw (Exception) { return nbAxes_; }
+  const std::vector<double> getRowWeights() const throw (Exception) { return rowWeights_; }
+  const	std::vector<double> getColumnWeights() const throw (Exception) { return colWeights_; }	  
+  const std::vector<double>& getEigenValues() const throw (Exception) { return eigenValues_; }
+  const RowMatrix<double>& getRowCoordinates() const throw (Exception) { return rowCoord_; }
+  const RowMatrix<double>& getColCoordinates() const throw (Exception) { return colCoord_; }
+  const RowMatrix<double>& getPrincipalAxes() const throw (Exception) { return ppalAxes_; }
+  const RowMatrix<double>& getPrincipalComponents() const throw (Exception) { return ppalComponents_; }
+};
+
+} // end of namespace bpp.
+
+#endif  // _DUALITYDIAGRAM_H_
+
+
diff --git a/src/Bpp/Numeric/Stat/Mva/PrincipalComponentAnalysis.cpp b/src/Bpp/Numeric/Stat/Mva/PrincipalComponentAnalysis.cpp
new file mode 100644
index 0000000..4a14f43
--- /dev/null
+++ b/src/Bpp/Numeric/Stat/Mva/PrincipalComponentAnalysis.cpp
@@ -0,0 +1,182 @@
+//
+// File: PrincipalComponentAnalysis.cpp
+// Created by: Mathieu Groussin
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 16, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for phylogenetic data analysis.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "PrincipalComponentAnalysis.h"
+#include "../../Matrix/Matrix.h"
+#include "../../Matrix/MatrixTools.h"
+#include "../../VectorTools.h"
+#include "DualityDiagram.h"
+
+#include <cmath>
+
+using namespace bpp;
+using namespace std;
+
+PrincipalComponentAnalysis::PrincipalComponentAnalysis(
+  const Matrix<double>& data,
+  unsigned int nbAxes,
+  const vector<double>& rowW,
+  const vector<double>& colW,
+  bool centered,
+  bool scaled,
+  double tol,
+  bool verbose) throw (Exception) :
+  DualityDiagram(),
+  columnMeans_(),
+  columnSd_()
+{
+  RowMatrix<double> tmpData = data;
+  
+  // Centering of data?
+  if (centered)
+  {
+    center(tmpData, rowW);
+  }
+  
+  // Scaling of data?
+  if (scaled)
+  {
+    scale(tmpData, rowW);
+  }
+
+  setData(tmpData, rowW, colW, nbAxes, tol, verbose);
+}
+
+/******************************************************************************/
+
+PrincipalComponentAnalysis::PrincipalComponentAnalysis(
+  const Matrix<double>& data,
+  unsigned int nbAxes,
+  bool centered,
+  bool scaled,
+  double tol,
+  bool verbose) throw (Exception) :
+  DualityDiagram(),
+  columnMeans_(),
+  columnSd_()
+{
+  size_t nRow = data.getNumberOfRows();
+  size_t nCol = data.getNumberOfColumns();
+
+  vector<double> rowW(nRow);
+  vector<double> colW(nCol);
+  VectorTools::fill(rowW, 1. / static_cast<double>(nRow));
+  VectorTools::fill(colW, 1.);
+
+  RowMatrix<double> tmpData = data;
+
+  // Centering of data?
+  if (centered)
+  {
+    center(tmpData, rowW);
+  }
+  
+  // Scaling of data?
+  if (scaled)
+  {
+    scale(tmpData, rowW);
+  }
+
+  setData(tmpData, rowW, colW, nbAxes, tol, verbose);
+}
+
+/******************************************************************************/
+
+void PrincipalComponentAnalysis::center(Matrix<double>& matrix, const vector<double>& rowW) throw (Exception)
+{
+  size_t nRow = matrix.getNumberOfRows();
+  size_t nCol = matrix.getNumberOfColumns();
+  if (nRow != rowW.size())
+    throw Exception("PrincipalComponentAnalysis::center. The number of row weigths have to be equal to the number of rows!");
+
+  double sumRowWeights = VectorTools::sum(rowW);
+
+  vector<double> columnMeans(nCol);
+  for (unsigned int i = 0; i < nCol; i++)
+  {
+    double tmp = 0.;
+    for (unsigned int j = 0; j < nRow; j++)
+    {
+      tmp += matrix(j, i) * rowW[j];
+    }
+    columnMeans[i] = tmp / sumRowWeights;
+  }
+
+  for (unsigned int i = 0; i < nCol; i++)
+  {
+    for (unsigned int j = 0; j < nRow; j++)
+    {
+      matrix(j, i) -= columnMeans[i];
+    }
+  }
+}
+
+/******************************************************************************/
+
+void PrincipalComponentAnalysis::scale(Matrix<double>& matrix, const vector<double>& rowW) throw (Exception)
+{
+  size_t nRow = matrix.getNumberOfRows();
+  size_t nCol = matrix.getNumberOfColumns();
+  if (nRow != rowW.size())
+    throw Exception("PrincipalComponentAnalysis::scale. The number of row weigths have to be equal to the number of rows!");
+
+  double sumRowWeights = VectorTools::sum(rowW);
+
+  vector<double> columnSd(nCol);
+  for (size_t i = 0; i < nCol; i++)
+  {
+    double tmp = 0.;
+    for (unsigned int j = 0; j < nRow; j++)
+    {
+      tmp += pow(matrix(j, i), 2) * rowW[j];
+    }
+    columnSd[i] = sqrt(tmp / sumRowWeights);
+  }
+
+  for (size_t i = 0; i < nCol; i++)
+  {
+    for (unsigned int j = 0; j < nRow; j++)
+    {
+      if (columnSd[i] == 0.)
+        matrix(j, i) = 0.;
+      else
+        matrix(j, i) /= columnSd[i];
+    }
+  }
+}
+
diff --git a/src/Bpp/Numeric/Stat/Mva/PrincipalComponentAnalysis.h b/src/Bpp/Numeric/Stat/Mva/PrincipalComponentAnalysis.h
new file mode 100644
index 0000000..6351f28
--- /dev/null
+++ b/src/Bpp/Numeric/Stat/Mva/PrincipalComponentAnalysis.h
@@ -0,0 +1,138 @@
+//
+// File: PrincipalComponentAnalysis.h
+// Created by: Mathieu Groussin
+// Created on: Thu Mar 03 10:13 2011
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide basal and
+   utilitary classes. This file belongs to the Bio++ Project.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+
+#ifndef _PRINCIPALCOMPONENTANALYSIS_H_
+#define _PRINCIPALCOMPONENTANALYSIS_H_
+
+#include "../../Matrix/Matrix.h"
+#include "DualityDiagram.h"
+
+namespace bpp
+{
+/**
+ * @brief This class allows to perform a principal component analysis.
+ *
+ * Two constructors are available. The first one allows the user to specify the row and column weights. The second one specify default weights:
+ * uniform weights unit weights are created for rows and columns respectively.
+ *
+ * The code of this class is deeply inspired from the R code of the dudi.pca function available in the ade4 package.
+ */
+class PrincipalComponentAnalysis:
+  public DualityDiagram
+{
+private:
+  std::vector<double> columnMeans_;
+  std::vector<double> columnSd_;
+
+public:
+  /**
+   * @brief Build a new PrincipalComponentAnalysis object.
+   *
+   * @param data The input data (a RowMatrix) to analyse.
+   * @param nbAxes The number of kept axes during the analysis.
+   * @param rowW A vector of values specifying the weights of rows.
+   * @param colW A vector of values specifying the weights of columns.
+   * @param centered If true the input matrix is centered according to the column means.
+   * @param scaled If true the input matrix is normalized according to the standard deviations of columns.
+   * @param tol Tolerance threshold for null eigenvalues (a value less than tol times the first one is considered as null)
+   * @param verbose Should warnings be dispayed.
+   * @throw Exception if an error occured.
+   */
+  PrincipalComponentAnalysis(
+    const Matrix<double>& data,
+    unsigned int nbAxes,
+    const std::vector<double>& rowW,
+    const std::vector<double>& colW,
+    bool centered = true,
+    bool scaled = true,
+    double tol = 0.0000001,
+    bool verbose = true)
+  throw (Exception);
+
+  /**
+   * @brief Build a new PrincipalComponentAnalysis object and specify default row and column weights.
+   *
+   * @param data The input data (a RowMatrix) to analyse.
+   * @param nbAxes The number of kept axes during the analysis.
+   * @param centered If true the input matrix is centered according to the column means.
+   * @param scaled If true the input matrix is normalized according to the standard deviations of columns.
+   * @param tol Tolerance threshold for null eigenvalues (a value less than tol times the first one is considered as null)
+   * @param verbose Should warnings be dispayed.
+   * @throw Exception if an error occured.
+   */
+  PrincipalComponentAnalysis(
+    const Matrix<double>& data,
+    unsigned int nbAxes,
+    bool centered = true,
+    bool scaled = true,
+    double tol = 0.0000001,
+    bool verbose = true)
+  throw (Exception);
+
+  virtual ~PrincipalComponentAnalysis() {}
+
+  PrincipalComponentAnalysis* clone() const { return new PrincipalComponentAnalysis(*this); }
+
+public:
+  /**
+   * @brief This function allows to center an input matrix from its column means.
+   *
+   * @param matrix The input data (a Matrix) to center.
+   * @param rowW A vector with row weights.
+   */
+  static void center(Matrix<double>& matrix, const std::vector<double>& rowW) throw (Exception);
+
+  /**
+   * @brief This function allows to center an input matrix from its column means.
+   *
+   * @param matrix The input data (a Matrix) to center.
+   * @param rowW A vector with row weights.
+   */
+  static void scale(Matrix<double>& matrix, const std::vector<double>& rowW) throw (Exception);
+
+public:
+  const std::vector<double>& getColumnMeans() const throw (Exception) { return columnMeans_; }
+  const std::vector<double>& getColumnSd() const throw (Exception) { return columnSd_; }
+};
+
+} // end of namespace bpp.
+
+#endif  // _PRINCIPALCOMPONENTANALYSIS_H_
+
diff --git a/src/Bpp/Numeric/Stat/StatTest.h b/src/Bpp/Numeric/Stat/StatTest.h
new file mode 100644
index 0000000..c8747a8
--- /dev/null
+++ b/src/Bpp/Numeric/Stat/StatTest.h
@@ -0,0 +1,73 @@
+//
+// File: StatTest.h
+// Created by: Julien Dutheil
+// Created on: Tue Mar 18 13:56 2008
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _STATTEST_H_
+#define _STATTEST_H_
+
+#include "../../Clonable.h"
+
+//From the STL:
+#include <string>
+
+namespace bpp
+{
+
+/**
+ * @brief Interface for statistical test results.
+ *
+ * Specific test may add specific methods to the ones provided here.
+ */
+class StatTest:
+  public virtual Clonable
+{
+  public:
+    StatTest() {}
+    virtual ~StatTest() {}
+
+  public:
+    virtual std::string getName() const = 0;
+    virtual double getStatistic() const = 0;
+    virtual double getPValue() const = 0;
+
+};
+
+} // end of namespace bpp;
+
+#endif //_STATTEST_H_
+
diff --git a/src/Bpp/Numeric/Stat/StatTools.cpp b/src/Bpp/Numeric/Stat/StatTools.cpp
new file mode 100644
index 0000000..4a9f842
--- /dev/null
+++ b/src/Bpp/Numeric/Stat/StatTools.cpp
@@ -0,0 +1,60 @@
+//
+// File: StatTools.cpp
+// Created by: Julien Dutheil
+// Created on: Sun Jan 30 19:10 2011
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "StatTools.h"
+
+//From the STL:
+#include <algorithm>
+
+using namespace bpp;
+using namespace std;
+
+vector<double> StatTools::computeFdr(const vector<double>& pvalues) {
+  size_t n = pvalues.size();
+  vector<PValue_> sortedPValues;
+  for (size_t i = 0; i < n; ++i) {
+    sortedPValues.push_back(PValue_(pvalues[i], i));  
+  }
+  sort(sortedPValues.begin(), sortedPValues.end());
+  vector<double> fdr(pvalues.size());
+  for (size_t i = 0; i < sortedPValues.size(); ++i) {
+    fdr[sortedPValues[i].index_] = sortedPValues[i].pvalue_ * static_cast<double>(n) / ( static_cast<double>(sortedPValues[i].index_ + 1));
+  }
+  return fdr;
+}
diff --git a/src/Bpp/Numeric/Stat/StatTools.h b/src/Bpp/Numeric/Stat/StatTools.h
new file mode 100644
index 0000000..e65f20d
--- /dev/null
+++ b/src/Bpp/Numeric/Stat/StatTools.h
@@ -0,0 +1,89 @@
+//
+// File: StatTools.h
+// Created by: Julien Dutheil
+// Created on: Sun Jan 30 19:10 2011
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _STATTOOLS_H_
+#define _STATTOOLS_H_
+
+//From the STL:
+#include <vector>
+#include <cstddef>
+
+namespace bpp {
+
+/**
+ * @brief Statistics tools and utilitary functions.
+ */
+class StatTools
+{
+  private:
+    struct PValue_ {
+      double pvalue_;
+      size_t index_;
+      PValue_(double pvalue, size_t index):
+        pvalue_(pvalue), index_(index) {}
+
+      bool operator<(const PValue_& pvalue) const {
+        return pvalue.pvalue_ < pvalue_;
+      }
+    };
+
+  public:
+    /**
+     * @brief Compute the false discovery rate for a set of input p-values, using Benjamini and Hochberg's 'FDR' method.
+     * 
+     * The false discovery rate is computed by sorting all pvalues.
+     * The FDR r is calculated with the formula
+     * @f$ r = p * n / i at f$
+     * where p is the p-value, n is the number of tests (the size of the input vector) and i is the rank of the p-value, that is the index in the sorted array.
+     * 
+     * References:
+     * - Benjamini, Y and Hochberg, Y (1995). Controlling the false discovery rate: a practical and powerful approach to multiple testing. Journal of the Royal Statistical Society, Series B (Methodological) 57(1):289-300.
+     * - Verhoeven, KJF; Simonsen, KL; M. McIntyre, LM (2005). Implementing false discovery rate control: increasing your power. Oikos. 108(3):643-647.
+     *
+     * @author Julien Dutheil
+     * @param pvalues The input p-values.
+     * @return The corresponding false discovery rates.
+     */
+    static std::vector<double> computeFdr(const std::vector<double>& pvalues);
+};
+
+} //end of namespace bpp.
+
+#endif //_STATTOOLS_H_
+
diff --git a/src/Bpp/Numeric/TransformedParameter.h b/src/Bpp/Numeric/TransformedParameter.h
new file mode 100644
index 0000000..3360b36
--- /dev/null
+++ b/src/Bpp/Numeric/TransformedParameter.h
@@ -0,0 +1,312 @@
+//
+// File: TransformedParameter.h
+// Created by: Julien Dutheil
+// Created on: Fri Jan 30 09:42 2009
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 19, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _TRANSFORMEDPARAMETER_H_
+#define _TRANSFORMEDPARAMETER_H_
+
+#include "Parameter.h"
+#include "NumConstants.h"
+
+#include <cmath>
+
+namespace bpp
+{
+
+/**
+ * @brief The TransformedParameter abstract class.
+ *
+ * This class extends the Parameter class.
+ * A transformed parameter does not have a constraint attached to it, and is supposed to range from -inf to +inf.
+ * It uses a transformation in order to do this, typically using a bijection.
+ * The exact function used to achieve the transformation depends on the implementation of the interface.
+ */ 
+class TransformedParameter:
+  public Parameter
+{
+	public:
+    TransformedParameter(const std::string& name, double value):
+      Parameter(name, value) {}
+		
+		TransformedParameter* clone() const = 0;
+	
+	public:
+    /**
+     * @brief Set the value of the parameter using the orignal coordinate system.
+     *
+     * @param value Parameter value in original coordinates.
+     * @throw ConstraintException if the value is not correct.
+     */
+    virtual void setOriginalValue(double value) throw (ConstraintException) = 0;
+
+    /**
+     * @return The current value of the parameter in orignal coordinates.
+     */
+    virtual double getOriginalValue() const = 0;
+
+    /**
+     * @return The first order derivative of the transformation at the original point.
+     * @throw NotImplementedException if the transformation does not support derivation
+     * or if the derivation was not implemented.
+     */
+    virtual double getFirstOrderDerivative() const throw (NotImplementedException) = 0;
+    
+    /**
+     * @return The second order derivative of the transformation at the original point.
+     * @throw NotImplementedException if the transformation does not support derivation
+     * or if the derivation was not implemented.
+     */
+    virtual double getSecondOrderDerivative() const throw (NotImplementedException) = 0;
+};
+
+/**
+ * @brief Parameter transformation from ] b, +inf [ or ] -inf, b [ to ]-inf, + inf [.
+ *
+ * The equation of the tranformation is 
+ * @f[
+ * x' = \begin{cases}
+ *   \log(a\cdot(x-b)) & \text{if $x < b+1$},\\
+ *   a(x-1-b)          & \text{if $a \geq b+1$}.
+ * \end{cases}
+ * @f]
+ * for a transformation from ] b, +inf [ to ]-inf, + inf [.
+ * The 'b' parameter is the lower bound and 'a' is a scaling factor set to 1 by default.
+ * For a transformation from  ] -inf, b [, the transformation is then
+ * @f[
+ * x' = \begin{cases}
+ *   -\log(-a\cdot(x-b)) & \text{if $x < b-1$},\\
+ *   -a(x-1-b)           & \text{if $a \geq b-1$}.
+ * \end{cases}
+ * @f]
+ */
+class RTransformedParameter:
+  public TransformedParameter
+{
+  private:
+    double scale_;
+    double bound_;
+    bool positive_;
+
+  public:
+    /**
+     * @brief Build a new RTransformedParameter, with given bound and scale.
+     *
+     * @param name the name of the parameter.
+     * @param value the value of th eparameter, in orginal coordinates.
+     * @param bound the inerval bound to use.
+     * @param positive tell if the original interval is positive or negative.
+     * @param scale the scaling factor.
+     */
+    RTransformedParameter(const std::string& name, double value, double bound = 0, bool positive = true, double scale = 1):
+      TransformedParameter(name, 1.),
+      scale_(scale),
+      bound_(bound),
+      positive_(positive)
+    {
+      setOriginalValue(value);
+    }
+
+    RTransformedParameter* clone() const { return new RTransformedParameter(*this); }
+
+  public:
+    void setOriginalValue(double value) throw (ConstraintException) 
+    {
+      if (positive_ ? value <= bound_ : value >= bound_) throw ConstraintException("RTransformedParameter::setValue", this, value);
+      if (positive_  & (value < 1 + bound_)) setValue(log(scale_ * (value - bound_)));
+      if (positive_  & (value >= 1 + bound_)) setValue(scale_ * (value - 1. - bound_));
+      if (!positive_ & (value > -1 + bound_)) setValue(log(-scale_ * (value - bound_)));
+      if (!positive_ & (value <= -1 + bound_)) setValue(-scale_ * (value - 1. - bound_));
+    }
+
+    double getOriginalValue() const
+    {
+      double x = getValue();
+      if (positive_)
+        if(x < 0) return exp(x) / scale_ + bound_;
+        else      return x / scale_ + 1. + bound_;
+      else 
+        if(x < 0) return - exp(-x) / scale_ + bound_;
+        else      return - x / scale_ - 1. + bound_;
+    }
+
+    double getFirstOrderDerivative() const throw (NotImplementedException)
+    {
+      double x = getValue();
+      if (positive_)
+        if(x < 0) return exp(x) / scale_;
+        else      return 1. / scale_;
+      else 
+        if(x < 0) return exp(-x) / scale_;
+        else      return - 1. / scale_;
+    }
+
+    double getSecondOrderDerivative() const throw (NotImplementedException)
+    {
+      double x = getValue();
+      if (positive_)
+        if(x < 0) return exp(x) / scale_;
+        else      return 0;
+      else 
+        if(x < 0) return - exp(-x) / scale_;
+        else      return 0;
+    }
+
+};
+
+/**
+ * @brief Parameter transformation from ] a, b [ to ]-inf, + inf [.
+ *
+ * The equation of the tranformation is 
+ * @f[
+ * x' = s\tan\left(\pi\frac{x-a}{b-a} - \frac{\pi}{2}\right)
+ * @f]
+ * The 'a' and 'b' parameters are the lower and upper bounds and 's' is a sclaing factor set to 1 by default.
+ * If the hyperbolic option is set to true (the default), then the following transformation is used instead:
+ * @f[
+ * x' = s\,\text{atanh}\left(2\frac{x-a}{b-a} - 1\right)
+ * @f]
+ *
+ */
+class IntervalTransformedParameter:
+  public TransformedParameter
+{
+  private:
+    double scale_;
+    double lowerBound_;
+    double upperBound_;
+    bool hyper_;
+    double tiny_;
+
+  public:
+    /**
+     * @brief Build a new IntervalTransformedParameter, with given bounds and scale.
+     *
+     * @param name the name of the parameter.
+     * @param value the value of th eparameter, in orginal coordinates.
+     * @param lowerBound the inerval lower bound to use.
+     * @param upperBound the inerval lower bound to use.
+     * @param scale the scaling factor.
+     * @param hyper tell if the hyberboic function should be used (true by default).
+     */
+    IntervalTransformedParameter(const std::string& name, double value, double lowerBound = 0, double upperBound = 1, double scale = 1, bool hyper = true):
+      TransformedParameter(name, hyper ?
+          scale * atanh(2. * (value - lowerBound) / (upperBound - lowerBound) - 1.) :
+          scale * tan(NumConstants::PI() * (value - lowerBound)/(upperBound - lowerBound) - NumConstants::PI() / 2.)),
+      scale_(scale),
+      lowerBound_(lowerBound),
+      upperBound_(upperBound),
+      hyper_(hyper),
+      tiny_(NumConstants::TINY())
+    {}
+
+    IntervalTransformedParameter* clone() const { return new IntervalTransformedParameter(*this); }
+
+  public:
+    void setOriginalValue(double value) throw (ConstraintException) 
+    {
+      if (value <= lowerBound_ || value >= upperBound_) throw ConstraintException("IntervalTransformedParameter::setValue", this, value);
+      setValue(hyper_ ?
+          scale_ * atanh(2. * (value - lowerBound_) / (upperBound_ - lowerBound_) - 1.) :
+          scale_ * tan(NumConstants::PI() * (value - lowerBound_)/(upperBound_ - lowerBound_) - NumConstants::PI() / 2.));
+    }
+
+    double getOriginalValue() const
+    {
+      double x = getValue();
+      double x2 = hyper_ ?
+        (tanh(x / scale_) + 1.) * (upperBound_ - lowerBound_) / 2. + lowerBound_ :
+        (atan(x / scale_) + NumConstants::PI() / 2.) * (upperBound_ - lowerBound_) / NumConstants::PI() + lowerBound_;
+      return x2;
+    }
+
+
+    double getFirstOrderDerivative() const throw (NotImplementedException)
+    {
+      double x = getValue();
+      double x2 = hyper_ ?
+        1. / (cosh(pow(x / scale_, 2))) * (upperBound_ - lowerBound_) / (2. * scale_) :
+        (upperBound_ - lowerBound_) / (NumConstants::PI() * scale_ * (pow(x / scale_, 2) + 1.));
+      return x2;
+    }
+    double getSecondOrderDerivative() const throw (NotImplementedException)
+    {
+      double x = getValue();
+      double x2 = hyper_ ?
+        - 1. / (cosh(pow(x / scale_, 2))) * tanh(x / scale_) *(upperBound_ - lowerBound_) / (scale_ * scale_) :
+        -2. * x * (upperBound_ - lowerBound_) / (NumConstants::PI() * pow(scale_, 3) * pow((pow(x / scale_, 2) + 1.), 2));
+      return x2;
+    }
+};
+
+/**
+ * @brief 'Placebo' parameter transformation from ] b, +inf [ or ] -inf, b [ to ]-inf, + inf [.
+ *
+ * The class create a Transformed parameter which is exactly the same as a standard parameter.
+ * It only implements the setOriginalValue and getOriginalValue methods, and remove the constraint.
+ */
+class PlaceboTransformedParameter:
+  public TransformedParameter
+{
+  public:
+    PlaceboTransformedParameter(const std::string& name, double value):
+      TransformedParameter(name, value)
+    {}
+
+    PlaceboTransformedParameter* clone() const { return new PlaceboTransformedParameter(*this); }
+
+  public:
+    void setOriginalValue(double value) throw (ConstraintException) 
+    {
+      setValue(value);
+    }
+
+    double getOriginalValue() const
+    {
+      return getValue();
+    }
+    
+    double getFirstOrderDerivative() const throw (NotImplementedException) { return 1.; }
+    
+    double getSecondOrderDerivative() const throw (NotImplementedException) { return 0.; }
+};
+
+
+} //end of namespace bpp.
+
+#endif	//_TRANSFORMEDPARAMETER_H_
+
diff --git a/src/Bpp/Numeric/VectorExceptions.h b/src/Bpp/Numeric/VectorExceptions.h
new file mode 100644
index 0000000..b3fe62a
--- /dev/null
+++ b/src/Bpp/Numeric/VectorExceptions.h
@@ -0,0 +1,155 @@
+//
+// File: VectorExceptions.h
+// Created by: Julien Dutheil
+// Created on: 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _VECTOREXCEPTIONS_H_
+#define _VECTOREXCEPTIONS_H_
+
+#include "../Exceptions.h"
+#include "../Text/TextTools.h"
+
+//From the STL/
+#include <string>
+#include <vector>
+
+namespace bpp
+{
+
+/**
+ * @brief General Exception dealing with vectors.
+ */
+template<class T>
+class VectorException :
+  public Exception
+{
+
+	protected:
+		const std::vector<T> * vect_;
+			
+	public:
+		VectorException(const std::string& text, const std::vector<T>* vect = 0) :
+			Exception("VectorException: " + text),
+			vect_(vect) {};
+
+    VectorException(const VectorException& ve): Exception(ve), vect_(ve.vect_) {}
+    VectorException& operator=(const VectorException& ve)
+    {
+      Exception::operator=(ve);
+      vect_ = ve.vect_;
+      return *this;
+    }
+	
+		virtual ~VectorException() throw () {};
+		
+	public:
+		virtual const std::vector<T>* getVector() const { return vect_; }
+};
+
+/**
+ * @brief Exception thrown when an empty vector was found.
+ */
+template<class T>
+class EmptyVectorException :
+  public VectorException<T>
+{
+
+	public:
+		EmptyVectorException(const std::string& text, const std::vector<T>* vect = 0) :
+			VectorException<T>("EmptyVectorException: " + text, vect) {};
+	
+		virtual ~EmptyVectorException() throw () {}
+};
+
+/**
+ * @brief Exception thrown when a dimension problem occured.
+ */
+class DimensionException :
+  public Exception
+{
+	private:
+		size_t dimension_;
+		size_t correctDimension_; 
+			
+	public:
+		DimensionException(const std::string& text, size_t dimension, size_t correctDimension) :
+		    Exception("DimensionException (found " + TextTools::toString(dimension) + ", should be " + TextTools::toString(correctDimension) + ") " + text),
+        dimension_(dimension),
+        correctDimension_(correctDimension) {};
+	
+		virtual ~DimensionException() throw () {}
+
+	public:
+		virtual size_t getDimension() const { return dimension_; }
+		virtual size_t getCorrectDimension() const { return correctDimension_; }
+};
+
+/**
+ * @brief Exception thrown when a given element was not found in the vector.
+ */
+template<class T> class ElementNotFoundException :
+  public VectorException<T>
+{
+
+	private:
+		const T* element_;
+			
+	public:
+		ElementNotFoundException(const std::string& text, const std::vector<T>* vect = 0, const T* element = 0) :
+			VectorException<T>("ElementNotFoundException: " + text, vect),
+			element_(element) {};
+
+    ElementNotFoundException(const ElementNotFoundException& enfe):
+      VectorException<T>(enfe), element_(enfe.element_) {}
+    
+    ElementNotFoundException& operator=(const ElementNotFoundException& enfe)
+    {
+      VectorException<T>::operator=(enfe);
+      element_ = enfe.element_;
+      return *this;
+    }
+
+		virtual ~ElementNotFoundException() throw () {};
+		
+	public:
+		virtual const T* getElement() const { return element_; }
+};
+
+} //end of namespace bpp.
+
+#endif //_VECTOREXCEPTIONS_H_
+
diff --git a/src/Bpp/Numeric/VectorTools.cpp b/src/Bpp/Numeric/VectorTools.cpp
new file mode 100644
index 0000000..a4e9f08
--- /dev/null
+++ b/src/Bpp/Numeric/VectorTools.cpp
@@ -0,0 +1,101 @@
+//
+// File: VectorTools.cpp
+// Created by: Julien Dutheil
+// Created on: Fri Mar 14 14:16:32 2003
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+// From Utils:
+#include "../Text/TextTools.h"
+
+#include "VectorTools.h"
+using namespace bpp;
+
+// From the STL:
+#include <cmath>
+#include <iostream>
+using namespace std;
+
+/******************************************************************************/
+
+vector<double> VectorTools::breaks(const vector<double>& v, unsigned int n)
+{
+  vector<double> out;
+  vector<double> r = VectorTools::range(v);
+  double part = (r[1] - r[0]) / n;
+  for (unsigned int i = 0; i < n; ++i)
+  {
+    out.push_back(r[0] + (part * i));
+  }
+  out.push_back(r[1]);
+  return out;
+}
+
+/******************************************************************************/
+
+bool VectorTools::test()
+{
+  vector<double> x1(5);
+  vector<double> x2(5);
+  x1[0] = -3.4;
+  x1[1] =  1.8;
+  x1[2] = -2.1;
+  x1[3] = -2.5;
+  x1[4] =  1.0;
+
+  x2[0] = -5.3;
+  x2[1] = -4.8;
+  x2[2] =  2.7;
+  x2[3] =  7.2;
+  x2[4] =  0.4;
+
+  print(x1);
+  print(x2);
+  double m1 = mean<double, double>(x1);
+  double m2 = mean<double, double>(x2);
+  double v1 = var<double, double>(x1);
+  double v2 = var<double, double>(x2);
+  cout << "Mean x1 = " << m1 << "\tVar x1 = " << v1 << endl;
+  cout << "Mean x2 = " << m2 << "\tVar x2 = " << v2 << endl;
+  cov<double, double>(x1, x2);
+  cor<double, double>(x1, x2);
+  cos<double, double>(x1, x2);
+  shannon<double, double>(x1);
+  return m1 == -0.2 && m2 == 0.04 && v1 == 6.565 && v2 == 27.603;
+}
+
+/******************************************************************************/
+
+
diff --git a/src/Bpp/Numeric/VectorTools.h b/src/Bpp/Numeric/VectorTools.h
new file mode 100644
index 0000000..8c4ea51
--- /dev/null
+++ b/src/Bpp/Numeric/VectorTools.h
@@ -0,0 +1,1939 @@
+//
+// File: VectorTools.h
+// Created by: Julien Dutheil
+// Created on: Fri Mar 14 14:16:32 2003
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide classes
+   for numerical calculus.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#ifndef _VECTORTOOLS_H_
+#define _VECTORTOOLS_H_
+
+#include "VectorExceptions.h"
+#include "NumTools.h"
+#include "AdaptiveKernelDensityEstimation.h"
+#include "Matrix/Matrix.h"
+#include "../Io/OutputStream.h"
+#include "../App/ApplicationTools.h"
+
+// From the STL:
+#include <vector>
+#include <map>
+#include <cmath>
+#include <algorithm>
+#include <complex>
+
+namespace bpp
+{
+typedef std::vector<std::complex<double> > Vcomplex;
+typedef std::vector<Vcomplex> VVcomplex;
+typedef std::vector<VVcomplex> VVVcomplex;
+
+typedef std::vector<std::complex<long double> > Vlcomplex;
+typedef std::vector<Vlcomplex> VVlcomplex;
+typedef std::vector<VVlcomplex> VVVlcomplex;
+
+typedef std::vector<double> Vdouble;
+typedef std::vector<Vdouble> VVdouble;
+typedef std::vector<VVdouble> VVVdouble;
+typedef std::vector<VVVdouble> VVVVdouble;
+
+typedef std::vector<long double> Vldouble;
+typedef std::vector<Vldouble> VVldouble;
+typedef std::vector<VVldouble> VVVldouble;
+typedef std::vector<VVVldouble> VVVVldouble;
+
+typedef std::vector<int> Vint;
+typedef std::vector<Vint> VVint;
+typedef std::vector<VVint> VVVint;
+typedef std::vector<VVVint> VVVVint;
+
+/**
+ * @name Element-wise operations.
+ * @{
+ */
+
+template<class T>
+std::vector<T>  operator+(const std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
+{
+  size_t size;
+  if (v1.size() != v2.size())
+  {
+    throw DimensionException("VectorTools::operator+", v1.size(), v2.size());
+  }
+  else
+  {
+    size = v1.size();
+  }
+  std::vector<T> result(size);
+  for (size_t i = 0; i < size; i++)
+  {
+    result[i] = v1[i] + v2[i];
+  }
+  return result;
+}
+
+template<class T>
+std::vector<T> operator-(const std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
+{
+  size_t size;
+  if (v1.size() != v2.size())
+  {
+    throw DimensionException("VectorTools::operator-", v1.size(), v2.size());
+  }
+  else
+  {
+    size = v1.size();
+  }
+  std::vector<T> result(size);
+  for (size_t i = 0; i < size; i++)
+  {
+    result[i] = v1[i] - v2[i];
+  }
+  return result;
+}
+
+template<class T>
+std::vector<T> operator*(const std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
+{
+  size_t size;
+  if (v1.size() != v2.size())
+  {
+    throw DimensionException("VectorTools::operator*", v1.size(), v2.size());
+  }
+  else
+  {
+    size = v1.size();
+  }
+  std::vector<T> result(size);
+  for (size_t i = 0; i < size; i++)
+  {
+    result[i] = v1[i] * v2[i];
+  }
+  return result;
+}
+
+template<class T>
+std::vector<T> operator/(const std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
+{
+  size_t size;
+  if (v1.size() != v2.size())
+  {
+    throw DimensionException("VectorTools::operator/", v1.size(), v2.size());
+  }
+  else
+  {
+    size = v1.size();
+  }
+  std::vector<T> result(size);
+  for (size_t i = 0; i < size; i++)
+  {
+    result[i] = v1[i] / v2[i];
+  }
+  return result;
+}
+
+
+template<class T, class C>
+std::vector<T> operator+(const std::vector<T>& v1, const C& c)
+{
+  std::vector<T> result(v1.size());
+  for (size_t i = 0; i < result.size(); i++)
+  {
+    result[i] = v1[i] + c;
+  }
+  return result;
+}
+template<class T, class C>
+std::vector<T> operator+(const C& c, const std::vector<T>& v1)
+{
+  std::vector<T> result(v1.size());
+  for (size_t i = 0; i < result.size(); i++)
+  {
+    result[i] = c + v1[i];
+  }
+  return result;
+}
+
+template<class T, class C>
+std::vector<T> operator-(const std::vector<T>& v1, const C& c)
+{
+  std::vector<T> result(v1.size());
+  for (size_t i = 0; i < result.size(); i++)
+  {
+    result[i] = v1[i] - c;
+  }
+  return result;
+}
+template<class T, class C>
+std::vector<T> operator-(const C& c, const std::vector<T>& v1)
+{
+  std::vector<T> result(v1.size());
+  for (size_t i = 0; i < result.size(); i++)
+  {
+    result[i] = c - v1[i];
+  }
+  return result;
+}
+
+template<class T, class C>
+std::vector<T> operator*(const std::vector<T>& v1, const C& c)
+{
+  std::vector<T> result(v1.size());
+  for (size_t i = 0; i < result.size(); i++)
+  {
+    result[i] = v1[i] * c;
+  }
+  return result;
+}
+template<class T, class C>
+std::vector<T> operator*(const C& c, const std::vector<T>& v1)
+{
+  std::vector<T> result(v1.size());
+  for (size_t i = 0; i < result.size(); i++)
+  {
+    result[i] = c * v1[i];
+  }
+  return result;
+}
+
+template<class T, class C>
+std::vector<T> operator/(const std::vector<T>& v1, const C& c)
+{
+  std::vector<T> result(v1.size());
+  for (size_t i = 0; i < result.size(); i++)
+  {
+    result[i] = v1[i] / c;
+  }
+  return result;
+}
+template<class T, class C>
+std::vector<T> operator/(const C& c, const std::vector<T>& v1)
+{
+  std::vector<T> result(v1.size());
+  for (size_t i = 0; i < result.size(); i++)
+  {
+    result[i] = c / v1[i];
+  }
+  return result;
+}
+
+
+template<class T>
+void operator+=(std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
+{
+  for (size_t i = 0; i < v1.size(); i++)
+  {
+    v1[i] += v2[i];
+  }
+}
+
+template<class T>
+void operator-=(std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
+{
+  for (size_t i = 0; i < v1.size(); i++)
+  {
+    v1[i] -= v2[i];
+  }
+}
+
+template<class T>
+void operator*=(std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
+{
+  for (size_t i = 0; i < v1.size(); i++)
+  {
+    v1[i] *= v2[i];
+  }
+}
+
+template<class T>
+void operator/=(std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
+{
+  for (size_t i = 0; i < v1.size(); i++)
+  {
+    v1[i] /= v2[i];
+  }
+}
+
+
+template<class T, class C>
+void operator+=(std::vector<T>& v1, const C& c)
+{
+  for (size_t i = 0; i < v1.size(); i++)
+  {
+    v1[i] += c;
+  }
+}
+
+template<class T, class C>
+void operator-=(std::vector<T>& v1, const C& c)
+{
+  for (size_t i = 0; i < v1.size(); i++)
+  {
+    v1[i] -= c;
+  }
+}
+
+template<class T, class C>
+void operator*=(std::vector<T>& v1, const C& c)
+{
+  for (size_t i = 0; i < v1.size(); i++)
+  {
+    v1[i] *= c;
+  }
+}
+
+template<class T, class C>
+void operator/=(std::vector<T>& v1, const C& c)
+{
+  for (size_t i = 0; i < v1.size(); i++)
+  {
+    v1[i] /= c;
+  }
+}
+/** @} */
+
+/******************************************************************************/
+
+class VectorTools
+{
+public:
+  VectorTools() {}
+  virtual ~VectorTools() {}
+
+public:
+  /**
+   * @name Matrix-like functions to resize arrays.
+   *
+   * @{
+   */
+  template<class T>
+  static void resize2(VVdouble& vv, size_t n1, size_t n2)
+  {
+    vv.resize(n1);
+    for (size_t i = 0; i < n1; i++) { vv[i].resize(n2); }
+  }
+
+  template<class T>
+  static void resize3(VVVdouble& vvv, size_t n1, size_t n2, size_t n3)
+  {
+    vvv.resize(n1);
+    for (size_t i = 0; i < n1; i++)
+    {
+      vvv[i].resize(n2);
+      for (size_t j = 0; j < n2; j++)
+      {
+        vvv[i][j].resize(n3);
+      }
+    }
+  }
+
+  static void resize4(VVVVdouble& vvvv, size_t n1, size_t n2, size_t n3, size_t n4)
+  {
+    vvvv.resize(n1);
+    for (size_t i = 0; i < n1; i++)
+    {
+      vvvv[i].resize(n2);
+      for (size_t j = 0; j < n2; j++)
+      {
+        vvvv[i][j].resize(n3);
+        for (size_t k = 0; k < n3; k++)
+        {
+          vvvv[i][j][k].resize(n4);
+        }
+      }
+    }
+  }
+  /** @} */
+
+  template<class T>
+  static void fill(std::vector<T>& v, T value)
+  {
+    for (typename std::vector<T>::iterator it = v.begin(); it < v.end(); it++)
+    {
+      *it = value;
+    }
+  }
+
+  /**
+   * @brief Build a sequence std::vector.
+   *
+   * Build a std::vector from a value to another with a specified step.
+   * This works for numerical values for which additions, subtractions and division
+   * makes sens.
+   *
+   * @param from The begining.
+   * @param to The end.
+   * @param by The step.
+   * @return A std::vector containing the sequence.
+   */
+  template<class T>
+  static std::vector<T> seq(T from, T to, T by)
+  {
+    std::vector<T> v;
+    if (from < to)
+    {
+      // for (T i = from ; i <= to ; i += by) {           // Not good for double, 'to'
+      for (T i = from; i <= to + (by / 100); i += by)
+      { // must be a little bit larger
+        v.push_back(i);
+      }
+    }
+    else
+    {
+      for (T i = from; i >= to - (by / 100); i -= by)
+      {
+        v.push_back(i);
+      }
+    }
+    return v;
+  }
+
+  /**
+   * @brief Send the position of the first occurence of 'which'.
+   *
+   * Comparisons are performed using the == operator.
+   * Maximum complexity: O(v.size()).
+   *
+   * @param v The std::vector to search.
+   * @param which The element to search.
+   * @return The position of which in v.
+   */
+  template<class T>
+  static size_t which(const std::vector<T>& v, const T& which) throw (ElementNotFoundException<T> )
+  {
+    for (size_t i = 0; i < v.size(); i++)
+    {
+      if (v[i] == which) return i;
+    }
+    throw ElementNotFoundException<T>("VectorTools::which.", &v, &which);
+  }
+
+  /**
+   * @brief Send the positions of all occurences of 'which'.
+   *
+   * Comparisons are performed using the == operator.
+   * Complexity: O(v.size()).
+   *
+   * @param v The std::vector to search.
+   * @param which The element to search.
+   * @return A std::vector containing the positions of which in v.
+   */
+  template<class T>
+  static std::vector<size_t> whichAll(const std::vector<T>& v, const T& which) throw (ElementNotFoundException<T> )
+  {
+    std::vector<size_t> w;
+    for (size_t i = 0; i < v.size(); i++)
+    {
+      if (v[i] == which) w.push_back(i);
+    }
+    if (w.size())
+      return w;
+    throw ElementNotFoundException<T>("VectorTools::whichAll.", &v, &which);
+  }
+
+  /**
+   * @brief Send a new std::vector with unique elements.
+   *
+   * The input std::vector is copied, and the copy is sorted using QuickSort algorithm.
+   * A one-pass loop then look for duplicates and copy unique element to a result std::vector.
+   * The output std::vector is hence sorted.
+   *
+   * If v is empty, it is passed 'as is' in return (after being copied).
+   *
+   * @param v the std::vector to parse.
+   */
+  template<class T>
+  static std::vector<T> unique(const std::vector<T>& v)
+  {
+    if (v.size() == 0) return v;
+    std::vector<T> sortedV(v.begin(), v.end());
+    sort(sortedV.begin(), sortedV.end());
+    std::vector<T> uniq;
+    uniq.push_back(sortedV[0]);
+    for (size_t i = 1; i < sortedV.size(); i++)
+    {
+      if (sortedV[i] != sortedV[i - 1]) uniq.push_back(sortedV[i]);
+    }
+    return uniq;
+  }
+
+  /**
+   * @brief Tell if the std::vector as unique elements.
+   *
+   * The input std::vector is copied, and the copy is sorted using QuickSort algorithm.
+   * A one-pass loop then look for duplicates.
+   *
+   * If v is empty, the method returns 'true'.
+   *
+   * @param v the std::vector to parse.
+   */
+  template<class T>
+  static bool isUnique(const std::vector<T>& v)
+  {
+    if (v.size() == 0) return true;
+    std::vector<T> sortedV(v.begin(), v.end());
+    sort(sortedV.begin(), sortedV.end());
+    for (size_t i = 1; i < sortedV.size(); i++)
+    {
+      if (sortedV[i] == sortedV[i - 1]) return false;
+    }
+    return true;
+  }
+
+  /**
+   * @author Laurent Gueguen
+   * @param v1 the std::vector of elements,
+   * @param v2 the std::vector of the selected positions
+   * @return the std::vector of the selected elements, in the order of the
+   *  required positions
+   */
+  template<class T>
+  static std::vector<T> extract(const std::vector<T>& v1, const std::vector<int>& v2)
+  {
+    std::vector<T> v(v2.size());
+    for (size_t i = 0; i < v2.size(); i++)
+    {
+      v[i] = v1[v2[i]];
+    }
+    return v;
+  }
+
+  /**
+   * @brief Count each element of a std::vector.
+   *
+   * @return A map with keys = unique std::vector values and values = count for each std::vector value.
+   * @param v the std::vector to parse.
+   */
+  template<class T>
+  static std::map<T, size_t> countValues(const std::vector<T>& v)
+  {
+    std::map<T, size_t> c;
+    for (size_t i = 0; i < v.size(); i++)
+    {
+      c[v[i]]++;
+    }
+    return c;
+  }
+
+  /**
+   * @brief Get the break points for a given number of classes.
+   *
+   * Given a std::vector of values, return the values that cut the range of values
+   * in a given number of classes.
+   *
+   * @param v The std::vector to parse.
+   * @param n The expected number of classes.
+   * @return a std::vector of size = n + 1 containing the breaking points.
+   */
+  static std::vector<double> breaks(const std::vector<double>& v, unsigned int n);
+
+  /**
+   * @brief Get the optimal class number following Scott's method.
+   *
+   * Use Scott's (1979) method to compute the optimal class number for histogram.
+   *
+   * Scott, D.W. (1979) On optimal and data-based histograms. Biometrika, 66, 605¿610.
+   *
+   * @param v The std::vector to parse.
+   * @return The number of classes.
+   */
+  template<class T>
+  static size_t nclassScott(const std::vector<T>& v)
+  {
+    std::vector<T> r1 = VectorTools::range(v);
+    T r = r1[1] - r1[0];
+    double n = v.size();
+    double h = 3.5 * VectorTools::sd<T, double>(v) * std::pow(n, -1. / 3);
+    return (size_t) ceil(r / h);
+  }
+
+  /**
+   * @return The product of all elements in a std::vector.
+   * @param v1 A std::vector.
+   */
+  template<class T>
+  static T prod(const std::vector<T>& v1)
+  {
+    T p = 1;
+    for (size_t i = 0; i < v1.size(); i++) { p *= v1[i]; }
+    return p;
+  }
+
+  /**
+   * @return The cumulative product of all elements in a std::vector.
+   * @param v1 A std::vector.
+   * @author Julien Dutheil
+   */
+  template<class T>
+  static std::vector<T> cumProd(const std::vector<T>& v1)
+  {
+    std::vector<T> p(v1.size());
+    if (v1.size() == 0) return p;
+    p[0] = v1[0];
+    for (size_t i = 1; i < v1.size(); i++) { p[i] = v1[i] * p[i - 1]; }
+    return p;
+  }
+
+  /**
+   * @return The sum of all elements in a std::vector.
+   * @param v1 A std::vector.
+   */
+  template<class T>
+  static T sum(const std::vector<T>& v1)
+  {
+    T s = 0;
+    for (size_t i = 0; i < v1.size(); i++) { s += v1[i]; }
+    return s;
+  }
+
+  /**
+   * @return The cumulative sum of all elements in a std::vector.
+   * @param v1 A std::vector.
+   * @author Julien Dutheil
+   */
+  template<class T>
+  static std::vector<T> cumSum(const std::vector<T>& v1)
+  {
+    std::vector<T> s(v1.size());
+    if (v1.size() == 0) return s;
+    s[0] = v1[0];
+    for (size_t i = 1; i < v1.size(); i++) { s[i] = v1[i] + s[i - 1]; }
+    return s;
+  }
+
+  /**
+   * @author Laurent Gueguen
+   * @return Log-normalize std::vector v1, ie add a constant to the elements of v
+   *  such that @f$\sum_i(\exp(v_i)) = 1 at f$.
+   * @param v std::vector.
+   */
+  template<class T>
+  static void logNorm(std::vector<T>& v)
+  {
+    T M = max(v);
+    T x = std::exp(v[0] - M);
+    for (size_t i = 1; i < v.size(); i++)
+    {
+      x += std::exp(v[i] - M);
+    }
+    v -= M + std::log(x);
+  }
+
+  /**
+   * @author Laurent Gueguen
+   * @return From std::vector v1, return @f$\log(\sum_i(\exp(v1_i)))@f$.
+   * @param v1 a std::vector.
+   */
+  template<class T>
+  static T logSumExp(const std::vector<T>& v1)
+  {
+    T M = max(v1);
+    T x = std::exp(v1[0] - M);
+    for (size_t i = 1; i < v1.size(); i++)
+    {
+      x += std::exp(v1[i] - M);
+    }
+    return std::log(x) + M;
+  }
+
+  /**
+   * @author Laurent Gueguen
+   * @return From std::vector v1, return @f$\log(\sum_i(v2_i * \exp(v1_i)))@f$.
+   * @param v1 a std::vector.
+   * @param v2 another std::vector.
+   */
+  template<class T>
+  static T logSumExp(const std::vector<T>& v1, const std::vector<T>& v2)
+  {
+    size_t size;
+    if (v1.size() != v2.size())
+      throw DimensionException("VectorTools::logsumexp", v1.size(), v2.size());
+    else
+      size = v1.size();
+
+    T M = max(v1);
+    T x = v2[0] * std::exp(v1[0] - M);
+    for (size_t i = 1; i < size; i++)
+    {
+      x += v2[i] * std::exp(v1[i] - M);
+    }
+    return std::log(x) + M;
+  }
+
+  /**
+   * @author Laurent Gueguen
+   * @return From std::vector v1, return @f$\log(\textrm{mean}_i(\exp(v1_i)))@f$.
+   * @param v1 a std::vector.
+   */
+  template<class T>
+  static T logMeanExp(const std::vector<T>& v1)
+  {
+    T M = max(v1);
+    T x = std::exp(v1[0] - M);
+    for (size_t i = 1; i < v1.size(); i++)
+    {
+      x += std::exp(v1[i] - M);
+    }
+    return std::log(x) + M - std::log(v1.size());
+  }
+
+
+  /**
+   * @author Laurent Gueguen
+   * @return From std::vector v1, return @f$\sum_i(\exp(v1_i))@f$.
+   * @param v1 a std::vector.
+   */
+  template<class T>
+  static T sumExp(const std::vector<T>& v1)
+  {
+    T M = max(v1);
+    T x = std::exp(v1[0] - M);
+    for (size_t i = 1; i < v1.size(); i++)
+    {
+      x += std::exp(v1[i] - M);
+    }
+    return x * std::exp(M);
+  }
+
+  /**
+   * @author Laurent Gueguen
+   * @return From std::vector v1, return @f$\sum_i(v2_i * \exp(v1_i))@f$.
+   * @param v1 a std::vector.
+   * @param v2 another std::vector.
+   */
+  template<class T>
+  static T sumExp(const std::vector<T>& v1, const std::vector<T>& v2)
+  {
+    size_t size;
+    if (v1.size() != v2.size())
+      throw DimensionException("VectorTools::logsumexp", v1.size(), v2.size());
+    else
+      size = v1.size();
+
+    T M = max(v1);
+    T x = v2[0] * std::exp(v1[0] - M);
+    for (size_t i = 1; i < size; i++)
+    {
+      x += v2[i] * std::exp(v1[i] - M);
+    }
+    return x * std::exp(M);
+  }
+
+  /**
+   * @name These methods apply the corresponding function to each element
+   * and return the result in a new std::vector.
+   *
+   * @{
+   */
+  template<class T>
+  static std::vector<double> log(const std::vector<T>& v1)
+  {
+    std::vector<double> v2(v1.size());
+    for (size_t i = 0; i < v2.size(); i++) { v2[i] = std::log(v1[i]); }
+    return v2;
+  }
+  template<class T>
+  static std::vector<double> log(const std::vector<T>& v1, double base)
+  {
+    std::vector<double> v2(v1.size());
+    for (size_t i = 0; i < v2.size(); i++) { v2[i] = std::log(v1[i]) / std::log(base); }
+    return v2;
+  }
+
+  template<class T>
+  static std::vector<double> exp(const std::vector<T>& v1)
+  {
+    std::vector<double> v2(v1.size());
+    for (size_t i = 0; i < v2.size(); i++) { v2[i] = std::exp(v1[i]); }
+    return v2;
+  }
+
+  template<class T>
+  static std::vector<double> cos(const std::vector<T>& v1)
+  {
+    std::vector<double> v2(v1.size());
+    for (size_t i = 0; i < v2.size(); i++) { v2[i] = std::cos(v1[i]); }
+    return v2;
+  }
+
+  template<class T>
+  static std::vector<double> sin(const std::vector<T>& v1)
+  {
+    std::vector<double> v2(v1.size());
+    for (size_t i = 0; i < v2.size(); i++) { v2[i] = std::sin(v1[i]); }
+    return v2;
+  }
+
+  template<class T>
+  static std::vector<double> log10(const std::vector<T>& v1)
+  {
+    std::vector<double> v2(v1.size());
+    for (size_t i = 0; i < v1.size(); i++) { v2[i] = std::log10(v1[i]); }
+    return v2;
+  }
+
+  template<class T>
+  static std::vector<T> fact(const std::vector<T>& v1)
+  {
+    std::vector<T> v2(v1.size());
+    for (size_t i = 0; i < v1.size(); i++) { v2[i] = NumTools::fact<T>(v1[i]); }
+    return v2;
+  }
+
+  template<class T>
+  static std::vector<T> sqr(const std::vector<T>& v1)
+  {
+    std::vector<T> v2(v1.size());
+    for (size_t i = 0; i < v1.size(); i++) { v2[i] = NumTools::sqr<T>(v1[i]); }
+    return v2;
+  }
+
+  template<class T>
+  static std::vector<T> pow(const std::vector<T>& v1, T& b)
+  {
+    std::vector<T> v2(v1.size());
+    for (size_t i = 0; i < v1.size(); i++) { v2[i] = std::pow(v1[i], b); }
+    return v2;
+  }
+  /** @} */
+
+  /**
+   * @brief Concatenate a std::vector after converting to string.
+   *
+   * @param v The std::vector to concatenate.
+   * @param delim A string which is used to separate the values (default is " ").
+   */
+  template<class T>
+  static std::string paste(const std::vector<T>& v, const std::string& delim = " ")
+  {
+    std::ostringstream out;
+    for (size_t i = 0; i < v.size(); i++)
+    {
+      out << v[i];
+      if (i < v.size() - 1)
+        out << delim;
+    }
+    return out.str();
+  }
+
+  /**
+   * @brief Print a std::vector to a stream.
+   * @param v1 A std::vector.
+   * @param out A stream.
+   * @param delim A string which is used to separate the values (default is " ").
+   */
+  template<class T>
+  static void print(const std::vector<T>& v1, OutputStream& out = * ApplicationTools::message, const std::string& delim = " ")
+  {
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      out << v1[i];
+      if (i < v1.size() - 1)
+        out << delim;
+    }
+    out.endLine();
+  }
+
+  /**
+   * @brief Print a std::vector to a stream in R format
+   * @param v1 A std::vector.
+   * @param variableName the variable name (default "x").
+   * @param out A stream (default cout).
+   */
+  template<class T>
+  static void printForR(const std::vector<T>& v1, std::string variableName = "x", std::ostream& out = std::cout)
+  {
+    out.precision(12);
+    out << variableName << "<-c(";
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      out << v1[i];
+      if (i < v1.size() - 1)
+        out << ", ";
+    }
+    out << ")" << std::endl;
+  }
+
+  /**
+   * @return The scalar product of two std::vectors.
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   * @throw DimensionException If the two std::vector do not have the same length.
+   */
+  template<class InputType, class OutputType>
+  static OutputType scalar(const std::vector<InputType>& v1, const std::vector<InputType>& v2) throw (DimensionException)
+  {
+    if (v1.size() != v2.size())
+    {
+      throw DimensionException("VectorFunctions::scalar", v1.size(), v2.size());
+    }
+    OutputType result = 0;
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      result += v1[i] * v2[i];
+    }
+    return result;
+  }
+  /**
+   * This dt product correspond to the dot product <v1,v2> in the space defined by
+   * @f[
+   * M =
+   * \begin{pmatrix}
+   * w_1 & \ldots & \\
+   * \vdots & w_2  & \ldots\\
+   *        & \vdots & \ddots\\
+   * \end{pmatrix}
+   * @f]
+   * @return The "weighted" scalar product of two std::vectors.
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   * @param w A std::vector of weights.
+   * @throw DimensionException If the two std::vector do not have the same length or do not match the length of the weights.
+   */
+  template<class InputType, class OutputType>
+  static OutputType scalar(const std::vector<InputType>& v1, const std::vector<InputType>& v2, const std::vector<InputType>& w) throw (DimensionException)
+  {
+    if (v1.size() != w.size())
+    {
+      throw DimensionException("VectorFunctions::scalar", v1.size(), w.size());
+    }
+    if (v2.size() != w.size())
+    {
+      throw DimensionException("VectorFunctions::scalar", v2.size(), w.size());
+    }
+    OutputType result = 0;
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      result += v1[i] * v2[i] * w[i];
+    }
+    return result;
+  }
+
+  /**
+   * @return The scalar Kronecker product of two std::vectors.
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   * @throw DimensionException If the two std::vector do not have the same length.
+   */
+  template<class T>
+  static std::vector<T> kroneckerMult(const std::vector<T>& v1, const std::vector<T>& v2) throw (DimensionException)
+  {
+    size_t n1 = v1.size();
+    size_t n2 = v2.size();
+    std::vector<T> v3(n1 * n2);
+    for (size_t i = 0; i < n1; i++)
+    {
+      T v1i = v1[i];
+      for (size_t j = 0; j < n2; j++)
+      {
+        v3[i * n2 + j] = v1i * v2[j];
+      }
+    }
+    return v3;
+  }
+
+  /**
+   * @return The norm of a std::vector (@f$\sqrt{\sum_i^n x_i^2}@f$).
+   * @param v1 A std::vector.
+   */
+  template<class InputType, class OutputType>
+  static OutputType norm(const std::vector<InputType>& v1)
+  {
+    OutputType result = 0;
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      result += v1[i] * v1[i];
+    }
+    return sqrt(result);
+  }
+
+  /**
+   * @return The "weighted" norm of a std::vector (@f$\sqrt{\sum_i^n x_i^2}@f$).
+   * @param v1 A std::vector.
+   * @param w A std::vector of weights.
+   * @throw DimensionException If v1 and w do not have the same length.
+   * @see scalar.
+   */
+  template<class InputType, class OutputType>
+  static OutputType norm(const std::vector<InputType>& v1, const std::vector<InputType>& w) throw (DimensionException)
+  {
+    if (v1.size() != w.size())
+    {
+      throw DimensionException("VectorFunctions::norm", v1.size(), w.size());
+    }
+    OutputType result = 0;
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      result += v1[i] * v1[i] * w[i];
+    }
+    return sqrt(result);
+  }
+
+  /**
+   * @return The cosinus of the angle of two std::vectors.
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   * @throw DimensionException If the two std::vector do not have the same length.
+   */
+  template<class InputType, class OutputType>
+  static OutputType cos(const std::vector<InputType>& v1, const std::vector<InputType>& v2) throw (DimensionException)
+  {
+    return scalar<InputType, OutputType>(v1, v2)
+           / (norm<InputType, OutputType>(v1) * norm<InputType, OutputType>(v2));
+  }
+
+  /**
+   * @return The weighted cosinus of the angle of two std::vectors.
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   * @param w A std::vector of weights.
+   * @throw DimensionException If the two std::vector do not have the same length.
+   */
+  template<class InputType, class OutputType>
+  static OutputType cos(const std::vector<InputType>& v1, const std::vector<InputType>& v2, const std::vector<InputType>& w) throw (DimensionException)
+  {
+    return scalar<InputType, OutputType>(v1, v2, w)
+           / (norm<InputType, OutputType>(v1, w) * norm<InputType, OutputType>(v2, w));
+  }
+
+  /**
+   * @name Extrema.
+   *
+   * @{
+   */
+
+  /**
+   * @brief Template function to get the minimum value of a std::vector.
+   *
+   * The < operator must be defined for the specified class.
+   *
+   * @param v The input std::vector.
+   * @return The minimum value in the std::vector.
+   * @throw EmptyVectorException If the input std::vector is empty.
+   */
+  template<class T>
+  static T min(const std::vector<T>& v) throw (EmptyVectorException<T> )
+  {
+    if (v.size() == 0) throw EmptyVectorException<T>("VectorFunctions::min()", &v);
+    T mini = v[0];
+    for (size_t i = 1; i < v.size(); i++)
+    {
+      if (v[i] < mini) mini = v[i];
+    }
+    return mini;
+  }
+
+  /**
+   * @brief Template function to get the maximum value of a std::vector.
+   *
+   * The > operator must be defined for the specified class.
+   *
+   * @param v The input std::vector.
+   * @return The maximum value in the std::vector.
+   * @throw EmptyVectorException If the input std::vector is empty.
+   */
+  template<class T>
+  static T max(const std::vector<T>& v) throw (EmptyVectorException<T> )
+  {
+    if (v.size() == 0) throw EmptyVectorException<T>("VectorFuntions::max()", &v);
+    T maxi = v[0];
+    for (size_t i = 1; i < v.size(); i++)
+    {
+      if (v[i] > maxi) maxi = v[i];
+    }
+    return maxi;
+  }
+
+  /**
+   * @brief Template function to get the index of the maximum value of a std::vector.
+   *
+   * The > operator must be defined for the specified class.
+   * The position sent is the first one matching the maximum value.
+   *
+   * @param v The input std::vector.
+   * @return The position of the maximum value in the std::vector.
+   * @throw EmptyVectorException If the input std::vector is empty.
+   */
+  template<class T>
+  static size_t whichMax(const std::vector<T>& v) throw (EmptyVectorException<T> )
+  {
+    if (v.size() == 0) throw EmptyVectorException<T>("VectorFuntions::whichMax()", &v);
+    T maxi = v[0];
+    size_t pos = 0;
+    for (size_t i = 1; i < v.size(); i++)
+    {
+      if (v[i] > maxi)
+      {
+        maxi = v[i];
+        pos = i;
+      }
+    }
+    return pos;
+  }
+
+  /**
+   * @brief Template function to get the index of the minimum value of a std::vector.
+   *
+   * The < operator must be defined for the specified class.
+   * The position sent is the first one matching the maximum value.
+   *
+   * @param v The input std::vector.
+   * @return The position of the minimum value in the std::vector.
+   * @throw EmptyVectorException If the input std::vector is empty.
+   */
+  template<class T>
+  static size_t whichMin(const std::vector<T>& v) throw (EmptyVectorException<T> )
+  {
+    if (v.size() == 0) throw EmptyVectorException<T>("VectorFunctions::whichMin()", &v);
+    T mini = v[0];
+    size_t pos = 0;
+    for (size_t i = 1; i < v.size(); i++)
+    {
+      if (v[i] < mini)
+      {
+        mini = v[i];
+        pos = i;
+      }
+    }
+    return pos;
+  }
+
+  /**
+   * @brief Template function to get the indices of the maximum value of a std::vector.
+   *
+   * The > and == operator must be defined for the specified class.
+   * All positions matching the maximum value are returned.
+   *
+   * @param v The input std::vector.
+   * @return A vector of positions matching the maximum value in the std::vector.
+   * @throw EmptyVectorException If the input std::vector is empty.
+   */
+  template<class T>
+  static std::vector<size_t> whichMaxAll(const std::vector<T>& v) throw (EmptyVectorException<T> )
+  {
+    if (v.size() == 0) throw EmptyVectorException<T>("VectorFuntions::whichMaxAll()", &v);
+    T maxi = max(v);
+    std::vector<size_t> pos;
+    for (size_t i = 0; i < v.size(); i++)
+    {
+      if (v[i] == maxi)
+      {
+        pos.push_back(i);
+      }
+    }
+    return pos;
+  }
+
+  /**
+   * @brief Template function to get the indices of the minimum value of a std::vector.
+   *
+   * The < and == operator must be defined for the specified class.
+   * All positions matching the maximum value are returned.
+   *
+   * @param v The input std::vector.
+   * @return A vector of positions matching the minimum value in the std::vector.
+   * @throw EmptyVectorException If the input std::vector is empty.
+   */
+  template<class T>
+  static std::vector<size_t> whichMinAll(const std::vector<T>& v) throw (EmptyVectorException<T> )
+  {
+    if (v.size() == 0) throw EmptyVectorException<T>("VectorFuntions::whichMinAll()", &v);
+    T mini = min(v);
+    std::vector<size_t> pos;
+    for (size_t i = 0; i < v.size(); i++)
+    {
+      if (v[i] == mini)
+      {
+        pos.push_back(i);
+      }
+    }
+    return pos;
+  }
+
+
+  /**
+   * @brief Template function to get both extrema of a std::vector.
+   *
+   * Both < and > operators must be defined for the specified class.
+   *
+   * @param v The input std::vector.
+   * @return A std::vector of size 2 which values are min(v) and max(v).
+   * throw EmptyVectorException If the input std::vector is empty.
+   */
+  template<class T>
+  static std::vector<T> range(const std::vector<T>& v) throw (EmptyVectorException<T> )
+  {
+    if (v.size() == 0)
+      throw EmptyVectorException<T>("VectorTools::range()", &v);
+    std::vector<T> r(2);
+    r[0] = r[1] = v[0];
+    for (size_t i = 1; i < v.size(); i++)
+    {
+      if (v[i] < r[0]) r[0] = v[i];
+      if (v[i] > r[1]) r[1] = v[i];
+    }
+    return r;
+  }
+
+private:
+  template<class T> class order_Cmp_
+  {
+    const std::vector<T>& values_;
+
+public:
+    order_Cmp_(const std::vector<T>& v) : values_(v) {}
+    bool operator()(size_t a, size_t b) { return values_[a] < values_[b]; }
+  };
+
+public:
+  /**
+   * @brief Template function to get the order of elements in the input vector.
+   *
+   * This function is equivalent to the R 'order' function. It will sort elements by increasing size, so that [0] in the resulting outptu vector is the indice of the minimum element in the input vector, [1] is the second minimum, etc.
+   *
+   * @param v The input std::vector.
+   * @return Vector with sorted positions, according to input vector.
+   * throw EmptyVectorException If the input std::vector is empty.
+   */
+  template<class T>
+  static std::vector<size_t> order(const std::vector<T>& v) throw (EmptyVectorException<T> )
+  {
+    if (v.size() == 0)
+      throw EmptyVectorException<T>("VectorTools::sort()", &v);
+    // Private inner class:
+    std::vector<size_t> index(v.size());
+    for (size_t i = 0; i < index.size(); ++i)
+    {
+      index[i] = i;
+    }
+    sort(index.begin(), index.end(), order_Cmp_<T>(v));
+    return index;
+  }
+
+  /** @} */
+
+  /**
+   * @brief Template function to get the absolute value of all elements of a std::vector.
+   *
+   *
+   * @param v The input std::vector.
+   * @return A vector with all absolute values.
+   */
+  template<class T>
+  static std::vector<T> abs(const std::vector<T>& v) throw (EmptyVectorException<T> )
+  {
+    std::vector<T> vabs(v.size());
+    for (size_t i = 1; i < v.size(); i++)
+    {
+      vabs[i] = std::abs(v[i]);
+    }
+    return vabs;
+  }
+
+  /**
+   * @return The mean value of the std::vector.
+   * @param v1 A std::vector.
+   */
+  template<class InputType, class OutputType>
+  static OutputType mean(const std::vector<InputType>& v1)
+  {
+    return (OutputType)sum<InputType>(v1) / (OutputType)v1.size();
+  }
+  /**
+   * @return The weighted mean value of the std::vector.
+   * @param v1 A std::vector.
+   * @param w A std::vector of weights.
+   * @param normalizeWeights Tell if weights should be normalized so that they sum to 1.
+   */
+  template<class InputType, class OutputType>
+  static OutputType mean(const std::vector<InputType>& v1, const std::vector<InputType>& w, bool normalizeWeights = true)
+  {
+    if (normalizeWeights)
+    {
+      std::vector<InputType> wn = w / sum(w);
+      return scalar<InputType, OutputType>(v1, wn);
+    }
+    else
+    {
+      return scalar<InputType, OutputType>(v1, w);
+    }
+  }
+
+  /**
+   * @return The median value of the std::vector.
+   * @param v1 A std::vector.
+   */
+  template<class InputType>
+  static InputType median(std::vector<InputType>& v1)
+  {
+    InputType med = 0;
+    if (v1.size() == 0) return med;
+    if (v1.size() == 1) return v1[0];
+    sort(v1.begin(), v1.end());
+    size_t i = v1.size() / 2;
+    if (v1.size() % 2 == 0)
+    {
+      // Vector size is pair
+      med = double((v1[i - 1] + v1[i]) / 2);
+    }
+    else
+    {
+      // Vector size is impair
+      med = v1[i];
+    }
+    return med;
+  }
+
+  /**
+   * @brief Set the mean of a std::vector to be 0.
+   *
+   * @return A std::vector with mean 0.
+   * @param v1 A std::vector.
+   */
+  template<class InputType, class OutputType>
+  static std::vector<OutputType> center(const std::vector<InputType>& v1)
+  {
+    OutputType m = mean<InputType, OutputType>(v1);
+    std::vector<OutputType> v(v1.size());
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      v[i] = (OutputType)v1[i] - m;
+    }
+    return v;
+  }
+  /**
+   * @brief Set the weighted mean of a std::vector to be 0.
+   *
+   * @return A std::vector with mean 0.
+   * @param v1 A std::vector.
+   * @param w A std::vector of weights.
+   * @param normalizeWeights Tell if weights should be normalized so that they sum to 1.
+   */
+  template<class InputType, class OutputType>
+  static std::vector<OutputType> center(const std::vector<InputType>& v1, const std::vector<InputType>& w, bool normalizeWeights = true)
+  {
+    OutputType m = mean<InputType, OutputType>(v1, w, normalizeWeights);
+    std::vector<OutputType> v(v1.size());
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      v[i] = (OutputType)v1[i] - m;
+    }
+    return v;
+  }
+
+  /**
+   * @return The covariance of two std::vectors.
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   * @param unbiased Tell if an unbiased estimate must be computed.
+   * @throw DimensionException If the two std::vector do not have the same length.
+   */
+  template<class InputType, class OutputType>
+  static OutputType cov(const std::vector<InputType>& v1, const std::vector<InputType>& v2, bool unbiased = true) throw (DimensionException)
+  {
+    OutputType n = (OutputType)v1.size();
+    OutputType x =  scalar<InputType, OutputType>(
+      center<InputType, OutputType>(v1),
+      center<InputType, OutputType>(v2)
+      ) / n;
+    if (unbiased) x = x * n / (n - 1);
+    return x;
+  }
+
+  /**
+   * @return The weighted covariance of two std::vectors.
+   * To have a population estimate you have to multiply by \f$\frac{n}{n-1}\f$.
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   * @param w A std::vector of weights.
+   * @param unbiased Tell if an unbiased estimate must be computed.
+   * @param normalizeWeights Tell if weights should be normalized so that they sum to 1.
+   * @throw DimensionException If the two std::vector do not have the same length.
+   */
+  template<class InputType, class OutputType>
+  static OutputType cov(const std::vector<InputType>& v1, const std::vector<InputType>& v2, const std::vector<InputType>& w, bool unbiased = true, bool normalizeWeights = true) throw (DimensionException)
+  {
+    if (normalizeWeights)
+    {
+      std::vector<InputType> wn = w / sum(w);
+      OutputType x = scalar<InputType, OutputType>(
+        center<InputType, OutputType>(v1, wn, false),
+        center<InputType, OutputType>(v2, wn, false),
+        wn
+        );
+      if (unbiased)
+      {
+        x = x / (1 - sum(sqr<double>(wn)));
+      }
+      return x;
+    }
+    else
+    {
+      OutputType x = scalar<InputType, OutputType>(
+        center<InputType, OutputType>(v1, w, false),
+        center<InputType, OutputType>(v2, w, false),
+        w
+        );
+      if (unbiased)
+      {
+        x = x / (1 - sum(sqr(w)));
+      }
+      return x;
+    }
+  }
+  /**
+   * @return The variance of the std::vector.
+   * @param v1 The sample std::vector.
+   * @param unbiased Tell if an unbiased estimate must be computed.
+   */
+  template<class InputType, class OutputType>
+  static OutputType var(const std::vector<InputType>& v1, bool unbiased = true)
+  {
+    return cov<InputType, OutputType>(v1, v1, unbiased);
+  }
+  /**
+   * @return The weighted variance of the std::vector.
+   * @param v1 The sample std::vector.
+   * @param w A std::vector of weights.
+   * @param unbiased Tell if an unbiased estimate must be computed.
+   * @param normalizeWeights Tell if weights should be normalized so that they sum to 1.
+   * @throw DimensionException If v1 and w do not have the same length.
+   */
+  template<class InputType, class OutputType>
+  static OutputType var(const std::vector<InputType>& v1, const std::vector<InputType>& w, bool unbiased = true, bool normalizeWeights = true) throw (DimensionException)
+  {
+    return cov<InputType, OutputType>(v1, v1, w, unbiased, normalizeWeights);
+  }
+
+  /**
+   * @return The standard deviation of the std::vector.
+   * @param v1 The sample std::vector.
+   * @param unbiased Tell if an unbiased estimate must be computed.
+   */
+  template<class InputType, class OutputType>
+  static OutputType sd(const std::vector<InputType>& v1, bool unbiased = true)
+  {
+    return sqrt(var<InputType, OutputType>(v1, unbiased));
+  }
+
+  /**
+   * @return The weighted standard deviation of the std::vector.
+   * @param v1 The sample std::vector.
+   * @param w A std::vector of weights.
+   * @param unbiased Tell if an unbiased estimate must be computed.
+   * @param normalizeWeights Tell if weights should be normalized so that they sum to 1.
+   * @throw DimensionException If v1 and w do not have the same length.
+   */
+  template<class InputType, class OutputType>
+  static OutputType sd(const std::vector<InputType>& v1, const std::vector<InputType>& w, bool unbiased = true, bool normalizeWeights = true) throw (DimensionException)
+  {
+    return sqrt(var<InputType, OutputType>(v1, w, unbiased, normalizeWeights));
+  }
+
+  /**
+   * @return The Pearson correlation coefficient of two std::vectors.
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   * @throw DimensionException If the two std::vector do not have the same length.
+   */
+  template<class InputType, class OutputType>
+  static OutputType cor(const std::vector<InputType>& v1, const std::vector<InputType>& v2) throw (DimensionException)
+  {
+    return cov<InputType, OutputType>(v1, v2)
+           / ( sd<InputType, OutputType>(v1) * sd<InputType, OutputType>(v2) );
+  }
+
+  /**
+   * @return The weighted Pearson correlation coefficient of two std::vectors.
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   * @param w A std::vector of weights.
+   * @param normalizeWeights Tell if weights should be normalized so that they sum to 1.
+   * @throw DimensionException If the two std::vector do not have the same length.
+   */
+  template<class InputType, class OutputType>
+  static OutputType cor(const std::vector<InputType>& v1, const std::vector<InputType>& v2, const std::vector<InputType>& w, bool normalizeWeights = true) throw (DimensionException)
+  {
+    if (normalizeWeights)
+    {
+      std::vector<InputType> wn = w / sum(w);
+      return cov<InputType, OutputType>(v1, v2, wn, false, false)
+             / ( sd<InputType, OutputType>(v1, wn, false, false) * sd<InputType, OutputType>(v2, wn, false, false) );
+    }
+    else
+    {
+      return cov<InputType, OutputType>(v1, v2, w, false, false)
+             / ( sd<InputType, OutputType>(v1, w, false, false) * sd<InputType, OutputType>(v2, w, false, false) );
+    }
+  }
+
+  /**
+   * @return Compute the Shannon entropy indice of a vector of frequencies.
+   *
+   * The elements of the vector should contain frequencies
+   * of each modality of the variable and sum to one. This verification is left to the user
+   * though.
+   *
+   * @author Julien Dutheil
+   * @see shannonDiscrete for computing the shannon indice of a sample, discrete version.
+   * @see shannonContinuous for computing the shannon indice of a sample, continuous version.
+   *
+   * @param v The input std::vector.
+   * @param base The base of the logarithm to use.
+   */
+  template<class InputType, class OutputType>
+  static OutputType shannon(const std::vector<InputType>& v, double base = 2.7182818)
+  {
+    OutputType s = 0;
+    for (size_t i = 0; i < v.size(); i++)
+    {
+      if (v[i] > 0) s += static_cast<OutputType>(v[i] * std::log(v[i]) / std::log(base));
+    }
+    return -s;
+  }
+
+  /**
+   * @return Compute the Shannon entropy indice of a vector.
+   *
+   * This is the discrete version. The vector is supposed to be a finite sample from
+   * a discrete distribution. The counts of each observed state are computed and used
+   * to compute the discrete entropy.
+   *
+   * @author Julien Dutheil
+   * @see shannonContinuous for the continuous version.
+   * @see shannon for direct computation from frequencies.
+   *
+   * @param v The input std::vector.
+   * @param base The base of the logarithm to use.
+   */
+  template<class InputType, class OutputType>
+  static OutputType shannonDiscrete(const std::vector<InputType>& v, double base = 2.7182818)
+  {
+    std::map<InputType, double> counts;
+    for (size_t i = 0; i < v.size(); i++)
+    {
+      counts[v[i]]++;
+    }
+    OutputType s = 0;
+    double n = static_cast<double>(v.size());
+    for (typename std::map<InputType, double>::iterator it = counts.begin(); it != counts.end(); it++)
+    {
+      s += static_cast<OutputType>((it->second / n) * std::log(it->second / n) / std::log(base));
+    }
+    return -s;
+  }
+
+  /**
+   * @return Compute mutual information index from two samples from discrete variables.
+   *
+   * This is the discrete version. Each vector is supposed to be a finite sample from
+   * a discrete distribution. The counts of each (joint) observed state are computed
+   * and used to compute the discrete mutual information.
+   *
+   * @author Julien Dutheil
+   * @see miContinuous.
+   *
+   * @param v1 The first input vector.
+   * @param v2 The second input vector.
+   * @param base The base of the logarithm to use.
+   * @throw DimensionException if the two vectors do not have the same lengths.
+   */
+  template<class InputType, class OutputType>
+  static OutputType miDiscrete(const std::vector<InputType>& v1, const std::vector<InputType>& v2, double base = 2.7182818) throw (DimensionException)
+  {
+    if (v1.size() != v2.size())
+      throw DimensionException("VectorTools::miDiscrete. The two samples must have the same length.", v2.size(), v1.size());
+    std::map<InputType, double> counts1;
+    std::map<InputType, double> counts2;
+    std::map<InputType, std::map<InputType, double> > counts12;
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      counts1[v1[i]]++;
+      counts2[v2[i]]++;
+      counts12[v1[i]][v2[i]]++;
+    }
+    OutputType s = 0;
+    double n = static_cast<double>(v1.size());
+    for (typename std::map<InputType, std::map<InputType, double> >::iterator it1 = counts12.begin(); it1 != counts12.end(); it1++)
+    {
+      for (typename std::map<InputType, double>::iterator it2 = it1->second.begin(); it2 != it1->second.end(); it2++)
+      {
+        s += static_cast<OutputType>((it2->second / n) * std::log(it2->second * n / (counts1[it1->first] * counts2[it2->first])) / std::log(base));
+      }
+    }
+    return s;
+  }
+
+  /**
+   * @return Compute the Shannon entropy indice of a sample from a continuous variable.
+   *
+   * This is the continuous version. The vector is supposed to be a finite sample from
+   * a continuous distribution. The density is of the distribution is estimated using
+   * a kernel method, and is used to compute the continuous entropy.
+   *
+   * Reference: Ivan Kojadinovic (2004) _Computational Statistics & Data Analysis_, 46:269-294
+   *
+   * @author Julien Dutheil
+   * @see shannon For the discrete version.
+   *
+   * @param v The input std::vector.
+   * @param base The base of the logarithm to use.
+   */
+  template<class InputType, class OutputType>
+  static OutputType shannonContinuous(const std::vector<InputType>& v, double base = 2.7182818)
+  {
+    LinearMatrix<InputType> m(1, v.size());
+    for (size_t i = 0; i < v.size(); i++)
+    {
+      m(0, i) = v[i];
+    }
+    AdaptiveKernelDensityEstimation kd(m);
+    OutputType s = 0;
+    std::vector<double> x(1);
+    for (size_t i = 0; i < v.size(); i++)
+    {
+      x[0] = static_cast<double>(v[i]);
+      s += static_cast<OutputType>(std::log(kd.kDensity(x)) / std::log(base));
+    }
+    return -s / static_cast<double>(v.size());
+  }
+
+  /**
+   * @return Compute mutual information index from two samples from continuous variables.
+   *
+   * This is the continuous version. Each vector is supposed to be a finite sample from
+   * a continuous distribution. The density is of the distribution is estimated using
+   * a kernel method, as well as the joint density, and are used to compute the continuous
+   * mutual information.
+   *
+   * Reference: Ivan Kojadinovic (2004) _Computational Statistics & Data Analysis_, 46:269-294
+   *
+   * @author Julien Dutheil
+   * @see miDiscrete For the discrete version.
+   * @warning This function is experimental. Notably, bad kernel density estimates may lead to negative MI :(
+   *
+   * @param v1 The first input vector.
+   * @param v2 The second input vector.
+   * @param base The base of the logarithm to use.
+   * @throw DimensionException if the two vectors do not have the same lengths.
+   */
+  template<class InputType, class OutputType>
+  static OutputType miContinuous(const std::vector<InputType>& v1, const std::vector<InputType>& v2, double base = 2.7182818) throw (DimensionException)
+  {
+    if (v1.size() != v2.size())
+      throw DimensionException("VectorTools::miContinuous. The two samples must have the same length.", v2.size(), v1.size());
+    LinearMatrix<InputType> m1(1, v1.size());
+    LinearMatrix<InputType> m2(1, v2.size());
+    LinearMatrix<InputType> m12(2, v1.size());
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      m1(0, i) = m12(0, i) = v1[i];
+      m2(0, i) = m12(1, i) = v2[i];
+    }
+    AdaptiveKernelDensityEstimation kd1(m1);
+    AdaptiveKernelDensityEstimation kd2(m2);
+    AdaptiveKernelDensityEstimation kd12(m12);
+    OutputType s = 0;
+    std::vector<double> x1(1);
+    std::vector<double> x2(1);
+    std::vector<double> x12(2);
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      x1[0] = x12[0] = static_cast<double>(v1[i]);
+      x2[0] = x12[1] = static_cast<double>(v2[i]);
+      s += static_cast<OutputType>(std::log(kd12.kDensity(x12) / (kd1.kDensity(x1) * kd2.kDensity(x2))) / std::log(base));
+    }
+    return s / static_cast<double>(v1.size());
+  }
+
+  /**
+   * @return 'true' if the two std::vectors contains the same elements, whatever their order in the container.
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   */
+  template<class T>
+  static bool haveSameElements(const std::vector<T>& v1, const std::vector<T>& v2)
+  {
+    std::vector<T> u1(v1);
+    std::vector<T> u2(v2);
+    if (u1.size() != u2.size()) return false;
+    std::sort(u1.begin(), u1.end());
+    std::sort(u2.begin(), u2.end());
+    return u1 == u2;
+  }
+
+  /**
+   * @return 'true' if the two std::vectors contains the same elements, <b>in the same frequency</b>, whatever their order in the container.
+   *
+   * @warning The two input std::vectors will be sorted.
+   *
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   */
+  template<class T>
+  static bool haveSameElements(std::vector<T>& v1, std::vector<T>& v2)
+  {
+    if (v1.size() != v2.size()) return false;
+    std::sort(v1.begin(), v1.end());
+    std::sort(v2.begin(), v2.end());
+    return v1 == v2;
+  }
+
+  /**
+   * @return 'true' if a the input std::vector contains the given element.
+   * @param vec The std::vector to check.
+   * @param el The element to look for.
+   */
+  template<class T>
+  static bool contains(const std::vector<T>& vec, T el)
+  {
+    for (size_t i = 0; i < vec.size(); i++)
+    {
+      if (vec[i] == el) return true;
+    }
+    return false;
+  }
+
+  /**
+   * @return 'true' if a the first std::vector contains all elements of the second std::vector.
+   *
+   * @warning The two input std::vectors will be sorted.
+   *
+   * @param v1 The first std::vector to check.
+   * @param v2 The second std::vector to check.
+   */
+  template<class T>
+  static bool containsAll(std::vector<T>& v1, std::vector<T>& v2)
+  {
+    std::sort(v1.begin(), v1.end());
+    std::sort(v2.begin(), v2.end());
+    size_t j = 0;
+    for (size_t i = 0; i < v2.size(); i++)
+    {
+      if (i > 0 && v2[i] == v2[i - 1]) continue;
+      while (j < v1.size() - 1 && v1[j] < v2[i]) j++;
+      if (v1[j] != v2[i]) return false;
+    }
+    return true;
+  }
+
+  /**
+   * @return A std::vector which is the union of two std::vectors passed as input.
+   * Duplicate element will be removed.
+   * @param vec1 Vector 1.
+   * @param vec2 Vector 2.
+   */
+  template<class T>
+  static std::vector<T> vectorUnion(const std::vector<T>& vec1, const std::vector<T>& vec2)
+  {
+    std::vector<T> unionEl = vec1;
+    for (size_t j = 0; j < vec2.size(); j++)
+    {
+      if (!contains(unionEl, vec2[j]))
+        unionEl.push_back(vec2[j]);
+    }
+    return unionEl;
+  }
+
+  /**
+   * @return A std::vector which is the union of all std::vectors passed as input.
+   * Duplicate element will be removed.
+   * @param vecElementL A std::vector of std::vectors.
+   */
+  template<class T>
+  static std::vector<T> vectorUnion(const std::vector< std::vector<T> >& vecElementL)
+  {
+    std::vector<T> unionEl;
+    for (size_t i = 0; i < vecElementL.size(); i++)
+    {
+      for (size_t j = 0; j < vecElementL[i].size(); j++)
+      {
+        if (!contains(unionEl, vecElementL[i][j]))
+          unionEl.push_back(vecElementL[i][j]);
+      }
+    }
+    return unionEl;
+  }
+
+  /**
+   * @return A std::vector which is the intersection of two std::vectors passed as input.
+   * @param vec1 Vector 1.
+   * @param vec2 Vector 2.
+   */
+  template<class T>
+  static std::vector<T> vectorIntersection(const std::vector<T>& vec1, const std::vector<T>& vec2)
+  {
+    std::vector<T> interEl;
+    for (size_t i = 0; i < vec1.size(); i++)
+    {
+      if (contains(vec2, vec1[i])) interEl.push_back(vec1[i]);
+    }
+    return interEl;
+  }
+
+  /**
+   * @return A std::vector which is the intersection of all std::vectors passed as input.
+   * @param vecElementL A std::vector of std::vectors.
+   */
+  template<class T>
+  static std::vector<T> vectorIntersection(const std::vector< std::vector<T> >& vecElementL)
+  {
+    if (vecElementL.size() == 1) return vecElementL[0];
+    std::vector<T> interEl;
+    if (vecElementL.size() == 0) return interEl;
+    for (size_t i = 0; i < vecElementL[0].size(); i++)
+    {
+      bool test = true;
+      for (size_t j = 1; test && j < vecElementL.size(); j++)
+      {
+        if (!contains(vecElementL[j], vecElementL[0][i])) test = false;
+      }
+      if (test) interEl.push_back(vecElementL[0][i]);
+    }
+    return interEl;
+  }
+
+  /**
+   * @brief Append the content of a std::vector to another one.
+   * @param vec1 Vector 1.
+   * @param vec2 Vector 2.
+   */
+  template<class T>
+  static void append(std::vector<T>& vec1, const std::vector<T>& vec2)
+  {
+    vec1.insert(vec1.end(), vec2.begin(), vec2.end());
+    // for(size_t i = 0; i < vec2.size(); i++)
+    // {
+    //  vec1.push_back(vec2[i]);
+    // }
+  }
+
+  /**
+   * @brief Prepend the content of a std::vector to another one.
+   * @param vec1 Vector 1.
+   * @param vec2 Vector 2.
+   */
+  template<class T>
+  static void prepend(std::vector<T>& vec1, const std::vector<T>& vec2)
+  {
+    vec1.insert(vec1.begin(), vec2.begin(), vec2.end());
+  }
+
+
+  /**
+   * @return A single std::vector made of the concatenation of the std::vectors passed as input.
+   * @param vecElementL A std::vector of std::vectors.
+   */
+  template<class T>
+  static std::vector<T> append(const std::vector< std::vector<T> >& vecElementL)
+  {
+    if (vecElementL.size() == 1) return vecElementL[0];
+    std::vector<T> v;
+    if (vecElementL.size() == 0) return v;
+    for (size_t i = 0; i < vecElementL[0].size(); i++)
+    {
+      v.push_back(vecElementL[0][i]);
+    }
+    return v;
+  }
+
+  /**
+   * @brief Extend the content of a std::vector with another one. Only the elements not present in the first vector will be added.
+   * @param vec1 Vector 1.
+   * @param vec2 Vector 2.
+   */
+  template<class T>
+  static void extend(std::vector<T>& vec1, const std::vector<T>& vec2)
+  {
+    for (size_t i = 0; i < vec2.size(); i++)
+    {
+      if (!contains(vec1, vec2[i]))
+        vec1.push_back(vec2[i]);
+    }
+  }
+
+  /**
+   * @return A single std::vector made of the repetion of the std::vectors passed as input.
+   * @param vec A std::vector.
+   * @param n the number of repetitions
+   */
+  template<class T>
+  static std::vector<T> rep(const std::vector<T>& vec, size_t n)
+  {
+    if (n == 1) return vec;
+    std::vector<T> v;
+    if (n == 0) return v;
+    v.resize(vec.size() * n);
+    for (size_t i = 0; i < v.size(); i++)
+    {
+      v[i] = vec[i % vec.size()];
+    }
+    return v;
+  }
+
+  /**
+   * @brief This function returns the difference of two std::vectors.
+   *
+   * @warning The two input std::vectors will be sorted. As a consequence, the output std::vector will be also sorted.
+   *
+   * @param v1 First std::vector.
+   * @param v2 Second std::vector.
+   * @param v3 A std::vector to be populated with all elements in v1 that are not found in v2.
+   */
+  template<class T>
+  static void diff(std::vector<T>& v1, std::vector<T>& v2, std::vector<T>& v3)
+  {
+    if (v2.size() == 0) append(v3, v1);
+    std::sort(v1.begin(), v1.end());
+    std::sort(v2.begin(), v2.end());
+    size_t j = 0;
+    for (size_t i = 0; i < v1.size(); i++)
+    {
+      if (i > 0 && v1[i] == v1[i - 1]) continue;
+      while (j < v2.size() - 1 && v2[j] < v1[i]) j++;
+      if (v2[j] != v1[i]) v3.push_back(v1[i]);
+    }
+  }
+
+  /**
+   * @brief Test function.
+   * @return true if all tests are passed.
+   */
+  static bool test();
+};
+} // end of namespace bpp.
+
+#endif  // _VECTORTOOLS_H_
+
diff --git a/src/Bpp/Text/KeyvalTools.cpp b/src/Bpp/Text/KeyvalTools.cpp
new file mode 100644
index 0000000..1b8f78b
--- /dev/null
+++ b/src/Bpp/Text/KeyvalTools.cpp
@@ -0,0 +1,118 @@
+//
+// File: KeyvalTools.cpp
+// Created by: Julien Dutheil
+// Created on: Mon May 13:16 CET 2009
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (2009)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "KeyvalTools.h"
+#include "NestedStringTokenizer.h"
+
+//From the STL:
+#include <memory>
+
+using namespace bpp;
+using namespace std;
+
+void KeyvalTools::singleKeyval(const std::string& desc, std::string& key, std::string& val, const std::string& split) throw (KeyvalException)
+{
+  string::size_type i = desc.find(split);
+  if (i == string::npos)
+    throw KeyvalException("Bad syntax! keyval should be of the form 'key" + split + "=value', found '" + desc + "'.");
+  key = desc.substr(0, i);
+  val = desc.substr(i+1);
+}
+
+void KeyvalTools::multipleKeyvals(const std::string& desc, std::map<std::string,std::string>& keyvals, const std::string& split, bool nested) throw (KeyvalException)
+{
+  auto_ptr<StringTokenizer> st;
+  if (nested)
+    st.reset(new NestedStringTokenizer(desc, "(", ")", split));
+  else
+    st.reset(new StringTokenizer(desc, split));
+  string key, val;
+  vector<string> tokens;
+  //Check tokens:
+  string token;
+  while (st->hasMoreToken())
+  {
+    token = st->nextToken();
+    if (token == "=")
+    {
+      //We need to merge the next token with the last one:
+      if (tokens.size() == 0)
+        throw KeyvalException("Invalid syntax, found '=' without argument name.");
+      if (!st->hasMoreToken())
+        throw KeyvalException("Invalid syntax, found '=' without argument value.");
+      string nextToken = st->nextToken();
+      if (nextToken == "=")
+        throw KeyvalException("Invalid syntax, found a double '='.");
+      tokens[tokens.size() - 1] += "=" + nextToken;
+    }
+    else
+    {
+      tokens.push_back(token);
+    }
+  }
+  for (vector<string>::iterator it = tokens.begin(); it != tokens.end(); it++)
+  {
+    singleKeyval(*it, key, val);
+    keyvals[key] = val;
+  }
+}
+
+void KeyvalTools::parseProcedure(const std::string& desc, std::string& name, std::map<std::string, std::string>& args) throw (KeyvalException)
+{
+  string::size_type begin = desc.find_first_of("(");
+  string::size_type end = desc.find_last_of(")");
+  
+  if (begin == string::npos && end == string::npos)
+  {
+    //Empty procedure:
+    name = desc;
+    return;
+  }
+  if (begin == string::npos && end != string::npos)
+    throw KeyvalException("Bad keyval procedure, missing opening parenthesis.");
+  if (begin == string::npos && end != string::npos)
+    throw KeyvalException("Bad keyval procedure, missing closing parenthesis.");
+  
+  if (!TextTools::isEmpty(desc.substr(end + 1)))
+    throw KeyvalException("Bad keyval procedure, extra characters after closing parenthesis: " + desc.substr(end + 1));
+  //Get the procedure name (without leading spaces):
+  name = TextTools::removeFirstWhiteSpaces(desc.substr(0, begin));
+  multipleKeyvals(desc.substr(begin + 1, end - begin - 1), args);
+}
+
diff --git a/src/Bpp/Text/KeyvalTools.h b/src/Bpp/Text/KeyvalTools.h
new file mode 100644
index 0000000..4a078c5
--- /dev/null
+++ b/src/Bpp/Text/KeyvalTools.h
@@ -0,0 +1,117 @@
+//
+// File: KeyvalTools.h
+// Created by: Julien Dutheil
+// Created on: Mon May 13:16 CET 2009
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Tools, (2009)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _KEYVALTOOLS_H_
+#define _KEYVALTOOLS_H_
+
+#include "StringTokenizer.h"
+#include "TextTools.h"
+#include "../Exceptions.h"
+
+//From the STL:
+#include <map>
+
+namespace bpp
+{
+
+/**
+ * @brief Exception thrown by the Keyval parser.
+ */
+class KeyvalException :
+  public Exception
+{
+  public:
+    KeyvalException(const std::string& message) : Exception(message) {}
+};
+
+/**
+ * @brief Tools to deal with the keyval syntax.
+ *
+ * This class contains method to deal with parameter=value syntax procedure.
+ * A keyval procedure takes the form 
+ * @code
+ * proc(p1=v1,p2=v2,p3=v3,etc)
+ * @endcode
+ * where 'p' are parameter names, and 'v' are the corresponding values.
+ * These values can be nested keyval procedures.
+ */
+class KeyvalTools
+{
+  public:
+    KeyvalTools();
+    virtual ~KeyvalTools();
+
+  public:
+    /**
+     * @brief Split a string into a key and a value (General purpose function).
+     *
+     * @param desc  [in]  A string descibing the keyval, with format key=val (space are considered normal character, that's up to you to deal with that afterward!).
+     * @param key   [out] Will contain the text of the key.
+     * @param val   [out] Will contain the text of the value.
+     * @param split [in]  The delimiter. Default is '=' but ':' can be used.
+     * @throw KeyvalException If the syntax describing the keyval is not correct.
+     */
+    static void singleKeyval(const std::string& desc, std::string& key, std::string& val, const std::string& split = "=") throw (KeyvalException);
+    
+    /**
+     * @brief Split a string into several keys and corresponding values (General purpose function).
+     *
+     * @param desc [in]  A string descibing the keyval, with format key1=val1,key2=val2,etc (space are considered normal character, that's up to you to deal with that afterward!).
+     * @param keyvals [out] Will contain the text of the keys and their corresponding values.
+     * @param split [in] The keyval delimiter.the default is a coma, but a space character can be used for instance.
+     * @param nested [in] Tell if nested keyval procedures are expected.
+     * @throw KeyvalException If the syntax describing the keyval is not correct.
+     */
+    static void multipleKeyvals(const std::string& desc, std::map<std::string, std::string>& keyvals, const std::string& split = ",", bool nested = true) throw (KeyvalException);
+
+    /**
+     * @brief Parse (not recursively) a procedure string.
+     *
+     * @param desc [in]  A string descibing the keyval procedure.
+     * @param name [out] Outputs the name of the procedure.
+     * @param args [out] Fills a map with all keys and values for parameters.
+     * @throw KeyvalException If the description is invalid (one parenthesis is missing for instance).
+     */
+    static void parseProcedure(const std::string& desc, std::string& name, std::map<std::string, std::string>& args) throw (KeyvalException);
+};
+
+} //End of namespace bpp.
+
+#endif  //_KEYVALTOOLS_H_
+
diff --git a/src/Bpp/Text/NestedStringTokenizer.cpp b/src/Bpp/Text/NestedStringTokenizer.cpp
new file mode 100644
index 0000000..bff6bc6
--- /dev/null
+++ b/src/Bpp/Text/NestedStringTokenizer.cpp
@@ -0,0 +1,153 @@
+//
+// File: NestedStringTokenizer.cpp
+// Author : Julien Dutheil
+// Last modification : Monday May 22 10:57 2006
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to map data onto
+a sequence or a phylogenetic tree.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "NestedStringTokenizer.h"
+#include "TextTools.h"
+
+using namespace bpp;
+
+//From the STL:
+#include <iostream>
+
+using namespace std;
+
+NestedStringTokenizer::NestedStringTokenizer(const std::string& s, const std::string& open, const std::string& end, const std::string& delimiters, bool solid)
+  throw (Exception):
+    StringTokenizer()
+{
+  int blocks = 0;
+  string cache = "";
+	if (!solid)
+  {
+    string::size_type index = s.find_first_not_of(delimiters, 0);
+		while (index != s.npos)
+    {
+      string::size_type newIndex = s.find_first_of(delimiters, index);
+      bool endBlockFound = false;
+      while (!endBlockFound)
+      {
+			  if (newIndex != s.npos)
+        {
+			    string token = s.substr(index, newIndex - index);
+          blocks += static_cast<int>(TextTools::count(token, open)) - static_cast<int>(TextTools::count(token, end));
+        
+				  if (blocks == 0)
+          {
+            tokens_.push_back(cache + token);
+            cache = ""; //reset cache.
+				    index = s.find_first_not_of(delimiters, newIndex);
+            endBlockFound = true;
+          }
+          else
+          {
+            // Ignore this token untill closing block is found
+            cache += s.substr(index, newIndex - index + 1);
+            index = newIndex + 1;
+            newIndex = s.find_first_of(delimiters, index);
+          }
+			  }
+        else
+        {
+			    string token = s.substr(index);
+          blocks += static_cast<int>(TextTools::count(token, open)) - static_cast<int>(TextTools::count(token, end));
+			    if (blocks == 0)
+          {
+				    tokens_.push_back(cache + token);
+            cache = ""; //reset cache.
+				    index = newIndex;
+            endBlockFound = true;
+          }
+          else throw Exception("NestedStringTokenizer (constructor). Unclosed block.");
+			  }
+      }
+		}
+	}
+	else
+  {
+    string::size_type index = 0;
+		while (index != s.npos)
+    {
+      string::size_type newIndex = s.find(delimiters, index);
+      bool endBlockFound = false;
+      while (!endBlockFound)
+      {
+			  if (newIndex != s.npos)
+        {
+			    string token = s.substr(index, newIndex - index);
+          blocks += static_cast<int>(TextTools::count(token, open)) - static_cast<int>(TextTools::count(token, end));
+				  
+          if (blocks == 0)
+          {
+            tokens_.push_back(cache + token);
+            cache = ""; //reset cache.
+				    index = newIndex + delimiters.size();
+            endBlockFound = true;
+          }
+          else
+          {
+            // Ignore this token untill closing block is found
+            cache += s.substr(index, newIndex - index + 1);
+            index = newIndex + 1;
+            newIndex = s.find(delimiters, index);
+          }
+			  }
+        else
+        {
+  		    string token = s.substr(index);
+          blocks += static_cast<int>(TextTools::count(token, open)) - static_cast<int>(TextTools::count(token, end));
+	  	    if (blocks == 0)
+          {
+				    tokens_.push_back(cache + token);
+            cache = ""; //reset cache.
+				    index = newIndex;
+            endBlockFound = true;
+          }
+          else throw Exception("Unclosed block."); 
+			  }
+		  }
+	  }
+  }
+}
+
+const std::string& NestedStringTokenizer::nextToken() throw (Exception)
+{
+	if (!hasMoreToken()) throw Exception("No more token in nested tokenizer.");
+	return tokens_[currentPosition_++];
+}
+
diff --git a/src/Bpp/Text/NestedStringTokenizer.h b/src/Bpp/Text/NestedStringTokenizer.h
new file mode 100644
index 0000000..0a4dd36
--- /dev/null
+++ b/src/Bpp/Text/NestedStringTokenizer.h
@@ -0,0 +1,99 @@
+//
+// File: NestedStringTokenizer.h
+// Author : Julien Dutheil
+// Last modification : Monday May 22 10:57 2006
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to map data onto
+a sequence or a phylogenetic tree.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _NESTEDSTRINGTOKENIZER_H_
+#define _NESTEDSTRINGTOKENIZER_H_
+
+//From the STL:
+#include <deque>
+#include <string>
+
+#include "StringTokenizer.h"
+#include "../Exceptions.h"
+
+namespace bpp
+{
+
+/**
+ * @brief An improved tokenizer for strings.
+ *
+ * Splits a string according to a given (set of) delimiter(s).
+ * Delimiters in certains blocks ({}, [], etc) are ignored.
+ */
+class NestedStringTokenizer:
+  public StringTokenizer
+{
+	public:
+		
+		/**
+		 * @brief Build a new StringTokenizer from a string.
+		 *
+		 * @param s          The string to parse.
+     * @param open       Opening block.
+     * @param end        Ending block.
+		 * @param delimiters Chars that must be considered as delimiters.
+		 * @param solid      If true, delimiters is considered as a single bloc delimiter.
+		 */
+		NestedStringTokenizer(const std::string& s, const std::string& open, const std::string& end, const std::string& delimiters = " \t\n\f\r", bool solid = false) throw (Exception);
+		
+		virtual ~NestedStringTokenizer() {}
+	
+	public:
+		
+		/**
+		 * @brief Get the next available token.
+		 * If no token is availbale, throw an Exception.
+		 *
+		 * @return The next token if there is one.
+		 */
+		const std::string& nextToken() throw (Exception);
+
+
+    /**
+     * @brief This function is not supported for nested tokenizers.
+     *
+     * @return An empty string.
+     */
+    std::string unparseRemainingTokens() const { return ""; }
+};
+
+} //end of namespace bpp;
+
+#endif	//_NESTEDSTRINGTOKENIZER_H_
+
diff --git a/src/Bpp/Text/StringTokenizer.cpp b/src/Bpp/Text/StringTokenizer.cpp
new file mode 100644
index 0000000..51389a9
--- /dev/null
+++ b/src/Bpp/Text/StringTokenizer.cpp
@@ -0,0 +1,122 @@
+//
+// File: StringTokenizer.cpp
+// Author : Julien Dutheil
+//          Sylvain Gaillard
+// Last modification : Monday September 20 2004
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include "StringTokenizer.h"
+
+using namespace bpp;
+using namespace std;
+
+StringTokenizer::StringTokenizer(const std::string& s, const std::string& delimiters, bool solid, bool allowEmptyTokens):
+  tokens_(),
+  splits_(),
+  currentPosition_(0)
+{
+	if (!solid)
+  {
+    string::size_type index = s.find_first_not_of(delimiters, 0);
+		while( index != s.npos)
+    {
+      string::size_type newIndex = s.find_first_of(delimiters, index);
+			if (newIndex != s.npos)
+      {
+				tokens_.push_back(s.substr(index, newIndex - index));
+				if (!allowEmptyTokens) index = s.find_first_not_of(delimiters, newIndex);
+        else                   index = newIndex + 1;
+        splits_.push_back(s.substr(newIndex, index - newIndex));
+			}
+      else
+      {
+				tokens_.push_back(s.substr(index));
+				index = newIndex;
+			}
+		}
+	}
+	else
+  {
+    string::size_type index = 0;
+		while (index != s.npos)
+    {
+      string::size_type newIndex = s.find(delimiters, index);
+			if (newIndex != s.npos)
+      {
+				tokens_.push_back(s.substr(index, newIndex - index));
+				if (!allowEmptyTokens)
+        {
+          index = newIndex + delimiters.size();
+          while (index != string::npos && s.substr(index, delimiters.size()) == delimiters)
+            index += delimiters.size();
+        }
+        else index = newIndex + delimiters.size();
+				splits_.push_back(s.substr(newIndex, index - newIndex));
+			}
+      else
+      {
+				tokens_.push_back(s.substr(index));
+				index = newIndex;
+			}
+		}
+	}
+}
+
+const std::string& StringTokenizer::nextToken() throw (Exception)
+{
+	if (!hasMoreToken()) throw Exception("No more token in tokenizer.");
+	return tokens_[currentPosition_++];
+}
+
+void StringTokenizer::removeEmptyTokens()
+{
+  for (size_t i = tokens_.size(); i > currentPosition_; i--)
+  {
+    if (tokens_[i-1] == "") tokens_.erase(tokens_.begin() + i - 1);
+  }
+}
+
+std::string StringTokenizer::unparseRemainingTokens() const
+{
+  string s;
+  for (size_t i = currentPosition_; i < tokens_.size() - 1; ++i) {
+    s += tokens_[i] + splits_[i];
+  }
+  if (numberOfRemainingTokens() > 0)
+    s += tokens_.back();
+  return s;
+}
+
diff --git a/src/Bpp/Text/StringTokenizer.h b/src/Bpp/Text/StringTokenizer.h
new file mode 100644
index 0000000..3e96097
--- /dev/null
+++ b/src/Bpp/Text/StringTokenizer.h
@@ -0,0 +1,142 @@
+//
+// File: StringTokenizer.h
+// Author : Julien Dutheil
+//          Sylvain Gaillard
+// Last modification : Monday September 20 2004
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _STRINGTOKENIZER_H_
+#define _STRINGTOKENIZER_H_
+
+#include <deque>
+#include <string>
+#include <iostream>
+
+#include "../Exceptions.h"
+
+namespace bpp
+{
+
+/**
+ * @brief A tokenizer for strings.
+ *
+ * Splits a string according to a given (set of) delimiter(s).
+ */
+class StringTokenizer
+{
+	protected:
+
+		/** @brief Where the tokens are stored. */
+    std::deque<std::string> tokens_;
+    std::deque<std::string> splits_;
+		
+		/** @brief the current position in the token list. */
+		size_t currentPosition_;
+
+	public:
+		
+		/**
+		 * @brief Build a new StringTokenizer from a string.
+		 *
+		 * @param s                The string to parse.
+		 * @param delimiters       Chars that must be considered as delimiters.
+		 * @param solid            If true, delimiters is considered as a single bloc delimiter.
+     * @param allowEmptyTokens Tell if empty tokens are allowed or should be ignored.
+		 */
+		StringTokenizer(const std::string& s, const std::string& delimiters = " \t\n\f\r", bool solid = false, bool allowEmptyTokens = false);
+	
+		virtual ~StringTokenizer() {}
+
+  public:
+    StringTokenizer(): tokens_(), splits_(), currentPosition_(0) {}
+	
+	public:
+		
+		/**
+		 * @brief Get the next available token.
+		 * If no token is availbale, throw an Exception.
+		 *
+		 * @return The next token if there is one.
+		 */
+    const std::string& nextToken() throw (Exception);
+	
+		/**
+		 * @brief Tell if some tokens are still available.
+		 * @return True if some tokens are still available.
+		 */
+		bool hasMoreToken() const {
+      return currentPosition_ < tokens_.size();
+    }
+	
+		/**
+		 * @brief Tell how many tokens are available.
+		 *
+		 * @return the number of tokens available.
+		 */
+		size_t numberOfRemainingTokens() const { return tokens_.size() - currentPosition_; }
+
+		/**
+		 * @brief Get a particular token.
+		 *
+		 * Do not move the iterator.
+		 *
+		 * @param pos The index of the token.
+		 * @return the token at position 'pos'.
+		 */
+    const std::string& getToken(size_t pos) const { return tokens_[pos]; }
+
+		/**
+		 * @brief Retrieve all tokens.
+		 *
+		 * @return A reference toward the vector of tokens.
+		 */
+		const std::deque<std::string>& getTokens() const { return tokens_; }
+
+    /**
+     * @brief remove all empty token from the current position.
+     */
+    void removeEmptyTokens();
+
+    /**
+     * @return The remaining tokens as if the original corresponding string was not parsed.
+     */
+    std::string unparseRemainingTokens() const;
+};
+
+} //end of namespace bpp.
+
+#endif	//_STRINGTOKENIZER_H_
+
diff --git a/src/Bpp/Text/TextTools.cpp b/src/Bpp/Text/TextTools.cpp
new file mode 100644
index 0000000..f187f7e
--- /dev/null
+++ b/src/Bpp/Text/TextTools.cpp
@@ -0,0 +1,525 @@
+//
+// File: TextTools.cpp
+// Created by: Julien Dutheil
+// Created on: Fri Aug  8 12:57:50 2003
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide utilitary
+   classes. This file belongs to the Bio++ Project.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use,
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info".
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability.
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or
+   data to be ensured and,  more generally, to use and operate it in the
+   same conditions as regards security.
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+ */
+
+#include "TextTools.h"
+
+using namespace bpp;
+
+#include <ctype.h>
+#include <sstream>
+#include <iomanip>
+
+using namespace std;
+
+/******************************************************************************/
+
+bool TextTools::isEmpty(const std::string& s)
+{
+  for (unsigned int i = 0; i < s.size(); i++)
+  {
+    char c = s[i];
+    if (c != ' ' && c != '\n' && c != '\t')
+      return false;
+  }
+  return true;
+}
+
+/******************************************************************************/
+
+std::string TextTools::toUpper(const std::string& s)
+{
+  string result = "";
+  for (size_t i = 0; i < s.size(); i++)
+  {
+    result += static_cast<char>(toupper(static_cast<int>(s[i])));
+  }
+  return result;
+}
+
+/******************************************************************************/
+
+std::string TextTools::toLower(const std::string& s)
+{
+  string result = "";
+  for (size_t i = 0; i < s.size(); i++)
+  {
+    result += static_cast<char>(tolower(static_cast<int>(s[i])));
+  }
+  return result;
+}
+
+/******************************************************************************/
+
+bool TextTools::isWhiteSpaceCharacter(char c)
+{
+  return (c == ' ')
+         || (c == '\t')
+         || (c == '\n')
+         || (c == '\r')
+         || (c == '\f');
+}
+
+/******************************************************************************/
+
+std::string TextTools::removeWhiteSpaces(const std::string& s)
+{
+  // Copy sequence
+  string st (s);
+
+  // For all sequence's characters
+  for (unsigned int i = 0; i < st.size(); i++)
+  {
+    if (isWhiteSpaceCharacter(st[i]))
+    {
+      st.erase(st.begin() + i); // Remove character
+      i--;
+    }
+  }
+
+  // Send result
+  return st;
+}
+
+/******************************************************************************/
+
+std::string TextTools::removeFirstWhiteSpaces(const std::string& s)
+{
+  // Copy sequence
+  string st (s);
+
+  while (st.size() > 0 && isWhiteSpaceCharacter(st[0]))
+  {
+    st.erase(st.begin());
+  }
+
+  // Send result
+  return st;
+}
+
+/******************************************************************************/
+
+std::string TextTools::removeLastWhiteSpaces(const std::string& s)
+{
+  // Copy sequence
+  string st (s);
+
+  while (st.size() > 0 && isWhiteSpaceCharacter(st[st.size() - 1]))
+  {
+    st.erase(st.end() - 1);
+  }
+
+  // Send result
+  return st;
+}
+
+/******************************************************************************/
+
+std::string TextTools::removeSurroundingWhiteSpaces(const std::string& s)
+{
+  return removeFirstWhiteSpaces(removeLastWhiteSpaces(s));
+}
+
+/******************************************************************************/
+
+bool TextTools::isNewLineCharacter(char c)
+{
+  return (c == '\n')
+         || (c == '\r');
+}
+
+/******************************************************************************/
+
+std::string TextTools::removeNewLines(const std::string& s)
+{
+  // Copy string
+  string st (s);
+
+  // For all string's characters
+  for (unsigned int i = 0; i < st.size(); i++)
+  {
+    if (isNewLineCharacter(st[i]))
+    {
+      st.erase(st.begin() + i); // Remove character
+      i--;
+    }
+  }
+
+  // Send result
+  return st;
+}
+
+/******************************************************************************/
+
+std::string TextTools::removeLastNewLines(const std::string& s)
+{
+  // Copy string
+  string st (s);
+
+  while (st.size() > 0 && isNewLineCharacter(st[st.size() - 1]))
+  {
+    st.erase(st.end() - 1);
+  }
+
+  // Send result
+  return st;
+}
+
+/******************************************************************************/
+
+bool TextTools::isDecimalNumber(char c)
+{
+  if (c == '0' || c == '1' || c == '2' || c == '3' || c == '4'
+      || c == '5' || c == '6' || c == '7' || c == '8' || c == '9')
+    return true;
+  else
+    return false;
+}
+
+/******************************************************************************/
+
+bool TextTools::isDecimalNumber(const std::string& s, char dec, char scientificNotation)
+{
+  size_t sepCount = 0;
+  size_t sciCount = 0;
+  size_t i = 0;
+  if (s[0] == '-') i = 1;
+  for (; i < s.size(); ++i)
+  {
+    char c = s[i];
+    if (c == dec)
+      sepCount++;
+    else if (c == scientificNotation) {
+      sciCount++;
+      if (i == s.size() - 1) return false; //Must be sthg after scientific notation.
+      c = s[i + 1];
+      if (c == '-') i++;
+      if (i == s.size() - 1) return false; //Must be sthg after scientific notation.
+      if (sepCount == 0) sepCount = 1; //We do not want any dec in the exponent.
+    } else if (!isDecimalNumber(c))
+      return false;
+    if (sepCount > 1 || sciCount > 1)
+      return false;
+  }
+  return true;
+}
+
+/******************************************************************************/
+
+bool TextTools::isDecimalInteger(const std::string& s, char scientificNotation)
+{
+  size_t sciCount = 0;
+  size_t i = 0;
+  if (s[0] == '-') i = 1;
+  for (; i < s.size(); ++i)
+  {
+    char c = s[i];
+    if (c == scientificNotation) {
+      sciCount++;
+      if (i == s.size() - 1) return false; //Must be sthg after scientific notation.
+      c = s[i + 1];
+      if (c == '-') return false; //Not an integer then!
+    } else if (!isDecimalNumber(c))
+      return false;
+    if (sciCount > 1)
+      return false;
+  }
+  return true;
+}
+
+/******************************************************************************/
+
+std::string TextTools::toString(int i)
+{
+  ostringstream oss;
+  oss << i;
+  return oss.str();
+}
+
+/******************************************************************************/
+
+std::string TextTools::toString(char c)
+{
+  ostringstream oss;
+  oss << c;
+  return oss.str();
+}
+
+/******************************************************************************/
+
+std::string TextTools::toString(double d, int precision)
+{
+  ostringstream oss;
+  oss << setprecision(precision) << d;
+  return oss.str();
+}
+
+/******************************************************************************/
+
+int TextTools::toInt(const std::string& s) throw (Exception)
+{
+  if (!isDecimalInteger(s)) throw Exception("TextTools::toInt(). Invalid number specification: " + s);
+  istringstream iss(s);
+  int i;
+  iss >> i;
+  return i;
+}
+
+/******************************************************************************/
+
+double TextTools::toDouble(const std::string& s) throw (Exception)
+{
+  if (!isDecimalNumber(s)) throw Exception("TextTools::toDouble(). Invalid number specification: " + s);
+  istringstream iss(s);
+  double d;
+  iss >> d;
+  return d;
+}
+
+/******************************************************************************/
+
+std::string TextTools::resizeRight(const std::string& s, size_t newSize, char fill)
+{
+  if (s.size() > newSize)
+    return s.substr(0, newSize);
+  else
+    return s + string(newSize - s.size(), fill);
+}
+
+/******************************************************************************/
+
+std::string TextTools::resizeLeft(const std::string& s, size_t newSize, char fill)
+{
+  if (s.size() > newSize)
+    return s.substr(s.size() - newSize);
+  else
+    return string(newSize - s.size(), fill) + s;
+}
+
+/******************************************************************************/
+
+std::vector<std::string> TextTools::split(const std::string& s, size_t n)
+{
+  vector<string> v;
+  string tmp = s;
+  while (tmp.size() > n)
+  {
+    v.push_back(tmp.substr(0, n));
+    tmp = tmp.substr(n);
+  }
+  v.push_back(tmp);
+  return v;
+}
+
+/******************************************************************************/
+
+std::string TextTools::removeSubstrings(const std::string& s, char blockBeginning, char blockEnding)
+throw (Exception)
+{
+  string t = "";
+  int blockCount = 0;
+  int begPos = 0;
+  for (unsigned int i = 0; i < s.size(); i++)
+  {
+    char current = s[i];
+    if (current == blockBeginning)
+    {
+      blockCount++;
+      t += s.substr(begPos, i - begPos);
+    }
+    else if (current == blockEnding)
+    {
+      blockCount--;
+      if (blockCount == 0)
+      {
+        begPos = i + 1;
+      }
+      else if (blockCount < 0)
+        throw Exception("TextTools::removeSubstrings(). " +
+                        string("Ending block character without corresponding beginning one at position ") + toString((int)i) + ".");
+    }
+  }
+  t += s.substr(begPos);
+  return t;
+}
+
+/******************************************************************************/
+
+std::string TextTools::removeSubstrings(const std::string& s, char blockBeginning, char blockEnding, std::vector<string>& exceptionsBeginning, std::vector<string>& exceptionsEnding)
+throw (Exception)
+{
+  string t = "";
+  int blockCount = 0;
+  size_t begPos = 0;
+  for (size_t i = 0; i < s.size(); i++)
+  {
+    char current = s[i];
+    if (current == blockBeginning)
+    {
+      bool except = false;
+      for (size_t j = 0; j < exceptionsBeginning.size(); j++)
+      {
+        size_t pos = exceptionsBeginning[j].find(blockBeginning);
+        if (pos != string::npos) {
+          size_t left = i - pos;
+          size_t right = i + exceptionsBeginning[j].length() - pos;
+          if ((right < s.length() - 1) && (hasSubstring (s.substr(left, right), exceptionsBeginning[j])))
+          {
+            except = true;
+            break;
+          }
+        }
+      }
+      if (!except)
+      {
+        blockCount++;
+        t += s.substr(begPos, i - begPos);
+      }
+    }
+    else if ( (current == blockEnding) && (blockCount > 0) )
+    {
+      for (size_t j = 0; j < exceptionsEnding.size(); j++)
+      {
+        size_t pos = exceptionsEnding[j].find(blockEnding);
+        if (pos != string::npos) {
+          size_t left = i - pos;
+          size_t right = i + exceptionsEnding[j].length() - pos;
+          if ((right < s.length() - 1 ) && (hasSubstring (s.substr(left, right), exceptionsEnding[j])))
+          {
+            break;
+          }
+        }
+      }
+      blockCount--;
+      if (blockCount == 0)
+      {
+        begPos = i + 1;
+      }
+      else if (blockCount < 0)
+        throw Exception("TextTools::removeSubstrings(). " +
+                        string("Ending block character without corresponding beginning one at position ") + toString((int)i) + ".");
+    }
+  }
+  t += s.substr(begPos);
+  return t;
+}
+
+/******************************************************************************/
+
+std::string TextTools::removeChar(const std::string& s, char c)
+{
+  // Copy sequence
+  string st(s);
+
+  // For all sequence's characters
+  for (unsigned int i = 0; i < st.size(); i++)
+  {
+    if (st[i] == c)
+    {
+      st.erase(st.begin() + i); // Remove character
+      i--;
+    }
+  }
+
+  // Send result
+  return st;
+}
+
+/******************************************************************************/
+
+unsigned int TextTools::count(const std::string& s, const std::string& pattern)
+{
+  unsigned int count = 0;
+  string::size_type index = s.find(pattern);
+  while (index != string::npos)
+  {
+    count++;
+    index = s.find(pattern, index + 1);
+  }
+  return count;
+}
+
+/******************************************************************************/
+
+bool TextTools::startsWith(const std::string& s, const std::string& pattern)
+{
+  if (s.size() < pattern.size())
+    return false;
+  return s.substr(0, pattern.size()) == pattern;
+}
+
+/******************************************************************************/
+
+bool TextTools::endsWith(const std::string& s, const std::string& pattern)
+{
+  if (s.size() < pattern.size())
+    return false;
+  return s.substr(s.size() - pattern.size()) == pattern;
+}
+
+/******************************************************************************/
+
+bool TextTools::hasSubstring(const std::string& s, const std::string& pattern)
+{
+  if (s.size() < pattern.size())
+    return false;
+  for (size_t i = 0; i < s.size() - pattern.size() + 1; ++i)
+  {
+    if (s.substr(i, pattern.size()) == pattern)
+      return true;
+  }
+  return false;
+}
+
+/******************************************************************************/
+
+void TextTools::replaceAll(std::string& target, const std::string& query, const std::string& replacement)
+{
+  if (query.empty())
+    return;
+  size_t pos = 0;
+  while (pos != string::npos) {
+    pos = target.find(query, pos);
+    target.replace(pos, query.length(), replacement);
+    pos += replacement.length(); //We prevent recursivity!
+  
+  }
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Text/TextTools.h b/src/Bpp/Text/TextTools.h
new file mode 100644
index 0000000..423d8fd
--- /dev/null
+++ b/src/Bpp/Text/TextTools.h
@@ -0,0 +1,411 @@
+//
+// File: TextTools.h
+// Created by: Julien Dutheil
+// Created on: Fri Aug  8 12:57:50 2003
+//
+
+/*
+   Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+   This software is a computer program whose purpose is to provide basal and
+   utilitary classes. This file belongs to the Bio++ Project.
+
+   This software is governed by the CeCILL  license under French law and
+   abiding by the rules of distribution of free software.  You can  use, 
+   modify and/ or redistribute the software under the terms of the CeCILL
+   license as circulated by CEA, CNRS and INRIA at the following URL
+   "http://www.cecill.info". 
+
+   As a counterpart to the access to the source code and  rights to copy,
+   modify and redistribute granted by the license, users are provided only
+   with a limited warranty  and the software's author,  the holder of the
+   economic rights,  and the successive licensors  have only  limited
+   liability. 
+
+   In this respect, the user's attention is drawn to the risks associated
+   with loading,  using,  modifying and/or developing or reproducing the
+   software by the user in light of its specific status of free software,
+   that may mean  that it is complicated to manipulate,  and  that  also
+   therefore means  that it is reserved for developers  and  experienced
+   professionals having in-depth computer knowledge. Users are therefore
+   encouraged to load and test the software's suitability as regards their
+   requirements in conditions enabling the security of their systems and/or 
+   data to be ensured and,  more generally, to use and operate it in the 
+   same conditions as regards security. 
+
+   The fact that you are presently reading this means that you have had
+   knowledge of the CeCILL license and that you accept its terms.
+   */
+
+#ifndef _TEXTTOOLS_H_
+#define _TEXTTOOLS_H_
+
+#include "../Exceptions.h"
+
+
+// From the STL:
+#include <string>
+#include <vector>
+#include <sstream>
+#include <iomanip>
+
+namespace bpp
+{
+
+  /**
+   * @brief Some utilitary functions that work on strings.
+   */
+  class TextTools
+  {
+    public:
+
+      /**
+       * @brief Tell if a string is empty.
+       *
+       * A string is considered to be 'empty' if it is only made of white
+       * spaces.
+       *
+       * @param s The string to check.
+       * @return True if the string has only white characters.
+       */
+      static bool isEmpty(const std::string& s);
+
+      /**
+       * @brief Make the string uppercase.
+       *
+       * @param s The string to analyse.
+       * @return A copy of the string with all chars uppercase.
+       */
+      static std::string toUpper(const std::string& s);
+
+      /**
+       * @brief Make the string lowercase.
+       *
+       * @param s The string to analyse.
+       * @return A copy of the string with all chars lowercase.
+       */
+      static std::string toLower(const std::string& s);
+
+      /**
+       * @brief Tell if a character is a white space or not.
+       *
+       * @param c The character to check.
+       * @return True if c is one of the following: ' ', '\\t', '\\n', '\\r' or '\\f'.
+       */
+      static bool isWhiteSpaceCharacter(char c);
+
+      /**
+       * @brief Remove all white spaces characters in a string.
+       *
+       * @param s The string to parse.
+       * @return A copy of 's' without white spaces characters.
+       */
+      static std::string removeWhiteSpaces (const std::string& s);
+
+      /**
+       * @brief Remove all white spaces characters at the beginning of a string.
+       *
+       * @param s The string to parse.
+       * @return A copy of 's' beginning with the first non-white character.
+       */
+      static std::string removeFirstWhiteSpaces (const std::string& s);
+
+      /**
+       * @brief Remove all white spaces characters at the end of a string.
+       *
+       * @param s The string to parse.
+       * @return A copy of 's' ending with the last non-white character.
+       */
+      static std::string removeLastWhiteSpaces (const std::string& s);
+
+      /**
+       * @brief Remove all white spaces characters at the beginning and the end of a string.
+       *
+       * @param s The string to parse.
+       * @return A copy of 's' beginning with the first non-white character
+       * and ending with the last one.
+       */
+      static std::string removeSurroundingWhiteSpaces(const std::string& s);
+
+      /**
+       * @brief Tell if a character is a new line character or not.
+       *
+       * @param c The character to check.
+       * @return True if c is one of the following: '\\n' or '\\r'.
+       */
+      static bool isNewLineCharacter(char c);
+
+      /**
+       * @brief Remove all new line characters in a string.
+       *
+       * @param s The string to parse.
+       * @return A copy of 's' without new line characters.
+       */
+      static std::string removeNewLines (const std::string& s);
+
+      /**
+       * @brief Remove all new line characters at the end of a string.
+       *
+       * @param s The string to parse.
+       * @return A copy of 's' ending with the last non-new line character.
+       */
+      static std::string removeLastNewLines(const std::string& s);
+
+      /**
+       * @brief Tell is a given character describes a decimal number.
+       *
+       * @param c The character to check.
+       * @return true if the given character is the reprensentation of a decimal number.
+       */
+      static bool isDecimalNumber(char c);
+
+      /**
+       * @brief Tell is a given character string describes a decimal number.
+       *
+       * NB: for now, this parser will not recognize thousands delimiters, and not the scientific notation neither.
+       * @param s The string to parse.
+       * @param dec The decimal separator.
+       * @param scientificNotation character to use for scientific notation (typically 'e' or 'E').
+       * @return true if the given string is the representation of a decimal number.
+       */
+      static bool isDecimalNumber(const std::string& s, char dec = '.', char scientificNotation = 'e');
+
+      /**
+       * @brief Tell is a given character string describes a decimal integer.
+       *
+       * NB: for now, this parser will not recognize thousands delimiters, and not the scientific notation neither.
+       * @param s The string to parse.
+       * @param scientificNotation character to use for scientific notation (typically 'e' or 'E').
+       * @return true if the given string is the representation of a decimal integer.
+       */
+      static bool isDecimalInteger(const std::string& s, char scientificNotation = 'e');
+
+      /**
+       * @brief General template method to convert to a string.
+       *
+       * @param t The object to convert.
+       * @return A string equal to t.
+       */
+      template<class T> static std::string toString(T t)
+      {
+        std::ostringstream oss;
+        oss << t;
+        return oss.str();
+      }
+
+      /**
+       * @brief Template string conversion.
+       * 
+       * @param t The object to convert.
+       * @param precision To use (for numbers).
+       * @return A string equal to t.
+       */
+      template<class T>
+        static std::string toString(T t, int precision)
+        {
+          std::ostringstream oss;
+          oss << std::setprecision(precision) << t;
+          return oss.str();
+        }
+
+      /**
+       * @brief General template method to convert from string.
+       *
+       * @param s The string to convert.
+       * @return An object from string t.
+       */
+      template<class T> static T fromString(const std::string& s)
+      {
+        std::istringstream iss(s);
+        T obj;
+        iss >> obj;
+        return obj;
+      }
+
+      /**
+       * @brief Convert from int to string.
+       *
+       * @param i The integer to convert.
+       * @return A string equal to i.
+       */
+      static std::string toString(int i);
+
+      /**
+       * @brief Convert from char to string.
+       *
+       * @param c The character to convert.
+       * @return A string equal to c.
+       */
+      static std::string toString(char c);
+
+      /**
+       * @brief Convert from double to string.
+       *
+       * @param d The double to convert.
+       * @param precision To use (for numbers).
+       * @return A string equal to d.
+       */
+      static std::string toString(double d, int precision = 6);
+
+      /**
+       * @brief Convert from string to int.
+       *
+       * @param s The string to parse.
+       * @return The integer corresponding to s.
+       * @throw Exception if the string does not specify a valid number.
+       */
+      static int toInt(const std::string& s) throw (Exception);
+
+      /**
+       * @brief Convert from string to double.
+       *
+       * @param s The string to parse.
+       * @return The double corresponding to s.
+       * @throw Exception if the string does not specify a valid number.
+       */
+      static double toDouble(const std::string& s) throw (Exception);
+
+      /**
+       * @brief Template to string conversion.
+       * 
+       * @param s The string to parse.
+       * @return An object of class R corresponding to s.
+       */
+      template<class T>
+      static T to(const std::string& s)
+      {
+        std::istringstream iss(s);
+        T t;
+        iss >> t;
+        return t;
+      }
+
+      /**
+       * @brief Send a string of size 'newSize', which is a copy of 's' truncated or
+       * filled with character 'fill' at the end.
+       *
+       * @param s       The string to parse.
+       * @param newSize The new string size.
+       * @param fill    The character to use to fill the string id length < newSize.
+       * @return A string of size newsize which is a copy from the left of s.
+       */
+      static std::string resizeRight(const std::string& s, size_t newSize, char fill = ' ');
+
+      /**
+       * @brief Send a string of size 'newSize', which is a copy of 's' truncated or
+       * filled with character 'fill' at the beginning.
+       *
+       * @param s       The string to parse.
+       * @param newSize The new string size.
+       * @param fill    The character to use to fill the string id length < newSize.
+       * @return A string of size newsize which is a copy from the right of s.
+       */
+      static std::string resizeLeft(const std::string& s, size_t newSize, char fill = ' ');
+
+      /**
+       * @brief Split a string into parts of size 'n'.
+       *
+       * The last part may contain < n chars.
+       *
+       * @param s The string to parse.
+       * @param n The number of tokens.
+       * @return A vector of strings with all tokens.
+       */
+      static std::vector<std::string> split(const std::string& s, size_t n);
+
+      /**
+       * @brief Remove substrings from a string.
+       *
+       * All substrings beginning with blockBeginning
+       * and ending with blockEnding will be removed.
+       * Nesting blocks are allowed, the most extern block will be removed.
+       *
+       * @param s The string to parse.
+       * @param blockBeginning The character specifying the beginning of each block.
+       * @param blockEnding    The character specifying the end of each block.
+       * @return The string with all blocks removed.
+       * @throw Exception If some blocks are not well formed.
+       */
+      static std::string removeSubstrings(const std::string& s, char blockBeginning, char blockEnding)
+        throw (Exception);
+  
+      /**
+       * @brief Remove substrings from a string, unless they match some specific substrings.
+       *
+       * All substrings beginning with blockBeginning
+       * and ending with blockEnding will be removed, except if they begin with 
+       * a string included in the vector exceptionsBeginning or end with a string
+       * included in the vector exceptionsEnding.
+       * Nesting blocks are allowed, the most extern block will be removed.
+       *
+       * @param s The string to parse.
+       * @param blockBeginning The character specifying the beginning of each block.
+       * @param blockEnding    The character specifying the end of each block.
+       * @param exceptionsBeginning A vector containing all strings specifying the beginning of blocks that should not be removed. 
+       * @param exceptionsEnding A vector containing all strings specifying the ending of blocks that should not be removed.
+       * @return The string with all blocks removed.
+       * @throw Exception If some blocks are not well formed.
+       */
+      static std::string removeSubstrings(const std::string& s, char blockBeginning, char blockEnding, std::vector<std::string>& exceptionsBeginning, std::vector<std::string>& exceptionsEnding)
+        throw (Exception);
+  
+      /**
+       * @brief Remove all occurences of a character in a string.
+       *
+       * @param s The string to parse.
+       * @param c The character to remove.
+       * @return The string with all specified chars removed.
+       */
+      static std::string removeChar(const std::string& s, char c);
+
+      /**
+       * @brief Count the occurences of a given pattern in a string.
+       *
+       * @param s The string to search.
+       * @param pattern The pattern to use (this is a mere string, not a regexp!).
+       * @return The number of occurences of 'pattern' in 's'.
+       */
+      static unsigned int count(const std::string& s, const std::string& pattern);
+
+      /**
+       * @brief Tell is a string begins with a certain motif.
+       *
+       * @param s The string to search.
+       * @param pattern The pattern to use (this is a mere string, not a regexp!).
+       * @return true/false
+       */
+      static bool startsWith(const std::string& s, const std::string& pattern);
+
+      /**
+       * @brief Tell is a string ends with a certain motif.
+       *
+       * @param s The string to search.
+       * @param pattern The pattern to use (this is a mere string, not a regexp!).
+       * @return true/false
+       */
+      static bool endsWith(const std::string& s, const std::string& pattern);
+
+      /**
+       * @brief Tell is a string contains a certain motif.
+       *
+       * @param s The string to search.
+       * @param pattern The pattern to use (this is a mere string, not a regexp!).
+       * @return true/false
+       */
+      static bool hasSubstring(const std::string& s, const std::string& pattern);
+
+      /**
+       * @brief Replacement of all non-overlapping occurrences of a certain motif in a string.
+       *
+       * @param target String to be modified
+       * @param query The motif to look for
+       * @param replacement The replacement string
+       */
+      static void replaceAll(std::string& target, const std::string& query, const std::string& replacement);
+     
+  };
+
+} //end of namespace bpp.
+
+#endif	//_TEXTTOOLS_H_
+
diff --git a/src/Bpp/Utils/AttributesTools.cpp b/src/Bpp/Utils/AttributesTools.cpp
new file mode 100644
index 0000000..d2cd916
--- /dev/null
+++ b/src/Bpp/Utils/AttributesTools.cpp
@@ -0,0 +1,266 @@
+//
+// File: AttributesTools.cpp
+// Created by: Julien Dutheil
+// Created on: 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide basal and 
+utilitary classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+// From the STL:
+#include <cstdlib>
+#include <string>
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+
+#include "AttributesTools.h"
+#include "../App/ApplicationTools.h"
+#include "../Text/TextTools.h"
+#include "../Io/FileTools.h"
+
+using namespace bpp;
+
+/******************************************************************************/
+
+std::vector<std::string> AttributesTools::getVector( int argc, char * argv[])
+{
+  vector<string> result(argc);
+  for(int i = 1; i < argc; i++) result[i] = string(argv[i]);
+  //Ignore first argc which is the program name!    
+  return result;
+}
+
+/******************************************************************************/
+
+std::map<std::string, std::string> AttributesTools::getAttributesMap(
+  const std::vector<std::string> & argv,
+  const std::string & delimiter)
+{
+  map<string, string> am;
+  getAttributesMap(argv, am, delimiter);
+  return am;
+}
+
+/******************************************************************************/
+
+void AttributesTools::getAttributesMap(
+  const std::vector<std::string> & argv,
+  std::map<std::string, std::string> & am,
+  const std::string & delimiter)
+{
+  vector<string> argv2(argv.size());
+  //First make a few cleaning:
+  for(unsigned int i = 0; i < argv.size(); i++)
+  {
+    //Make a few corrections first:
+    string arg = removeComments(argv[i], string("#"), string("\n"));//remove shell comments.
+    arg = removeComments(arg, string("//"), string("\n"));//remove C simple comments.
+    arg = removeComments(arg, string("/*"), string("*/"));//remove C multiple comments.
+    arg = TextTools::removeWhiteSpaces(arg);
+    argv2[i] = arg;
+  }
+  //Now parse arguments:
+  for(unsigned int i = 0; i < argv.size(); i++)
+  {
+    string arg = argv2[i];
+    if(arg == "") continue; //Skipping void line.
+    while(arg[arg.size()-1] == '\\')
+    {
+      //Splitted line
+      i++;
+      arg = arg.substr(0, arg.length()-1) + argv2[i];
+    }
+    //Parsing:
+    string::size_type limit = arg.find(delimiter, 0);
+    if(limit == string::npos)
+    {
+      //Invalid parameter
+      (*ApplicationTools::warning << "WARNING!!! Parameter '" << arg << "' has been ignored.").endLine();
+    }
+    else
+    {
+      string name  = string(arg.begin(), arg.begin() + limit);
+      string value = string(arg.begin() + limit + delimiter.size(), arg.end());
+      if(name == "param")
+      {
+        //Recursive inclusion:
+        getAttributesMapFromFile(value, am, delimiter);
+      }
+      else am[name] = value;
+    }
+  }
+}
+
+/******************************************************************************/
+
+void AttributesTools::getAttributesMapFromFile(
+  const std::string & file,
+  std::map<std::string, std::string> & params,
+  const std::string & delimiter)
+{
+  cout << "Parsing file " << file << " for options." << endl;
+  ifstream input(file.c_str(), ios::in);
+  vector<string> lines = FileTools::putStreamIntoVectorOfStrings(input);
+  getAttributesMap(lines, params, delimiter);
+}
+
+/******************************************************************************/
+
+std::map<std::string, std::string> AttributesTools::getAttributesMapFromFile(
+  const std::string & file,
+  const std::string & delimiter)
+{
+  map<string, string> params;
+  getAttributesMapFromFile(file, params, delimiter);
+  return params;
+}
+
+/******************************************************************************/
+
+void AttributesTools::actualizeAttributesMap(
+  std::map<std::string, std::string> & attMap,
+  const std::map<std::string, std::string> & atts)
+{
+  for(map<string, string>::const_iterator i = atts.begin(); i != atts.end(); i++)
+  {
+    attMap[i->first] = i->second;
+  }
+}
+
+/******************************************************************************/
+
+void AttributesTools::resolveVariables(
+  std::map<std::string, std::string> & am,
+  char varCode,
+  char varBeg,
+  char varEnd)
+throw (Exception)
+{
+  //Now resolve any variable:
+  for (map<string, string>::iterator it = am.begin(); it != am.end(); it++)
+  {
+    string value = it->second;
+    string::size_type index1 = value.find(TextTools::toString(varCode) + TextTools::toString(varBeg));
+    while (index1 != string::npos)
+    {
+      string::size_type index2 = value.find(TextTools::toString(varEnd), index1);
+      if (index2 != string::npos)
+      {
+        string varName  = value.substr(index1 + 2, index2 - index1 - 2);
+        map<string, string>::iterator varIt = am.find(varName);
+        string varValue = "";
+	if (varIt == am.end())
+        {
+          if (ApplicationTools::error)
+            (*ApplicationTools::error << "Variable '" << varName << "' is undefined and was ignored.").endLine();
+        }
+        else
+        {
+          varValue = varIt->second;
+        }
+        //Modify original field:
+        string newValue = value.substr(0, index1) + varValue + value.substr(index2 + 1);
+        it->second = newValue;
+      }
+      else
+        throw Exception("Syntax error, variable name is not closed.");
+      value = it->second;
+      index1 = value.find(TextTools::toString(varCode) + TextTools::toString(varBeg));
+    }
+  }
+}
+
+/******************************************************************************/
+
+std::string AttributesTools::removeComments(
+  const std::string & s,
+  const std::string & begin,
+  const std::string & end)
+{
+  string r = s;
+  string::size_type last = 0;
+  do
+  {
+    string::size_type first = r.find(begin, last);
+    if(first == string::npos) return r; //No shell comment.
+    //else:  
+    last = r.find(end, first);
+    if(last == string::npos)
+    {
+      r.erase(r.begin() + first, r.end());
+    }
+    else
+    {
+      r.erase(r.begin() + first, r.begin() + last);
+    }
+  } while(last != string::npos);
+  return r;
+}
+
+/******************************************************************************/
+
+std::map<std::string, std::string> AttributesTools::parseOptions(int args, char ** argv) throw (Exception)
+{
+  // Get the parameters from command line:
+  map<string, string> cmdParams = AttributesTools::getAttributesMap(
+    AttributesTools::getVector(args, argv), "=");
+
+  // Look for a specified file with parameters:
+  map<string, string> params;
+  if(cmdParams.find("param") != cmdParams.end())
+  {
+    string file = cmdParams["param"];
+    if(!FileTools::fileExists(file))
+    {
+      throw Exception("AttributesTools::parseOptions(). Parameter file not found.");
+    }
+    else
+    {
+      params = getAttributesMapFromFile(file, "=");
+      // Actualize attributes with ones passed to command line:
+      actualizeAttributesMap(params, cmdParams);
+    }
+  }
+  else
+  {
+    params = cmdParams;
+  }
+  // Resolve variables:
+  resolveVariables(params);
+  return params;
+}
+
+/******************************************************************************/
+
diff --git a/src/Bpp/Utils/AttributesTools.h b/src/Bpp/Utils/AttributesTools.h
new file mode 100644
index 0000000..e83390a
--- /dev/null
+++ b/src/Bpp/Utils/AttributesTools.h
@@ -0,0 +1,251 @@
+//
+// File: AttributesTools.h
+// Created by: Julien Dutheil
+// Created on: 2003
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Tools, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide basal and 
+utilitary classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _ATTRIBUTES_TOOLS_H_
+#define _ATTRIBUTES_TOOLS_H_
+
+#include "../Exceptions.h"
+
+// From the STL:
+#include <cstdlib>
+#include <map>
+#include <string>
+#include <vector>
+
+namespace bpp 
+{
+
+/**
+ * @brief Some functions to deal with attributes, i.e. parameters passed to a program/method.
+ *
+ * These methods allows you to retrieve attributes from command line arguments or
+ * from a file.
+ * The underlying syntax is <code> attributeName = argument </code>.
+ * Here the delimiter char is '=', but another character may be used.
+ *
+ * In files, shell comments: <code> # my comment line here </code>,
+ * C comments: <code> / * my comment block here * / </code> (but multiline not supported!)
+ * and C++ comments: <code> // my comment line here </code> are allowed, and ignored while parsing.
+ *
+ * Lines may be broken, using the bash character '\' at the end of the line:
+ * @code
+ * optionfile=/home/foo/\
+ *    bar.txt
+ * @endcode
+ * will be read as
+ * @code
+ * optionfile=/home/foo/bar.txt
+ * @endcode
+ * 
+ * Attributes are stored as a map<string, string>, with attributes names as keys,
+ * and arguments as values.
+ *
+ * Here is an example of use.
+ * This piece of code typically is at the begining of the main function.
+ * It uses the FileTools and ApplicationTools classes, for checking file existence and displaying messages respectively.
+ * @code
+ * // Get the parameters from command line:
+ * map<string, string> cmdParams = AttributesTools::getAttributesMap(
+ *     AttributesTools::getVector(argc, argv), "=");
+ *
+ * // Look for a specified file with parameters:
+ * int main(int argc, char *argv[]) {
+ *   map<string, string> params;
+ *   if(cmdParams.find("param") != cmdParams.end()) {
+ *     string file = cmdParams["param"];
+ *     if(!FileTools::fileExists(file)) {
+ *       ApplicationTools::displayError("Parameter file not found.");
+ *       exit(-1);
+ *     } else {
+ *       params = AttributesTools::getAttributesMapFromFile(file, "=");
+ *       // Actualize attributes with the ones passed to command line:
+ *       AttributesTools::actualizeAttributesMap(params, cmdParams);
+ *     }
+ *   } else {
+ *     params = cmdParams;
+ *   }
+ * ...
+ * @endcode
+ * These pieces of code does the following:
+ * - get all parameters from the command line and store them in a map,
+ * - check if some parameter is called 'param'. If so, look for the file 
+ *   given as value and try to read some parameters from it.
+ * - If an parameter file was found, update the parameter in it with those from
+ *   the command line. This implies that when a parameter is found in bothe the
+ *   command line and the option file, the value from the command line will be
+ *   retained.
+ *
+ * Support for variable is also available.
+ * A variable character is specified (typically '$()') and may be used to de-reference any argument.
+ * For instance,
+ * @code
+ * data=LSU
+ * file=$(data).out
+ * @endcode
+ *
+ * will be equivalent to
+ * @code
+ * data=LSU
+ * file=LSU.out
+ * @endcode
+ */
+class AttributesTools
+{
+  
+  public:
+    
+    AttributesTools() {}
+    virtual ~AttributesTools() {}
+    
+    /**
+     * @brief Get attributes a vector of strings from command line arguments.
+     *
+     * @param argc The number of arguments.
+     * @param argv The array with all arguments.
+     * @return A vector with all arguments as strings.
+     */
+    static std::vector<std::string> getVector(int argc, char * argv[]);
+  
+    /**
+     * @brief Get an attribute map from a vector of arguments.
+     *
+     * This method also resolve all variable calls.
+     *
+     * @param argv      The vector of arguments.
+     * @param delimiter The string that separates attribute names from arguments (for instance '=').
+     * @return          The attribute map.
+     */
+    static std::map<std::string, std::string> getAttributesMap(
+      const std::vector<std::string> & argv,
+      const std::string & delimiter = "=");
+
+    /**
+     * @brief Get an attribute map from a vector of arguments.
+     *
+     * This method also resolve all variable calls.
+     *
+     * @param argv      The vector of arguments.
+     * @param am        The attribute map to fill.
+     * @param delimiter The string that separates attribute names from arguments (for instance '=').
+     */
+    static void getAttributesMap(
+      const std::vector<std::string> & argv,
+      std::map<std::string, std::string> & am,
+      const std::string & delimiter = "=");
+
+    /**
+     * @brief Get an attribute map from a file.
+     *
+     * @param file      The file with all arguments.
+     * @param delimiter The string that separates attribute names from arguments (for instance '=').
+     * @return An attribute map.
+     */
+    static std::map<std::string, std::string> getAttributesMapFromFile(
+      const std::string & file,
+      const std::string & delimiter);
+    
+    /**
+     * @brief Get an attribute map from a file.
+     *
+     * @param file      The file with all arguments.
+     * @param params    An attribute map to fill.
+     * @param delimiter The string that separates attribute names from arguments (for instance '=').
+     */
+    static void getAttributesMapFromFile(
+      const std::string & file,
+      std::map<std::string, std::string> & params,
+      const std::string & delimiter);
+  
+    /**
+     * @brief Actualizes an attribute map with another.
+     *
+     * All fields in map 2 will be added to map 1.
+     * If two attributes have the same name, then map 1 value will be overwritten.
+     *
+     * @param attMap The attributes map.
+     * @param atts   The attributes to add to the map.
+     */
+    static void actualizeAttributesMap(
+      std::map<std::string, std::string> & attMap,
+      const std::map<std::string, std::string> & atts);
+    
+    /**
+     * @brief Resolve the variables.
+     *
+     * If used prior to the actualizeAttributesMap, this function will make the
+     * variables 'local', whereas using them after will make them 'global'.
+     *
+     * @param am The attributes map.
+     * @param varCode   The code that defines variable recalls.
+     * @param varBeg    Variables begin name code.
+     * @param varEnd    Variables end name code.
+     * @throw Exception If there is a syntax error.
+     */
+    static void resolveVariables(std::map<std::string, std::string> & am,
+      char varCode = '$',
+      char varBeg = '(',
+      char varEnd = ')') throw (Exception);
+
+    /**
+     * @brief Global function that reads all parameters from command line and files,
+     * and set the values in a map.
+     *
+     * @param args Number of arguments, as passed to the main function.
+     * @param argv Array of values, as passed to the main function.
+     * @return An attributes map.
+     * @throw Exception in case an option file is not found.
+     */
+    static std::map<std::string, std::string> parseOptions(int args, char ** argv) throw (Exception);
+
+  private:
+    
+    /**
+     * @brief Remove comments from a string.
+     *
+     * @param s     The string to parse.
+     * @param begin Comments front delimiter.
+     * @param end   Comments end delimiter.
+     */
+    static std::string removeComments(const std::string & s, const std::string & begin, const std::string & end);
+};
+
+} //end of namespace bpp.
+
+#endif // _ATTRIBUTES_TOOLS_H_
+
diff --git a/src/Bpp/Utils/MapTools.h b/src/Bpp/Utils/MapTools.h
new file mode 100644
index 0000000..8bc0049
--- /dev/null
+++ b/src/Bpp/Utils/MapTools.h
@@ -0,0 +1,129 @@
+//
+// File: MapTools.h
+// Created by: Julien Dutheil
+// Created on: Tue May 13 18:16:10 2003
+//
+
+/*
+Copyright or © or Copr. CNRS, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide utilitary
+classes. This file belongs to the Bio++ Project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#ifndef _MAPTOOLS_H_
+#define _MAPTOOLS_H_
+
+#include <map>
+#include <vector>
+
+namespace bpp
+{
+
+/**
+ * @brief A fiew tools working on map objects.
+ */
+class MapTools
+{
+	public:
+	
+		/**
+		 * @brief Get a vector of all keys in a map.
+		 *
+		 * @param myMap the map to check.
+		 * @return a vector of all keys.
+		 */
+		template <class Key, class T, class Cmp >
+		static std::vector<Key> getKeys(const std::map<Key, T, Cmp> & myMap)
+		{
+			std::vector<Key> keys;
+			for(typename std::map<Key, T>::const_iterator i = myMap.begin(); i != myMap.end(); i++)
+      {
+				keys.push_back(i->first);
+			}
+			return keys;
+		}
+		
+		/**
+		 * @brief Get a vector of all keys in a map.
+		 *
+		 * @param myMap the map to check.
+		 * @return a vector of all keys.
+		 */
+		template <class Key, class T >
+		static std::vector<Key> getKeys(const std::map<Key, T> & myMap)
+		{
+			std::vector<Key> keys;
+			for(typename std::map<Key, T>::const_iterator i = myMap.begin(); i != myMap.end(); i++)
+      {
+				keys.push_back(i->first);
+			}
+			return keys;
+		}
+		
+		/**
+		 * @brief Get a vector of all values in a map.
+		 *
+		 * @param myMap the map to check.
+		 * @return a vector of all values.
+		 */
+		template <class Key, class T, class Cmp >
+		static std::vector<T> getValues(const std::map<Key, T, Cmp> & myMap)
+		{
+			std::vector<T> values;
+			for(typename std::map<Key, T>::const_iterator i = myMap.begin(); i != myMap.end(); i++)
+      {
+				values.push_back(i->second);
+			}
+			return values;
+		}
+
+		/**
+		 * @brief Get a vector of all values in a map.
+		 *
+		 * @param myMap the map to check.
+		 * @return a vector of all values.
+		 */
+		template <class Key, class T >
+		static std::vector<T> getValues(const std::map<Key, T> & myMap)
+		{
+			std::vector<T> values;
+			for(typename std::map<Key, T>::const_iterator i = myMap.begin(); i != myMap.end(); i++)
+      {
+				values.push_back(i->second);
+			}
+			return values;
+		}
+
+};
+
+} //end of namespace bpp.
+
+#endif	//_MAPTOOLS_H_
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..f3006b1
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,248 @@
+# CMake script for Bio++ Core
+# Author: Sylvain Gaillard and Julien Dutheil
+# Created: 17/08/2009
+
+# File list
+SET(CPP_FILES
+  Bpp/Exceptions.cpp
+  Bpp/BppString.cpp
+  Bpp/App/ApplicationTools.cpp
+  Bpp/App/BppApplication.cpp
+  Bpp/App/NumCalcApplicationTools.cpp
+  Bpp/Io/FileTools.cpp
+  Bpp/Io/BppOParametrizableFormat.cpp
+  Bpp/Io/BppODiscreteDistributionFormat.cpp
+  Bpp/Io/IoDiscreteDistributionFactory.cpp
+  Bpp/Utils/AttributesTools.cpp
+  Bpp/Text/KeyvalTools.cpp
+  Bpp/Text/NestedStringTokenizer.cpp
+  Bpp/Text/StringTokenizer.cpp
+  Bpp/Text/TextTools.cpp
+  Bpp/Graph/BasicONode.cpp
+  Bpp/Graph/BasicTNode.cpp
+  Bpp/Graphics/ColorTools.cpp
+  Bpp/Graphics/GraphicDevice.cpp
+  Bpp/Graphics/Fig/XFigGraphicDevice.cpp
+  Bpp/Graphics/Fig/XFigLaTeXFontManager.cpp
+  Bpp/Graphics/Fig/XFigPostscriptFontManager.cpp
+  Bpp/Graphics/Font/Font.cpp
+  Bpp/Graphics/Latex/DvipsColorSet.cpp
+  Bpp/Graphics/Latex/PgfGraphicDevice.cpp
+  Bpp/Graphics/Molscript/MolscriptColorSet.cpp
+  Bpp/Graphics/Svg/SvgGraphicDevice.cpp
+  Bpp/Graphics/R/RColorSet.cpp
+  Bpp/Numeric/NumTools.cpp
+  Bpp/Numeric/Parameter.cpp
+  Bpp/Numeric/ParameterExceptions.cpp
+  Bpp/Numeric/ParameterList.cpp
+  Bpp/Numeric/Random/RandomTools.cpp
+  Bpp/Numeric/Random/ContingencyTableGenerator.cpp
+  Bpp/Numeric/Random/Uniform01K.cpp
+  Bpp/Numeric/Random/Uniform01QD.cpp
+  Bpp/Numeric/Random/Uniform01WH.cpp
+  Bpp/Numeric/AbstractParameterAliasable.cpp
+  Bpp/Numeric/AbstractParametrizable.cpp
+  Bpp/Numeric/AdaptiveKernelDensityEstimation.cpp
+  Bpp/Numeric/VectorTools.cpp
+  Bpp/Numeric/AutoParameter.cpp
+  Bpp/Numeric/DataTable.cpp
+  Bpp/Numeric/Function/AbstractOptimizer.cpp
+  Bpp/Numeric/Function/BrentOneDimension.cpp
+  Bpp/Numeric/Function/ConjugateGradientMultiDimensions.cpp
+  Bpp/Numeric/Function/DirectionFunction.cpp
+  Bpp/Numeric/Function/DownhillSimplexMethod.cpp
+  Bpp/Numeric/Function/FivePointsNumericalDerivative.cpp
+  Bpp/Numeric/Function/FunctionTools.cpp
+  Bpp/Numeric/Function/GoldenSectionSearch.cpp
+  Bpp/Numeric/Function/MetaOptimizer.cpp
+  Bpp/Numeric/Function/NewtonOneDimension.cpp
+  Bpp/Numeric/Function/NewtonBacktrackOneDimension.cpp
+  Bpp/Numeric/Function/BfgsMultiDimensions.cpp
+  Bpp/Numeric/Function/OneDimensionOptimizationTools.cpp
+  Bpp/Numeric/Function/OptimizationStopCondition.cpp
+  Bpp/Numeric/Function/PowellMultiDimensions.cpp
+  Bpp/Numeric/Function/ReparametrizationFunctionWrapper.cpp
+  Bpp/Numeric/Function/SimpleMultiDimensions.cpp
+  Bpp/Numeric/Function/SimpleNewtonMultiDimensions.cpp
+  Bpp/Numeric/Function/ThreePointsNumericalDerivative.cpp
+  Bpp/Numeric/Function/TwoPointsNumericalDerivative.cpp
+  Bpp/Numeric/Hmm/LogsumHmmLikelihood.cpp
+  Bpp/Numeric/Hmm/LowMemoryRescaledHmmLikelihood.cpp
+  Bpp/Numeric/Hmm/RescaledHmmLikelihood.cpp
+  Bpp/Numeric/Prob/Simplex.cpp
+  Bpp/Numeric/Prob/AbstractDiscreteDistribution.cpp
+  Bpp/Numeric/Prob/BetaDiscreteDistribution.cpp
+  Bpp/Numeric/Prob/ConstantDistribution.cpp
+  Bpp/Numeric/Prob/DirichletDiscreteDistribution.cpp
+  Bpp/Numeric/Prob/ExponentialDiscreteDistribution.cpp
+  Bpp/Numeric/Prob/GammaDiscreteDistribution.cpp
+  Bpp/Numeric/Prob/GaussianDiscreteDistribution.cpp
+  Bpp/Numeric/Prob/InvariantMixedDiscreteDistribution.cpp
+  Bpp/Numeric/Prob/MixtureOfDiscreteDistributions.cpp
+  Bpp/Numeric/Prob/SimpleDiscreteDistribution.cpp
+  Bpp/Numeric/Prob/TruncatedExponentialDiscreteDistribution.cpp
+  Bpp/Numeric/Prob/UniformDiscreteDistribution.cpp
+  Bpp/Numeric/Stat/ContingencyTableTest.cpp
+  Bpp/Numeric/Stat/StatTools.cpp
+  Bpp/Numeric/Stat/Mva/DualityDiagram.cpp 
+  Bpp/Numeric/Stat/Mva/PrincipalComponentAnalysis.cpp 
+  Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.cpp 
+  )
+
+SET(H_FILES
+  Bpp/BppString.h
+  Bpp/BppBoolean.h
+  Bpp/BppVector.h
+  Bpp/Clonable.h
+  Bpp/Exceptions.h
+  Bpp/App/ApplicationTools.h
+  Bpp/App/BppApplication.h
+  Bpp/App/NumCalcApplicationTools.h
+  Bpp/Graph/UNode.h
+  Bpp/Graph/ONode.h
+  Bpp/Graph/TNode.h
+  Bpp/Graph/BasicONode.h
+  Bpp/Graph/BasicTNode.h
+  Bpp/Graphics/AbstractGraphicDevice.h
+  Bpp/Graphics/ColorManager.h
+  Bpp/Graphics/ColorSet.h
+  Bpp/Graphics/ColorTools.h
+  Bpp/Graphics/DefaultColorSet.h
+  Bpp/Graphics/GraphicDevice.h
+  Bpp/Graphics/Point2D.h
+  Bpp/Graphics/Point2DTools.h
+  Bpp/Graphics/RgbColor.h
+  Bpp/Io/FileTools.h
+  Bpp/Io/IoFormat.h
+  Bpp/Io/IoParametrizable.h
+  Bpp/Io/IoDiscreteDistribution.h
+  Bpp/Io/IoDiscreteDistributionFactory.h
+  Bpp/Io/OutputStream.h
+  Bpp/Io/BppOParametrizableFormat.h
+  Bpp/Io/BppODiscreteDistributionFormat.h
+  Bpp/Numeric/AbstractParameterAliasable.h
+  Bpp/Numeric/AbstractParametrizable.h
+  Bpp/Numeric/AdaptiveKernelDensityEstimation.h
+  Bpp/Numeric/AutoParameter.h
+  Bpp/Numeric/Constraints.h
+  Bpp/Numeric/DataTableExceptions.h
+  Bpp/Numeric/DataTable.h
+  Bpp/Numeric/Number.h
+  Bpp/Numeric/NumConstants.h
+  Bpp/Numeric/NumTools.h
+  Bpp/Numeric/ParameterAliasable.h
+  Bpp/Numeric/ParameterExceptions.h
+  Bpp/Numeric/Parameter.h
+  Bpp/Numeric/ParameterList.h
+  Bpp/Numeric/Parametrizable.h
+  Bpp/Numeric/TransformedParameter.h
+  Bpp/Numeric/Random/RandomFactory.h
+  Bpp/Numeric/Random/RandomTools.h
+  Bpp/Numeric/Random/ContingencyTableGenerator.h
+  Bpp/Numeric/Random/Uniform01K.h
+  Bpp/Numeric/Random/Uniform01QD.h
+  Bpp/Numeric/Random/Uniform01WH.h
+  Bpp/Numeric/VectorExceptions.h
+  Bpp/Numeric/VectorTools.h
+  Bpp/Numeric/Range.h
+  Bpp/Text/KeyvalTools.h
+  Bpp/Text/NestedStringTokenizer.h
+  Bpp/Text/StringTokenizer.h
+  Bpp/Text/TextTools.h
+  Bpp/Utils/AttributesTools.h
+  Bpp/Utils/MapTools.h
+  Bpp/Graphics/Fig/XFigGraphicDevice.h
+  Bpp/Graphics/Fig/XFigLaTeXFontManager.h
+  Bpp/Graphics/Fig/XFigPostscriptFontManager.h
+  Bpp/Graphics/Font/Font.h
+  Bpp/Graphics/Font/FontManager.h
+  Bpp/Graphics/Latex/DvipsColorSet.h
+  Bpp/Graphics/Latex/PgfGraphicDevice.h
+  Bpp/Graphics/Molscript/MolscriptColorSet.h
+  Bpp/Graphics/R/RColorSet.h
+  Bpp/Graphics/Svg/SvgGraphicDevice.h
+  Bpp/Numeric/Function/AbstractNumericalDerivative.h
+  Bpp/Numeric/Function/AbstractOptimizer.h
+  Bpp/Numeric/Function/BrentOneDimension.h
+  Bpp/Numeric/Function/ConjugateGradientMultiDimensions.h
+  Bpp/Numeric/Function/DirectionFunction.h
+  Bpp/Numeric/Function/DownhillSimplexMethod.h
+  Bpp/Numeric/Function/FivePointsNumericalDerivative.h
+  Bpp/Numeric/Function/Functions.h
+  Bpp/Numeric/Function/FunctionTools.h
+  Bpp/Numeric/Function/GoldenSectionSearch.h
+  Bpp/Numeric/Function/MetaOptimizer.h
+  Bpp/Numeric/Function/NewtonOneDimension.h
+  Bpp/Numeric/Function/NewtonBacktrackOneDimension.h
+  Bpp/Numeric/Function/BfgsMultiDimensions.h
+  Bpp/Numeric/Function/OneDimensionOptimizationTools.h
+  Bpp/Numeric/Function/OptimizationStopCondition.h
+  Bpp/Numeric/Function/Optimizer.h
+  Bpp/Numeric/Function/PowellMultiDimensions.h
+  Bpp/Numeric/Function/ReparametrizationFunctionWrapper.h
+  Bpp/Numeric/Function/SimpleMultiDimensions.h
+  Bpp/Numeric/Function/SimpleNewtonMultiDimensions.h
+  Bpp/Numeric/Function/ThreePointsNumericalDerivative.h
+  Bpp/Numeric/Function/TwoPointsNumericalDerivative.h
+  Bpp/Numeric/Hmm/HmmEmissionProbabilities.h
+  Bpp/Numeric/Hmm/HmmExceptions.h
+  Bpp/Numeric/Hmm/HmmLikelihood.h
+  Bpp/Numeric/Hmm/HmmStateAlphabet.h
+  Bpp/Numeric/Hmm/HmmTransitionMatrix.h
+  Bpp/Numeric/Hmm/LogsumHmmLikelihood.h
+  Bpp/Numeric/Hmm/LowMemoryRescaledHmmLikelihood.h
+  Bpp/Numeric/Hmm/RescaledHmmLikelihood.h
+  Bpp/Numeric/Matrix/EigenValue.h
+  Bpp/Numeric/Matrix/LUDecomposition.h
+  Bpp/Numeric/Matrix/Matrix.h
+  Bpp/Numeric/Matrix/MatrixTools.h
+  Bpp/Numeric/Prob/Simplex.h
+  Bpp/Numeric/Prob/AbstractDiscreteDistribution.h
+  Bpp/Numeric/Prob/BetaDiscreteDistribution.h
+  Bpp/Numeric/Prob/ConstantDistribution.h
+  Bpp/Numeric/Prob/DirichletDiscreteDistribution.h
+  Bpp/Numeric/Prob/DiscreteDistribution.h
+  Bpp/Numeric/Prob/ExponentialDiscreteDistribution.h
+  Bpp/Numeric/Prob/GammaDiscreteDistribution.h
+  Bpp/Numeric/Prob/GaussianDiscreteDistribution.h
+  Bpp/Numeric/Prob/InvariantMixedDiscreteDistribution.h
+  Bpp/Numeric/Prob/MixtureOfDiscreteDistributions.h
+  Bpp/Numeric/Prob/MultipleDiscreteDistribution.h
+  Bpp/Numeric/Prob/SimpleDiscreteDistribution.h
+  Bpp/Numeric/Prob/TruncatedExponentialDiscreteDistribution.h
+  Bpp/Numeric/Prob/UniformDiscreteDistribution.h
+  Bpp/Numeric/Stat/StatTest.h 
+  Bpp/Numeric/Stat/ContingencyTableTest.h 
+  Bpp/Numeric/Stat/StatTools.h 
+  Bpp/Numeric/Stat/Mva/DualityDiagram.h 
+  Bpp/Numeric/Stat/Mva/PrincipalComponentAnalysis.h 
+  Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.h 
+)
+
+# Build the static lib
+ADD_LIBRARY(bppcore-static STATIC ${CPP_FILES})
+SET_TARGET_PROPERTIES(bppcore-static
+  PROPERTIES OUTPUT_NAME bpp-core
+  CLEAN_DIRECT_OUTPUT 1
+  )
+TARGET_LINK_LIBRARIES(bppcore-static ${LIBS})
+
+# Build the shared lib
+ADD_LIBRARY(bppcore-shared SHARED ${CPP_FILES})
+SET_TARGET_PROPERTIES(bppcore-shared
+  PROPERTIES OUTPUT_NAME bpp-core
+  CLEAN_DIRECT_OUTPUT 1
+  VERSION ${BPPCORE_VERSION}
+  SOVERSION ${BPPCORE_VERSION_MAJOR}
+  )
+TARGET_LINK_LIBRARIES(bppcore-shared ${LIBS})
+
+# Install libs
+INSTALL(TARGETS bppcore-static bppcore-shared DESTINATION lib${LIB_SUFFIX})
+
+# Install headers
+INSTALL(DIRECTORY Bpp/ DESTINATION include/Bpp FILES_MATCHING PATTERN "*.h")
+
+# Generate generic include files (.all)
+INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_SOURCE_DIR}/genIncludes.sh ${CMAKE_PREFIX_PATH}/include/Bpp)")
+
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000..af83f96
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,94 @@
+# CMake script for bpp-core unit tests
+# Author: Julien Dutheil
+# Created: 27/10/2010
+
+MACRO(TEST_FIND_LIBRARY OUTPUT_LIBS lib_name include_to_find)
+  #start:
+  FIND_PATH(${lib_name}_INCLUDE_DIR ${include_to_find})
+
+  SET(${lib_name}_NAMES ${lib_name} ${lib_name}.lib ${lib_name}.dll)
+  FIND_LIBRARY(${lib_name}_LIBRARY NAMES ${${lib_name}_NAMES})
+  IF(${lib_name}_LIBRARY)
+    MESSAGE("-- Library ${lib_name} found here:")
+    MESSAGE("   includes: ${${lib_name}_INCLUDE_DIR}")
+    MESSAGE("   dynamic libraries: ${${lib_name}_LIBRARY}")
+    MESSAGE(WARNING "Library ${lib_name} is already installed in the system tree. Test will be built against it. This may lead to unexpected results. You may want to do 'make install' before 'make test', or remove the installed version.")
+  ELSE()
+    SET(${lib_name}_LIBRARY "-L../src -lbpp-core")
+    SET(${lib_name}_INCLUDE_DIR "../src/")
+  ENDIF()
+  INCLUDE_DIRECTORIES(${${lib_name}_INCLUDE_DIR})
+  SET(${OUTPUT_LIBS} ${${OUTPUT_LIBS}} ${${lib_name}_LIBRARY})
+ENDMACRO(TEST_FIND_LIBRARY)
+
+#Find the bpp-core library library:
+TEST_FIND_LIBRARY(LIBS bpp-core Bpp/Clonable.h)
+
+ADD_EXECUTABLE(test_numconstants test_numconstants.cpp)
+TARGET_LINK_LIBRARIES(test_numconstants ${LIBS})
+ADD_TEST(test_numconstants "test_numconstants")
+
+ADD_EXECUTABLE(test_eigen test_eigen.cpp)
+TARGET_LINK_LIBRARIES(test_eigen ${LIBS})
+ADD_TEST(test_eigen "test_eigen")
+
+ADD_EXECUTABLE(test_matrices test_matrices.cpp)
+TARGET_LINK_LIBRARIES(test_matrices ${LIBS})
+ADD_TEST(test_matrices "test_matrices")
+
+ADD_EXECUTABLE(test_derivative1 test_derivative1.cpp)
+TARGET_LINK_LIBRARIES(test_derivative1 ${LIBS})
+ADD_TEST(test_derivative1 "test_derivative1")
+
+ADD_EXECUTABLE(test_downhill test_downhill.cpp)
+TARGET_LINK_LIBRARIES(test_downhill ${LIBS})
+ADD_TEST(test_downhill "test_downhill")
+
+ADD_EXECUTABLE(test_powell test_powell.cpp)
+TARGET_LINK_LIBRARIES(test_powell ${LIBS})
+ADD_TEST(test_powell "test_powell")
+
+ADD_EXECUTABLE(test_gradient test_gradient.cpp)
+TARGET_LINK_LIBRARIES(test_gradient ${LIBS})
+ADD_TEST(test_gradient "test_gradient")
+
+ADD_EXECUTABLE(test_bfgs test_bfgs.cpp)
+TARGET_LINK_LIBRARIES(test_bfgs ${LIBS})
+ADD_TEST(test_bfgs "test_bfgs")
+
+ADD_EXECUTABLE(test_distributions test_distributions.cpp)
+TARGET_LINK_LIBRARIES(test_distributions ${LIBS})
+ADD_TEST(test_distributions "test_distributions")
+
+ADD_EXECUTABLE(test_stats test_stats.cpp)
+TARGET_LINK_LIBRARIES(test_stats ${LIBS})
+ADD_TEST(test_stats "test_stats")
+
+ADD_EXECUTABLE(test_mva test_mva.cpp)
+TARGET_LINK_LIBRARIES(test_mva ${LIBS})
+ADD_TEST(test_mva "test_mva")
+
+ADD_EXECUTABLE(test_sample test_sample.cpp)
+TARGET_LINK_LIBRARIES(test_sample ${LIBS})
+ADD_TEST(test_sample "test_sample")
+
+ADD_EXECUTABLE(test_range test_range.cpp)
+TARGET_LINK_LIBRARIES(test_range ${LIBS})
+ADD_TEST(test_range "test_range")
+
+ADD_EXECUTABLE(test_text_tools test_text_tools.cpp)
+TARGET_LINK_LIBRARIES(test_text_tools ${LIBS})
+ADD_TEST(test_text_tools "test_text_tools")
+
+IF(UNIX)
+  SET_PROPERTY(TEST test_numconstants test_eigen test_matrices test_derivative1 test_downhill test_powell test_gradient test_bfgs test_distributions test_stats test_mva test_sample test_range test_text_tools PROPERTY ENVIRONMENT "LD_LIBRARY_PATH=$ENV{LD_LIBRARY_PATH}:../src")
+ENDIF()
+
+IF(APPLE)
+  SET_PROPERTY(TEST test_numconstants test_eigen test_matrices test_derivative1 test_downhill test_powell test_gradient test_bfgs test_distributions test_stats test_mva test_sample test_range test_text_tools PROPERTY ENVIRONMENT "DYLD_LIBRARY_PATH=$ENV{DYLD_LIBRARY_PATH}:../src")
+ENDIF()
+
+IF(WIN32)
+  SET(ENV{PATH} "$ENV{PATH};..\\src")
+ENDIF()
+
diff --git a/test/PolynomialFunction.h b/test/PolynomialFunction.h
new file mode 100644
index 0000000..7030015
--- /dev/null
+++ b/test/PolynomialFunction.h
@@ -0,0 +1,127 @@
+//
+// File: PolynomialFunction.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Oct 27 18:46 2010
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/Function/Functions.h>
+#include <Bpp/Numeric/AbstractParametrizable.h>
+
+#include <map>
+#include <string>
+
+using namespace bpp;
+using namespace std;
+
+class PolynomialFunction1:
+  public virtual Function,
+  public AbstractParametrizable
+{
+  private:
+    double fval_;
+ 
+  public:
+    PolynomialFunction1() : AbstractParametrizable(""), fval_(0) {
+      //We declare parameters here:
+      addParameter_(new Parameter("x", 0));
+      addParameter_(new Parameter("y", 0));
+      addParameter_(new Parameter("z", 0));
+      fireParameterChanged(getParameters());
+    }
+ 
+    PolynomialFunction1* clone() const { return new PolynomialFunction1(*this); }
+ 
+  public:
+    void setParameters(const ParameterList& pl) 
+        throw (ParameterNotFoundException, ConstraintException, Exception)
+    {
+      matchParametersValues(pl);
+    }
+    double getValue() const throw (Exception) { return fval_; }
+ 
+    void fireParameterChanged(const ParameterList& pl) {
+      double x = getParameterValue("x");
+      double y = getParameterValue("y");
+      double z = getParameterValue("z");
+      fval_ = (x-5)*(x-5) + (y+2)*(y+2) + (z-3)*(z-3);
+    }
+};
+
+class PolynomialFunction1Der1:
+  public PolynomialFunction1,
+  public virtual DerivableFirstOrder
+{
+  protected:
+    bool compFirstDer_;
+    mutable map<string, double> firstDer_;
+
+  public:
+    PolynomialFunction1Der1(): compFirstDer_(true), firstDer_() {
+      //Need to compute derivatives:
+      fireParameterChanged(getParameters());
+    }
+ 
+    PolynomialFunction1Der1* clone() const { return new PolynomialFunction1Der1(*this); }
+ 
+  public:
+    void setParameters(const ParameterList& pl) 
+        throw (ParameterNotFoundException, ConstraintException, Exception)
+    {
+      matchParametersValues(pl);
+    }
+ 
+    void fireParameterChanged(const ParameterList& pl) {
+      PolynomialFunction1::fireParameterChanged(pl);
+      if (compFirstDer_) {
+        double x = getParameterValue("x");
+        double y = getParameterValue("y");
+        double z = getParameterValue("z");
+        firstDer_["x"] = 2 * (x - 5);
+        firstDer_["y"] = 2 * (y + 2);
+        firstDer_["z"] = 2 * (z - 3);
+      }
+    }
+
+    void enableFirstOrderDerivatives(bool yn) { compFirstDer_ = yn; }
+    bool enableFirstOrderDerivatives() const { return compFirstDer_; }
+
+    double getFirstOrderDerivative(const std::string& variable) const throw (Exception) {
+      if (!compFirstDer_)
+        throw Exception("PolynomialFunction1Der1::getFirstOrderDerivative. First order derivatives are not computed.");
+      return firstDer_[variable];
+    }
+};
+
diff --git a/test/test_bfgs.cpp b/test/test_bfgs.cpp
new file mode 100644
index 0000000..9eb7bc4
--- /dev/null
+++ b/test/test_bfgs.cpp
@@ -0,0 +1,65 @@
+//
+// File: test_bfgs.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Jan 31 19:45 2011
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/Function/BfgsMultiDimensions.h>
+#include <vector>
+#include <iostream>
+#include "PolynomialFunction.h"
+
+using namespace bpp;
+using namespace std;
+
+int main() {
+  PolynomialFunction1Der1 f;
+  cout << f.getValue() << endl;
+  BfgsMultiDimensions optimizer(&f);
+  optimizer.init(f.getParameters());
+  optimizer.optimize();
+  double minf = optimizer.getFunctionValue();
+  double x = f.getParameterValue("x");
+  double y = f.getParameterValue("y");
+  double z = f.getParameterValue("z");
+  cout << "x=" << x << endl;
+  cout << "y=" << y << endl;
+  cout << "z=" << z << endl;
+  cout << "f=" << minf << endl;
+  cout << setprecision(20) << (abs(minf) + abs(x - 5) + abs(y + 2) + abs(z - 3)) << endl;
+  bool test = abs(minf) + abs(x - 5) + abs(y + 2) + abs(z - 3) < 0.01;
+  return (test ? 0 : 1);
+}
diff --git a/test/test_derivative1.cpp b/test/test_derivative1.cpp
new file mode 100644
index 0000000..77cb089
--- /dev/null
+++ b/test/test_derivative1.cpp
@@ -0,0 +1,117 @@
+//
+// File: test_derivative1.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Oct 28 12:49 2010
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/Function/TwoPointsNumericalDerivative.h>
+#include <Bpp/Numeric/Function/ThreePointsNumericalDerivative.h>
+#include <Bpp/Numeric/Function/FivePointsNumericalDerivative.h>
+#include <Bpp/Numeric/Random/RandomTools.h>
+#include <vector>
+#include <iostream>
+#include "PolynomialFunction.h"
+
+using namespace bpp;
+using namespace std;
+
+int main() {
+  PolynomialFunction1 f;
+  PolynomialFunction1Der1 f1;
+  ParameterList pl = f.getParameters();
+  TwoPointsNumericalDerivative nd2pt(&f)  ; nd2pt.setParametersToDerivate(pl.getParameterNames());
+  ThreePointsNumericalDerivative nd3pt(&f); nd3pt.setParametersToDerivate(pl.getParameterNames());
+  FivePointsNumericalDerivative nd5pt(&f) ; nd5pt.setParametersToDerivate(pl.getParameterNames());
+  
+  for (unsigned int repeat = 0; repeat < 10000; ++repeat) {
+    for (unsigned int i = 0; i < pl.size(); ++i) {
+      double val = RandomTools::giveRandomNumberBetweenZeroAndEntry(100) - 50;
+      pl[i].setValue(val);
+    }
+
+    nd2pt.setParameters(pl);
+    vector<double> derivativesNum2pt(pl.size());
+    for (unsigned int i = 0; i < pl.size(); ++i) {
+      derivativesNum2pt[i] = nd2pt.getFirstOrderDerivative(pl.getParameterNames()[i]);
+    }
+
+    nd3pt.setParameters(pl);
+    vector<double> derivativesNum3pt(pl.size());
+    for (unsigned int i = 0; i < pl.size(); ++i) {
+      derivativesNum3pt[i] = nd3pt.getFirstOrderDerivative(pl.getParameterNames()[i]);
+    }
+
+    nd5pt.setParameters(pl);
+    vector<double> derivativesNum5pt(pl.size());
+    for (unsigned int i = 0; i < pl.size(); ++i) {
+      derivativesNum5pt[i] = nd5pt.getFirstOrderDerivative(pl.getParameterNames()[i]);
+    }
+
+    vector<double> derivativesAna(pl.size());
+    f1.setParameters(pl);
+    bool test = true;
+    for (unsigned int i = 0; i < pl.size(); ++i) {
+      derivativesAna[i] = f1.getFirstOrderDerivative(pl.getParameterNames()[i]);
+      if (abs(derivativesAna[i] - derivativesNum2pt[i]) > std::sqrt(nd2pt.getInterval())) test = false;
+      if (abs(derivativesAna[i] - derivativesNum3pt[i]) > std::sqrt(nd2pt.getInterval())) test = false;
+      if (abs(derivativesAna[i] - derivativesNum5pt[i]) > std::sqrt(nd2pt.getInterval())) test = false;
+    }
+
+    //Test:
+    if (!test) {
+      //Failure!
+      for (unsigned int i = 0; i < pl.size(); ++i) {
+        cout << setprecision(20) << pl[i].getName() << "=" << pl[i].getValue() << endl;
+        cout << setprecision(20) << "Ana. Der.     =" << derivativesAna[i]    << endl;
+        cout << setprecision(20) << "Num. Der. 2pts=" << derivativesNum2pt[i] << endl;
+        cout << setprecision(20) << "Num. Der. 3pts=" << derivativesNum3pt[i] << endl;
+        cout << setprecision(20) << "Num. Der. 5pts=" << derivativesNum5pt[i] << endl;
+      }
+      return 1;
+    } else {
+      //for (unsigned int i = 0; i < pl.size(); ++i) {
+      //  cout << pl[i].getName();
+      //  cout << "\t" << pl[i].getValue();
+      //  cout << "\t" << derivativesAna[i];
+      //  cout << "\t" << derivativesNum2pt[i];
+      //  cout << "\t" << derivativesNum3pt[i];
+      //  cout << "\t" << derivativesNum5pt[i];
+      //  cout << endl;
+      //}
+    }
+  }
+  return 0;
+}
diff --git a/test/test_distributions.cpp b/test/test_distributions.cpp
new file mode 100644
index 0000000..20257b4
--- /dev/null
+++ b/test/test_distributions.cpp
@@ -0,0 +1,155 @@
+//
+// File: test_distirbutions.cpp
+// Created by: Julien Dutheil
+// Created on: Fri Jun 8 20:54 2012
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/Prob/ExponentialDiscreteDistribution.h>
+#include <Bpp/Numeric/Prob/TruncatedExponentialDiscreteDistribution.h>
+
+using namespace bpp;
+using namespace std;
+
+void testSumProbs(const DiscreteDistribution& dist) throw (Exception) {
+  cout << "Test sum of probabilities: ";
+  cout.flush();
+  double s = VectorTools::sum(dist.getProbabilities());
+  if (abs(s - 1.0) > 0.000001)
+    throw Exception("Probabilities sum to " + TextTools::toString(s));
+  cout << "ok" << endl;
+}
+
+void testEqualProbs(const DiscreteDistribution& dist) throw (Exception) {
+  cout << "Test equality of probabilities: ";
+  cout.flush();
+  for (size_t i = 1; i < dist.getNumberOfCategories(); ++i)
+    if (abs(dist.getProbability(i) - dist.getProbability(i - 1)) > 0.000001)
+      throw Exception("Probability " + TextTools::toString(i) + " and " + TextTools::toString(i - 1) + " differ.");
+  cout << "ok" << endl;
+}
+
+int main() {
+  try {
+
+    cout << "Testing Exponential distribution with lambda = 0.2:" << endl;
+    for (unsigned int i = 2; i <= 100; i += 5) {
+      cout << "Testing " << i << " classes." << endl;
+      ExponentialDiscreteDistribution expDist(i, 0.2);
+      testSumProbs(expDist);
+      testEqualProbs(expDist);
+    }
+
+    cout << "Testing Exponential distribution with lambda = 5:" << endl;
+    for (unsigned int i = 2; i <= 100;  i += 5) {
+      cout << "Testing " << i << " classes." << endl;
+      ExponentialDiscreteDistribution expDist(i, 5);
+      testSumProbs(expDist);
+      testEqualProbs(expDist);
+    }
+
+    cout << "Testing Truncated Exponential distribution with lambda = 0.2 and t = 0.1:" << endl;
+    for (unsigned int i = 2; i <= 100; i += 5) {
+      cout << "Testing " << i << " classes." << endl;
+      TruncatedExponentialDiscreteDistribution trExpDist(i, 0.2, 0.1);
+      testSumProbs(trExpDist);
+      testEqualProbs(trExpDist);
+    }
+
+    cout << "Testing Truncated Exponential distribution with lambda = 5 and t = 0.1:" << endl;
+    for (unsigned int i = 2; i <= 100; i += 5) {
+      cout << "Testing " << i << " classes." << endl;
+      TruncatedExponentialDiscreteDistribution trExpDist(i, 5, 0.1);
+      testSumProbs(trExpDist);
+      testEqualProbs(trExpDist);
+    }
+
+    cout << "Testing Truncated Exponential distribution with lambda = 0.2 and t = 4:" << endl;
+    for (unsigned int i = 2; i <= 100; i += 5) {
+      cout << "Testing " << i << " classes." << endl;
+      TruncatedExponentialDiscreteDistribution trExpDist(i, 0.2, 4);
+      testSumProbs(trExpDist);
+      testEqualProbs(trExpDist);
+    }
+
+    cout << "Testing Truncated Exponential distribution with lambda = 5 and t = 4:" << endl;
+    for (unsigned int i = 2; i <= 100; i += 5) {
+      cout << "Testing " << i << " classes." << endl;
+      TruncatedExponentialDiscreteDistribution trExpDist(i, 5, 4);
+      testSumProbs(trExpDist);
+      testEqualProbs(trExpDist);
+    }
+
+    //Now makes some more precise calculations:
+
+    cout << "Check values for exponential distribution:" << endl;
+    // x = -log(1-p)/lambda
+    ExponentialDiscreteDistribution expDist(4, 0.2);
+    cout << expDist.getLowerBound() << "\t" << "0" << endl;;
+    cout << expDist.getBound(0)     << "\t" << "1.438410" << endl;;
+    cout << expDist.getBound(1)     << "\t" << "3.465736" << endl;;
+    cout << expDist.getBound(2)     << "\t" << "6.931472" << endl;;
+    cout << expDist.getUpperBound() << "\t" << "+inf" << endl;;
+
+    if (abs(expDist.getLowerBound() - 0) > 0.0001) throw Exception("Unvalid bound.");
+    if (abs(expDist.getBound(0) - 1.438410) > 0.0001) throw Exception("Unvalid bound.");
+    if (abs(expDist.getBound(1) - 3.465736) > 0.0001) throw Exception("Unvalid bound.");
+    if (abs(expDist.getBound(2) - 6.931472) > 0.0001) throw Exception("Unvalid bound.");
+
+    cout << "Check values for truncated exponential distribution:" << endl;
+    // x = -log(1 - (1 - lambda*t) * p) / lambda
+    TruncatedExponentialDiscreteDistribution trExpDist(4, 0.2, 1);
+    cout << trExpDist.getLowerBound() << "\t" << "0" << endl;;
+    cout << trExpDist.getBound(0)     << "\t" << "0.2318813" << endl;;
+    cout << trExpDist.getBound(1)     << "\t" << "0.4750416" << endl;;
+    cout << trExpDist.getBound(2)     << "\t" << "0.7306344" << endl;;
+    cout << trExpDist.getUpperBound() << "\t" << "1" << endl;;
+
+    if (abs(trExpDist.getLowerBound() - 0) > 0.0001) throw Exception("Unvalid bound.");
+    if (abs(trExpDist.getBound(0) - 0.2318813) > 0.0001) throw Exception("Unvalid bound.");
+    if (abs(trExpDist.getBound(1) - 0.4750416) > 0.0001) throw Exception("Unvalid bound.");
+    if (abs(trExpDist.getBound(2) - 0.7306344) > 0.0001) throw Exception("Unvalid bound.");
+    if (abs(trExpDist.getUpperBound() - 1) > 0.0001) throw Exception("Unvalid bound.");
+
+
+
+
+    return 0;
+  } catch(Exception& ex) {
+    cout << "failed :(" << endl;
+    return 1;
+  }
+}
+
diff --git a/test/test_downhill.cpp b/test/test_downhill.cpp
new file mode 100644
index 0000000..f9fa6a4
--- /dev/null
+++ b/test/test_downhill.cpp
@@ -0,0 +1,65 @@
+//
+// File: test_downhill.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Oct 27 18:46 2010
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/Function/DownhillSimplexMethod.h>
+#include <vector>
+#include <iostream>
+#include "PolynomialFunction.h"
+
+using namespace bpp;
+using namespace std;
+
+int main() {
+  PolynomialFunction1 f;
+  cout << f.getValue() << endl;
+  DownhillSimplexMethod optimizer(&f);
+  optimizer.init(f.getParameters());
+  optimizer.optimize();
+  double minf = f.getValue();
+  double x = f.getParameterValue("x");
+  double y = f.getParameterValue("y");
+  double z = f.getParameterValue("z");
+  cout << "x=" << x << endl;
+  cout << "y=" << y << endl;
+  cout << "z=" << z << endl;
+  cout << "f=" << minf << endl;
+  cout << setprecision(20) << (abs(minf) + abs(x - 5) + abs(y + 2) + abs(z - 3)) << endl;
+  bool test = abs(minf) + abs(x - 5) + abs(y + 2) + abs(z - 3) < optimizer.getStopCondition()->getTolerance();
+  return (test ? 0 : 1);
+}
diff --git a/test/test_eigen.cpp b/test/test_eigen.cpp
new file mode 100644
index 0000000..9883f52
--- /dev/null
+++ b/test/test_eigen.cpp
@@ -0,0 +1,73 @@
+//
+// File: test_eigen.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Feb 5 07:50 2009
+//
+
+/*
+Copyright or © or Copr. Bio++Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/Matrix/Matrix.h>
+#include <Bpp/Numeric/Matrix/MatrixTools.h>
+#include <vector>
+#include <iostream>
+
+using namespace bpp;
+using namespace std;
+
+int main() {
+  RowMatrix<double> m(2,2);
+  m(0,0) = 2.3;
+  m(0,1) = 1.4;
+  m(1,0) = 5.0;
+  m(1,1) = -0.9;
+  EigenValue<double> eigen(m);
+  RowMatrix<double> D  = eigen.getD();
+  const vector<double> L  = eigen.getRealEigenValues();
+  RowMatrix<double> V1 = eigen.getV();
+  RowMatrix<double> V2;
+  MatrixTools::inv(V1, V2);
+  cout << "M=" << endl;
+  MatrixTools::print(m);
+  cout << "D=" << endl;
+  MatrixTools::print(D);
+  cout << "V1=" << endl;
+  MatrixTools::print(V1);
+  cout << "V2=" << endl;
+  MatrixTools::print(V2);
+  RowMatrix<double> test;
+  MatrixTools::mult(V1, L, V2, test);
+  cout << "V1 . D . V2=" << endl;
+  MatrixTools::print(test);
+  return (test.equals(m) ? 0 : 1);
+}
diff --git a/test/test_gradient.cpp b/test/test_gradient.cpp
new file mode 100644
index 0000000..1e7d2ef
--- /dev/null
+++ b/test/test_gradient.cpp
@@ -0,0 +1,65 @@
+//
+// File: test_gradient.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Oct 28 10:28 2010
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/Function/ConjugateGradientMultiDimensions.h>
+#include <vector>
+#include <iostream>
+#include "PolynomialFunction.h"
+
+using namespace bpp;
+using namespace std;
+
+int main() {
+  PolynomialFunction1Der1 f;
+  cout << f.getValue() << endl;
+  ConjugateGradientMultiDimensions optimizer(&f);
+  optimizer.init(f.getParameters());
+  optimizer.optimize();
+  double minf = optimizer.getFunctionValue();
+  double x = f.getParameterValue("x");
+  double y = f.getParameterValue("y");
+  double z = f.getParameterValue("z");
+  cout << "x=" << x << endl;
+  cout << "y=" << y << endl;
+  cout << "z=" << z << endl;
+  cout << "f=" << minf << endl;
+  cout << setprecision(20) << (abs(minf) + abs(x - 5) + abs(y + 2) + abs(z - 3)) << endl;
+  bool test = abs(minf) + abs(x - 5) + abs(y + 2) + abs(z - 3) < optimizer.getStopCondition()->getTolerance();
+  return (test ? 0 : 1);
+}
diff --git a/test/test_matrices.cpp b/test/test_matrices.cpp
new file mode 100644
index 0000000..d64ec91
--- /dev/null
+++ b/test/test_matrices.cpp
@@ -0,0 +1,67 @@
+//
+// File: test_matrices.cpp
+// Created by: Julien Dutheil
+// Created on: Nov 2011
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/Matrix/Matrix.h>
+#include <Bpp/Numeric/Matrix/MatrixTools.h>
+#include <vector>
+#include <iostream>
+
+using namespace bpp;
+using namespace std;
+
+int main() {
+  RowMatrix<double> m(2,2);
+  m(0,0) = 2.3;
+  m(0,1) = 1.4;
+  m(1,0) = 5.0;
+  m(1,1) = -0.9;
+  MatrixTools::print(m);
+  RowMatrix<double> n(2, 2);
+  MatrixTools::transpose(m, n),
+  MatrixTools::print(n);
+  RowMatrix<double> m2(2, 2);
+  MatrixTools::transpose(n, m2);
+  RowMatrix<double> o(2, 2);
+  MatrixTools::mult(m, n, o);
+  MatrixTools::print(o);
+ 
+  bool test = m.equals(m2, 0.000001);
+  ApplicationTools::displayBooleanResult("Test passed", test);
+  return (test ? 0 : 1);
+}
diff --git a/test/test_mva.cpp b/test/test_mva.cpp
new file mode 100644
index 0000000..4bd2765
--- /dev/null
+++ b/test/test_mva.cpp
@@ -0,0 +1,175 @@
+//
+// File: test_mva.cpp
+// Created by: Matheu Groussin
+// Created on: Tue Mar 22 14:54 2011
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <string>
+#include <stdlib.h>
+#include <ctime>
+#include <set>
+#include <map>
+#include <cmath>
+
+using namespace std;
+
+#include <Bpp/Numeric/Matrix/EigenValue.h>
+#include <Bpp/Numeric/Matrix/MatrixTools.h>
+#include <Bpp/Numeric/Matrix/Matrix.h>
+#include <Bpp/Numeric/Stat/Mva/DualityDiagram.h>
+#include <Bpp/Numeric/Stat/Mva/PrincipalComponentAnalysis.h>
+#include <Bpp/Numeric/Stat/Mva/CorrespondenceAnalysis.h>
+#include <Bpp/Numeric/VectorTools.h>
+
+using namespace bpp;
+
+/*This program performs some tests for the Pca, Coa and Dudi classes*/
+
+int main(int args, char ** argv)
+{
+	unsigned int nRows = 3;
+	unsigned int nCols = 3;
+	RowMatrix<double> matrix(nRows, nCols);
+	RowMatrix<double> matrix2(nRows, nCols+1);
+	RowMatrix<double> matrix3(nRows, nCols);
+	
+	matrix(0,0) = 10;
+	matrix(1,0) = 20;
+	matrix(2,0) = 30;
+	matrix(0,1) = 20;
+	matrix(1,1) = 10;
+	matrix(2,1) = 40;
+	matrix(0,2) = 30;
+	matrix(1,2) = 40;
+	matrix(2,2) = 10;
+	
+	cout << endl;
+	cout << "First test for the Pca class, with a square matrix : " << endl;
+	cout << endl;
+	cout << "Here's the input matrix : " << endl;
+	MatrixTools::print(matrix, cout);
+	
+	vector<double> rowW(nRows);
+	vector<double> colW(nCols);
+	VectorTools::fill(rowW, 1./static_cast<double>(nRows));
+	VectorTools::fill(colW, 1.);
+	
+	//The constructor with row and column weights is called
+	PrincipalComponentAnalysis* pca1 = new PrincipalComponentAnalysis(matrix, 3, rowW, colW, true, true);
+	
+	cout << "The matrix of Row Coordinates : " << endl;
+	MatrixTools::print(pca1->getRowCoordinates(),cout);
+	cout << endl;
+	cout << endl;
+	
+			
+	matrix2(0,0) = 10;
+	matrix2(1,0) = 20;
+	matrix2(2,0) = 30;
+	matrix2(0,1) = 20;
+	matrix2(1,1) = 10;
+	matrix2(2,1) = 40;
+	matrix2(0,2) = 30;
+	matrix2(1,2) = 40;
+	matrix2(2,2) = 10;
+	matrix2(0,3) = 50;
+	matrix2(1,3) = 10;
+	matrix2(2,3) = 10;
+	
+	cout << endl;
+	cout << "Second test for the Pca class, with a matrix containing more columns than rows: " << endl;
+	cout << endl;
+	cout << "Here's the input matrix : " << endl;
+	MatrixTools::print(matrix2,cout);
+	
+	//The constructor without row and column weigths is called. Default weights will be created.
+	PrincipalComponentAnalysis* pca2 = new PrincipalComponentAnalysis(matrix2, 3, true, true);
+	
+	cout << "The matrix of Principal Axes : " << endl;
+	MatrixTools::print(pca2->getPrincipalAxes(),cout);
+	cout << endl;
+	cout << endl;
+	
+	
+	matrix3(0,0) = 0.10;
+	matrix3(1,0) = 0.20;
+	matrix3(2,0) = 0.30;
+	matrix3(0,1) = 0.40;
+	matrix3(1,1) = 0.50;
+	matrix3(2,1) = 0.60;
+	matrix3(0,2) = 0.50;
+	matrix3(1,2) = 0.30;
+	matrix3(2,2) = 0.10;	
+	
+	cout << endl;
+	cout << "Test for the Coa class, with a square matrix : " << endl;
+	cout << endl;
+	cout << "Here's the input matrix : " << endl;
+	MatrixTools::print(matrix3,cout);
+	
+	//The Coa constructor is called.
+	CorrespondenceAnalysis* coa = new CorrespondenceAnalysis(matrix3, 3);
+
+	cout << "The matrix of Principal Components : " << endl;
+	MatrixTools::print(coa->getPrincipalComponents(),cout);
+	cout << endl;
+	cout << endl;
+	
+	
+	delete pca1;
+	delete pca2;
+	delete coa;
+  return 0;	
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/test_numconstants.cpp b/test/test_numconstants.cpp
new file mode 100644
index 0000000..916d390
--- /dev/null
+++ b/test/test_numconstants.cpp
@@ -0,0 +1,62 @@
+//
+// File: test_numconstants.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Aug 28 20:45 2012
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/NumConstants.h>
+
+#include <iostream>
+#include <limits>
+
+using namespace bpp;
+using namespace std;
+
+int main() {
+  cout << "Min double\t:" << numeric_limits<double>::min() << endl;
+  cout << "Max double\t:" << numeric_limits<double>::max() << endl;
+  cout << "bpp::NumConstants::INF()\t:" << NumConstants::INF() << endl;
+  cout << "bpp::NumConstants::MINF()\t:" << NumConstants::MINF() << endl;
+  cout << "bpp::NumConstants::PINF()\t:" << NumConstants::PINF() << endl;
+  cout << "bpp::NumConstants::NaNF()\t:" << NumConstants::NaN() << endl;
+  if (numeric_limits<double>::min() < NumConstants::MINF()) return 1;
+  if (numeric_limits<double>::max() > NumConstants::PINF()) return 1;
+  cout << "Compiler implements infinity\t:" << (numeric_limits<double>::has_infinity ? "yes" : "no") << endl;
+  cout << "Compiler implements quiet nan\t:" << (numeric_limits<double>::has_quiet_NaN ? "yes" : "no") << endl;
+  cout << "Compiler implements signaling nan\t:" << (numeric_limits<double>::has_signaling_NaN ? "yes" : "no") << endl;
+  return 0;
+}
+
diff --git a/test/test_powell.cpp b/test/test_powell.cpp
new file mode 100644
index 0000000..d649265
--- /dev/null
+++ b/test/test_powell.cpp
@@ -0,0 +1,65 @@
+//
+// File: test_powell.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Oct 27 18:46 2010
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/Function/PowellMultiDimensions.h>
+#include <vector>
+#include <iostream>
+#include "PolynomialFunction.h"
+
+using namespace bpp;
+using namespace std;
+
+int main() {
+  PolynomialFunction1 f;
+  cout << f.getValue() << endl;
+  PowellMultiDimensions optimizer(&f);
+  optimizer.init(f.getParameters());
+  optimizer.optimize();
+  double minf = f.getValue();
+  double x = f.getParameterValue("x");
+  double y = f.getParameterValue("y");
+  double z = f.getParameterValue("z");
+  cout << "x=" << x << endl;
+  cout << "y=" << y << endl;
+  cout << "z=" << z << endl;
+  cout << "f=" << minf << endl;
+  cout << setprecision(20) << (abs(minf) + abs(x - 5) + abs(y + 2) + abs(z - 3)) << endl;
+  bool test = abs(minf) + abs(x - 5) + abs(y + 2) + abs(z - 3) < optimizer.getStopCondition()->getTolerance();
+  return (test ? 0 : 1);
+}
diff --git a/test/test_range.cpp b/test/test_range.cpp
new file mode 100644
index 0000000..5a2c4f9
--- /dev/null
+++ b/test/test_range.cpp
@@ -0,0 +1,198 @@
+//
+// File: test_range.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Nov 5 16:12 2011
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/Range.h>
+#include <Bpp/Numeric/VectorTools.h>
+#include <iostream>
+
+using namespace bpp;
+using namespace std;
+
+template<class T> void test_range(RangeCollection<T>& collection) {
+  cout << collection.toString() << endl;
+ 
+  Range<unsigned int> r(10, 13);
+  cout << "Adding " << r.toString() << endl;
+  collection.addRange(r);
+  cout << collection.toString() << endl;
+
+  r = Range<unsigned int>(18, 21);
+  cout << "Adding " << r.toString() << endl;
+  collection.addRange(r);
+  cout << collection.toString() << endl;
+
+  r = Range<unsigned int>(25, 23);
+  cout << "Adding " << r.toString() << endl;
+  collection.addRange(r);
+  cout << collection.toString() << endl;
+
+  r = Range<unsigned int>(7, 11);
+  cout << "Adding " << r.toString() << endl;
+  collection.addRange(r);
+  cout << collection.toString() << endl;
+
+  r = Range<unsigned int>(9, 24);
+  cout << "Restricting to " << r.toString() << endl;
+  collection.restrictTo(r);
+  cout << collection.toString() << endl;
+
+  r = Range<unsigned int>(5, 23);
+  cout << "Restricting to " << r.toString() << endl;
+  collection.restrictTo(r);
+  cout << collection.toString() << endl;
+
+  r = Range<unsigned int>(19, 24);
+  cout << "Adding " << r.toString() << endl;
+  collection.addRange(r);
+  cout << collection.toString() << endl;
+
+  r = Range<unsigned int>(0, 50);
+  cout << "Adding " << r.toString() << endl;
+  collection.addRange(r);
+  cout << collection.toString() << endl;
+}
+
+int main() {
+  
+  cout << endl << "..:: Definitions ::.." << endl;
+  Range<unsigned int> r1(3, 6);
+  Range<unsigned int> r2(10, 12);
+  Range<unsigned int> r3(0, 2);
+  Range<unsigned int> r4(0, 5);
+  Range<unsigned int> r5(4, 25);
+  Range<unsigned int> r6(4, 5);
+  Range<unsigned int> r7(1, 50);
+  Range<unsigned int> r8(1, 3);
+  Range<unsigned int> r9(6, 8);
+  cout << "r1: " << r1.toString() << endl;
+  cout << "r2: " << r2.toString() << endl;
+  cout << "r3: " << r3.toString() << endl;
+  cout << "r4: " << r4.toString() << endl;
+  cout << "r5: " << r5.toString() << endl;
+  cout << "r6: " << r6.toString() << endl;
+  cout << "r7: " << r7.toString() << endl;
+  cout << "r8: " << r8.toString() << endl;
+  cout << "r9: " << r9.toString() << endl;
+  
+  cout << endl << "..:: Overlaps ::.." << endl;
+  cout << r1.overlap(r2) << endl;
+  if (r1.overlap(r2)) return 1;
+  cout << r1.overlap(r3) << endl;
+  if (r1.overlap(r3)) return 1;
+  cout << r1.overlap(r4) << endl;
+  if (!r1.overlap(r4)) return 1;
+  cout << r1.overlap(r5) << endl;
+  if (!r1.overlap(r5)) return 1;
+  cout << r1.overlap(r6) << endl;
+  if (!r1.overlap(r6)) return 1;
+  cout << r1.overlap(r7) << endl;
+  if (!r1.overlap(r7)) return 1;
+  cout << r1.overlap(r8) << endl;
+  if (r1.overlap(r8)) return 1;
+  cout << r1.overlap(r9) << endl;
+  if (r1.overlap(r9)) return 1;
+
+  cout << endl << "..:: Contiguous ::.." << endl;
+  cout << r1.isContiguous(r2) << endl;
+  if (r1.isContiguous(r2)) return 1;
+  cout << r1.isContiguous(r3) << endl;
+  if (r1.isContiguous(r3)) return 1;
+  cout << r1.isContiguous(r4) << endl;
+  if (r1.isContiguous(r4)) return 1;
+  cout << r1.isContiguous(r5) << endl;
+  if (r1.isContiguous(r5)) return 1;
+  cout << r1.isContiguous(r6) << endl;
+  if (r1.isContiguous(r6)) return 1;
+  cout << r1.isContiguous(r7) << endl;
+  if (r1.isContiguous(r7)) return 1;
+  cout << r1.isContiguous(r8) << endl;
+  if (!r1.isContiguous(r8)) return 1;
+  cout << r1.isContiguous(r9) << endl;
+  if (!r1.isContiguous(r9)) return 1;
+
+  Range<unsigned int> r;
+
+  cout << endl << "..:: Expand ::.." << endl;
+  r = r1; r.expandWith(r2); cout << "r1 \\/ r2: " << r.toString() << endl;
+  if (r != r1) return 1;
+  r = r1; r.expandWith(r3); cout << "r1 \\/ r3: " << r.toString() << endl;
+  if (r != r1) return 1;
+  r = r1; r.expandWith(r4); cout << "r1 \\/ r4: " << r.toString() << endl;
+  if (r != Range<unsigned int>(0, 6)) return 1;
+  r = r1; r.expandWith(r5); cout << "r1 \\/ r5: "  << r.toString() << endl;
+  if (r != Range<unsigned int>(3, 25)) return 1;
+  r = r1; r.expandWith(r6); cout << "r1 \\/ r6: "  << r.toString() << endl;
+  if (r != r1) return 1;
+  r = r1; r.expandWith(r7); cout << "r1 \\/ r7: "  << r.toString() << endl;
+  if (r != r7) return 1;
+
+  cout << endl << "..:: Slice ::.." << endl;
+  r = r1; r.sliceWith(r2); cout << "r1 /\\ r2: " << r.toString() << endl;
+  if (r != Range<unsigned int>(0, 0)) return 1;
+  r = r1; r.sliceWith(r3); cout << "r1 /\\ r3: " << r.toString() << endl;
+  if (r != Range<unsigned int>(0, 0)) return 1;
+  r = r1; r.sliceWith(r4); cout << "r1 /\\ r4: " << r.toString() << endl;
+  if (r != Range<unsigned int>(3, 5)) return 1;
+  r = r1; r.sliceWith(r5); cout << "r1 /\\ r5: "  << r.toString() << endl;
+  if (r != Range<unsigned int>(4, 6)) return 1;
+  r = r1; r.sliceWith(r6); cout << "r1 /\\ r6: "  << r.toString() << endl;
+  if (r != r6) return 1;
+  r = r1; r.sliceWith(r7); cout << "r1 /\\ r7: "  << r.toString() << endl;
+  if (r != r1) return 1;
+
+  cout << endl << "..:: Operators ::.." << endl;
+  r = r1; r += 1; cout << "r1 += 1: " << r.toString() << endl;
+  if (r != Range<unsigned int>(4, 7)) return 1;
+  r = r1 + 2; cout << "r1 + 2: " << r.toString() << endl;
+  if (r != Range<unsigned int>(5, 8)) return 1;
+  r = r1; r -= 1; cout << "r1 -= 1: " << r.toString() << endl;
+  if (r != Range<unsigned int>(2, 5)) return 1;
+  r = r1 - 2; cout << "r1 - 2: " << r.toString() << endl;
+  if (r != Range<unsigned int>(1, 4)) return 1;
+
+  cout << endl << "..:: MultiRange ::.." << endl;
+  MultiRange<unsigned int> mr;
+  test_range(mr);
+
+  cout << endl << "..:: RangeSet ::.." << endl;
+  RangeSet<unsigned int> rs;
+  test_range(rs);
+
+  return 0;
+}
diff --git a/test/test_sample.cpp b/test/test_sample.cpp
new file mode 100644
index 0000000..e09dfb1
--- /dev/null
+++ b/test/test_sample.cpp
@@ -0,0 +1,131 @@
+//
+// File: test_sample.cpp
+// Created by: Julien Dutheil
+// Created on: Wed Sep 28 14:36 2011
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/VectorTools.h>
+#include <Bpp/Numeric/Random/RandomTools.h>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <cmath>
+
+using namespace bpp;
+using namespace std;
+
+int main() {
+  //Create vector:
+  vector<string> pop;
+  pop.push_back("A");
+  pop.push_back("B");
+  pop.push_back("C");
+  pop.push_back("D");
+  pop.push_back("E");
+  unsigned int n = 10000;
+
+  cout << "-*- Check without replacement -*-" << endl;
+  for (unsigned int k = 1; k < 5; ++k) {
+    map<string, unsigned int> counts;
+    for (unsigned int i = 0; i < n; ++i) {
+      vector<string> sample(k);
+      RandomTools::getSample(pop, sample, false);
+      for (size_t j = 0; j < sample.size(); ++j) {
+        counts[sample[j]]++;
+      }
+    }
+    for (map<string, unsigned int>::iterator it = counts.begin(); it != counts.end(); ++it) {
+      double fobs = static_cast<double>(it->second) / static_cast<double>(n);
+      double fexp = static_cast<double>(k) / 5.;
+      cout << it->first << "\t" << it->second << "\t" << fobs << "\t" << fexp << endl;
+      if (abs(fobs - fexp) > 0.1)
+        return 1;
+    }
+    cout << "---------------------------------------" << endl;
+  }
+
+  cout << "-*- Check with replacement -*-" << endl;
+  for (unsigned int k = 1; k < 5; ++k) {
+    map<string, unsigned int> counts;
+    for (unsigned int i = 0; i < n; ++i) {
+      vector<string> sample(k);
+      RandomTools::getSample(pop, sample, true);
+      for (size_t j = 0; j < sample.size(); ++j) {
+        counts[sample[j]]++;
+      }
+    }
+    for (map<string, unsigned int>::iterator it = counts.begin(); it != counts.end(); ++it) {
+      double fobs = static_cast<double>(it->second) / static_cast<double>(n);
+      double fexp = static_cast<double>(k) / 5.;
+      cout << it->first << "\t" << it->second << "\t" << fobs << "\t" << fexp << endl;
+      if (abs(fobs - fexp) > 0.1)
+        return 1;
+    }
+    cout << "---------------------------------------" << endl;
+  }
+
+  cout << "-*- Check with replacement and weights -*-" << endl;
+  vector<double> weights;
+  weights.push_back(2);
+  weights.push_back(3);
+  weights.push_back(8);
+  weights.push_back(2);
+  weights.push_back(1);
+  double sumw = VectorTools::sum(weights);
+  vector<double> fexp = weights / sumw;
+  for (unsigned int k = 1; k < 5; ++k) {
+    map<string, unsigned int> counts;
+    for (unsigned int i = 0; i < n; ++i) {
+      vector<string> sample(k);
+      RandomTools::getSample(pop, weights, sample, true);
+      for (size_t j = 0; j < sample.size(); ++j) {
+        counts[sample[j]]++;
+      }
+    }
+    for (size_t i = 0; i < pop.size(); ++i) {
+      double fobs = static_cast<double>(counts[pop[i]]) / static_cast<double>(n*k);
+      cout << pop[i] << "\t" << counts[pop[i]] << "\t" << fobs << "\t" << fexp[i] << endl;
+      if (abs(fobs - fexp[i]) > 0.1)
+        return 1;
+    }
+    cout << "---------------------------------------" << endl;
+  }
+
+
+
+  return 0;
+}
+
diff --git a/test/test_stats.cpp b/test/test_stats.cpp
new file mode 100644
index 0000000..58a5442
--- /dev/null
+++ b/test/test_stats.cpp
@@ -0,0 +1,87 @@
+//
+// File: test_stats.cpp
+// Created by: Julien Dutheil
+// Created on: Thu Dec 9 15:38 2010
+//
+
+/*
+Copyright or © or Copr. Bio++Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Numeric/Stat/ContingencyTableTest.h>
+#include <Bpp/Numeric/VectorTools.h>
+#include <Bpp/Numeric/Random/ContingencyTableGenerator.h>
+#include <Bpp/Numeric/Random/RandomTools.h>
+#include <Bpp/Numeric/Matrix/MatrixTools.h>
+#include <vector>
+#include <iostream>
+#include <cmath>
+
+using namespace bpp;
+using namespace std;
+
+//tbl<-rbind(c(6,12,16,20),c(9,34,28,12))
+//chisq.test(tbl);
+int main() {
+  vector< vector<size_t> > table;
+  vector<size_t> row1;
+  row1.push_back(6);
+  row1.push_back(12);
+  row1.push_back(16);
+  row1.push_back(20);
+  table.push_back(row1);
+  vector<size_t> row2;
+  row2.push_back(9);
+  row2.push_back(34);
+  row2.push_back(28);
+  row2.push_back(12);
+  table.push_back(row2);
+  ContingencyTableTest test(table);
+  VectorTools::print(test.getMarginRows());
+  VectorTools::print(test.getMarginColumns());
+  ContingencyTableGenerator ctRand(test.getMarginRows(), test.getMarginColumns());
+  RowMatrix<size_t> rtable = ctRand.rcont2();
+  MatrixTools::print(rtable);
+
+  cout << test.getStatistic() << " \t" << test.getPValue() << endl;
+  if (abs(test.getPValue() - 0.01324) > 0.0001)
+    return 1;
+
+  //Now test permutations:
+  ContingencyTableTest test2(table, 20000);
+  cout << test2.getStatistic() << " \t" << test2.getPValue() << endl;
+  if (abs(test2.getPValue() - 0.01324) > 0.01)
+    return 1;
+
+  return 0;
+}
+
diff --git a/test/test_text_tools.cpp b/test/test_text_tools.cpp
new file mode 100644
index 0000000..c466711
--- /dev/null
+++ b/test/test_text_tools.cpp
@@ -0,0 +1,112 @@
+//
+// File: test_text_tools.cpp
+// Created by: Julien Dutheil
+// Created on: Mon Nov 5 16:12 2011
+//
+
+/*
+Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
+
+This software is a computer program whose purpose is to provide classes
+for numerical calculus. This file is part of the Bio++ project.
+
+This software is governed by the CeCILL  license under French law and
+abiding by the rules of distribution of free software.  You can  use, 
+modify and/ or redistribute the software under the terms of the CeCILL
+license as circulated by CEA, CNRS and INRIA at the following URL
+"http://www.cecill.info". 
+
+As a counterpart to the access to the source code and  rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty  and the software's author,  the holder of the
+economic rights,  and the successive licensors  have only  limited
+liability. 
+
+In this respect, the user's attention is drawn to the risks associated
+with loading,  using,  modifying and/or developing or reproducing the
+software by the user in light of its specific status of free software,
+that may mean  that it is complicated to manipulate,  and  that  also
+therefore means  that it is reserved for developers  and  experienced
+professionals having in-depth computer knowledge. Users are therefore
+encouraged to load and test the software's suitability as regards their
+requirements in conditions enabling the security of their systems and/or 
+data to be ensured and,  more generally, to use and operate it in the 
+same conditions as regards security. 
+
+The fact that you are presently reading this means that you have had
+knowledge of the CeCILL license and that you accept its terms.
+*/
+
+#include <Bpp/Text/TextTools.h>
+#include <Bpp/Text/StringTokenizer.h>
+#include <iostream>
+
+using namespace bpp;
+using namespace std;
+
+int main()
+{
+  cout << "Testing string conversion..." << endl;
+  if ( TextTools::isDecimalNumber("aazz")) { cout << "aazz is not a decimal number!" << endl; return 1; }
+  if ( TextTools::isDecimalNumber("-aazz")) { cout << "-aazz is not a decimal number!" << endl; return 1; }
+  if ( TextTools::isDecimalNumber("-3.45z")) { cout << "-3.45z is not a decimal number!" << endl; return 1; }
+  if (!TextTools::isDecimalNumber("0")) { cout << "0 is a decimal number!" << endl; return 1; }
+  if (!TextTools::isDecimalNumber("123")) { cout << "123 is a decimal number!" << endl; return 1; }
+  if (!TextTools::isDecimalNumber("-123")) { cout << "-123 is a decimal number!" << endl; return 1; }
+  if (!TextTools::isDecimalNumber("-123.456")) { cout << "-123.456 is a decimal number!" << endl; return 1; }
+  if (!TextTools::isDecimalInteger("123456")) { cout << "123456 is a decimal integer!" << endl; return 1; }
+  if (!TextTools::isDecimalInteger("-7890")) { cout << "-7890 is a decimal integer!" << endl; return 1; }
+  if (!TextTools::isDecimalNumber("-123.456e-5")) { cout << "-123.456e-5 is a decimal number!" << endl; return 1; }
+  if ( TextTools::isDecimalNumber("-123.456e-5.8")) { cout << "-123.456e-5.8 is not a decimal number!" << endl; return 1; }
+  if (!TextTools::isDecimalInteger("-123e6")) { cout << "-123e6 is a decimal integer!" << endl; return 1; }
+  if ( TextTools::isDecimalInteger("-123.456e5")) { cout << "-123.456e5 is not a decimal integer!" << endl; return 1; }
+  if ( TextTools::isDecimalInteger("-123e-6")) { cout << "-123e-6 is not a decimal integer!" << endl; return 1; }
+
+  cout << "Testing string tokenizer..." << endl;
+  string t;
+  StringTokenizer st1(" aaazzer  aeerd a    eer", " \t", false, false);
+  if (st1.numberOfRemainingTokens() != 4) return 1;
+  cout << (t = st1.nextToken()) << endl;
+  if (t != "aaazzer") return 1;
+  cout << (t = st1.nextToken()) << endl;
+  if (t != "aeerd") return 1;
+  cout << (t = st1.nextToken()) << endl;
+  if (t != "a") return 1;
+  cout << (t = st1.nextToken()) << endl;
+  if (t != "eer") return 1;
+
+  StringTokenizer st2(" aaazzer  aeerd a    eer", " \t", false, true);
+  if (st2.numberOfRemainingTokens() != 8) return 1;
+  cout << (t = st2.nextToken()) << endl;
+  if (t != "aaazzer") return 1;
+  cout << (t = st2.nextToken()) << endl;
+  if (t != "") return 1;
+  cout << (t = st2.nextToken()) << endl;
+  if (t != "aeerd") return 1;
+  cout << (t = st2.nextToken()) << endl;
+  if (t != "a") return 1;
+  cout << (t = st2.nextToken()) << endl;
+  if (t != "") return 1;
+  cout << (t = st2.nextToken()) << endl;
+  if (t != "") return 1;
+  cout << (t = st2.nextToken()) << endl;
+  if (t != "") return 1;
+  cout << (t = st2.nextToken()) << endl;
+  if (t != "eer") return 1;
+ 
+  StringTokenizer st3(" aaazzer  aeerd a    eer", " \t", true, false);
+  if (st3.numberOfRemainingTokens() != 1) return 1;
+  cout << (t = st3.nextToken()) << endl;
+  if (t != " aaazzer  aeerd a    eer") return 1;
+
+  StringTokenizer st4(" aaazzer  aeerd a    eer", " \t", false, false);
+  cout << st4.nextToken() << "+";
+  cout << st4.unparseRemainingTokens() << endl;
+  cout << st4.nextToken() << "+";
+  cout << st4.unparseRemainingTokens() << endl;
+  cout << st4.nextToken() << "+";
+  cout << st4.unparseRemainingTokens() << endl;
+  cout << st4.nextToken() << "+";
+  cout << st4.unparseRemainingTokens() << endl;
+  return 0;
+}

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



More information about the debian-med-commit mailing list